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 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 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 vd.field_bool("imprison");
252 vd.field_bool("start_murders");
254}