From 21c0601ebdbed547e97f44c8ab62f24eb30c306c Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 1 Feb 2022 11:20:41 -0500 Subject: [PATCH] Add methods to log builder to simplify common log entry pieces --- src/ai/quipping.rs | 9 ++--- src/components/serialize.rs | 1 + src/effects/triggers.rs | 12 +++---- src/gamelog.rs | 4 ++- src/gamelog/builder.rs | 48 +++++++++++++++++++-------- src/gamelog/logstore.rs | 9 +++++ src/inventory_system/equip_use.rs | 15 ++++----- src/inventory_system/remove_system.rs | 6 ++-- src/melee_combat_system.rs | 21 ++++++------ src/ranged_combat_system.rs | 21 ++++++------ src/saveload_system.rs | 2 ++ src/trigger_system.rs | 2 +- 12 files changed, 92 insertions(+), 58 deletions(-) diff --git a/src/ai/quipping.rs b/src/ai/quipping.rs index 4576d4f..51705cd 100644 --- a/src/ai/quipping.rs +++ b/src/ai/quipping.rs @@ -2,7 +2,7 @@ use ::rltk::{Point, RandomNumberGenerator}; use ::specs::prelude::*; use crate::components::{MyTurn, Name, Quips, Viewshed}; -use crate::{colors, gamelog}; +use crate::gamelog; pub struct QuipSystem {} @@ -31,9 +31,10 @@ impl<'a> System<'a> for QuipSystem { (rng.roll_dice(1, quip.available.len() as i32) - 1) as usize }; - gamelog::color_line(colors::YELLOW, &name.name) - .append_white("says") - .append_color(colors::CYAN, &quip.available[quip_index]) + gamelog::Logger::new() + .npc_name(&name.name) + .append("says") + .npc_name(&quip.available[quip_index]) .log(); quip.available.remove(quip_index); diff --git a/src/components/serialize.rs b/src/components/serialize.rs index 450366d..46dbe26 100644 --- a/src/components/serialize.rs +++ b/src/components/serialize.rs @@ -18,4 +18,5 @@ pub struct SerializationHelper { #[derive(Component, Serialize, Deserialize, Clone)] pub struct DMSerializationHelper { pub map: MasterDungeonMap, + pub log: Vec>, } diff --git a/src/effects/triggers.rs b/src/effects/triggers.rs index 612ed67..2d3d893 100644 --- a/src/effects/triggers.rs +++ b/src/effects/triggers.rs @@ -18,12 +18,10 @@ pub fn item_trigger(creator: Option, item: Entity, targets: &Targets, ec if let Some(c) = ecs.write_storage::().get_mut(item) { if c.charges < 1 { // Cancel - gamelog::color_line( - colors::CYAN, - &ecs.read_storage::().get(item).unwrap().name, - ) - .append_white("is out of charges!") - .log(); + gamelog::Logger::new() + .item_name(&ecs.read_storage::().get(item).unwrap().name) + .append("is out of charges!") + .log(); return; } else { @@ -159,7 +157,7 @@ fn event_trigger( add_effect(creator, EffectType::WellFed, targets.clone()); let names = ecs.read_storage::(); gamelog::line("You eat the") - .append_color(colors::CYAN, &names.get(entity).unwrap().name) + .item_name(&names.get(entity).unwrap().name) .log(); did_something = true; diff --git a/src/gamelog.rs b/src/gamelog.rs index e397824..9b85008 100644 --- a/src/gamelog.rs +++ b/src/gamelog.rs @@ -5,11 +5,13 @@ mod builder; mod logstore; use ::rltk::RGB; +use ::serde::{Deserialize, Serialize}; pub use builder::*; use logstore::*; -pub use logstore::{clear_log, log_display}; +pub use logstore::{clear_log, clone_log, log_display, restore_log}; /// A section of colored text for the game log +#[derive(Serialize, Deserialize, Clone)] pub struct LogFragment { /// The color of the text pub color: RGB, diff --git a/src/gamelog/builder.rs b/src/gamelog/builder.rs index bcfd68a..6f33534 100644 --- a/src/gamelog/builder.rs +++ b/src/gamelog/builder.rs @@ -40,20 +40,13 @@ impl Logger { } /// Sets the color of text to be added to the current line + #[allow(dead_code)] 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 @@ -67,14 +60,41 @@ impl Logger { self } - /// Convenience method to append text with a new color - pub fn append_color(self, color: RGB, text: T) -> Self { - self.color(color).append(text) + pub fn npc_name(mut self, text: T) -> Self { + self.fragments.push(LogFragment { + color: colors::YELLOW, + text: text.to_string(), + }); + + self } - /// Convenience method to append white text after the text has had a different color - pub fn append_white(self, text: T) -> Self { - self.append_color(colors::WHITE, text) + pub fn item_name(mut self, text: T) -> Self { + self.fragments.push(LogFragment { + color: colors::CYAN, + text: text.to_string(), + }); + + self + } + + pub fn damage(mut self, damage: i32) -> Self { + self.fragments.push(LogFragment { + color: colors::RED, + text: format!("{}", damage).to_string(), + }); + + self + } + + /// Convenience method to append text with a new color + pub fn append_color(mut self, color: RGB, text: T) -> Self { + self.fragments.push(LogFragment { + color, + text: text.to_string(), + }); + + self } /// Append the current line to the log output diff --git a/src/gamelog/logstore.rs b/src/gamelog/logstore.rs index fe6322f..47bcdd1 100644 --- a/src/gamelog/logstore.rs +++ b/src/gamelog/logstore.rs @@ -34,3 +34,12 @@ pub fn log_display() -> TextBuilder { buf } + +pub fn clone_log() -> Vec> { + LOG.lock().unwrap().clone() +} + +pub fn restore_log(log: &mut Vec>) { + clear_log(); + LOG.lock().unwrap().append(log); +} diff --git a/src/inventory_system/equip_use.rs b/src/inventory_system/equip_use.rs index d3c0643..46fd774 100644 --- a/src/inventory_system/equip_use.rs +++ b/src/inventory_system/equip_use.rs @@ -4,7 +4,7 @@ use crate::components::{ CursedItem, EquipmentChanged, Equippable, Equipped, IdentifiedItem, InBackpack, Name, WantsToUseItem, }; -use crate::{colors, gamelog}; +use crate::gamelog; pub struct ItemEquipOnUse {} @@ -51,14 +51,14 @@ impl<'a> System<'a> for ItemEquipOnUse { if already_equipped.owner == target && already_equipped.slot == target_slot { if cursed.get(item_entity).is_some() { gamelog::line("You cannot un-equip") - .append_color(colors::CYAN, &name.name) - .append_white("- it is cursed!") + .item_name(&name.name) + .append("- it is cursed!") .log(); can_equip = false; } else { to_unequip.push(item_entity); if target == *player_entity { - gamelog::log_line(format!("You un-equip {}.", name.name)); + gamelog::line("You un-equip").item_name(&name.name).log(); } } } @@ -96,10 +96,9 @@ impl<'a> System<'a> for ItemEquipOnUse { .expect("Unable to equip item"); backpack.remove(useitem.item); if target == *player_entity { - gamelog::log_line(format!( - "You equip {}.", - names.get(useitem.item).unwrap().name - )); + gamelog::line("You equip") + .item_name(&names.get(useitem.item).unwrap().name) + .log(); } } diff --git a/src/inventory_system/remove_system.rs b/src/inventory_system/remove_system.rs index d48b629..567a1b3 100644 --- a/src/inventory_system/remove_system.rs +++ b/src/inventory_system/remove_system.rs @@ -1,7 +1,7 @@ use ::specs::prelude::*; use crate::components::{CursedItem, Equipped, InBackpack, Name, WantsToRemoveItem}; -use crate::{colors, gamelog}; +use crate::gamelog; pub struct ItemRemoveSystem {} @@ -22,8 +22,8 @@ impl<'a> System<'a> for ItemRemoveSystem { for (entity, to_remove) in (&entities, &wants_remove).join() { if cursed.get(to_remove.item).is_some() { gamelog::line("You cannot remove") - .append_color(colors::CYAN, &names.get(to_remove.item).unwrap().name) - .append_white(" - it is cursed.") + .item_name(&names.get(to_remove.item).unwrap().name) + .append(" - it is cursed.") .log(); continue; diff --git a/src/melee_combat_system.rs b/src/melee_combat_system.rs index 0bb0787..965936e 100644 --- a/src/melee_combat_system.rs +++ b/src/melee_combat_system.rs @@ -160,12 +160,13 @@ impl<'a> System<'a> for MeleeCombatSystem { target: wants_melee.target, }, ); - gamelog::color_line(colors::YELLOW, &name.name) - .append_white("hits") - .append_color(colors::YELLOW, &target_name.name) - .append_white("for") - .append_color(colors::RED, format!("{}", damage)) - .append_white("hp.") + gamelog::Logger::new() + .npc_name(&name.name) + .append("hits") + .npc_name(&target_name.name) + .append("for") + .damage(damage) + .append("hp.") .log(); // Proc effects @@ -190,9 +191,9 @@ impl<'a> System<'a> for MeleeCombatSystem { } else if natural_roll == 1 { // Natural 1 miss gamelog::color_line(colors::CYAN, &name.name) - .append_white("considers attacking") + .append("considers attacking") .append_color(colors::CYAN, &target_name.name) - .append_white("but misjudges the timing!") + .append("but misjudges the timing!") .log(); add_effect( None, @@ -209,9 +210,9 @@ impl<'a> System<'a> for MeleeCombatSystem { } else { // Miss gamelog::color_line(colors::CYAN, &name.name) - .append_white("attacks") + .append("attacks") .append_color(colors::CYAN, &target_name.name) - .append_white("but can't connect.") + .append("but can't connect.") .log(); add_effect( None, diff --git a/src/ranged_combat_system.rs b/src/ranged_combat_system.rs index 4f19e89..dd315ba 100644 --- a/src/ranged_combat_system.rs +++ b/src/ranged_combat_system.rs @@ -185,12 +185,13 @@ impl<'a> System<'a> for RangedCombatSystem { target: wants_shoot.target, }, ); - gamelog::color_line(colors::YELLOW, &name.name) - .append_white("hits") - .append_color(colors::YELLOW, &target_name.name) - .append_white("for") - .append_color(colors::RED, format!("{}", damage)) - .append_white("hp.") + gamelog::Logger::new() + .npc_name(&name.name) + .append("hits") + .npc_name(&target_name.name) + .append("for") + .damage(damage) + .append("hp.") .log(); // Proc effects if let Some(chance) = &weapon_info.proc_chance { @@ -214,9 +215,9 @@ impl<'a> System<'a> for RangedCombatSystem { } else if natural_roll == 1 { // Natural 1 miss gamelog::color_line(colors::CYAN, &name.name) - .append_white("considers attacking") + .append("considers attacking") .append_color(colors::CYAN, &target_name.name) - .append_white("but misjudges the timing!") + .append("but misjudges the timing!") .log(); add_effect( None, @@ -233,9 +234,9 @@ impl<'a> System<'a> for RangedCombatSystem { } else { // Miss gamelog::color_line(colors::CYAN, &name.name) - .append_white("attacks") + .append("attacks") .append_color(colors::CYAN, &target_name.name) - .append_white("but can't connect.") + .append("but can't connect.") .log(); add_effect( None, diff --git a/src/saveload_system.rs b/src/saveload_system.rs index f08055c..ddfff4a 100644 --- a/src/saveload_system.rs +++ b/src/saveload_system.rs @@ -43,6 +43,7 @@ pub fn save_game(ecs: &mut World) { .create_entity() .with(DMSerializationHelper { map: dungeon_master, + log: crate::gamelog::clone_log(), }) .marked::>() .build(); @@ -298,6 +299,7 @@ pub fn load_game(ecs: &mut World) { let mut dungeon_master = ecs.write_resource::(); *dungeon_master = h.map.clone(); deleteme2 = Some(e); + crate::gamelog::restore_log(&mut h.log.clone()); } for (e, _p, pos) in (&entities, &player, &position).join() { diff --git a/src/trigger_system.rs b/src/trigger_system.rs index 78b850c..5312134 100644 --- a/src/trigger_system.rs +++ b/src/trigger_system.rs @@ -35,7 +35,7 @@ impl<'a> System<'a> for TriggerSystem { // We triggered it if let Some(name) = names.get(entity_id) { gamelog::color_line(colors::RED, &name.name) - .append_white("triggers!") + .append("triggers!") .log(); }