ck3_history_extractor/structures/
faith.rs

1use 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/// A struct representing a faith in the game
17#[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}