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 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 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 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 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 && !token.is("yes")
117 && !token.is("no")
118 {
119 token.expect_number();
120 }
121 vd.field_numeric("supply_limit_mult_for_others");
122
123 vd.field_validated_block("prestige_opinion_override", |block, data| {
124 let mut vd = Validator::new(block, data);
125 for token in vd.values() {
126 token.expect_number();
127 }
128 });
129
130 vd.field_choice("royal_court", &["none", "any", "top_liege"]);
131 vd.field_list_items("blocked_subject_courts", Item::GovernmentType);
132 vd.field_choice("main_administrative_tier", &["county", "duchy", "kingdom"]);
133 vd.field_choice("min_appointment_tier", &["county", "duchy", "kingdom"]);
134 vd.field_choice("minimum_provincial_maa_tier", &["county", "duchy", "kingdom"]);
135 vd.advice_field(
136 "title_maa_setup",
137 "docs say `title_maa_setup` but vanilla uses `administrative_title_maa_setup`",
138 );
139 vd.field_choice(
140 "administrative_title_maa_setup",
141 &[
142 "main_administrative_tier_and_top_liege",
143 "vassals_and_top_liege",
144 "top_vassals_and_top_liege",
145 ],
146 );
147
148 vd.field_integer("max_dread");
149
150 vd.advice_field(
151 "vassal_contract",
152 "docs say vassal_contract but it's vassal_contract_group",
153 );
154 vd.field_item("vassal_contract_group", Item::SubjectContractGroup);
155 vd.field_item("house_unity", Item::HouseUnity);
156 vd.field_item("domicile_type", Item::DomicileType);
157
158 vd.field_script_value_builder("opinion_of_liege", |key| {
159 let mut sc = ScopeContext::new(Scopes::Character, key);
160 sc.define_name("vassal", Scopes::Character, key);
161 sc.define_name("liege", Scopes::Character, key);
162 sc
163 });
164 vd.field_validated_key("opinion_of_liege_desc", |key, bv, data| {
165 let mut sc = ScopeContext::new(Scopes::None, key);
166 sc.define_name("vassal", Scopes::Character, key);
167 sc.define_name("liege", Scopes::Character, key);
168 validate_desc(bv, data, &mut sc);
169 });
170 vd.field_script_value_builder("opinion_of_suzerain", |key| {
171 let mut sc = ScopeContext::new(Scopes::Character, key);
172 sc.define_name("suzerain", Scopes::Character, key);
173 sc.define_name("tributary", Scopes::Character, key);
174 sc
175 });
176 vd.field_validated_key("opinion_of_suzerain_desc", |key, bv, data| {
177 let mut sc = ScopeContext::new(Scopes::None, key);
178 sc.define_name("suzerain", Scopes::Character, key);
179 sc.define_name("tributary", Scopes::Character, key);
180 validate_desc(bv, data, &mut sc);
181 });
182 vd.field_script_value_builder("opinion_of_overlord", |key| {
183 let mut sc = ScopeContext::new(Scopes::Character, key);
184 sc.define_name("overlord", Scopes::Character, key);
185 sc.define_name("subject", Scopes::Character, key);
186 sc
187 });
188 vd.field_validated_key("opinion_of_overlord_desc", |key, bv, data| {
189 let mut sc = ScopeContext::new(Scopes::None, key);
190 sc.define_name("overlord", Scopes::Character, key);
191 sc.define_name("subject", Scopes::Character, key);
192 validate_desc(bv, data, &mut sc);
193 });
194
195 vd.field_validated_block("currency_levels_cap", |block, data| {
196 let mut vd = Validator::new(block, data);
197 vd.field_integer("piety");
198 vd.field_integer("prestige");
199 vd.field_integer("influence");
200 vd.field_integer("merit");
201 });
202
203 vd.field_list_items("compatible_government_type_succession", Item::GovernmentType);
204
205 vd.field_validated_block("ai", validate_ai);
206 vd.multi_field_validated_block("character_modifier", |block, data| {
207 let vd = Validator::new(block, data);
208 validate_modifs(block, data, ModifKinds::Character, vd);
209 });
210 vd.multi_field_validated_block("top_liege_character_modifier", |block, data| {
211 let vd = Validator::new(block, data);
212 validate_modifs(block, data, ModifKinds::Character, vd);
213 });
214 vd.field_validated_block("color", validate_color);
215
216 vd.field_script_value_no_breakdown_rooted(
217 "ai_ruler_desired_kingdom_titles",
218 Scopes::Character,
219 );
220 vd.field_script_value_no_breakdown_rooted(
221 "ai_ruler_desired_empire_titles",
222 Scopes::Character,
223 );
224 vd.field_trigger_rooted(
225 "ai_can_reassign_council_positions",
226 Tooltipped::No,
227 Scopes::Character,
228 );
229
230 vd.replaced_field("flag", "`flags` list");
231 vd.field_list("flags");
232
233 vd.field_item("tax_slot_type", Item::TaxSlotType);
236 vd.field_list_numeric_exactly("realm_mask_offset", 2);
237 vd.field_list_numeric_exactly("realm_mask_scale", 2);
238 }
239}
240
241fn validate_ai(block: &Block, data: &Everything) {
242 let mut vd = Validator::new(block, data);
243 vd.field_bool("use_lifestyle");
244 vd.field_bool("arrange_marriage");
245 vd.field_bool("use_goals");
246 vd.field_bool("use_decisions");
247 vd.field_bool("use_scripted_guis");
248 vd.field_bool("use_legends");
249 vd.field_bool("perform_religious_reformation");
250 vd.field_bool("use_great_projects");
251 vd.field_bool("imprison");
253 vd.field_bool("start_murders");
255}