Refactor game log to allow coloring of messages

This commit is contained in:
Timothy Warren 2022-02-01 09:21:06 -05:00
parent 7e3ceab2a2
commit c3e51d7b06
4 changed files with 120 additions and 37 deletions

View File

@ -1,24 +1,18 @@
/// A struct to hold the player's game log.
#[derive(Default)]
pub struct GameLog {
pub entries: Vec<String>,
}
//! Game Log
//!
//! Where the exploits of the current game are recorded
mod builder;
mod logstore;
impl GameLog {
/// Convenience constructor that adds the first
/// entry to the game log.
pub fn new<S: ToString>(first_entry: S) -> Self {
let mut log = GameLog::default();
log.append(first_entry);
use ::rltk::RGB;
pub use builder::*;
use logstore::*;
pub use logstore::{clear_log, log_display};
log
}
/// Convenience method for adding an entry to the game log.
/// Generic on the [`ToString`] trait so that [`&str`], [`String`],
/// and `&String` types, all work without more type juggling
/// at the call site.
pub fn append<S: ToString>(&mut self, s: S) {
self.entries.push(s.to_string());
}
/// A section of colored text for the game log
pub struct LogFragment {
/// The color of the text
pub color: RGB,
/// The text fragment
pub text: String,
}

63
src/game_log/builder.rs Normal file
View File

@ -0,0 +1,63 @@
use ::rltk::prelude::*;
use super::{append_entry, LogFragment};
use crate::colors;
/// The game log builder - builds one line at a time
pub struct Logger {
current_color: RGB,
fragments: Vec<LogFragment>,
}
/// Convenience method to create a new [`Logger`] and
/// immediately append text
pub fn line<T: ToString>(text: T) -> Logger {
Logger::new().append(text)
}
impl Logger {
pub fn new() -> Self {
Logger {
current_color: colors::WHITE,
fragments: Vec::new(),
}
}
/// Sets the color of text to be added to the current line
pub fn color(mut self, color: RGB) -> Self {
self.current_color = color;
self
}
/// The original [`color`](Logger::color) method, using [`rltk`] color constants
#[allow(dead_code)]
pub fn rltk_color(mut self, color: (u8, u8, u8)) -> Self {
self.current_color = RGB::named(color);
self
}
/// Appends text to the current line of the game log.
/// Generic on the [`ToString`] trait so that [`&str`], [`String`],
/// and `&String` types, all work without more type juggling
/// at the call site.
pub fn append<T: ToString>(mut self, text: T) -> Self {
self.fragments.push(LogFragment {
color: self.current_color,
text: text.to_string(),
});
self
}
/// Convenience method to append text with a new color
pub fn append_color<T: ToString>(mut self, color: RGB, text: T) -> Self {
self.color(color).append(text)
}
/// Append the current line to the log output
pub fn log(self) {
append_entry(self.fragments);
}
}

35
src/game_log/logstore.rs Normal file
View File

@ -0,0 +1,35 @@
use std::sync::Mutex;
use ::rltk::prelude::*;
use super::LogFragment;
lazy_static! {
static ref LOG: Mutex<Vec<Vec<LogFragment>>> = Mutex::new(Vec::new());
}
pub fn append_fragment(fragment: LogFragment) {
LOG.lock().unwrap().push(vec![fragment]);
}
pub fn append_entry(fragments: Vec<LogFragment>) {
LOG.lock().unwrap().push(fragments);
}
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| {
log.iter().for_each(|frag| {
buf.fg(frag.color);
buf.line_wrap(&frag.text);
});
buf.ln();
});
buf
}

View File

@ -4,6 +4,7 @@ mod tooltip;
use std::cmp::Ordering;
use ::rltk::prelude::*;
use ::rltk::{Point, Rltk, RGB};
use ::specs::prelude::*;
pub use enums::*;
@ -15,8 +16,7 @@ use crate::components::{
InBackpack, KnownSpells, MagicItem, MagicItemClass, Name, ObfuscatedName, Pools, StatusEffect,
Viewshed, Weapon,
};
use crate::game_log::GameLog;
use crate::{camera, colors, Map, MasterDungeonMap, State};
use crate::{camera, colors, game_log, Map, MasterDungeonMap, State};
pub fn get_item_color(ecs: &World, item: Entity) -> RGB {
let dm = ecs.fetch::<crate::map::MasterDungeonMap>();
@ -77,8 +77,6 @@ pub fn draw_hollow_box(
fg: RGB,
bg: RGB,
) {
use rltk::to_cp437;
console.set(sx, sy, fg, bg, to_cp437('┌'));
console.set(sx + width, sy, fg, bg, to_cp437('┐'));
console.set(sx, sy + height, fg, bg, to_cp437('└'));
@ -95,8 +93,6 @@ pub fn draw_hollow_box(
}
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
use rltk::to_cp437;
draw_hollow_box(ctx, 0, 0, 79, 59, colors::BOX_GRAY, colors::BLACK); // Overall box
draw_hollow_box(ctx, 0, 0, 49, 45, colors::BOX_GRAY, colors::BLACK); // Map box
draw_hollow_box(ctx, 0, 45, 79, 14, colors::BOX_GRAY, colors::BLACK); // Log box
@ -329,14 +325,9 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
}
// Draw the log
let log = ecs.fetch::<GameLog>();
let mut y = 46;
for s in log.entries.iter().rev() {
if y < 59 {
ctx.print(2, y, s);
}
y += 1;
}
let mut block = TextBlock::new(1, 46, 79, 58);
block.print(&game_log::log_display());
block.render(&mut ::rltk::BACKEND_INTERNAL.lock().consoles[0].console);
draw_tooltips(ecs, ctx);
}