diff --git a/src/gamelog/builder.rs b/src/gamelog/builder.rs index 3570041..4f36cb0 100644 --- a/src/gamelog/builder.rs +++ b/src/gamelog/builder.rs @@ -7,35 +7,80 @@ pub struct Logger { } impl Logger { + /// Creates a blank builder for making message log entries. pub fn new() -> Self { Logger { current_colour: RGB::named(rltk::WHITE), fragments: Vec::new() } } + /// Sets the colour of the current message logger. pub fn colour(mut self, colour: (u8, u8, u8)) -> Self { self.current_colour = RGB::named(colour); return self; } + /// Appends text in the current colour to the current message logger. pub fn append(mut self, text: T) -> Self { + let mut text_with_space = text.to_string(); + text_with_space.push_str(" "); + self.fragments.push(LogFragment { colour: self.current_colour, text: text_with_space }); + return self; + } + + /// Appends text in the current colour to the current message logger, with no space. + #[allow(dead_code)] + pub fn append_n(mut self, text: T) -> Self { self.fragments.push(LogFragment { colour: self.current_colour, text: text.to_string() }); return self; } + /// Appends a period to the current message logger. + pub fn period(mut self) -> Self { + self.fragments.push(LogFragment { colour: self.current_colour, text: ".".to_string() }); + return self; + } + + /// Pushes the finished log entry. pub fn log(self) { return append_entry(self.fragments); } + /// Appends text in YELLOW to the current message logger. pub fn npc_name(mut self, text: T) -> Self { + let mut text_with_space = text.to_string(); + text_with_space.push_str(" "); + self.fragments.push(LogFragment { colour: RGB::named(rltk::YELLOW), text: text_with_space }); + return self; + } + + /// Appends text in YELLOW to the current message logger, with no space. + pub fn npc_name_n(mut self, text: T) -> Self { self.fragments.push(LogFragment { colour: RGB::named(rltk::YELLOW), text: text.to_string() }); return self; } + /// Appends text in CYAN to the current message logger. pub fn item_name(mut self, text: T) -> Self { + let mut text_with_space = text.to_string(); + text_with_space.push_str(" "); + self.fragments.push(LogFragment { colour: RGB::named(rltk::CYAN), text: text_with_space }); + return self; + } + + /// Appends text in CYAN to the current message logger, with no space. + pub fn item_name_n(mut self, text: T) -> Self { self.fragments.push(LogFragment { colour: RGB::named(rltk::CYAN), text: text.to_string() }); return self; } + /// Appends text in RED to the current message logger. pub fn damage(mut self, damage: i32) -> Self { + self.fragments.push(LogFragment { colour: RGB::named(rltk::RED), text: format!("{} ", damage).to_string() }); + return self; + } + + /// Appends text in RED to the current message logger, with no space. + #[allow(dead_code)] + pub fn damage_n(mut self, damage: i32) -> Self { self.fragments.push(LogFragment { colour: RGB::named(rltk::RED), text: format!("{}", damage).to_string() }); return self; } diff --git a/src/gamelog/events.rs b/src/gamelog/events.rs index f7c7b4f..7781fa1 100644 --- a/src/gamelog/events.rs +++ b/src/gamelog/events.rs @@ -9,6 +9,7 @@ pub fn clear_events() { EVENTS.lock().unwrap().clear(); } +#[allow(unused_mut)] pub fn record_event(event: T, n: i32) { let event_name = event.to_string(); let mut events_lock = EVENTS.lock(); diff --git a/src/gamelog/logstore.rs b/src/gamelog/logstore.rs index 9d8ec10..dc05a02 100644 --- a/src/gamelog/logstore.rs +++ b/src/gamelog/logstore.rs @@ -19,18 +19,22 @@ pub fn clear_log() { LOG.lock().unwrap().clear(); } -pub fn log_display() -> TextBuilder { - let mut buf = TextBuilder::empty(); - - LOG.lock().unwrap().iter().rev().take(12).for_each(|log| { +pub fn print_log(console: &mut Box, pos: Point, descending: bool, len: usize) { + let mut y = pos.y; + let mut x = pos.x; + LOG.lock().unwrap().iter().rev().take(len).for_each(|log| { log.iter().for_each(|frag| { - buf.fg(frag.colour); - buf.line_wrap(&frag.text); + console.print_color(x, y, frag.colour.into(), RGB::named(rltk::BLACK).into(), &frag.text); + x += frag.text.len() as i32; + x += 0; }); - buf.ln(); + if descending { + y += 1; + } else { + y -= 1; + } + x = pos.x; }); - - return buf; } pub fn clone_log() -> Vec> { diff --git a/src/gamelog/mod.rs b/src/gamelog/mod.rs index aad720f..4ba9ad8 100644 --- a/src/gamelog/mod.rs +++ b/src/gamelog/mod.rs @@ -4,7 +4,7 @@ mod builder; pub use builder::*; mod logstore; use logstore::*; -pub use logstore::{clear_log, clone_log, log_display, restore_log}; +pub use logstore::{clear_log, clone_log, print_log, restore_log}; mod events; pub use events::*; diff --git a/src/gui.rs b/src/gui.rs index 4ef7066..6786199 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -2,35 +2,33 @@ use super::{ gamelog, rex_assets::RexAssets, CombatStats, InBackpack, Map, Name, Player, Point, Position, RunState, State, Viewshed, }; -use rltk::{Rltk, TextBlock, VirtualKeyCode, RGB}; +use rltk::{Rltk, VirtualKeyCode, RGB}; use specs::prelude::*; pub fn draw_ui(ecs: &World, ctx: &mut Rltk) { - ctx.draw_box(0, 43, 79, 6, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK)); + ctx.draw_hollow_box_double(0, 45, 79, 14, RGB::named(rltk::WHITE), RGB::named(rltk::BLACK)); // Render stats let combat_stats = ecs.read_storage::(); let players = ecs.read_storage::(); for (_player, stats) in (&players, &combat_stats).join() { let health = format!(" HP {}/{} ", stats.hp, stats.max_hp); - ctx.print_color_right(36, 43, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &health); - ctx.draw_bar_horizontal(38, 43, 34, stats.hp, stats.max_hp, RGB::named(rltk::RED), RGB::named(rltk::BLACK)); + ctx.print_color_right(36, 45, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &health); + ctx.draw_bar_horizontal(38, 45, 34, stats.hp, stats.max_hp, RGB::named(rltk::RED), RGB::named(rltk::BLACK)); } - // Render message log - let mut block = TextBlock::new(1, 44, 78, 5); - let _ = block.print(&gamelog::log_display()); - block.render(&mut rltk::BACKEND_INTERNAL.lock().consoles[0].console); + // Render the message log at [1, 46], descending, with 6 lines. + gamelog::print_log(&mut rltk::BACKEND_INTERNAL.lock().consoles[0].console, Point::new(1, 46), true, 13); // Render depth let map = ecs.fetch::(); let depth = format!(" D{} ", map.depth); - ctx.print_color_right(78, 43, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &depth); + ctx.print_color_right(78, 45, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &depth); // Render turn ctx.print_color_right( 78, - 49, + 59, RGB::named(rltk::YELLOW), RGB::named(rltk::BLACK), &format!(" T{} ", crate::gamelog::get_event_count("Turn")), diff --git a/src/inventory_system.rs b/src/inventory_system.rs index 56e7585..e4ba2e2 100644 --- a/src/inventory_system.rs +++ b/src/inventory_system.rs @@ -27,7 +27,8 @@ impl<'a> System<'a> for ItemCollectionSystem { if pickup.collected_by == *player_entity { gamelog::Logger::new() .append("You pick up the") - .item_name(format!("{}.", &names.get(pickup.item).unwrap().name)) + .item_name_n(format!("{}", &names.get(pickup.item).unwrap().name)) + .period() .log(); } } @@ -89,7 +90,11 @@ impl<'a> System<'a> for ItemUseSystem { let is_cursed = cursed_items.get(wants_to_use.item); - gamelog::Logger::new().append("You use the").item_name(format!("{}.", &item_being_used.name)).log(); + gamelog::Logger::new() + .append("You use the") + .item_name_n(format!("{}", &item_being_used.name)) + .period() + .log(); // TARGETING let mut targets: Vec = Vec::new(); @@ -213,7 +218,8 @@ impl<'a> System<'a> for ItemUseSystem { .damage(damage.amount) .colour(rltk::WHITE) .append("damage from the") - .item_name(format!("{}.", &item_being_used.name)) + .item_name_n(format!("{}", &item_being_used.name)) + .period() .log(); } } @@ -324,7 +330,8 @@ impl<'a> System<'a> for ItemDropSystem { if entity == *player_entity { gamelog::Logger::new() .append("You drop the") - .item_name(format!("{}.", &names.get(to_drop.item).unwrap().name)) + .item_name_n(format!("{}", &names.get(to_drop.item).unwrap().name)) + .period() .log(); } } diff --git a/src/main.rs b/src/main.rs index 491f469..4cde3f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -368,7 +368,7 @@ impl GameState for State { } const DISPLAYWIDTH: i32 = 80; -const DISPLAYHEIGHT: i32 = 50; +const DISPLAYHEIGHT: i32 = 60; fn main() -> rltk::BError { use rltk::RltkBuilder; @@ -436,6 +436,9 @@ fn main() -> rltk::BError { gamelog::clear_log(); gamelog::clear_events(); + for _ in 0..5 { + gamelog::Logger::new().log(); + } gamelog::Logger::new() .append("Welcome!") .colour(rltk::CYAN) diff --git a/src/melee_combat_system.rs b/src/melee_combat_system.rs index 2211ba9..2a3b548 100644 --- a/src/melee_combat_system.rs +++ b/src/melee_combat_system.rs @@ -57,7 +57,8 @@ impl<'a> System<'a> for MeleeCombatSystem { .npc_name(&name.name) .colour(rltk::WHITE) .append("hits the") - .npc_name(format!("{}.", &target_name.name)) + .npc_name_n(format!("{}", &target_name.name)) + .period() .log(); SufferDamage::new_damage(&mut inflict_damage, wants_melee.target, damage); } diff --git a/src/spawner.rs b/src/spawner.rs index 09ae288..78b90c2 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -133,13 +133,13 @@ fn room_table(map_depth: i32) -> RandomTable { .add("orc", 4 + map_depth) // Potions .add("weak health potion", 4) - .add("health potion", 1 + map_depth) + .add("health potion", 1 + (map_depth / 2)) // Scrolls - .add("fireball scroll", 1 + map_depth) + .add("fireball scroll", 1 + (map_depth / 3)) .add("cursed fireball scroll", 1) - .add("confusion scroll", 1) + .add("confusion scroll", 2) .add("magic missile scroll", 4) - .add("magic map scroll", 1) + .add("magic map scroll", 2) .add("cursed magic map scroll", 1); }