1use crate::block::Block;
2use crate::context::ScopeContext;
3use crate::db::{Db, DbKind};
4use crate::everything::Everything;
5use crate::game::GameFlags;
6use crate::item::{Item, ItemLoader};
7use crate::scopes::Scopes;
8use crate::script_value::validate_script_value;
9use crate::token::Token;
10use crate::tooltipped::Tooltipped;
11use crate::validator::Validator;
12use crate::vic3::tables::modifs::maybe_warn_modifiable_capitalization;
13
14#[derive(Clone, Debug)]
15pub struct PoliticalMovement {}
16
17inventory::submit! {
18 ItemLoader::Normal(GameFlags::Vic3, Item::PoliticalMovement, PoliticalMovement::add)
19}
20
21impl PoliticalMovement {
22 pub fn add(db: &mut Db, key: Token, block: Block) {
23 db.add(Item::PoliticalMovement, key, block, Box::new(Self {}));
24 }
25}
26
27impl DbKind for PoliticalMovement {
28 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
29 maybe_warn_modifiable_capitalization(key);
30
31 let mut vd = Validator::new(block, data);
32
33 data.verify_exists(Item::Localization, key);
34 let loca = format!("{key}_name");
35 data.verify_exists_implied(Item::Localization, &loca, key);
36
37 vd.field_item("category", Item::PoliticalMovementCategory);
38 vd.field_item("ideology", Item::Ideology);
39 vd.field_list_items("character_ideologies", Item::Ideology);
40
41 vd.field_trigger_rooted("creation_trigger", Tooltipped::No, Scopes::Country);
42 vd.field_script_value_rooted("creation_weight", Scopes::Country);
43 vd.field_effect_rooted("on_created", Tooltipped::No, Scopes::PoliticalMovement);
44
45 vd.field_trigger_builder("culture_selection_trigger", Tooltipped::No, |key| {
46 let mut sc = ScopeContext::new(Scopes::Culture, key);
47 sc.define_name("country", Scopes::Country, key);
48 sc
49 });
50 vd.field_script_value_builder("culture_selection_weight", |key| {
51 let mut sc = ScopeContext::new(Scopes::Culture, key);
52 sc.define_name("country", Scopes::Country, key);
53 sc
54 });
55
56 vd.field_trigger_builder("religion_selection_trigger", Tooltipped::No, |key| {
57 let mut sc = ScopeContext::new(Scopes::Religion, key);
58 sc.define_name("country", Scopes::Country, key);
59 sc
60 });
61 vd.field_script_value_builder("religion_selection_weight", |key| {
62 let mut sc = ScopeContext::new(Scopes::Religion, key);
63 sc.define_name("country", Scopes::Country, key);
64 sc
65 });
66
67 vd.field_trigger_builder("character_support_trigger", Tooltipped::No, |key| {
68 let mut sc = ScopeContext::new(Scopes::Character, key);
69 sc.define_name("culture", Scopes::Culture, key);
70 sc.define_name("religion", Scopes::Religion, key);
71 sc.define_name("interest_group", Scopes::InterestGroup, key);
72 sc
73 });
74 vd.field_script_value_builder("character_support_weight", |key| {
75 let mut sc = ScopeContext::new(Scopes::Character, key);
76 sc.define_name("culture", Scopes::Culture, key);
77 sc.define_name("religion", Scopes::Religion, key);
78 sc
79 });
80
81 vd.field_trigger_rooted(
82 "can_pressure_interest_group",
83 Tooltipped::No,
84 Scopes::InterestGroup,
85 );
86
87 vd.field_trigger_builder("pop_support_trigger", Tooltipped::No, |key| {
88 let mut sc = ScopeContext::new(Scopes::Pop, key);
89 sc.define_name("culture", Scopes::Culture, key);
90 sc.define_name("religion", Scopes::Religion, key);
91 sc
92 });
93 vd.field_list_items("pop_support_factors", Item::PoliticalMovementPopSupport);
94 vd.field_script_value_builder("pop_support_weight", |key| {
95 let mut sc = ScopeContext::new(Scopes::Pop, key);
96 sc.define_name("culture", Scopes::Culture, key);
97 sc.define_name("religion", Scopes::Religion, key);
98 sc
99 });
100
101 for field in &["revolution", "secession"] {
102 vd.field_validated_block(field, |block, data| {
103 let mut vd = Validator::new(block, data);
104 vd.field_trigger_builder("possible", Tooltipped::No, |key| {
105 let mut sc = ScopeContext::new(Scopes::PoliticalMovement, key);
106 sc.define_name("clout", Scopes::Value, key);
107 sc
108 });
109 vd.field_script_value_builder("weight", |key| {
110 let mut sc = ScopeContext::new(Scopes::PoliticalMovement, key);
111 sc.define_name("clout", Scopes::Value, key);
112 sc
113 });
114 vd.field_validated_block("forced_tags", |block, data| {
115 let mut vd = Validator::new(block, data);
116 vd.unknown_block_fields(|key, block| {
117 data.verify_exists(Item::Country, key);
118 let mut vd = Validator::new(block, data);
119 vd.field_trigger_rooted(
120 "trigger",
121 Tooltipped::No,
122 Scopes::PoliticalMovement,
123 );
124 vd.field_script_value_rooted("weight", Scopes::PoliticalMovement);
125 });
126 });
127 vd.field_trigger_builder("interest_group_can_join", Tooltipped::No, |key| {
128 let mut sc = ScopeContext::new(Scopes::InterestGroup, key);
129 sc.define_name("political_movement", Scopes::PoliticalMovement, key);
130 sc
131 });
132 vd.field_validated_key("state_weight", |key, bv, data| {
133 let mut sc = ScopeContext::new(Scopes::State, key);
134 sc.define_name("political_movement", Scopes::PoliticalMovement, key);
135 sc.define_name("clout", Scopes::Value, key);
136 validate_script_value(bv, data, &mut sc);
137 });
138 vd.field_validated_key("target_fraction_of_states", |key, bv, data| {
139 let mut sc = ScopeContext::new(Scopes::PoliticalMovement, key);
140 sc.define_name("clout", Scopes::Value, key);
141 validate_script_value(bv, data, &mut sc);
142 });
143 });
144 }
145
146 vd.field_script_value_rooted(
147 "law_enactment_radicalism_multiplier",
148 Scopes::PoliticalMovement,
149 );
150 vd.field_script_value_rooted("active_law_radicalism_multiplier", Scopes::PoliticalMovement);
151 vd.field_validated_key("additional_radicalism_factors", |key, bv, data| {
152 let mut sc = ScopeContext::new(Scopes::PoliticalMovement, key);
153 sc.define_name("culture", Scopes::Culture, key);
154 sc.define_name("religion", Scopes::Religion, key);
155 validate_script_value(bv, data, &mut sc);
156 });
157
158 vd.field_trigger_rooted("disband_trigger", Tooltipped::No, Scopes::Country);
161 vd.field_effect_rooted("on_disbanded", Tooltipped::No, Scopes::Country);
162 vd.field_bool("can_have_slave_supporters");
163 vd.field_bool("can_cause_obstinance");
164 }
165}
166
167#[derive(Clone, Debug)]
168pub struct PoliticalMovementCategory {}
169
170inventory::submit! {
171 ItemLoader::Normal(GameFlags::Vic3, Item::PoliticalMovementCategory, PoliticalMovementCategory::add)
172}
173
174impl PoliticalMovementCategory {
175 pub fn add(db: &mut Db, key: Token, block: Block) {
176 db.add(Item::PoliticalMovementCategory, key, block, Box::new(Self {}));
177 }
178}
179
180impl DbKind for PoliticalMovementCategory {
181 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
182 let mut vd = Validator::new(block, data);
183
184 let loca = format!("{key}_icon");
185 data.verify_exists_implied(Item::Localization, &loca, key);
186
187 vd.field_item("icon", Item::File);
188 vd.field_bool("cultural_identity");
189 vd.field_bool("religious_identity");
190 vd.field_bool("minimum_support_is_within_identity");
191 vd.field_numeric("minimum_support_to_create");
192 vd.field_numeric("minimum_support_to_maintain");
193
194 vd.field_numeric("sorting_order");
197 }
198}
199
200#[derive(Clone, Debug)]
201pub struct PoliticalMovementPopSupport {}
202
203inventory::submit! {
204 ItemLoader::Normal(GameFlags::Vic3, Item::PoliticalMovementPopSupport, PoliticalMovementPopSupport::add)
205}
206
207impl PoliticalMovementPopSupport {
208 pub fn add(db: &mut Db, key: Token, block: Block) {
209 db.add(Item::PoliticalMovementPopSupport, key, block, Box::new(Self {}));
210 }
211}
212
213impl DbKind for PoliticalMovementPopSupport {
214 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
215 let mut vd = Validator::new(block, data);
216
217 vd.field_item("name", Item::Localization);
218
219 vd.field_trigger_rooted("visible", Tooltipped::No, Scopes::PoliticalMovement);
220 }
221}