extends log builder, swaps away from textblocks

line wrapping no longer works, but in return the message log can easily be swapped between ascending/descending, and spaces/no spaces between entries.

realistically nobody wants to read a huge wrapped line anyway so those can just be avoided
This commit is contained in:
Llywelwyn 2023-07-11 02:41:01 +01:00
parent b562e093ea
commit 42901b984e
9 changed files with 89 additions and 30 deletions

View file

@ -7,35 +7,80 @@ pub struct Logger {
} }
impl Logger { impl Logger {
/// Creates a blank builder for making message log entries.
pub fn new() -> Self { pub fn new() -> Self {
Logger { current_colour: RGB::named(rltk::WHITE), fragments: Vec::new() } 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 { pub fn colour(mut self, colour: (u8, u8, u8)) -> Self {
self.current_colour = RGB::named(colour); self.current_colour = RGB::named(colour);
return self; return self;
} }
/// Appends text in the current colour to the current message logger.
pub fn append<T: ToString>(mut self, text: T) -> Self { pub fn append<T: ToString>(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<T: ToString>(mut self, text: T) -> Self {
self.fragments.push(LogFragment { colour: self.current_colour, text: text.to_string() }); self.fragments.push(LogFragment { colour: self.current_colour, text: text.to_string() });
return self; 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) { pub fn log(self) {
return append_entry(self.fragments); return append_entry(self.fragments);
} }
/// Appends text in YELLOW to the current message logger.
pub fn npc_name<T: ToString>(mut self, text: T) -> Self { pub fn npc_name<T: ToString>(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<T: ToString>(mut self, text: T) -> Self {
self.fragments.push(LogFragment { colour: RGB::named(rltk::YELLOW), text: text.to_string() }); self.fragments.push(LogFragment { colour: RGB::named(rltk::YELLOW), text: text.to_string() });
return self; return self;
} }
/// Appends text in CYAN to the current message logger.
pub fn item_name<T: ToString>(mut self, text: T) -> Self { pub fn item_name<T: ToString>(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<T: ToString>(mut self, text: T) -> Self {
self.fragments.push(LogFragment { colour: RGB::named(rltk::CYAN), text: text.to_string() }); self.fragments.push(LogFragment { colour: RGB::named(rltk::CYAN), text: text.to_string() });
return self; return self;
} }
/// Appends text in RED to the current message logger.
pub fn damage(mut self, damage: i32) -> Self { 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() }); self.fragments.push(LogFragment { colour: RGB::named(rltk::RED), text: format!("{}", damage).to_string() });
return self; return self;
} }

View file

@ -9,6 +9,7 @@ pub fn clear_events() {
EVENTS.lock().unwrap().clear(); EVENTS.lock().unwrap().clear();
} }
#[allow(unused_mut)]
pub fn record_event<T: ToString>(event: T, n: i32) { pub fn record_event<T: ToString>(event: T, n: i32) {
let event_name = event.to_string(); let event_name = event.to_string();
let mut events_lock = EVENTS.lock(); let mut events_lock = EVENTS.lock();

View file

@ -19,18 +19,22 @@ pub fn clear_log() {
LOG.lock().unwrap().clear(); LOG.lock().unwrap().clear();
} }
pub fn log_display() -> TextBuilder { pub fn print_log(console: &mut Box<dyn Console>, pos: Point, descending: bool, len: usize) {
let mut buf = TextBuilder::empty(); let mut y = pos.y;
let mut x = pos.x;
LOG.lock().unwrap().iter().rev().take(12).for_each(|log| { LOG.lock().unwrap().iter().rev().take(len).for_each(|log| {
log.iter().for_each(|frag| { log.iter().for_each(|frag| {
buf.fg(frag.colour); console.print_color(x, y, frag.colour.into(), RGB::named(rltk::BLACK).into(), &frag.text);
buf.line_wrap(&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<Vec<crate::gamelog::LogFragment>> { pub fn clone_log() -> Vec<Vec<crate::gamelog::LogFragment>> {

View file

@ -4,7 +4,7 @@ mod builder;
pub use builder::*; pub use builder::*;
mod logstore; mod logstore;
use 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; mod events;
pub use events::*; pub use events::*;

View file

@ -2,35 +2,33 @@ use super::{
gamelog, rex_assets::RexAssets, CombatStats, InBackpack, Map, Name, Player, Point, Position, RunState, State, gamelog, rex_assets::RexAssets, CombatStats, InBackpack, Map, Name, Player, Point, Position, RunState, State,
Viewshed, Viewshed,
}; };
use rltk::{Rltk, TextBlock, VirtualKeyCode, RGB}; use rltk::{Rltk, VirtualKeyCode, RGB};
use specs::prelude::*; use specs::prelude::*;
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) { 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 // Render stats
let combat_stats = ecs.read_storage::<CombatStats>(); let combat_stats = ecs.read_storage::<CombatStats>();
let players = ecs.read_storage::<Player>(); let players = ecs.read_storage::<Player>();
for (_player, stats) in (&players, &combat_stats).join() { for (_player, stats) in (&players, &combat_stats).join() {
let health = format!(" HP {}/{} ", stats.hp, stats.max_hp); 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.print_color_right(36, 45, 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.draw_bar_horizontal(38, 45, 34, stats.hp, stats.max_hp, RGB::named(rltk::RED), RGB::named(rltk::BLACK));
} }
// Render message log // Render the message log at [1, 46], descending, with 6 lines.
let mut block = TextBlock::new(1, 44, 78, 5); gamelog::print_log(&mut rltk::BACKEND_INTERNAL.lock().consoles[0].console, Point::new(1, 46), true, 13);
let _ = block.print(&gamelog::log_display());
block.render(&mut rltk::BACKEND_INTERNAL.lock().consoles[0].console);
// Render depth // Render depth
let map = ecs.fetch::<Map>(); let map = ecs.fetch::<Map>();
let depth = format!(" D{} ", map.depth); 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 // Render turn
ctx.print_color_right( ctx.print_color_right(
78, 78,
49, 59,
RGB::named(rltk::YELLOW), RGB::named(rltk::YELLOW),
RGB::named(rltk::BLACK), RGB::named(rltk::BLACK),
&format!(" T{} ", crate::gamelog::get_event_count("Turn")), &format!(" T{} ", crate::gamelog::get_event_count("Turn")),

View file

@ -27,7 +27,8 @@ impl<'a> System<'a> for ItemCollectionSystem {
if pickup.collected_by == *player_entity { if pickup.collected_by == *player_entity {
gamelog::Logger::new() gamelog::Logger::new()
.append("You pick up the") .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(); .log();
} }
} }
@ -89,7 +90,11 @@ impl<'a> System<'a> for ItemUseSystem {
let is_cursed = cursed_items.get(wants_to_use.item); 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 // TARGETING
let mut targets: Vec<Entity> = Vec::new(); let mut targets: Vec<Entity> = Vec::new();
@ -213,7 +218,8 @@ impl<'a> System<'a> for ItemUseSystem {
.damage(damage.amount) .damage(damage.amount)
.colour(rltk::WHITE) .colour(rltk::WHITE)
.append("damage from the") .append("damage from the")
.item_name(format!("{}.", &item_being_used.name)) .item_name_n(format!("{}", &item_being_used.name))
.period()
.log(); .log();
} }
} }
@ -324,7 +330,8 @@ impl<'a> System<'a> for ItemDropSystem {
if entity == *player_entity { if entity == *player_entity {
gamelog::Logger::new() gamelog::Logger::new()
.append("You drop the") .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(); .log();
} }
} }

View file

@ -368,7 +368,7 @@ impl GameState for State {
} }
const DISPLAYWIDTH: i32 = 80; const DISPLAYWIDTH: i32 = 80;
const DISPLAYHEIGHT: i32 = 50; const DISPLAYHEIGHT: i32 = 60;
fn main() -> rltk::BError { fn main() -> rltk::BError {
use rltk::RltkBuilder; use rltk::RltkBuilder;
@ -436,6 +436,9 @@ fn main() -> rltk::BError {
gamelog::clear_log(); gamelog::clear_log();
gamelog::clear_events(); gamelog::clear_events();
for _ in 0..5 {
gamelog::Logger::new().log();
}
gamelog::Logger::new() gamelog::Logger::new()
.append("Welcome!") .append("Welcome!")
.colour(rltk::CYAN) .colour(rltk::CYAN)

View file

@ -57,7 +57,8 @@ impl<'a> System<'a> for MeleeCombatSystem {
.npc_name(&name.name) .npc_name(&name.name)
.colour(rltk::WHITE) .colour(rltk::WHITE)
.append("hits the") .append("hits the")
.npc_name(format!("{}.", &target_name.name)) .npc_name_n(format!("{}", &target_name.name))
.period()
.log(); .log();
SufferDamage::new_damage(&mut inflict_damage, wants_melee.target, damage); SufferDamage::new_damage(&mut inflict_damage, wants_melee.target, damage);
} }

View file

@ -133,13 +133,13 @@ fn room_table(map_depth: i32) -> RandomTable {
.add("orc", 4 + map_depth) .add("orc", 4 + map_depth)
// Potions // Potions
.add("weak health potion", 4) .add("weak health potion", 4)
.add("health potion", 1 + map_depth) .add("health potion", 1 + (map_depth / 2))
// Scrolls // Scrolls
.add("fireball scroll", 1 + map_depth) .add("fireball scroll", 1 + (map_depth / 3))
.add("cursed fireball scroll", 1) .add("cursed fireball scroll", 1)
.add("confusion scroll", 1) .add("confusion scroll", 2)
.add("magic missile scroll", 4) .add("magic missile scroll", 4)
.add("magic map scroll", 1) .add("magic map scroll", 2)
.add("cursed magic map scroll", 1); .add("cursed magic map scroll", 1);
} }