Add event counting to game log, completing section 5.29
This commit is contained in:
parent
21c0601ebd
commit
83cab40c13
@ -1,3 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ::serde::{Deserialize, Serialize};
|
||||
use ::specs::prelude::*;
|
||||
use ::specs_derive::*;
|
||||
@ -19,4 +21,5 @@ pub struct SerializationHelper {
|
||||
pub struct DMSerializationHelper {
|
||||
pub map: MasterDungeonMap,
|
||||
pub log: Vec<Vec<crate::gamelog::LogFragment>>,
|
||||
pub events: HashMap<String, i32>,
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ use crate::{colors, gamelog, EquipmentChanged, Map, StatusEffect};
|
||||
|
||||
pub fn inflict_damage(ecs: &mut World, damage: &EffectSpawner, target: Entity) {
|
||||
let mut pools = ecs.write_storage::<Pools>();
|
||||
let player_entity = ecs.fetch::<Entity>();
|
||||
if let Some(pool) = pools.get_mut(target) {
|
||||
if !pool.god_mode {
|
||||
if let Some(creator) = damage.creator {
|
||||
@ -31,6 +32,14 @@ pub fn inflict_damage(ecs: &mut World, damage: &EffectSpawner, target: Entity) {
|
||||
},
|
||||
Targets::Single { target },
|
||||
);
|
||||
if target == *player_entity {
|
||||
gamelog::record_event("Damage Taken", amount);
|
||||
}
|
||||
if let Some(creator) = damage.creator {
|
||||
if creator == *player_entity {
|
||||
gamelog::record_event("Damage Inflicted", amount);
|
||||
}
|
||||
}
|
||||
|
||||
if pool.hit_points.current < 1 {
|
||||
add_effect(
|
||||
|
@ -2,11 +2,13 @@
|
||||
//!
|
||||
//! Where the exploits of the current game are recorded
|
||||
mod builder;
|
||||
mod events;
|
||||
mod logstore;
|
||||
|
||||
use ::rltk::RGB;
|
||||
use ::serde::{Deserialize, Serialize};
|
||||
pub use builder::*;
|
||||
pub use events::*;
|
||||
use logstore::*;
|
||||
pub use logstore::{clear_log, clone_log, log_display, restore_log};
|
||||
|
||||
|
@ -81,7 +81,7 @@ impl Logger {
|
||||
pub fn damage(mut self, damage: i32) -> Self {
|
||||
self.fragments.push(LogFragment {
|
||||
color: colors::RED,
|
||||
text: format!("{}", damage).to_string(),
|
||||
text: format!("{}", damage),
|
||||
});
|
||||
|
||||
self
|
||||
|
43
src/gamelog/events.rs
Normal file
43
src/gamelog/events.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
lazy_static! {
|
||||
static ref EVENTS: Mutex<HashMap<String, i32>> = Mutex::new(HashMap::new());
|
||||
}
|
||||
|
||||
pub fn clear_events() {
|
||||
EVENTS.lock().unwrap().clear();
|
||||
}
|
||||
|
||||
pub fn record_event<T: ToString>(event: T, n: i32) {
|
||||
let event_name = event.to_string();
|
||||
let mut events_lock = EVENTS.lock();
|
||||
let events = events_lock.as_mut().unwrap();
|
||||
if let Some(e) = events.get_mut(&event_name) {
|
||||
*e += n;
|
||||
} else {
|
||||
events.insert(event_name, n);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_event_count<T: ToString>(event: T) -> i32 {
|
||||
let event_name = event.to_string();
|
||||
let events_lock = EVENTS.lock();
|
||||
let events = events_lock.unwrap();
|
||||
if let Some(e) = events.get(&event_name) {
|
||||
*e
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_events() -> HashMap<String, i32> {
|
||||
EVENTS.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn load_events(events: HashMap<String, i32>) {
|
||||
clear_events();
|
||||
events.iter().for_each(|(k, v)| {
|
||||
EVENTS.lock().unwrap().insert(k.to_string(), *v);
|
||||
});
|
||||
}
|
53
src/gui.rs
53
src/gui.rs
@ -421,3 +421,56 @@ pub fn ranged_target(
|
||||
|
||||
(ItemMenuResult::NoResponse, None)
|
||||
}
|
||||
|
||||
pub fn game_over(ctx: &mut Rltk) -> GameOverResult {
|
||||
ctx.print_color_centered(15, colors::YELLOW, colors::BLACK, "Your journey has ended!");
|
||||
ctx.print_color_centered(
|
||||
17,
|
||||
colors::WHITE,
|
||||
colors::BLACK,
|
||||
"One day, we'll tell you all about how you did.",
|
||||
);
|
||||
ctx.print_color_centered(
|
||||
18,
|
||||
colors::WHITE,
|
||||
colors::BLACK,
|
||||
"That day, sadly, is not in this chapter...",
|
||||
);
|
||||
|
||||
ctx.print_color_centered(
|
||||
19,
|
||||
colors::WHITE,
|
||||
colors::BLACK,
|
||||
format!("You lived for {} turns.", gamelog::get_event_count("Turn")),
|
||||
);
|
||||
ctx.print_color_centered(
|
||||
20,
|
||||
colors::RED,
|
||||
colors::BLACK,
|
||||
&format!(
|
||||
"You suffered {} points of damage.",
|
||||
gamelog::get_event_count("Damage Taken")
|
||||
),
|
||||
);
|
||||
ctx.print_color_centered(
|
||||
21,
|
||||
colors::RED,
|
||||
colors::BLACK,
|
||||
&format!(
|
||||
"You inflicted {} points of damage.",
|
||||
gamelog::get_event_count("Damage Inflicted")
|
||||
),
|
||||
);
|
||||
|
||||
ctx.print_color_centered(
|
||||
23,
|
||||
colors::MAGENTA,
|
||||
colors::BLACK,
|
||||
"Press any key to return to the menu.",
|
||||
);
|
||||
|
||||
match ctx.key {
|
||||
None => GameOverResult::NoSelection,
|
||||
Some(_) => GameOverResult::QuitToMenu,
|
||||
}
|
||||
}
|
||||
|
@ -336,34 +336,6 @@ pub fn main_menu(gs: &mut State, ctx: &mut Rltk) -> MainMenuResult {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn game_over(ctx: &mut Rltk) -> GameOverResult {
|
||||
ctx.print_color_centered(15, colors::YELLOW, colors::BLACK, "Your journey has ended!");
|
||||
ctx.print_color_centered(
|
||||
17,
|
||||
colors::WHITE,
|
||||
colors::BLACK,
|
||||
"One day, we'll tell you all about how you did.",
|
||||
);
|
||||
ctx.print_color_centered(
|
||||
18,
|
||||
colors::WHITE,
|
||||
colors::BLACK,
|
||||
"That day, sadly, is not in this chapter...",
|
||||
);
|
||||
|
||||
ctx.print_color_centered(
|
||||
20,
|
||||
colors::MAGENTA,
|
||||
colors::BLACK,
|
||||
"Press any key to return to the menu.",
|
||||
);
|
||||
|
||||
match ctx.key {
|
||||
None => GameOverResult::NoSelection,
|
||||
Some(_) => GameOverResult::QuitToMenu,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn show_cheat_mode(_gs: &mut State, ctx: &mut Rltk) -> CheatMenuResult {
|
||||
let count = 4;
|
||||
let mut y = (25 - (count / 2)) as i32;
|
||||
|
12
src/main.rs
12
src/main.rs
@ -164,6 +164,8 @@ fn register_components(state: &mut State) {
|
||||
/// * Creates the [`Player`](crate::spawner::player)
|
||||
/// * Generates the first [`map`](crate::state::State::generate_world_map)
|
||||
fn init_state() -> State {
|
||||
use ::rltk::{Point, RandomNumberGenerator};
|
||||
|
||||
let mut state = State::new();
|
||||
|
||||
register_components(&mut state);
|
||||
@ -176,8 +178,8 @@ fn init_state() -> State {
|
||||
|
||||
state.ecs.insert(MasterDungeonMap::new());
|
||||
state.ecs.insert(Map::new(1, 64, 64, "New Map"));
|
||||
state.ecs.insert(::rltk::Point::zero());
|
||||
state.ecs.insert(::rltk::RandomNumberGenerator::new());
|
||||
state.ecs.insert(Point::zero());
|
||||
state.ecs.insert(RandomNumberGenerator::new());
|
||||
|
||||
let player_entity = spawner::player(&mut state.ecs, 0, 0);
|
||||
state.ecs.insert(player_entity);
|
||||
@ -193,10 +195,12 @@ fn init_state() -> State {
|
||||
|
||||
/// The entry point
|
||||
fn main() -> ::rltk::BError {
|
||||
let context = ::rltk::RltkBuilder::simple(80, 60)
|
||||
use ::rltk::{main_loop, RltkBuilder};
|
||||
|
||||
let context = RltkBuilder::simple(80, 60)
|
||||
.unwrap()
|
||||
.with_title("Roguelike Tutorial")
|
||||
.build()?;
|
||||
|
||||
::rltk::main_loop(context, init_state())
|
||||
main_loop(context, init_state())
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ pub fn save_game(ecs: &mut World) {
|
||||
.with(DMSerializationHelper {
|
||||
map: dungeon_master,
|
||||
log: crate::gamelog::clone_log(),
|
||||
events: crate::gamelog::clone_events(),
|
||||
})
|
||||
.marked::<SimpleMarker<SerializeMe>>()
|
||||
.build();
|
||||
@ -300,6 +301,7 @@ pub fn load_game(ecs: &mut World) {
|
||||
*dungeon_master = h.map.clone();
|
||||
deleteme2 = Some(e);
|
||||
crate::gamelog::restore_log(&mut h.log.clone());
|
||||
crate::gamelog::load_events(h.events.clone());
|
||||
}
|
||||
|
||||
for (e, _p, pos) in (&entities, &player, &position).join() {
|
||||
|
@ -169,6 +169,8 @@ impl State {
|
||||
gamelog::line("Welcome to")
|
||||
.append_color(colors::CYAN, "Rusty Roguelike")
|
||||
.log();
|
||||
|
||||
gamelog::clear_events();
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,6 +221,9 @@ impl GameState for State {
|
||||
}
|
||||
RunState::AwaitingInput => {
|
||||
newrunstate = player_input(self, ctx);
|
||||
if newrunstate != RunState::AwaitingInput {
|
||||
crate::gamelog::record_event("Turn", 1);
|
||||
}
|
||||
}
|
||||
RunState::Ticking => {
|
||||
let mut should_change_target = false;
|
||||
|
Loading…
Reference in New Issue
Block a user