1use std::collections::BTreeMap;
2
3use super::{
4 super::{
5 display::{Grapher, RealmDifference, Timeline},
6 game_data::{GameData, Localizable, LocalizationError},
7 structures::{
8 Artifact, Character, Culture, Dynasty, Faith, FromGameObject, GameObjectDerived,
9 GameObjectEntity, House, Memory, Title,
10 },
11 types::{GameId, GameString, HashMap, Shared, Wrapper, WrapperMut},
12 },
13 game_object::GameObjectMap,
14 ParsingError,
15};
16
17use jomini::common::{Date, PdsDate};
18
19use serde::{ser::SerializeMap, Serialize, Serializer};
20
21pub type GameRef<T> = Shared<GameObjectEntity<T>>;
22
23fn get_or_insert_dummy<T: GameObjectDerived + FromGameObject>(
25 map: &mut HashMap<GameId, GameRef<T>>,
26 key: &GameId,
27) -> GameRef<T> {
28 if let Some(val) = map.get(key) {
29 return val.clone();
30 } else {
31 let v = Shared::wrap(GameObjectEntity::new(*key));
32 map.insert(*key, v.clone());
33 v
34 }
35}
36
37impl Serialize for Shared<Option<GameRef<Character>>> {
38 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39 where
40 S: serde::Serializer,
41 {
42 match self.get_internal().as_ref() {
43 Some(c) => c.serialize(serializer),
44 None => serializer.serialize_none(),
45 }
46 }
47}
48
49fn serialize_ref_map<T: Serialize + GameObjectDerived, S: Serializer>(
50 map: &HashMap<GameId, GameRef<T>>,
51 serializer: S,
52) -> Result<S::Ok, S::Error> {
53 let mut state = serializer.serialize_map(Some(map.len()))?;
54 for (k, v) in map.iter() {
55 state.serialize_entry(k, &*v.get_internal())?;
56 }
57 state.end()
58}
59
60#[derive(Serialize)]
82pub struct GameState {
83 #[serde(serialize_with = "serialize_ref_map")]
85 characters: HashMap<GameId, GameRef<Character>>,
86 #[serde(serialize_with = "serialize_ref_map")]
88 titles: HashMap<GameId, GameRef<Title>>,
89 #[serde(serialize_with = "serialize_ref_map")]
91 faiths: HashMap<GameId, GameRef<Faith>>,
92 #[serde(serialize_with = "serialize_ref_map")]
94 cultures: HashMap<GameId, GameRef<Culture>>,
95 #[serde(serialize_with = "serialize_ref_map")]
97 dynasties: HashMap<GameId, GameRef<Dynasty>>,
98 #[serde(serialize_with = "serialize_ref_map")]
99 houses: HashMap<GameId, GameRef<House>>,
100 #[serde(serialize_with = "serialize_ref_map")]
102 memories: HashMap<GameId, GameRef<Memory>>,
103 #[serde(serialize_with = "serialize_ref_map")]
105 artifacts: HashMap<GameId, GameRef<Artifact>>,
106 traits_lookup: Vec<GameString>,
108 contract_transform: HashMap<GameId, Shared<Option<GameRef<Character>>>>,
110 character_transform: HashMap<GameId, GameId>,
111 #[serde(skip)]
112 county_data: HashMap<String, (GameRef<Faith>, GameRef<Culture>)>,
113 current_date: Option<Date>,
115 offset_date: Option<Date>,
117}
118
119impl Default for GameState {
120 fn default() -> Self {
121 GameState {
122 characters: HashMap::default(),
123 titles: HashMap::default(),
124 faiths: HashMap::default(),
125 cultures: HashMap::default(),
126 dynasties: HashMap::default(),
127 houses: HashMap::default(),
128 memories: HashMap::default(),
129 artifacts: HashMap::default(),
130 traits_lookup: Vec::new(),
131 contract_transform: HashMap::default(),
132 character_transform: HashMap::default(),
133 county_data: HashMap::default(),
134 current_date: None,
135 offset_date: None,
136 }
137 }
138}
139
140impl GameState {
141 pub fn add_lookup(&mut self, array: Vec<GameString>) {
143 self.traits_lookup = array;
144 }
145
146 pub fn add_character_transform(&mut self, transform: HashMap<GameId, GameId>) {
147 self.character_transform = transform;
148 }
149
150 pub fn get_trait(&self, id: u16) -> GameString {
152 self.traits_lookup[id as usize].clone()
153 }
154
155 pub fn set_current_date(&mut self, date: Date, offset: Date) {
157 self.current_date = Some(date);
158 self.offset_date = Some(offset);
159 }
160
161 pub fn get_current_date(&self) -> Option<Date> {
163 return self.current_date;
164 }
165
166 pub fn get_character(&mut self, key: &GameId) -> GameRef<Character> {
168 get_or_insert_dummy(&mut self.characters, key)
169 }
170
171 pub fn get_vassal(&mut self, contract_id: &GameId) -> Shared<Option<GameRef<Character>>> {
173 if let Some(v) = self.contract_transform.get(contract_id) {
174 return v.clone();
175 } else {
176 let v = Shared::wrap(None);
177 self.contract_transform.insert(*contract_id, v.clone());
178 return v;
179 }
180 }
181
182 pub fn add_contract(&mut self, contract_id: &GameId, character_id: &GameId) {
184 let char = self.get_character(character_id);
185 if let Some(contract) = self.contract_transform.get_mut(contract_id) {
186 contract.get_internal_mut().replace(char);
187 } else {
188 self.contract_transform
189 .insert(*contract_id, Shared::wrap(Some(char)));
190 }
191 }
192
193 pub fn get_title(&mut self, key: &GameId) -> GameRef<Title> {
195 get_or_insert_dummy(&mut self.titles, key)
196 }
197
198 pub fn get_faith(&mut self, key: &GameId) -> GameRef<Faith> {
200 get_or_insert_dummy(&mut self.faiths, key)
201 }
202
203 pub fn get_culture(&mut self, key: &GameId) -> GameRef<Culture> {
205 get_or_insert_dummy(&mut self.cultures, key)
206 }
207
208 pub fn get_dynasty(&mut self, key: &GameId) -> GameRef<Dynasty> {
210 get_or_insert_dummy(&mut self.dynasties, key)
211 }
212
213 pub fn get_memory(&mut self, key: &GameId) -> GameRef<Memory> {
215 get_or_insert_dummy(&mut self.memories, key)
216 }
217
218 pub fn get_artifact(&mut self, key: &GameId) -> GameRef<Artifact> {
220 get_or_insert_dummy(&mut self.artifacts, key)
221 }
222
223 pub fn get_house(&mut self, key: &GameId) -> GameRef<House> {
224 get_or_insert_dummy(&mut self.houses, key)
225 }
226
227 pub fn add_house(&mut self, key: &GameId, value: &GameObjectMap) -> Result<(), ParsingError> {
228 self.get_house(key).get_internal_mut().init(value, self)
229 }
230
231 pub fn add_artifact(
232 &mut self,
233 key: &GameId,
234 value: &GameObjectMap,
235 ) -> Result<(), ParsingError> {
236 self.get_artifact(key).get_internal_mut().init(value, self)
237 }
238
239 pub fn add_character(
241 &mut self,
242 key: &GameId,
243 value: &GameObjectMap,
244 ) -> Result<(), ParsingError> {
245 let char = self.get_character(key);
246 char.get_internal_mut().init(value, self)?;
247 if let Some(alt) = self.character_transform.get(key) {
248 if let Some(alt_char) = self.characters.get(alt) {
249 if alt_char.get_internal().inner().is_none() {
250 alt_char
252 .get_internal_mut()
253 .replace(char.get_internal().inner().unwrap().clone());
254 }
255 }
256 }
257 Ok(())
258 }
259
260 pub fn add_title(&mut self, key: &GameId, value: &GameObjectMap) -> Result<(), ParsingError> {
262 self.get_title(key).get_internal_mut().init(value, self)
263 }
264
265 pub fn add_faith(&mut self, key: &GameId, value: &GameObjectMap) -> Result<(), ParsingError> {
267 self.get_faith(key).get_internal_mut().init(value, self)
268 }
269
270 pub fn add_culture(&mut self, key: &GameId, value: &GameObjectMap) -> Result<(), ParsingError> {
272 self.get_culture(key).get_internal_mut().init(value, self)
273 }
274
275 pub fn add_dynasty(&mut self, key: &GameId, value: &GameObjectMap) -> Result<(), ParsingError> {
277 self.get_dynasty(key).get_internal_mut().init(value, self)
278 }
279
280 pub fn add_memory(&mut self, key: &GameId, value: &GameObjectMap) -> Result<(), ParsingError> {
282 self.get_memory(key).get_internal_mut().init(value, self)
283 }
284
285 pub fn get_baronies_of_counties<F: Fn(&Title) -> bool>(&self, filter: F) -> Vec<GameString> {
286 let mut res = Vec::new();
287 for title in self.titles.values() {
288 if let Some(title) = title.get_internal().inner() {
289 if filter(&title) {
290 res.append(&mut title.get_barony_keys());
291 }
292 }
293 }
294 res
295 }
296
297 pub fn add_county_data(
298 &mut self,
299 county_data: HashMap<String, (GameRef<Faith>, GameRef<Culture>)>,
300 ) {
301 self.county_data = county_data;
302 }
303
304 pub fn new_grapher(&self) -> Grapher {
305 let mut total_yearly_deaths: BTreeMap<i16, u32> = BTreeMap::default();
306 let mut faith_yearly_deaths = HashMap::default();
307 let mut culture_yearly_deaths = HashMap::default();
308 let start_year = self.current_date.unwrap().year() - self.offset_date.unwrap().year();
309 for character in self.characters.values() {
310 if let Some(char) = character.get_internal().inner() {
311 if let Some(death_date) = char.get_death_date() {
312 if death_date.year() <= start_year
313 || death_date.year() >= self.current_date.unwrap().year()
314 {
315 continue;
316 }
317 let count = total_yearly_deaths.entry(death_date.year()).or_insert(0);
318 *count += 1;
319 {
320 let entry = faith_yearly_deaths
321 .entry(char.get_faith().as_ref().unwrap().get_internal().get_id())
322 .or_insert(BTreeMap::default());
323 let count = entry.entry(death_date.year()).or_insert(0);
324 *count += 1;
325 }
326 {
327 let entry = culture_yearly_deaths
328 .entry(char.get_culture().as_ref().unwrap().get_internal().get_id())
329 .or_insert(BTreeMap::default());
330 let count = entry.entry(death_date.year()).or_insert(0);
331 *count += 1;
332 }
333 }
334 }
335 }
336 Grapher::new(
337 faith_yearly_deaths,
338 culture_yearly_deaths,
339 total_yearly_deaths,
340 )
341 }
342
343 pub fn new_timeline(&self) -> Timeline {
344 const DESTROYED_STR: &str = "destroyed";
345 const USURPED_STR: &str = "usurped";
346 const CONQUERED_START_STR: &str = "conq"; let mut lifespans = Vec::new();
349 let mut latest_event = 0;
350 let mut event_checkout = Vec::new();
351 for title in self.titles.values() {
352 if let Some(t) = title.get_internal().inner() {
354 let hist = t.get_history_iter();
355 if hist.len() == 0 {
356 continue;
357 }
358 let k = t.get_key();
359 let kingdom = k.as_ref().starts_with("k_");
361 if kingdom {
362 event_checkout.push(title.clone());
363 continue;
365 }
366 let empire = k.as_ref().starts_with("e_");
367 if !empire {
368 continue;
369 }
370 event_checkout.push(title.clone());
371 event_checkout.push(t.get_capital().unwrap().clone());
372 let mut item = (title.clone(), Vec::new());
373 let mut empty = true;
374 let mut start = 0;
375 for entry in hist {
376 let yr = entry.0.year();
377 if yr > latest_event {
378 latest_event = yr;
379 }
380 let event = entry.2.as_ref();
381 if event == DESTROYED_STR {
382 item.1.push((start, yr));
384 empty = true;
385 } else if empty {
386 start = yr;
388 empty = false;
389 }
390 }
391 if empire {
392 if !empty {
393 item.1.push((start, 0));
394 }
395 lifespans.push(item);
397 }
398 }
399 }
400 let mut events: Vec<(
401 i16,
402 GameRef<Character>,
403 GameRef<Title>,
404 GameString,
405 RealmDifference,
406 )> = Vec::new();
407 for title in event_checkout {
408 if let Some(tit) = title.get_internal().inner() {
409 let mut hist = tit.get_history_iter().skip_while(|a| a.1.is_none());
411 let next = hist.next();
412 if next.is_none() {
413 continue;
414 }
415 if let Some(first_char) = next.unwrap().1.as_ref().unwrap().get_internal().inner() {
416 let mut faith = first_char
417 .get_faith()
418 .as_ref()
419 .unwrap()
420 .get_internal()
421 .get_id();
422 let mut culture = first_char
423 .get_culture()
424 .as_ref()
425 .unwrap()
426 .get_internal()
427 .get_id();
428 for entry in hist {
429 let char = entry.1.as_ref();
430 if char.is_none() {
431 continue;
432 }
433 let char = char.unwrap();
434 let event = entry.2.as_ref();
435 if let Some(ch) = char.get_internal().inner() {
436 let char_faith = ch.get_faith().as_ref().unwrap().clone();
437 let ch_faith = char_faith.get_internal();
438 let char_culture = ch.get_culture().as_ref().unwrap().clone();
439 let ch_culture = char_culture.get_internal();
440 if event == USURPED_STR || event.starts_with(CONQUERED_START_STR) {
441 let year: i16 = entry.0.year();
442 if ch_faith.get_id() != faith {
443 events.push((
444 year,
445 char.clone(),
446 title.clone(),
447 GameString::from("faith"),
448 RealmDifference::Faith(char_faith.clone()),
449 ));
450 faith = ch_faith.get_id();
451 } else if ch_culture.get_id() != culture {
452 events.push((
453 year,
454 char.clone(),
455 title.clone(),
456 GameString::from("people"),
457 RealmDifference::Culture(char_culture.clone()),
458 ));
459 culture = ch_culture.get_id();
460 }
461 } else {
462 if ch_faith.get_id() != faith {
463 faith = ch_faith.get_id();
464 }
465 if ch_culture.get_id() != culture {
466 culture = ch_culture.get_id();
467 }
468 }
469 }
470 }
471 }
472 }
473 }
474 events.sort_by(|a, b| a.0.cmp(&b.0));
475 return Timeline::new(lifespans, self.current_date.unwrap().year(), events);
476 }
477}
478
479impl Localizable for GameState {
480 fn localize(&mut self, localization: &GameData) -> Result<(), LocalizationError> {
481 for character in self.characters.values_mut() {
482 character.localize(localization)?;
483 }
484 for title in &mut self.titles.values_mut() {
485 title.localize(localization)?;
486 if let Some(internal) = title.get_internal_mut().inner_mut() {
487 if let Some(assoc) = self.county_data.get_mut(internal.get_key().as_ref()) {
488 if let Title::County { faith, culture, .. } = internal {
489 *faith = Some(assoc.0.clone());
490 *culture = Some(assoc.1.clone());
491 }
492 }
493 }
494 }
495 for faith in &mut self.faiths.values_mut() {
496 faith.localize(localization)?;
497 }
498 for culture in &mut self.cultures.values_mut() {
499 culture.localize(localization)?;
500 }
501 for house in &mut self.houses.values_mut() {
502 house.localize(localization)?;
503 }
504 for dynasty in &mut self.dynasties.values_mut() {
505 dynasty.localize(localization)?;
506 }
507 for memory in &mut self.memories.values_mut() {
508 memory.localize(localization)?;
509 }
510 for artifact in &mut self.artifacts.values_mut() {
511 artifact.localize(localization)?;
512 }
513 Ok(())
514 }
515}
516
517#[cfg(test)]
518mod tests {
519
520 use super::*;
521
522 #[test]
523 fn test_get_or_insert_dummy() {
524 let mut map = HashMap::default();
525 let key = 1;
526 let val = get_or_insert_dummy::<Artifact>(&mut map, &key);
527 assert_eq!(val.get_internal().get_id(), key);
528 let val2 = get_or_insert_dummy(&mut map, &key);
529 assert_eq!(val.get_internal().get_id(), val2.get_internal().get_id());
530 }
531}