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 validate_script_value(bv, data, &mut sc);
136 });
137 vd.field_validated_key("target_fraction_of_states", |key, bv, data| {
138 let mut sc = ScopeContext::new(Scopes::PoliticalMovement, key);
139 sc.define_name("clout", Scopes::Value, key);
140 validate_script_value(bv, data, &mut sc);
141 });
142 });
143 }
144
145 vd.field_script_value_rooted(
146 "law_enactment_radicalism_multiplier",
147 Scopes::PoliticalMovement,
148 );
149 vd.field_script_value_rooted("active_law_radicalism_multiplier", Scopes::PoliticalMovement);
150 vd.field_validated_key("additional_radicalism_factors", |key, bv, data| {
151 let mut sc = ScopeContext::new(Scopes::PoliticalMovement, key);
152 sc.define_name("culture", Scopes::Culture, key);
153 sc.define_name("religion", Scopes::Religion, key);
154 validate_script_value(bv, data, &mut sc);
155 });
156
157 vd.field_trigger_rooted("disband_trigger", Tooltipped::No, Scopes::Country);
160 vd.field_effect_rooted("on_disbanded", Tooltipped::No, Scopes::Country);
161 vd.field_bool("can_have_slave_supporters");
162 vd.field_bool("can_cause_obstinance");
163 }
164}
165
166#[derive(Clone, Debug)]
167pub struct PoliticalMovementCategory {}
168
169inventory::submit! {
170 ItemLoader::Normal(GameFlags::Vic3, Item::PoliticalMovementCategory, PoliticalMovementCategory::add)
171}
172
173impl PoliticalMovementCategory {
174 pub fn add(db: &mut Db, key: Token, block: Block) {
175 db.add(Item::PoliticalMovementCategory, key, block, Box::new(Self {}));
176 }
177}
178
179impl DbKind for PoliticalMovementCategory {
180 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
181 let mut vd = Validator::new(block, data);
182
183 let loca = format!("{key}_icon");
184 data.verify_exists_implied(Item::Localization, &loca, key);
185
186 vd.field_item("icon", Item::File);
187 vd.field_bool("cultural_identity");
188 vd.field_bool("religious_identity");
189 vd.field_bool("minimum_support_is_within_identity");
190 vd.field_numeric("minimum_support_to_create");
191 vd.field_numeric("minimum_support_to_maintain");
192
193 vd.field_numeric("sorting_order");
196 }
197}
198
199#[derive(Clone, Debug)]
200pub struct PoliticalMovementPopSupport {}
201
202inventory::submit! {
203 ItemLoader::Normal(GameFlags::Vic3, Item::PoliticalMovementPopSupport, PoliticalMovementPopSupport::add)
204}
205
206impl PoliticalMovementPopSupport {
207 pub fn add(db: &mut Db, key: Token, block: Block) {
208 db.add(Item::PoliticalMovementPopSupport, key, block, Box::new(Self {}));
209 }
210}
211
212impl DbKind for PoliticalMovementPopSupport {
213 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
214 let mut vd = Validator::new(block, data);
215
216 vd.field_item("name", Item::Localization);
217
218 vd.field_trigger_rooted("visible", Tooltipped::No, Scopes::PoliticalMovement);
219 }
220}