144 lines
5.2 KiB
Rust
144 lines
5.2 KiB
Rust
use std::collections::{ HashSet, HashMap };
|
|
use std::sync::Mutex;
|
|
use crate::data::events::EVENT;
|
|
use crate::data::names::*;
|
|
|
|
lazy_static! {
|
|
/// A count of each event that has happened over the run. i.e. "turns", "descended", "ascended"
|
|
static ref EVENT_COUNTER: Mutex<HashMap<String, i32>> = Mutex::new(HashMap::new());
|
|
// A record of events that happened on a given turn. i.e. "Advanced to level 2".
|
|
pub static ref EVENTS: Mutex<HashMap<u32, Vec<String>>> = Mutex::new(HashMap::new());
|
|
// A record of floors visited, and monsters killed. Used to determine if an event is significant.
|
|
static ref VISITED: Mutex<HashSet<String>> = Mutex::new({
|
|
let mut set = HashSet::new();
|
|
set.insert(NAME_OVERMAP.to_string());
|
|
set
|
|
});
|
|
static ref KILLED: Mutex<HashSet<String>> = Mutex::new(HashSet::new());
|
|
}
|
|
|
|
/// Makes a copy of event counts (FOR SERIALIZATION)
|
|
pub fn clone_event_counts() -> HashMap<String, i32> {
|
|
EVENT_COUNTER.lock().unwrap().clone()
|
|
}
|
|
/// Makes a copy of events (FOR SERIALIZATION)
|
|
pub fn clone_events() -> HashMap<u32, Vec<String>> {
|
|
EVENTS.lock().unwrap().clone()
|
|
}
|
|
/// Fetches event counter into mutex (FOR DESERIALIZATION)
|
|
pub fn restore_event_counter(events: HashMap<String, i32>) {
|
|
EVENT_COUNTER.lock().unwrap().clear();
|
|
events.iter().for_each(|(k, v)| {
|
|
EVENT_COUNTER.lock().unwrap().insert(k.to_string(), *v);
|
|
});
|
|
}
|
|
/// Fetches events into mutex (FOR DESERIALIZATION)
|
|
pub fn restore_events(events: HashMap<u32, Vec<String>>) {
|
|
EVENTS.lock().unwrap().clear();
|
|
events.iter().for_each(|(k, v)| {
|
|
EVENTS.lock().unwrap().insert(*k, v.to_vec());
|
|
});
|
|
}
|
|
/// Wipes all events - for starting a new game.
|
|
pub fn clear_events() {
|
|
EVENT_COUNTER.lock().unwrap().clear();
|
|
EVENTS.lock().unwrap().clear();
|
|
}
|
|
|
|
#[allow(unused_mut)]
|
|
/// Increments the event counter by n for a given event.
|
|
fn modify_event_count<T: ToString>(event: T, n: i32) {
|
|
let event_name = event.to_string();
|
|
let mut events_lock = EVENT_COUNTER.lock();
|
|
let mut events = events_lock.as_mut().unwrap();
|
|
if let Some(e) = events.get_mut(&event_name) {
|
|
*e += n;
|
|
} else {
|
|
events.insert(event_name, n);
|
|
}
|
|
}
|
|
/// Returns how many times an event has taken place.
|
|
pub fn get_event_count<T: ToString>(event: T) -> i32 {
|
|
let event_name = event.to_string();
|
|
let events_lock = EVENT_COUNTER.lock();
|
|
let events = events_lock.unwrap();
|
|
if let Some(e) = events.get(&event_name) {
|
|
*e
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
/// Records an event on the current turn.
|
|
pub fn record_event(event: EVENT) {
|
|
let mut new_event: String = "unknown event".to_string();
|
|
let mut significant_event = true;
|
|
match event {
|
|
EVENT::TURN(n) => {
|
|
modify_event_count(EVENT::COUNT_TURN, n);
|
|
significant_event = false;
|
|
}
|
|
// If de-levelling is ever implemented, this needs refactoring (along with a lot of stuff).
|
|
EVENT::LEVEL(n) => {
|
|
modify_event_count(EVENT::COUNT_LEVEL, n);
|
|
let new_lvl = get_event_count(EVENT::COUNT_LEVEL);
|
|
if new_lvl == 1 {
|
|
new_event = format!("You embarked on your first adventure!");
|
|
} else {
|
|
new_event = format!("Advanced to level {}", new_lvl);
|
|
}
|
|
}
|
|
EVENT::CHANGED_FLOOR(n) => {
|
|
modify_event_count(EVENT::COUNT_CHANGED_FLOOR, 1);
|
|
if VISITED.lock().unwrap().contains(&n) {
|
|
significant_event = false;
|
|
} else {
|
|
VISITED.lock().unwrap().insert(n.clone());
|
|
new_event = format!("Visited {} for the first time", n);
|
|
}
|
|
}
|
|
EVENT::KICKED_SOMETHING(n) => {
|
|
modify_event_count(EVENT::COUNT_KICK, n);
|
|
significant_event = false;
|
|
}
|
|
EVENT::BROKE_DOOR(n) => {
|
|
modify_event_count(EVENT::COUNT_BROKE_DOOR, n);
|
|
significant_event = false;
|
|
}
|
|
EVENT::PLAYER_CONFUSED(n) => {
|
|
modify_event_count(EVENT::COUNT_PLAYER_CONFUSED, n);
|
|
significant_event = false;
|
|
}
|
|
EVENT::LOOKED_FOR_HELP(n) => {
|
|
modify_event_count(EVENT::COUNT_LOOKED_FOR_HELP, n);
|
|
significant_event = false;
|
|
}
|
|
EVENT::KILLED(name) => {
|
|
modify_event_count(EVENT::COUNT_KILLED, 1);
|
|
if KILLED.lock().unwrap().contains(&name) {
|
|
significant_event = false;
|
|
} else {
|
|
KILLED.lock().unwrap().insert(name.clone());
|
|
new_event = format!("Killed your first {}", name);
|
|
}
|
|
}
|
|
EVENT::DISCOVERED(name) => {
|
|
new_event = format!("Discovered {}", name);
|
|
}
|
|
EVENT::IDENTIFIED(name) => {
|
|
new_event = format!("Identified {}", name);
|
|
}
|
|
EVENT::PLAYER_DIED(str) => {
|
|
// Generating the String is handled in the death effect, to avoid passing the ecs here.
|
|
new_event = format!("{}", str);
|
|
}
|
|
}
|
|
|
|
if significant_event {
|
|
EVENTS.lock()
|
|
.as_mut()
|
|
.unwrap()
|
|
.entry(get_event_count(EVENT::COUNT_TURN) as u32)
|
|
.or_insert_with(Vec::new)
|
|
.push(new_event);
|
|
}
|
|
}
|