ck3_history_extractor/structures/
lineage.rs1use jomini::common::Date;
2use serde::{ser::SerializeStruct, Serialize};
3
4use super::{
5 super::{
6 game_data::{GameData, Localizable, LocalizationError, Localize},
7 parser::{GameObjectMap, GameObjectMapping, GameState, ParsingError, SaveFileValue},
8 types::{GameString, Wrapper},
9 },
10 Character, EntityRef, FromGameObject, GameObjectDerived, GameRef,
11};
12
13pub struct LineageNode {
15 character: GameRef<Character>,
16 date: Date,
17 score: i32,
18 prestige: i32,
19 piety: i32,
20 dread: f32,
21 lifestyle: Option<GameString>,
22 perks: Vec<GameString>, }
24
25impl LineageNode {
26 pub fn get_character(&self) -> GameRef<Character> {
28 self.character.clone()
29 }
30}
31
32impl FromGameObject for LineageNode {
33 fn from_game_object(
34 base: &GameObjectMap,
35 game_state: &mut GameState,
36 ) -> Result<Self, ParsingError> {
37 let mut perks = Vec::new();
38 if let Some(perks_node) = base.get("perk") {
39 if let SaveFileValue::Object(o) = perks_node {
40 for perk in o.as_array()? {
41 perks.push(perk.as_string()?)
42 }
43 } else {
44 perks.push(perks_node.as_string()?);
45 }
46 }
47 Ok(LineageNode {
48 character: game_state.get_character(&base.get_game_id("character")?),
49 date: base.get_date("date")?,
50 score: if let Some(score_node) = base.get("score") {
51 score_node.as_integer()? as i32
52 } else {
53 0
54 },
55 prestige: if let Some(prestige_node) = base.get("prestige") {
56 prestige_node.as_integer()? as i32
57 } else {
58 0
59 },
60 piety: if let Some(piety_node) = base.get("piety") {
61 piety_node.as_integer()? as i32
62 } else {
63 0
64 },
65 dread: if let Some(dread_node) = base.get("dread") {
66 dread_node.as_real()? as f32
67 } else {
68 0.0
69 },
70 lifestyle: if let Some(lifestyle_node) = base.get("lifestyle") {
71 Some(lifestyle_node.as_string()?)
72 } else {
73 None
74 },
75 perks: perks,
76 })
77 }
78}
79
80impl GameObjectDerived for LineageNode {
81 fn get_name(&self) -> GameString {
82 self.character
83 .get_internal()
84 .inner()
85 .expect("Character in lineage must be initialized")
86 .get_name()
87 }
88
89 fn get_references<E: From<EntityRef>, C: Extend<E>>(&self, collection: &mut C) {
90 collection.extend([E::from(self.character.clone().into())]);
91 }
92}
93
94impl Localizable for LineageNode {
95 fn localize(&mut self, localization: &GameData) -> Result<(), LocalizationError> {
96 if let Some(lifestyle) = &self.lifestyle {
97 self.lifestyle = Some(localization.localize(lifestyle.to_string() + "_name")?);
98 }
99 for perk in self.perks.iter_mut() {
100 let mut perk_key = perk.to_string();
101 if perk_key == "family_man_perk" {
102 perk_key += if self
103 .character
104 .get_internal()
105 .inner()
106 .expect("Character in lineage must be initialized")
107 .get_female()
108 {
109 "_female_name"
110 } else {
111 "_male_name"
112 }
113 } else {
114 perk_key += "_name";
115 }
116 *perk = localization.localize(perk_key)?;
117 }
118 Ok(())
119 }
120}
121
122impl Serialize for LineageNode {
123 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
124 where
125 S: serde::Serializer,
126 {
127 let mut state = serializer.serialize_struct("LineageNode", 8)?;
128 state.serialize_field("character", &*self.character.get_internal())?;
129 state.serialize_field("date", &self.date)?;
130 state.serialize_field("score", &self.score)?;
131 state.serialize_field("prestige", &self.prestige)?;
132 state.serialize_field("piety", &self.piety)?;
133 state.serialize_field("dread", &self.dread)?;
134 state.serialize_field("lifestyle", &self.lifestyle)?;
135 state.serialize_field("perks", &self.perks)?;
136 state.end()
137 }
138}