Project Alice
Loading...
Searching...
No Matches
politics.cpp
Go to the documentation of this file.
1#include "politics.hpp"
2#include "dcon_generated.hpp"
3#include "demographics.hpp"
4#include "effects.hpp"
5#include "prng.hpp"
7#include "triggers.hpp"
8
9namespace politics {
10
11float vote_total(sys::state& state, dcon::nation_id nation) {
12 float total = 0.f;
13 state.world.for_each_province([&](dcon::province_id province) {
14 if(nation == state.world.province_get_nation_from_province_ownership(province)) {
15 for(auto pop_loc : state.world.province_get_pop_location(province)) {
16 auto pop_id = pop_loc.get_pop();
17 total += pop_vote_weight(state, pop_id, nation);
18 }
19 }
20 });
21 return total;
22}
23
24float get_popular_support(sys::state& state, dcon::nation_id nation, dcon::issue_option_id issue_option) {
25 auto total = state.world.nation_get_demographics(nation, demographics::total);
26 if(total <= 0.f) {
27 return 0.f;
28 }
29 auto dkey = demographics::to_key(state, issue_option);
30 return state.world.nation_get_demographics(nation, dkey) / total;
31}
32
33float get_voter_support(sys::state& state, dcon::nation_id nation, dcon::issue_option_id issue_option) {
34 auto total = vote_total(state, nation);
35 if(total <= 0.f) {
36 return 0.f;
37 }
38 auto support = 0.f;
39 auto dkey = pop_demographics::to_key(state, issue_option);
40
41 for(auto province : state.world.nation_get_province_ownership(nation)) {
42 for(auto pop_loc : province.get_province().get_pop_location()) {
43 auto pop_id = pop_loc.get_pop();
44 auto vote_size = pop_vote_weight(state, pop_id, nation);
45 support += vote_size * state.world.pop_get_demographics(pop_id.id, dkey);
46 }
47 }
48 return support / total;
49}
50
51bool can_appoint_ruling_party(sys::state& state, dcon::nation_id nation) {
52 return dcon::fatten(state.world, nation).get_government_type().get_can_appoint_ruling_party();
53}
54
55bool is_election_ongoing(sys::state& state, dcon::nation_id nation) {
56 auto election_end_date = dcon::fatten(state.world, nation).get_election_ends();
57 return election_end_date && election_end_date > state.current_date;
58}
59
60bool has_elections(sys::state& state, dcon::nation_id nation) {
61 return dcon::fatten(state.world, nation).get_government_type().get_has_elections();
62}
63
64sys::date next_election_date(sys::state& state, dcon::nation_id nation) {
65 auto end_date = state.world.nation_get_election_ends(nation);
66 return end_date + int32_t(30.5f * state.world.nation_get_government_type(nation).get_duration());
67}
68
69dcon::reform_id get_reform_by_name(sys::state& state, std::string_view name) {
70 dcon::reform_id result{};
71 auto it = state.lookup_key(name);
72 if(it) {
73 state.world.for_each_reform([&](dcon::reform_id reform_id) {
74 auto key = state.world.reform_get_name(reform_id);
75 if(it == key) {
76 result = reform_id;
77 }
78 });
79 }
80 return result;
81}
82
83dcon::issue_id get_issue_by_name(sys::state& state, std::string_view name) {
84 dcon::issue_id result{};
85 auto it = state.lookup_key(name);
86 if(it) {
87 state.world.for_each_issue([&](dcon::issue_id issue_id) {
88 auto key = state.world.issue_get_name(issue_id);
89 if(it == key) {
90 result = issue_id;
91 }
92 });
93 }
94 return result;
95}
96
97bool reform_is_selected(sys::state& state, dcon::nation_id nation, dcon::reform_option_id reform_option) {
98 auto reform = state.world.reform_option_get_parent_reform(reform_option);
99 return reform && reform_option == state.world.nation_get_reforms(nation, reform);
100}
101
102bool issue_is_selected(sys::state& state, dcon::nation_id nation, dcon::issue_option_id issue_option) {
103 auto issue = state.world.issue_option_get_parent_issue(issue_option);
104 return issue && issue_option == state.world.nation_get_issues(nation, issue);
105}
106
107bool can_enact_political_reform(sys::state& state, dcon::nation_id nation, dcon::issue_option_id issue_option) {
108 if(!issue_option)
109 return false;
110
111 auto issue = state.world.issue_option_get_parent_issue(issue_option);
112 auto current = state.world.nation_get_issues(nation, issue.id).id;
113 auto allow = state.world.issue_option_get_allow(issue_option);
114 auto time_limit = state.world.nation_get_last_issue_or_reform_change(nation);
115 auto tag = state.world.nation_get_identity_from_identity_holder(nation);
116 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
117 auto end = start + state.world.national_identity_get_political_party_count(tag);
118 auto count_party_issues = state.world.political_party_get_party_issues_size();
119
120 if(current != issue_option && (!time_limit || (time_limit + int32_t(state.defines.min_delay_between_reforms * 30) <= state.current_date)) &&
121 (!state.world.issue_get_is_next_step_only(issue.id) || current.index() + 1 == issue_option.index() ||
122 current.index() - 1 == issue_option.index()) &&
123 (!allow || trigger::evaluate(state, allow, trigger::to_generic(nation), trigger::to_generic(nation), 0))) {
124
125 float total = 0.0f;
126 for(uint32_t icounter = state.world.ideology_size(); icounter-- > 0;) {
127 dcon::ideology_id iid{dcon::ideology_id::value_base_t(icounter)};
128 auto condition = issue_option.index() > current.index() ? state.world.ideology_get_add_political_reform(iid) : state.world.ideology_get_remove_political_reform(iid);
129 auto upperhouse_weight = 0.01f * state.world.nation_get_upper_house(nation, iid);
130
131 float party_special_issues_support_total = 0.0f;
132 float count_found = 0.0f;
133
134 for(int32_t i = start; i < end; i++) {
135 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
136 if(politics::political_party_is_active(state, nation, pid)
137 && (state.world.nation_get_government_type(nation).get_ideologies_allowed() & culture::to_bits(state.world.political_party_get_ideology(pid))) != 0
138 && state.world.political_party_get_ideology(pid) == iid) {
139
140 for(uint32_t j = 0; j < count_party_issues; ++j) {
141 auto popt = state.world.political_party_get_party_issues(pid, dcon::issue_id{ dcon::issue_id::value_base_t(j) });
142 auto opt_mod = state.world.issue_option_get_support_modifiers(popt, issue_option);
143
144 if(opt_mod) {
145 party_special_issues_support_total += upperhouse_weight* trigger::evaluate_additive_modifier(state, opt_mod, trigger::to_generic(nation), trigger::to_generic(nation), 0);
146 count_found += 1.0f;
147 }
148 }
149
150 break; // only look at one active party per ideology
151 }
152 }
153
154 if(count_found > 0.0f)
155 total += std::clamp(party_special_issues_support_total / count_found, -1.0f, 1.0f);
156 else if(condition && upperhouse_weight > 0.0f)
157 total += upperhouse_weight * std::clamp(trigger::evaluate_additive_modifier(state, condition, trigger::to_generic(nation), trigger::to_generic(nation), 0), -1.0f, 1.0f);
158 if(total > 0.5f)
159 return true;
160 }
161 }
162 return false;
163}
164
165bool can_enact_social_reform(sys::state& state, dcon::nation_id n, dcon::issue_option_id o) {
166 if(!o)
167 return false;
168
169 auto issue = state.world.issue_option_get_parent_issue(o);
170 auto current = state.world.nation_get_issues(n, issue.id).id;
171 auto allow = state.world.issue_option_get_allow(o);
172 auto time_limit = state.world.nation_get_last_issue_or_reform_change(n);
173 auto tag = state.world.nation_get_identity_from_identity_holder(n);
174 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
175 auto end = start + state.world.national_identity_get_political_party_count(tag);
176 auto count_party_issues = state.world.political_party_get_party_issues_size();
177
178 if(current != o && (!time_limit || (time_limit + int32_t(state.defines.min_delay_between_reforms * 30) <= state.current_date)) &&
179 (!state.world.issue_get_is_next_step_only(issue.id) || current.index() + 1 == o.index() ||
180 current.index() - 1 == o.index()) &&
181 (!allow || trigger::evaluate(state, allow, trigger::to_generic(n), trigger::to_generic(n), 0))) {
182
183 float total = 0.0f;
184 for(uint32_t icounter = state.world.ideology_size(); icounter-- > 0;) {
185 dcon::ideology_id iid{dcon::ideology_id::value_base_t(icounter)};
186 auto condition = o.index() > current.index() ? state.world.ideology_get_add_social_reform(iid) : state.world.ideology_get_remove_social_reform(iid);
187 auto upperhouse_weight = 0.01f * state.world.nation_get_upper_house(n, iid);
188
189 float party_special_issues_support_total = 0.0f;
190 float count_found = 0.0f;
191
192 for(int32_t i = start; i < end; i++) {
193 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
195 && (state.world.nation_get_government_type(n).get_ideologies_allowed() & culture::to_bits(state.world.political_party_get_ideology(pid))) != 0
196 && state.world.political_party_get_ideology(pid) == iid) {
197
198 for(uint32_t j = 0; j < count_party_issues; ++j) {
199 auto popt = state.world.political_party_get_party_issues(pid, dcon::issue_id{ dcon::issue_id::value_base_t(j) });
200 auto opt_mod = state.world.issue_option_get_support_modifiers(popt, o);
201
202 if(opt_mod) {
203 party_special_issues_support_total += upperhouse_weight * trigger::evaluate_additive_modifier(state, opt_mod, trigger::to_generic(n), trigger::to_generic(n), 0);
204 count_found += 1.0f;
205 }
206 }
207
208 break; // only look at one active party per ideology
209 }
210 }
211
212 if(count_found > 0.0f)
213 total += std::clamp(party_special_issues_support_total / count_found, -1.0f, 1.0f);
214 else if(condition && upperhouse_weight > 0.0f)
215 total += upperhouse_weight * std::clamp(trigger::evaluate_additive_modifier(state, condition, trigger::to_generic(n), trigger::to_generic(n), 0), -1.0f, 1.0f);
216 if(total > 0.5f)
217 return true;
218 }
219 }
220 return false;
221}
222
223bool can_enact_military_reform(sys::state& state, dcon::nation_id n, dcon::reform_option_id o) {
224 if(!o)
225 return false;
226
227 auto reform = state.world.reform_option_get_parent_reform(o);
228 auto current = state.world.nation_get_reforms(n, reform.id).id;
229 auto allow = state.world.reform_option_get_allow(o);
230 auto stored_rp = state.world.nation_get_research_points(n);
231 if(o.index() > current.index() && (!state.world.reform_get_is_next_step_only(reform.id) || current.index() + 1 == o.index()) &&
232 (!allow || trigger::evaluate(state, allow, trigger::to_generic(n), trigger::to_generic(n), 0))) {
233
234 float base_cost = float(state.world.reform_option_get_technology_cost(o));
235 float reform_factor = politics::get_military_reform_multiplier(state, n);
236
237 if(base_cost * reform_factor <= stored_rp)
238 return true;
239 }
240 return false;
241}
242
243bool can_enact_economic_reform(sys::state& state, dcon::nation_id n, dcon::reform_option_id o) {
244 if(!o)
245 return false;
246
247 auto reform = state.world.reform_option_get_parent_reform(o);
248 auto current = state.world.nation_get_reforms(n, reform.id).id;
249 auto allow = state.world.reform_option_get_allow(o);
250 auto stored_rp = state.world.nation_get_research_points(n);
251 if(o.index() > current.index() && (!state.world.reform_get_is_next_step_only(reform.id) || current.index() + 1 == o.index()) &&
252 (!allow || trigger::evaluate(state, allow, trigger::to_generic(n), trigger::to_generic(n), 0))) {
253
254 float base_cost = float(state.world.reform_option_get_technology_cost(o));
255 float reform_factor = politics::get_economic_reform_multiplier(state, n);
256
257 if(base_cost * reform_factor <= stored_rp)
258 return true;
259 }
260 return false;
261}
262
263float get_military_reform_multiplier(sys::state& state, dcon::nation_id n) {
264 float reform_factor = 1.0f +
265 state.world.nation_get_modifier_values(n, sys::national_mod_offsets::self_unciv_military_modifier) +
266 state.world.nation_get_modifier_values(state.world.nation_get_in_sphere_of(n), sys::national_mod_offsets::unciv_military_modifier);
267
268 for(uint32_t icounter = state.world.ideology_size(); icounter-- > 0;) {
269 dcon::ideology_id iid{dcon::ideology_id::value_base_t(icounter)};
270 auto condition = state.world.ideology_get_add_military_reform(iid);
271 auto upperhouse_weight = 0.01f * state.world.nation_get_upper_house(n, iid);
272 if(condition && upperhouse_weight > 0.0f)
273 reform_factor += state.defines.military_reform_uh_factor * upperhouse_weight * trigger::evaluate_additive_modifier(state, condition, trigger::to_generic(n), trigger::to_generic(n), 0);
274 }
275 return reform_factor;
276}
277
278float get_economic_reform_multiplier(sys::state& state, dcon::nation_id n) {
279 float reform_factor = 1.0f +
280 state.world.nation_get_modifier_values(n, sys::national_mod_offsets::self_unciv_economic_modifier) +
281 state.world.nation_get_modifier_values(state.world.nation_get_in_sphere_of(n), sys::national_mod_offsets::unciv_economic_modifier);
282
283 for(uint32_t icounter = state.world.ideology_size(); icounter-- > 0;) {
284 dcon::ideology_id iid{dcon::ideology_id::value_base_t(icounter)};
285 auto condition = state.world.ideology_get_add_economic_reform(iid);
286 auto upperhouse_weight = 0.01f * state.world.nation_get_upper_house(n, iid);
287 if(condition && upperhouse_weight > 0.0f)
288 reform_factor += state.defines.economic_reform_uh_factor * upperhouse_weight * trigger::evaluate_additive_modifier(state, condition, trigger::to_generic(n), trigger::to_generic(n), 0);
289 }
290 return reform_factor;
291}
292
293bool political_party_is_active(sys::state& state, dcon::nation_id n, dcon::political_party_id p) {
294 auto start_date = state.world.political_party_get_start_date(p);
295 auto end_date = state.world.political_party_get_end_date(p);
296 bool b = (!start_date || start_date <= state.current_date) && (!end_date || end_date > state.current_date);
297 if(auto k = state.world.political_party_get_trigger(p); b && k) {
299 }
300 return b;
301}
302
303void set_ruling_party(sys::state& state, dcon::nation_id n, dcon::political_party_id p) {
304 state.world.nation_set_ruling_party(n, p);
305 for(auto pi : state.culture_definitions.party_issues) {
306 state.world.nation_set_issues(n, pi, state.world.political_party_get_party_issues(p, pi));
307 }
311 if(auto rules = state.world.nation_get_combined_issue_rules(n); (rules & issue_rule::factory_priority) == 0) {
312 for(auto po : state.world.nation_get_province_ownership_as_nation(n)) {
313 for(auto fl : po.get_province().get_factory_location()) {
314 economy::set_factory_priority(state, fl.get_factory(), 0);
315 }
316 }
317 }
318}
319
320void force_ruling_party_ideology(sys::state& state, dcon::nation_id n, dcon::ideology_id id) {
321 auto tag = state.world.nation_get_identity_from_identity_holder(n);
322 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
323 auto end = start + state.world.national_identity_get_political_party_count(tag);
324
325 for(int32_t i = start; i < end; i++) {
326 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
327 if(politics::political_party_is_active(state, n, pid) && state.world.political_party_get_ideology(pid) == id) {
328 set_ruling_party(state, n, pid);
329 return;
330 }
331 }
332}
333
334void appoint_ruling_party(sys::state& state, dcon::nation_id n, dcon::political_party_id p) {
335 int32_t reform_totals = 0;
336 for(auto preform : state.culture_definitions.political_issues) {
337 auto creform = state.world.nation_get_issues(n, preform);
338 auto base_reform = state.world.issue_get_options(preform)[0];
339 reform_totals += creform.id.index() - base_reform.index();
340 }
341 for(auto preform : state.culture_definitions.social_issues) {
342 auto creform = state.world.nation_get_issues(n, preform);
343 auto base_reform = state.world.issue_get_options(preform)[0];
344 reform_totals += creform.id.index() - base_reform.index();
345 }
346
347 auto angry_value = (0.1f * float(reform_totals) + 1.0f) * state.defines.ruling_party_angry_change;
348 auto happy_value = state.defines.ruling_party_happy_change;
349
350 /*
351 If the new party ideology is *not* the same as the old one: all pops gain ((total number of political and social reforms over
352 baseline) x 0.01 + 1.0) x define:RULING_PARTY_ANGRY_CHANGE x pop support of the old ideology militancy all pops gain
353 define:RULING_PARTY_HAPPY_CHANGE x pop support of the new ideology militancy The same is also done for all party issues that
354 differ between the two.
355 */
356
357 auto old_party = state.world.nation_get_ruling_party(n);
358
359 for(auto pa_id : state.culture_definitions.party_issues) {
360 auto new_id = state.world.political_party_get_party_issues(p, pa_id);
361 auto old_id = state.world.political_party_get_party_issues(old_party, pa_id);
362
363 if(new_id != old_id) {
364 for(auto pr : state.world.nation_get_province_ownership(n)) {
365 for(auto pop : pr.get_province().get_pop_location()) {
366 auto base_mil = pop.get_pop().get_militancy();
367 auto adj_mil = base_mil + pop.get_pop().get_demographics(pop_demographics::to_key(state, old_id)) * angry_value +
368 pop.get_pop().get_demographics(pop_demographics::to_key(state, new_id)) * happy_value;
369 pop.get_pop().set_militancy(adj_mil); // note: no clamp, we just do that once at the end
370 }
371 }
372 }
373 }
374 {
375 auto new_id = state.world.political_party_get_ideology(p);
376 auto old_id = state.world.political_party_get_ideology(old_party);
377
378 if(new_id != old_id) {
379 for(auto pr : state.world.nation_get_province_ownership(n)) {
380 for(auto pop : pr.get_province().get_pop_location()) {
381 auto base_mil = pop.get_pop().get_militancy();
382 auto adj_mil = base_mil + pop.get_pop().get_demographics(pop_demographics::to_key(state, old_id)) * angry_value +
383 pop.get_pop().get_demographics(pop_demographics::to_key(state, new_id)) * happy_value;
384 pop.get_pop().set_militancy(std::clamp(adj_mil, 0.0f, 10.0f));
385 }
386 }
387 }
388 }
389
390 state.world.nation_set_ruling_party_last_appointed(n, state.current_date);
391 set_ruling_party(state, n, p);
392}
393
394void force_nation_ideology(sys::state& state, dcon::nation_id n, dcon::ideology_id id) {
395 state.world.for_each_ideology([&](auto iid) { state.world.nation_set_upper_house(n, iid, 0.0f); });
396 state.world.nation_set_upper_house(n, id, 100.0f);
397
398 force_ruling_party_ideology(state, n, id);
399}
400
401void update_displayed_identity(sys::state& state, dcon::nation_id id) {
402 auto ident = state.world.nation_get_identity_from_identity_holder(id);
403 auto gov_id = state.world.nation_get_government_type(id);
404 assert(!gov_id || state.world.government_type_is_valid(gov_id));
405 if(gov_id) {
406 state.world.nation_set_color(id, state.world.national_identity_get_government_color(ident, gov_id));
407 } else {
408 state.world.nation_set_color(id, state.world.national_identity_get_color(ident));
409 }
410 state.province_ownership_changed.store(true, std::memory_order::release);
411}
412
413void change_government_type(sys::state& state, dcon::nation_id n, dcon::government_type_id new_type) {
414 auto old_gov = state.world.nation_get_government_type(n);
415 if(old_gov != new_type) {
416 assert(state.world.government_type_is_valid(new_type));
417 state.world.nation_set_government_type(n, new_type);
418
419 if((state.world.government_type_get_ideologies_allowed(new_type) &
420 culture::to_bits(state.world.nation_get_ruling_party(n).get_ideology())) == 0) {
421
422 auto tag = state.world.nation_get_identity_from_identity_holder(n);
423 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
424 auto end = start + state.world.national_identity_get_political_party_count(tag);
425
426 for(int32_t i = start; i < end; i++) {
427 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
428 if(politics::political_party_is_active(state, n, pid) &&
429 (state.world.government_type_get_ideologies_allowed(new_type) &
430 culture::to_bits(state.world.political_party_get_ideology(pid))) != 0) {
431
432 set_ruling_party(state, n, pid);
433 break;
434 }
435 }
436 }
437
438 // Cancel elections
439 // If a government which allows elections -> Will immediately start a new one
440 // Else, it will just leave it cancelled
441 state.world.nation_set_election_ends(n, sys::date{});
442
443 recalculate_upper_house(state, n);
444
445 // TODO: notify player ?
447 }
448}
449
450float pop_vote_weight(sys::state& state, dcon::pop_id p, dcon::nation_id n) {
451 /*
452 When a pop's "votes" in any form, the weight of that vote is the product of the size of the pop and the national modifier for
453 voting for their strata (this could easily result in a strata having no votes). If the nation has primary culture voting set
454 then primary culture pops get a full vote, accepted culture pops get a half vote, and other culture pops get no vote. If it
455 has culture voting, primary and accepted culture pops get a full vote and no one else gets a vote. If neither is set, all pops
456 get an equal vote.
457 */
458
459 auto type = state.world.pop_get_poptype(p);
460 if(state.world.pop_type_get_voting_forbidden(type))
461 return 0.0f;
462
463 auto size = state.world.pop_get_size(p);
464 auto strata = culture::pop_strata(state.world.pop_type_get_strata(type));
465 auto vmod = [&]() {
466 switch(strata) {
468 return std::max(0.0f, state.world.nation_get_modifier_values(n, sys::national_mod_offsets::poor_vote));
470 return std::max(0.0f, state.world.nation_get_modifier_values(n, sys::national_mod_offsets::middle_vote));
472 return std::max(0.0f, state.world.nation_get_modifier_values(n, sys::national_mod_offsets::rich_vote));
473 default:
474 return 0.0f;
475 }
476 }();
477
478 auto rules = state.world.nation_get_combined_issue_rules(n);
479 if((rules & issue_rule::primary_culture_voting) != 0) {
480 if(state.world.pop_get_culture(p) == state.world.nation_get_primary_culture(n))
481 return size * vmod;
482 else if(state.world.pop_get_is_primary_or_accepted_culture(p))
483 return size * vmod * 0.5f;
484 else
485 return 0.0f;
486 } else if((rules & issue_rule::culture_voting) != 0) {
487 if(state.world.pop_get_is_primary_or_accepted_culture(p))
488 return size * vmod;
489 else
490 return 0.0f;
491 } else {
492 return size * vmod;
493 }
494}
495
496void recalculate_upper_house(sys::state& state, dcon::nation_id n) {
497 /*
498 Every year, the upper house of each nation is updated. If the "same as ruling party" rule is set, the upper house becomes 100%
499 the ideology of the ruling party. If the rule is "state vote", then for each non-colonial state: for each pop in the state
500 that is not prevented from voting by its type we distribute its weighted vote proportionally to its ideology support, giving
501 us an ideology distribution for each of those states. The state ideology distributions are then normalized and summed to form
502 the distribution for the upper house. For "population_vote" and "rich_only" the voting weight of each non colonial pop (or
503 just the rich ones for "rich only") is distributed proportionally to its ideological support, with the sum for all eligible
504 pops forming the distribution for the upper house.
505 */
506 static std::vector<float> accumulated_in_state;
507 accumulated_in_state.resize(state.world.ideology_size());
508
509 auto rules = state.world.nation_get_combined_issue_rules(n);
510 auto allowed_ideo = state.world.nation_get_government_type(n).get_ideologies_allowed();
511 //(allowed_ideo & culture::to_bits(i)) != 0
512
513 if((rules & issue_rule::same_as_ruling_party) != 0) {
514 auto rp_ideology = state.world.political_party_get_ideology(state.world.nation_get_ruling_party(n));
515 for(auto i : state.world.in_ideology) {
516 state.world.nation_set_upper_house(n, i, 0.0f);
517 }
518 if(rp_ideology)
519 state.world.nation_set_upper_house(n, rp_ideology, 100.0f);
520 } else if((rules & issue_rule::state_vote) != 0) {
521 for(auto i : state.world.in_ideology) {
522 state.world.nation_set_upper_house(n, i, 0.0f);
523 }
524 float state_total = 0.0f;
525
526 for(auto si : state.world.nation_get_state_ownership(n)) {
527 if(si.get_state().get_capital().get_is_colonial())
528 continue; // skip colonial states
529
530 for(auto i : state.world.in_ideology) {
531 accumulated_in_state[i.id.index()] = 0.0f;
532 }
533
534 province::for_each_province_in_state_instance(state, si.get_state(), [&](dcon::province_id p) {
535 for(auto pop : state.world.province_get_pop_location(p)) {
536 auto weight = pop_vote_weight(state, pop.get_pop(), n);
537 if(weight > 0) {
538 for(auto i : state.world.in_ideology) {
539 if((allowed_ideo & culture::to_bits(i)) != 0)
540 accumulated_in_state[i.id.index()] +=
541 weight * state.world.pop_get_demographics(pop.get_pop(), pop_demographics::to_key(state, i));
542 }
543 }
544 }
545 });
546 float total = 0.0f;
547 for(auto i : state.world.in_ideology) {
548 total += accumulated_in_state[i.id.index()];
549 }
550 if(total > 0) {
551 for(auto i : state.world.in_ideology) {
552 auto scaled = accumulated_in_state[i.id.index()] / total;
553 state_total += scaled;
554 state.world.nation_get_upper_house(n, i) += scaled;
555 }
556 }
557 }
558
559 if(state_total > 0) {
560 auto scale_factor = 100.0f / state_total;
561 for(auto i : state.world.in_ideology) {
562 state.world.nation_get_upper_house(n, i) *= scale_factor;
563 }
564 } else {
565 auto rp_ideology = state.world.political_party_get_ideology(state.world.nation_get_ruling_party(n));
566 for(auto i : state.world.in_ideology) {
567 state.world.nation_set_upper_house(n, i, 0.0f);
568 }
569 if(rp_ideology)
570 state.world.nation_set_upper_house(n, rp_ideology, 100.0f);
571 }
572 } else if((rules & issue_rule::rich_only) != 0) {
573 for(auto i : state.world.in_ideology) {
574 state.world.nation_set_upper_house(n, i, 0.0f);
575 }
576 for(auto p : state.world.nation_get_province_ownership(n)) {
577 if(p.get_province().get_is_colonial())
578 continue; // skip colonial provinces
579
580 for(auto pop : state.world.province_get_pop_location(p.get_province())) {
581 if(pop.get_pop().get_poptype().get_strata() == uint8_t(culture::pop_strata::rich)) {
582 auto weight = pop.get_pop().get_size(); // allegedly
583 if(weight > 0) {
584 for(auto i : state.world.in_ideology) {
585 if((allowed_ideo & culture::to_bits(i)) != 0)
586 state.world.nation_get_upper_house(n, i) += weight * state.world.pop_get_demographics(pop.get_pop(), pop_demographics::to_key(state, i));
587 }
588 }
589 }
590 }
591 }
592 float total = 0.0f;
593 for(auto i : state.world.in_ideology) {
594 total += state.world.nation_get_upper_house(n, i);
595 }
596 if(total > 0) {
597 auto scale_factor = 100.0f / total;
598 for(auto i : state.world.in_ideology) {
599 state.world.nation_get_upper_house(n, i) *= scale_factor;
600 }
601 } else {
602 auto rp_ideology = state.world.political_party_get_ideology(state.world.nation_get_ruling_party(n));
603 for(auto i : state.world.in_ideology) {
604 state.world.nation_set_upper_house(n, i, 0.0f);
605 }
606 if(rp_ideology)
607 state.world.nation_set_upper_house(n, rp_ideology, 100.0f);
608 }
609 } else {
610 for(auto i : state.world.in_ideology) {
611 state.world.nation_set_upper_house(n, i, 0.0f);
612 }
613 for(auto p : state.world.nation_get_province_ownership(n)) {
614 if(p.get_province().get_is_colonial())
615 continue; // skip colonial provinces
616
617 for(auto pop : state.world.province_get_pop_location(p.get_province())) {
618 auto weight = pop_vote_weight(state, pop.get_pop(), n);
619 if(weight > 0) {
620 for(auto i : state.world.in_ideology) {
621 if((allowed_ideo & culture::to_bits(i)) != 0)
622 state.world.nation_get_upper_house(n, i) +=
623 weight * state.world.pop_get_demographics(pop.get_pop(), pop_demographics::to_key(state, i));
624 }
625 }
626 }
627 }
628 float total = 0.0f;
629 for(auto i : state.world.in_ideology) {
630 total += state.world.nation_get_upper_house(n, i);
631 }
632 if(total > 0) {
633 auto scale_factor = 100.0f / total;
634 for(auto i : state.world.in_ideology) {
635 state.world.nation_get_upper_house(n, i) *= scale_factor;
636 }
637 } else {
638 auto rp_ideology = state.world.political_party_get_ideology(state.world.nation_get_ruling_party(n));
639 for(auto i : state.world.in_ideology) {
640 state.world.nation_set_upper_house(n, i, 0.0f);
641 }
642 if(rp_ideology)
643 state.world.nation_set_upper_house(n, rp_ideology, 100.0f);
644 }
645 }
646
647 if(n == state.local_player_nation) {
649 [n](sys::state& state, text::layout_base& contents) {
650 text::add_line(state, contents, "msg_upper_house_1");
651 for(auto i : state.world.in_ideology) {
652 auto frac = state.world.nation_get_upper_house(n, i);
653 if(frac > 0.f) {
654 text::add_line(state, contents, "msg_upper_house_2", text::variable_type::x, text::fp_one_place{frac}, text::variable_type::y, i.get_name());
655 }
656 }
657 },
658 "msg_upper_house_title",
659 n, dcon::nation_id{}, dcon::nation_id{},
661 });
662 }
663}
664
666 province::for_each_land_province(state, [&](dcon::province_id p) {
667 auto si = state.world.province_get_state_membership(p);
668 auto nf = state.world.state_instance_get_owner_focus(si);
669 auto party = state.world.national_focus_get_ideology(nf);
670 if(party) {
671 auto& l = state.world.province_get_party_loyalty(p, party);
672 l = std::clamp(l + state.world.national_focus_get_loyalty_value(nf), -1.0f, 1.0f);
673 }
674 });
675}
676
677float party_total_support(sys::state& state, dcon::pop_id pop, dcon::political_party_id par_id, dcon::nation_id nat_id, dcon::province_id prov_id) {
678 auto n = dcon::fatten(state.world, nat_id);
679 auto p = dcon::fatten(state.world, prov_id);
680
681 auto weight = pop_vote_weight(state, pop, n);
682 if(weight > 0.f) {
683 auto ideological_share = state.world.pop_get_consciousness(pop) / 20.0f;
684
685 float ruling_party_support = p.get_modifier_values(sys::provincial_mod_offsets::local_ruling_party_support) +
686 n.get_modifier_values(sys::national_mod_offsets::ruling_party_support) + 1.0f;
687 float prov_vote_mod = p.get_modifier_values(sys::provincial_mod_offsets::number_of_voters) + 1.0f;
688
689 auto pid = state.world.political_party_get_ideology(par_id);
690 auto base_support = (p.get_party_loyalty(pid) + 1.0f) * prov_vote_mod *
691 (par_id == n.get_ruling_party() ? ruling_party_support : 1.0f) * weight;
692 auto issue_support = 0.0f;
693 for(auto pi : state.culture_definitions.party_issues) {
694 auto party_pos = state.world.political_party_get_party_issues(par_id, pi);
695 issue_support += state.world.pop_get_demographics(pop, pop_demographics::to_key(state, party_pos));
696 }
697 auto ideology_support = state.world.pop_get_demographics(pop, pop_demographics::to_key(state, pid));
698 return base_support * (issue_support * (1.0f - ideological_share) + ideology_support * ideological_share);
699 } else {
700 return 0.f;
701 }
702}
703
705 dcon::political_party_id par;
706 float vote = 0.0f;
707};
708
709void start_election(sys::state& state, dcon::nation_id n) {
710 if(state.world.nation_get_election_ends(n) < state.current_date) {
711 state.world.nation_set_election_ends(n, state.current_date + int32_t(state.defines.campaign_duration) * 30);
712 if(n == state.local_player_nation) {
713 auto end_date = state.world.nation_get_election_ends(n);
715 [end_date](sys::state& state, text::layout_base& contents) {
716 text::add_line(state, contents, "msg_election_start_1", text::variable_type::x, end_date);
717 },
718 "msg_election_start_title",
719 n, dcon::nation_id{}, dcon::nation_id{},
721 });
722 }
723 event::fire_fixed_event(state, state.national_definitions.on_election_started, trigger::to_generic(n),
725 }
726}
727
729 static std::vector<party_vote> party_votes;
730 static std::vector<party_vote> provincial_party_votes;
731
732 for(auto n : state.world.in_nation) {
733 /*
734 A country with elections starts one every 5 years.
735 Elections last define:CAMPAIGN_DURATION months.
736 */
737 if(has_elections(state, n)) {
738 if(n.get_election_ends() == state.current_date) {
739 // make election results
740
741 party_votes.clear();
742 float total_vote = 0.0f;
743
744 auto tag = state.world.nation_get_identity_from_identity_holder(n);
745 auto start = state.world.national_identity_get_political_party_first(tag).id.index();
746 auto end = start + state.world.national_identity_get_political_party_count(tag);
747
748 for(int32_t i = start; i < end; i++) {
749 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
751 && (n.get_government_type().get_ideologies_allowed() & culture::to_bits(state.world.political_party_get_ideology(pid))) != 0) {
752 party_votes.push_back(party_vote{pid, 0.0f});
753 }
754 }
755
756 if(party_votes.size() == 0)
757 continue; // ERROR: no valid parties
758
759 // - Determine the vote in each province. Note that voting is *by active party* not by ideology.
760 for(auto p : n.get_province_ownership()) {
761 if(p.get_province().get_is_colonial())
762 continue; // skip colonial provinces
763
764 provincial_party_votes.clear();
765 float province_total = 0.0f;
766 for(auto& par : party_votes) {
767 provincial_party_votes.push_back(party_vote{par.par, 0.0f});
768 }
769
770 float ruling_party_support =
771 p.get_province().get_modifier_values(sys::provincial_mod_offsets::local_ruling_party_support) +
772 n.get_modifier_values(sys::national_mod_offsets::ruling_party_support) + 1.0f;
773 float prov_vote_mod = p.get_province().get_modifier_values(sys::provincial_mod_offsets::number_of_voters) + 1.0f;
774
775 for(auto pop : p.get_province().get_pop_location()) {
776 auto weight = pop_vote_weight(state, pop.get_pop(), n);
777 if(weight > 0) {
778 auto ideological_share = pop.get_pop().get_consciousness() / 20.0f;
779 for(auto& par : provincial_party_votes) {
780 /*
781 - For each party we do the following: figure out the pop's ideological support for the party and
782 its issues based support for the party (by summing up its support for each issue that the party
783 has set, except that pops of non-accepted cultures will never support more restrictive culture
784 voting parties). The pop then votes for the party (i.e. contributes its voting weight in support)
785 based on the sum of its issue and ideological support, except that the greater consciousness the
786 pop has, the more its vote is based on ideological support (pops with 0 consciousness vote based
787 on issues alone). The support for the party is then multiplied by
788 (provincial-modifier-ruling-party-support + national-modifier-ruling-party-support + 1), if it is
789 the ruling party, and by (1 + province-party-loyalty) for its ideology.
790 - Pop votes are also multiplied by (provincial-modifier-number-of-voters + 1)
791 */
792 auto pid = state.world.political_party_get_ideology(par.par);
793 auto base_support = (p.get_province().get_party_loyalty(pid) + 1.0f)
794 * prov_vote_mod * (par.par == n.get_ruling_party() ? ruling_party_support : 1.0f) * weight;
795 auto issue_support = 0.0f;
796 for(auto pi : state.culture_definitions.party_issues) {
797 auto party_pos = state.world.political_party_get_party_issues(par.par, pi);
798 issue_support += pop.get_pop().get_demographics(pop_demographics::to_key(state, party_pos));
799 }
800 auto ideology_support = pop.get_pop().get_demographics(pop_demographics::to_key(state, pid));
801 auto total_support = base_support * (issue_support * (1.0f - ideological_share) + ideology_support * ideological_share);
802
803 province_total += total_support;
804 par.vote += total_support;
805 }
806 }
807 }
808
809 if(province_total > 0) {
810 /*
811 - After the vote has occurred in each province, the winning party there has the province's ideological
812 loyalty for its ideology increased by define:LOYALTY_BOOST_ON_PARTY_WIN x
813 (provincial-boost-strongest-party-modifier + 1) x fraction-of-vote-for-winning-party
814 - If voting rule "largest_share" is in effect: all votes are added to the sum towards the party that
815 recieved the most votes in the province. If it is "dhont", then the votes in each province are normalized
816 to the number of votes from the province, and for "sainte_laque" the votes from the provinces are simply
817 summed up.
818 */
819
820 uint32_t winner = 0;
821 float winner_amount = provincial_party_votes[0].vote;
822 for(uint32_t i = 1; i < provincial_party_votes.size(); ++i) {
823 if(provincial_party_votes[i].vote > winner_amount) {
824 winner = i;
825 winner_amount = provincial_party_votes[i].vote;
826 }
827 }
828
829 auto pid = state.world.political_party_get_ideology(provincial_party_votes[winner].par);
830 auto& l = p.get_province().get_party_loyalty(pid);
831 l = std::clamp(l + state.defines.loyalty_boost_on_party_win *
832 (p.get_province().get_modifier_values(sys::provincial_mod_offsets::boost_strongest_party) + 1.0f)
833 * winner_amount / province_total,
834 -1.0f, 1.0f);
835 auto national_rule = n.get_combined_issue_rules();
836
837 if((national_rule & issue_rule::largest_share) != 0) {
838 party_votes[winner].vote += winner_amount;
839 } else if((national_rule & issue_rule::dhont) != 0) {
840 for(uint32_t i = 0; i < provincial_party_votes.size(); ++i) {
841 party_votes[i].vote += provincial_party_votes[i].vote / province_total;
842 }
843 } else /*if((national_rule & issue_rule::sainte_laque) != 0)*/ {
844 for(uint32_t i = 0; i < provincial_party_votes.size(); ++i) {
845 party_votes[i].vote += provincial_party_votes[i].vote;
846 }
847 }
848 }
849 }
850
851 /*
852 What happens with the election result depends partly on the average militancy of the nation. If it is less than 5:
853 We find the ideology group with the greatest support (each active party gives their support to their group), then
854 the party with the greatest support from the winning group is elected. If average militancy is greater than 5: the
855 party with the greatest individual support wins. (Note: so at average militancy less than 5, having parties with
856 duplicate ideologies makes an ideology group much more likely to win, because they get double counted.)
857 */
858
859 auto total_pop = n.get_demographics(demographics::total);
860 auto avg_mil = total_pop > 0.0f ? n.get_demographics(demographics::militancy) / total_pop : 0.0f;
861
862 if(avg_mil <= 5.0f) {
863 static auto per_group = state.world.ideology_group_make_vectorizable_float_buffer();
864 for(auto ig : state.world.in_ideology_group) {
865 per_group.set(ig, 0.0f);
866 }
867 for(uint32_t i = 0; i < party_votes.size(); ++i) {
868 per_group.get(state.world.ideology_get_ideology_group_from_ideology_group_membership(
869 state.world.political_party_get_ideology(party_votes[i].par))) += party_votes[i].vote;
870 }
871 dcon::ideology_group_id winner;
872 float winner_amount = -1.0f;
873 float total = 0.0f;
874 for(auto ig : state.world.in_ideology_group) {
875 if(per_group.get(ig) > winner_amount) {
876 winner_amount = per_group.get(ig);
877 winner = ig;
878 }
879 }
880
881 uint32_t winner_b = 0;
882 float winner_amount_b = -1.0f;
883 for(uint32_t i = 0; i < party_votes.size(); ++i) {
884 total += party_votes[i].vote;
885 if(state.world.ideology_get_ideology_group_from_ideology_group_membership(
886 state.world.political_party_get_ideology(party_votes[i].par)) == winner &&
887 party_votes[i].vote > winner_amount_b) {
888 winner_b = i;
889 winner_amount_b = party_votes[i].vote;
890 }
891 }
892
893 set_ruling_party(state, n, party_votes[winner_b].par);
894
896 [rp = party_votes[winner_b].par, frac = winner_amount_b / total](sys::state& state, text::layout_base& contents) {
897 text::add_line(state, contents, "msg_election_end_2", text::variable_type::x, state.world.political_party_get_name(rp), text::variable_type::y, text::fp_percentage{frac});
898 },
899 "msg_election_end_title",
900 n, dcon::nation_id{}, dcon::nation_id{},
902 });
903 } else {
904 uint32_t winner = 0;
905 float winner_amount = party_votes[0].vote;
906 float total = 0.0f;
907 for(uint32_t i = 1; i < party_votes.size(); ++i) {
908 total += party_votes[i].vote;
909 if(party_votes[i].vote > winner_amount) {
910 winner = i;
911 winner_amount = party_votes[i].vote;
912 }
913 }
914
915 set_ruling_party(state, n, party_votes[winner].par);
916
918 [rp = party_votes[winner].par, frac = winner_amount / total](sys::state& state, text::layout_base& contents) {
919 text::add_line(state, contents, "msg_election_end_1", text::variable_type::x, state.world.political_party_get_name(rp), text::variable_type::y, text::fp_percentage{frac});
920 },
921 "msg_election_end_title",
922 n, dcon::nation_id{}, dcon::nation_id{},
924 });
925 }
926 event::fire_fixed_event(state, state.national_definitions.on_election_finished, trigger::to_generic(n),
928 } else if(next_election_date(state, n) <= state.current_date) {
929 start_election(state, n);
930 } else if(state.current_date < n.get_election_ends()) { // do election event
931 /*
932 While an election is ongoing, random events from the `on_election_tick` category will be fired. These events are picked in
933 the usual way: based on their weights out of those that have their trigger conditions (if any) satisfied. Events occur
934 once every define:CAMPAIGN_EVENT_BASE_TIME / 2 days to define:CAMPAIGN_EVENT_BASE_TIME days (uniformly distributed).
935 */
936 auto randoms = rng::get_random_pair(state, uint32_t(n.get_election_ends().value), uint32_t(n.id.value));
937 int32_t time_value = int32_t(state.defines.campaign_event_base_time / 2.0f);
938
939 int32_t first_roll = int32_t(uint32_t(randoms.low) % time_value) + time_value;
940 int32_t second_roll = first_roll + int32_t(uint32_t(randoms.low >> 32) % time_value) + time_value;
941 int32_t third_roll = second_roll + int32_t(uint32_t(randoms.high) % time_value) + time_value;
942 int32_t fourth_roll = third_roll + int32_t(uint32_t(randoms.high >> 32) % time_value) + time_value;
943
944 auto election_start = n.get_election_ends() - int32_t(state.defines.campaign_duration) * 30;
945
946 if(election_start + first_roll == state.current_date || election_start + second_roll == state.current_date
947 || election_start + third_roll == state.current_date || election_start + fourth_roll == state.current_date) {
948
949 event::fire_fixed_event(state, state.national_definitions.on_election_tick, trigger::to_generic(n.id),
951 }
952 }
953 }
954 }
955}
956
957void set_issue_option(sys::state& state, dcon::nation_id n, dcon::issue_option_id opt) {
958 auto parent = state.world.issue_option_get_parent_issue(opt);
959 auto effect_t = state.world.issue_option_get_on_execute_trigger(opt);
960 auto effect_k = state.world.issue_option_get_on_execute_effect(opt);
961 if(effect_k && (!effect_t || trigger::evaluate(state, effect_t, trigger::to_generic(n), trigger::to_generic(n), 0))) {
962 effect::execute(state, effect_k, trigger::to_generic(n), trigger::to_generic(n), 0, uint32_t(state.current_date.value),
963 uint32_t((opt.index() << 2) ^ n.index()));
964 }
965 state.world.nation_set_issues(n, parent, opt);
966}
967void set_reform_option(sys::state& state, dcon::nation_id n, dcon::reform_option_id opt) {
968 auto parent = state.world.reform_option_get_parent_reform(opt);
969 auto effect_t = state.world.reform_option_get_on_execute_trigger(opt);
970 auto effect_k = state.world.reform_option_get_on_execute_effect(opt);
971 if(effect_k && (!effect_t || trigger::evaluate(state, effect_t, trigger::to_generic(n), trigger::to_generic(n), 0))) {
972 effect::execute(state, effect_k, trigger::to_generic(n), trigger::to_generic(n), 0, uint32_t(state.current_date.value),
973 uint32_t((opt.index() << 2) ^ n.index()));
974 }
975 state.world.nation_set_reforms(n, parent, opt);
976}
977
978} // namespace politics
#define assert(condition)
Definition: debug.h:74
constexpr uint64_t to_bits(dcon::ideology_id id)
Definition: culture.hpp:92
void update_nation_issue_rules(sys::state &state, dcon::nation_id n_id)
Definition: culture.cpp:766
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
constexpr dcon::demographics_key total(0)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
constexpr dcon::demographics_key militancy(4)
void bound_budget_settings(sys::state &state, dcon::nation_id n)
Definition: economy.cpp:5252
void set_factory_priority(sys::state &state, dcon::factory_id f, int32_t priority)
Definition: economy.cpp:1006
void execute(sys::state &state, dcon::effect_key key, int32_t primary, int32_t this_slot, int32_t from_slot, uint32_t r_lo, uint32_t r_hi)
Definition: effects.cpp:5361
void fire_fixed_event(sys::state &state, std::vector< nations::fixed_event > const &v, int32_t primary_slot, slot_type pt, dcon::nation_id this_slot, int32_t from_slot, slot_type ft)
Definition: events.cpp:709
constexpr uint32_t same_as_ruling_party
Definition: culture.hpp:34
constexpr uint32_t state_vote
Definition: culture.hpp:36
constexpr uint32_t culture_voting
Definition: culture.hpp:29
constexpr uint32_t rich_only
Definition: culture.hpp:35
constexpr uint32_t dhont
Definition: culture.hpp:32
constexpr uint32_t largest_share
Definition: culture.hpp:31
constexpr uint32_t primary_culture_voting
Definition: culture.hpp:28
constexpr uint32_t factory_priority
Definition: culture.hpp:12
void post(sys::state &state, message &&m)
void daily_party_loyalty_update(sys::state &state)
Definition: politics.cpp:665
bool can_enact_social_reform(sys::state &state, dcon::nation_id n, dcon::issue_option_id o)
Definition: politics.cpp:165
float pop_vote_weight(sys::state &state, dcon::pop_id p, dcon::nation_id n)
Definition: politics.cpp:450
float get_military_reform_multiplier(sys::state &state, dcon::nation_id n)
Definition: politics.cpp:263
float vote_total(sys::state &state, dcon::nation_id nation)
Definition: politics.cpp:11
bool can_enact_political_reform(sys::state &state, dcon::nation_id nation, dcon::issue_option_id issue_option)
Definition: politics.cpp:107
float get_economic_reform_multiplier(sys::state &state, dcon::nation_id n)
Definition: politics.cpp:278
float get_voter_support(sys::state &state, dcon::nation_id nation, dcon::issue_option_id issue_option)
Definition: politics.cpp:33
bool reform_is_selected(sys::state &state, dcon::nation_id nation, dcon::reform_option_id reform_option)
Definition: politics.cpp:97
void recalculate_upper_house(sys::state &state, dcon::nation_id n)
Definition: politics.cpp:496
dcon::issue_id get_issue_by_name(sys::state &state, std::string_view name)
Definition: politics.cpp:83
sys::date next_election_date(sys::state &state, dcon::nation_id nation)
Definition: politics.cpp:64
void force_ruling_party_ideology(sys::state &state, dcon::nation_id n, dcon::ideology_id id)
Definition: politics.cpp:320
void force_nation_ideology(sys::state &state, dcon::nation_id n, dcon::ideology_id id)
Definition: politics.cpp:394
dcon::reform_id get_reform_by_name(sys::state &state, std::string_view name)
Definition: politics.cpp:69
bool can_appoint_ruling_party(sys::state &state, dcon::nation_id nation)
Definition: politics.cpp:51
void set_issue_option(sys::state &state, dcon::nation_id n, dcon::issue_option_id opt)
Definition: politics.cpp:957
bool political_party_is_active(sys::state &state, dcon::nation_id n, dcon::political_party_id p)
Definition: politics.cpp:293
void change_government_type(sys::state &state, dcon::nation_id n, dcon::government_type_id new_type)
Definition: politics.cpp:413
void update_displayed_identity(sys::state &state, dcon::nation_id id)
Definition: politics.cpp:401
float get_popular_support(sys::state &state, dcon::nation_id nation, dcon::issue_option_id issue_option)
Definition: politics.cpp:24
bool can_enact_military_reform(sys::state &state, dcon::nation_id n, dcon::reform_option_id o)
Definition: politics.cpp:223
void set_reform_option(sys::state &state, dcon::nation_id n, dcon::reform_option_id opt)
Definition: politics.cpp:967
bool issue_is_selected(sys::state &state, dcon::nation_id nation, dcon::issue_option_id issue_option)
Definition: politics.cpp:102
bool has_elections(sys::state &state, dcon::nation_id nation)
Definition: politics.cpp:60
float party_total_support(sys::state &state, dcon::pop_id pop, dcon::political_party_id par_id, dcon::nation_id nat_id, dcon::province_id prov_id)
Definition: politics.cpp:677
void appoint_ruling_party(sys::state &state, dcon::nation_id n, dcon::political_party_id p)
Definition: politics.cpp:334
void update_elections(sys::state &state)
Definition: politics.cpp:728
void set_ruling_party(sys::state &state, dcon::nation_id n, dcon::political_party_id p)
Definition: politics.cpp:303
void start_election(sys::state &state, dcon::nation_id n)
Definition: politics.cpp:709
bool is_election_ongoing(sys::state &state, dcon::nation_id nation)
Definition: politics.cpp:55
bool can_enact_economic_reform(sys::state &state, dcon::nation_id n, dcon::reform_option_id o)
Definition: politics.cpp:243
dcon::pop_demographics_key to_key(sys::state const &state, dcon::ideology_id v)
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
void for_each_land_province(sys::state &state, F const &func)
random_pair get_random_pair(sys::state const &state, uint32_t value_in)
Definition: prng.cpp:26
void update_single_nation_modifiers(sys::state &state, dcon::nation_id n)
Definition: modifiers.cpp:426
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1899
int32_t to_generic(dcon::province_id v)
Definition: triggers.hpp:12
bool evaluate(sys::state &state, dcon::trigger_key key, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5810
float evaluate_additive_modifier(sys::state &state, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5741
uint uint32_t
uchar uint8_t
@ ident
dcon::political_party_id par
Definition: politics.cpp:705