Add methods to log builder to simplify common log entry pieces

This commit is contained in:
Timothy Warren 2022-02-01 11:20:41 -05:00
parent a3f6c7b9d0
commit 21c0601ebd
12 changed files with 92 additions and 58 deletions

View File

@ -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);

View File

@ -18,4 +18,5 @@ pub struct SerializationHelper {
#[derive(Component, Serialize, Deserialize, Clone)]
pub struct DMSerializationHelper {
pub map: MasterDungeonMap,
pub log: Vec<Vec<crate::gamelog::LogFragment>>,
}

View File

@ -18,11 +18,9 @@ pub fn item_trigger(creator: Option<Entity>, item: Entity, targets: &Targets, ec
if let Some(c) = ecs.write_storage::<Consumable>().get_mut(item) {
if c.charges < 1 {
// Cancel
gamelog::color_line(
colors::CYAN,
&ecs.read_storage::<Name>().get(item).unwrap().name,
)
.append_white("is out of charges!")
gamelog::Logger::new()
.item_name(&ecs.read_storage::<Name>().get(item).unwrap().name)
.append("is out of charges!")
.log();
return;
@ -159,7 +157,7 @@ fn event_trigger(
add_effect(creator, EffectType::WellFed, targets.clone());
let names = ecs.read_storage::<Name>();
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;

View File

@ -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,

View File

@ -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<T: ToString>(self, color: RGB, text: T) -> Self {
self.color(color).append(text)
pub fn npc_name<T: ToString>(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<T: ToString>(self, text: T) -> Self {
self.append_color(colors::WHITE, text)
pub fn item_name<T: ToString>(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<T: ToString>(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

View File

@ -34,3 +34,12 @@ pub fn log_display() -> TextBuilder {
buf
}
pub fn clone_log() -> Vec<Vec<LogFragment>> {
LOG.lock().unwrap().clone()
}
pub fn restore_log(log: &mut Vec<Vec<LogFragment>>) {
clear_log();
LOG.lock().unwrap().append(log);
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -43,6 +43,7 @@ pub fn save_game(ecs: &mut World) {
.create_entity()
.with(DMSerializationHelper {
map: dungeon_master,
log: crate::gamelog::clone_log(),
})
.marked::<SimpleMarker<SerializeMe>>()
.build();
@ -298,6 +299,7 @@ pub fn load_game(ecs: &mut World) {
let mut dungeon_master = ecs.write_resource::<MasterDungeonMap>();
*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() {

View File

@ -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();
}