1#![allow(non_upper_case_globals)]
2
3use std::sync::LazyLock;
4
5use crate::everything::Everything;
6use crate::helpers::TigerHashMap;
7use crate::imperator::modif::ModifKinds;
8use crate::item::Item;
9use crate::lowercase::Lowercase;
10use crate::report::{ErrorKey, Severity, report};
11use crate::token::Token;
12
13pub fn lookup_modif(name: &Token, data: &Everything, warn: Option<Severity>) -> Option<ModifKinds> {
16 let name_lc = Lowercase::new(name.as_str());
17
18 if let result @ Some(_) = MODIF_MAP.get(&name_lc).copied() {
19 return result;
20 }
21
22 if let Some(part) = name_lc.strip_prefix_unchecked("local_") {
28 for &sfx in &["_output", "_desired_pop_ratio", "_happyness"] {
29 if let Some(part) = part.strip_suffix_unchecked(sfx) {
30 maybe_warn(Item::PopType, &part, name, data, warn);
31 return Some(ModifKinds::Province | ModifKinds::State);
32 }
33 }
34 }
35
36 if let Some(part) = name_lc.strip_prefix_unchecked("global_") {
41 for &sfx in &["_output", "_city_desired_pop_ratio", "_desired_pop_ratio", "_happyness"] {
42 if let Some(part) = part.strip_suffix_unchecked(sfx) {
43 maybe_warn(Item::PopType, &part, name, data, warn);
44 return Some(ModifKinds::Country);
45 }
46 }
47 }
48
49 if let Some(part) = name_lc.strip_prefix_unchecked("culture_") {
52 for &sfx in &["_output", "_happiness"] {
53 if let Some(part) = part.strip_suffix_unchecked(sfx) {
54 maybe_warn(Item::PopType, &part, name, data, warn);
55 return Some(ModifKinds::Country);
56 }
57 }
58 }
59
60 if let Some(part) = name_lc.strip_suffix_unchecked("_cost_modifier") {
62 maybe_warn(Item::Price, &part, name, data, warn);
63 return Some(ModifKinds::Country);
64 }
65
66 if let Some(part) = name_lc.strip_suffix_unchecked("_influence") {
68 maybe_warn(Item::PartyType, &part, name, data, warn);
69 return Some(ModifKinds::Country);
70 }
71
72 if let Some(part) = name_lc.strip_prefix_unchecked("monthly_")
74 && let Some(part) = part.strip_suffix_unchecked("_conviction")
75 {
76 maybe_warn(Item::PartyType, &part, name, data, warn);
77 return Some(ModifKinds::Character);
78 }
79
80 for &sfx in &[
87 "_discipline",
88 "_morale",
89 "_offensive",
90 "_defensive",
91 "_maintenance_cost",
92 "_movement_speed",
93 ] {
94 if let Some(part) = name_lc.strip_suffix_unchecked(sfx) {
95 maybe_warn(Item::Unit, &part, name, data, warn);
96 return Some(ModifKinds::Country);
97 }
98 }
99
100 if let Some(part) = name_lc.strip_suffix_unchecked("_combat_bonus") {
103 for (i, _) in part.rmatch_indices_unchecked('_') {
106 if data.item_exists_lc(Item::Terrain, &part.slice(i + 1..)) {
107 maybe_warn(Item::Unit, &part.slice(..i), name, data, warn);
109 return Some(ModifKinds::Country);
110 }
111 }
112 maybe_warn(Item::Terrain, &part, name, data, warn);
114 return Some(ModifKinds::Country);
115 }
116
117 if let Some(part) = name_lc.strip_suffix_unchecked("_cost") {
120 if let Some(sev) = warn
121 && !data.item_exists(Item::Unit, part.as_str())
122 && !data.item_exists(Item::Building, part.as_str())
123 {
124 let msg = format!("{part} not found as unit or building");
125 let info = format!("so the modifier {name} does not exist");
126 report(ErrorKey::MissingItem, sev).msg(msg).info(info).loc(name).push();
127 }
128 return Some(ModifKinds::Country);
129 }
130
131 if let Some(part) = name_lc.strip_suffix_unchecked("_investment") {
133 maybe_warn(Item::TechnologyTable, &part, name, data, warn);
134 return Some(ModifKinds::Country);
135 }
136
137 None
138}
139
140fn maybe_warn(itype: Item, s: &Lowercase, name: &Token, data: &Everything, warn: Option<Severity>) {
141 if let Some(sev) = warn
142 && !data.item_exists_lc(itype, s)
143 {
144 let msg = format!("could not find {itype} {s}");
145 let info = format!("so the modifier {name} does not exist");
146 report(ErrorKey::MissingItem, sev).strong().msg(msg).info(info).loc(name).push();
147 }
148}
149
150static MODIF_MAP: LazyLock<TigerHashMap<Lowercase<'static>, ModifKinds>> = LazyLock::new(|| {
151 let mut hash = TigerHashMap::default();
152 for (s, kind) in MODIF_TABLE.iter().copied() {
153 hash.insert(Lowercase::new_unchecked(s), kind);
154 }
155 hash
156});
157
158const MODIF_TABLE: &[(&str, ModifKinds)] = &[
162 ("happiness_for_wrong_religion_modifier", ModifKinds::Country),
163 ("local_happiness_for_wrong_religion_modifier", ModifKinds::Province),
164 ("cultural_assimilation_speed_modifier", ModifKinds::Country),
165 ("build_cost", ModifKinds::Country),
166 ("build_time", ModifKinds::Country),
167 ("desert_hills_combat_bonus", ModifKinds::Country),
168 ("minimum_unrest", ModifKinds::Province.union(ModifKinds::State)),
169 ("local_unrest", ModifKinds::Province.union(ModifKinds::State)),
170 ("global_unrest", ModifKinds::Country),
171 ("tax_income", ModifKinds::Province.union(ModifKinds::State)),
172 ("global_tax_income", ModifKinds::Country),
173 ("local_tax_modifier", ModifKinds::Province.union(ModifKinds::State)),
174 ("global_tax_modifier", ModifKinds::Country),
175 ("local_population_growth", ModifKinds::Province.union(ModifKinds::State)),
176 ("global_population_growth", ModifKinds::Country),
177 ("local_population_capacity", ModifKinds::Province.union(ModifKinds::State)),
178 ("local_population_capacity_modifier", ModifKinds::Province.union(ModifKinds::State)),
179 ("global_population_capacity_modifier", ModifKinds::Country),
180 ("total_population_capacity_modifier", ModifKinds::Province.union(ModifKinds::Country)),
181 ("local_building_slot", ModifKinds::Province.union(ModifKinds::State)),
182 ("global_building_slot", ModifKinds::Country),
183 ("global_monthly_state_loyalty", ModifKinds::Country),
184 ("local_monthly_state_loyalty", ModifKinds::Province.union(ModifKinds::State)),
185 ("city_monthly_state_loyalty", ModifKinds::Province.union(ModifKinds::State)),
186 ("happiness_for_wrong_culture_modifier", ModifKinds::Province.union(ModifKinds::Country)),
187 ("happiness_for_wrong_culture_group_modifier", ModifKinds::Province.union(ModifKinds::Country)),
188 ("happiness_for_same_culture_modifier", ModifKinds::Country),
189 ("local_happiness_for_same_culture_modifier", ModifKinds::Province.union(ModifKinds::State)),
190 ("happiness_for_same_religion_modifier", ModifKinds::Country),
191 ("local_happiness_for_same_religion_modifier", ModifKinds::Province.union(ModifKinds::State)),
192 ("global_population_happiness", ModifKinds::Country),
193 ("local_population_happiness", ModifKinds::Province.union(ModifKinds::State)),
194 ("land_morale", ModifKinds::Country),
195 ("naval_morale", ModifKinds::Country),
196 ("land_morale_modifier", ModifKinds::Country),
197 ("naval_morale_modifier", ModifKinds::Country),
198 ("non_retinue_morale_modifier", ModifKinds::Country),
199 ("local_manpower", ModifKinds::Province.union(ModifKinds::State)),
200 ("global_manpower", ModifKinds::Country),
201 ("local_manpower_modifier", ModifKinds::Province.union(ModifKinds::State)),
202 ("global_manpower_modifier", ModifKinds::Country),
203 ("manpower_recovery_speed", ModifKinds::Country),
204 ("attrition", ModifKinds::Province.union(ModifKinds::State)),
205 ("land_unit_attrition", ModifKinds::Country.union(ModifKinds::Unit)),
206 ("naval_unit_attrition", ModifKinds::Country.union(ModifKinds::Unit)),
207 ("army_weight_modifier", ModifKinds::Country.union(ModifKinds::Unit)),
208 ("navy_weight_modifier", ModifKinds::Country.union(ModifKinds::Unit)),
209 ("max_attrition", ModifKinds::Province.union(ModifKinds::State)),
210 ("supply_limit", ModifKinds::Province.union(ModifKinds::State)),
211 ("supply_limit_modifier", ModifKinds::Province.union(ModifKinds::State)),
212 ("global_supply_limit_modifier", ModifKinds::Country),
213 ("war_exhaustion", ModifKinds::Country),
214 ("max_war_exhaustion", ModifKinds::Country),
215 ("fort_level", ModifKinds::Province.union(ModifKinds::State)),
216 ("blockade_efficiency", ModifKinds::Country),
217 ("monthly_centralization", ModifKinds::Country),
218 ("monthly_legitimacy", ModifKinds::Country),
219 ("agressive_expansion_impact", ModifKinds::Country),
220 ("agressive_expansion_monthly_change", ModifKinds::Country),
221 ("agressive_expansion_monthly_decay", ModifKinds::Country),
222 ("local_ship_recruit_speed", ModifKinds::Province.union(ModifKinds::State)),
223 ("local_cohort_recruit_speed", ModifKinds::Province.union(ModifKinds::State)),
224 ("global_ship_recruit_speed", ModifKinds::Country),
225 ("global_cohort_recruit_speed", ModifKinds::Country),
226 ("garrison_size", ModifKinds::Province.union(ModifKinds::Country)),
227 ("garrison_growth", ModifKinds::Province.union(ModifKinds::Country)),
228 ("technology_investment", ModifKinds::Country),
229 ("movement_cost", ModifKinds::Province.union(ModifKinds::State)),
230 ("army_movement_speed", ModifKinds::Unit.union(ModifKinds::Country)),
231 ("navy_movement_speed", ModifKinds::Unit.union(ModifKinds::Country)),
232 ("movement_speed_if_no_road", ModifKinds::Unit.union(ModifKinds::Country)),
233 ("local_state_trade_routes", ModifKinds::Province.union(ModifKinds::State)),
234 ("global_capital_trade_routes", ModifKinds::Country),
235 ("global_state_trade_routes", ModifKinds::Country),
236 ("research_points", ModifKinds::Country.union(ModifKinds::Province)),
237 ("research_points_modifier", ModifKinds::Country),
238 ("local_research_points_modifier", ModifKinds::Province.union(ModifKinds::State)),
239 ("omen_power", ModifKinds::Country),
240 ("omen_duration", ModifKinds::Country),
241 ("discipline", ModifKinds::Country.union(ModifKinds::Unit)),
242 ("local_defensive", ModifKinds::Province.union(ModifKinds::State)),
243 ("global_defensive", ModifKinds::Country),
244 ("commerce_value", ModifKinds::Province.union(ModifKinds::State)),
245 ("local_commerce_value_modifier", ModifKinds::Province.union(ModifKinds::State)),
246 ("global_commerce_modifier", ModifKinds::Country),
247 ("global_export_commerce_modifier", ModifKinds::Country),
248 ("global_import_commerce_modifier", ModifKinds::Country),
249 ("state_commerce_modifier", ModifKinds::Province.union(ModifKinds::State)),
250 ("tribute_income_modifier", ModifKinds::Country),
251 ("ruler_popularity_gain", ModifKinds::Country),
252 ("max_loyalty", ModifKinds::Country),
253 ("integrate_speed", ModifKinds::Country),
254 ("fabricate_claim_speed", ModifKinds::Country),
255 (
256 "monthly_wage_for_character",
257 ModifKinds::Character.union(ModifKinds::Country).union(ModifKinds::State),
258 ),
259 ("monthly_wage_modifier", ModifKinds::Country),
260 ("monthly_wage_on_character_modifier", ModifKinds::Character),
261 ("monthly_governor_wage", ModifKinds::Country.union(ModifKinds::Character)),
262 (
263 "monthly_local_governor_wage",
264 ModifKinds::Province.union(ModifKinds::State).union(ModifKinds::Country),
265 ),
266 ("monthly_character_popularity", ModifKinds::Character.union(ModifKinds::Country)),
267 ("monthly_character_popularity_decay", ModifKinds::Character.union(ModifKinds::Country)),
268 ("monthly_character_prominence", ModifKinds::Character.union(ModifKinds::Country)),
269 ("monthly_character_fam_prestige", ModifKinds::Character.union(ModifKinds::Country)),
270 ("cohort_reinforcement_speed", ModifKinds::Country.union(ModifKinds::Unit)),
271 ("land_morale_recovery", ModifKinds::Country.union(ModifKinds::Unit)),
272 ("naval_morale_recovery", ModifKinds::Country.union(ModifKinds::Unit)),
273 ("siege_ability", ModifKinds::Country.union(ModifKinds::Unit)),
274 ("assault_ability", ModifKinds::Country.union(ModifKinds::Unit)),
275 ("siege_engineers", ModifKinds::Country.union(ModifKinds::Legion)),
276 ("diplomatic_reputation", ModifKinds::Country),
277 ("diplomatic_relations", ModifKinds::Country),
278 ("max_rivals", ModifKinds::Character.union(ModifKinds::Country)),
279 ("max_friends", ModifKinds::Character.union(ModifKinds::Country)),
280 ("current_corruption", ModifKinds::Character.union(ModifKinds::Country)),
281 ("monthly_corruption", ModifKinds::Character.union(ModifKinds::Country)),
282 ("subject_opinions", ModifKinds::Country),
283 ("subject_loyalty", ModifKinds::Country),
284 ("loyalty_to_overlord", ModifKinds::Country),
285 ("fort_maintenance_cost", ModifKinds::Country.union(ModifKinds::State)),
286 ("army_maintenance_cost", ModifKinds::Country.union(ModifKinds::Unit)),
287 ("navy_maintenance_cost", ModifKinds::Country.union(ModifKinds::Unit)),
288 ("mercenary_land_maintenance_cost", ModifKinds::Country),
289 ("mercenary_naval_maintenance_cost", ModifKinds::Country),
290 ("country_civilization_value", ModifKinds::Country),
291 ("local_country_civilization_value", ModifKinds::Province.union(ModifKinds::State)),
292 ("local_monthly_civilization", ModifKinds::Province.union(ModifKinds::State)),
293 ("global_monthly_civilization", ModifKinds::Country),
294 ("global_start_experience", ModifKinds::Country),
295 ("local_start_experience", ModifKinds::Province.union(ModifKinds::State)),
296 ("global_cohort_start_experience", ModifKinds::Country),
297 ("local_cohort_start_experience", ModifKinds::Province.union(ModifKinds::State)),
298 ("global_ship_start_experience", ModifKinds::Country),
299 ("local_ship_start_experience", ModifKinds::Province.union(ModifKinds::State)),
300 ("experience_decay", ModifKinds::Country.union(ModifKinds::Unit)),
301 ("monthly_experience_gain", ModifKinds::Country.union(ModifKinds::Unit)),
302 ("martial", ModifKinds::Character),
303 ("finesse", ModifKinds::Character),
304 ("charisma", ModifKinds::Character),
305 ("zeal", ModifKinds::Character),
306 ("fertility", ModifKinds::Character.union(ModifKinds::Country)),
307 ("health", ModifKinds::Character.union(ModifKinds::Country)),
308 ("barbarian_growth", ModifKinds::Province),
309 ("barbarian_spawn_chance", ModifKinds::Province.union(ModifKinds::State)),
310 (
311 "loyalty_gain_chance",
312 ModifKinds::Country.union(ModifKinds::Character).union(ModifKinds::Unit),
313 ),
314 (
315 "loyalty_gain_chance_modifier",
316 ModifKinds::Country.union(ModifKinds::Character).union(ModifKinds::Unit),
317 ),
318 ("prominence", ModifKinds::Character.union(ModifKinds::Country)),
319 ("senate_influence", ModifKinds::Character),
320 ("monthly_party_approval", ModifKinds::Country),
321 ("monthly_tyranny", ModifKinds::Country),
322 ("monthly_political_influence", ModifKinds::Country),
323 ("monthly_political_influence_modifier", ModifKinds::Country),
324 ("retreat_delay", ModifKinds::Country),
325 ("improve_relation_impact", ModifKinds::Country),
326 ("hostile_attrition", ModifKinds::Country),
327 ("local_hostile_attrition", ModifKinds::Province.union(ModifKinds::State)),
328 ("election_term_duration", ModifKinds::Country),
329 ("ship_repair_at_sea", ModifKinds::Country),
330 ("war_score_cost", ModifKinds::Country),
331 ("base_resources", ModifKinds::Province.union(ModifKinds::State)),
332 ("local_goods_from_slaves", ModifKinds::Province.union(ModifKinds::State)),
333 ("global_goods_from_slaves", ModifKinds::Country),
334 ("disallow_job", ModifKinds::Character),
335 ("disallow_office", ModifKinds::Character),
336 ("disallow_command", ModifKinds::Character),
337 ("show_3d_fort", ModifKinds::Province),
338 ("control_range_modifier", ModifKinds::Country),
339 ("diplomatic_range_modifier", ModifKinds::Country),
340 ("monthly_character_wealth", ModifKinds::Character),
341 ("primary_heir_attraction", ModifKinds::Character.union(ModifKinds::Country)),
342 ("support_for_character_as_heir", ModifKinds::Character),
343 ("next_ruler_legitimacy", ModifKinds::Country),
344 ("num_of_clan_chiefs", ModifKinds::Country),
345 ("clan_retinue_size", ModifKinds::Country),
346 ("enslavement_efficiency", ModifKinds::Character.union(ModifKinds::Country)),
347 ("local_output_modifier", ModifKinds::Province.union(ModifKinds::State)),
348 ("holdings_possible_for_character", ModifKinds::Character),
349 ("available_holdings", ModifKinds::Character),
350 ("holding_income_modifier", ModifKinds::Character),
351 ("stability_monthly_change", ModifKinds::Country),
352 ("stability_monthly_decay", ModifKinds::Country),
353 ("civil_war_threshold", ModifKinds::Country),
354 ("ship_capture_chance", ModifKinds::Country),
355 ("naval_damage_done", ModifKinds::Country.union(ModifKinds::Unit)),
356 ("naval_damage_taken", ModifKinds::Country.union(ModifKinds::Unit)),
357 ("ship_cost", ModifKinds::Country),
358 ("cohort_cost", ModifKinds::Country),
359 ("pirate_haven", ModifKinds::Province),
360 ("pirate_plunder", ModifKinds::Province),
361 ("anti_piracy_cb", ModifKinds::Country),
362 ("naval_range", ModifKinds::Country),
363 ("monthly_military_experience", ModifKinds::Country),
364 ("monthly_military_experience_modifier", ModifKinds::Country),
365 ("local_pop_promotion_speed", ModifKinds::Province.union(ModifKinds::State)),
366 ("global_pop_promotion_speed", ModifKinds::Country),
367 ("local_pop_promotion_speed_modifier", ModifKinds::Province.union(ModifKinds::State)),
368 ("global_pop_promotion_speed_modifier", ModifKinds::Country),
369 ("local_pop_demotion_speed", ModifKinds::Province.union(ModifKinds::State)),
370 ("global_pop_demotion_speed", ModifKinds::Country),
371 ("local_pop_demotion_speed_modifier", ModifKinds::Province.union(ModifKinds::State)),
372 ("global_pop_demotion_speed_modifier", ModifKinds::Country),
373 ("local_migration_attraction", ModifKinds::Province.union(ModifKinds::State)),
374 ("local_migration_speed", ModifKinds::Province.union(ModifKinds::State)),
375 ("global_migration_speed", ModifKinds::Country),
376 ("local_migration_speed_modifier", ModifKinds::Province.union(ModifKinds::State)),
377 ("global_migration_speed_modifier", ModifKinds::Country),
378 ("local_pop_conversion_speed", ModifKinds::Province.union(ModifKinds::State)),
379 ("global_pop_conversion_speed", ModifKinds::Country),
380 ("local_pop_conversion_speed_modifier", ModifKinds::Province.union(ModifKinds::State)),
381 ("global_pop_conversion_speed_modifier", ModifKinds::Country),
382 ("local_pop_assimilation_speed", ModifKinds::Province.union(ModifKinds::State)),
383 ("global_pop_assimilation_speed", ModifKinds::Country),
384 ("local_pop_assimilation_speed_modifier", ModifKinds::Province.union(ModifKinds::State)),
385 ("global_pop_assimilation_speed_modifier", ModifKinds::Country),
386 ("cultural_integration_speed_modifier", ModifKinds::CountryCulture),
387 ("cultural_assimilation_speed_modifier", ModifKinds::CountryCulture),
388 ("culture_happiness_modifier", ModifKinds::CountryCulture),
389 ("local_monthly_food", ModifKinds::Province.union(ModifKinds::State)),
390 ("global_monthly_food_modifier", ModifKinds::Country),
391 ("global_food_capacity", ModifKinds::Country),
392 ("local_food_capacity", ModifKinds::Province.union(ModifKinds::State)),
393 ("local_monthly_food_modifier", ModifKinds::Province.union(ModifKinds::State)),
394 ("local_hostile_food_multiplier", ModifKinds::Province.union(ModifKinds::State)),
395 ("pop_food_consumption", ModifKinds::Province.union(ModifKinds::State)),
396 ("monthly_character_experience", ModifKinds::Character.union(ModifKinds::Country)),
397 ("monthly_character_experience_decay", ModifKinds::Character.union(ModifKinds::Country)),
398 ("monthly_conviction_for_head_of_family_party", ModifKinds::Character),
399 ("local_base_trade_routes", ModifKinds::Province.union(ModifKinds::State)),
400 ("local_base_trade_routes_modifier", ModifKinds::Province.union(ModifKinds::State)),
401 ("enable_intervene", ModifKinds::Country),
402 ("character_loyalty", ModifKinds::Country.union(ModifKinds::Character)),
403 ("general_loyalty", ModifKinds::Country),
404 ("admiral_loyalty", ModifKinds::Country),
405 ("governor_loyalty", ModifKinds::Country),
406 ("clan_chief_loyalty", ModifKinds::Country),
407 ("levy_size_multiplier", ModifKinds::Country),
408 ("movement_speed_if_no_road", ModifKinds::Country),
409 ("great_work_total_workrate_character_modifier", ModifKinds::Character),
410 ("great_work_slaves_workrate_character_modifier", ModifKinds::Character),
411 ("great_work_tribals_workrate_character_modifier", ModifKinds::Character),
412 ("great_work_freemen_workrate_character_modifier", ModifKinds::Character),
413 ("great_work_fixed_prestige_character_modifier", ModifKinds::Character),
414 ("local_combat_width_modifier", ModifKinds::Province.union(ModifKinds::State)),
415 ("watercrossing_enabled_for_river", ModifKinds::Country),
416 ("watercrossing_enabled_for_strait", ModifKinds::Country),
417 ("watercrossing_enabled_for_shore", ModifKinds::Country),
418 ("succession_value", ModifKinds::Character),
419 ("fort_limit", ModifKinds::Country),
420 ("local_fort_limit", ModifKinds::Province.union(ModifKinds::State)),
421 ("global_settlement_building_slot", ModifKinds::Country),
422 ("max_research_efficiency", ModifKinds::Country),
423 ("max_mercenary_stacks", ModifKinds::Country),
424];