tiger_lib/ck3/data/
government.rs

1use crate::block::Block;
2use crate::ck3::modif::ModifKinds;
3use crate::ck3::tables::misc::GOVERNMENT_RULES;
4use crate::context::ScopeContext;
5use crate::db::{Db, DbKind};
6use crate::desc::validate_desc;
7use crate::everything::Everything;
8use crate::game::GameFlags;
9use crate::item::{Item, ItemLoader};
10use crate::modif::validate_modifs;
11use crate::scopes::Scopes;
12use crate::token::Token;
13use crate::tooltipped::Tooltipped;
14use crate::validate::validate_color;
15use crate::validator::Validator;
16
17#[derive(Clone, Debug)]
18pub struct Government {}
19
20inventory::submit! {
21    ItemLoader::Normal(GameFlags::Ck3, Item::GovernmentType, Government::add)
22}
23
24impl Government {
25    pub fn add(db: &mut Db, key: Token, block: Block) {
26        db.add(Item::GovernmentType, key, block, Box::new(Self {}));
27    }
28}
29
30impl DbKind for Government {
31    fn add_subitems(&self, _key: &Token, block: &Block, db: &mut Db) {
32        if let Some(vec) = block.get_field_list("flags") {
33            for token in vec {
34                db.add_flag(Item::GovernmentFlag, token.clone());
35            }
36        }
37    }
38
39    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
40        let mut vd = Validator::new(block, data);
41
42        // let modif = format!("{key}_levy_contribution_add");
43        // data.verify_exists_implied(Item::ModifierFormat, &modif, key);
44        // let modif = format!("{key}_levy_contribution_mult");
45        // data.verify_exists_implied(Item::ModifierFormat, &modif, key);
46        // let modif = format!("{key}_tax_contribution_add");
47        // data.verify_exists_implied(Item::ModifierFormat, &modif, key);
48        // let modif = format!("{key}_tax_contribution_mult");
49        // data.verify_exists_implied(Item::ModifierFormat, &modif, key);
50        // let modif = format!("{key}_opinion");
51        // data.verify_exists_implied(Item::ModifierFormat, &modif, key);
52        // let modif = format!("{key}_vassal_opinion");
53        // data.verify_exists_implied(Item::ModifierFormat, &modif, key);
54        // let modif = format!("{key}_opinion_same_faith");
55        // data.verify_exists_implied(Item::ModifierFormat, &modif, key);
56
57        data.verify_exists(Item::Localization, key);
58        let loca = format!("{key}_adjective");
59        data.verify_exists_implied(Item::Localization, &loca, key);
60        let loca = format!("{key}_realm");
61        data.verify_exists_implied(Item::Localization, &loca, key);
62        let loca = format!("{key}_desc");
63        data.verify_exists_implied(Item::Localization, &loca, key);
64        if block.has_key("vassal_contract") {
65            let loca = format!("{key}_vassals_label");
66            data.verify_exists_implied(Item::Localization, &loca, key);
67        }
68
69        vd.field_validated_block("government_rules", |block, data| {
70            let mut vd = Validator::new(block, data);
71            for field in GOVERNMENT_RULES {
72                vd.field_bool(field);
73            }
74        });
75
76        // deprecated
77        for field in GOVERNMENT_RULES {
78            vd.field_bool(field);
79        }
80
81        vd.field_choice(
82            "mechanic_type",
83            &[
84                "feudal",
85                "mercenary",
86                "holy_order",
87                "clan",
88                "theocracy",
89                "administrative",
90                "landless_adventurer",
91                "herder",
92                "nomad",
93                "mandala",
94            ],
95        );
96        // TODO: "All government types listed above should have one default"
97        vd.field_bool("is_mechanic_type_default");
98
99        vd.field_integer("fallback");
100
101        vd.field_trigger_rooted("can_get_government", Tooltipped::No, Scopes::Character);
102        vd.field_trigger_rooted("can_move_realm_capital", Tooltipped::Yes, Scopes::Character);
103
104        vd.field_item("primary_holding", Item::HoldingType);
105        vd.field_list_items("valid_holdings", Item::HoldingType);
106        vd.field_list_items("required_county_holdings", Item::HoldingType);
107        vd.field_item("generated_character_template", Item::CharacterTemplate);
108
109        vd.field_list_items("primary_heritages", Item::CultureHeritage);
110        vd.field_list_items("preferred_religions", Item::Religion);
111        // TODO: test whether this was removed in 1.13
112        vd.field_list_items("primary_cultures", Item::Culture);
113
114        vd.field_bool("court_generate_spouses");
115        if let Some(token) = vd.field_value("court_generate_commanders") {
116            if !token.is("yes") && !token.is("no") {
117                token.expect_number();
118            }
119        }
120        vd.field_numeric("supply_limit_mult_for_others");
121
122        vd.field_validated_block("prestige_opinion_override", |block, data| {
123            let mut vd = Validator::new(block, data);
124            for token in vd.values() {
125                token.expect_number();
126            }
127        });
128
129        vd.field_choice("royal_court", &["none", "any", "top_liege"]);
130        vd.field_list_items("blocked_subject_courts", Item::GovernmentType);
131        vd.field_choice("main_administrative_tier", &["county", "duchy", "kingdom"]);
132        vd.field_choice("min_appointment_tier", &["county", "duchy", "kingdom"]);
133        vd.field_choice("minimum_provincial_maa_tier", &["county", "duchy", "kingdom"]);
134        vd.advice_field(
135            "title_maa_setup",
136            "docs say `title_maa_setup` but vanilla uses `administrative_title_maa_setup`",
137        );
138        vd.field_choice(
139            "administrative_title_maa_setup",
140            &[
141                "main_administrative_tier_and_top_liege",
142                "vassals_and_top_liege",
143                "top_vassals_and_top_liege",
144            ],
145        );
146
147        vd.field_integer("max_dread");
148
149        vd.advice_field(
150            "vassal_contract",
151            "docs say vassal_contract but it's vassal_contract_group",
152        );
153        vd.field_item("vassal_contract_group", Item::SubjectContractGroup);
154        vd.field_item("house_unity", Item::HouseUnity);
155        vd.field_item("domicile_type", Item::DomicileType);
156
157        vd.field_script_value_builder("opinion_of_liege", |key| {
158            let mut sc = ScopeContext::new(Scopes::Character, key);
159            sc.define_name("vassal", Scopes::Character, key);
160            sc.define_name("liege", Scopes::Character, key);
161            sc
162        });
163        vd.field_validated_key("opinion_of_liege_desc", |key, bv, data| {
164            let mut sc = ScopeContext::new(Scopes::None, key);
165            sc.define_name("vassal", Scopes::Character, key);
166            sc.define_name("liege", Scopes::Character, key);
167            validate_desc(bv, data, &mut sc);
168        });
169        vd.field_script_value_builder("opinion_of_suzerain", |key| {
170            let mut sc = ScopeContext::new(Scopes::Character, key);
171            sc.define_name("suzerain", Scopes::Character, key);
172            sc.define_name("tributary", Scopes::Character, key);
173            sc
174        });
175        vd.field_validated_key("opinion_of_suzerain_desc", |key, bv, data| {
176            let mut sc = ScopeContext::new(Scopes::None, key);
177            sc.define_name("suzerain", Scopes::Character, key);
178            sc.define_name("tributary", Scopes::Character, key);
179            validate_desc(bv, data, &mut sc);
180        });
181        vd.field_script_value_builder("opinion_of_overlord", |key| {
182            let mut sc = ScopeContext::new(Scopes::Character, key);
183            sc.define_name("overlord", Scopes::Character, key);
184            sc.define_name("subject", Scopes::Character, key);
185            sc
186        });
187        vd.field_validated_key("opinion_of_overlord_desc", |key, bv, data| {
188            let mut sc = ScopeContext::new(Scopes::None, key);
189            sc.define_name("overlord", Scopes::Character, key);
190            sc.define_name("subject", Scopes::Character, key);
191            validate_desc(bv, data, &mut sc);
192        });
193
194        vd.field_validated_block("currency_levels_cap", |block, data| {
195            let mut vd = Validator::new(block, data);
196            vd.field_integer("piety");
197            vd.field_integer("prestige");
198            vd.field_integer("influence");
199            vd.field_integer("merit");
200        });
201
202        vd.field_list_items("compatible_government_type_succession", Item::GovernmentType);
203
204        vd.field_validated_block("ai", validate_ai);
205        vd.multi_field_validated_block("character_modifier", |block, data| {
206            let vd = Validator::new(block, data);
207            validate_modifs(block, data, ModifKinds::Character, vd);
208        });
209        vd.multi_field_validated_block("top_liege_character_modifier", |block, data| {
210            let vd = Validator::new(block, data);
211            validate_modifs(block, data, ModifKinds::Character, vd);
212        });
213        vd.field_validated_block("color", validate_color);
214
215        vd.field_script_value_no_breakdown_rooted(
216            "ai_ruler_desired_kingdom_titles",
217            Scopes::Character,
218        );
219        vd.field_script_value_no_breakdown_rooted(
220            "ai_ruler_desired_empire_titles",
221            Scopes::Character,
222        );
223        vd.field_trigger_rooted(
224            "ai_can_reassign_council_positions",
225            Tooltipped::No,
226            Scopes::Character,
227        );
228
229        vd.replaced_field("flag", "`flags` list");
230        vd.field_list("flags");
231
232        // undocumented
233
234        vd.field_item("tax_slot_type", Item::TaxSlotType);
235        vd.field_list_numeric_exactly("realm_mask_offset", 2);
236        vd.field_list_numeric_exactly("realm_mask_scale", 2);
237    }
238}
239
240fn validate_ai(block: &Block, data: &Everything) {
241    let mut vd = Validator::new(block, data);
242    vd.field_bool("use_lifestyle");
243    vd.field_bool("arrange_marriage");
244    vd.field_bool("use_goals");
245    vd.field_bool("use_decisions");
246    vd.field_bool("use_scripted_guis");
247    vd.field_bool("use_legends");
248    vd.field_bool("perform_religious_reformation");
249    vd.field_bool("use_great_projects");
250    // TODO: test whether this was removed in 1.13
251    vd.field_bool("imprison");
252    // TODO: test whether this was removed in 1.13
253    vd.field_bool("start_murders");
254}