ck3_history_extractor/structures/
faith.rs1use std::path::Path;
2
3use serde::Serialize;
4
5use super::{
6 super::{
7 display::{Grapher, ProceduralPath, Renderable},
8 game_data::{GameData, Localizable, LocalizationError, Localize, MapGenerator, MapImage},
9 jinja_env::FAITH_TEMPLATE_NAME,
10 parser::{GameObjectMap, GameObjectMapping, GameState, ParsingError},
11 types::{GameString, Wrapper},
12 },
13 Character, EntityRef, FromGameObject, GameObjectDerived, GameObjectEntity, GameRef, Title,
14};
15
16#[derive(Serialize)]
18pub struct Faith {
19 name: GameString,
20 tenets: Vec<GameString>,
21 head_title: Option<GameRef<Title>>,
22 head: Option<GameRef<Character>>,
23 fervor: f32,
24 doctrines: Vec<GameString>,
25}
26
27impl FromGameObject for Faith {
28 fn from_game_object(
29 base: &GameObjectMap,
30 game_state: &mut GameState,
31 ) -> Result<Self, ParsingError> {
32 let mut val = Self {
33 name: base
34 .get("name")
35 .or(base.get("template"))
36 .map(|v| v.as_string())
37 .transpose()?
38 .unwrap(),
39 fervor: base.get_real("fervor")? as f32,
40 head_title: base
41 .get_game_id("religious_head")
42 .map(|v| game_state.get_title(&v))
43 .ok(),
44 head: None,
45 tenets: Vec::new(),
46 doctrines: Vec::new(),
47 };
48 for t in base.get_object("doctrine")?.as_array()? {
49 let s = t.as_string()?;
50 if s.contains("tenet") {
51 val.tenets.push(s);
52 } else {
53 val.doctrines.push(s);
54 }
55 }
56 return Ok(val);
57 }
58
59 fn finalize(&mut self, _reference: &GameRef<Self>) {
60 if let Some(head_title) = &self.head_title {
61 if let Some(head) = head_title.get_internal().inner() {
62 self.head = head.get_holder()
63 }
64 }
65 }
66}
67
68impl GameObjectDerived for Faith {
69 fn get_name(&self) -> GameString {
70 self.name.clone()
71 }
72
73 fn get_references<E: From<EntityRef>, C: Extend<E>>(&self, collection: &mut C) {
74 if let Some(head) = &self.head {
75 collection.extend([E::from(head.clone().into())]);
76 }
77 }
78}
79
80impl ProceduralPath for Faith {
81 fn get_subdir() -> &'static str {
82 "faiths"
83 }
84}
85
86impl Renderable for GameObjectEntity<Faith> {
87 fn get_template() -> &'static str {
88 FAITH_TEMPLATE_NAME
89 }
90
91 fn render(
92 &self,
93 path: &Path,
94 game_state: &GameState,
95 grapher: Option<&Grapher>,
96 data: &GameData,
97 ) {
98 if let Some(grapher) = grapher {
99 let mut buf = path.join(Faith::get_subdir());
100 buf.push(self.id.to_string() + ".svg");
101 grapher.create_faith_graph(self.id, &buf);
102 }
103 if let Some(map) = data.get_map() {
104 let filter = |title: &Title| {
105 if let Title::County { faith, .. } = title {
106 if let Some(c_faith) = faith {
107 return c_faith.get_internal().id == self.id;
108 }
109 }
110 return false;
111 };
112 let keys = game_state.get_baronies_of_counties(filter);
113 if !keys.is_empty() {
114 let mut buf = path.join(Faith::get_subdir());
115 buf.push(self.id.to_string() + ".png");
116 let mut faith_map = map.create_map_flat(keys, [70, 255, 70]);
117 if let Some(inner) = self.inner() {
118 faith_map.draw_text(format!("Map of the {} faith", &inner.name));
119 }
120 faith_map.save_in_thread(&buf);
121 }
122 }
123 }
124}
125
126impl Localizable for Faith {
127 fn localize(&mut self, localization: &GameData) -> Result<(), LocalizationError> {
128 self.name = localization.localize(&self.name)?;
129 for tenet in self.tenets.iter_mut() {
130 *tenet = localization.localize(tenet.to_string() + "_name")?;
131 }
132 for doctrine in self.doctrines.iter_mut() {
133 *doctrine = localization.localize(doctrine.to_string() + "_name")?;
134 }
135 Ok(())
136 }
137}