Project Alice
Loading...
Searching...
No Matches
culture.cpp
Go to the documentation of this file.
1#include "culture.hpp"
2#include "dcon_generated.hpp"
3#include "demographics.hpp"
5#include "prng.hpp"
7#include "system_state.hpp"
8#include "triggers.hpp"
9
10namespace culture {
11
13 switch(t) {
15 return "army_tech";
17 return "navy_tech";
19 return "commerce_tech";
21 return "culture_tech";
23 return "industry_tech";
24 //non-vanilla
26 return "military_theory_tech";
28 return "population_tech";
30 return "diplomacy_tech";
32 return "flavor_tech";
33 default:
34 break;
35 }
36 return "none";
37}
38
40 state.world.nation_resize_issues(state.world.issue_size());
41
42 state.world.for_each_issue([&](dcon::issue_id i) {
43 auto def_option = state.world.issue_get_options(i)[0];
44 state.world.execute_serial_over_nation([&](auto ids) { state.world.nation_set_issues(ids, i, def_option); });
45 });
46
47 state.world.nation_resize_reforms(state.world.reform_size());
48
49 state.world.for_each_reform([&](dcon::reform_id i) {
50 auto def_option = state.world.reform_get_options(i)[0];
51 state.world.execute_serial_over_nation([&](auto ids) { state.world.nation_set_reforms(ids, i, def_option); });
52 });
53}
54
55void reload_unlocked_commodities(sys::state& state, dcon::nation_id target_nation) {
56 state.world.for_each_commodity([&](dcon::commodity_id c_id) {
57 state.world.nation_set_unlocked_commodities(target_nation, c_id, false);
58 });
59
60 state.world.for_each_technology([&](dcon::technology_id t_id) {
61 auto tech_id = fatten(state.world, t_id);
62
63 if(!state.world.nation_get_active_technologies(target_nation, tech_id)) {
64 return;
65 }
66
67 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
68 if(tech_id.get_activate_building(id)) {
69 state.world.nation_set_active_building(target_nation, id, true);
70
71 auto output = state.world.factory_type_get_output(id);
72
73 state.world.nation_set_unlocked_commodities(target_nation, output, true);
74 }
75 });
76 });
77 state.world.for_each_invention([&](dcon::invention_id i_id) {
78 auto inv_id = fatten(state.world, i_id);
79
80 if(!state.world.nation_get_active_inventions(target_nation, inv_id)) {
81 return;
82 }
83
84 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
85 if(inv_id.get_activate_building(id)) {
86 state.world.nation_set_active_building(target_nation, id, true);
87 auto output = state.world.factory_type_get_output(id);
88 state.world.nation_set_unlocked_commodities(target_nation, output, true);
89 }
90 });
91 });
92}
93
96 state.world.execute_serial_over_nation([&](auto nation_indices) {
97 state.world.nation_set_max_building_level(nation_indices, uint8_t(t), 0);
98 });
99
100 }
101 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
102 state.world.execute_serial_over_nation([&](auto nation_indices) {
103 state.world.nation_set_active_building(nation_indices, id, ve::vbitfield_type{0});
104 });
105 });
106 state.world.for_each_commodity([&](dcon::commodity_id id) {
107 state.world.execute_serial_over_nation([&](auto nation_indices) {
108 state.world.nation_set_unlocked_commodities(nation_indices, id, ve::vbitfield_type{ 0 });
109 });
110 });
111 for(uint32_t i = 0; i < state.military_definitions.unit_base_definitions.size(); ++i) {
112 dcon::unit_type_id uid = dcon::unit_type_id{ dcon::unit_type_id::value_base_t(i) };
113 state.world.execute_serial_over_nation([&](auto nation_indices) {
114 state.world.nation_set_active_unit(nation_indices, uid, ve::vbitfield_type{ 0 });
115 });
116 }
117 for(uint32_t i = 0; i < state.culture_definitions.crimes.size(); ++i) {
118 dcon::crime_id uid = dcon::crime_id{ dcon::crime_id::value_base_t(i) };
119 state.world.execute_serial_over_nation([&](auto nation_indices) {
120 state.world.nation_set_active_crime(nation_indices, uid, ve::vbitfield_type{ 0 });
121 });
122 }
123
124 for(auto cmod : state.world.in_commodity) {
125 state.world.execute_serial_over_nation([&](auto nation_indices) {
126 state.world.nation_set_rgo_goods_output(nation_indices, cmod, 0.0f);
127 });
128 }
129 for(auto cmod : state.world.in_commodity) {
130 state.world.execute_serial_over_nation([&](auto nation_indices) {
131 state.world.nation_set_factory_goods_output(nation_indices, cmod, 0.0f);
132 });
133 }
134 for(auto cmod : state.world.in_commodity) {
135 state.world.execute_serial_over_nation([&](auto nation_indices) {
136 state.world.nation_set_rgo_size(nation_indices, cmod, 0.0f);
137 });
138 }
139 for(auto cmod : state.world.in_commodity) {
140 state.world.execute_serial_over_nation([&](auto nation_indices) {
141 state.world.nation_set_factory_goods_throughput(nation_indices, cmod, 0.0f);
142 });
143 }
144 for(auto cmod : state.world.in_rebel_type) {
145 state.world.execute_serial_over_nation([&](auto nation_indices) {
146 state.world.nation_set_rebel_org_modifier(nation_indices, cmod, 0.0f);
147 });
148 }
149 state.world.execute_serial_over_nation([&](auto nation_indices) {
150 state.world.nation_set_has_gas_attack(nation_indices, ve::vbitfield_type{ 0 });
151 });
152 state.world.execute_serial_over_nation([&](auto nation_indices) {
153 state.world.nation_set_has_gas_defense(nation_indices, ve::vbitfield_type{ 0 });
154 });
156}
157
159 state.world.for_each_technology([&](dcon::technology_id t_id) {
160 auto tech_id = fatten(state.world, t_id);
161
162 // apply modifiers from active technologies
163 /*
164 auto tech_mod = tech_id.get_modifier();
165 if(tech_mod) {
166 auto& tech_nat_values = tech_mod.get_national_values();
167 for(uint32_t i = 0; i < sys::national_modifier_definition::modifier_definition_size; ++i) {
168 if(!(tech_nat_values.offsets[i]))
169 break; // no more modifier values attached to this tech
170
171 state.world.execute_serial_over_nation([&,
172 fixed_offset = tech_nat_values.offsets[i],
173 modifier_amount = tech_nat_values.values[i]
174 ](auto nation_indices) {
175 auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
176 auto old_mod_value = state.world.nation_get_modifier_values(nation_indices, fixed_offset);
177 state.world.nation_set_modifier_values(nation_indices, fixed_offset,
178 ve::select(has_tech_mask, old_mod_value + modifier_amount, old_mod_value));
179 });
180 }
181 }
182 */
183
185 if(tech_id.get_increase_building(t)) {
186 state.world.execute_serial_over_nation([&](auto nation_indices) {
187 auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
188 auto old_rr_value = state.world.nation_get_max_building_level(nation_indices, uint8_t(t));
189 state.world.nation_set_max_building_level(nation_indices, uint8_t(t), ve::select(has_tech_mask, old_rr_value + 1, old_rr_value));
190 });
191 }
192 }
193
194 //if(tech_id.get_colonial_points() != 0.0f) {
195 // auto amount = tech_id.get_colonial_points();
196 // state.world.execute_serial_over_nation([&](auto nation_indices) {
197 // auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
198 // auto old_cp_value = state.world.nation_get_permanent_colonial_points(nation_indices);
199 // state.world.nation_set_permanent_colonial_points(nation_indices, ve::select(has_tech_mask, old_cp_value + amount, old_cp_value));
200 // });
201 //}
202
203 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
204 if(tech_id.get_activate_building(id)) {
205 state.world.execute_serial_over_nation([&](auto nation_indices) {
206 auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
207 auto old_value = state.world.nation_get_active_building(nation_indices, id);
208 state.world.nation_set_active_building(nation_indices, id, old_value | has_tech_mask);
209 });
210 }
211 });
212 for(uint32_t i = 0; i < state.military_definitions.unit_base_definitions.size(); ++i) {
213 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
214 if(tech_id.get_activate_unit(uid)) {
215 state.world.execute_serial_over_nation([&](auto nation_indices) {
216 auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
217 auto old_value = state.world.nation_get_active_unit(nation_indices, uid);
218 state.world.nation_set_active_unit(nation_indices, uid, old_value | has_tech_mask);
219 });
220 }
221 }
222
223 for(auto cmod : tech_id.get_rgo_goods_output()) {
224 state.world.execute_serial_over_nation([&](auto nation_indices) {
225 auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
226 auto old_value = state.world.nation_get_rgo_goods_output(nation_indices, cmod.type);
227 state.world.nation_set_rgo_goods_output(nation_indices, cmod.type,
228 ve::select(has_tech_mask, old_value + cmod.amount, old_value));
229 });
230 }
231 for(auto cmod : tech_id.get_factory_goods_output()) {
232 state.world.execute_serial_over_nation([&](auto nation_indices) {
233 auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
234 auto old_value = state.world.nation_get_factory_goods_output(nation_indices, cmod.type);
235 state.world.nation_set_factory_goods_output(nation_indices, cmod.type,
236 ve::select(has_tech_mask, old_value + cmod.amount, old_value));
237 });
238 }
239 for(auto cmod : tech_id.get_rgo_size()) {
240 state.world.execute_serial_over_nation([&](auto nation_indices) {
241 auto has_tech_mask = state.world.nation_get_active_technologies(nation_indices, t_id);
242 auto old_value = state.world.nation_get_rgo_size(nation_indices, cmod.type);
243 state.world.nation_set_rgo_size(nation_indices, cmod.type, ve::select(has_tech_mask, old_value + cmod.amount, old_value));
244 });
245 }
246 for(auto& umod : tech_id.get_modified_units()) {
247 state.world.for_each_nation([&](dcon::nation_id nid) {
248 if(state.world.nation_get_active_technologies(nid, t_id)) {
249 state.world.nation_get_unit_stats(nid, umod.type) += umod;
250 }
251 });
252 }
253 });
254
255 for(auto n : state.world.in_nation) {
257 }
258}
259
261 state.world.for_each_invention([&](dcon::invention_id i_id) {
262 auto inv_id = fatten(state.world, i_id);
263
264 // apply modifiers from active inventions
265 /*
266 auto inv_mod = inv_id.get_modifier();
267 if(inv_mod) {
268 auto& inv_nat_values = inv_mod.get_national_values();
269 for(uint32_t i = 0; i < sys::national_modifier_definition::modifier_definition_size; ++i) {
270 if(!(inv_nat_values.offsets[i]))
271 break; // no more modifier values attached to this invention
272
273 state.world.execute_serial_over_nation([&,
274 fixed_offset = inv_nat_values.offsets[i],
275 modifier_amount = inv_nat_values.values[i]
276 ](auto nation_indices) {
277 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
278 auto old_mod_value = state.world.nation_get_modifier_values(nation_indices, fixed_offset);
279 state.world.nation_set_modifier_values(nation_indices, fixed_offset,
280 ve::select(has_inv_mask, old_mod_value + modifier_amount, old_mod_value));
281 });
282 }
283 }
284 */
285
287 if(inv_id.get_increase_building(t)) {
288 state.world.execute_serial_over_nation([&](auto nation_indices) {
289 auto has_tech_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
290 auto old_rr_value = state.world.nation_get_max_building_level(nation_indices, uint8_t(t));
291 state.world.nation_set_max_building_level(nation_indices, uint8_t(t), ve::select(has_tech_mask, old_rr_value + 1, old_rr_value));
292 });
293 }
294 }
295
296 if(inv_id.get_enable_gas_attack()) {
297 state.world.execute_serial_over_nation([&](auto nation_indices) {
298 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
299 auto old_value = state.world.nation_get_has_gas_attack(nation_indices);
300 state.world.nation_set_has_gas_attack(nation_indices, old_value | has_inv_mask);
301 });
302 }
303 if(inv_id.get_enable_gas_defense()) {
304 state.world.execute_serial_over_nation([&](auto nation_indices) {
305 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
306 auto old_value = state.world.nation_get_has_gas_defense(nation_indices);
307 state.world.nation_set_has_gas_defense(nation_indices, old_value | has_inv_mask);
308 });
309 }
310
311 //if(inv_id.get_colonial_points() != 0.0f) {
312 // auto amount = inv_id.get_colonial_points();
313 // state.world.execute_serial_over_nation([&](auto nation_indices) {
314 // auto has_tech_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
315 // auto old_cp_value = state.world.nation_get_permanent_colonial_points(nation_indices);
316 // state.world.nation_set_permanent_colonial_points(nation_indices, ve::select(has_tech_mask, old_cp_value + amount, old_cp_value));
317 // });
318 //}
319
320 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
321 if(inv_id.get_activate_building(id)) {
322 state.world.execute_serial_over_nation([&](auto nation_indices) {
323 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
324 auto old_value = state.world.nation_get_active_building(nation_indices, id);
325 state.world.nation_set_active_building(nation_indices, id, old_value | has_inv_mask);
326 });
327 }
328 });
329 for(uint32_t i = 0; i < state.military_definitions.unit_base_definitions.size(); ++i) {
330 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
331 if(inv_id.get_activate_unit(uid)) {
332 state.world.execute_serial_over_nation([&](auto nation_indices) {
333 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
334 auto old_value = state.world.nation_get_active_unit(nation_indices, uid);
335 state.world.nation_set_active_unit(nation_indices, uid, old_value | has_inv_mask);
336 });
337 }
338 }
339 for(uint32_t i = 0; i < state.culture_definitions.crimes.size(); ++i) {
340 dcon::crime_id uid = dcon::crime_id{dcon::crime_id::value_base_t(i)};
341 if(inv_id.get_activate_crime(uid)) {
342 state.world.execute_serial_over_nation([&](auto nation_indices) {
343 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
344 auto old_value = state.world.nation_get_active_crime(nation_indices, uid);
345 state.world.nation_set_active_crime(nation_indices, uid, old_value | has_inv_mask);
346 });
347 }
348 }
349
350 for(auto cmod : inv_id.get_rgo_goods_output()) {
351 state.world.execute_serial_over_nation([&](auto nation_indices) {
352 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
353 auto old_value = state.world.nation_get_rgo_goods_output(nation_indices, cmod.type);
354 state.world.nation_set_rgo_goods_output(nation_indices, cmod.type,
355 ve::select(has_inv_mask, old_value + cmod.amount, old_value));
356 });
357 }
358 for(auto cmod : inv_id.get_rgo_size()) {
359 state.world.execute_serial_over_nation([&](auto nation_indices) {
360 auto has_tech_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
361 auto old_value = state.world.nation_get_rgo_size(nation_indices, cmod.type);
362 state.world.nation_set_rgo_size(nation_indices, cmod.type, ve::select(has_tech_mask, old_value + cmod.amount, old_value));
363 });
364 }
365 for(auto cmod : inv_id.get_factory_goods_output()) {
366 state.world.execute_serial_over_nation([&](auto nation_indices) {
367 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
368 auto old_value = state.world.nation_get_factory_goods_output(nation_indices, cmod.type);
369 state.world.nation_set_factory_goods_output(nation_indices, cmod.type,
370 ve::select(has_inv_mask, old_value + cmod.amount, old_value));
371 });
372 }
373 for(auto cmod : inv_id.get_factory_goods_throughput()) {
374 state.world.execute_serial_over_nation([&](auto nation_indices) {
375 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
376 auto old_value = state.world.nation_get_factory_goods_throughput(nation_indices, cmod.type);
377 state.world.nation_set_factory_goods_throughput(nation_indices, cmod.type,
378 ve::select(has_inv_mask, old_value + cmod.amount, old_value));
379 });
380 }
381 for(auto cmod : inv_id.get_rebel_org()) {
382 state.world.execute_serial_over_nation([&](auto nation_indices) {
383 auto has_inv_mask = state.world.nation_get_active_inventions(nation_indices, i_id);
384 if(cmod.type) {
385 auto old_value = state.world.nation_get_rebel_org_modifier(nation_indices, cmod.type);
386 state.world.nation_set_rebel_org_modifier(nation_indices, cmod.type,
387 ve::select(has_inv_mask, old_value + cmod.amount, old_value));
388 } else if(has_inv_mask.v != 0) {
389 state.world.for_each_rebel_type([&](dcon::rebel_type_id rt) {
390 auto old_value = state.world.nation_get_rebel_org_modifier(nation_indices, rt);
391 state.world.nation_set_rebel_org_modifier(nation_indices, rt,
392 ve::select(has_inv_mask, old_value + cmod.amount, old_value));
393 });
394 }
395 });
396 }
397 for(auto& umod : inv_id.get_modified_units()) {
398 state.world.for_each_nation([&](dcon::nation_id nid) {
399 if(state.world.nation_get_active_inventions(nid, i_id)) {
400 auto& existing_stats = state.world.nation_get_unit_stats(nid, umod.type);
401 existing_stats += umod;
402 }
403 });
404 }
405 });
406
407 for(auto n : state.world.in_nation) {
409 }
410}
411
412void apply_technology(sys::state& state, dcon::nation_id target_nation, dcon::technology_id t_id) {
413 auto tech_id = fatten(state.world, t_id);
414
415 state.world.nation_set_active_technologies(target_nation, t_id, true);
416
417 auto tech_mod = tech_id.get_modifier();
418 if(tech_mod) {
419 auto& tech_nat_values = tech_mod.get_national_values();
421 if(!(tech_nat_values.offsets[i]))
422 break; // no more modifier values attached to this tech
423
424 auto fixed_offset = tech_nat_values.offsets[i];
425 auto modifier_amount = tech_nat_values.values[i];
426
427 state.world.nation_get_modifier_values(target_nation, fixed_offset) += modifier_amount;
428 }
429 }
430
431 auto& plur = state.world.nation_get_plurality(target_nation);
432 plur = std::clamp(plur + tech_id.get_plurality() * 100.0f, 0.0f, 100.0f);
433
435 if(tech_id.get_increase_building(t)) {
436 state.world.nation_get_max_building_level(target_nation, uint8_t(t)) += 1;
437 }
438 }
439 state.world.nation_get_permanent_colonial_points(target_nation) += tech_id.get_colonial_points();
440 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
441 if(tech_id.get_activate_building(id)) {
442 state.world.nation_set_active_building(target_nation, id, true);
443
444 auto output = state.world.factory_type_get_output(id);
445
446 state.world.nation_set_unlocked_commodities(target_nation, output, true);
447 }
448 });
449 for(uint32_t i = 0; i < state.military_definitions.unit_base_definitions.size(); ++i) {
450 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
451 if(tech_id.get_activate_unit(uid)) {
452 state.world.nation_set_active_unit(target_nation, uid, true);
453 }
454 }
455
456 for(auto cmod : tech_id.get_rgo_goods_output()) {
457 state.world.nation_get_rgo_goods_output(target_nation, cmod.type) += cmod.amount;
458 }
459 for(auto cmod : tech_id.get_factory_goods_output()) {
460 state.world.nation_get_factory_goods_output(target_nation, cmod.type) += cmod.amount;
461 }
462 for(auto cmod : tech_id.get_rgo_size()) {
463 state.world.nation_get_rgo_size(target_nation, cmod.type) += cmod.amount;
464 }
465 for(auto& umod : tech_id.get_modified_units()) {
466 if(umod.type == state.military_definitions.base_army_unit) {
467 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
468 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
469 if(state.military_definitions.unit_base_definitions[uid].is_land) {
470 state.world.nation_get_unit_stats(target_nation, uid) += umod;
471 }
472 }
473 } else if(umod.type == state.military_definitions.base_naval_unit) {
474 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
475 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
476 if(!state.military_definitions.unit_base_definitions[uid].is_land) {
477 state.world.nation_get_unit_stats(target_nation, uid) += umod;
478 }
479 }
480 } else {
481 state.world.nation_get_unit_stats(target_nation, umod.type) += umod;
482 }
483 }
484}
485
486void remove_technology(sys::state& state, dcon::nation_id target_nation, dcon::technology_id t_id) {
487 auto tech_id = fatten(state.world, t_id);
488
489 state.world.nation_set_active_technologies(target_nation, t_id, false);
490
491 auto tech_mod = tech_id.get_modifier();
492 if(tech_mod) {
493 auto& tech_nat_values = tech_mod.get_national_values();
495 if(!(tech_nat_values.offsets[i]))
496 break; // no more modifier values attached to this tech
497
498 auto fixed_offset = tech_nat_values.offsets[i];
499 auto modifier_amount = tech_nat_values.values[i];
500
501 state.world.nation_get_modifier_values(target_nation, fixed_offset) -= modifier_amount;
502 }
503 }
504
505 auto& plur = state.world.nation_get_plurality(target_nation);
506 plur = std::clamp(plur - tech_id.get_plurality() * 100.0f, 0.0f, 100.0f);
507
509 if(tech_id.get_increase_building(t)) {
510 state.world.nation_get_max_building_level(target_nation, uint8_t(t)) -= 1;
511 }
512 }
513 state.world.nation_get_permanent_colonial_points(target_nation) -= tech_id.get_colonial_points();
514
515 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
516 if(tech_id.get_activate_building(id)) {
517 state.world.nation_set_active_building(target_nation, id, false);
518 }
519 });
520
521 reload_unlocked_commodities(state, target_nation);
522
523 for(uint32_t i = 0; i < state.military_definitions.unit_base_definitions.size(); ++i) {
524 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
525 if(tech_id.get_activate_unit(uid)) {
526 state.world.nation_set_active_unit(target_nation, uid, false);
527 }
528 }
529
530 for(auto cmod : tech_id.get_rgo_goods_output()) {
531 state.world.nation_get_rgo_goods_output(target_nation, cmod.type) -= cmod.amount;
532 }
533 for(auto cmod : tech_id.get_factory_goods_output()) {
534 state.world.nation_get_factory_goods_output(target_nation, cmod.type) -= cmod.amount;
535 }
536 for(auto cmod : tech_id.get_rgo_size()) {
537 state.world.nation_get_rgo_size(target_nation, cmod.type) -= cmod.amount;
538 }
539 for(auto& umod : tech_id.get_modified_units()) {
540 if(umod.type == state.military_definitions.base_army_unit) {
541 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
542 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
543 if(state.military_definitions.unit_base_definitions[uid].is_land) {
544 state.world.nation_get_unit_stats(target_nation, uid) -= umod;
545 }
546 }
547 } else if(umod.type == state.military_definitions.base_naval_unit) {
548 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
549 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
550 if(!state.military_definitions.unit_base_definitions[uid].is_land) {
551 state.world.nation_get_unit_stats(target_nation, uid) -= umod;
552 }
553 }
554 } else {
555 state.world.nation_get_unit_stats(target_nation, umod.type) -= umod;
556 }
557 }
558}
559
560void apply_invention(sys::state& state, dcon::nation_id target_nation, dcon::invention_id i_id) { // TODO: shared prestige effect
561 auto inv_id = fatten(state.world, i_id);
562
563 state.world.nation_set_active_inventions(target_nation, i_id, true);
564
565 // apply modifiers from active inventions
566 auto inv_mod = inv_id.get_modifier();
567 if(inv_mod) {
568 auto& inv_nat_values = inv_mod.get_national_values();
570 if(!(inv_nat_values.offsets[i]))
571 break; // no more modifier values attached to this tech
572
573 auto fixed_offset = inv_nat_values.offsets[i];
574 auto modifier_amount = inv_nat_values.values[i];
575
576 state.world.nation_get_modifier_values(target_nation, fixed_offset) += modifier_amount;
577 }
578 }
579
581 if(inv_id.get_increase_building(t)) {
582 state.world.nation_get_max_building_level(target_nation, uint8_t(t)) += 1;
583 }
584 }
585
586 state.world.nation_get_permanent_colonial_points(target_nation) += inv_id.get_colonial_points();
587 if(inv_id.get_enable_gas_attack()) {
588 state.world.nation_set_has_gas_attack(target_nation, true);
589 }
590 if(inv_id.get_enable_gas_defense()) {
591 state.world.nation_set_has_gas_defense(target_nation, true);
592 }
593
594 auto& plur = state.world.nation_get_plurality(target_nation);
595 plur = std::clamp(plur + inv_id.get_plurality() * 100.0f, 0.0f, 100.0f);
596
597 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
598 if(inv_id.get_activate_building(id)) {
599 state.world.nation_set_active_building(target_nation, id, true);
600 auto output = state.world.factory_type_get_output(id);
601 state.world.nation_set_unlocked_commodities(target_nation, output, true);
602 }
603 });
604 for(uint32_t i = 0; i < state.military_definitions.unit_base_definitions.size(); ++i) {
605 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
606 if(inv_id.get_activate_unit(uid)) {
607 state.world.nation_set_active_unit(target_nation, uid, true);
608 }
609 }
610 for(uint32_t i = 0; i < state.culture_definitions.crimes.size(); ++i) {
611 dcon::crime_id uid = dcon::crime_id{dcon::crime_id::value_base_t(i)};
612 if(inv_id.get_activate_crime(uid)) {
613 state.world.nation_set_active_crime(target_nation, uid, true);
614 }
615 }
616
617 for(auto cmod : inv_id.get_rgo_goods_output()) {
618 state.world.nation_get_rgo_goods_output(target_nation, cmod.type) += cmod.amount;
619 }
620 for(auto cmod : inv_id.get_rgo_size()) {
621 state.world.nation_get_rgo_size(target_nation, cmod.type) += cmod.amount;
622 }
623 for(auto cmod : inv_id.get_factory_goods_output()) {
624 state.world.nation_get_factory_goods_output(target_nation, cmod.type) += cmod.amount;
625 }
626 for(auto cmod : inv_id.get_factory_goods_throughput()) {
627 state.world.nation_get_factory_goods_throughput(target_nation, cmod.type) += cmod.amount;
628 }
629 for(auto cmod : inv_id.get_rebel_org()) {
630 if(cmod.type) {
631 state.world.nation_get_rebel_org_modifier(target_nation, cmod.type) += cmod.amount;
632 } else {
633 state.world.for_each_rebel_type(
634 [&](dcon::rebel_type_id rt) { state.world.nation_get_rebel_org_modifier(target_nation, rt) += cmod.amount; });
635 }
636 }
637 for(auto& umod : inv_id.get_modified_units()) {
638 if(umod.type == state.military_definitions.base_army_unit) {
639 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
640 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
641 if(state.military_definitions.unit_base_definitions[uid].is_land) {
642 state.world.nation_get_unit_stats(target_nation, uid) += umod;
643 }
644 }
645 } else if(umod.type == state.military_definitions.base_naval_unit) {
646 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
647 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
648 if(!state.military_definitions.unit_base_definitions[uid].is_land) {
649 state.world.nation_get_unit_stats(target_nation, uid) += umod;
650 }
651 }
652 } else {
653 state.world.nation_get_unit_stats(target_nation, umod.type) += umod;
654 }
655 }
656
657 if(auto p = inv_id.get_shared_prestige(); p > 0) {
658 int32_t total = 0;
659 for(auto n : state.world.in_nation) {
660 if(n.get_active_inventions(i_id)) {
661 ++total;
662 }
663 }
664 nations::adjust_prestige(state, target_nation, p / float(total));
665 }
666}
667
668void remove_invention(sys::state& state, dcon::nation_id target_nation,
669 dcon::invention_id i_id) { // TODO: shared prestige effect
670 auto inv_id = fatten(state.world, i_id);
671
672 state.world.nation_set_active_inventions(target_nation, i_id, false);
673
674 // apply modifiers from active inventions
675 auto inv_mod = inv_id.get_modifier();
676 if(inv_mod) {
677 auto& inv_nat_values = inv_mod.get_national_values();
679 if(!(inv_nat_values.offsets[i]))
680 break; // no more modifier values attached to this tech
681
682 auto fixed_offset = inv_nat_values.offsets[i];
683 auto modifier_amount = inv_nat_values.values[i];
684
685 state.world.nation_get_modifier_values(target_nation, fixed_offset) -= modifier_amount;
686 }
687 }
688
690 if(inv_id.get_increase_building(t)) {
691 state.world.nation_get_max_building_level(target_nation, uint8_t(t)) -= 1;
692 }
693 }
694
695 state.world.nation_get_permanent_colonial_points(target_nation) -= inv_id.get_colonial_points();
696 if(inv_id.get_enable_gas_attack()) {
697 state.world.nation_set_has_gas_attack(target_nation, false);
698 }
699 if(inv_id.get_enable_gas_defense()) {
700 state.world.nation_set_has_gas_defense(target_nation, false);
701 }
702
703 auto& plur = state.world.nation_get_plurality(target_nation);
704 plur = std::clamp(plur - inv_id.get_plurality() * 100.0f, 0.0f, 100.0f);
705
706 state.world.for_each_factory_type([&](dcon::factory_type_id id) {
707 if(inv_id.get_activate_building(id)) {
708 state.world.nation_set_active_building(target_nation, id, false);
709 }
710 });
711
712 reload_unlocked_commodities(state, target_nation);
713
714 for(uint32_t i = 0; i < state.military_definitions.unit_base_definitions.size(); ++i) {
715 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
716 if(inv_id.get_activate_unit(uid)) {
717 state.world.nation_set_active_unit(target_nation, uid, false);
718 }
719 }
720 for(uint32_t i = 0; i < state.culture_definitions.crimes.size(); ++i) {
721 dcon::crime_id uid = dcon::crime_id{dcon::crime_id::value_base_t(i)};
722 if(inv_id.get_activate_crime(uid)) {
723 state.world.nation_set_active_crime(target_nation, uid, false);
724 }
725 }
726
727 for(auto cmod : inv_id.get_rgo_goods_output()) {
728 state.world.nation_get_rgo_goods_output(target_nation, cmod.type) -= cmod.amount;
729 }
730 for(auto cmod : inv_id.get_rgo_size()) {
731 state.world.nation_get_rgo_size(target_nation, cmod.type) -= cmod.amount;
732 }
733 for(auto cmod : inv_id.get_factory_goods_output()) {
734 state.world.nation_get_factory_goods_output(target_nation, cmod.type) -= cmod.amount;
735 }
736 for(auto cmod : inv_id.get_factory_goods_throughput()) {
737 state.world.nation_get_factory_goods_throughput(target_nation, cmod.type) -= cmod.amount;
738 }
739 for(auto cmod : inv_id.get_rebel_org()) {
740 if(cmod.type) {
741 state.world.nation_get_rebel_org_modifier(target_nation, cmod.type) -= cmod.amount;
742 } else {
743 state.world.for_each_rebel_type(
744 [&](dcon::rebel_type_id rt) { state.world.nation_get_rebel_org_modifier(target_nation, rt) -= cmod.amount; });
745 }
746 }
747 for(auto& umod : inv_id.get_modified_units()) {
748 if(umod.type == state.military_definitions.base_army_unit) {
749 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
750 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
751 if(state.military_definitions.unit_base_definitions[uid].is_land) {
752 state.world.nation_get_unit_stats(target_nation, uid) -= umod;
753 }
754 }
755 } else if(umod.type == state.military_definitions.base_naval_unit) {
756 for(uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
757 dcon::unit_type_id uid = dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)};
758 if(!state.military_definitions.unit_base_definitions[uid].is_land) {
759 state.world.nation_get_unit_stats(target_nation, uid) -= umod;
760 }
761 }
762 } else {
763 state.world.nation_get_unit_stats(target_nation, umod.type) -= umod;
764 }
765 }
766
767 if(auto p = inv_id.get_shared_prestige(); p > 0) {
768 int32_t total = 0;
769 for(auto n : state.world.in_nation) {
770 if(n.get_active_inventions(i_id)) {
771 ++total;
772 }
773 }
774 nations::adjust_prestige(state, target_nation, -(p / float(total + 1)));
775 }
776}
777
779 return state.flag_type_map[static_cast<size_t>(type)];
780}
781
782flag_type get_current_flag_type(sys::state const& state, dcon::nation_id target_nation) {
783 if(state.world.nation_get_owned_province_count(target_nation) == 0)
784 return flag_type::default_flag;
785
786 auto gov_type = state.world.nation_get_government_type(target_nation);
787 if(!gov_type)
788 return flag_type::default_flag;
789
790 auto id = state.world.national_identity_get_government_flag_type(state.world.nation_get_identity_from_identity_holder(target_nation), gov_type);
791 if(id != 0)
792 return flag_type(id - 1);
793
794 return flag_type(state.world.government_type_get_flag(gov_type));
795}
796
797flag_type get_current_flag_type(sys::state const& state, dcon::national_identity_id identity) {
798 auto holder = state.world.national_identity_get_nation_from_identity_holder(identity);
799 if(holder) {
800 return get_current_flag_type(state, holder);
801 } else {
802 return flag_type::default_flag;
803 }
804}
805void fix_slaves_in_province(sys::state& state, dcon::nation_id owner, dcon::province_id p) {
806 auto rules = state.world.nation_get_combined_issue_rules(owner);
807 if(!owner || (rules & issue_rule::slavery_allowed) == 0) {
808 state.world.province_set_is_slave(p, false);
809 bool mine = state.world.commodity_get_is_mine(state.world.province_get_rgo(p));
810 for(auto pop : state.world.province_get_pop_location(p)) {
811 if(pop.get_pop().get_poptype() == state.culture_definitions.slaves) {
812 pop.get_pop().set_poptype(mine ? state.culture_definitions.laborers : state.culture_definitions.farmers);
813 }
814 }
815 } else if(state.world.province_get_is_slave(p) == false) { // conversely, could become a slave state if slaves are found
816 bool found_slave = false;
817 for(auto pop : state.world.province_get_pop_location(p)) {
818 if(pop.get_pop().get_poptype() == state.culture_definitions.slaves) {
819 found_slave = true;
820 break;
821 }
822 }
823 if(found_slave) {
824 province::for_each_province_in_state_instance(state, state.world.province_get_state_membership(p), [&](dcon::province_id p2) {
825 state.world.province_set_is_slave(p2, true);
826 });
827 }
828 }
829}
830
831void update_nation_issue_rules(sys::state& state, dcon::nation_id n_id) {
832 auto old_rules = state.world.nation_get_combined_issue_rules(n_id);
833 uint32_t combined = 0;
834 state.world.for_each_issue([&](dcon::issue_id i_id) {
835 auto current_opt = state.world.nation_get_issues(n_id, i_id);
836 auto rules_for_opt = state.world.issue_option_get_rules(current_opt);
837 combined |= rules_for_opt;
838 });
839 state.world.for_each_reform([&](dcon::reform_id i_id) {
840 auto current_opt = state.world.nation_get_reforms(n_id, i_id);
841 auto rules_for_opt = state.world.reform_option_get_rules(current_opt);
842 combined |= rules_for_opt;
843 });
844 state.world.nation_set_combined_issue_rules(n_id, combined);
845
846 if((old_rules & issue_rule::slavery_allowed) != 0 && (combined & issue_rule::slavery_allowed) == 0) {
847
848 for(auto p : state.world.nation_get_province_ownership(n_id)) {
849 state.world.province_set_is_slave(p.get_province(), false);
850 bool mine = state.world.commodity_get_is_mine(state.world.province_get_rgo(p.get_province()));
851 for(auto pop : state.world.province_get_pop_location(p.get_province())) {
852 if(pop.get_pop().get_poptype() == state.culture_definitions.slaves) {
853 pop.get_pop().set_poptype(mine ? state.culture_definitions.laborers : state.culture_definitions.farmers);
854 }
855 }
856 }
857 }
858 if((old_rules & issue_rule::can_subsidise) != 0 && (combined & issue_rule::can_subsidise) == 0) {
859 for(auto p : state.world.nation_get_province_ownership(n_id)) {
860 for(auto f : p.get_province().get_factory_location()) {
861 f.get_factory().set_subsidized(false);
862 }
863 }
864 }
865}
867 state.world.execute_serial_over_nation([&](auto n_id) {
868 ve::int_vector combined;
869 state.world.for_each_issue([&](dcon::issue_id i_id) {
870 auto current_opt = state.world.nation_get_issues(n_id, i_id);
871 auto rules_for_opt = state.world.issue_option_get_rules(current_opt);
872 combined = combined | rules_for_opt;
873 });
874 state.world.for_each_reform([&](dcon::reform_id i_id) {
875 auto current_opt = state.world.nation_get_reforms(n_id, i_id);
876 auto rules_for_opt = state.world.reform_option_get_rules(current_opt);
877 combined = combined | rules_for_opt;
878 });
879 state.world.nation_set_combined_issue_rules(n_id, combined);
880 });
881}
882
884 state.world.for_each_pop([&state](dcon::pop_id pid) {
885 float total = 0.0f;
886 float pol_sup = 0.0f;
887 float soc_sup = 0.0f;
888 state.world.for_each_issue_option([&](dcon::issue_option_id i) {
889 auto sup = pop_demographics::get_demo(state, pid, pop_demographics::to_key(state, i));
890 total += sup;
891
892 auto par = state.world.issue_option_get_parent_issue(i);
893 if(state.world.issue_get_issue_type(par) == uint8_t(culture::issue_type::political)) {
894 pol_sup += sup;
895 } else if(state.world.issue_get_issue_type(par) == uint8_t(culture::issue_type::social)) {
896 soc_sup += sup;
897 }
898 });
899 if(total > 0) {
900 pop_demographics::set_political_reform_desire(state, pid, pol_sup / total);
901 pop_demographics::set_social_reform_desire(state, pid, soc_sup / total);
902 }
903 });
904}
905
907 state.world.for_each_pop([&state](dcon::pop_id pid) {
908 auto ptype = state.world.pop_get_poptype(pid);
909 auto owner = nations::owner_of_pop(state, pid);
910 auto psize = state.world.pop_get_size(pid);
911 if(psize <= 0)
912 return;
913
914 { // ideologies
915 static auto buf = state.world.ideology_make_vectorizable_float_buffer();
916 float total = 0.0f;
917 state.world.for_each_ideology([&](dcon::ideology_id iid) {
918 buf.set(iid, 0.0f);
919 if(state.world.ideology_get_enabled(iid) &&
920 (!state.world.ideology_get_is_civilized_only(iid) || state.world.nation_get_is_civilized(owner))) {
921 auto ptrigger = state.world.pop_type_get_ideology(ptype, iid);
922 if(ptrigger) {
923 auto amount = trigger::evaluate_multiplicative_modifier(state, ptrigger, trigger::to_generic(pid),
924 trigger::to_generic(pid), 0);
925 buf.set(iid, amount);
926 total += amount;
927 }
928 }
929 });
930 if(total != 0) {
931 float adjustment_factor = 1.0f / total;
932 state.world.for_each_ideology([&state, pid, adjustment_factor](dcon::ideology_id iid) {
933 auto normalized_amount = buf.get(iid) * adjustment_factor;
934 pop_demographics::set_demo(state, pid, pop_demographics::to_key(state, iid), normalized_amount);
935 });
936 }
937 }
938 { // issues
939 static auto buf = state.world.issue_option_make_vectorizable_float_buffer();
940 float total = 0.0f;
941 state.world.for_each_issue_option([&](dcon::issue_option_id iid) {
942 auto opt = fatten(state.world, iid);
943 auto allow = opt.get_allow();
944 auto parent_issue = opt.get_parent_issue();
945 auto co = state.world.nation_get_issues(owner, parent_issue);
946 buf.set(iid, 0.0f);
947 if((state.world.nation_get_is_civilized(owner) || state.world.issue_get_issue_type(parent_issue) == uint8_t(issue_type::party))
948 && (state.world.issue_get_is_next_step_only(parent_issue) == false || co.id.index() == iid.index() || co.id.index() + 1 == iid.index() || co.id.index() - 1 == iid.index())) {
949
950 if(auto mtrigger = state.world.pop_type_get_issues(ptype, iid); mtrigger) {
951 auto amount = trigger::evaluate_multiplicative_modifier(state, mtrigger, trigger::to_generic(pid),
952 trigger::to_generic(pid), 0);
953 buf.set(iid, amount);
954 total += amount;
955 }
956 }
957 });
958 if(total != 0) {
959 float adjustment_factor = 1.0f / total;
960 state.world.for_each_issue_option([&state, pid, adjustment_factor](dcon::issue_option_id iid) {
961 auto normalized_amount = buf.get(iid) * adjustment_factor;
962 pop_demographics::set_demo(state, pid, pop_demographics::to_key(state, iid), normalized_amount);
963 });
964 }
965 }
966 });
967}
968
969float effective_technology_cost(sys::state& state, uint32_t current_year, dcon::nation_id target_nation,
970 dcon::technology_id tech_id) {
971 /*
972 The effective amount of research points a tech costs = base-cost x 0v(1 - (current-year - tech-availability-year) /
973 define:TECH_YEAR_SPAN) x define:TECH_FACTOR_VASSAL(if your overlord has the tech) / (1 + tech-category-research-modifier)
974 */
975 auto base_cost = state.world.technology_get_cost(tech_id);
976 auto availability_year = state.world.technology_get_year(tech_id);
977 auto folder = state.world.technology_get_folder_index(tech_id);
978 auto category = state.culture_definitions.tech_folders[folder].category;
979 auto research_mod = [&]() {
980 switch(category) {
981 case tech_category::army:
982 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::army_tech_research_bonus) + 1.0f;
983 case tech_category::navy:
984 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::navy_tech_research_bonus) + 1.0f;
985 case tech_category::commerce:
986 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::commerce_tech_research_bonus) + 1.0f;
987 case tech_category::culture:
988 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::culture_tech_research_bonus) + 1.0f;
989 case tech_category::industry:
990 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::industry_tech_research_bonus) + 1.0f;
991 //non vanilla
992 case tech_category::military_theory:
993 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::military_theory_tech_research_bonus) + 1.0f;
994 case tech_category::population:
995 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::population_tech_research_bonus) + 1.0f;
996 case tech_category::diplomacy:
997 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::diplomacy_tech_research_bonus) + 1.0f;
998 case tech_category::flavor:
999 return state.world.nation_get_modifier_values(target_nation, sys::national_mod_offsets::flavor_tech_research_bonus) + 1.0f;
1000 default:
1001 return 1.0f;
1002 }
1003 }();
1004 auto ol_mod = state.world.nation_get_active_technologies(
1005 state.world.overlord_get_ruler(state.world.nation_get_overlord_as_subject(target_nation)), tech_id)
1006 ? state.defines.tech_factor_vassal
1007 : 1.0f;
1008 return float(base_cost) * ol_mod * (1.0f / research_mod) *
1009 (1.0f - std::max(0.0f, float(int32_t(current_year) - availability_year) / state.defines.tech_year_span));
1010}
1011
1012void update_research(sys::state& state, uint32_t current_year) {
1013 for(auto n : state.world.in_nation) {
1014 if(n.get_owned_province_count() != 0 && n.get_current_research()) {
1015 if(n.get_active_technologies(n.get_current_research())) {
1016 n.set_current_research(dcon::technology_id{});
1017 } else {
1018 auto cost = effective_technology_cost(state, current_year, n, n.get_current_research());
1019 if(n.get_research_points() >= cost) {
1020 n.get_research_points() -= cost;
1021 apply_technology(state, n, n.get_current_research());
1022
1024 [t = n.get_current_research()](sys::state& state, text::layout_base& contents) {
1025 text::add_line(state, contents, "msg_tech_1", text::variable_type::x, state.world.technology_get_name(t));
1026 ui::technology_description(state, contents, t);
1027 },
1028 "msg_tech_title",
1029 n, dcon::nation_id{}, dcon::nation_id{},
1031 });
1032
1033 n.set_current_research(dcon::technology_id{});
1034 }
1035 }
1036 }
1037 }
1038}
1039
1041 /*
1042 Inventions have a chance to be discovered on the 1st of every month. The invention chance modifier is computed additively, and
1043 the result is the chance out of 100 that the invention will be discovered. When an invention with shared prestige is
1044 discovered, the discoverer gains that amount of shared prestige / the number of times it has been discovered (including the
1045 current time).
1046 */
1047 for(auto inv : state.world.in_invention) {
1048 auto lim = inv.get_limit();
1049 auto odds = inv.get_chance();
1050 if(lim) {
1051 ve::execute_serial_fast<dcon::nation_id>(state.world.nation_size(), [&](auto nids) {
1052 auto may_discover = !state.world.nation_get_active_inventions(nids, inv)
1053 && (state.world.nation_get_owned_province_count(nids) != 0)
1054 && trigger::evaluate(state, lim, trigger::to_generic(nids), trigger::to_generic(nids), 0);
1055
1056 if(ve::compress_mask(may_discover).v != 0) {
1057 auto chances = odds
1058 ? trigger::evaluate_additive_modifier(state, odds, trigger::to_generic(nids), trigger::to_generic(nids), 0)
1059 : 1.f;
1060 ve::apply([&](dcon::nation_id n, float chance, bool allow_discovery) {
1061 if(allow_discovery) {
1062 auto random = rng::get_random(state, uint32_t(inv.id.index()) << 5 ^ uint32_t(n.index()));
1063 if(int32_t(random % 100) < int32_t(chance)) {
1064 apply_invention(state, n, inv);
1065
1066 notification::post(state, notification::message{
1067 [inv](sys::state& state, text::layout_base& contents) {
1068 text::add_line(state, contents, "msg_inv_1", text::variable_type::x, state.world.invention_get_name(inv));
1069 ui::invention_description(state, contents, inv, 0);
1070 },
1071 "msg_inv_title",
1072 n, dcon::nation_id{}, dcon::nation_id{},
1073 sys::message_base_type::invention
1074 });
1075 }
1076 }
1077 }, nids, chances, may_discover);
1078 }
1079 });
1080 } else {
1081 ve::execute_serial_fast<dcon::nation_id>(state.world.nation_size(), [&](auto nids) {
1082 auto may_not_discover =
1083 state.world.nation_get_active_inventions(nids, inv) || (state.world.nation_get_owned_province_count(nids) == 0);
1084 if(ve::compress_mask(may_not_discover).v != 0) {
1085 auto chances = odds
1086 ? trigger::evaluate_additive_modifier(state, odds, trigger::to_generic(nids), trigger::to_generic(nids), 0)
1087 : 1.f;
1088 ve::apply([&](dcon::nation_id n, float chance, bool block_discovery) {
1089 if(!block_discovery) {
1090 auto random = rng::get_random(state, uint32_t(inv.id.index()) << 5 ^ uint32_t(n.index()));
1091 if(int32_t(random % 100) < int32_t(chance)) {
1092 apply_invention(state, n, inv);
1093
1094 notification::post(state, notification::message{
1095 [inv](sys::state& state, text::layout_base& contents) {
1096 text::add_line(state, contents, "msg_inv_1", text::variable_type::x, state.world.invention_get_name(inv));
1097 ui::invention_description(state, contents, inv, 0);
1098 },
1099 "msg_inv_title",
1100 n, dcon::nation_id{}, dcon::nation_id{},
1101 sys::message_base_type::invention
1102 });
1103 }
1104 }
1105 }, nids, chances, may_not_discover);
1106 }
1107 });
1108 }
1109 }
1110}
1111
1112void replace_cores(sys::state& state, dcon::national_identity_id old_tag, dcon::national_identity_id new_tag) {
1113 if(new_tag) {
1114 for(auto cores_of : state.world.national_identity_get_core(old_tag)) {
1115 state.world.try_create_core(cores_of.get_province(), new_tag);
1116 }
1117 }
1118 auto core_list = state.world.national_identity_get_core(old_tag);
1119 while(core_list.begin() != core_list.end()) {
1120 state.world.delete_core((*core_list.begin()).id);
1121 }
1122}
1123
1124} // namespace culture
uint32_t get_remapped_flag_type(sys::state const &state, flag_type type)
Definition: culture.cpp:778
void discover_inventions(sys::state &state)
Definition: culture.cpp:1040
void reload_unlocked_commodities(sys::state &state, dcon::nation_id target_nation)
Definition: culture.cpp:55
void apply_invention(sys::state &state, dcon::nation_id target_nation, dcon::invention_id i_id)
Definition: culture.cpp:560
float effective_technology_cost(sys::state &state, uint32_t current_year, dcon::nation_id target_nation, dcon::technology_id tech_id)
Definition: culture.cpp:969
void fix_slaves_in_province(sys::state &state, dcon::nation_id owner, dcon::province_id p)
Definition: culture.cpp:805
void replace_cores(sys::state &state, dcon::national_identity_id old_tag, dcon::national_identity_id new_tag)
Definition: culture.cpp:1112
void clear_existing_tech_effects(sys::state &state)
Definition: culture.cpp:94
void repopulate_technology_effects(sys::state &state)
Definition: culture.cpp:158
void update_all_nations_issue_rules(sys::state &state)
Definition: culture.cpp:866
void set_default_issue_and_reform_options(sys::state &state)
Definition: culture.cpp:39
void remove_invention(sys::state &state, dcon::nation_id target_nation, dcon::invention_id i_id)
Definition: culture.cpp:668
void repopulate_invention_effects(sys::state &state)
Definition: culture.cpp:260
void update_research(sys::state &state, uint32_t current_year)
Definition: culture.cpp:1012
flag_type get_current_flag_type(sys::state const &state, dcon::nation_id target_nation)
Definition: culture.cpp:782
void restore_unsaved_values(sys::state &state)
Definition: culture.cpp:883
void remove_technology(sys::state &state, dcon::nation_id target_nation, dcon::technology_id t_id)
Definition: culture.cpp:486
void create_initial_ideology_and_issues_distribution(sys::state &state)
Definition: culture.cpp:906
void apply_technology(sys::state &state, dcon::nation_id target_nation, dcon::technology_id t_id)
Definition: culture.cpp:412
std::string get_tech_category_name(tech_category t)
Definition: culture.cpp:12
void update_nation_issue_rules(sys::state &state, dcon::nation_id n_id)
Definition: culture.cpp:831
tech_category
Definition: culture.hpp:106
province_building_type
Definition: constants.hpp:578
constexpr uint32_t can_subsidise
Definition: culture.hpp:13
constexpr uint32_t slavery_allowed
Definition: culture.hpp:27
void reset_unit_stats(sys::state &state)
Definition: military.cpp:186
void adjust_prestige(sys::state &state, dcon::nation_id n, float delta)
Definition: nations.cpp:1900
dcon::nation_id owner_of_pop(sys::state const &state, dcon::pop_id pop_ids)
Definition: nations.cpp:87
void post(sys::state &state, message &&m)
void set_political_reform_desire(sys::state &state, dcon::pop_id p, float v)
void set_social_reform_desire(sys::state &state, dcon::pop_id p, float v)
void set_demo(sys::state &state, dcon::pop_id p, dcon::pop_demographics_key k, float v)
dcon::pop_demographics_key to_key(sys::state const &state, dcon::ideology_id v)
float get_demo(sys::state const &state, dcon::pop_id p, dcon::pop_demographics_key k)
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
Definition: text.cpp:1923
int32_t to_generic(dcon::province_id v)
Definition: triggers.hpp:12
float evaluate_multiplicative_modifier(sys::state &state, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
Definition: triggers.cpp:5812
void technology_description(sys::state &state, text::layout_base &contents, dcon::technology_id tech_id) noexcept
T select(bool v, T a, T b)
uint uint32_t
uchar uint8_t
static constexpr uint32_t modifier_definition_size
Definition: modifiers.hpp:231
Holds important data about the game world, state, and other data regarding windowing,...