1#![allow(non_upper_case_globals)]
2
3use std::borrow::Cow;
4use std::sync::LazyLock;
5
6use crate::everything::Everything;
7use crate::helpers::{TigerHashMap, TigerHashMapExt};
8use crate::item::Item;
9use crate::lowercase::Lowercase;
10use crate::report::{ErrorKey, Severity, report, untidy};
11use crate::scopes::Scopes;
12use crate::token::Token;
13use crate::vic3::modif::ModifKinds;
14
15pub fn lookup_modif(name: &Token, data: &Everything, warn: Option<Severity>) -> Option<ModifKinds> {
16 let name_lc = Lowercase::new(name.as_str());
17
18 let kind = lookup_engine_modif(name, &name_lc, data, warn);
19
20 if data.item_exists_lc(Item::ModifierTypeDefinition, &name_lc) {
22 return kind.or_else(|| Some(lookup_modif_prefix(name)));
23 } else if let Some(sev) = warn {
24 let info = kind
25 .and(Some("You can create it and the game engine will apply the modifier"))
26 .unwrap_or("You can create it and the modifier will appear in game, but the engine will not apply any effect");
27 report(ErrorKey::MissingItem, sev)
28 .msg("modifier type definition does not exist")
29 .info(info)
30 .wiki("https://vic3.paradoxwikis.com/Modifier_types#Defining_modifier_types")
31 .loc(name)
32 .push();
33 }
34
35 None
36}
37
38fn lookup_modif_prefix(name: &Token) -> ModifKinds {
39 for (prefix, kind) in MODIF_PREFIX_TABLE {
40 if name.as_str().starts_with(prefix) {
41 return kind;
42 }
43 }
44 untidy(ErrorKey::Modifiers)
47 .msg("script only modifier does not use a valid prefix")
48 .info("consider using a prefix to ensure the modifier flows to the intended scope")
49 .wiki("https://vic3.paradoxwikis.com/Modifier_types#Modifier_type_flow")
50 .loc(name)
51 .push();
52 ModifKinds::all()
53}
54
55pub fn lookup_engine_modif(
58 name: &Token,
59 name_lc: &Lowercase,
60 data: &Everything,
61 warn: Option<Severity>,
62) -> Option<ModifKinds> {
63 if let result @ Some(_) = MODIF_MAP.get(name_lc).copied() {
64 return result;
65 }
66
67 if let Some(info) = MODIF_REMOVED_MAP.get(name_lc).copied() {
68 if let Some(sev) = warn {
69 let msg = format!("{name} has been removed");
70 report(ErrorKey::Removed, sev).msg(msg).info(info).loc(name).push();
71 }
72 return None;
73 }
74
75 if let Some(part) = name_lc.strip_prefix_unchecked("building_employment_") {
80 for &sfx in &["_add", "_mult"] {
81 if let Some(part) = part.strip_suffix_unchecked(sfx) {
82 maybe_warn(Item::PopType, &part, name, data, warn);
83 return Some(ModifKinds::Building);
84 }
85 }
86 }
87 if let Some(part) = name_lc.strip_prefix_unchecked("building_group_") {
102 for &sfx in &["_fertility_mult", "_mortality_mult", "_standard_of_living_add"] {
103 if let Some(part) = part.strip_suffix_unchecked(sfx) {
104 for (i, _) in part.rmatch_indices_unchecked('_') {
106 if data.item_exists_lc(Item::PopType, &part.slice(i + 1..)) {
107 maybe_warn(Item::BuildingGroup, &part.slice(..i), name, data, warn);
108 return Some(ModifKinds::Building);
109 }
110 }
111 maybe_warn(Item::BuildingGroup, &part, name, data, warn);
113 return Some(ModifKinds::Building);
114 }
115 }
116 for &sfx in &[
117 "_allowed_collectivization_add",
118 "_infrastructure_usage_mult",
119 "_employee_mult",
120 "_tax_mult",
121 "_unincorporated_throughput_add",
122 "_throughput_add",
123 "_self_investment_chance_add",
124 "_construction_efficiency_add",
125 ] {
126 if let Some(part) = part.strip_suffix_unchecked(sfx) {
127 maybe_warn(Item::BuildingGroup, &part, name, data, warn);
128 return Some(ModifKinds::Building);
129 }
130 }
131 if let Some(part) = part.strip_suffix_unchecked("_throughput_mult") {
132 maybe_warn(Item::BuildingGroup, &part, name, data, warn);
133 if let Some(sev) = warn {
134 let msg = format!("`{name}` was removed in 1.5");
135 let info = "it was replaced with `_add`";
136 report(ErrorKey::Removed, sev).msg(msg).info(info).loc(name).push();
137 }
138 return Some(ModifKinds::Building);
139 }
140 }
141
142 if let Some(part) = name_lc.strip_suffix_unchecked("_throughput_mult") {
144 maybe_warn(Item::BuildingType, &part, name, data, warn);
145 if let Some(sev) = warn {
146 let msg = format!("`{name}` was removed in 1.5");
147 let info = "it was replaced with `_add`";
148 report(ErrorKey::Removed, sev).msg(msg).info(info).loc(name).push();
149 }
150 return Some(ModifKinds::Building);
151 }
152 if let Some(part) = name_lc.strip_suffix_unchecked("_throughput_add") {
154 maybe_warn(Item::BuildingType, &part, name, data, warn);
155 return Some(ModifKinds::Building);
156 }
157
158 if let Some(part) = name_lc.strip_prefix_unchecked("building_") {
165 for &sfx in &[
166 "_fertility_mult",
167 "_job_attractiveness_mult",
168 "_mortality_mult",
169 "_shares_add",
170 "_shares_mult",
171 "_standard_of_living_add",
172 ] {
173 if let Some(part) = part.strip_suffix_unchecked(sfx) {
174 maybe_warn(Item::PopType, &part, name, data, warn);
175 return Some(ModifKinds::Building);
176 }
177 }
178 }
179
180 if let Some(part) = name_lc.strip_prefix_unchecked("building_input_") {
182 if let Some(part) = part.strip_suffix_unchecked("_add") {
183 maybe_warn(Item::Goods, &part, name, data, warn);
184 if let Some(sev) = warn {
185 let msg = format!("`{name}` was removed in 1.5");
186 let info = format!("replaced with `goods_input_{part}_add`");
187 report(ErrorKey::Removed, sev).msg(msg).info(info).loc(name).push();
188 }
189 return Some(ModifKinds::Building);
190 }
191 }
192
193 if let Some(part) = name_lc.strip_prefix_unchecked("goods_input_") {
196 for &sfx in &["_add", "_mult"] {
197 if let Some(part) = part.strip_suffix_unchecked(sfx) {
198 maybe_warn(Item::Goods, &part, name, data, warn);
199 return Some(ModifKinds::Goods);
200 }
201 }
202 }
203
204 if let Some(part) = name_lc.strip_prefix_unchecked("goods_trade_advantage_") {
206 if let Some(part) = part.strip_suffix_unchecked("_mult") {
207 maybe_warn(Item::Goods, &part, name, data, warn);
208 return Some(ModifKinds::Goods);
209 }
210 }
211
212 if let Some(part) = name_lc.strip_prefix_unchecked("building_output_") {
215 for &sfx in &["_add", "_mult"] {
216 if let Some(part) = part.strip_suffix_unchecked(sfx) {
217 maybe_warn(Item::Goods, &part, name, data, warn);
218 if let Some(sev) = warn {
219 let msg = format!("`{name}` was removed in 1.5");
220 let info = format!("it was replaced with `goods_output_{part}{sfx}`");
221 report(ErrorKey::Removed, sev).msg(msg).info(info).loc(name).push();
222 }
223 return Some(ModifKinds::Building);
224 }
225 }
226 }
227 if let Some(part) = name_lc.strip_prefix_unchecked("goods_output_") {
230 for &sfx in &["_add", "_mult"] {
231 if let Some(part) = part.strip_suffix_unchecked(sfx) {
232 maybe_warn(Item::Goods, &part, name, data, warn);
233 return Some(ModifKinds::Goods);
234 }
235 }
236 }
237
238 if let Some(part) = name_lc.strip_prefix_unchecked("character_") {
240 if let Some(part) = part.strip_suffix_unchecked("_mult") {
241 maybe_warn(Item::BattleCondition, &part, name, data, warn);
242 return Some(ModifKinds::Character);
243 }
244 }
245
246 if let Some(part) = name_lc.strip_prefix_unchecked("country_institution_cost_") {
249 for &sfx in &["_add", "_mult"] {
250 if let Some(part) = part.strip_suffix_unchecked(sfx) {
251 maybe_warn(Item::Institution, &part, name, data, warn);
252 return Some(ModifKinds::Country);
253 }
254 }
255 }
256
257 if let Some(part) = name_lc.strip_prefix_unchecked("country_institution_impact_") {
259 if let Some(part) = part.strip_suffix_unchecked("_mult") {
260 maybe_warn(Item::Institution, &part, name, data, warn);
261 return Some(ModifKinds::Country);
262 }
263 }
264
265 if let Some(part) = name_lc.strip_prefix_unchecked("country_institution_size_change_speed_") {
267 if let Some(part) = part.strip_suffix_unchecked("_mult") {
268 maybe_warn(Item::Institution, &part, name, data, warn);
269 return Some(ModifKinds::Country);
270 }
271 }
272
273 if let Some(part) = name_lc.strip_prefix_unchecked("country_can_impose_same_") {
275 if let Some(part) = part.strip_suffix_unchecked("_in_power_bloc_bool") {
276 maybe_warn(Item::LawGroup, &part, name, data, warn);
277 return Some(ModifKinds::Country);
278 }
279 }
280
281 if let Some(part) = name_lc.strip_prefix_unchecked("country_") {
284 for &sfx in &["_pol_str_mult", "_voting_power_add"] {
285 if let Some(part) = part.strip_suffix_unchecked(sfx) {
286 maybe_warn(Item::PopType, &part, name, data, warn);
287 return Some(ModifKinds::Country);
288 }
289 }
290 }
291
292 if let Some(part) = name_lc.strip_prefix_unchecked("country_") {
294 if let Some(part) = part.strip_suffix_unchecked("_max_investment_add") {
295 maybe_warn(Item::Institution, &part, name, data, warn);
296 return Some(ModifKinds::Country);
297 }
298 }
299
300 if let Some(part) = name_lc.strip_prefix_unchecked("country_subsidies_") {
302 maybe_warn(Item::BuildingGroup, &part, name, data, warn);
303 if let Some(sev) = warn {
304 let msg = format!("`{name}` was removed in 1.7");
305 report(ErrorKey::Removed, sev).msg(msg).loc(name).push();
306 }
307 return Some(ModifKinds::Country);
308 }
309
310 if let Some(part) = name_lc.strip_prefix_unchecked("country_enactment_success_chance_") {
312 if let Some(part) = part.strip_suffix_unchecked("_add") {
313 maybe_warn(Item::LawType, &part, name, data, warn);
314 return Some(ModifKinds::Country);
315 }
316 }
317
318 for &pfx in &[
324 "country_allow_assimilation_",
325 "country_allow_conversion_",
326 "country_allow_voting_",
327 "country_disallow_government_work_",
328 "country_disallow_military_work_",
329 ] {
330 if let Some(part) = name_lc.strip_prefix_unchecked(pfx) {
331 if let Some(part) = part.strip_suffix_unchecked("_bool") {
332 maybe_warn(Item::AcceptanceStatus, &part, name, data, warn);
333 return Some(ModifKinds::Country);
334 }
335 }
336 }
337
338 if let Some(part) = name_lc.strip_prefix_unchecked("country_disallow_") {
340 if let Some(part) = part.strip_suffix_unchecked("_bool") {
341 maybe_warn(Item::LawType, &part, name, data, warn);
342 return Some(ModifKinds::Country);
343 }
344 }
345
346 for &pfx in &[
354 "country_assimilation_",
355 "country_loyalism_increases_",
356 "country_political_strength_",
357 "country_qualification_growth_",
358 "country_radicalism_increases_",
359 "country_voting_power_",
360 "country_wage_",
361 ] {
362 if let Some(part) = name_lc.strip_prefix_unchecked(pfx) {
363 if let Some(part) = part.strip_suffix_unchecked("_mult") {
364 maybe_warn(Item::AcceptanceStatus, &part, name, data, warn);
365 return Some(ModifKinds::Country);
366 }
367 }
368 }
369
370 if let Some(part) = name_lc.strip_prefix_unchecked("country_standard_of_living_") {
372 if let Some(part) = part.strip_suffix_unchecked("_add") {
373 maybe_warn(Item::AcceptanceStatus, &part, name, data, warn);
374 return Some(ModifKinds::Country);
375 }
376 }
377
378 if let Some(part) = name_lc.strip_prefix_unchecked("country_fervor_target_") {
380 if let Some(part) = part.strip_suffix_unchecked("_add") {
381 maybe_warn(Item::Culture, &part, name, data, warn);
382 return Some(ModifKinds::Country);
383 }
384 }
385
386 if let Some(part) = name_lc.strip_prefix_unchecked("country_") {
389 if let Some(part) = part.strip_suffix_unchecked("_cultural_acceptance_add") {
390 if let Some(sev) = warn {
391 if !data.item_exists_lc(Item::SocialClass, &part)
392 && !data.item_exists_lc(Item::Culture, &part)
393 {
394 let msg = format!("{part} not found as culture or social class");
395 let info = format!("so the modifier {name} will have no effect");
396 report(ErrorKey::MissingItem, sev).msg(msg).info(info).loc(name).push();
397 }
398 }
399 return Some(ModifKinds::Country);
400 }
401 }
402
403 if let Some(part) = name_lc.strip_prefix_unchecked("country_") {
413 for &sfx in &[
414 "_acceptance_max_add",
415 "_acceptance_min_add",
416 "_cultural_acceptance_add",
417 "_cultural_acceptance_mult",
418 "_education_access_add",
419 "_education_access_mult",
420 "_qualification_growth_add",
421 "_qualification_growth_mult",
422 "_qualification_growth_other_class",
423 "_qualification_growth_same_class",
424 ] {
425 if let Some(part) = part.strip_suffix_unchecked(sfx) {
426 maybe_warn(Item::SocialClass, &part, name, data, warn);
427 return Some(ModifKinds::Country);
428 }
429 }
430 }
431
432 if let Some(part) = name_lc.strip_prefix_unchecked("country_enactment_time_") {
434 if let Some(part) = part.strip_suffix_unchecked("_mult") {
435 maybe_warn(Item::LawType, &part, name, data, warn);
436 return Some(ModifKinds::Country);
437 }
438 }
439
440 if let Some(part) = name_lc.strip_prefix_unchecked("country_") {
443 if let Some(part) = part.strip_suffix_unchecked("_require_subsidies_bool") {
444 if let Some(sev) = warn {
445 if !data.item_exists_lc(Item::BuildingGroup, &part)
446 && !data.item_exists_lc(Item::BuildingType, &part)
447 {
448 let msg = format!("{part} not found as building type or building group");
449 let info = format!("so the modifier {name} will have no effect");
450 report(ErrorKey::MissingItem, sev).msg(msg).info(info).loc(name).push();
451 }
452 }
453 return Some(ModifKinds::Country);
454 }
455 }
456
457 if let Some(part) = name_lc.strip_prefix_unchecked("country_") {
464 for &sfx in &[
465 "_export_tariffs_rate_add",
466 "_import_tariffs_rate_add",
467 "_max_export_tariffs_level_add",
468 "_max_import_tariffs_level_add",
469 "_min_export_tariffs_level_add",
470 "_min_import_tariffs_level_add",
471 ] {
472 if let Some(part) = part.strip_suffix_unchecked(sfx) {
473 maybe_warn(Item::Goods, &part, name, data, warn);
474 return Some(ModifKinds::Country);
475 }
476 }
477 }
478
479 if let Some(part) = name_lc.strip_prefix_unchecked("interest_group_") {
483 for &sfx in &["_approval_add", "_pol_str_mult", "_pop_attraction_mult"] {
484 if let Some(part) = part.strip_suffix_unchecked(sfx) {
485 maybe_warn(Item::InterestGroup, &part, name, data, warn);
486 return Some(ModifKinds::InterestGroup);
487 }
488 }
489 }
490
491 if let Some(part) = name_lc.strip_prefix_unchecked("state_") {
494 if let Some(part) = part.strip_suffix_unchecked("_standard_of_living_add") {
495 if let Some(sev) = warn {
496 if !data.item_exists_lc(Item::Religion, &part)
497 && !data.item_exists_lc(Item::Culture, &part)
498 {
499 let msg = format!("{part} not found as culture or religion");
500 let info = format!("so the modifier {name} will have no effect");
501 report(ErrorKey::MissingItem, sev).msg(msg).info(info).loc(name).push();
502 }
503 }
504 return Some(ModifKinds::State);
505 }
506 }
507
508 if let Some(part) = name_lc.strip_prefix_unchecked("state_") {
516 for &sfx in &[
517 "_consumption_multiplier_add",
518 "_dependent_wage_mult",
519 "_internal_migration_disallowed_bool",
520 "_investment_pool_contribution_add",
521 "_investment_pool_efficiency_mult",
522 "_mass_migration_disallowed_bool",
523 "_mortality_mult",
524 ] {
525 if let Some(part) = part.strip_suffix_unchecked(sfx) {
526 maybe_warn(Item::PopType, &part, name, data, warn);
527 return Some(ModifKinds::State);
528 }
529 }
530 }
531
532 if let Some(part) = name_lc.strip_prefix_unchecked("state_pop_support_") {
535 for &sfx in &["_add", "_mult"] {
536 if let Some(part) = part.strip_suffix_unchecked(sfx) {
537 if data.item_exists_lc(Item::LawType, &part) {
538 if let Some(sev) = warn {
539 let msg = "support for law types has been replaced by support for political movements";
540 report(ErrorKey::Removed, sev).msg(msg).loc(name).push();
541 }
542 } else {
543 maybe_warn(Item::PoliticalMovement, &part, name, data, warn);
544 }
545 return Some(ModifKinds::State);
546 }
547 }
548 }
549
550 if let Some(part) = name_lc.strip_prefix_unchecked("state_sell_orders_") {
552 if let Some(part) = part.strip_suffix_unchecked("_add") {
553 maybe_warn(Item::Goods, &part, name, data, warn);
554 return Some(ModifKinds::State);
555 }
556 }
557 if let Some(part) = name_lc.strip_prefix_unchecked("state_buy_orders_") {
559 if let Some(part) = part.strip_suffix_unchecked("_add") {
560 maybe_warn(Item::Goods, &part, name, data, warn);
561 return Some(ModifKinds::State);
562 }
563 }
564
565 if let Some(part) = name_lc.strip_prefix_unchecked("state_") {
567 if let Some(part) = part.strip_suffix_unchecked("_max_level_add") {
568 maybe_warn(Item::BuildingType, &part, name, data, warn);
569
570 if let Some(sev) = warn {
571 if data.item_exists(Item::BuildingType, part.as_str())
572 && !data.item_has_property(Item::BuildingType, part.as_str(), "max_level")
573 {
574 let msg = format!("building {part} does not have `has_max_level = yes`");
575 let info = format!("so the modifier {name} will have no effect");
576 report(ErrorKey::MissingItem, sev)
577 .strong()
578 .msg(msg)
579 .info(info)
580 .loc(name)
581 .push();
582 }
583 }
584 return Some(ModifKinds::State);
585 }
586 }
587
588 if let Some(part) = name_lc.strip_prefix_unchecked("state_harvest_condition_") {
591 for &sfx in &["_duration_mult", "_impact_mult"] {
592 if let Some(part) = part.strip_suffix_unchecked(sfx) {
593 maybe_warn(Item::HarvestConditionType, &part, name, data, warn);
594 return Some(ModifKinds::State);
595 }
596 }
597 }
598
599 for &pfx in &["state_loyalism_increases_", "state_radicalism_increases_"] {
602 if let Some(part) = name_lc.strip_prefix_unchecked(pfx) {
603 if let Some(part) = part.strip_suffix_unchecked("_mult") {
604 maybe_warn(Item::AcceptanceStatus, &part, name, data, warn);
605 return Some(ModifKinds::State);
606 }
607 }
608 }
609
610 for &pfx in &["unit_defense_", "unit_offense_"] {
615 if let Some(part) = name_lc.strip_prefix_unchecked(pfx) {
616 for &sfx in &["_add", "_mult"] {
617 if let Some(part) = part.strip_suffix_unchecked(sfx) {
618 maybe_warn(Item::TerrainKey, &part, name, data, warn);
619 return Some(ModifKinds::UnitCombat);
620 }
621 }
622 }
623 }
624
625 if let Some(part) = name_lc.strip_prefix_unchecked("unit_") {
628 for &sfx in &["_offense_add", "_offense_mult"] {
629 if let Some(part) = part.strip_suffix_unchecked(sfx) {
630 maybe_warn(Item::CombatUnit, &part, name, data, warn);
631 return Some(ModifKinds::UnitCombat);
632 }
633 }
634 }
635
636 if let Some(part) = name_lc.strip_prefix_unchecked("power_bloc_invite_acceptance_") {
638 if let Some(part) = part.strip_suffix_unchecked("_add") {
639 maybe_warn(Item::CountryRank, &part, name, data, warn);
640 return Some(ModifKinds::PowerBloc);
641 }
642 }
643
644 if let Some(part) = name_lc.strip_prefix_unchecked("power_bloc_mandate_progress_per_") {
647 for &sfx in &["_member_add", "_member_mult"] {
648 if let Some(part) = part.strip_suffix_unchecked(sfx) {
649 maybe_warn(Item::CountryRank, &part, name, data, warn);
650 return Some(ModifKinds::PowerBloc);
651 }
652 }
653 }
654
655 None
658}
659
660fn maybe_warn(itype: Item, s: &Lowercase, name: &Token, data: &Everything, warn: Option<Severity>) {
661 if let Some(sev) = warn {
662 if !data.item_exists_lc(itype, s) {
663 let msg = format!("could not find {itype} {s}");
664 let info = format!("so the modifier {name} will have no effect");
665 report(ErrorKey::MissingItem, sev).strong().msg(msg).info(info).loc(name).push();
666 }
667 }
668}
669
670pub fn maybe_warn_modifiable_capitalization(name: &Token) {
671 if !name.is_lowercase() {
672 untidy(ErrorKey::DefinitionName)
673 .msg("item name contains capital letters, but modifier type definition names must be lowercase")
674 .info("so dynamic modifiers for this item will not be available")
675 .loc(name)
676 .push();
677 }
678}
679
680pub fn modif_loc_vic3(name: &Token, data: &Everything) -> (Cow<'static, str>, Cow<'static, str>) {
683 let name_lc = Lowercase::new(name.as_str());
684
685 if MODIF_MAP.contains_key(&name_lc) {
686 let desc_loc = format!("{name_lc}_desc");
687 return (name_lc.into_cow(), Cow::Owned(desc_loc));
688 }
689
690 if let Some(part) = name_lc.strip_prefix_unchecked("state_") {
691 if let Some(part) = part.strip_suffix_unchecked("_standard_of_living_add") {
692 if data.item_exists_lc(Item::Religion, &part) {
693 return (
694 Cow::Borrowed("STATE_RELIGION_SOL_MODIFIER"),
695 Cow::Borrowed("STATE_RELIGION_SOL_MODIFIER_DESC"),
696 );
697 } else if data.item_exists_lc(Item::Culture, &part) {
698 return (
699 Cow::Borrowed("STATE_CULTURE_SOL_MODIFIER"),
700 Cow::Borrowed("STATE_CULTURE_SOL_MODIFIER_DESC"),
701 );
702 }
703 return (
705 Cow::Borrowed("STATE_RELIGION_SOL_MODIFIER"),
706 Cow::Borrowed("STATE_RELIGION_SOL_MODIFIER_DESC"),
707 );
708 }
709 }
710
711 if let Some(part) = name_lc.strip_prefix_unchecked("country_fervor_target_") {
712 if part.strip_suffix_unchecked("_add").is_some() {
713 return (
714 Cow::Borrowed("COUNTRY_FERVOR_TARGET_CULTURE_MODIFIER"),
715 Cow::Borrowed("COUNTRY_FERVOR_TARGET_CULTURE_MODIFIER_DESC"),
716 );
717 }
718 }
719
720 if let Some(part) = name_lc.strip_prefix_unchecked("country_") {
721 if part.strip_suffix_unchecked("_cultural_acceptance_add").is_some() {
722 return (
723 Cow::Borrowed("COUNTRY_CULTURE_CULTURAL_ACCEPTANCE_MODIFIER"),
724 Cow::Borrowed("COUNTRY_CULTURE_CULTURAL_ACCEPTANCE_MODIFIER_DESC"),
725 );
726 }
727 }
728
729 let desc_loc = format!("{name}_desc");
731 (Cow::Borrowed(name.as_str()), Cow::Owned(desc_loc))
732}
733
734const MODIF_PREFIX_TABLE: [(&str, ModifKinds); 13] = [
735 ("character_", ModifKinds::Character),
736 ("country_", ModifKinds::Country),
737 ("state_", ModifKinds::State),
738 ("unit_", ModifKinds::Unit),
739 ("battle_", ModifKinds::Battle),
740 ("building_", ModifKinds::Building),
741 ("interest_group_", ModifKinds::InterestGroup),
742 ("market_", ModifKinds::Market),
743 ("political_movement_", ModifKinds::PoliticalMovement),
744 ("tax_", ModifKinds::Tax),
745 ("goods_", ModifKinds::Goods),
746 ("military_formation_", ModifKinds::MilitaryFormation),
747 ("power_bloc_", ModifKinds::PowerBloc),
748];
749
750static MODIF_MAP: LazyLock<TigerHashMap<Lowercase<'static>, ModifKinds>> = LazyLock::new(|| {
751 let mut hash = TigerHashMap::default();
752 for (s, kind) in MODIF_TABLE.iter().copied() {
753 hash.insert(Lowercase::new_unchecked(s), kind);
754 }
755 hash
756});
757
758const MODIF_TABLE: &[(&str, ModifKinds)] = &[
762 ("battle_casualties_mult", ModifKinds::Battle),
763 ("battle_combat_width_mult", ModifKinds::Battle),
764 ("battle_defense_owned_province_mult", ModifKinds::Battle),
765 ("battle_offense_owned_province_mult", ModifKinds::Battle),
766 ("battle_total_combat_width_mult", ModifKinds::Battle),
767 ("building_cash_reserves_mult", ModifKinds::Building),
768 ("building_company_government_dividends_add", ModifKinds::Building),
769 ("building_company_worker_dividends_add", ModifKinds::Building),
770 ("building_economy_of_scale_level_cap_add", ModifKinds::Building),
771 ("building_goods_input_mult", ModifKinds::Building),
772 ("building_job_attractiveness_mult", ModifKinds::Building),
773 ("building_level_bureaucracy_cost_add", ModifKinds::Building),
774 ("building_minimum_incorporated_subsistence_employment_add", ModifKinds::Building),
775 ("building_minimum_wage_mult", ModifKinds::Building),
776 ("building_mobilization_cost_mult", ModifKinds::Building),
777 ("building_nationalization_cost_mult", ModifKinds::Building),
778 ("building_nationalization_investment_return_add", ModifKinds::Building),
779 ("building_nationalization_radicals_mult", ModifKinds::Building),
780 ("building_self_investment_chance_add", ModifKinds::Building),
781 ("building_subsistence_output_add", ModifKinds::Building),
782 ("building_subsistence_output_mult", ModifKinds::Building),
783 ("building_throughput_add", ModifKinds::Building),
784 ("building_training_rate_add", ModifKinds::Building),
785 ("building_training_rate_mult", ModifKinds::Building),
786 ("building_unincorporated_subsistence_output_mult", ModifKinds::Building),
787 ("building_unincorporated_throughput_add", ModifKinds::Building),
788 ("building_working_conditions_mult", ModifKinds::Building),
789 ("character_advancement_speed_add", ModifKinds::Character),
793 ("character_advancement_speed_mult", ModifKinds::Character),
794 ("character_blockade_mult", ModifKinds::Character),
795 ("character_command_limit_add", ModifKinds::Character),
796 ("character_command_limit_mult", ModifKinds::Character),
797 ("character_convoy_protection_mult", ModifKinds::Character),
798 ("character_convoy_raiding_mult", ModifKinds::Character),
799 ("character_coup_strength_add", ModifKinds::Character),
800 ("character_coup_strength_mult", ModifKinds::Character),
801 ("character_expedition_events_explorer_mult", ModifKinds::Character),
802 ("character_health_add", ModifKinds::Character),
803 ("character_interception_add", ModifKinds::Character),
804 ("character_popularity_add", ModifKinds::Character),
805 ("character_supply_route_cost_mult", ModifKinds::MilitaryFormation),
806 ("country_acceptance_homeland_add", ModifKinds::Country),
807 ("country_acceptance_no_shared_heritage_trait_add", ModifKinds::Country),
808 ("country_acceptance_no_shared_language_trait_add", ModifKinds::Country),
809 ("country_acceptance_no_shared_religious_trait_add", ModifKinds::Country),
810 ("country_acceptance_no_shared_tradition_trait_add", ModifKinds::Country),
811 ("country_acceptance_not_homeland_add", ModifKinds::Country),
812 ("country_acceptance_primary_culture_add", ModifKinds::Country),
813 ("country_acceptance_shared_heritage_trait_add", ModifKinds::Country),
814 ("country_acceptance_shared_heritage_trait_group_add", ModifKinds::Country),
815 ("country_acceptance_shared_language_trait_add", ModifKinds::Country),
816 ("country_acceptance_shared_language_trait_group_add", ModifKinds::Country),
817 ("country_acceptance_shared_religious_trait_add", ModifKinds::Country),
818 ("country_acceptance_shared_religious_trait_group_add", ModifKinds::Country),
819 ("country_acceptance_shared_tradition_trait_add", ModifKinds::Country),
820 ("country_acceptance_state_religion_add", ModifKinds::Country),
821 ("country_agitator_slots_add", ModifKinds::Country),
822 ("country_ahead_of_time_research_penalty_mult", ModifKinds::Country),
823 ("country_all_buildings_protected_bool", ModifKinds::Country),
824 ("country_allow_enacting_decrees_in_subject_bool", ModifKinds::Country),
825 ("country_allow_multiple_alliances_bool", ModifKinds::Country),
826 ("country_amenability_add", ModifKinds::Country),
827 ("country_assimilation_delta_threshold_add", ModifKinds::Country),
828 ("country_authority_add", ModifKinds::Country),
829 ("country_authority_mult", ModifKinds::Country),
830 ("country_authority_per_subject_add", ModifKinds::Country),
831 ("country_block_government_reform_bool", ModifKinds::Country),
832 ("country_bolster_attraction_factor", ModifKinds::Country),
833 ("country_bolster_cost_mult", ModifKinds::Country),
834 ("country_bureaucracy_add", ModifKinds::Country),
835 ("country_bureaucracy_investment_cost_factor_mult", ModifKinds::Country),
836 ("country_bureaucracy_mult", ModifKinds::Country),
837 ("country_can_form_construction_company_bool", ModifKinds::Country),
838 ("country_can_only_conscript_peasants_bool", ModifKinds::Country),
839 ("country_cannot_be_target_for_law_imposition_bool", ModifKinds::Country),
840 ("country_cannot_cancel_law_enactment_bool", ModifKinds::Country),
841 ("country_cannot_enact_laws_bool", ModifKinds::Country),
842 ("country_cannot_start_law_enactment_bool", ModifKinds::Country),
843 ("country_company_construction_efficiency_bonus_add", ModifKinds::Country),
844 ("country_company_throughput_bonus_add", ModifKinds::Country),
845 ("country_construction_add", ModifKinds::Country),
846 ("country_construction_goods_cost_mult", ModifKinds::Country),
847 ("country_consumption_tax_cost_mult", ModifKinds::Country),
848 ("country_conversion_delta_threshold_add", ModifKinds::Country),
849 ("country_convoy_contribution_to_market_owner_add", ModifKinds::Country),
850 ("country_convoy_damage_taken_mult", ModifKinds::Country),
851 ("country_convoys_capacity_add", ModifKinds::Country),
852 ("country_convoys_capacity_mult", ModifKinds::Country),
853 ("country_coup_resistance_add", ModifKinds::Country),
854 ("country_coup_resistance_mult", ModifKinds::Country),
855 ("country_damage_relations_speed_mult", ModifKinds::Country),
856 ("country_diplomatic_play_maneuvers_add", ModifKinds::Country),
857 ("country_diplomatic_reputation_add", ModifKinds::Country),
858 ("country_disable_investment_pool_bool", ModifKinds::Country),
859 ("country_disable_nationalization_bool", ModifKinds::Country),
860 ("country_disable_nationalization_without_compensation_bool", ModifKinds::Country),
861 ("country_disable_non_company_privatization_bool", ModifKinds::Country),
862 ("country_disallow_aggressive_plays_bool", ModifKinds::Country),
863 ("country_disallow_agitator_invites_bool", ModifKinds::Country),
864 ("country_disallow_trade_bool", ModifKinds::Country),
865 ("country_disallow_trade_outside_canton_bool", ModifKinds::Country),
866 ("country_economic_dependence_on_overlord_add", ModifKinds::Country),
867 ("country_education_fervor_add", ModifKinds::Country),
868 ("country_electoral_confidence_impact_mult", ModifKinds::Country),
869 ("country_expedition_events_explorer_mult", ModifKinds::Country),
870 ("country_expenses_add", ModifKinds::Country),
871 ("country_financial_districts_buy_farms_likelyhood", ModifKinds::Country),
872 ("country_free_charters_add", ModifKinds::Country),
873 ("country_forbid_electoral_fraud_bool", ModifKinds::Country),
874 ("country_forbid_monopoly_bool", ModifKinds::Country),
875 ("country_force_privatization_bool", ModifKinds::Country),
876 ("country_foreign_collectivization_bool", ModifKinds::Country),
877 ("country_gold_reserve_limit_mult", ModifKinds::Country),
878 ("country_government_buildings_protected_bool", ModifKinds::Country),
879 ("country_government_dividends_efficiency_add", ModifKinds::Country),
880 ("country_government_dividends_reinvestment_add", ModifKinds::Country),
881 ("country_government_dividends_waste_add", ModifKinds::Country),
882 ("country_government_wages_mult", ModifKinds::Country),
883 ("country_higher_diplomatic_acceptance_same_religion_bool", ModifKinds::Country),
884 ("country_higher_leverage_from_economic_dependence_bool", ModifKinds::Country),
885 ("country_ignores_landing_craft_penalty_bool", ModifKinds::Country),
886 ("country_improve_relations_speed_mult", ModifKinds::Country),
887 ("country_infamy_decay_mult", ModifKinds::Country),
888 ("country_infamy_generation_mult", ModifKinds::Country),
889 ("country_infamy_generation_against_unrecognized_mult", ModifKinds::Country),
890 ("country_influence_add", ModifKinds::Country),
891 ("country_influence_mult", ModifKinds::Country),
892 ("country_initiator_war_goal_maneuver_cost_mult", ModifKinds::Country),
893 ("country_institution_size_change_speed_mult", ModifKinds::Country),
894 ("country_join_power_bloc_member_in_defensive_plays_bool", ModifKinds::Country),
895 ("country_join_power_bloc_member_in_plays_bool", ModifKinds::Country),
896 ("country_law_enactment_imposition_success_add", ModifKinds::Country),
897 ("country_law_enactment_max_setbacks_add", ModifKinds::Country),
898 ("country_law_enactment_stall_add", ModifKinds::Country),
899 ("country_law_enactment_stall_mult", ModifKinds::Country),
900 ("country_law_enactment_success_add", ModifKinds::Country),
901 ("country_law_enactment_time_mult", ModifKinds::Country),
902 ("country_leader_has_law_enactment_success_mult", ModifKinds::Country),
903 ("country_legitimacy_base_add", ModifKinds::Country),
904 ("country_legitimacy_govt_leader_clout_add", ModifKinds::Country),
905 ("country_legitimacy_govt_size_add", ModifKinds::Country),
906 ("country_legitimacy_govt_total_clout_add", ModifKinds::Country),
907 ("country_legitimacy_govt_total_votes_add", ModifKinds::Country),
908 ("country_legitimacy_headofstate_add", ModifKinds::Country),
909 ("country_legitimacy_ideological_incoherence_mult", ModifKinds::Country),
910 ("country_legitimacy_min_add", ModifKinds::Country),
911 ("country_leverage_generation_add", ModifKinds::Country),
912 ("country_leverage_generation_mult", ModifKinds::Country),
913 ("country_leverage_resistance_add", ModifKinds::Country),
914 ("country_leverage_resistance_mult", ModifKinds::Country),
915 ("country_liberty_desire_add", ModifKinds::Country),
916 ("country_liberty_desire_decrease_mult", ModifKinds::Country),
917 ("country_liberty_desire_increase_mult", ModifKinds::Country),
918 ("country_liberty_desire_of_subjects_mult", ModifKinds::Country),
919 ("country_loan_interest_rate_add", ModifKinds::Country),
920 ("country_loan_interest_rate_mult", ModifKinds::Country),
921 ("country_lobby_leverage_generation_mult", ModifKinds::Country),
922 ("country_loyalists_from_legitimacy_mult", ModifKinds::Country),
923 ("country_mass_migration_attraction_mult", ModifKinds::Country),
924 ("country_max_companies_add", ModifKinds::Country),
925 ("country_max_declared_interests_add", ModifKinds::Country),
926 ("country_max_declared_interests_mult", ModifKinds::Country),
927 ("country_max_weekly_construction_progress_add", ModifKinds::Country),
928 ("country_migration_restrictiveness_add", ModifKinds::Country),
929 ("country_military_goods_cost_mult", ModifKinds::Country),
930 ("country_military_tech_research_speed_mult", ModifKinds::Country),
931 ("country_military_tech_spread_mult", ModifKinds::Country),
932 ("country_military_wages_mult", ModifKinds::Country),
933 ("country_min_cultural_acceptance_add", ModifKinds::Country),
934 ("country_minting_add", ModifKinds::Country),
935 ("country_minting_mult", ModifKinds::Country),
936 ("country_must_have_movement_to_enact_laws_bool", ModifKinds::Country),
937 ("country_nationalization_cost_non_members_mult", ModifKinds::Country),
938 ("country_no_advantage_loss_from_lack_of_interest_bool", ModifKinds::Country),
939 ("country_non_state_religion_wages_mult", ModifKinds::Country),
940 ("country_opposition_ig_approval_add", ModifKinds::Country),
941 ("country_overlord_income_transfer_mult", ModifKinds::Country),
942 ("country_pact_leverage_generation_add", ModifKinds::Country),
943 ("country_pact_leverage_generation_mult", ModifKinds::Country),
944 ("country_party_whip_impact_add", ModifKinds::Country),
945 ("country_port_connection_cost_mult", ModifKinds::Country),
946 ("country_prestige_add", ModifKinds::Country),
947 ("country_prestige_from_army_power_projection_mult", ModifKinds::Country),
948 ("country_prestige_from_navy_power_projection_mult", ModifKinds::Country),
949 ("country_prestige_mult", ModifKinds::Country),
950 ("country_primary_culture_fervor_from_laws_add", ModifKinds::Country),
951 ("country_private_construction_allocation_mult", ModifKinds::Country),
952 ("country_production_tech_research_speed_mult", ModifKinds::Country),
953 ("country_production_tech_spread_mult", ModifKinds::Country),
954 ("country_radicals_from_conquest_mult", ModifKinds::Country),
955 ("country_radicals_from_legitimacy_mult", ModifKinds::Country),
956 ("country_reduced_liberty_desire_same_religion_bool", ModifKinds::Country),
957 ("country_resource_depletion_chance_mult", ModifKinds::Country),
958 ("country_resource_discovery_chance_mult", ModifKinds::Country),
959 ("country_revolution_clock_time_add", ModifKinds::Country),
960 ("country_revolution_progress_add", ModifKinds::Country),
961 ("country_revolution_progress_mult", ModifKinds::Country),
962 ("country_secession_clock_time_add", ModifKinds::Country),
963 ("country_secession_progress_add", ModifKinds::Country),
964 ("country_secession_progress_mult", ModifKinds::Country),
965 ("country_society_tech_research_speed_mult", ModifKinds::Country),
966 ("country_society_tech_spread_mult", ModifKinds::Country),
967 ("country_state_religion_wages_mult", ModifKinds::Country),
968 ("country_subject_income_transfer_heathen_mult", ModifKinds::Country),
969 ("country_subject_income_transfer_mult", ModifKinds::Country),
970 ("country_support_independence_weekly_liberty_desire_add", ModifKinds::Country),
971 ("country_support_separatism_resistance_mult", ModifKinds::Country),
972 ("country_support_separatism_separatism_mult", ModifKinds::Country),
973 ("country_suppression_attraction_factor", ModifKinds::Country),
974 ("country_suppression_cost_mult", ModifKinds::Country),
975 ("country_tax_income_add", ModifKinds::Country),
976 ("country_tech_group_research_speed_mult", ModifKinds::Country),
977 ("country_tech_research_speed_mult", ModifKinds::Country),
978 ("country_tech_spread_add", ModifKinds::Country),
979 ("country_tech_spread_mult", ModifKinds::Country),
980 ("country_tension_decay_mult", ModifKinds::Country),
981 ("country_treaty_leverage_generation_add", ModifKinds::Country),
982 ("country_treaty_leverage_generation_mult", ModifKinds::Country),
983 ("country_two_spains_conservative_drift_add", ModifKinds::Country),
984 ("country_two_spains_liberal_drift_add", ModifKinds::Country),
985 ("country_voting_power_base_add", ModifKinds::Country),
986 ("country_voting_power_from_literacy_add", ModifKinds::Country),
987 ("country_voting_power_mult", ModifKinds::Country),
988 ("country_voting_power_wealth_threshold_add", ModifKinds::Country),
989 ("country_war_exhaustion_casualties_mult", ModifKinds::Country),
990 ("country_weekly_innovation_add", ModifKinds::Country),
991 ("country_weekly_innovation_max_add", ModifKinds::Country),
992 ("country_weekly_innovation_mult", ModifKinds::Country),
993 ("country_yankee_and_dixie_cultures_obsessed_with_guns", ModifKinds::Country),
994 ("interest_group_amenability_add", ModifKinds::InterestGroup),
995 ("interest_group_approval_add", ModifKinds::InterestGroup),
996 ("interest_group_in_government_approval_add", ModifKinds::InterestGroup),
997 ("interest_group_in_government_attraction_mult", ModifKinds::InterestGroup),
998 ("interest_group_in_opposition_agitator_popularity_add", ModifKinds::InterestGroup),
999 ("interest_group_in_opposition_approval_add", ModifKinds::InterestGroup),
1000 ("interest_group_pol_str_factor", ModifKinds::InterestGroup),
1001 ("interest_group_pol_str_mult", ModifKinds::InterestGroup),
1002 ("interest_group_pop_attraction_mult", ModifKinds::InterestGroup),
1003 ("military_formation_attrition_risk_add", ModifKinds::MilitaryFormation),
1004 ("military_formation_attrition_risk_mult", ModifKinds::MilitaryFormation),
1005 ("military_formation_mobilization_speed_add", ModifKinds::MilitaryFormation),
1006 ("military_formation_mobilization_speed_mult", ModifKinds::MilitaryFormation),
1007 ("military_formation_movement_speed_add", ModifKinds::MilitaryFormation),
1008 ("military_formation_movement_speed_mult", ModifKinds::MilitaryFormation),
1009 ("military_formation_organization_gain_add", ModifKinds::MilitaryFormation),
1010 ("military_formation_organization_gain_mult", ModifKinds::MilitaryFormation),
1011 ("political_movement_character_attraction_mult", ModifKinds::PoliticalMovement),
1012 ("political_movement_pop_attraction_mult", ModifKinds::PoliticalMovement),
1013 ("political_movement_radicalism_add", ModifKinds::PoliticalMovement),
1014 ("political_movement_radicalism_from_enactment_approval_mult", ModifKinds::PoliticalMovement),
1015 (
1016 "political_movement_radicalism_from_enactment_disapproval_mult",
1017 ModifKinds::PoliticalMovement,
1018 ),
1019 ("power_bloc_allow_foreign_investment_lower_rank_bool", ModifKinds::PowerBloc),
1020 ("power_bloc_allow_wider_migration_area_bool", ModifKinds::PowerBloc),
1021 ("power_bloc_cohesion_add", ModifKinds::PowerBloc),
1022 ("power_bloc_cohesion_mult", ModifKinds::PowerBloc),
1023 ("power_bloc_cohesion_per_member_add", ModifKinds::PowerBloc),
1024 ("power_bloc_customs_union_bool", ModifKinds::PowerBloc),
1025 ("power_bloc_disallow_embargo_bool", ModifKinds::PowerBloc),
1026 ("power_bloc_disallow_war_bool", ModifKinds::PowerBloc),
1027 ("power_bloc_income_transfer_to_leader_factor", ModifKinds::PowerBloc),
1028 ("power_bloc_invite_acceptance_add", ModifKinds::PowerBloc),
1029 ("power_bloc_leader_can_add_wargoal_bool", ModifKinds::PowerBloc),
1030 ("power_bloc_leader_can_force_state_religion_bool", ModifKinds::PowerBloc),
1031 ("power_bloc_leader_can_make_subjects_bool", ModifKinds::PowerBloc),
1032 ("power_bloc_leader_can_regime_change_bool", ModifKinds::PowerBloc),
1033 ("power_bloc_leader_can_spread_culture_to_pb_bool", ModifKinds::PowerBloc),
1034 ("power_bloc_leverage_generation_mult", ModifKinds::PowerBloc),
1035 ("power_bloc_mandate_progress_mult", ModifKinds::PowerBloc),
1036 ("power_bloc_target_sway_cost_mult", ModifKinds::PowerBloc),
1037 ("power_bloc_trade_advantage_add", ModifKinds::PowerBloc),
1038 ("state_allow_assimilation_in_homeland_bool", ModifKinds::State),
1039 ("state_assimilation_mult", ModifKinds::State),
1040 ("state_birth_rate_mult", ModifKinds::State),
1041 ("state_blockade_resistance_add", ModifKinds::State),
1042 ("state_bureaucracy_population_base_cost_factor_mult", ModifKinds::State),
1043 ("state_colony_growth_creation_factor", ModifKinds::State),
1044 ("state_colony_growth_speed_mult", ModifKinds::State),
1045 ("state_conscription_rate_add", ModifKinds::State),
1046 ("state_conscription_rate_mult", ModifKinds::State),
1047 ("state_construction_mult", ModifKinds::State),
1048 ("state_contiguous_incorporation_speed_mult", ModifKinds::State),
1049 ("state_conversion_mult", ModifKinds::State),
1050 ("state_decree_cost_mult", ModifKinds::State),
1051 ("state_dependent_political_participation_add", ModifKinds::State),
1052 ("state_dependent_wage_add", ModifKinds::State),
1053 ("state_dependent_wage_mult", ModifKinds::State),
1054 ("state_devastation_decay_mult", ModifKinds::State),
1055 ("state_disallow_incorporation_bool", ModifKinds::State),
1056 ("state_education_access_add", ModifKinds::State),
1057 ("state_education_access_wealth_add", ModifKinds::State),
1058 ("state_expected_sol_from_literacy", ModifKinds::State),
1059 ("state_expected_sol_mult", ModifKinds::State),
1060 ("state_export_advantage_mult", ModifKinds::State),
1061 ("state_free_state_pop_support_movement_anti_slavery_mult", ModifKinds::State),
1062 ("state_food_security_add", ModifKinds::State),
1063 ("state_import_advantage_mult", ModifKinds::State),
1064 ("state_incorporation_speed_mult", ModifKinds::State),
1065 ("state_infrastructure_add", ModifKinds::State),
1066 ("state_infrastructure_from_automobiles_consumption_add", ModifKinds::State),
1067 ("state_infrastructure_from_population_add", ModifKinds::State),
1068 ("state_infrastructure_from_population_max_add", ModifKinds::State),
1069 ("state_infrastructure_from_population_max_mult", ModifKinds::State),
1070 ("state_infrastructure_from_population_mult", ModifKinds::State),
1071 ("state_infrastructure_mult", ModifKinds::State),
1072 ("state_institution_impact_add", ModifKinds::State),
1073 ("state_lower_strata_expected_sol_add", ModifKinds::State),
1074 ("state_lower_strata_standard_of_living_add", ModifKinds::State),
1075 ("state_loyalists_from_political_movements_mult", ModifKinds::State),
1076 ("state_max_trade_advantage_from_capacity_add", ModifKinds::State),
1077 ("state_middle_strata_expected_sol_add", ModifKinds::State),
1078 ("state_middle_strata_standard_of_living_add", ModifKinds::State),
1079 ("state_migration_pull_add", ModifKinds::State),
1080 ("state_migration_pull_mult", ModifKinds::State),
1081 ("state_migration_pull_unincorporated_mult", ModifKinds::State),
1082 ("state_migration_quota_mult", ModifKinds::State),
1083 ("state_market_access_price_impact", ModifKinds::State),
1084 ("state_minimum_incorporated_subsistence_arable_land_add", ModifKinds::State),
1085 ("state_mortality_mult", ModifKinds::State),
1086 ("state_mortality_turmoil_mult", ModifKinds::State),
1087 ("state_mortality_wealth_mult", ModifKinds::State),
1088 ("state_non_contiguous_incorporation_speed_mult", ModifKinds::State),
1089 ("state_non_homeland_colony_growth_speed_mult", ModifKinds::State),
1090 ("state_non_homeland_mortality_mult", ModifKinds::State),
1091 ("state_peasants_education_access_add", ModifKinds::State),
1092 ("state_political_strength_from_wealth_mult", ModifKinds::State),
1093 ("state_political_strength_from_welfare_mult", ModifKinds::State),
1094 ("state_pollution_generation_add", ModifKinds::State),
1095 ("state_pollution_reduction_health_mult", ModifKinds::State),
1096 ("state_pop_pol_str_add", ModifKinds::State),
1097 ("state_pop_pol_str_mult", ModifKinds::State),
1098 ("state_pop_qualifications_mult", ModifKinds::State),
1099 ("state_radicals_and_loyalists_from_sol_change_mult", ModifKinds::State),
1100 ("state_radicals_from_political_movements_mult", ModifKinds::State),
1101 ("state_slave_import_mult", ModifKinds::State),
1102 ("state_standard_of_living_add", ModifKinds::State),
1103 ("state_subvention_export_add", ModifKinds::State),
1104 ("state_subvention_import_add", ModifKinds::State),
1105 ("state_tariff_export_add", ModifKinds::State),
1106 ("state_tariff_import_add", ModifKinds::State),
1107 ("state_tax_capacity_add", ModifKinds::State),
1108 ("state_tax_capacity_mult", ModifKinds::State),
1109 ("state_tax_collection_mult", ModifKinds::State),
1110 ("state_tax_waste_add", ModifKinds::State),
1111 ("state_trade_advantage_from_capacity_add", ModifKinds::State),
1112 ("state_trade_advantage_mult", ModifKinds::State),
1113 ("state_trade_advantage_same_religion_add", ModifKinds::State),
1114 ("state_trade_capacity_add", ModifKinds::State),
1115 ("state_trade_capacity_mult", ModifKinds::State),
1116 ("state_trade_quantity_mult", ModifKinds::State),
1117 ("state_turmoil_effects_mult", ModifKinds::State),
1118 ("state_unincorporated_starting_wages_mult", ModifKinds::State),
1119 ("state_upper_strata_expected_sol_add", ModifKinds::State),
1120 ("state_upper_strata_standard_of_living_add", ModifKinds::State),
1121 ("state_urbanization_per_level_add", ModifKinds::State),
1122 ("state_urbanization_per_level_mult", ModifKinds::State),
1123 ("state_weekly_trades_add", ModifKinds::State),
1124 ("state_welfare_payments_add", ModifKinds::State),
1125 ("state_welfare_payments_mult", ModifKinds::State),
1126 ("state_working_adult_ratio_add", ModifKinds::State),
1127 ("tax_consumption_add", ModifKinds::Tax),
1128 ("tax_dividends_add", ModifKinds::Tax),
1129 ("tax_heathen_add", ModifKinds::Tax),
1130 ("tax_income_add", ModifKinds::Tax),
1131 ("tax_land_add", ModifKinds::Tax),
1132 ("tax_per_capita_add", ModifKinds::Tax),
1133 ("unit_army_defense_add", ModifKinds::UnitCombat),
1142 ("unit_army_defense_mult", ModifKinds::UnitCombat),
1143 ("unit_army_experience_gain_add", ModifKinds::Unit),
1144 ("unit_army_experience_gain_mult", ModifKinds::Unit),
1145 ("unit_army_offense_add", ModifKinds::UnitCombat),
1146 ("unit_army_offense_mult", ModifKinds::UnitCombat),
1147 ("unit_blockade_add", ModifKinds::UnitNonCombat),
1148 ("unit_blockade_mult", ModifKinds::UnitNonCombat),
1149 ("unit_convoy_defense_mult", ModifKinds::UnitNonCombat),
1150 ("unit_convoy_raiding_interception_mult", ModifKinds::UnitNonCombat),
1151 ("unit_convoy_raiding_mult", ModifKinds::UnitNonCombat),
1152 ("unit_defense_add", ModifKinds::UnitCombat),
1153 ("unit_defense_mult", ModifKinds::UnitCombat),
1154 ("unit_devastation_mult", ModifKinds::UnitCombat),
1155 ("unit_experience_gain_add", ModifKinds::Unit),
1156 ("unit_experience_gain_mult", ModifKinds::Unit),
1157 ("unit_kill_rate_add", ModifKinds::UnitCombat),
1158 ("unit_morale_damage_mult", ModifKinds::UnitCombat),
1159 ("unit_morale_loss_add", ModifKinds::UnitCombat),
1160 ("unit_morale_loss_mult", ModifKinds::UnitCombat),
1161 ("unit_morale_recovery_mult", ModifKinds::UnitNonCombat),
1162 ("unit_navy_defense_add", ModifKinds::UnitCombat),
1163 ("unit_navy_defense_mult", ModifKinds::UnitCombat),
1164 ("unit_navy_experience_gain_add", ModifKinds::Unit),
1165 ("unit_navy_experience_gain_mult", ModifKinds::Unit),
1166 ("unit_navy_offense_add", ModifKinds::UnitCombat),
1167 ("unit_navy_offense_mult", ModifKinds::UnitCombat),
1168 ("unit_occupation_mult", ModifKinds::UnitCombat),
1169 ("unit_offense_add", ModifKinds::UnitCombat),
1170 ("unit_offense_mult", ModifKinds::UnitCombat),
1171 ("unit_provinces_captured_mult", ModifKinds::UnitCombat),
1172 ("unit_provinces_lost_mult", ModifKinds::UnitCombat),
1173 ("unit_recovery_rate_add", ModifKinds::UnitCombat),
1174 ("unit_supply_consumption_mult", ModifKinds::UnitNonCombat), ];
1176
1177pub fn modif_scope_kind(scopes: Scopes) -> ModifKinds {
1178 let mut kinds = ModifKinds::empty();
1179
1180 for s in scopes {
1181 kinds.set(
1182 #[allow(clippy::match_same_arms)]
1184 match s {
1185 Scopes::Country => ModifKinds::Country,
1186 Scopes::Character => ModifKinds::Character,
1187 Scopes::State => ModifKinds::State,
1188 Scopes::Building => ModifKinds::Building,
1189 Scopes::Institution => ModifKinds::Country,
1190 Scopes::InterestGroup => ModifKinds::InterestGroup,
1191 Scopes::JournalEntry => ModifKinds::Country,
1192 Scopes::PoliticalMovement => ModifKinds::PoliticalMovement,
1193 Scopes::PowerBloc => ModifKinds::PowerBloc,
1194 _ => ModifKinds::empty(),
1195 },
1196 true,
1197 );
1198 }
1199 kinds
1200}
1201
1202pub static MODIF_FLOW_MAP: LazyLock<TigerHashMap<ModifKinds, ModifKinds>> = LazyLock::new(|| {
1205 let mut map = TigerHashMap::with_capacity(MODIF_FLOW_TABLE.len());
1206 for (a, b) in MODIF_FLOW_TABLE.iter().copied() {
1207 map.insert(a, b);
1208 }
1209 map
1210});
1211
1212const MODIF_FLOW_TABLE: &[(ModifKinds, ModifKinds)] = &[
1216 (
1217 ModifKinds::Character,
1221 ModifKinds::Character.union(ModifKinds::Battle).union(ModifKinds::UnitCombat),
1222 ),
1223 (
1224 ModifKinds::Country,
1225 ModifKinds::Country
1226 .union(ModifKinds::State)
1228 .union(ModifKinds::InterestGroup)
1229 .union(ModifKinds::MilitaryFormation)
1230 .union(ModifKinds::PoliticalMovement)
1231 .union(ModifKinds::Building)
1233 .union(ModifKinds::Battle)
1234 .union(ModifKinds::Tax)
1235 .union(ModifKinds::Goods)
1237 .union(ModifKinds::Unit),
1239 ),
1241 (
1242 ModifKinds::State,
1243 ModifKinds::State
1244 .union(ModifKinds::Building)
1246 .union(ModifKinds::Battle)
1247 .union(ModifKinds::Tax)
1248 .union(ModifKinds::Goods)
1250 .union(ModifKinds::UnitCombat),
1252 ),
1254 (
1255 ModifKinds::Unit,
1256 ModifKinds::Unit, ),
1258 (
1259 ModifKinds::Battle,
1260 ModifKinds::Battle
1261 .union(ModifKinds::UnitCombat),
1263 ),
1264 (
1265 ModifKinds::Building,
1266 ModifKinds::Building
1267 .union(ModifKinds::Goods),
1269 ),
1271 (ModifKinds::InterestGroup, ModifKinds::InterestGroup),
1272 (ModifKinds::Market, ModifKinds::Market),
1273 (ModifKinds::PoliticalMovement, ModifKinds::PoliticalMovement),
1274 (ModifKinds::Tariff, ModifKinds::Tariff),
1275 (ModifKinds::Tax, ModifKinds::Tax),
1276 (ModifKinds::Goods, ModifKinds::Goods),
1277 (
1278 ModifKinds::MilitaryFormation,
1279 ModifKinds::MilitaryFormation
1280 .union(ModifKinds::Unit)
1282 .union(ModifKinds::Character),
1283 ),
1285 (ModifKinds::PowerBloc, ModifKinds::PowerBloc),
1286];
1287
1288pub fn modif_flow_suggest(name: &str, kind: ModifKinds) -> Option<&'static str> {
1289 MODIF_FLOW_SUGGEST
1290 .get(name)
1291 .and_then(|&(other, other_kind)| other_kind.intersects(kind).then_some(other))
1292}
1293
1294static MODIF_FLOW_SUGGEST: LazyLock<TigerHashMap<&str, (&str, ModifKinds)>> = LazyLock::new(|| {
1295 let mut map = TigerHashMap::with_capacity(MODIF_FLOW_SUGGEST_TABLE.len() * 2);
1296 for &(a, b) in MODIF_FLOW_SUGGEST_TABLE {
1297 map.insert(a, (b, *MODIF_MAP.get(b).unwrap()));
1298 map.insert(b, (a, *MODIF_MAP.get(a).unwrap()));
1299 }
1300 map
1301});
1302
1303const MODIF_FLOW_SUGGEST_TABLE: &[(&str, &str)] = &[
1304 ("unit_blockade_mult", "character_blockade_mult"),
1305 ("unit_convoy_defense_mult", "character_convoy_protection_mult"),
1306 ("unit_convoy_raiding_mult", "character_convoy_raiding_mult"),
1307 ("unit_convoy_raiding_interception_mult", "character_interception_add"),
1308 ("unit_supply_consumption_mult", "building_mobilization_cost_mult"),
1309];
1310
1311static MODIF_REMOVED_MAP: LazyLock<TigerHashMap<Lowercase<'static>, &'static str>> =
1312 LazyLock::new(|| {
1313 let mut hash = TigerHashMap::default();
1314 for (s, info) in MODIF_REMOVED_TABLE.iter().copied() {
1315 hash.insert(Lowercase::new_unchecked(s), info);
1316 }
1317 hash
1318 });
1319
1320const MODIF_REMOVED_TABLE: &[(&str, &str)] = &[
1321 ("building_input_mult", "replaced in 1.5 with building_goods_input_mult"),
1322 ("building_throughput_mult", "replaced in 1.5 with building_throughput_add"),
1323 ("technology_invention_cost_mult", "replaced in 1.4.0 with country_tech_research_speed_mult"),
1324 (
1325 "country_production_tech_cost_mult",
1326 "replaced in 1.4.0 with country_production_tech_research_speed_mult",
1327 ),
1328 (
1329 "country_production_weekly_innovation_mult",
1330 "replaced in 1.4.0 with country_production_tech_research_speed_mult",
1331 ),
1332 (
1333 "country_military_tech_cost_mult",
1334 "replaced in 1.4.0 with country_military_tech_research_speed_mult",
1335 ),
1336 (
1337 "country_military_weekly_innovation_mult",
1338 "replaced in 1.4.0 with country_military_tech_research_speed_mult",
1339 ),
1340 (
1341 "country_society_tech_cost_mult",
1342 "replaced in 1.4.0 with country_society_tech_research_speed_mult",
1343 ),
1344 (
1345 "country_society_weekly_innovation_mult",
1346 "replaced in 1.4.0 with country_society_tech_research_speed_mult",
1347 ),
1348 ("country_trade_route_exports_add", "removed in 1.5"),
1349 ("country_trade_route_imports_add", "removed in 1.5"),
1350 (
1351 "country_army_power_projection_add",
1352 "replaced in 1.5 with country_prestige_from_army_power_projection_mult",
1353 ),
1354 (
1355 "country_army_power_projection_mult",
1356 "replaced in 1.5 with country_prestige_from_army_power_projection_mult",
1357 ),
1358 (
1359 "country_navy_power_projection_add",
1360 "replaced in 1.5 with country_prestige_from_navy_power_projection_mult",
1361 ),
1362 (
1363 "country_navy_power_projection_mult",
1364 "replaced in 1.5 with country_prestige_from_navy_power_projection_mult",
1365 ),
1366 ("character_attrition_risk_add", "removed in 1.5"),
1367 ("character_attrition_risk_mult", "removed in 1.5"),
1368 ("character_convoy_protection_add", "replaced in 1.5 with character_country_protection_mult"),
1369 ("character_convoy_raiding_add", "replaced in 1.5 with character_country_raiding_mult"),
1370 ("front_advancement_speed_add", "removed in 1.5"),
1371 ("front_advancement_speed_mult", "removed in 1.5"),
1372 ("front_enemy_advancement_speed_add", "removed in 1.5"),
1373 ("front_enemy_advancement_speed_mult", "removed in 1.5"),
1374 ("character_command_limit_combat_unit_conscript_add", "removed in 1.6"),
1375 ("character_command_limit_combat_unit_flotilla_add", "removed in 1.6"),
1376 ("character_command_limit_combat_unit_regular_add", "removed in 1.6"),
1377 ("building_government_shares_add", "removed in 1.7"),
1378 ("building_production_mult", "removed in 1.7"),
1379 ("building_throughput_oil_mult", "removed in 1.7"),
1380 ("building_workforce_shares_add", "removed in 1.7"),
1381 ("country_all_buildings_protected", "renamed to country_all_buildings_protected_bool in 1.7"),
1382 ("country_allow_multiple_alliances", "renamed to country_allow_multiple_alliances_bool in 1.7"),
1383 ("country_cannot_enact_laws", "renamed to country_cannot_enact_laws_bool in 1.7"),
1384 ("country_decree_cost_mult", "removed in 1.7"),
1385 ("country_disable_investment_pool", "renamed to country_disable_investment_pool_bool in 1.7"),
1386 (
1387 "country_disallow_aggressive_plays",
1388 "renamed to country_disallow_aggressive_plays_bool in 1.7",
1389 ),
1390 (
1391 "country_disallow_agitator_invites",
1392 "renamed to country_disallow_agitator_invites_bool in 1.7",
1393 ),
1394 (
1395 "country_disallow_discriminated_migration",
1396 "renamed to country_disallow_discriminated_migration_bool in 1.7",
1397 ),
1398 ("country_disallow_migration", "renamed to country_disallow_migration_bool in 1.7"),
1399 (
1400 "country_government_buildings_protected",
1401 "renamed to country_government_buildings_protected_bool in 1.7",
1402 ),
1403 (
1404 "country_ignores_landing_craft_penalty",
1405 "renamed to country_ignores_landing_craft_penalty_bool in 1.7",
1406 ),
1407 ("country_mandate_subsidies", "removed in 1.7"),
1408 (
1409 "country_must_have_movement_to_enact_laws",
1410 "renamed to country_must_have_movement_to_enact_laws_bool in 1.7",
1411 ),
1412 ("country_private_buildings_protected", "removed in 1.7"),
1413 ("country_promotion_ig_attraction_mult", "removed in 1.7"),
1414 ("country_subsidies_all", "removed in 1.7"),
1415 ("market_disallow_trade_routes", "renamed to market_disallow_trade_routes_bool in 1.7"),
1416 ("state_disallow_incorporation", "renamed to state_disallow_incorporation_bool in 1.7"),
1417 ("state_port_range_add", "removed in 1.7"),
1418 ("state_unincorporated_standard_of_living_add", "removed in 1.7"),
1419 ("state_urbanization_add", "removed in 1.7"),
1420 ("state_urbanization_mult", "removed in 1.7"),
1421 ("unit_mobilization_speed_mult", "removed in 1.7"),
1422 ("country_leverage_resistance_per_population_add", "removed in 1.7.1"),
1423 ("character_morale_cap_add", "removed in 1.8"),
1424 ("country_bolster_ig_attraction_mult", "removed in 1.8"),
1425 ("country_disallow_discriminated_migration_bool", "removed in 1.8"),
1426 ("country_disallow_migration_bool", "removed in 1.8"),
1427 ("country_force_collectivization_bool", "removed in 1.8"),
1428 ("country_suppression_ig_attraction_mult", "removed in 1.8"),
1429 ("political_movement_enact_support_mult", "removed in 1.8"),
1430 ("political_movement_preserve_support_mult", "removed in 1.8"),
1431 ("political_movement_radicalism_mult", "removed in 1.8"),
1432 ("political_movement_restore_support_mult", "removed in 1.8"),
1433 ("political_movement_support_add", "removed in 1.8"),
1434 ("political_movement_support_mult", "removed in 1.8"),
1435 ("state_accepted_birth_rate_mult", "removed in 1.8"),
1436 (
1437 "state_colony_growth_creation_mult",
1438 "replaced with state_colony_growth_creation_factor in 1.8",
1439 ),
1440 ("state_loyalists_from_sol_change_accepted_culture_mult", "removed in 1.8"),
1441 ("state_loyalists_from_sol_change_accepted_religion_mult", "removed in 1.8"),
1442 ("state_loyalists_from_sol_change_mult", "removed in 1.8"),
1443 ("state_middle_expected_sol", "removed in 1.8"),
1444 ("state_middle_standard_of_living_add", "removed in 1.8"),
1445 ("state_minimum_wealth_add", "removed in 1.8"),
1446 ("state_political_strength_from_discrimination_mult", "removed in 1.8"),
1447 ("state_poor_expected_sol", "removed in 1.8"),
1448 ("state_poor_standard_of_living_add", "removed in 1.8"),
1449 ("state_radicals_from_discrimination_mult", "removed in 1.8"),
1450 ("state_radicals_from_sol_change_accepted_culture_mult", "removed in 1.8"),
1451 ("state_radicals_from_sol_change_accepted_religion_mult", "removed in 1.8"),
1452 ("state_radicals_from_sol_change_mult", "removed in 1.8"),
1453 ("state_rich_expected_sol", "removed in 1.8"),
1454 ("state_rich_standard_of_living_add", "removed in 1.8"),
1455 ("country_allow_national_collectivization_bool", "removed in 1.8.4"),
1456 ("country_allow_trade_routes_without_interest_bool", "removed in 1.9"),
1457 ("country_bolster_attraction_mult", "changed to country_bolster_attraction_factor in 1.9"),
1458 ("country_company_pay_to_establish_bool", "removed in 1.9"),
1459 ("country_free_trade_routes_add", "removed in 1.9"),
1460 (
1461 "country_suppression_attraction_mult",
1462 "changed to country_suppression_attraction_factor in 1.9",
1463 ),
1464 ("country_trade_route_competitiveness_mult", "removed in 1.9"),
1465 ("country_trade_route_cost_mult", "removed in 1.9"),
1466 ("country_trade_route_quantity_mult", "removed in 1.9"),
1467 ("market_disallow_trade_routes_bool", "removed in 1.9"),
1468 ("market_land_trade_capacity_add", "removed in 1.9"),
1469 ("market_max_exports_add", "removed in 1.9"),
1470 ("market_max_imports_add", "removed in 1.9"),
1471 ("power_bloc_religion_trade_route_competitiveness_mult", "removed in 1.9"),
1472 ("power_bloc_trade_route_cost_mult", "removed in 1.9"),
1473 ("tariff_export_add", "removed in 1.9"),
1474 ("tariff_export_outside_power_bloc_mult", "removed in 1.9"),
1475 ("tariff_import_add", "removed in 1.9"),
1476 ("tariff_import_outside_power_bloc_mult", "removed in 1.9"),
1477 ("country_acceptance_culture_base_add", "replaced with new acceptance system in 1.10"),
1478 (
1479 "country_company_government_dividends_add",
1480 "replaced with `building_company_government_dividends_add` in 1.10.4",
1481 ),
1482 (
1483 "country_company_worker_dividends_add",
1484 "replaced with `building_company_worker_dividends_add` in 1.10.4",
1485 ),
1486 (
1487 "country_disable_privatization_bool",
1488 "replaced with `country_disable_non_company_privatization_bool` in 1.10.4",
1489 ),
1490 ("country_party_whip_impact_mult", "replaced with `country_party_whip_impact_add` in 1.10.4"),
1491 ("state_migration_push_mult", "removed in 1.12"),
1492 ("unit_advancement_speed_mult", "removed in 1.12"),
1493 ("unit_convoy_requirements_mult", "removed in 1.12"),
1494];