3#include "dcon_generated.hpp"
26 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, gp);
32template auto nation_accepts_culture<ve::tagged_vector<dcon::nation_id>, dcon::culture_id>(
sys::state const&, ve::tagged_vector<dcon::nation_id>, dcon::culture_id);
33template auto primary_culture_group<ve::tagged_vector<dcon::nation_id>>(
sys::state const&, ve::tagged_vector<dcon::nation_id>);
34template auto owner_of_pop<ve::tagged_vector<dcon::pop_id>>(
sys::state const&, ve::tagged_vector<dcon::pop_id>);
35template auto central_blockaded_fraction<ve::tagged_vector<dcon::nation_id>>(
sys::state const&, ve::tagged_vector<dcon::nation_id>);
36template auto central_reb_controlled_fraction<ve::tagged_vector<dcon::nation_id>>(
sys::state const&, ve::tagged_vector<dcon::nation_id>);
37template auto central_has_crime_fraction<ve::tagged_vector<dcon::nation_id>>(
sys::state const&, ve::tagged_vector<dcon::nation_id>);
38template auto occupied_provinces_fraction<ve::tagged_vector<dcon::nation_id>>(
sys::state const&, ve::tagged_vector<dcon::nation_id>);
41 std::vector<dcon::nation_id> subjects;
42 for(
auto s : state.world.in_nation) {
43 auto rel = state.world.nation_get_overlord_as_subject(s);
44 auto overlord = state.world.overlord_get_ruler(rel);
50 subjects.push_back(s);
62 int64_t estimated_change = 0;
63 for(
auto p : state.world.nation_get_province_ownership(n)) {
64 for(
auto pl : state.world.province_get_pop_location(p.get_province())) {
68 auto total = int64_t(growth) + colonial_migration + emigration;
69 estimated_change += total;
72 return estimated_change;
77 for(uint16_t i = 0; i < uint16_t(state.nations_by_rank.size()); ++i) {
80 return state.nations_by_rank[i];
84 return dcon::nation_id{};
88 auto location = state.world.pop_get_province_from_pop_location(pop_ids);
89 return state.world.province_get_nation_from_province_ownership(location);
93 state.world.for_each_state_instance([&](dcon::state_instance_id sid) {
94 auto owner = state.world.state_instance_get_nation_from_state_ownership(sid);
95 auto base_state = state.world.state_instance_get_definition(sid);
96 for(
auto mprov : state.world.state_definition_get_abstract_state_membership(base_state)) {
97 if(mprov.get_province().get_nation_from_province_ownership() == owner) {
98 mprov.get_province().set_state_membership(sid);
106 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_allies_count(ids, ve::int_vector()); });
107 state.world.for_each_diplomatic_relation([&](dcon::diplomatic_relation_id
id) {
108 if(state.world.diplomatic_relation_get_are_allied(
id)) {
109 state.world.nation_get_allies_count(state.world.diplomatic_relation_get_related_nations(id, 0)) += uint16_t(1);
110 state.world.nation_get_allies_count(state.world.diplomatic_relation_get_related_nations(id, 1)) += uint16_t(1);
114 state.world.for_each_nation([&](dcon::nation_id n) {
116 int32_t substates_total = 0;
117 for(
auto v : state.world.nation_get_overlord_as_ruler(n)) {
119 if(v.get_subject().get_is_substate())
122 state.world.nation_set_vassals_count(n, uint16_t(total));
123 state.world.nation_set_substates_count(n, uint16_t(substates_total));
128 if(state.diplomatic_cached_values_out_of_date) {
129 state.diplomatic_cached_values_out_of_date =
false;
135 state.world.market_resize_demand_satisfaction(state.world.commodity_size());
136 state.world.market_resize_supply_sold_ratio(state.world.commodity_size());
137 state.world.market_resize_direct_demand_satisfaction(state.world.commodity_size());
139 for(
auto n : state.world.in_nation)
140 n.set_is_great_power(
false);
142 for(
auto& gp : state.great_nations) {
143 state.world.nation_set_is_great_power(gp.nation,
true);
146 state.world.for_each_gp_relationship([&](dcon::gp_relationship_id rel) {
147 if((influence::level_mask & state.world.gp_relationship_get_status(rel)) == influence::level_in_sphere) {
148 auto t = state.world.gp_relationship_get_influence_target(rel);
149 auto gp = state.world.gp_relationship_get_great_power(rel);
150 state.world.nation_set_in_sphere_of(t, gp);
154 state.world.execute_serial_over_nation([&](
auto ids) {
155 auto treasury = state.world.nation_get_stockpiles(ids,
economy::money);
156 state.world.nation_set_last_treasury(ids, treasury);
163 float total_transport_speed = 0.f;
164 float total_amount_of_transports = 0.f;
166 for(
uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
167 dcon::unit_type_id j{ dcon::unit_type_id::value_base_t(i) };
169 total_transport_speed += state.military_definitions.unit_base_definitions[j].maximum_speed;
170 total_amount_of_transports += 1.f;
174 auto base_speed = total_transport_speed / total_amount_of_transports;
176 state.world.execute_parallel_over_market([&](
auto markets) {
177 auto sids = state.world.market_get_zone_from_local_market(markets);
178 auto population = ve::apply([&](
auto sid) {
182 auto naval_base =
ve::to_float(ve::apply([&](
auto sid) {
192 auto throughput = 100.f + 8000.f * naval_base + 1000.f * railroads + population / 50.f;
194 state.world.market_set_max_throughput(markets, throughput);
197 state.world.execute_parallel_over_trade_route([&](
auto routes) {
199 auto markets_0 = ve::apply([&](
auto route) {
return state.world.trade_route_get_connected_markets(route, 0); }, routes);
200 auto markets_1 = ve::apply([&](
auto route) {
return state.world.trade_route_get_connected_markets(route, 1); }, routes);
202 auto sids_0 = state.world.market_get_zone_from_local_market(markets_0);
203 auto sids_1 = state.world.market_get_zone_from_local_market(markets_1);
205 ve::apply([&](
auto sid_0,
auto sid_1,
auto route) {
206 if (state.world.trade_route_get_is_sea_route(route)) {
207 std::vector<dcon::province_id> path{ };
208 auto speed = base_speed;
209 dcon::province_id p_prev{ };
216 auto ps = path.size();
217 auto effective_distance = 0.f;
218 auto worst_movement_cost = 0.f;
220 for(
size_t i = 0; i < ps; i++) {
221 auto p_current = path[i];
222 auto adj = state.world.get_province_adjacency_by_province_pair(p_prev, p_current);
223 float distance = province::distance(state, adj);
225 state.world.province_get_modifier_values(p_current, sys::provincial_mod_offsets::movement_cost)
226 + state.world.province_get_modifier_values(p_prev, sys::provincial_mod_offsets::movement_cost);
227 effective_distance += std::max(0.01f, distance * std::max(0.01f, (sum_mods * 2.f + 1.0f)));
228 if(sum_mods > worst_movement_cost)
229 worst_movement_cost = std::max(0.01f, sum_mods);
233 state.world.trade_route_set_sea_distance(route, effective_distance / speed);
235 state.world.trade_route_set_sea_distance(route, 99999.f);
238 if(state.world.trade_route_get_is_land_route(route)) {
239 std::vector<dcon::province_id> path{ };
240 auto speed = base_speed;
241 dcon::province_id p_prev{ };
243 auto market_0_center = state.world.state_instance_get_capital(sid_0);
244 auto market_1_center = state.world.state_instance_get_capital(sid_1);
247 p_prev = market_0_center;
249 auto ps = path.size();
250 auto effective_distance = 0.f;
251 auto worst_movement_cost = 0.f;
252 auto min_railroad_level = 0.f;
254 for(
size_t i = 0; i < ps; i++) {
255 auto p_current = path[i];
256 auto adj = state.world.get_province_adjacency_by_province_pair(p_prev, p_current);
257 float distance = province::distance(state, adj);
259 state.world.province_get_modifier_values(p_current, sys::provincial_mod_offsets::movement_cost)
260 + state.world.province_get_modifier_values(p_prev, sys::provincial_mod_offsets::movement_cost);
261 float local_effective_distance = distance * std::max(0.01f, sum_mods * 3.f);
262 auto railroad_origin = state.world.province_get_building_level(p_prev, uint8_t(economy::province_building_type::railroad));
263 auto railroad_target = state.world.province_get_building_level(p_current, uint8_t(economy::province_building_type::railroad));
264 if(railroad_origin > 0 && railroad_target > 0) {
265 local_effective_distance = local_effective_distance / 2.f;
267 local_effective_distance -= 0.03f * std::min(railroad_target, railroad_origin) * local_effective_distance;
268 effective_distance += std::max(0.01f, local_effective_distance);
269 if(sum_mods > worst_movement_cost)
270 worst_movement_cost = std::max(0.01f, sum_mods);
274 state.world.trade_route_set_land_distance(route, effective_distance / speed);
276 state.world.trade_route_set_land_distance(route, 99999.f);
278 }, sids_0, sids_1, routes);
289 float total_transport_speed = 0.f;
290 float total_amount_of_transports = 0.f;
292 for(
uint32_t i = 2; i < state.military_definitions.unit_base_definitions.size(); ++i) {
293 dcon::unit_type_id j{ dcon::unit_type_id::value_base_t(i) };
295 total_transport_speed += state.military_definitions.unit_base_definitions[j].maximum_speed;
296 total_amount_of_transports += 1.f;
300 auto base_speed = total_transport_speed / total_amount_of_transports;
303 std::array<dcon::state_instance_id, 4000> capital_of_region = {};
304 std::array<float, 10000> population_of_region = { };
305 std::vector<float> nation_to_max_population = { };
306 nation_to_max_population.resize(state.world.nation_size());
308 state.world.for_each_state_instance([&](
auto candidate) {
312 auto connected_region = state.world.province_get_connected_coast_id(capital);
313 auto size = state.world.state_instance_get_demographics(
317 population_of_region[connected_region] += size;
319 if(!capital_of_region[connected_region]) {
320 capital_of_region[connected_region] = candidate;
322 auto current_population = state.world.state_instance_get_demographics(
325 if(size > current_population) {
326 capital_of_region[connected_region] = candidate;
332 state.world.for_each_state_instance([&](
auto candidate) {
335 auto connected_region = state.world.province_get_connected_coast_id(capital);
336 auto owner = state.world.province_get_nation_from_province_ownership(capital);
337 auto size = population_of_region[connected_region];
338 nation_to_max_population[owner.index()] = std::max(nation_to_max_population[owner.index()], size);
344 constexpr float M = 0.17f * 0.000'000'1f;
346 float world_population = 0.f;
347 state.world.for_each_nation([&](
auto nation) {
351 state.world.for_each_state_instance([&](
auto origin) {
355 auto market = state.world.state_instance_get_market_from_local_market(origin);
357 auto capital = state.world.state_instance_get_capital(origin);
358 auto owner = state.world.state_instance_get_nation_from_state_ownership(origin);
359 auto state_owner_capital = state.world.nation_get_capital(owner);
360 auto state_owner_capital_state = state.world.province_get_state_membership(state_owner_capital);
363 auto population_origin = state.world.state_instance_get_demographics(origin,
demographics::total);
365 auto connected_region = state.world.province_get_connected_coast_id(coast_0);
366 auto connected_region_size = 0.f;
368 state.world.for_each_state_instance([&](
auto sid) {
376 auto target_market = state.world.state_instance_get_market_from_local_market(sid);
377 auto route = state.world.get_trade_route_by_province_pair(market, target_market);
379 state.world.trade_route_set_is_sea_route(route,
true);
383 bool same_owner =
false;
384 bool different_region =
false;
385 bool capital_and_connected_region =
false;
387 auto target_owner = state.world.state_instance_get_nation_from_state_ownership(sid);
388 if(target_owner == owner) {
392 auto capital_target = state.world.state_instance_get_capital(sid);
393 auto connected_region_target = state.world.province_get_connected_coast_id(coast_1);
394 if(connected_region != connected_region_target) {
395 different_region =
true;
400 capital_of_region[connected_region_target] == sid
402 state_owner_capital_state == origin
406 state_owner_capital_state == sid
408 capital_of_region[connected_region] == origin
411 capital_and_connected_region =
true;
415 auto state_target_owner_capital = state.world.nation_get_capital(target_owner);
416 auto state_target_owner_capital_state = state.world.province_get_state_membership(state_target_owner_capital);
417 auto continent_target = state.world.province_get_continent(coast_1);
418 auto continent_origin = state.world.province_get_continent(state_owner_capital);
421 mult += std::min(naval_base_origin, naval_base_target) * 0.25f;
422 bool must_connect = same_owner && different_region && capital_and_connected_region;
428 float score_origin = population_origin;
429 float score_target = state.world.state_instance_get_demographics(sid,
demographics::total);
430 if(capital_of_region[connected_region_target] == sid && capital_of_region[connected_region] == origin) {
431 score_origin = population_of_region[connected_region];
432 score_target = population_of_region[connected_region_target];
436 float score_approximation = mult * M * score_origin * score_target / distance_approximation / distance_approximation / distance_approximation;
438 if(!(score_approximation >= 1.f || must_connect)) {
442 auto distance = 9999.f;
444 std::vector<dcon::province_id> path{ };
445 auto speed = base_speed;
446 dcon::province_id p_prev{ };
450 auto ps = path.size();
451 auto effective_distance = 0.f;
452 auto worst_movement_cost = 0.f;
454 for(
size_t i = 0; i < ps; i++) {
455 auto p_current = path[i];
456 auto adj = state.world.get_province_adjacency_by_province_pair(p_prev, p_current);
459 state.world.province_get_modifier_values(p_current, sys::provincial_mod_offsets::movement_cost)
460 + state.world.province_get_modifier_values(p_prev, sys::provincial_mod_offsets::movement_cost);
461 effective_distance += std::max(0.01f, local_distance * std::max(0.01f, (sum_mods * 2.f + 1.0f)));
462 if(sum_mods > worst_movement_cost)
463 worst_movement_cost = std::max(0.01f, sum_mods);
467 distance = effective_distance / speed;
470 float score = mult * M * score_origin * score_target / distance / distance / distance;
472 if(score >= 1.f || must_connect) {
473 auto new_route = state.world.force_create_trade_route(market, target_market);
474 state.world.trade_route_set_is_sea_route(new_route,
true);
480 std::vector<parent_link> best_parent;
481 std::vector<bool> parent_found;
482 parent_found.resize(state.world.market_size());
484 state.world.for_each_state_instance([&](
auto origin) {
487 auto origin_market = state.world.state_instance_get_market_from_local_market(origin);
488 auto origin_capital = state.world.state_instance_get_capital(origin);
489 auto origin_owner = state.world.state_instance_get_nation_from_state_ownership(origin);
490 auto origin_connected_region = state.world.province_get_connected_coast_id(origin_capital);
491 auto origin_connected_region_population = population_of_region[origin_connected_region];
492 if(origin != capital_of_region[origin_connected_region]) {
498 parent_found[origin_market.index()] =
false;
500 bool origin_is_major_node = origin_connected_region_population > 0.7f * nation_to_max_population[origin_owner.index()];
502 state.world.for_each_state_instance([&](
auto target) {
503 if(origin == target) {
508 auto target_market = state.world.state_instance_get_market_from_local_market(target);
509 auto target_capital = state.world.state_instance_get_capital(target);
510 auto target_owner = state.world.state_instance_get_nation_from_state_ownership(target);
512 auto target_connected_region = state.world.province_get_connected_coast_id(target_coast);
513 auto target_connected_region_population = population_of_region[target_connected_region];
515 if(target != capital_of_region[target_connected_region]) {
519 if(target_owner != origin_owner) {
524 auto route = state.world.get_trade_route_by_province_pair(origin_market, target_market);
526 state.world.trade_route_set_is_sea_route(route,
true);
530 bool target_is_major_node = target_connected_region_population > 0.7f * nation_to_max_population[target_owner.index()];
532 if(origin_is_major_node && target_is_major_node) {
533 auto new_route = state.world.force_create_trade_route(origin_market, target_market);
534 state.world.trade_route_set_is_sea_route(new_route,
true);
538 if(origin_is_major_node) {
539 best_parent.push_back({
547 if(target_is_major_node) {
548 best_parent.push_back({
559 if(a.dist < b.dist) {
566 return (a.
leaf.index() < b.
leaf.index());
569 for(
unsigned i = 0; i < best_parent.size(); i++) {
570 if(parent_found[best_parent[i].leaf.index()]) {
574 parent_found[best_parent[i].leaf.index()] =
true;
576 auto new_route =
state.world.force_create_trade_route(best_parent[i].leaf, best_parent[i].parent);
577 state.world.trade_route_set_is_sea_route(new_route,
true);
583 state.world.for_each_state_instance([&](
auto sid) {
584 auto owner = state.world.state_instance_get_nation_from_state_ownership(sid);
585 auto market = state.world.state_instance_get_market_from_local_market(sid);
586 std::set<dcon::state_instance_id::value_base_t> trade_route_candidates;
590 for(
auto adj : state.world.province_get_province_adjacency(prov)) {
591 if((adj.get_type() & (province::border::impassible_bit | province::border::coastal_bit)) == 0) {
593 adj.get_connected_provinces(0) != prov
594 ? adj.get_connected_provinces(0)
595 : adj.get_connected_provinces(1);
597 if(!other.get_state_membership())
599 if(other.get_state_membership() == sid)
601 if(trade_route_candidates.contains(other.get_state_membership().id.value))
604 trade_route_candidates.insert(other.get_state_membership().id.value);
609 for(
auto candidate_trade_partner_val : trade_route_candidates) {
610 auto si = dcon::state_instance_id{ uint16_t(candidate_trade_partner_val - 1) };
611 auto target_market = state.world.state_instance_get_market_from_local_market(si);
612 auto new_route = state.world.force_create_trade_route(market, target_market);
615 state.world.trade_route_set_is_sea_route(new_route,
true);
617 state.world.trade_route_set_is_land_route(new_route,
true);
621 generate_sea_trade_routes(state);
623 recalculate_markets_distance(state);
627 for(int32_t i = 0; i < state.province_definitions.first_sea_province.index(); ++i) {
628 dcon::province_id pid{dcon::province_id::value_base_t(i)};
629 auto owner = state.world.province_get_nation_from_province_ownership(pid);
630 if(owner && !(state.world.province_get_state_membership(pid))) {
631 auto state_instance = fatten(state.world, state.world.create_state_instance());
632 auto new_market = state.world.create_market();
633 auto new_local_market = state.world.force_create_local_market(new_market, state_instance);
635 auto abstract_state = state.world.province_get_state_from_abstract_state_membership(pid);
637 state_instance.set_definition(abstract_state);
638 state_instance.set_capital(pid);
639 state.world.force_create_state_ownership(state_instance, owner);
641 for(
auto mprov : state.world.state_definition_get_abstract_state_membership(abstract_state)) {
642 auto prov = mprov.get_province();
643 if(prov.get_nation_from_province_ownership() == owner) {
644 prov.set_state_membership(state_instance);
650 for(
auto si : state.world.in_state_instance) {
651 auto cap = si.get_capital();
653 auto slave = cap.get_is_slave();
654 auto colonial = cap.get_is_colonial();
657 state.world.province_set_is_colonial(p, colonial);
658 state.world.province_set_is_slave(p, slave);
664 auto target_nation = state.world.national_identity_get_nation_from_identity_holder(releasable);
665 if(!state.world.national_identity_get_is_not_releasable(releasable) &&
666 state.world.nation_get_owned_province_count(target_nation) == 0) {
667 bool owns_a_core =
false;
668 bool not_on_capital =
true;
669 state.world.national_identity_for_each_core(releasable, [&](dcon::core_id core) {
670 auto province = state.world.core_get_province(core);
671 owns_a_core |= state.world.province_get_nation_from_province_ownership(
province) == n;
672 not_on_capital &= state.world.nation_get_capital(n) !=
province;
674 return owns_a_core && not_on_capital && !state.world.nation_get_is_at_war(n);
682 return bool(fat_ident.get_nation_from_identity_holder().id);
686 auto rel = state.world.get_diplomatic_relation_by_diplomatic_pair(a, b);
687 return state.world.diplomatic_relation_get_are_allied(rel);
691 return state.world.nation_get_total_ports(n) == 0;
696 return fat_id.get_related_nations(0) == query ? fat_id.get_related_nations(1) : fat_id.get_related_nations(0);
699bool global_national_state::is_global_flag_variable_set(dcon::global_flag_id
id)
const {
701 return dcon::bit_vector_test(global_flag_variables.data(),
id.index());
705void global_national_state::set_global_flag_variable(dcon::global_flag_id
id,
bool state) {
707 dcon::bit_vector_set(global_flag_variables.data(),
id.index(), state);
711 auto holder = state.world.national_identity_get_nation_from_identity_holder(tag);
715 return state.world.national_identity_get_name(tag);
725 state.world.execute_serial_over_nation([&](
auto ids) {
726 auto admin_mod = state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::administrative_efficiency_modifier);
727 ve::fp_vector issue_sum;
728 for(
auto i : state.culture_definitions.social_issues) {
729 issue_sum = issue_sum + state.world.issue_option_get_administrative_multiplier(state.world.nation_get_issues(ids, i));
731 auto from_issues = issue_sum * state.defines.bureaucracy_percentage_increment + state.defines.max_bureaucracy_percentage;
733 auto non_colonial = state.world.nation_get_non_colonial_population(ids);
735 (admin_mod + 1.0f) * state.world.nation_get_non_colonial_bureaucrats(ids) / (non_colonial * from_issues), 0.0f);
737 state.world.nation_set_administrative_efficiency(ids, ve::min(total, 1.0f));
747 auto rp_mod_mod = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::research_points_modifier);
748 auto rp_mod = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::research_points);
750 float sum_from_pops = 0;
752 if(total_pop <= 0.0f)
755 state.world.for_each_pop_type([&](dcon::pop_type_id t) {
756 auto rp = state.world.pop_type_get_research_points(t);
758 sum_from_pops += rp * std::min(1.0f, state.world.nation_get_demographics(n,
demographics::to_key(state, t)) /
759 (total_pop * state.world.pop_type_get_research_optimum(t)));
763 return std::max(0.0f, (sum_from_pops + rp_mod) * (rp_mod_mod + 1.0f));
767 float total_priority = 0.f;
768 state.world.for_each_factory_type([&](
auto factory_type_id) {
771 + state.world.nation_get_factory_type_experience_priority_national(n, factory_type_id);
774 if(total_priority == 0.f) {
777 return state.world.nation_get_factory_type_experience_priority_national(n, ftid) / total_priority;
782 float total_priority = 0.f;
783 state.world.for_each_factory_type([&](
auto factory_type_id) {
786 + state.world.nation_get_factory_type_experience_priority_private(n, factory_type_id);
789 if(total_priority == 0.f) {
792 return state.world.nation_get_factory_type_experience_priority_private(n, ftid) / total_priority;
802 state.world.execute_serial_over_nation([&](
auto ids) {
803 auto rp_mod_mod = state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::research_points_modifier);
804 auto rp_mod = state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::research_points);
806 ve::fp_vector sum_from_pops;
809 state.world.for_each_pop_type([&](dcon::pop_type_id t) {
810 auto rp = state.world.pop_type_get_research_points(t);
812 sum_from_pops = ve::multiply_and_add(
816 state.world.nation_get_demographics(
820 (total_pop * state.world.pop_type_get_research_optimum(t))
830 state.world.nation_get_owned_province_count(ids) != 0,
832 (sum_from_pops + rp_mod) * (rp_mod_mod + 1.0f),
842 auto current_points = state.world.nation_get_research_points(ids);
843 auto capped_value = ve::min(
844 amount + current_points,
846 state.world.nation_get_is_civilized(ids),
848 state.world.nation_get_current_research(ids) == dcon::technology_id{},
850 amount + current_points
852 state.defines.max_research_points
855 state.world.nation_set_research_points(ids, capped_value);
857 ve::fp_vector total_priority_national { };
858 ve::fp_vector total_priority_private { };
860 state.world.for_each_factory_type([&](
auto factory_type_id) {
861 total_priority_national =
862 total_priority_national
863 + state.world.nation_get_factory_type_experience_priority_national(ids, factory_type_id);
864 total_priority_private =
865 total_priority_private
866 + state.world.nation_get_factory_type_experience_priority_private(ids, factory_type_id);
869 state.world.for_each_factory_type([&](
auto factory_type_id) {
870 auto national_p = state.world.nation_get_factory_type_experience_priority_national(ids, factory_type_id);
871 auto private_p = state.world.nation_get_factory_type_experience_priority_private(ids, factory_type_id);
873 ve::select(total_priority_national > 0.f, national_p / total_priority_national, 0.f)
875 ve::select(total_priority_private > 0.f, private_p / total_priority_private, 0.f);
877 auto exp = state.world.nation_get_factory_type_experience(ids, factory_type_id);
879 state.world.nation_set_factory_type_experience(ids, factory_type_id, (exp * 0.999f) + (priority * amount));
886 for(
auto i : state.world.nation_get_unilateral_relationship_as_target(n)) {
887 v += i.get_foreign_investment();
894 for(
auto i : state.world.nation_get_unilateral_relationship_as_source(n)) {
895 v += i.get_foreign_investment();
908 state.world.for_each_nation([&, iweight = state.defines.investment_score_factor](dcon::nation_id n) {
910 if(state.world.nation_get_owned_province_count(n) != 0) {
911 for(auto si : state.world.nation_get_state_ownership(n)) {
912 float total_level = 0;
914 si.get_state().get_demographics(demographics::to_employment_key(state, state.culture_definitions.primary_factory_worker)) +
915 si.get_state().get_demographics(demographics::to_employment_key(state, state.culture_definitions.secondary_factory_worker));
917 float total_factory_capacity = 0;
918 province::for_each_province_in_state_instance(state, si.get_state(), [&](dcon::province_id p) {
919 for(auto f : state.world.province_get_factory_location(p)) {
920 total_factory_capacity +=
921 float(f.get_factory().get_level() * f.get_factory().get_building_type().get_base_workforce());
922 total_level += float(f.get_factory().get_level());
925 if(total_factory_capacity > 0)
926 sum += 4.0f * total_level * std::max(std::min(1.0f, worker_total / total_factory_capacity), 0.05f);
928 sum += nations::get_foreign_investment_as_gp(state, n) * iweight;
931 state.world.nation_set_industrial_score(n, uint16_t(sum));
949 float lp_factor = state.defines.alice_military_score_leadership_factor;
950 state.world.execute_serial_over_nation([&, disarm = state.defines.disarmament_army_hit](
auto n) {
951 auto recruitable = ve::to_float(state.world.nation_get_recruitable_regiments(n));
952 auto active_regs = ve::to_float(state.world.nation_get_active_regiments(n));
953 auto is_disarmed = ve::apply([&](dcon::nation_id i) { return state.world.nation_get_disarmed_until(i) < state.current_date; }, n);
954 auto disarm_factor =
ve::select(is_disarmed, ve::fp_vector(disarm), ve::fp_vector(1.0f));
955 auto supply_mod = ve::max(state.world.nation_get_modifier_values(n, sys::national_mod_offsets::supply_consumption) + 1.0f, 0.1f);
956 auto avg_land_score = state.world.nation_get_averge_land_unit_score(n);
957 state.world.nation_set_military_score(n,
ve::to_int((ve::min(recruitable, active_regs * 4.0f) * avg_land_score) * ((disarm_factor * supply_mod) / 7.0f) + state.world.nation_get_capital_ship_score(n) + active_regs));
962 return std::max(0.0f, state.world.nation_get_prestige(n) +
963 state.world.nation_get_modifier_values(n, sys::national_mod_offsets::permanent_prestige));
968 state.world.for_each_nation([&](dcon::nation_id n) {
969 state.nations_by_rank[to_sort_count] = n;
972 std::sort(state.nations_by_rank.begin(), state.nations_by_rank.begin() + to_sort_count,
973 [&](dcon::nation_id a, dcon::nation_id b) {
974 auto fa = fatten(state.world, a);
975 auto fb = fatten(state.world, b);
976 if((fa.get_owned_province_count() != 0) != (fb.get_owned_province_count() != 0)) {
977 return (fa.get_owned_province_count() != 0);
979 if(fa.get_is_civilized() != fb.get_is_civilized())
980 return fa.get_is_civilized();
981 if(
bool(fa.get_overlord_as_subject().get_ruler()) !=
bool(fa.get_overlord_as_subject().get_ruler()))
982 return !
bool(fa.get_overlord_as_subject().get_ruler());
983 auto a_score = fa.get_military_score() + fa.get_industrial_score() +
prestige_score(state, a);
984 auto b_score = fb.get_military_score() + fb.get_industrial_score() +
prestige_score(state, b);
985 if(a_score != b_score)
986 return a_score > b_score;
987 return a.index() > b.index();
989 if(to_sort_count < state.nations_by_rank.size()) {
990 state.nations_by_rank[to_sort_count] = dcon::nation_id{};
992 for(
uint32_t i = 0; i < to_sort_count; ++i) {
993 state.world.nation_set_rank(
state.nations_by_rank[i], uint16_t(i + 1));
999 state.world.for_each_nation([&](dcon::nation_id n) {
1000 if(state.world.nation_get_owned_province_count(n) != 0) {
1001 state.nations_by_industrial_score[to_sort_count] = n;
1002 state.nations_by_military_score[to_sort_count] = n;
1003 state.nations_by_prestige_score[to_sort_count] = n;
1007 std::sort(state.nations_by_industrial_score.begin(), state.nations_by_industrial_score.begin() + to_sort_count,
1008 [&](dcon::nation_id a, dcon::nation_id b) {
1009 auto fa = fatten(state.world, a);
1010 auto fb = fatten(state.world, b);
1011 if(fa.get_is_civilized() && !fb.get_is_civilized())
1013 if(!fa.get_is_civilized() && fb.get_is_civilized())
1015 if(bool(fa.get_overlord_as_subject()) && !bool(fa.get_overlord_as_subject()))
1017 if(!bool(fa.get_overlord_as_subject()) && bool(fa.get_overlord_as_subject()))
1019 auto a_score = fa.get_industrial_score();
1020 auto b_score = fb.get_industrial_score();
1021 if(a_score != b_score)
1022 return a_score > b_score;
1023 return a.index() > b.index();
1025 std::sort(state.nations_by_military_score.begin(), state.nations_by_military_score.begin() + to_sort_count,
1026 [&](dcon::nation_id a, dcon::nation_id b) {
1027 auto fa = fatten(state.world, a);
1028 auto fb = fatten(state.world, b);
1029 if(fa.get_is_civilized() && !fb.get_is_civilized())
1031 if(!fa.get_is_civilized() && fb.get_is_civilized())
1033 if(bool(fa.get_overlord_as_subject()) && !bool(fa.get_overlord_as_subject()))
1035 if(!bool(fa.get_overlord_as_subject()) && bool(fa.get_overlord_as_subject()))
1037 auto a_score = fa.get_military_score();
1038 auto b_score = fb.get_military_score();
1039 if(a_score != b_score)
1040 return a_score > b_score;
1041 return a.index() > b.index();
1043 std::sort(state.nations_by_prestige_score.begin(), state.nations_by_prestige_score.begin() + to_sort_count,
1044 [&](dcon::nation_id a, dcon::nation_id b) {
1045 auto fa = fatten(state.world, a);
1046 auto fb = fatten(state.world, b);
1047 if(fa.get_is_civilized() && !fb.get_is_civilized())
1049 if(!fa.get_is_civilized() && fb.get_is_civilized())
1051 if(bool(fa.get_overlord_as_subject()) && !bool(fa.get_overlord_as_subject()))
1053 if(!bool(fa.get_overlord_as_subject()) && bool(fa.get_overlord_as_subject()))
1055 auto a_score = prestige_score(state, a);
1056 auto b_score = prestige_score(state, b);
1057 if(a_score != b_score)
1058 return a_score > b_score;
1059 return a.index() > b.index();
1061 for(
uint32_t i = 0; i < to_sort_count; ++i) {
1062 state.world.nation_set_industrial_rank(state.nations_by_industrial_score[i], uint16_t(i + 1));
1063 state.world.nation_set_military_rank(state.nations_by_military_score[i], uint16_t(i + 1));
1064 state.world.nation_set_prestige_rank(state.nations_by_prestige_score[i], uint16_t(i + 1));
1069 return state.world.nation_get_is_great_power(
id);
1073 bool at_least_one_added =
false;
1075 for(
auto i = state.great_nations.size(); i-- > 0;) {
1076 if(state.world.nation_get_rank(state.great_nations[i].nation) <= uint16_t(state.defines.great_nations_count)) {
1078 state.great_nations[i].last_greatness = state.current_date;
1079 }
else if(state.great_nations[i].last_greatness + int32_t(state.defines.greatness_days) < state.current_date ||
1080 state.world.nation_get_owned_province_count(state.great_nations[i].nation) == 0) {
1082 auto n = state.great_nations[i].nation;
1083 state.great_nations[i] = state.great_nations.back();
1084 state.great_nations.pop_back();
1085 at_least_one_added =
true;
1087 state.world.nation_set_is_great_power(n,
false);
1093 auto rels = state.world.nation_get_gp_relationship_as_great_power(n);
1094 while(rels.begin() != rels.end()) {
1095 auto rel = *(rels.begin());
1096 if(rel.get_influence_target().get_in_sphere_of() == n)
1097 rel.get_influence_target().set_in_sphere_of(dcon::nation_id{});
1098 state.world.delete_gp_relationship(rel);
1105 "msg_lost_gp_title",
1106 n, dcon::nation_id{}, dcon::nation_id{},
1112 for(
uint32_t i = 0; i <
uint32_t(state.defines.great_nations_count) && state.great_nations.size() < size_t(state.defines.great_nations_count); ++i) {
1113 auto n = state.nations_by_rank[i];
1114 if(n && !state.world.nation_get_is_great_power(n) && state.world.nation_get_owned_province_count(n) > 0) {
1115 at_least_one_added =
true;
1116 state.world.nation_set_is_great_power(n,
true);
1118 state.world.nation_set_state_from_flashpoint_focus(n, dcon::state_instance_id{});
1120 state.world.nation_set_in_sphere_of(n, dcon::nation_id{});
1121 auto rng = state.world.nation_get_gp_relationship_as_influence_target(n);
1122 while(
rng.begin() !=
rng.end()) {
1123 state.world.delete_gp_relationship(*(
rng.begin()));
1133 n, dcon::nation_id{}, dcon::nation_id{},
1138 if(at_least_one_added) {
1140 return state.world.nation_get_rank(a.nation) < state.world.nation_get_rank(b.nation);
1147 return status::great_power;
1148 }
else if(state.world.nation_get_rank(n) <= uint16_t(state.defines.colonial_rank)) {
1149 return status::secondary_power;
1150 }
else if(state.world.nation_get_is_civilized(n)) {
1151 return status::civilized;
1153 auto civ_progress = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::civilization_progress_modifier);
1154 if(civ_progress < 0.15f) {
1155 return status::primitive;
1156 }
else if(civ_progress < 0.5f) {
1157 return status::uncivilized;
1159 return status::westernizing;
1167 auto total = int32_t((
culture::effective_technology_cost(state, curr.to_ymd(state.start_date).year, n, tech_id) - state.world.nation_get_research_points(n)) / daily);
1168 return curr + total;
1172 return state.world.nation_get_current_research(n);
1176 return state.world.nation_get_suppression_points(n);
1180 return state.world.nation_get_leadership_points(n);
1188 float relevant_pop =
1189 state.world.nation_get_demographics(n,
demographics::to_key(state, state.world.nation_get_primary_culture(n)));
1190 for(
auto ac : state.world.in_culture) {
1191 if(state.world.nation_get_accepted_cultures(n, ac))
1195 return std::max(1, std::min(int32_t(relevant_pop / state.defines.national_focus_divider),
1196 int32_t(1 + state.world.nation_get_modifier_values(n, sys::national_mod_offsets::max_national_focus))));
1201 if(state.world.nation_get_state_from_flashpoint_focus(n))
1203 for(
auto si : state.world.nation_get_state_ownership(n)) {
1204 if(si.get_state().get_owner_focus())
1211 return state.world.nation_get_diplomatic_points(n);
1215 auto bmod = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::diplomatic_points_modifier) + 1.0f;
1216 auto dmod = bmod * state.defines.base_monthly_diplopoints;
1226 int32_t unit_sum = 0;
1227 for(
auto nv : state.world.nation_get_navy_control(n)) {
1228 for(
auto shp : nv.get_navy().get_navy_membership()) {
1229 unit_sum += state.military_definitions.unit_base_definitions[shp.get_ship().get_type()].colonial_points;
1234 float pts_factor = used_supply > base_supply ? std::max(0.0f, 2.0f - used_supply / base_supply) : 1.0f;
1235 points += unit_sum * pts_factor * state.defines.colonial_points_from_supply_factor;
1246 for(
auto p : state.world.nation_get_province_ownership(n)) {
1249 if(p.get_province().get_connected_region_id() == state.world.province_get_connected_region_id(state.world.nation_get_capital(n))
1250 || p.get_province().get_is_owner_core()) {
1251 if(p.get_province().get_is_owner_core()) {
1254 points += state.defines.colonial_points_for_non_core_base;
1262 for(
auto si : state.world.nation_get_state_ownership(n)) {
1263 auto scap = si.get_state().get_capital();
1264 if(scap.get_connected_region_id() != state.world.province_get_connected_region_id(state.world.nation_get_capital(n))) {
1275 state.world.for_each_technology([&](dcon::technology_id t) {
1276 if(state.world.nation_get_active_technologies(n, t))
1277 points +=
float(state.world.technology_get_colonial_points(t));
1287 for(
auto col : state.world.nation_get_colonization_as_colonizer(n)) {
1288 points += float(col.get_points_invested());
1294 for(
auto prov : state.world.nation_get_province_ownership(n)) {
1295 if(prov.get_province().get_is_colonial()) {
1296 points += state.defines.colonization_colony_province_maintainance;
1316 if(state.world.nation_get_rank(n) <= state.defines.colonial_rank) {
1317 float points = 0.0f;
1325 for(
auto cols : state.world.nation_get_colonization_as_colonizer(n)) {
1326 auto state_colonization = state.world.state_definition_get_colonization(cols.get_state());
1327 auto num_colonizers = state_colonization.end() - state_colonization.begin();
1328 if(cols.get_state().get_colonization_stage() ==
uint8_t(3)) {
1340 for(
auto cols : state.world.nation_get_colonization_as_colonizer(n)) {
1341 auto lvl = cols.get_level();
1342 for(
auto ocol : state.world.state_definition_get_colonization(cols.get_state())) {
1343 if(lvl < ocol.get_level())
1351 for(
auto it : state.world.nation_get_gp_relationship_as_great_power(n)) {
1352 if((it.get_status() & influence::is_banned) == 0) {
1353 if(it.get_influence() >= state.defines.increaseopinion_influence_cost
1354 && (influence::level_mask & it.get_status()) != influence::level_in_sphere
1355 && (influence::level_mask & it.get_status()) != influence::level_friendly) {
1357 }
else if(!(it.get_influence_target().get_in_sphere_of()) &&
1358 it.get_influence() >= state.defines.addtosphere_influence_cost) {
1360 }
else if(it.get_influence_target().get_in_sphere_of() &&
1361 (influence::level_mask & it.get_status()) == influence::level_friendly &&
1362 it.get_influence() >= state.defines.removefromsphere_influence_cost) {
1371 for(
auto i : state.culture_definitions.political_issues) {
1372 auto current = state.world.nation_get_issues(n, i);
1373 for(
auto o : state.world.issue_get_options(i)) {
1383 for(
auto i : state.culture_definitions.social_issues) {
1384 auto current = state.world.nation_get_issues(n, i);
1385 for(
auto o : state.world.issue_get_options(i)) {
1397 auto last_date = state.world.nation_get_last_issue_or_reform_change(n);
1398 if(
bool(last_date) && (last_date + int32_t(state.defines.min_delay_between_reforms * 30.0f)) > state.current_date)
1401 if(state.world.nation_get_is_civilized(n)) {
1422 auto stored_rp = state.world.nation_get_research_points(n);
1423 for(
auto i : state.culture_definitions.military_issues) {
1424 auto current = state.world.nation_get_reforms(n, i);
1425 for(
auto o : state.world.reform_get_options(i)) {
1431 for(
auto i : state.culture_definitions.economic_issues) {
1432 auto current = state.world.nation_get_reforms(n, i);
1433 for(
auto o : state.world.reform_get_options(i)) {
1443bool has_decision_available(
sys::state& state, dcon::nation_id n) {
1444 for(
uint32_t i = state.world.decision_size(); i-- > 0;) {
1445 dcon::decision_id did{dcon::decision_id::value_base_t(i)};
1446 if(!state.world.decision_get_hide_notification(did)) {
1447 auto lim = state.world.decision_get_potential(did);
1449 auto allow = state.world.decision_get_allow(did);
1459void get_active_political_parties(
sys::state& state, dcon::nation_id n, std::vector<dcon::political_party_id>& parties) {
1460 auto identity = state.world.nation_get_identity_from_identity_holder(n);
1461 auto start = state.world.national_identity_get_political_party_first(identity).id.index();
1462 auto end = start + state.world.national_identity_get_political_party_count(identity);
1463 for(int32_t i = start; i < end; i++) {
1464 auto pid = dcon::political_party_id(uint16_t(i));
1466 parties.push_back(pid);
1471void monthly_adjust_relationship(
sys::state& state, dcon::nation_id a, dcon::nation_id b,
float delta) {
1472 auto rel = state.world.get_diplomatic_relation_by_diplomatic_pair(a, b);
1474 rel = state.world.force_create_diplomatic_relation(a, b);
1476 auto&
val =
state.world.diplomatic_relation_get_value(rel);
1477 val = std::clamp(val + delta, -200.0f, std::max(val, 100.0f));
1486 for(
auto n : state.world.in_nation) {
1487 auto owned = n.get_province_ownership();
1488 if(owned.begin() != owned.end()) {
1489 auto pc = n.get_primary_culture();
1490 int32_t total_num_cores = 0;
1492 for(
auto core : n.get_identity_from_identity_holder().get_core()) {
1494 if(core.get_province().get_nation_from_province_ownership() != n) {
1495 if(core.get_province().get_dominant_culture() == pc)
1501 if(total_num_cores > 0) {
1502 n.set_revanchism(rpts /
float(total_num_cores));
1504 n.set_revanchism(0.0f);
1510void update_monthly_points(
sys::state& state) {
1527 state.world.execute_serial_over_nation([&](
auto ids) {
1528 auto imod = state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::badboy);
1529 state.world.nation_set_infamy(ids, ve::max(state.world.nation_get_infamy(ids) + imod, 0.0f));
1535 state.world.execute_serial_over_nation([&](
auto ids) {
1536 auto wmod =
state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::war_exhaustion);
1537 auto wmax_mod =
state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::max_war_exhaustion);
1538 state.world.nation_set_war_exhaustion(ids,
1539 ve::max(ve::min(
state.world.nation_get_war_exhaustion(ids) + wmod, wmax_mod), 0.0f));
1544 state.world.execute_serial_over_nation([&](
auto ids) {
1547 state.world.nation_set_plurality(ids, ve::max(ve::min(
state.world.nation_get_plurality(ids) + pmod, 100.0f), 0.f));
1553 state.world.execute_serial_over_nation([&](
auto ids) {
1554 auto bmod =
state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::diplomatic_points_modifier) + 1.0f;
1555 auto dmod = bmod *
state.defines.base_monthly_diplopoints;
1557 state.world.nation_set_diplomatic_points(ids, ve::max(ve::min(
state.world.nation_get_diplomatic_points(ids) + dmod, 9.0f), 0.f));
1564 state.world.execute_serial_over_nation([&](
auto ids) {
1565 auto bmod = (
state.world.nation_get_modifier_values(ids, sys::national_mod_offsets::suppression_points_modifier) + 1.0f);
1566 auto cmod = (bmod *
state.defines.suppression_points_gain_base) *
1569 state.defines.suppress_bureaucrat_factor);
1571 state.world.nation_set_suppression_points(ids, ve::max(ve::min(
state.world.nation_get_suppression_points(ids) + cmod,
state.defines.max_suppression), 0.f));
1578 for(
auto so :
state.world.in_overlord) {
1581 for(
auto an :
state.world.in_nation_adjacency) {
1582 if(an.get_connected_nations(0).get_is_at_war() ==
false && an.get_connected_nations(1).get_is_at_war() ==
false)
1591 for(
auto i :
state.world.in_unilateral_relationship) {
1592 if(i.get_military_access()) {
1596 for(
auto w :
state.world.in_war) {
1597 for(
auto n : w.get_war_participant()) {
1598 for(
auto m : w.get_war_participant()) {
1599 if(
n.get_is_attacker() !=
m.get_is_attacker()) {
1609float get_treasury(
sys::state& state, dcon::nation_id n) {
1613float get_bank_funds(
sys::state& state, dcon::nation_id n) {
1617float get_debt(
sys::state& state, dcon::nation_id n) {
1619 return v < 0.0f ? -v : 0.0f;
1622float tariff_efficiency(
sys::state& state, dcon::nation_id n) {
1623 auto eff_mod = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::tariff_efficiency_modifier);
1624 auto adm_eff = state.world.nation_get_administrative_efficiency(n);
1625 return std::clamp((state.defines.base_tariff_efficiency + eff_mod) * adm_eff * 10.f, 0.001f, 1.f);
1628float tax_efficiency(
sys::state& state, dcon::nation_id n) {
1629 auto eff_mod = state.world.nation_get_modifier_values(n, sys::national_mod_offsets::tax_efficiency);
1630 auto adm_eff = state.world.nation_get_administrative_efficiency(n);
1631 return std::clamp(state.defines.base_country_tax_efficiency + eff_mod * adm_eff, 0.01f, 1.f);
1634bool is_involved_in_crisis(
sys::state const& state, dcon::nation_id n) {
1635 if(n == state.primary_crisis_attacker)
1637 if(n == state.primary_crisis_defender)
1639 for(
auto& par : state.crisis_participants) {
1648bool is_committed_in_crisis(
sys::state const& state, dcon::nation_id n) {
1649 if(n == state.primary_crisis_attacker)
1651 if(n == state.primary_crisis_defender)
1653 for(
auto& par : state.crisis_participants) {
1657 return !par.merely_interested;
1662void adjust_relationship(
sys::state& state, dcon::nation_id a, dcon::nation_id b,
float delta) {
1663 if(state.world.nation_get_owned_province_count(a) == 0 || state.world.nation_get_owned_province_count(a) == 0)
1666 auto rel = state.world.get_diplomatic_relation_by_diplomatic_pair(a, b);
1668 rel = state.world.force_create_diplomatic_relation(a, b);
1670 auto&
val =
state.world.diplomatic_relation_get_value(rel);
1671 val = std::clamp(val + delta, -200.0f, 200.0f);
1674void create_nation_based_on_template(
sys::state& state, dcon::nation_id n, dcon::nation_id base) {
1675 state.world.nation_set_is_civilized(n, state.world.nation_get_is_civilized(base));
1676 state.world.nation_set_national_value(n, state.world.nation_get_national_value(base));
1677 state.world.nation_set_tech_school(n, state.world.nation_get_tech_school(base));
1678 state.world.nation_set_government_type(n, state.world.nation_get_government_type(base));
1679 state.world.nation_set_plurality(n, state.world.nation_get_plurality(base));
1680 state.world.nation_set_prestige(n, 0.0f);
1681 state.world.nation_set_infamy(n, 0.0f);
1682 state.world.nation_set_revanchism(n, 0.0f);
1683 state.world.for_each_technology([&](dcon::technology_id t) {
1684 state.world.nation_set_active_technologies(n, t, state.world.nation_get_active_technologies(base, t));
1686 state.world.for_each_invention([&](dcon::invention_id t) {
1687 state.world.nation_set_active_inventions(n, t,
state.world.nation_get_active_inventions(base, t));
1689 state.world.for_each_issue(
1690 [&](dcon::issue_id t) {
state.world.nation_set_issues(n, t,
state.world.nation_get_issues(base, t)); });
1691 if(!
state.world.nation_get_is_civilized(base)) {
1692 state.world.for_each_reform(
1693 [&](dcon::reform_id t) {
state.world.nation_set_reforms(n, t,
state.world.nation_get_reforms(base, t)); });
1695 state.world.nation_set_last_issue_or_reform_change(n,
sys::date{});
1697 state.world.for_each_ideology(
1698 [&](dcon::ideology_id i) {
state.world.nation_set_upper_house(n, i,
state.world.nation_get_upper_house(base, i)); });
1699 state.world.nation_set_is_substate(n,
false);
1706 state.world.for_each_commodity([&](dcon::commodity_id t) {
1707 state.world.nation_set_rgo_goods_output(n, t,
state.world.nation_get_rgo_goods_output(base, t));
1708 state.world.nation_set_factory_goods_output(n, t,
state.world.nation_get_factory_goods_output(base, t));
1709 state.world.nation_set_rgo_size(n, t,
state.world.nation_get_rgo_size(base, t));
1710 state.world.nation_set_factory_goods_throughput(n, t,
state.world.nation_get_factory_goods_throughput(base, t));
1712 state.world.for_each_rebel_type([&](dcon::rebel_type_id t) {
1713 state.world.nation_set_rebel_org_modifier(n, t,
state.world.nation_get_rebel_org_modifier(base, t));
1715 for(
uint32_t i = 0; i <
state.military_definitions.unit_base_definitions.size(); ++i) {
1716 state.world.nation_set_unit_stats(n, dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)},
1717 state.world.nation_get_unit_stats(base, dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)}));
1718 state.world.nation_set_active_unit(n, dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)},
1719 state.world.nation_get_active_unit(base, dcon::unit_type_id{dcon::unit_type_id::value_base_t(i)}));
1721 for(
uint32_t i = 0; i <
state.culture_definitions.crimes.size(); ++i) {
1722 state.world.nation_set_active_crime(n, dcon::crime_id{dcon::crime_id::value_base_t(i)},
1723 state.world.nation_get_active_crime(base, dcon::crime_id{dcon::crime_id::value_base_t(i)}));
1725 state.world.for_each_factory_type([&](dcon::factory_type_id t) {
1726 state.world.nation_set_active_building(n, t,
state.world.nation_get_active_building(base, t));
1728 state.world.for_each_commodity([&](dcon::commodity_id t) {
1729 state.world.nation_set_unlocked_commodities(n, t,
state.world.nation_get_unlocked_commodities(base, t));
1731 state.world.nation_set_has_gas_attack(n,
state.world.nation_get_has_gas_attack(base));
1732 state.world.nation_set_has_gas_defense(n,
state.world.nation_get_has_gas_defense(base));
1734 state.world.nation_set_max_building_level(n,
uint8_t(t),
state.world.nation_get_max_building_level(base,
uint8_t(t)));
1737 state.world.nation_set_education_spending(n, int8_t(100));
1738 state.world.nation_set_military_spending(n, int8_t(100));
1739 state.world.nation_set_administrative_spending(n, int8_t(100));
1740 state.world.nation_set_social_spending(n, int8_t(100));
1741 state.world.nation_set_land_spending(n, int8_t(100));
1742 state.world.nation_set_naval_spending(n, int8_t(100));
1743 state.world.nation_set_construction_spending(n, int8_t(100));
1744 state.world.nation_set_effective_land_spending(n, 1.0f);
1745 state.world.nation_set_effective_naval_spending(n, 1.0f);
1746 state.world.nation_set_effective_construction_spending(n, 1.0f);
1747 state.world.nation_set_spending_level(n, 1.0f);
1748 state.world.nation_set_poor_tax(n, int8_t(50));
1749 state.world.nation_set_middle_tax(n, int8_t(50));
1750 state.world.nation_set_rich_tax(n, int8_t(50));
1751 state.world.nation_set_tariffs_import(n, int8_t(5));
1752 state.world.nation_set_tariffs_export(n, int8_t(5));
1754 auto base_ruling_ideology =
state.world.political_party_get_ideology(
state.world.nation_get_ruling_party(base));
1756 auto identity =
state.world.nation_get_identity_from_identity_holder(n);
1757 auto start =
state.world.national_identity_get_political_party_first(identity).id.index();
1758 auto end = start +
state.world.national_identity_get_political_party_count(identity);
1760 for(int32_t i = start; i < end; i++) {
1761 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
1763 state.world.nation_set_ruling_party(n, pid);
1767 if(!
state.world.nation_get_ruling_party(n)) {
1768 for(int32_t i = start; i < end; i++) {
1769 auto pid = dcon::political_party_id(dcon::political_party_id::value_base_t(i));
1771 state.world.nation_set_ruling_party(n, pid);
1779 state.world.nation_set_primary_culture(n,
tag.get_primary_culture());
1780 state.world.nation_set_religion(n,
tag.get_religion());
1781 if(
auto cg =
tag.get_culture_group_from_cultural_union_of(); cg) {
1782 for(
auto c : cg.get_culture_group_membership()) {
1783 if(c.get_member().id !=
tag.get_primary_culture().id) {
1784 state.world.nation_set_accepted_cultures(n, c.get_member(),
true);
1794 for(
const auto n : state.world.in_nation) {
1795 if(n.get_marked_for_gc()) {
1796 n.set_marked_for_gc(
false);
1797 if(
auto lprovs = n.get_province_ownership(); lprovs.begin() == lprovs.end()) {
1802 if(
state.national_definitions.gc_pending) {
1803 state.national_definitions.gc_pending =
false;
1804 for(
uint32_t i =
state.world.rebel_faction_size(); i-- > 0; ) {
1805 dcon::rebel_faction_id rf{dcon::rebel_faction_id::value_base_t(i) };
1806 auto within =
state.world.rebel_faction_get_ruler_from_rebellion_within(rf);
1808 state.world.delete_rebel_faction(rf);
1813void cleanup_nation(
sys::state& state, dcon::nation_id n) {
1814 auto old_ident = state.world.nation_get_identity_from_identity_holder(n);
1816 auto control = state.world.nation_get_province_control(n);
1817 while(control.begin() != control.end()) {
1821 auto leaders =
state.world.nation_get_leader_loyalty(n);
1822 while(leaders.begin() != leaders.end()) {
1823 state.world.delete_leader((*leaders.begin()).get_leader());
1826 auto ss_range =
state.world.nation_get_overlord_as_ruler(n);
1827 while(ss_range.begin() != ss_range.end()) {
1828 auto subj = (*ss_range.begin()).get_subject();
1829 subj.set_is_substate(
false);
1833 auto ol =
state.world.nation_get_overlord_as_subject(n);
1834 if(
state.world.overlord_get_ruler(ol)) {
1853 auto diprel =
state.world.nation_get_diplomatic_relation(n);
1854 while(diprel.begin() != diprel.end()) {
1855 state.world.delete_diplomatic_relation(*diprel.begin());
1858 auto uni_diprel =
state.world.nation_get_unilateral_relationship_as_source(n);
1859 while(uni_diprel.begin() != uni_diprel.end()) {
1860 state.world.delete_unilateral_relationship(*uni_diprel.begin());
1863 auto uni_diprelb =
state.world.nation_get_unilateral_relationship_as_target(n);
1864 while(uni_diprelb.begin() != uni_diprelb.end()) {
1865 state.world.delete_unilateral_relationship(*uni_diprelb.begin());
1870 state.world.delete_movement((*
movements.begin()).get_movement());
1874 state.world.delete_nation(n);
1875 auto new_ident_holder =
state.world.create_nation();
1876 state.world.try_create_identity_holder(new_ident_holder, old_ident);
1878 for(
auto o :
state.world.in_nation) {
1879 if(o.get_in_sphere_of() == n) {
1884 "msg_rem_sphere_title",
1885 n, o, dcon::nation_id{},
1888 o.set_in_sphere_of(dcon::nation_id{});
1892 state.national_definitions.gc_pending =
true;
1893 state.diplomatic_cached_values_out_of_date =
true;
1896 if(n ==
state.local_player_nation) {
1902void adjust_prestige(
sys::state& state, dcon::nation_id n,
float delta) {
1903 float prestige_multiplier = 1.0f + state.world.nation_get_modifier_values(n, sys::national_mod_offsets::prestige);
1904 float v = state.world.nation_get_prestige(n) + (delta > 0 ? (delta * prestige_multiplier) : delta);
1905 float new_prestige = std::clamp(v, 0.f, max_prestige);
1906 state.world.nation_set_prestige(n, new_prestige);
1909bool destroy_vassal_relationships(
sys::state& state, dcon::nation_id n) {
1910 auto ov_rel = state.world.nation_get_overlord_as_ruler(n);
1911 for(
auto it = ov_rel.begin(); it != ov_rel.end(); ++it) {
1912 if((*it).get_subject().get_is_substate() ==
false) {
1913 release_vassal(state, *it);
1920void destroy_diplomatic_relationships(
sys::state& state, dcon::nation_id n) {
1922 auto gp_relationships = state.world.nation_get_gp_relationship_as_great_power(n);
1923 while(gp_relationships.begin() != gp_relationships.end()) {
1924 auto i = (*gp_relationships.begin()).get_influence_target();
1925 if(i.get_in_sphere_of() == n)
1926 i.set_in_sphere_of(dcon::nation_id{});
1927 state.world.delete_gp_relationship(*(gp_relationships.begin()));
1931 auto gp_relationships =
state.world.nation_get_gp_relationship_as_influence_target(n);
1932 while(gp_relationships.begin() != gp_relationships.end()) {
1933 state.world.delete_gp_relationship(*(gp_relationships.begin()));
1935 state.world.nation_set_in_sphere_of(n, dcon::nation_id{});
1938 for(
auto rel :
state.world.nation_get_diplomatic_relation(n)) {
1943 auto ov_rel =
state.world.nation_get_overlord_as_ruler(n);
1944 bool released_vassal =
true;
1945 while(released_vassal) {
1951 auto vas =
state.world.overlord_get_subject(
rel);
1952 auto ol =
state.world.overlord_get_ruler(
rel);
1954 if(
state.world.nation_get_is_substate(vas)) {
1955 state.world.nation_set_is_substate(vas,
false);
1956 state.world.nation_get_substates_count(ol)--;
1958 state.world.nation_get_vassals_count(ol)--;
1959 state.world.delete_overlord(rel);
1965void make_vassal(
sys::state& state, dcon::nation_id subject, dcon::nation_id overlord) {
1966 if(subject == overlord)
1968 if(state.world.nation_get_owned_province_count(subject) == 0 || state.world.nation_get_owned_province_count(overlord) == 0)
1971 auto current_ol = state.world.nation_get_overlord_as_subject(subject);
1972 auto current_ruler = state.world.overlord_get_ruler(current_ol);
1974 if(current_ruler && current_ruler != overlord) {
1975 release_vassal(state, current_ol);
1977 if(current_ruler == overlord) {
1978 if(
state.world.nation_get_is_substate(subject)) {
1979 state.world.nation_set_is_substate(subject,
false);
1980 state.world.nation_get_substates_count(current_ruler)--;
1983 state.world.force_create_overlord(subject, overlord);
1984 state.world.nation_get_vassals_count(overlord)++;
1991 if(
state.world.nation_get_owned_province_count(subject) == 0 ||
state.world.nation_get_owned_province_count(
overlord) == 0)
1994 auto current_ol =
state.world.nation_get_overlord_as_subject(subject);
1995 auto current_ruler =
state.world.overlord_get_ruler(current_ol);
1997 if(current_ruler && current_ruler !=
overlord) {
2000 if(current_ruler == overlord) {
2001 if(!
state.world.nation_get_is_substate(subject)) {
2002 state.world.nation_set_is_substate(subject,
true);
2003 state.world.nation_get_substates_count(current_ruler)++;
2006 state.world.force_create_overlord(subject, overlord);
2007 state.world.nation_set_is_substate(subject,
true);
2008 state.world.nation_get_vassals_count(overlord)++;
2009 state.world.nation_get_substates_count(current_ruler)++;
2014void break_alliance(
sys::state& state, dcon::diplomatic_relation_id rel) {
2015 if(state.world.diplomatic_relation_get_are_allied(rel)) {
2016 state.world.diplomatic_relation_set_are_allied(rel,
false);
2017 state.world.nation_get_allies_count(state.world.diplomatic_relation_get_related_nations(rel, 0))--;
2018 state.world.nation_get_allies_count(state.world.diplomatic_relation_get_related_nations(rel, 1))--;
2022void break_alliance(
sys::state& state, dcon::nation_id a, dcon::nation_id b) {
2023 if(
auto r = state.world.get_diplomatic_relation_by_diplomatic_pair(a, b); r) {
2024 if(state.world.diplomatic_relation_get_are_allied(r)) {
2025 break_alliance(state, r);
2026 if(a != state.local_player_nation) {
2031 "msg_alliance_ends_title",
2032 a, b, dcon::nation_id{},
2042 auto r =
state.world.get_diplomatic_relation_by_diplomatic_pair(a, b);
2044 r =
state.world.force_create_diplomatic_relation(a, b);
2046 if(!
state.world.diplomatic_relation_get_are_allied(r)) {
2047 state.world.nation_get_allies_count(a)++;
2048 state.world.nation_get_allies_count(b)++;
2049 state.world.diplomatic_relation_set_are_allied(r,
true);
2052 if(a !=
state.local_player_nation && b !=
state.local_player_nation) {
2057 "msg_alliance_starts_title",
2058 a, b, dcon::nation_id{},
2064bool other_nation_is_influencing(
sys::state& state, dcon::nation_id target, dcon::gp_relationship_id rel) {
2065 for(
auto orel : state.world.nation_get_gp_relationship_as_influence_target(target)) {
2066 if(orel != rel && orel.get_influence() > 0.0f)
2072bool can_accumulate_influence_with(
sys::state& state, dcon::nation_id gp, dcon::nation_id target, dcon::gp_relationship_id rel) {
2073 if((state.world.gp_relationship_get_status(rel) & influence::is_banned) != 0)
2079 if(state.world.gp_relationship_get_influence(rel) >= state.defines.max_influence
2080 && !other_nation_is_influencing(state, target, rel))
2085float get_base_shares(
sys::state& state, dcon::gp_relationship_id gp,
float total_gain, int32_t total_influence_shares) {
2086 if(total_influence_shares == 0)
2088 switch(state.world.gp_relationship_get_status(gp) & influence::priority_mask) {
2089 case influence::priority_one:
2090 return total_gain / float(total_influence_shares);
2091 case influence::priority_two:
2092 return 2.0f * total_gain / float(total_influence_shares);
2093 case influence::priority_three:
2094 return 3.0f * total_gain / float(total_influence_shares);
2096 case influence::priority_zero:
2101bool has_sphere_neighbour(
sys::state& state, dcon::nation_id n, dcon::nation_id target) {
2102 for(
auto g : state.world.nation_get_nation_adjacency(target)) {
2103 if(g.get_connected_nations(0) != target && g.get_connected_nations(0).get_in_sphere_of() == n)
2105 if(g.get_connected_nations(1) != target && g.get_connected_nations(1).get_in_sphere_of() == n)
2112 for(
auto rel : state.world.in_gp_relationship) {
2113 if(rel.get_penalty_expires_date() == state.current_date) {
2114 rel.set_status(rel.get_status() & ~(influence::is_banned | influence::is_discredited));
2118 for(
auto& grn :
state.great_nations) {
2119 dcon::nation_fat_id
n =
fatten(
state.world, grn.nation);
2123 int32_t total_influence_shares = 0;
2124 for(
auto rel :
n.get_gp_relationship_as_great_power()) {
2126 switch(
rel.get_status() & influence::priority_mask) {
2127 case influence::priority_one:
2128 total_influence_shares += 1;
2130 case influence::priority_two:
2131 total_influence_shares += 2;
2133 case influence::priority_three:
2134 total_influence_shares += 3;
2137 case influence::priority_zero:
2143 if(total_influence_shares > 0) {
2149 float total_gain =
state.defines.base_greatpower_daily_influence *
2150 (1.0f +
n.get_modifier_values(sys::national_mod_offsets::influence_modifier)) *
2151 (1.0f +
n.get_modifier_values(sys::national_mod_offsets::influence));
2166 float gp_score =
n.get_industrial_score() +
n.get_military_score() +
prestige_score(state, n);
2168 for(
auto rel :
n.get_gp_relationship_as_great_power()) {
2170 float base_shares =
get_base_shares(state, rel, total_gain, total_influence_shares);
2171 if(base_shares <= 0.0f)
2175 auto gp_invest =
state.world.unilateral_relationship_get_foreign_investment(
2176 state.world.get_unilateral_relationship_by_unilateral_pair(
rel.get_influence_target(), n));
2178 float discredit_factor =
2179 (
rel.get_status() & influence::is_discredited) != 0 ?
state.defines.discredit_influence_gain_factor : 0.0f;
2180 float neighbor_factor =
bool(
state.world.get_nation_adjacency_by_nation_adjacency_pair(n,
rel.get_influence_target()))
2181 ?
state.defines.neighbour_bonus_influence_percent
2184 ?
state.defines.sphere_neighbour_bonus_influence_percent
2186 float continent_factor =
n.get_capital().get_continent() !=
rel.get_influence_target().get_capital().get_continent()
2187 ?
state.defines.other_continent_bonus_influence_percent
2189 float puppet_factor =
rel.get_influence_target().get_overlord_as_subject().get_ruler() ==
n
2190 ?
state.defines.puppet_bonus_influence_percent
2192 float relationship_factor =
state.world.diplomatic_relation_get_value(
state.world.get_diplomatic_relation_by_diplomatic_pair(n,
rel.get_influence_target())) /
state.defines.relation_influence_modifier;
2194 float investment_factor = total_fi > 0.0f ?
state.defines.investment_influence_defense * gp_invest / total_fi : 0.0f;
2197 ?
state.defines.large_population_influence_penalty *
2199 state.defines.large_population_influence_penalty_chunk
2201 float score_factor = gp_score > 0.0f
2202 ? std::max(1.0f - (
rel.get_influence_target().get_industrial_score() +
rel.get_influence_target().get_military_score() +
prestige_score(state,
rel.get_influence_target())) / gp_score, 0.0f)
2205 float total_multiplier = 1.0f + discredit_factor + neighbor_factor + sphere_neighbor_factor + continent_factor + puppet_factor + relationship_factor + investment_factor + pop_factor + score_factor;
2207 auto gain_amount = base_shares * total_multiplier;
2214 rel.get_influence() += std::max(0.0f, gain_amount);
2215 if(
rel.get_influence() >
state.defines.max_influence) {
2216 auto overflow =
rel.get_influence() -
state.defines.max_influence;
2217 rel.get_influence() =
state.defines.max_influence;
2219 dcon::gp_relationship_id other_rel;
2220 for(
auto orel :
rel.get_influence_target().get_gp_relationship_as_influence_target()) {
2222 if(orel.get_influence() >
state.world.gp_relationship_get_influence(other_rel)) {
2229 auto& orl_i =
state.world.gp_relationship_get_influence(other_rel);
2230 orl_i = std::max(0.0f, orl_i - overflow);
2239bool can_put_flashpoint_focus_in_state(
sys::state& state, dcon::state_instance_id s, dcon::nation_id fp_nation) {
2240 auto fp_focus_nation = fatten(state.world, fp_nation);
2241 auto si = fatten(state.world, s);
2243 auto fp_ident = fp_focus_nation.get_identity_from_identity_holder();
2245 auto owner = si.get_nation_from_state_ownership();
2247 if(owner == fp_nation)
2252 if(fp_ident.get_is_not_releasable())
2255 if(fp_focus_nation.get_rank() > uint16_t(state.defines.colonial_rank)) {
2256 auto d = si.get_definition();
2257 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
2258 if(p.get_province().get_nation_from_province_ownership() == owner) {
2259 if(state.world.get_core_by_prov_tag_key(p.get_province(), fp_ident))
2268void monthly_flashpoint_update(
sys::state& state) {
2276 for(
auto si : state.world.in_state_instance) {
2277 auto owner = si.get_nation_from_state_ownership();
2278 auto owner_tag = owner.get_identity_from_identity_holder();
2280 auto owner_accepts_culture = [&](dcon::culture_id c) {
2284 if(
auto fp_focus_nation = si.get_nation_from_flashpoint_focus(); fp_focus_nation) {
2285 if(can_put_flashpoint_focus_in_state(state, si, fp_focus_nation)) {
2286 si.set_flashpoint_tag(fp_focus_nation.get_identity_from_identity_holder());
2290 si.set_nation_from_flashpoint_focus(dcon::nation_id{});
2294 dcon::national_identity_id qualifying_tag;
2296 auto d = si.get_definition();
2297 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
2298 if(p.get_province().get_nation_from_province_ownership() == owner) {
2299 for(
auto cores : p.get_province().get_core()) {
2300 if(!cores.get_identity().get_is_not_releasable()
2301 && !owner_accepts_culture(cores.get_identity().get_primary_culture())
2303 || si.get_demographics(
demographics::to_key(state, cores.get_identity().get_primary_culture())) >
2304 si.get_demographics(
demographics::to_key(state, state.world.national_identity_get_primary_culture(qualifying_tag))))) {
2306 qualifying_tag = cores.get_identity();
2312 si.set_flashpoint_tag(qualifying_tag);
2317 state.world.execute_serial_over_nation(
2318 [&](
auto ids) {
state.world.nation_set_has_flash_point_state(ids, ve::mask_vector(
false)); });
2319 for(
auto si :
state.world.in_state_instance) {
2320 if(si.get_flashpoint_tag()) {
2321 si.get_nation_from_state_ownership().set_has_flash_point_state(
true);
2326 state.world.execute_serial_over_nation(
2327 [&](
auto ids) {
state.world.nation_set_is_target_of_some_cb(ids, ve::mask_vector(
false)); });
2329 for(
auto target :
state.world.in_nation) {
2330 if(
target.get_has_flash_point_state()) {
2332 for(
auto actor :
state.world.in_nation) {
2333 auto owned =
actor.get_province_ownership();
2334 if(actor != target && owned.begin() != owned.end()) {
2336 target.set_is_target_of_some_cb(
true);
2345void daily_update_flashpoint_tension(
sys::state& state) {
2346 for(
auto si : state.world.in_state_instance) {
2347 if(si.get_flashpoint_tag()) {
2348 float total_increase = 0.0f;
2353 if(si.get_nation_from_state_ownership().get_is_target_of_some_cb()) {
2354 total_increase += state.defines.tension_from_cb;
2364 auto radicalism = state.world.movement_get_radicalism(mov);
2365 auto support = state.world.movement_get_pop_support(mov);
2367 auto pop_of_culture = si.get_demographics(
demographics::to_key(state, si.get_flashpoint_tag().get_primary_culture()));
2369 total_increase += std::min(state.defines.tension_from_movement_max,
2370 state.defines.tension_from_movement * radicalism * pop_of_culture * support / (state_pop * 4000.0f));
2377 if(si.get_nation_from_flashpoint_focus()) {
2378 total_increase += state.national_definitions.flashpoint_amount;
2384 total_increase += state.defines.tension_decay;
2390 total_increase += state.defines.tension_while_crisis;
2396 if(
auto rank = si.get_nation_from_state_ownership().get_rank();
2397 uint16_t(1) <= rank && rank <= uint16_t(int32_t(state.defines.great_nations_count))) {
2398 static float rank_amounts[8] = {state.defines.rank_1_tension_decay, state.defines.rank_2_tension_decay,
2399 state.defines.rank_3_tension_decay, state.defines.rank_4_tension_decay, state.defines.rank_5_tension_decay,
2400 state.defines.rank_6_tension_decay, state.defines.rank_7_tension_decay, state.defines.rank_8_tension_decay};
2402 total_increase += rank_amounts[rank - 1];
2409 for(
auto& gp : state.great_nations) {
2410 if(state.world.nation_get_is_at_war(gp.nation) ||
2411 (state.world.nation_get_disarmed_until(gp.nation) &&
2412 state.current_date <= state.world.nation_get_disarmed_until(gp.nation))) {
2413 auto continent = state.world.province_get_continent(state.world.nation_get_capital(gp.nation));
2414 if(si.get_capital().get_continent() == continent ||
2415 si.get_nation_from_state_ownership().get_capital().get_continent() == continent) {
2416 total_increase += state.defines.at_war_tension_decay;
2425 si.get_flashpoint_tension() = std::clamp(si.get_flashpoint_tension() + total_increase, 0.0f, 100.0f);
2427 si.set_flashpoint_tension(0.0f);
2434 for(
unsigned i = 0; i <
list.size(); i++) {
2443 for(
unsigned i = 0; i < state.crisis_attacker_wargoals.size(); i++) {
2444 if(state.crisis_attacker_wargoals[i].cb) {
2451 for(
unsigned i = 0; i <
state.crisis_defender_wargoals.size(); i++) {
2452 if(
state.crisis_defender_wargoals[i].cb) {
2461 state.crisis_state_instance = dcon::state_instance_id{};
2462 state.last_crisis_end_date =
state.current_date;
2464 state.crisis_last_checked_gp = 0;
2465 state.crisis_attacker = dcon::nation_id{};
2466 state.crisis_defender = dcon::nation_id{};
2468 for(
auto& par :
state.crisis_participants) {
2470 par.id = dcon::nation_id{};
2471 par.merely_interested =
false;
2472 par.supports_attacker =
false;
2478 state.crisis_temperature = 0.0f;
2479 state.crisis_war = dcon::war_id{};
2480 state.primary_crisis_attacker = dcon::nation_id{};
2481 state.primary_crisis_defender = dcon::nation_id{};
2484void add_as_primary_crisis_defender(
sys::state& state, dcon::nation_id n) {
2485 state.primary_crisis_defender = n;
2492 "msg_crisis_defender_title",
2493 n, dcon::nation_id{}, dcon::nation_id{},
2498void add_as_primary_crisis_attacker(
sys::state& state, dcon::nation_id n) {
2499 state.primary_crisis_attacker = n;
2506 "msg_crisis_attacker_title",
2507 n, dcon::nation_id{}, dcon::nation_id{},
2512void ask_to_defend_in_crisis(
sys::state& state, dcon::nation_id n) {
2513 if(state.world.nation_get_is_at_war(n)) {
2514 reject_crisis_participation(state);
2520 m.from =
state.crisis_defender;
2525void ask_to_attack_in_crisis(
sys::state& state, dcon::nation_id n) {
2526 if(state.world.nation_get_is_at_war(n)) {
2527 reject_crisis_participation(state);
2533 m.from =
state.crisis_attacker;
2538void reject_crisis_participation(
sys::state& state) {
2539 ++state.crisis_last_checked_gp;
2540 if(state.crisis_last_checked_gp < state.great_nations.size() &&
2541 (state.great_nations[state.crisis_last_checked_gp].nation == state.primary_crisis_attacker ||
2542 state.great_nations[state.crisis_last_checked_gp].nation == state.primary_crisis_defender)) {
2543 ++state.crisis_last_checked_gp;
2546 if(
state.crisis_last_checked_gp >=
state.great_nations.size()) {
2548 if(
state.crisis_attacker) {
2549 state.primary_crisis_attacker =
state.crisis_attacker;
2557 "msg_crisis_fizzle_title",
2558 state.local_player_nation,dcon::nation_id{}, dcon::nation_id{},
2568 if(
state.crisis_last_checked_gp >=
state.great_nations.size()) {
2572 if(
state.crisis_defender) {
2573 state.primary_crisis_defender =
state.crisis_defender;
2581 "msg_crisis_fizzle_title",
2582 state.local_player_nation, dcon::nation_id{}, dcon::nation_id{},
2586 auto first_wg =
state.crisis_attacker_wargoals.at(0);
2588 first_wg.target_nation, first_wg.secondary_nation, first_wg.state,
2599void cleanup_crisis_peace_offer(
sys::state& state, dcon::peace_offer_id peace) {
2600 auto wg = state.world.peace_offer_get_peace_offer_item(peace);
2601 while(wg.begin() != wg.end()) {
2602 state.world.delete_wargoal((*wg.begin()).get_wargoal());
2604 state.world.delete_peace_offer(peace);
2607void accept_crisis_peace_offer(
sys::state& state, dcon::nation_id from, dcon::nation_id to, dcon::peace_offer_id peace) {
2611 cleanup_crisis_peace_offer(state, peace);
2612 cleanup_crisis(state);
2616 state.current_crisis_state = new_state;
2619 if(!state.primary_crisis_attacker) {
2620 state.crisis_last_checked_gp = state.great_nations[0].nation != state.primary_crisis_defender ? 0 : 1;
2621 ask_to_attack_in_crisis(state, state.great_nations[state.crisis_last_checked_gp].nation);
2625 if(!
state.primary_crisis_defender) {
2626 state.crisis_last_checked_gp =
state.great_nations[0].nation !=
state.primary_crisis_attacker ? 0 : 1;
2631 state.crisis_last_checked_gp = 0;
2642 state.crisis_participants[0].id =
state.primary_crisis_attacker;
2643 state.crisis_participants[0].supports_attacker =
true;
2644 state.crisis_participants[0].merely_interested =
false;
2645 state.crisis_participants[1].id =
state.primary_crisis_defender;
2646 state.crisis_participants[1].supports_attacker =
false;
2647 state.crisis_participants[1].merely_interested =
false;
2649 auto first_wg =
state.crisis_attacker_wargoals.at(0);
2651 auto crisis_state_continent = [&]() {
2652 if(
auto p =
state.world.state_definition_get_abstract_state_membership(first_wg.state); p.begin() != p.end()) {
2653 return (*p.begin()).get_province().get_continent().id;
2655 return dcon::modifier_id{};
2658 auto crisis_defender_continent =
2659 state.world.province_get_continent(
state.world.nation_get_capital(
state.primary_crisis_defender));
2662 for(
auto& gp :
state.great_nations) {
2663 if(
gp.nation !=
state.primary_crisis_attacker &&
gp.nation !=
state.primary_crisis_defender &&
2664 !
state.world.nation_get_is_at_war(
gp.nation) &&
2665 state.world.nation_get_war_exhaustion(
gp.nation) <
state.defines.crisis_interest_war_exhaustion_limit) {
2666 auto cap_con =
state.world.province_get_continent(
state.world.nation_get_capital(
gp.nation));
2667 if(cap_con ==
state.province_definitions.europe || cap_con == crisis_state_continent ||
2668 cap_con == crisis_defender_continent ||
2669 (cap_con ==
state.province_definitions.north_america &&
2670 crisis_state_continent ==
state.province_definitions.south_america) ||
2671 (cap_con ==
state.province_definitions.north_america &&
2672 crisis_defender_continent ==
state.province_definitions.south_america) ||
2673 (cap_con ==
state.province_definitions.south_america &&
2674 crisis_state_continent ==
state.province_definitions.north_america) ||
2675 (cap_con ==
state.province_definitions.south_america &&
2676 crisis_defender_continent ==
state.province_definitions.north_america)) {
2693 dcon::nation_id secondary_attacker =
state.crisis_attacker;
2694 dcon::nation_id secondary_defender =
state.crisis_defender;
2696 for(
auto& i :
state.crisis_participants) {
2697 if(i.id && i.merely_interested ==
true &&
state.world.nation_get_is_player_controlled(i.id) ==
false) {
2698 if(
state.world.nation_get_ai_rival(i.id) ==
state.primary_crisis_attacker
2700 ||
state.world.nation_get_ai_rival(i.id) == secondary_attacker
2702 ||
state.world.nation_get_in_sphere_of(secondary_defender) == i.id) {
2704 i.merely_interested =
false;
2705 i.supports_attacker =
false;
2711 "msg_crisis_vol_join_title",
2712 i.id, dcon::nation_id{}, dcon::nation_id{},
2715 }
else if(
state.world.nation_get_ai_rival(i.id) ==
state.primary_crisis_defender
2717 ||
state.world.nation_get_ai_rival(i.id) == secondary_defender
2719 ||
state.world.nation_get_in_sphere_of(secondary_attacker) == i.id) {
2721 i.merely_interested =
false;
2722 i.supports_attacker =
true;
2728 "msg_crisis_vol_join_title",
2729 i.id, dcon::nation_id{}, dcon::nation_id{},
2745 if(state.great_nations.size() <= 2)
2766 state.last_crisis_end_date + 31 * int32_t(state.defines.crisis_cooldown_months) < state.current_date)) {
2776 std::vector<dcon::state_instance_id> most_likely_states;
2777 for(
auto si : state.world.in_state_instance) {
2778 auto owner_war = si.get_nation_from_state_ownership().get_is_at_war();
2779 auto ft = si.get_flashpoint_tag();
2780 auto ften = si.get_flashpoint_tension();
2781 auto ihold_at_war = si.get_flashpoint_tag().get_nation_from_identity_holder().get_is_at_war();
2783 if(si.get_nation_from_state_ownership().get_is_at_war() ==
false && si.get_flashpoint_tag() &&
2784 si.get_flashpoint_tension() > 50.0f &&
2785 si.get_flashpoint_tag().get_nation_from_identity_holder().get_is_at_war() ==
false) {
2786 most_likely_states.push_back(si);
2789 std::sort(most_likely_states.begin(), most_likely_states.end(), [&](dcon::state_instance_id a, dcon::state_instance_id b) {
2791 state.world.state_instance_get_flashpoint_tension(a) - state.world.state_instance_get_flashpoint_tension(b);
2792 if(tension_diff != 0.0f) {
2793 return tension_diff > 0.0f;
2795 return a.index() < b.index();
2798 for(
uint32_t i = 0; i < 3 && i < most_likely_states.size(); ++i) {
2800 state.world.state_instance_get_flashpoint_tension(most_likely_states[i]));
2802 if(rvalue < chance) {
2803 state.crisis_state_instance = most_likely_states[i];
2804 auto crisis_liberation_tag =
state.world.state_instance_get_flashpoint_tag(
state.crisis_state_instance);
2805 state.world.state_instance_set_flashpoint_tension(
state.crisis_state_instance, 0.0f);
2807 auto crisis_state_instance = most_likely_states[i];
2808 state.world.state_instance_set_flashpoint_tension(crisis_state_instance, 0.0f);
2809 auto owner =
state.world.state_instance_get_nation_from_state_ownership(crisis_state_instance);
2810 if (owner &&
state.world.nation_get_is_great_power(owner)) {
2819 crisis_liberation_tag,
2820 state.world.state_instance_get_definition(crisis_state_instance),
2821 state.military_definitions.crisis_liberate
2829 "msg_new_crisis_title",
2830 state.local_player_nation, dcon::nation_id{}, dcon::nation_id{},
2843 for(
auto sd :
state.world.in_state_definition) {
2844 if(sd.get_colonization_temperature() >= 100.0f) {
2845 auto colonizers = sd.get_colonization();
2846 auto num_colonizers = colonizers.end() - colonizers.begin();
2847 if(num_colonizers == 2) {
2848 auto attacking_colonizer = (*colonizers.begin()).get_colonizer();
2849 auto defending_colonizer = (*(colonizers.begin() + 1)).get_colonizer();
2851 sd.set_colonization_temperature(0.0f);
2854 attacking_colonizer,
2855 defending_colonizer,
2857 dcon::national_identity_id{},
2859 state.military_definitions.crisis_colony
2862 state.crisis_attacker = attacking_colonizer;
2863 if(attacking_colonizer.get_is_great_power()) {
2864 state.primary_crisis_attacker = attacking_colonizer;
2866 state.crisis_defender = defending_colonizer;
2867 if(defending_colonizer.get_is_great_power()) {
2868 state.primary_crisis_defender = defending_colonizer;
2876 "msg_new_crisis_title",
2877 state.local_player_nation, dcon::nation_id{}, dcon::nation_id{},
2887 state.last_crisis_end_date =
state.current_date;
2891 state.crisis_temperature = 0.0f;
2896 if(
state.primary_crisis_attacker) {
2902 if(
state.primary_crisis_defender) {
2915 int32_t participants = 0;
2916 for(
auto& par :
state.crisis_participants) {
2919 if(!par.merely_interested)
2927 state.crisis_temperature +=
state.defines.crisis_temperature_increase *
state.defines.crisis_temperature_participant_factor *
2928 float(participants) / float(total);
2930 if(
state.crisis_temperature >= 100) {
2933 assert(
state.crisis_attacker_wargoals.size() > 0);
2935 auto first_wg =
state.crisis_attacker_wargoals.at(0);
2937 state.crisis_defender,
2938 first_wg.cb, first_wg.state,
2939 first_wg.wg_tag, first_wg.secondary_nation);
2941 if(
state.crisis_attacker !=
state.primary_crisis_attacker) {
2943 state.world.war_set_primary_attacker(war,
state.primary_crisis_attacker);
2945 if(
state.crisis_defender !=
state.primary_crisis_defender) {
2947 state.world.war_set_primary_defender(war,
state.primary_crisis_defender);
2950 for(
auto& par :
state.crisis_participants) {
2952 if(!par.merely_interested && par.id !=
state.primary_crisis_attacker && par.id !=
state.primary_crisis_defender) {
2960 for(
auto wg :
state.crisis_attacker_wargoals) {
2964 if(wg.cb == first_wg.cb && wg.state == first_wg.state && wg.wg_tag == first_wg.wg_tag && wg.secondary_nation == first_wg.secondary_nation) {
2968 wg.state, wg.wg_tag, wg.secondary_nation);
2970 for(
auto wg :
state.crisis_defender_wargoals) {
2975 wg.state, wg.wg_tag, wg.secondary_nation);
2984 float p_factor =
state.defines.crisis_did_not_take_side_prestige_factor_base +
2985 state.defines.crisis_did_not_take_side_prestige_factor_year * float(
state.current_date.value) / float(365);
2987 for(
auto& par :
state.crisis_participants) {
2991 if(par.merely_interested) {
2998 state.world.war_set_is_crisis_war(war,
true);
3000 if(
state.military_definitions.great_wars_enabled) {
3001 int32_t gp_attackers = 0;
3002 int32_t gp_defenders = 0;
3004 for(
auto par :
state.world.war_get_war_participant(war)) {
3006 if(par.get_is_attacker())
3013 if(gp_attackers >= 2 && gp_defenders >= 2) {
3014 state.world.war_set_is_great(war,
true);
3015 state.world.war_set_name(war,
state.lookup_key(std::string_view{
"great_war_name" }));
3022 [pa =
state.world.war_get_primary_attacker(war), pd =
state.world.war_get_primary_defender(war), name =
state.world.war_get_name(war), tag =
state.world.war_get_over_tag(war), st =
state.world.war_get_over_state(war)](
sys::state& state,
text::layout_base& contents) {
3024 text::substitution_map sub;
3026 text::add_to_substitution_map(sub, text::variable_type::order, std::string_view(
""));
3027 text::add_to_substitution_map(sub, text::variable_type::second, text::get_adjective(state, pd));
3028 text::add_to_substitution_map(sub, text::variable_type::second_country, pd);
3029 text::add_to_substitution_map(sub, text::variable_type::first, text::get_adjective(state, pa));
3030 text::add_to_substitution_map(sub, text::variable_type::third, tag);
3031 text::add_to_substitution_map(sub, text::variable_type::state, st);
3032 text::add_to_substitution_map(sub, text::variable_type::country_adj, state.world.national_identity_get_adjective(tag));
3034 std::string resolved_war_name = text::resolve_string_substitution(state, name, sub);
3035 text::add_line(state, contents,
"msg_crisis_escalates_1", text::variable_type::x, std::string_view{resolved_war_name});
3037 "msg_crisis_escalates_title",
3038 state.local_player_nation, dcon::nation_id{}, dcon::nation_id{},
3045void update_pop_acceptance(
sys::state& state, dcon::nation_id n) {
3046 auto pc = state.world.nation_get_primary_culture(n);
3047 for(
auto pr : state.world.nation_get_province_ownership(n)) {
3048 for(
auto pop : pr.get_province().get_pop_location()) {
3050 if(pc == pop.get_pop().get_culture()) {
3051 pop.get_pop().set_is_primary_or_accepted_culture(
true);
3054 if(state.world.nation_get_accepted_cultures(n, pop.get_pop().get_culture()) ==
true) {
3055 pop.get_pop().set_is_primary_or_accepted_culture(
true);
3058 pop.get_pop().set_is_primary_or_accepted_culture(
false);
3064void liberate_nation_from(
sys::state& state, dcon::national_identity_id liberated, dcon::nation_id from) {
3067 auto holder = state.world.national_identity_get_nation_from_identity_holder(liberated);
3069 holder = state.world.create_nation();
3070 state.world.nation_set_identity_from_identity_holder(holder, liberated);
3072 auto lprovs =
state.world.nation_get_province_ownership(holder);
3073 if(lprovs.begin() == lprovs.end()) {
3076 for(
auto c :
state.world.national_identity_get_core(liberated)) {
3077 if(c.get_province().get_nation_from_province_ownership() == from) {
3083 if(
state.world.province_get_nation_from_province_ownership(
state.world.nation_get_capital(from)) != from) {
3088void release_nation_from(
sys::state& state, dcon::national_identity_id liberated, dcon::nation_id from) {
3091 auto holder = state.world.national_identity_get_nation_from_identity_holder(liberated);
3092 auto source_tag = state.world.nation_get_identity_from_identity_holder(from);
3094 holder = state.world.create_nation();
3095 state.world.nation_set_identity_from_identity_holder(holder, liberated);
3097 auto lprovs =
state.world.nation_get_province_ownership(holder);
3098 if(lprovs.begin() == lprovs.end()) {
3101 for(
auto c :
state.world.national_identity_get_core(liberated)) {
3102 if(c.get_province().get_nation_from_province_ownership() == from &&
3103 !(
state.world.get_core_by_prov_tag_key(c.get_province(), source_tag))) {
3107 if(
state.world.province_get_nation_from_province_ownership(
state.world.nation_get_capital(from)) != from) {
3112void remove_cores_from_owned(
sys::state& state, dcon::nation_id n, dcon::national_identity_id tag) {
3113 for(
auto prov : state.world.nation_get_province_ownership(n)) {
3114 if(
auto core = state.world.get_core_by_prov_tag_key(prov.get_province(), tag); core) {
3115 state.world.delete_core(core);
3120void perform_nationalization(
sys::state& state, dcon::nation_id n) {
3121 for(
auto rel : state.world.nation_get_unilateral_relationship_as_target(n)) {
3122 if(rel.get_foreign_investment() > 0.0f) {
3126 rel.set_foreign_investment(0.0f);
3131void adjust_influence(
sys::state& state, dcon::nation_id great_power, dcon::nation_id target,
float delta) {
3132 if(great_power == target)
3135 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, great_power);
3137 rel = state.world.force_create_gp_relationship(target, great_power);
3139 auto&
inf =
state.world.gp_relationship_get_influence(rel);
3140 inf = std::clamp(inf + delta, 0.0f,
state.defines.max_influence);
3143void adjust_influence_with_overflow(
sys::state& state, dcon::nation_id great_power, dcon::nation_id target,
float delta) {
3144 if(state.world.nation_get_owned_province_count(great_power) == 0 || state.world.nation_get_owned_province_count(target) == 0)
3146 if(great_power == target)
3148 if(state.world.nation_get_is_great_power(target) || !state.world.nation_get_is_great_power(great_power))
3151 auto rel = state.world.get_gp_relationship_by_gp_influence_pair(target, great_power);
3153 rel = state.world.force_create_gp_relationship(target, great_power);
3155 auto&
inf =
state.world.gp_relationship_get_influence(rel);
3159 if(
state.world.nation_get_in_sphere_of(target) == great_power) {
3160 inf +=
state.defines.addtosphere_influence_cost;
3161 state.world.nation_set_in_sphere_of(target, dcon::nation_id{});
3163 auto& l =
state.world.gp_relationship_get_status(rel);
3166 inf +=
state.defines.increaseopinion_influence_cost;
3168 auto& l =
state.world.gp_relationship_get_status(rel);
3173 while(inf >
state.defines.max_influence) {
3174 if(
state.world.nation_get_in_sphere_of(target) != great_power) {
3175 inf -=
state.defines.removefromsphere_influence_cost;
3176 auto affected_gp =
state.world.nation_get_in_sphere_of(target);
3177 state.world.nation_set_in_sphere_of(target, dcon::nation_id{});
3179 auto orel =
state.world.get_gp_relationship_by_gp_influence_pair(target, affected_gp);
3180 auto& l =
state.world.gp_relationship_get_status(orel);
3183 }
else if((
state.world.gp_relationship_get_status(rel) & influence::level_mask) == influence::level_friendly) {
3184 state.world.nation_set_in_sphere_of(target, great_power);
3185 inf -=
state.defines.addtosphere_influence_cost;
3186 auto& l =
state.world.gp_relationship_get_status(rel);
3189 inf -=
state.defines.increaseopinion_influence_cost;
3191 auto& l =
state.world.gp_relationship_get_status(rel);
3197void adjust_foreign_investment(
sys::state& state, dcon::nation_id great_power, dcon::nation_id target,
float delta) {
3198 auto rel = state.world.get_unilateral_relationship_by_unilateral_pair(target, great_power);
3200 rel = state.world.force_create_unilateral_relationship(target, great_power);
3202 auto& invest =
state.world.unilateral_relationship_get_foreign_investment(rel);
3203 invest = std::max(0.0f, invest + delta);
3206float get_yesterday_income(
sys::state& state, dcon::nation_id n) {
3220void make_civilized(
sys::state& state, dcon::nation_id n) {
3221 if(state.world.nation_get_is_civilized(n))
3230 int32_t military_reforms_active_count = 0;
3231 int32_t econ_reforms_active_count = 0;
3232 int32_t total_military_reforms_count = 0;
3233 int32_t total_econ_reforms_count = 0;
3235 for(
auto r : state.world.in_reform) {
3236 auto current_option = state.world.nation_get_reforms(n, r);
3237 auto& opts = state.world.reform_get_options(r);
3238 for(
uint32_t i = 0; i < opts.size(); ++i) {
3241 ++total_military_reforms_count;
3242 if(opts[i] == current_option)
3243 military_reforms_active_count += int32_t(i);
3245 ++total_econ_reforms_count;
3246 if(opts[i] == current_option)
3247 econ_reforms_active_count += int32_t(i);
3253 assert(total_military_reforms_count != 0);
3254 assert(total_econ_reforms_count != 0);
3256 float mil_tech_fraction = std::clamp(
float(military_reforms_active_count) /
float(total_military_reforms_count),
3257 state.defines.unciv_tech_spread_min,
state.defines.unciv_tech_spread_max);
3258 float econ_tech_fraction = std::clamp(
float(econ_reforms_active_count) /
float(total_econ_reforms_count),
3259 state.defines.unciv_tech_spread_min,
state.defines.unciv_tech_spread_max);
3261 dcon::nation_id model =
state.world.nation_get_in_sphere_of(n);
3263 model =
state.nations_by_rank[0];
3265 for(
uint32_t idx = 0; idx <
state.world.technology_size();) {
3267 auto this_group =
state.world.technology_get_folder_index(dcon::technology_id{dcon::technology_id::value_base_t(idx)});
3272 int32_t model_tech_count = 0;
3273 for(
uint32_t sidx = idx; sidx <
state.world.technology_size(); ++sidx) {
3274 auto sid = dcon::technology_id{dcon::technology_id::value_base_t(sidx)};
3275 if(
state.world.technology_get_folder_index(sid) != this_group)
3278 if(
state.world.nation_get_active_technologies(model, sid)) {
3286 float target_amount = float(model_tech_count) * (is_military ? mil_tech_fraction : econ_tech_fraction);
3287 int32_t
target_count = int32_t(std::ceil(target_amount));
3289 for(
uint32_t sidx = idx; sidx <
state.world.technology_size(); ++sidx) {
3290 auto sid = dcon::technology_id{dcon::technology_id::value_base_t(sidx)};
3292 if(
state.world.technology_get_folder_index(sid) != this_group)
3295 if(target_amount > 0) {
3296 if(!
state.world.nation_get_active_technologies(n, sid))
3305 for(; idx <
state.world.technology_size(); ++idx) {
3306 if(
state.world.technology_get_folder_index(dcon::technology_id{dcon::technology_id::value_base_t(idx)}) != this_group)
3311 state.world.nation_set_is_civilized(n,
true);
3312 for(
auto o :
state.culture_definitions.political_issues) {
3313 state.world.nation_set_issues(n, o,
state.world.issue_get_options(o)[0]);
3315 for(
auto o :
state.culture_definitions.social_issues) {
3316 state.world.nation_set_issues(n, o,
state.world.issue_get_options(o)[0]);
3318 for(
auto r :
state.world.in_reform) {
3319 state.world.nation_set_reforms(n, r, dcon::reform_option_id{});
3327void make_uncivilized(
sys::state& state, dcon::nation_id n) {
3328 if(!state.world.nation_get_is_civilized(n))
3331 state.world.nation_set_is_civilized(n,
false);
3333 for(
auto o : state.culture_definitions.military_issues) {
3334 state.world.nation_set_reforms(n, o, state.world.reform_get_options(o)[0]);
3336 for(
auto o :
state.culture_definitions.economic_issues) {
3337 state.world.nation_set_reforms(n, o,
state.world.reform_get_options(o)[0]);
3339 for(
auto o :
state.culture_definitions.political_issues) {
3340 state.world.nation_set_issues(n, o, dcon::issue_option_id{});
3342 for(
auto o :
state.culture_definitions.social_issues) {
3343 state.world.nation_set_issues(n, o, dcon::issue_option_id{});
3345 for(
auto r :
state.world.in_reform) {
3346 state.world.nation_set_reforms(n, r, dcon::reform_option_id{});
3352void enact_reform(
sys::state& state, dcon::nation_id source, dcon::reform_option_id r) {
3357 auto e = state.world.reform_option_get_on_execute_effect(r);
3359 auto t = state.world.reform_option_get_on_execute_trigger(r);
3368 float base_cost = float(
state.world.reform_option_get_technology_cost(r));
3371 state.world.nation_get_research_points(source) -= base_cost * reform_factor;
3373 float base_cost = float(
state.world.reform_option_get_technology_cost(r));
3376 state.world.nation_get_research_points(source) -= base_cost * reform_factor;
3385 for(
auto id :
state.world.in_ideology) {
3386 if(
id ==
state.culture_definitions.conservative) {
3387 state.world.nation_get_upper_house(source,
id) +=
state.defines.conservative_increase_after_reform * 100.0f;
3389 state.world.nation_get_upper_house(source,
id) /= (1.0f +
state.defines.conservative_increase_after_reform);
3391 state.world.nation_set_reforms(source,
state.world.reform_option_get_parent_reform(r), r);
3397void enact_issue(
sys::state& state, dcon::nation_id source, dcon::issue_option_id i) {
3399 auto e = state.world.issue_option_get_on_execute_effect(i);
3401 auto t = state.world.issue_option_get_on_execute_trigger(i);
3414 float winner_support =
winner ?
state.world.movement_get_pop_support(winner) : 1.0f;
3415 for(
auto m :
state.world.nation_get_movement_within(source)) {
3416 if(
m.get_movement().get_associated_issue_option() &&
m.get_movement().get_associated_issue_option() != i &&
3417 m.get_movement().get_pop_support() > winner_support) {
3419 m.get_movement().get_transient_radicalism() +=
3420 std::min(3.0f,
m.get_movement().get_pop_support() / winner_support - 1.0f) *
state.defines.wrong_reform_radical_impact;
3424 state.world.delete_movement(winner);
3432 auto issue =
state.world.issue_option_get_parent_issue(i);
3436 if(
state.world.issue_get_is_next_step_only(issue)) {
3437 for(
auto id :
state.world.in_ideology) {
3438 auto condition = is_social
3439 ? (i.index() >
current.index() ?
state.world.ideology_get_remove_social_reform(
id) :
state.world.ideology_get_add_social_reform(
id))
3440 : (i.index() >
current.index() ?
state.world.ideology_get_remove_political_reform(
id) :
state.world.ideology_get_add_political_reform(
id));
3446 for(
auto pr :
state.world.nation_get_province_ownership(source)) {
3447 for(
auto pop : pr.get_province().get_pop_location()) {
3465 for(
auto pr :
state.world.nation_get_province_ownership(source)) {
3466 for(
auto pop : pr.get_province().get_pop_location()) {
3471 if(
auto m =
pop.get_pop().get_movement_from_pop_movement_membership(); m &&
m.get_pop_support() > winner_support) {
3487 for(
auto id :
state.world.in_ideology) {
3488 if(
id ==
state.culture_definitions.conservative) {
3489 state.world.nation_get_upper_house(source,
id) +=
state.defines.conservative_increase_after_reform * 100.0f;
3491 state.world.nation_get_upper_house(source,
id) /= (1.0f +
state.defines.conservative_increase_after_reform);
3494 state.world.nation_set_issues(source, issue, i);
3499 state.world.nation_set_last_issue_or_reform_change(source,
state.current_date);
#define assert(condition)
float effective_technology_cost(sys::state &state, uint32_t current_year, dcon::nation_id target_nation, dcon::technology_id tech_id)
void apply_technology(sys::state &state, dcon::nation_id target_nation, dcon::technology_id t_id)
void update_nation_issue_rules(sys::state &state, dcon::nation_id n_id)
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
float get_estimated_colonial_migration(sys::state &state, dcon::pop_id ids)
constexpr dcon::demographics_key total(0)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
constexpr dcon::demographics_key consciousness(3)
float get_monthly_pop_increase(sys::state &state, dcon::pop_id ids)
float get_estimated_emigration(sys::state &state, dcon::pop_id ids)
@ be_crisis_primary_attacker
@ be_crisis_primary_defender
void post(sys::state &state, message const &m)
Pushes a diplomatic message to the list of pending diplomatic requests for the specified recipient (m...
float max_loan(sys::state &state, dcon::nation_id n)
constexpr dcon::commodity_id money(0)
float estimate_tax_income_by_strata(sys::state &state, dcon::nation_id n, culture::pop_strata ps)
float estimate_gold_income(sys::state &state, dcon::nation_id n)
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)
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)
void switch_scene(sys::state &state, scene_id ui_scene)
int32_t naval_supply_points_used(sys::state &state, dcon::nation_id n)
void add_to_war(sys::state &state, dcon::war_id w, dcon::nation_id n, bool as_attacker, bool on_war_creation)
bool can_use_cb_against(sys::state &state, dcon::nation_id from, dcon::nation_id target)
bool has_truce_with(sys::state &state, dcon::nation_id attacker, dcon::nation_id target)
uint32_t state_naval_base_level(sys::state const &state, dcon::state_instance_id si)
uint32_t state_railroad_level(sys::state const &state, dcon::state_instance_id si)
void add_wargoal(sys::state &state, dcon::war_id wfor, dcon::nation_id added_by, dcon::nation_id target, dcon::cb_type_id type, dcon::state_definition_id sd, dcon::national_identity_id tag, dcon::nation_id secondary_nation)
dcon::war_id create_war(sys::state &state, dcon::nation_id primary_attacker, dcon::nation_id primary_defender, dcon::cb_type_id primary_wargoal, dcon::state_definition_id primary_wargoal_state, dcon::national_identity_id primary_wargoal_tag, dcon::nation_id primary_wargoal_secondary)
bool are_at_war(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
void implement_peace_offer(sys::state &state, dcon::peace_offer_id offer)
void implement_war_goal(sys::state &state, dcon::war_id war, dcon::cb_type_id wargoal, dcon::nation_id from, dcon::nation_id target, dcon::nation_id secondary_nation, dcon::state_definition_id wargoal_state, dcon::national_identity_id wargoal_t)
int32_t naval_supply_points(sys::state &state, dcon::nation_id n)
uint8_t decrease_level(uint8_t v)
uint8_t increase_level(uint8_t v)
constexpr uint8_t level_mask
int32_t get_level(sys::state &state, dcon::nation_id gp, dcon::nation_id target)
float colonial_points_from_naval_bases(sys::state &state, dcon::nation_id n)
status get_status(sys::state &state, dcon::nation_id n)
bool is_great_power(sys::state const &state, dcon::nation_id id)
int32_t free_colonial_points(sys::state &state, dcon::nation_id n)
void break_alliance(sys::state &state, dcon::diplomatic_relation_id rel)
bool is_losing_colonial_race(sys::state &state, dcon::nation_id n)
bool can_release_as_vassal(sys::state const &state, dcon::nation_id n, dcon::national_identity_id releasable)
void adjust_prestige(sys::state &state, dcon::nation_id n, float delta)
bool has_political_reform_available(sys::state &state, dcon::nation_id n)
constexpr float max_prestige
void crisis_state_transition(sys::state &state, sys::crisis_state new_state)
void monthly_adjust_relationship(sys::state &state, dcon::nation_id a, dcon::nation_id b, float delta)
float get_foreign_investment(sys::state &state, dcon::nation_id n)
bool identity_has_holder(sys::state const &state, dcon::national_identity_id ident)
void update_administrative_efficiency(sys::state &state)
void release_vassal(sys::state &state, dcon::overlord_id rel)
bool are_allied(sys::state &state, dcon::nation_id a, dcon::nation_id b)
void ask_to_attack_in_crisis(sys::state &state, dcon::nation_id n)
bool destroy_vassal_relationships(sys::state &state, dcon::nation_id n)
void make_alliance(sys::state &state, dcon::nation_id a, dcon::nation_id b)
void crisis_add_wargoal(std::vector< sys::full_wg > &list, sys::full_wg wg)
float used_colonial_points(sys::state &state, dcon::nation_id n)
float get_base_shares(sys::state &state, dcon::gp_relationship_id gp, float total_gain, int32_t total_influence_shares)
bool has_sphere_neighbour(sys::state &state, dcon::nation_id n, dcon::nation_id target)
bool can_expand_colony(sys::state &state, dcon::nation_id n)
float diplomatic_points(sys::state const &state, dcon::nation_id n)
bool has_social_reform_available(sys::state &state, dcon::nation_id n)
void update_military_scores(sys::state &state)
float suppression_points(sys::state const &state, dcon::nation_id n)
void cleanup_nation(sys::state &state, dcon::nation_id n)
void ask_to_defend_in_crisis(sys::state &state, dcon::nation_id n)
dcon::nation_id get_nth_great_power(sys::state const &state, uint16_t n)
bool is_landlocked(sys::state &state, dcon::nation_id n)
float prestige_score(sys::state const &state, dcon::nation_id n)
float colonial_points_from_technology(sys::state &state, dcon::nation_id n)
void generate_initial_state_instances(sys::state &state)
void update_cached_values(sys::state &state)
void make_substate(sys::state &state, dcon::nation_id subject, dcon::nation_id overlord)
float leadership_points(sys::state const &state, dcon::nation_id n)
float monthly_diplomatic_points(sys::state const &state, dcon::nation_id n)
float daily_research_points(sys::state &state, dcon::nation_id n)
dcon::nation_id get_relationship_partner(sys::state const &state, dcon::diplomatic_relation_id rel_id, dcon::nation_id query)
void restore_cached_values(sys::state &state)
dcon::text_key name_from_tag(sys::state &state, dcon::national_identity_id tag)
void update_revanchism(sys::state &state)
float priority_national(sys::state &state, dcon::nation_id n, dcon::factory_type_id ftid)
int64_t get_monthly_pop_increase_of_nation(sys::state &state, dcon::nation_id n)
bool sphereing_progress_is_possible(sys::state &state, dcon::nation_id n)
sys::date get_research_end_date(sys::state &state, dcon::technology_id tech_id, dcon::nation_id n)
void create_nation_based_on_template(sys::state &state, dcon::nation_id n, dcon::nation_id base)
void update_industrial_scores(sys::state &state)
void update_research_points(sys::state &state)
void restore_state_instances(sys::state &state)
int32_t national_focuses_in_use(sys::state &state, dcon::nation_id n)
bool has_reform_available(sys::state &state, dcon::nation_id n)
float get_foreign_investment_as_gp(sys::state &state, dcon::nation_id n)
void generate_sea_trade_routes(sys::state &state)
std::vector< dcon::nation_id > nation_get_subjects(sys::state &state, dcon::nation_id n)
void update_great_powers(sys::state &state)
void cleanup_crisis(sys::state &state)
void recalculate_markets_distance(sys::state &state)
dcon::nation_id owner_of_pop(sys::state const &state, dcon::pop_id pop_ids)
dcon::technology_id current_research(sys::state const &state, dcon::nation_id n)
void generate_initial_trade_routes(sys::state &state)
bool can_accumulate_influence_with(sys::state &state, dcon::nation_id gp, dcon::nation_id target, dcon::gp_relationship_id rel)
int32_t max_national_focuses(sys::state &state, dcon::nation_id n)
void update_ui_rankings(sys::state &state)
void update_rankings(sys::state &state)
int32_t max_colonial_points(sys::state &state, dcon::nation_id n)
float colonial_points_from_ships(sys::state &state, dcon::nation_id n)
float priority_private(sys::state &state, dcon::nation_id n, dcon::factory_type_id ftid)
auto nation_accepts_culture(sys::state const &state, T ids, U cul_ids)
void post(sys::state &state, message &&m)
bool can_enact_social_reform(sys::state &state, dcon::nation_id n, dcon::issue_option_id o)
float get_military_reform_multiplier(sys::state &state, dcon::nation_id n)
bool can_enact_political_reform(sys::state &state, dcon::nation_id nation, dcon::issue_option_id issue_option)
float get_economic_reform_multiplier(sys::state &state, dcon::nation_id n)
bool political_party_is_active(sys::state &state, dcon::nation_id n, dcon::political_party_id p)
void update_displayed_identity(sys::state &state, dcon::nation_id id)
bool can_enact_military_reform(sys::state &state, dcon::nation_id n, dcon::reform_option_id o)
bool can_enact_economic_reform(sys::state &state, dcon::nation_id n, dcon::reform_option_id o)
void set_militancy(sys::state &state, dcon::pop_id p, float v)
void set_consciousness(sys::state &state, dcon::pop_id p, float v)
dcon::pop_demographics_key to_key(sys::state const &state, dcon::ideology_id v)
float get_consciousness(sys::state const &state, dcon::pop_id p)
float get_militancy(sys::state const &state, dcon::pop_id p)
float get_demo(sys::state const &state, dcon::pop_id p, dcon::pop_demographics_key k)
dcon::province_id state_get_coastal_capital(sys::state &state, dcon::state_instance_id s)
float direct_distance(sys::state &state, dcon::province_id a, dcon::province_id b)
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
float distance(sys::state &state, dcon::province_adjacency_id pair)
bool state_is_coastal(sys::state &state, dcon::state_instance_id s)
std::vector< dcon::province_id > make_naval_path(sys::state &state, dcon::province_id start, dcon::province_id end)
std::vector< dcon::province_id > make_unowned_path(sys::state &state, dcon::province_id start, dcon::province_id end)
bool can_invest_in_colony(sys::state &state, dcon::nation_id n, dcon::state_definition_id d)
void set_province_controller(sys::state &state, dcon::province_id p, dcon::nation_id n)
bool state_is_coastal_non_core_nb(sys::state &state, dcon::state_instance_id s)
void change_province_owner(sys::state &state, dcon::province_id id, dcon::nation_id new_owner)
dcon::province_id pick_capital(sys::state &state, dcon::nation_id n)
dcon::movement_id get_movement_by_independence(sys::state &state, dcon::nation_id n, dcon::national_identity_id i)
dcon::movement_id get_movement_by_position(sys::state &state, dcon::nation_id n, dcon::issue_option_id o)
uint64_t get_random(sys::state const &state, uint32_t value_in)
void update_single_nation_modifiers(sys::state &state, dcon::nation_id n)
void add_line(sys::state &state, layout_base &dest, dcon::text_key txt, int32_t indent)
dcon::text_key get_name(sys::state &state, dcon::nation_id id)
int32_t to_generic(dcon::province_id v)
bool evaluate(sys::state &state, dcon::trigger_key key, int32_t primary, int32_t this_slot, int32_t from_slot)
float evaluate_additive_modifier(sys::state &state, dcon::value_modifier_key modifier, int32_t primary, int32_t this_slot, int32_t from_slot)
T select(bool v, T a, T b)
int32_t to_int(int32_t a)
float to_float(int32_t a)
Holds data regarding a diplomatic message between two specified nations at a certain date,...
dcon::nation_id target_nation
Holds important data about the game world, state, and other data regarding windowing,...