3#include "dcon_generated.hpp"
16template auto is_overseas<ve::tagged_vector<dcon::province_id>>(
sys::state const&, ve::tagged_vector<dcon::province_id>);
20 auto owners = state.world.province_get_nation_from_province_ownership(ids);
21 auto owner_cap = state.world.nation_get_capital(owners);
22 return (state.world.province_get_continent(ids) != state.world.province_get_continent(owner_cap)) &&
23 (state.world.province_get_connected_region_id(ids) != state.world.province_get_connected_region_id(owner_cap));
27 auto it = state.world.get_nation_adjacency_by_nation_adjacency_pair(a, b);
31 if(!state.adjacency_data_out_of_date)
34 state.adjacency_data_out_of_date =
false;
35 state.world.nation_adjacency_resize(0);
38 state.world.for_each_province([&](dcon::province_id
id) { state.world.province_set_connected_region_id(
id, 0); });
40 static std::vector<dcon::province_id> to_fill_list;
41 uint16_t current_fill_id = 0;
42 state.province_definitions.connected_region_is_coastal.clear();
44 to_fill_list.reserve(state.world.province_size());
46 for(int32_t i = state.province_definitions.first_sea_province.index(); i-- > 0;) {
47 dcon::province_id
id{dcon::province_id::value_base_t(i)};
48 if(state.world.province_get_connected_region_id(
id) == 0) {
51 bool found_coast =
false;
53 to_fill_list.push_back(
id);
55 while(!to_fill_list.empty()) {
56 auto current_id = to_fill_list.back();
57 to_fill_list.pop_back();
59 found_coast = found_coast || state.world.province_get_is_coast(current_id);
61 state.world.province_set_connected_region_id(current_id, current_fill_id);
62 for(
auto rel : state.world.province_get_province_adjacency(current_id)) {
65 auto owner_a = rel.get_connected_provinces(0).get_nation_from_province_ownership();
66 auto owner_b = rel.get_connected_provinces(1).get_nation_from_province_ownership();
67 if(owner_a == owner_b) {
68 if(rel.get_connected_provinces(0).get_connected_region_id() == 0)
69 to_fill_list.push_back(rel.get_connected_provinces(0));
70 if(rel.get_connected_provinces(1).get_connected_region_id() == 0)
71 to_fill_list.push_back(rel.get_connected_provinces(1));
73 state.world.try_create_nation_adjacency(owner_a, owner_b);
79 state.province_definitions.connected_region_is_coastal.push_back(found_coast);
89 state.world.for_each_province([&](dcon::province_id
id) { state.world.province_set_connected_coast_id(
id, 0); });
91 static std::vector<dcon::province_id> to_fill_list;
92 uint16_t current_fill_id = 0;
93 to_fill_list.reserve(state.world.province_size());
95 for(int32_t i = state.province_definitions.first_sea_province.index(); i-- > 0;) {
96 dcon::province_id
id{ dcon::province_id::value_base_t(i) };
97 if(state.world.province_get_connected_coast_id(
id) == 0 && state.world.province_get_is_coast(
id)) {
100 to_fill_list.push_back(
id);
101 while(!to_fill_list.empty()) {
102 auto current_id = to_fill_list.back();
103 to_fill_list.pop_back();
105 state.world.province_set_connected_coast_id(current_id, current_fill_id);
106 for(
auto rel : state.world.province_get_province_adjacency(current_id)) {
114 auto owner_a = rel.get_connected_provinces(0).get_nation_from_province_ownership();
115 auto owner_b = rel.get_connected_provinces(1).get_nation_from_province_ownership();
117 auto coast_a = rel.get_connected_provinces(0).get_is_coast();
118 auto coast_b = rel.get_connected_provinces(1).get_is_coast();
120 if(owner_a == owner_b && coast_a == coast_b) {
121 if(rel.get_connected_provinces(0).get_connected_coast_id() == 0)
122 to_fill_list.push_back(rel.get_connected_provinces(0));
123 if(rel.get_connected_provinces(1).get_connected_coast_id() == 0)
124 to_fill_list.push_back(rel.get_connected_provinces(1));
130 to_fill_list.clear();
136 state.province_ownership_changed.store(
true, std::memory_order::release);
140 auto trad_cap = state.world.national_identity_get_capital(state.world.nation_get_identity_from_identity_holder(n));
141 if(state.world.province_get_nation_from_province_ownership(trad_cap) == n) {
144 dcon::province_id best_choice;
145 for(
auto prov : state.world.nation_get_province_ownership(n)) {
148 prov.get_province().get_is_owner_core() == state.world.province_get_is_owner_core(best_choice)) {
149 best_choice = prov.get_province().id;
150 }
else if(prov.get_province().get_is_owner_core() && !state.world.province_get_is_owner_core(best_choice)) {
151 best_choice = prov.get_province().id;
158 auto old_con = state.world.province_get_nation_from_province_control(p);
160 state.world.province_set_last_control_change(p, state.current_date);
161 auto rc = state.world.province_get_rebel_faction_from_province_rebel_control(p);
162 auto owner = state.world.province_get_nation_from_province_ownership(p);
164 state.world.nation_get_rebel_controlled_count(owner) -= uint16_t(1);
166 state.world.nation_get_central_rebel_controlled(owner) -= uint16_t(1);
170 if(old_con == owner) {
171 state.world.nation_get_occupied_count(owner) += uint16_t(1);
172 if(state.world.province_get_is_blockaded(p) && !
is_overseas(state, p)) {
173 state.world.nation_get_central_blockaded(owner) -= uint16_t(1);
175 }
else if(n == owner) {
176 state.world.nation_get_occupied_count(owner) -= uint16_t(1);
179 state.world.province_set_rebel_faction_from_province_rebel_control(p, dcon::rebel_faction_id{});
180 state.world.province_set_nation_from_province_control(p, n);
181 state.military_definitions.pending_blackflag_update =
true;
186 auto old_con = state.world.province_get_rebel_faction_from_province_rebel_control(p);
188 state.world.province_set_last_control_change(p, state.current_date);
189 auto owner = state.world.province_get_nation_from_province_ownership(p);
190 if(!old_con && owner) {
191 state.world.nation_get_rebel_controlled_count(owner) += uint16_t(1);
193 state.world.nation_get_central_rebel_controlled(owner) += uint16_t(1);
196 if(owner && state.world.province_get_nation_from_province_control(p) == owner) {
197 state.world.nation_get_occupied_count(owner) += uint16_t(1);
198 if(state.world.province_get_is_blockaded(p) && !
is_overseas(state, p)) {
199 state.world.nation_get_central_blockaded(owner) -= uint16_t(1);
202 state.world.province_set_rebel_faction_from_province_rebel_control(p, rf);
203 state.world.province_set_nation_from_province_control(p, dcon::nation_id{});
204 state.military_definitions.pending_blackflag_update =
true;
210 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_central_province_count(ids, ve::int_vector()); });
211 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_central_blockaded(ids, ve::int_vector()); });
212 state.world.execute_serial_over_nation(
213 [&](
auto ids) { state.world.nation_set_central_rebel_controlled(ids, ve::int_vector()); });
214 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_rebel_controlled_count(ids, ve::int_vector()); });
215 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_central_ports(ids, ve::int_vector()); });
216 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_central_crime_count(ids, ve::int_vector()); });
217 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_total_ports(ids, ve::int_vector()); });
218 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_occupied_count(ids, ve::int_vector()); });
219 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_owned_state_count(ids, ve::int_vector()); });
220 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_is_colonial_nation(ids, ve::mask_vector()); });
224 for(
auto n : state.world.in_nation) {
225 auto orange = n.get_province_ownership();
226 n.set_owned_province_count(uint16_t(orange.end() - orange.begin()));
229 for(int32_t i = 0; i < state.province_definitions.first_sea_province.index(); ++i) {
230 dcon::province_id pid{dcon::province_id::value_base_t(i)};
232 auto owner = state.world.province_get_nation_from_province_ownership(pid);
234 bool owner_core =
false;
235 for(
auto c : state.world.province_get_core(pid)) {
236 if(c.get_identity().get_nation_from_identity_holder() == owner) {
241 state.world.province_set_is_owner_core(pid, owner_core);
243 state.world.province_set_is_owner_core(pid,
false);
247 for(
auto n : state.world.in_nation) {
248 if(n.get_capital().get_nation_from_province_ownership() != n) {
253 for(int32_t i = 0; i < state.province_definitions.first_sea_province.index(); ++i) {
254 dcon::province_id pid{dcon::province_id::value_base_t(i)};
256 auto owner = state.world.province_get_nation_from_province_ownership(pid);
259 bool reb_controlled = bool(state.world.province_get_rebel_faction_from_province_rebel_control(pid));
262 state.world.nation_get_rebel_controlled_count(owner) += uint16_t(1);
264 if(state.world.province_get_is_coast(pid)) {
265 state.world.nation_get_total_ports(owner) += uint16_t(1);
267 if(
auto c = state.world.province_get_nation_from_province_control(pid);
bool(c) && c != owner) {
268 state.world.nation_get_occupied_count(owner) += uint16_t(1);
270 if(state.world.province_get_is_colonial(pid)) {
271 state.world.nation_set_is_colonial_nation(owner,
true);
274 state.world.nation_get_central_province_count(owner) += uint16_t(1);
277 state.world.nation_get_central_blockaded(owner) += uint16_t(1);
279 if(state.world.province_get_is_coast(pid)) {
280 state.world.nation_get_central_ports(owner) += uint16_t(1);
283 state.world.nation_get_central_rebel_controlled(owner) += uint16_t(1);
285 if(state.world.province_get_crime(pid)) {
286 state.world.nation_get_central_crime_count(owner) += uint16_t(1);
291 state.world.for_each_state_instance([&](dcon::state_instance_id s) {
292 auto owner = state.world.state_instance_get_nation_from_state_ownership(s);
293 state.world.nation_get_owned_state_count(owner) += uint16_t(1);
295 for(
auto prv : state.world.state_definition_get_abstract_state_membership(state.world.state_instance_get_definition(s))) {
296 if(state.world.province_get_nation_from_province_ownership(prv.get_province()) == owner) {
297 p = prv.get_province().id;
301 state.world.state_instance_set_capital(s, p);
306 if(!state.national_cached_values_out_of_date)
309 state.national_cached_values_out_of_date =
false;
311 restore_cached_values(state);
315 state.world.execute_serial_over_nation([&](
auto ids) { state.world.nation_set_central_blockaded(ids, ve::int_vector()); });
316 for(int32_t i = 0; i < state.province_definitions.first_sea_province.index(); ++i) {
317 dcon::province_id pid{ dcon::province_id::value_base_t(i) };
319 auto owner = state.world.province_get_nation_from_province_ownership(pid);
323 state.world.nation_get_central_blockaded(owner) += uint16_t(1);
331 for(int32_t i = 0; i < state.province_definitions.first_sea_province.index(); ++i) {
332 dcon::province_id pid{dcon::province_id::value_base_t(i)};
334 for(
auto adj : state.world.province_get_province_adjacency(pid)) {
337 state.world.province_set_is_coast(pid,
true);
343 for(
auto si : state.world.in_state_instance) {
346 state.world.state_instance_set_naval_base_is_taken(si,
true);
348 for(
auto pc : state.world.province_get_province_building_construction(p)) {
349 if(pc.get_type() == uint8_t(economy::province_building_type::naval_base))
350 state.world.state_instance_set_naval_base_is_taken(si, true);
356 restore_cached_values(state);
360 for(
auto pb : state.world.province_get_province_building_construction(
id)) {
368 if(n != state.world.province_get_nation_from_province_control(
id))
375 int32_t min_build_railroad =
376 int32_t(state.world.province_get_modifier_values(
id, sys::provincial_mod_offsets::min_build_railroad));
381 auto owner = state.world.province_get_nation_from_province_ownership(
id);
383 if(owner != state.world.province_get_nation_from_province_control(
id))
389 if(state.world.nation_get_is_great_power(n) ==
false || state.world.nation_get_is_great_power(owner) ==
true)
391 if(state.world.nation_get_is_civilized(owner) ==
false)
394 auto rules = state.world.nation_get_combined_issue_rules(owner);
401 auto rules = state.world.nation_get_combined_issue_rules(n);
408 int32_t min_build_railroad =
409 int32_t(state.world.province_get_modifier_values(
id, sys::provincial_mod_offsets::min_build_railroad));
414 for(
auto pb : state.world.province_get_province_building_construction(
id)) {
421 if(state.world.province_get_nation_from_province_ownership(
id) != n)
423 if(state.world.province_get_nation_from_province_ownership(
id) != state.world.province_get_nation_from_province_control(
id))
430 int32_t min_build = int32_t(state.world.province_get_modifier_values(
id, sys::provincial_mod_offsets::min_build_fort));
435 for(
auto pb : state.world.province_get_province_building_construction(
id)) {
442 if(state.world.province_get_nation_from_province_ownership(
id) != n)
444 if(state.world.province_get_is_coast(
id) ==
false)
446 if(state.world.province_get_nation_from_province_ownership(
id) != state.world.province_get_nation_from_province_control(
id))
451 auto si = state.world.province_get_state_membership(
id);
455 int32_t min_build = int32_t(state.world.province_get_modifier_values(
id, sys::provincial_mod_offsets::min_build_naval_base));
457 return (max_local_lvl - current_lvl - min_build > 0) && (current_lvl > 0 || !si.get_naval_base_is_taken()) && !
has_naval_base_being_built(state,
id);
461 for(
auto pb : state.world.province_get_province_building_construction(
id)) {
469 auto owner = state.world.province_get_nation_from_province_ownership(
id);
471 if(owner != state.world.province_get_nation_from_province_control(
id))
477 if(state.world.nation_get_is_great_power(n) ==
false || state.world.nation_get_is_great_power(owner) ==
true)
479 if(state.world.nation_get_is_civilized(owner) ==
false)
482 auto rules = state.world.nation_get_combined_issue_rules(owner);
489 auto rules = state.world.nation_get_combined_issue_rules(n);
496 int32_t current_lvl = state.world.province_get_building_level(
id,
uint8_t(t));
497 int32_t max_local_lvl = state.world.nation_get_max_building_level(n,
uint8_t(t));
498 int32_t min_build = int32_t(state.world.province_get_modifier_values(
id, sys::provincial_mod_offsets::min_build_railroad));
503 return bool(
dcon::fatten(state.world,
id).get_nation_from_province_ownership());
506 auto owner = state.world.province_get_nation_from_province_ownership(
id);
510 auto owner = state.world.province_get_nation_from_province_ownership(
id);
514 auto owner = state.world.province_get_nation_from_province_ownership(
id);
517float rgo_employment(
sys::state& state, dcon::province_id
id) {
521 return state.world.province_get_rgo_full_profit(
id);
524 auto n = state.world.province_get_nation_from_province_ownership(
id);
525 return state.world.province_get_rgo_actual_production_per_good(
id, c);
528 bool is_mine = state.world.commodity_get_is_mine(state.world.province_get_rgo(prov_id));
529 auto sz = state.world.province_get_rgo_size(prov_id);
531 auto n =
dcon::fatten(state.world, prov_id).get_nation_from_province_ownership();
532 auto bonus = state.world.province_get_modifier_values(prov_id,
533 is_mine ? sys::provincial_mod_offsets::mine_rgo_size : sys::provincial_mod_offsets::farm_rgo_size) +
534 state.world.nation_get_modifier_values(n,
535 is_mine ? sys::national_mod_offsets::mine_rgo_size : sys::national_mod_offsets::farm_rgo_size) +
536 state.world.nation_get_rgo_size(n, state.world.province_get_rgo(prov_id)) + 1.0f;
543 for(
auto po : state.world.province_get_pop_location(p)) {
544 if(po.get_pop().get_is_primary_or_accepted_culture() &&
545 po.get_pop().get_poptype() == state.culture_definitions.bureaucrat) {
546 bsum += po.get_pop().get_size();
554 auto owner = state.world.state_instance_get_nation_from_state_ownership(
id);
556 auto admin_mod = state.world.nation_get_modifier_values(owner, sys::national_mod_offsets::administrative_efficiency_modifier);
558 float issue_sum = 0.0f;
559 for(
auto i : state.culture_definitions.social_issues) {
560 issue_sum += state.world.issue_option_get_administrative_multiplier(state.world.nation_get_issues(owner, i));
562 auto from_issues = issue_sum * state.defines.bureaucracy_percentage_increment + state.defines.max_bureaucracy_percentage;
563 float non_core_effect = 0.0f;
566 if(!state.world.province_get_is_owner_core(p)) {
567 non_core_effect += state.defines.noncore_tax_penalty;
569 for(
auto po : state.world.province_get_pop_location(p)) {
570 if(po.get_pop().get_is_primary_or_accepted_culture() &&
571 po.get_pop().get_poptype() == state.culture_definitions.bureaucrat) {
572 bsum += po.get_pop().get_size();
579 ? std::clamp(admin_mod + non_core_effect + state.defines.base_country_admin_efficiency +
580 std::min(state.culture_definitions.bureaucrat_tax_efficiency * bsum / total_pop, 1.0f) / from_issues,
600 auto si = state.world.province_get_state_membership(
id);
601 auto owner = state.world.province_get_nation_from_province_ownership(
id);
604 (1 - state.defines.admin_efficiency_crimefight_percent) *
605 state.world.nation_get_administrative_efficiency(owner)) *
606 (state.defines.max_crimefight_percent - state.defines.min_crimefight_percent) +
607 state.defines.min_crimefight_percent;
618 return militancy / total_pop;
622 auto first = state.world.province_adjacency_get_connected_provinces(adj, 0);
624 return state.world.province_adjacency_get_connected_provinces(adj, 1);
636 return direct_distance(state, state.world.state_instance_get_capital(state_id), prov_id);
640 return sorting_distance(state, state.world.state_instance_get_capital(state_id), prov_id);
644 if(state.world.state_instance_get_capital(
id).get_is_colonial() ==
false)
650 if(bureaucrat_size / total_size >= state.defines.state_creation_admin_limit) {
651 auto owner = state.world.state_instance_get_nation_from_state_ownership(
id);
664 bool entirely_overseas =
true;
665 float prov_count = 0.0f;
670 if(entirely_overseas) {
671 auto owner = state.world.state_instance_get_nation_from_state_ownership(
id);
673 return state.defines.colonization_create_state_cost * prov_count * std::max(
distance / state.defines.colonization_colony_state_distance, 1.0f);
682 state.world.province_set_is_colonial(p,
false);
685 auto timed_modifiers = state.world.province_get_current_modifiers(p);
686 for(
uint32_t i = timed_modifiers.size(); i-- > 0;) {
687 if(bool(timed_modifiers[i].expiration)) {
688 timed_modifiers.remove_at(i);
695 state.defines.colony_to_state_prestige_gain *
696 (1.0f + state.world.nation_get_modifier_values(source, sys::national_mod_offsets::colonial_prestige)));
707 state.world.nation_set_is_colonial_nation(source,
false);
708 for(
auto p : state.world.nation_get_province_ownership(source)) {
709 if(p.get_province().get_is_colonial()) {
710 state.world.nation_set_is_colonial_nation(source,
true);
717 auto state_def = state.world.province_get_state_from_abstract_state_membership(
id);
718 auto old_si = state.world.province_get_state_membership(
id);
719 auto old_market = state.world.state_instance_get_market_from_local_market(old_si);
720 auto old_owner = state.world.province_get_nation_from_province_ownership(
id);
722 if(new_owner == old_owner)
725 state.adjacency_data_out_of_date =
true;
726 state.national_cached_values_out_of_date =
true;
728 bool state_is_new =
false;
729 dcon::state_instance_id new_si;
731 auto pmods = state.world.province_get_current_modifiers(
id);
734 bool will_be_colonial = state.world.province_get_is_colonial(
id)
735 || (old_owner && state.world.nation_get_is_civilized(old_owner) ==
false
736 && state.world.nation_get_is_civilized(new_owner) ==
true)
740 state.world.state_instance_set_naval_base_is_taken(old_si,
false);
742 for(
auto pc : state.world.province_get_province_building_construction(
id)) {
744 state.world.state_instance_set_naval_base_is_taken(old_si,
false);
751 for(
auto si : state.world.nation_get_state_ownership(new_owner)) {
752 if(si.get_state().get_definition().id == state_def) {
753 new_si = si.get_state().id;
757 bool was_slave_state = !old_owner || state.world.province_get_is_slave(
id);
759 new_si = state.world.create_state_instance();
760 state.world.state_instance_set_definition(new_si, state_def);
761 state.world.try_create_state_ownership(new_si, new_owner);
762 state.world.state_instance_set_capital(new_si,
id);
763 state.world.province_set_is_colonial(
id, will_be_colonial);
764 state.world.province_set_is_slave(
id,
false);
766 state.world.nation_set_is_colonial_nation(new_owner,
true);
768 state.world.state_instance_set_naval_base_is_taken(new_si,
true);
770 auto new_market = state.world.create_market();
774 state.world.for_each_commodity([&](
auto cid){
775 state.world.market_set_price(new_market, cid, state.world.market_get_price(old_market, cid));
778 auto new_local_market = state.world.force_create_local_market(new_market, new_si);
782 std::set<dcon::state_instance_id::value_base_t> trade_route_candidates{};
785 for(
auto adj : state.world.province_get_province_adjacency(
id)) {
788 adj.get_connected_provinces(0) !=
id
789 ? adj.get_connected_provinces(0)
790 : adj.get_connected_provinces(1);
792 if(!other.get_state_membership())
794 if(other.get_state_membership() == new_si)
796 if(trade_route_candidates.contains(other.get_state_membership().id.value))
799 trade_route_candidates.insert(other.get_state_membership().id.value);
803 for(
auto candidate_trade_partner_val : trade_route_candidates) {
804 auto si = dcon::state_instance_id{ uint16_t(candidate_trade_partner_val - 1) };
805 auto target_market = state.world.state_instance_get_market_from_local_market(si);
806 auto new_route = state.world.force_create_trade_route(new_market, target_market);
807 state.world.trade_route_set_land_distance(new_route, 99999.f);
808 state.world.trade_route_set_sea_distance(new_route, 99999.f);
810 state.world.trade_route_set_is_sea_route(new_route,
true);
812 state.world.trade_route_set_is_land_route(new_route,
true);
817 auto sc = state.world.state_instance_get_capital(new_si);
818 state.world.province_set_is_colonial(
id, state.world.province_get_is_colonial(sc));
819 state.world.province_set_is_slave(
id, state.world.province_get_is_slave(sc));
821 if(state.world.state_instance_get_naval_base_is_taken(new_si)) {
824 state.world.state_instance_set_naval_base_is_taken(new_si,
true);
832 auto market = state.world.state_instance_get_market_from_local_market(new_si);
833 std::set<dcon::state_instance_id::value_base_t> old_trade_routes;
834 for(
auto item : state.world.market_get_trade_route(market)) {
836 item.get_connected_markets(0) != market
837 ? item.get_connected_markets(0)
838 : item.get_connected_markets(1);
840 old_trade_routes.insert(other.get_zone_from_local_market().id.value);
843 std::set<dcon::state_instance_id::value_base_t> trade_route_candidates{};
846 for(
auto adj : state.world.province_get_province_adjacency(
id)) {
849 adj.get_connected_provinces(0) !=
id
850 ? adj.get_connected_provinces(0)
851 : adj.get_connected_provinces(1);
853 if(!other.get_state_membership())
855 if(other.get_state_membership() == new_si)
857 if(old_trade_routes.contains(other.get_state_membership().id.value))
859 if(trade_route_candidates.contains(other.get_state_membership().id.value))
862 trade_route_candidates.insert(other.get_state_membership().id.value);
866 for(
auto candidate_trade_partner_val : trade_route_candidates) {
867 auto si = dcon::state_instance_id{ uint16_t(candidate_trade_partner_val - 1) };
868 auto target_market = state.world.state_instance_get_market_from_local_market(si);
869 auto new_route = state.world.force_create_trade_route(market, target_market);
870 state.world.trade_route_set_land_distance(new_route, 99999.f);
871 state.world.trade_route_set_sea_distance(new_route, 99999.f);
873 state.world.trade_route_set_is_sea_route(new_route,
true);
875 state.world.trade_route_set_is_land_route(new_route,
true);
878 if(was_slave_state) {
882 auto province_fac_range = state.world.province_get_factory_location(
id);
883 int32_t factories_in_province = int32_t(province_fac_range.end() - province_fac_range.begin());
885 int32_t factories_in_new_state = 0;
887 auto fac_range = state.world.province_get_factory_location(pr);
889 for(
const auto pfac : province_fac_range) {
890 for(int32_t i = 0; i < int32_t(fac_range.end() - fac_range.begin()); i++) {
891 const auto fac = *(fac_range.begin() + i);
892 if(fac.get_factory().get_building_type() == pfac.get_factory().get_building_type()) {
896 pfac.get_factory().get_level() =
uint8_t(new_level);
897 state.world.delete_factory(fac.get_factory().id);
902 factories_in_new_state += int32_t(fac_range.end() - fac_range.begin());
905 auto excess_factories = std::min((factories_in_new_state + factories_in_province) - int32_t(state.defines.factories_per_state), factories_in_province);
906 while(excess_factories > 0) {
907 state.world.delete_factory((*(province_fac_range.begin() + excess_factories - 1)).get_factory().id);
911 state.world.province_set_state_membership(
id, new_si);
913 for(
auto p : state.world.province_get_pop_location(
id)) {
915 if(state.world.nation_get_primary_culture(new_owner) == p.get_pop().get_culture()) {
916 p.get_pop().set_is_primary_or_accepted_culture(
true);
919 if(state.world.nation_get_accepted_cultures(new_owner, p.get_pop().get_culture())) {
920 p.get_pop().set_is_primary_or_accepted_culture(
true);
923 p.get_pop().set_is_primary_or_accepted_culture(
false);
926 state.world.nation_get_owned_province_count(new_owner) += uint16_t(1);
928 state.world.province_set_state_membership(
id, dcon::state_instance_id{});
930 state.world.province_set_building_level(
id,
uint8_t(t),
uint8_t(0));
933 auto province_fac_range = state.world.province_get_factory_location(
id);
934 while(province_fac_range.begin() != province_fac_range.end()) {
935 state.world.delete_factory((*province_fac_range.begin()).get_factory().id);
938 for(
auto p : state.world.province_get_pop_location(
id)) {
939 p.get_pop().set_is_primary_or_accepted_culture(
false);
945 for(
auto p : state.world.province_get_pop_location(
id)) {
949 for(
const auto src : p.get_pop().get_regiment_source()) {
950 if(!src.get_regiment().get_army_from_army_membership().get_is_retreating()
951 && !src.get_regiment().get_army_from_army_membership().get_navy_from_army_transport()
952 && !src.get_regiment().get_army_from_army_membership().get_battle_from_army_battle_participation()
953 && !src.get_regiment().get_army_from_army_membership().get_controller_from_army_rebel_control()) {
954 auto new_u = fatten(state.world, state.world.create_army());
955 new_u.set_controller_from_army_control(new_owner);
956 src.get_regiment().set_army_from_army_membership(new_u);
959 src.get_regiment().set_strength(0.f);
963 auto regs = p.get_pop().get_regiment_source();
964 while(regs.begin() != regs.end()) {
965 state.world.delete_regiment_source(*(regs.begin()));
968 auto lc = p.get_pop().get_province_land_construction();
969 while(lc.begin() != lc.end()) {
970 state.world.delete_province_land_construction(*(lc.begin()));
975 state.world.province_set_nation_from_province_ownership(
id, new_owner);
976 state.world.province_set_rebel_faction_from_province_rebel_control(
id, dcon::rebel_faction_id{});
977 state.world.province_set_last_control_change(
id, state.current_date);
978 state.world.province_set_nation_from_province_control(
id, new_owner);
979 state.world.province_set_siege_progress(
id, 0.0f);
984 state.world.province_set_is_owner_core(
id,
985 bool(state.world.get_core_by_prov_tag_key(
id, state.world.nation_get_identity_from_identity_holder(new_owner))));
988 dcon::province_id a_province;
992 if(state.crisis_attacker_wargoals.size() > 0) {
993 auto first_wg = state.crisis_attacker_wargoals.at(0);
994 if(old_si.get_definition() == first_wg.state)
997 auto local_market = state.world.state_instance_get_market_from_local_market(old_si);
999 state.world.delete_market(local_market);
1000 state.world.delete_state_instance(old_si);
1002 }
else if(state.world.state_instance_get_capital(old_si) ==
id) {
1003 state.world.state_instance_set_capital(old_si, a_province);
1008 state.world.nation_get_owned_province_count(old_owner) -= uint16_t(1);
1009 auto lprovs = state.world.nation_get_province_ownership(old_owner);
1010 if(lprovs.begin() == lprovs.end()) {
1011 state.world.nation_set_marked_for_gc(old_owner,
true);
1016 state.world.province_set_naval_rally_point(
id,
false);
1017 state.world.province_set_land_rally_point(
id,
false);
1023 auto rng = state.world.province_get_province_building_construction(
id);
1024 while(
rng.begin() !=
rng.end()) {
1025 state.world.delete_province_building_construction(*(
rng.begin()));
1030 auto rng = state.world.province_get_province_naval_construction(
id);
1031 while(
rng.begin() !=
rng.end()) {
1032 state.world.delete_province_naval_construction(*(
rng.begin()));
1036 for(
auto adj : state.world.province_get_province_adjacency(
id)) {
1037 auto other = adj.get_connected_provinces(0) !=
id ? adj.get_connected_provinces(0) : adj.get_connected_provinces(1);
1038 if(other.get_nation_from_province_ownership() == new_owner) {
1046 for(
auto ar : state.world.province_get_army_location_as_location(
id)) {
1047 if(ar.get_army() && ar.get_army().get_army_rebel_control().get_controller()) {
1048 assert(!ar.get_army().get_army_control().get_controller());
1049 state.world.army_set_controller_from_army_control(ar.get_army(), dcon::nation_id{});
1050 state.world.army_set_controller_from_army_rebel_control(ar.get_army(), dcon::rebel_faction_id{});
1051 state.world.army_set_is_retreating(ar.get_army(),
true);
1055 if(state_is_new && old_owner) {
1065 bool was_colonial = state.world.province_get_is_colonial(
id);
1079 if(!state.world.nation_get_is_civilized(new_owner)) {
1080 auto rp_mod_mod = 0.75f + state.world.nation_get_modifier_values(new_owner, sys::national_mod_offsets::research_points_modifier);
1082 float sum_from_pops = 0;
1084 state.world.for_each_pop_type([&](dcon::pop_type_id t) {
1085 auto rp = state.world.pop_type_get_research_points(t);
1087 sum_from_pops += rp * std::min(1.0f, state.world.province_get_demographics(
id,
demographics::to_key(state, t)) / (total_pop * state.world.pop_type_get_research_optimum(t)));
1091 auto amount = total_pop > 0.0f ? (state.defines.research_points_on_conquer_mult * sum_from_pops) * (rp_mod_mod + 1.0f) : 0.0f;
1092 state.world.nation_get_research_points(new_owner) += amount;
1099 if(state.world.province_get_is_owner_core(
id) ==
false && !was_colonial) {
1100 for(
auto pop : state.world.province_get_pop_location(
id)) {
1101 if(!pop.get_pop().get_is_primary_or_accepted_culture()) {
1110 state.world.province_set_nationalism(
id, state.defines.years_of_nationalism);
1115 auto old_n = state.world.province_get_nationalism(ids);
1116 auto new_nat = ve::max(old_n - 0.083f, 0.0f);
1117 state.world.province_set_nationalism(ids, new_nat);
1123 auto owner = state.world.province_get_nation_from_province_ownership(p);
1136 if((rvalues.high & 0xFF) >= chance) {
1137 if(state.world.province_get_crime(p)) {
1139 state.world.nation_get_central_crime_count(owner) -= uint16_t(1);
1141 state.world.province_set_crime(p, dcon::crime_id{});
1143 if(!state.world.province_get_crime(p)) {
1144 static std::vector<dcon::crime_id> possible_crimes;
1145 possible_crimes.clear();
1147 for(
uint32_t i = 0; i < state.culture_definitions.crimes.size(); ++i) {
1148 dcon::crime_id c{dcon::crime_id::value_base_t(i)};
1149 if(state.culture_definitions.crimes[c].available_by_default || state.world.nation_get_active_crime(owner, c)) {
1150 if(
auto t = state.culture_definitions.crimes[c].trigger; t) {
1152 possible_crimes.push_back(c);
1154 possible_crimes.push_back(c);
1159 if(
auto count = possible_crimes.size(); count != 0) {
1160 auto selected = possible_crimes[rvalues.low % count];
1161 state.world.province_set_crime(p, selected);
1163 state.world.nation_get_central_crime_count(owner) += uint16_t(1);
1171 for(
auto rel : state.world.state_definition_get_colonization(d)) {
1172 if(rel.get_colonizer() == n) {
1179bool can_invest_in_colony(
sys::state& state, dcon::nation_id n, dcon::state_definition_id d) {
1181 if(state.world.nation_get_rank(n) > uint16_t(state.defines.colonial_rank))
1184 if(state.world.state_definition_get_colonization_stage(d) >
uint8_t(2))
1189 auto first_wg = state.crisis_attacker_wargoals.at(0);
1190 if(first_wg.state == d)
1192 for(
auto par : state.world.war_get_war_participant(state.crisis_war)) {
1193 if(par.get_nation() == n)
1197 dcon::colonization_id colony_status;
1198 auto crange = state.world.state_definition_get_colonization(d);
1199 for(
auto rel : crange) {
1200 if(rel.get_colonizer() == n) {
1201 colony_status = rel.id;
1208 if(crange.end() - crange.begin() <= 1)
1216 if(state.world.colonization_get_last_investment(colony_status) + int32_t(state.defines.colonization_days_between_investment) > state.current_date)
1226 if(state.world.state_definition_get_colonization_stage(d) == 1) {
1227 return free_points >= int32_t(state.defines.colonization_interest_cost);
1228 }
else if(state.world.colonization_get_level(colony_status) <= 4) {
1229 return free_points >= int32_t(state.defines.colonization_influence_cost);
1231 return free_points >=
1232 int32_t(state.defines.colonization_extra_guard_cost * (state.world.colonization_get_level(colony_status) - 4) +
1233 state.defines.colonization_influence_cost);
1238 auto d = state.world.state_instance_get_definition(si);
1239 auto owner = state.world.state_instance_get_nation_from_state_ownership(si);
1240 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1241 if(p.get_province().get_nation_from_province_ownership() == owner) {
1242 for(
auto adj : p.get_province().get_province_adjacency()) {
1243 auto indx = adj.get_connected_provinces(0) != p.get_province() ? 0 : 1;
1244 auto o = adj.get_connected_provinces(indx).get_nation_from_province_ownership();
1247 if(o.get_overlord_as_subject().get_ruler() == n)
1256 if(state.world.state_definition_get_colonization_stage(d) >
uint8_t(1))
1259 auto mem = state.world.state_definition_get_abstract_state_membership(d);
1260 if(mem.begin() == mem.end() || (*mem.begin()).get_province().id.index() >= state.province_definitions.first_sea_province.index())
1264 if(state.world.nation_get_rank(n) > uint16_t(state.defines.colonial_rank))
1268 if(state.crisis_attacker_wargoals.size() > 0) {
1269 auto first_wg = state.crisis_attacker_wargoals.at(0);
1270 if(first_wg.state == d)
1272 for(
auto par : state.world.war_get_war_participant(state.crisis_war)) {
1273 if(par.get_nation() == n)
1278 float max_life_rating = -1.0f;
1279 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1280 if(!p.get_province().get_nation_from_province_ownership()) {
1281 max_life_rating = std::max(max_life_rating,
float(p.get_province().get_life_rating()));
1285 if(max_life_rating < 0.0f) {
1294 if(state.defines.colonial_liferating + state.world.nation_get_modifier_values(n, sys::national_mod_offsets::colonial_life_rating) > max_life_rating) {
1298 auto colonizers = state.world.state_definition_get_colonization(d);
1299 auto num_colonizers = colonizers.end() - colonizers.begin();
1303 if(num_colonizers >= 4)
1306 for(
auto c : colonizers) {
1307 if(c.get_colonizer() == n)
1317 bool adjacent = [&]() {
1318 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1319 if(!p.get_province().get_nation_from_province_ownership()) {
1320 for(
auto adj : p.get_province().get_province_adjacency()) {
1321 auto indx = adj.get_connected_provinces(0) != p.get_province() ? 0 : 1;
1322 auto o = adj.get_connected_provinces(indx).get_nation_from_province_ownership();
1325 if(o.get_overlord_as_subject().get_ruler() == n)
1346 bool reachable_by_sea =
false;
1348 dcon::province_id coastal_target = [&]() {
1349 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1350 if(!p.get_province().get_nation_from_province_ownership()) {
1351 if(p.get_province().get_is_coast())
1352 return p.get_province().id;
1355 return dcon::province_id{};
1358 if(!adjacent && coastal_target && state.world.nation_get_central_ports(n) != 0) {
1359 for(
auto p : state.world.nation_get_province_ownership(n)) {
1363 reachable_by_sea =
true;
1370 if(!adjacent && !reachable_by_sea)
1380 return free_points >= int32_t(state.defines.colonization_interest_cost_initial +
1381 (adjacent ? state.defines.colonization_interest_cost_neighbor_modifier : 0.0f));
1385 if(state.world.state_definition_get_colonization_stage(d) >
uint8_t(1))
1388 if(free_points < int32_t(state.defines.colonization_interest_cost_initial + state.defines.colonization_interest_cost_neighbor_modifier))
1391 auto mem = state.world.state_definition_get_abstract_state_membership(d);
1392 if(mem.begin() == mem.end() || (*mem.begin()).get_province().id.index() >= state.province_definitions.first_sea_province.index())
1396 if(state.world.nation_get_rank(n) > uint16_t(state.defines.colonial_rank))
1400 if(state.crisis_attacker_wargoals.size() > 0) {
1401 auto first_wg = state.crisis_attacker_wargoals.at(0);
1402 if(first_wg.state == d)
1406 float max_life_rating = -1.0f;
1407 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1408 if(!p.get_province().get_nation_from_province_ownership()) {
1409 max_life_rating = std::max(max_life_rating,
float(p.get_province().get_life_rating()));
1413 if(max_life_rating < 0.0f) {
1422 if(state.defines.colonial_liferating + state.world.nation_get_modifier_values(n, sys::national_mod_offsets::colonial_life_rating) > max_life_rating) {
1426 auto colonizers = state.world.state_definition_get_colonization(d);
1427 auto num_colonizers = colonizers.end() - colonizers.begin();
1431 if(num_colonizers >= 4)
1434 for(
auto c : colonizers) {
1435 if(c.get_colonizer() == n)
1446 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1447 if(!p.get_province().get_nation_from_province_ownership()) {
1448 for(
auto adj : p.get_province().get_province_adjacency()) {
1449 auto indx = adj.get_connected_provinces(0) != p.get_province() ? 0 : 1;
1450 auto o = adj.get_connected_provinces(indx).get_nation_from_province_ownership();
1453 if(o.get_overlord_as_subject().get_ruler() == n)
1461 bool reachable_by_sea =
false;
1463 if(!adjacent && coastal_target && state.world.nation_get_central_ports(n) != 0) {
1464 for(
auto p : state.world.nation_get_province_ownership(n)) {
1468 reachable_by_sea =
true;
1475 if(!adjacent && !reachable_by_sea)
1483 return free_points >= int32_t(state.defines.colonization_interest_cost_initial +
1484 (adjacent ? state.defines.colonization_interest_cost_neighbor_modifier : 0.0f));
1488 uint8_t greatest_other_level = 0;
1489 dcon::nation_id second_colonizer;
1490 for(
auto rel : state.world.state_definition_get_colonization(state_def)) {
1491 if(rel.get_colonizer() != source) {
1492 if(rel.get_level() >= greatest_other_level) {
1493 greatest_other_level = rel.get_level();
1494 second_colonizer = rel.get_colonizer();
1499 for(
auto rel : state.world.state_definition_get_colonization(state_def)) {
1500 if(rel.get_colonizer() == source) {
1502 if(state.world.state_definition_get_colonization_stage(state_def) == 1) {
1503 rel.get_points_invested() += uint16_t(state.defines.colonization_interest_cost);
1504 }
else if(rel.get_level() <= 4) {
1505 rel.get_points_invested() += uint16_t(state.defines.colonization_influence_cost);
1507 rel.get_points_invested() += uint16_t(
1508 state.defines.colonization_extra_guard_cost * (rel.get_level() - 4) + state.defines.colonization_influence_cost);
1511 rel.get_level() +=
uint8_t(1);
1512 rel.set_last_investment(state.current_date);
1519 if(state.world.state_definition_get_colonization_stage(state_def) == 1) {
1520 if(rel.get_level() >= int32_t(state.defines.colonization_interest_lead)) {
1522 state.world.state_definition_set_colonization_stage(state_def,
uint8_t(2));
1523 auto col_range = state.world.state_definition_get_colonization(state_def);
1524 while(int32_t(col_range.end() - col_range.begin()) > 2) {
1525 for(
auto r : col_range) {
1526 if(r.get_colonizer() != source && r.get_colonizer() != second_colonizer) {
1527 state.world.delete_colonization(r);
1533 }
else if(rel.get_level() >= int32_t(state.defines.colonization_interest_lead) + greatest_other_level) {
1534 state.world.state_definition_set_colonization_stage(state_def,
uint8_t(3));
1535 auto col_range = state.world.state_definition_get_colonization(state_def);
1536 while(int32_t(col_range.end() - col_range.begin()) > 1) {
1537 for(
auto r : col_range) {
1538 if(r.get_colonizer() != source) {
1539 state.world.delete_colonization(r);
1551 for(
auto d : state.world.in_state_definition) {
1552 auto colonizers = state.world.state_definition_get_colonization(d);
1553 auto num_colonizers = colonizers.end() - colonizers.begin();
1555 if(num_colonizers > 0) {
1556 int32_t unowned_provs = 0;
1557 for(
auto p : d.get_abstract_state_membership()) {
1558 if(!(p.get_province().get_nation_from_province_ownership())) {
1563 if(unowned_provs == 0) {
1564 while(colonizers.begin() != colonizers.end()) {
1565 state.world.delete_colonization(*(colonizers.begin()));
1567 d.set_colonization_stage(
uint8_t(0));
1572 if(num_colonizers == 0 && d.get_colonization_stage() != 0) {
1573 d.set_colonization_stage(
uint8_t(0));
1574 }
else if(num_colonizers > 1 && d.get_colonization_stage() ==
uint8_t(2)) {
1582 int32_t max_points = 0;
1583 float at_war_adjust = 0.0f;
1584 for(
auto c : colonizers) {
1585 max_points = std::max(max_points, int32_t(c.get_level()));
1586 if(state.world.nation_get_is_at_war(c.get_colonizer()) ||
1587 (state.world.nation_get_disarmed_until(c.get_colonizer()) &&
1588 state.current_date <= state.world.nation_get_disarmed_until(c.get_colonizer()))) {
1589 at_war_adjust = state.defines.at_war_tension_decay;
1593 float adjust = state.defines.colonization_influence_temperature_per_day +
1594 float(max_points) * state.defines.colonization_influence_temperature_per_level +
1597 d.set_colonization_temperature(std::clamp(d.get_colonization_temperature() + adjust, 0.0f, 100.0f));
1598 }
else if(num_colonizers == 1 &&
1599 (*colonizers.begin()).get_last_investment() + int32_t(state.defines.colonization_days_for_initial_investment) <=
1600 state.current_date) {
1606 d.set_colonization_stage(
uint8_t(3));
1607 (*colonizers.begin()).set_last_investment(state.current_date);
1608 }
else if(d.get_colonization_stage() ==
uint8_t(3) && num_colonizers != 0) {
1613 if((*colonizers.begin()).get_last_investment() + 31 * int32_t(state.defines.colonization_months_to_colonize) <=
1614 state.current_date) {
1616 d.set_colonization_stage(
uint8_t(0));
1618 state.world.delete_colonization(*(colonizers.begin()));
1619 }
while(colonizers.end() != colonizers.begin());
1620 }
else if(state.world.nation_get_is_player_controlled((*colonizers.begin()).get_colonizer()) ==
false) {
1621 auto source = (*colonizers.begin()).get_colonizer();
1623 for(
auto pr : state.world.state_definition_get_abstract_state_membership(d)) {
1624 if(!pr.get_province().get_nation_from_province_ownership()) {
1629 state.world.state_definition_set_colonization_temperature(d, 0.0f);
1630 state.world.state_definition_set_colonization_stage(d,
uint8_t(0));
1632 while(colonizers.begin() != colonizers.end()) {
1633 state.world.delete_colonization(*colonizers.begin());
1641 auto d = state.world.state_instance_get_definition(s);
1642 auto o = state.world.state_instance_get_nation_from_state_ownership(s);
1644 dcon::province_id result = { };
1645 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1646 if(p.get_province().get_nation_from_province_ownership() != o)
1648 if(!p.get_province().get_port_to())
1651 state.world.province_get_demographics(
1656 max_pop = state.world.province_get_demographics(
1660 result = p.get_province();
1667 auto d = state.world.state_instance_get_definition(s);
1668 auto o = state.world.state_instance_get_nation_from_state_ownership(s);
1669 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1670 if(p.get_province().get_nation_from_province_ownership() == o) {
1671 if(p.get_province().get_port_to())
1679 auto d = state.world.state_instance_get_definition(s);
1680 auto o = state.world.state_instance_get_nation_from_state_ownership(s);
1682 for(
auto p : state.world.state_definition_get_abstract_state_membership(d)) {
1683 if(p.get_province().get_nation_from_province_ownership() == o) {
1684 if(p.get_province().get_port_to()) {
1685 if(p.get_province().get_is_owner_core())
1696 state.world.try_create_core(prov, tag);
1697 if(state.world.province_get_nation_from_province_ownership(prov) ==
1698 state.world.national_identity_get_nation_from_identity_holder(tag)) {
1699 state.world.province_set_is_owner_core(prov,
true);
1705 auto core_rel = state.world.get_core_by_prov_tag_key(prov, tag);
1707 state.world.delete_core(core_rel);
1708 if(state.world.province_get_nation_from_province_ownership(prov) ==
1709 state.world.national_identity_get_nation_from_identity_holder(tag)) {
1710 state.world.province_set_is_owner_core(prov,
false);
1716 auto old_rgo = state.world.province_get_rgo(prov);
1717 state.world.province_set_rgo(prov, c);
1718 if(state.world.commodity_get_is_mine(old_rgo) != state.world.commodity_get_is_mine(c)) {
1719 if(state.world.commodity_get_is_mine(c)) {
1720 for(
auto pop : state.world.province_get_pop_location(prov)) {
1721 if(pop.get_pop().get_poptype() == state.culture_definitions.farmers) {
1722 pop.get_pop().set_poptype(state.culture_definitions.laborers);
1726 for(
auto pop : state.world.province_get_pop_location(prov)) {
1727 if(pop.get_pop().get_poptype() == state.culture_definitions.laborers) {
1728 pop.get_pop().set_poptype(state.culture_definitions.farmers);
1736 state.world.province_adjacency_get_type(state.province_definitions.canals[
id]) &=
~province::border::impassible_bit;
1741 return state.world.province_adjacency_get_distance(pair);
1746 auto apos = state.world.province_get_mid_point_b(a);
1747 auto bpos = state.world.province_get_mid_point_b(b);
1748 auto dot = (apos.x * bpos.x + apos.y * bpos.y) + apos.z * bpos.z;
1753 auto apos = state.world.province_get_mid_point_b(a);
1754 auto bpos = state.world.province_get_mid_point_b(b);
1755 auto dot = (apos.x * bpos.x + apos.y * bpos.y) + apos.z * bpos.z;
1761 auto controller = state.world.province_get_nation_from_province_control(prov);
1766 if(controller == nation_as)
1769 if(state.world.nation_get_in_sphere_of(controller) == nation_as)
1772 auto coverl = state.world.nation_get_overlord_as_subject(controller);
1773 if(state.world.overlord_get_ruler(coverl) == nation_as)
1776 auto url = state.world.get_unilateral_relationship_by_unilateral_pair(controller, nation_as);
1777 if(state.world.unilateral_relationship_get_military_access(url))
1788 auto controller = state.world.province_get_nation_from_province_control(prov);
1796 if(controller == nation_as)
1799 if(state.world.nation_get_in_sphere_of(controller) == nation_as)
1802 auto coverl = state.world.nation_get_overlord_as_subject(controller);
1803 if(state.world.overlord_get_ruler(coverl) == nation_as)
1806 auto url = state.world.get_unilateral_relationship_by_unilateral_pair(controller, nation_as);
1807 if(state.world.unilateral_relationship_get_military_access(url))
1817 auto controller = state.world.province_get_nation_from_province_control(prov);
1820 return !bool(state.world.province_get_rebel_faction_from_province_rebel_control(prov));
1825 if(controller == nation_as)
1828 if(state.world.nation_get_in_sphere_of(controller) == nation_as)
1831 auto coverl = state.world.nation_get_overlord_as_subject(controller);
1832 if(state.world.overlord_get_ruler(coverl) == nation_as)
1835 auto url = state.world.get_unilateral_relationship_by_unilateral_pair(controller, nation_as);
1836 if(state.world.unilateral_relationship_get_military_access(url))
1846 float distance_covered = 0.0f;
1847 float distance_to_target = 0.0f;
1851 if(other.distance_covered + other.distance_to_target != distance_covered + distance_to_target)
1852 return distance_covered + distance_to_target > other.distance_covered + other.distance_to_target;
1853 return other.province.index() >
province.index();
1857static void assert_path_result(std::vector<dcon::province_id>& v) {
1858 for(
auto const e : v)
1863std::vector<dcon::province_id> make_land_path(
sys::state& state, dcon::province_id start, dcon::province_id end, dcon::nation_id nation_as, dcon::army_id a) {
1865 std::vector<province_and_distance> path_heap;
1866 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
1868 std::vector<dcon::province_id> path_result;
1873 auto fill_path_result = [&](dcon::province_id i) {
1874 path_result.push_back(end);
1875 while(i && i != start) {
1876 path_result.push_back(i);
1877 i = origins_vector.get(i);
1882 while(path_heap.size() > 0) {
1883 std::pop_heap(path_heap.begin(), path_heap.end());
1884 auto nearest = path_heap.back();
1885 path_heap.pop_back();
1887 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
1889 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
1890 auto bits = adj.get_type();
1891 auto distance = adj.get_distance();
1894 if(other_prov == end) {
1895 fill_path_result(nearest.province);
1896 assert_path_result(path_result);
1900 if(other_prov.id.index() < state.province_definitions.first_sea_province.index()) {
1903 auto armies = state.world.province_get_army_location(other_prov);
1904 float danger_factor = (armies.begin() == armies.end() || (*armies.begin()).get_army().get_controller_from_army_control() == nation_as) ? 1.f : 4.f;
1905 path_heap.push_back(
1907 std::push_heap(path_heap.begin(), path_heap.end());
1908 origins_vector.set(other_prov, nearest.province);
1910 origins_vector.set(other_prov, dcon::province_id{0});
1914 path_heap.push_back(
1916 std::push_heap(path_heap.begin(), path_heap.end());
1917 origins_vector.set(other_prov, nearest.province);
1919 origins_vector.set(other_prov, dcon::province_id{0});
1926 assert_path_result(path_result);
1932 std::vector<province_and_distance> path_heap;
1933 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
1935 std::vector<dcon::province_id> path_result;
1940 auto fill_path_result = [&](dcon::province_id i) {
1941 path_result.push_back(end);
1942 while(i && i != start) {
1943 path_result.push_back(i);
1944 i = origins_vector.get(i);
1949 while(path_heap.size() > 0) {
1950 std::pop_heap(path_heap.begin(), path_heap.end());
1951 auto nearest = path_heap.back();
1952 path_heap.pop_back();
1954 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
1956 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
1957 auto bits = adj.get_type();
1958 auto distance = adj.get_distance();
1961 if(other_prov == end) {
1962 fill_path_result(nearest.province);
1963 assert_path_result(path_result);
1967 if(other_prov.id.index() < state.province_definitions.first_sea_province.index()) {
1969 path_heap.push_back(
1971 std::push_heap(path_heap.begin(), path_heap.end());
1972 origins_vector.set(other_prov, nearest.province);
1974 origins_vector.set(other_prov, dcon::province_id{0});
1977 origins_vector.set(other_prov, dcon::province_id{0});
1983 assert_path_result(path_result);
1989 std::vector<province_and_distance> path_heap;
1990 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
1992 std::vector<dcon::province_id> path_result;
1997 auto fill_path_result = [&](dcon::province_id i) {
1998 path_result.push_back(end);
1999 while(i && i != start) {
2000 path_result.push_back(i);
2001 i = origins_vector.get(i);
2006 while(path_heap.size() > 0) {
2007 std::pop_heap(path_heap.begin(), path_heap.end());
2008 auto nearest = path_heap.back();
2009 path_heap.pop_back();
2013 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
2015 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
2016 auto bits = adj.get_type();
2018 auto distance = adj.get_distance();
2020 if(railroad_origin > 0 && railroad_target > 0) {
2026 if(other_prov == end) {
2027 fill_path_result(nearest.province);
2028 assert_path_result(path_result);
2031 path_heap.push_back(
2033 std::push_heap(path_heap.begin(), path_heap.end());
2034 origins_vector.set(other_prov, nearest.province);
2039 assert_path_result(path_result);
2045 std::vector<province_and_distance> path_heap;
2046 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
2048 std::vector<dcon::province_id> path_result;
2053 auto fill_path_result = [&](dcon::province_id i) {
2054 path_result.push_back(end);
2055 while(i && i != start) {
2056 path_result.push_back(i);
2057 i = origins_vector.get(i);
2062 while(path_heap.size() > 0) {
2063 std::pop_heap(path_heap.begin(), path_heap.end());
2064 auto nearest = path_heap.back();
2065 path_heap.pop_back();
2067 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
2069 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
2070 auto bits = adj.get_type();
2071 auto distance = adj.get_distance();
2074 if(other_prov == end) {
2075 fill_path_result(nearest.province);
2076 assert_path_result(path_result);
2080 path_heap.push_back(
2082 std::push_heap(path_heap.begin(), path_heap.end());
2083 origins_vector.set(other_prov, nearest.province);
2089 assert_path_result(path_result);
2096 std::vector<province_and_distance> path_heap;
2097 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
2099 std::vector<dcon::province_id> path_result;
2104 auto fill_path_result = [&](dcon::province_id i) {
2105 path_result.push_back(end);
2106 while(i && i != start) {
2107 path_result.push_back(i);
2108 i = origins_vector.get(i);
2113 while(path_heap.size() > 0) {
2114 std::pop_heap(path_heap.begin(), path_heap.end());
2115 auto nearest = path_heap.back();
2116 path_heap.pop_back();
2118 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
2120 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
2121 auto bits = adj.get_type();
2122 auto distance = adj.get_distance();
2126 (other_prov.id.index() >= state.province_definitions.first_sea_province.index() ||
2127 nearest.province.index() >= state.province_definitions.first_sea_province.index())) {
2132 if(other_prov == end) {
2133 fill_path_result(nearest.province);
2134 assert_path_result(path_result);
2139 std::push_heap(path_heap.begin(), path_heap.end());
2140 origins_vector.set(other_prov, nearest.province);
2142 }
else if(other_prov.id.index() < state.province_definitions.first_sea_province.index() && other_prov == end && other_prov.get_port_to() == nearest.province) {
2144 fill_path_result(nearest.province);
2145 assert_path_result(path_result);
2147 }
else if(nearest.province.index() < state.province_definitions.first_sea_province.index() && state.world.province_get_port_to(nearest.province) == other_prov.id) {
2149 if(other_prov == end) {
2150 fill_path_result(nearest.province);
2151 assert_path_result(path_result);
2155 std::push_heap(path_heap.begin(), path_heap.end());
2156 origins_vector.set(other_prov, nearest.province);
2163 assert_path_result(path_result);
2168 float distance_covered = 0.0f;
2172 if(other.distance_covered != distance_covered)
2173 return distance_covered > other.distance_covered;
2174 return other.province.index() >
province.index();
2180 std::vector<retreat_province_and_distance> path_heap;
2181 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
2183 std::vector<dcon::province_id> path_result;
2185 auto fill_path_result = [&](dcon::province_id i) {
2186 while(i && i != start) {
2187 path_result.push_back(i);
2188 i = origins_vector.get(i);
2193 while(path_heap.size() > 0) {
2194 std::pop_heap(path_heap.begin(), path_heap.end());
2195 auto nearest = path_heap.back();
2196 path_heap.pop_back();
2198 if(nearest.province.index() < state.province_definitions.first_sea_province.index()) {
2199 fill_path_result(nearest.province);
2200 assert_path_result(path_result);
2204 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
2206 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
2207 auto bits = adj.get_type();
2208 auto distance = adj.get_distance();
2213 std::push_heap(path_heap.begin(), path_heap.end());
2214 origins_vector.set(other_prov, nearest.province);
2215 }
else if(other_prov.get_port_to() != nearest.province) {
2219 std::push_heap(path_heap.begin(), path_heap.end());
2220 origins_vector.set(other_prov, nearest.province);
2222 origins_vector.set(other_prov, dcon::province_id{0});
2228 assert_path_result(path_result);
2234 std::vector<retreat_province_and_distance> path_heap;
2235 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
2237 origins_vector.set(start, dcon::province_id{0});
2239 std::vector<dcon::province_id> path_result;
2241 auto fill_path_result = [&](dcon::province_id i) {
2242 while(i && i != start) {
2243 path_result.push_back(i);
2244 i = origins_vector.get(i);
2249 while(path_heap.size() > 0) {
2250 std::pop_heap(path_heap.begin(), path_heap.end());
2251 auto nearest = path_heap.back();
2252 path_heap.pop_back();
2255 fill_path_result(nearest.province);
2256 assert_path_result(path_result);
2260 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
2262 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
2263 auto bits = adj.get_type();
2264 auto distance = adj.get_distance();
2269 std::push_heap(path_heap.begin(), path_heap.end());
2270 origins_vector.set(other_prov, nearest.province);
2278 assert_path_result(path_result);
2283 std::vector<retreat_province_and_distance> path_heap;
2284 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
2286 origins_vector.set(start, dcon::province_id{0});
2288 std::vector<dcon::province_id> path_result;
2290 auto fill_path_result = [&](dcon::province_id i) {
2291 while(i && i != start) {
2292 path_result.push_back(i);
2293 i = origins_vector.get(i);
2298 while(path_heap.size() > 0) {
2299 std::pop_heap(path_heap.begin(), path_heap.end());
2300 auto nearest = path_heap.back();
2301 path_heap.pop_back();
2303 if(state.world.province_get_is_coast(nearest.province)) {
2304 fill_path_result(nearest.province);
2305 assert_path_result(path_result);
2309 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
2311 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
2312 auto bits = adj.get_type();
2313 auto distance = adj.get_distance();
2319 std::push_heap(path_heap.begin(), path_heap.end());
2320 origins_vector.set(other_prov, nearest.province);
2322 origins_vector.set(other_prov, dcon::province_id{0});
2331 assert_path_result(path_result);
2335 std::vector<retreat_province_and_distance> path_heap;
2336 auto origins_vector = ve::vectorizable_buffer<dcon::province_id, dcon::province_id>(state.world.province_size());
2338 origins_vector.set(start, dcon::province_id{0});
2340 std::vector<dcon::province_id> path_result;
2342 auto fill_path_result = [&](dcon::province_id i) {
2343 while(i && i != start) {
2344 path_result.push_back(i);
2345 i = origins_vector.get(i);
2350 while(path_heap.size() > 0) {
2351 std::pop_heap(path_heap.begin(), path_heap.end());
2352 auto nearest = path_heap.back();
2353 path_heap.pop_back();
2355 if(state.world.province_get_is_coast(nearest.province)) {
2356 fill_path_result(nearest.province);
2357 assert_path_result(path_result);
2361 for(
auto adj : state.world.province_get_province_adjacency(nearest.province)) {
2363 adj.get_connected_provinces(0) == nearest.province ? adj.get_connected_provinces(1) : adj.get_connected_provinces(0);
2364 auto bits = adj.get_type();
2365 auto distance = adj.get_distance();
2370 std::push_heap(path_heap.begin(), path_heap.end());
2371 origins_vector.set(other_prov, nearest.province);
2379 assert_path_result(path_result);
2384 for(
auto p : state.world.in_province) {
2385 auto tile_pos = p.get_mid_point();
2386 auto scaled_pos = tile_pos / glm::vec2{float(state.map_state.map_data.size_x), float(state.map_state.map_data.size_y)};
2388 glm::vec3 new_world_pos;
2389 float angle_x = 2 * scaled_pos.x *
math::pi;
2393 float angle_y = scaled_pos.y *
math::pi;
2398 p.set_mid_point_b(new_world_pos);
2400 for(
auto adj : state.world.in_province_adjacency) {
2401 auto dist =
direct_distance(state, adj.get_connected_provinces(0), adj.get_connected_provinces(1));
2402 adj.set_distance(dist);
#define assert(condition)
void fix_slaves_in_province(sys::state &state, dcon::nation_id owner, dcon::province_id p)
pop_satisfaction_wrapper_fat fatten(data_container const &c, pop_satisfaction_wrapper_id id) noexcept
constexpr dcon::demographics_key total(0)
dcon::demographics_key to_key(sys::state const &state, dcon::pop_type_id v)
constexpr dcon::demographics_key militancy(4)
float rgo_total_employment(sys::state &state, dcon::nation_id n, dcon::province_id p)
float rgo_total_max_employment(sys::state &state, dcon::nation_id n, dcon::province_id p)
float subsistence_max_pseudoemployment(sys::state &state, dcon::nation_id n, dcon::province_id p)
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)
constexpr uint32_t build_railway
constexpr uint32_t build_bank
constexpr uint32_t build_university
constexpr uint32_t allow_foreign_investment
float cos(float x) noexcept
float sin(float x) noexcept
float acos(float x) noexcept
bool province_is_under_siege(sys::state const &state, dcon::province_id ids)
bool are_allied_in_war(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
void army_arrives_in_province(sys::state &state, dcon::army_id a, dcon::province_id p, crossing_type crossing, dcon::land_battle_id from)
void eject_ships(sys::state &state, dcon::province_id p)
void update_blockade_status(sys::state &state)
bool are_in_common_war(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
bool can_embark_onto_sea_tile(sys::state &state, dcon::nation_id from, dcon::province_id p, dcon::army_id a)
bool are_at_war(sys::state const &state, dcon::nation_id a, dcon::nation_id b)
void invalidate_unowned_wargoals(sys::state &state)
void update_blackflag_status(sys::state &state, dcon::province_id p)
bool province_is_blockaded(sys::state const &state, dcon::province_id ids)
int32_t free_colonial_points(sys::state &state, dcon::nation_id n)
void adjust_prestige(sys::state &state, dcon::nation_id n, float delta)
void cleanup_crisis(sys::state &state)
void set_militancy(sys::state &state, dcon::pop_id p, float v)
float get_militancy(sys::state const &state, dcon::pop_id p)
constexpr uint8_t impassible_bit
constexpr uint8_t national_bit
constexpr uint8_t coastal_bit
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)
float sorting_distance(sys::state &state, dcon::province_id a, dcon::province_id b)
void upgrade_colonial_state(sys::state &state, dcon::nation_id source, dcon::state_instance_id si)
float state_sorting_distance(sys::state &state, dcon::state_instance_id state_id, dcon::province_id prov_id)
bool has_an_owner(sys::state &state, dcon::province_id id)
bool can_build_railroads(sys::state &state, dcon::province_id id, dcon::nation_id n)
void update_connected_regions(sys::state &state)
void update_blockaded_cache(sys::state &state)
void update_nationalism(sys::state &state)
void update_crimes(sys::state &state)
std::vector< dcon::province_id > make_safe_land_path(sys::state &state, dcon::province_id start, dcon::province_id end, dcon::nation_id nation_as)
std::vector< dcon::province_id > make_naval_retreat_path(sys::state &state, dcon::nation_id nation_as, dcon::province_id start)
bool has_access_to_province(sys::state &state, dcon::nation_id nation_as, dcon::province_id prov)
void restore_cached_values(sys::state &state)
bool has_naval_base_being_built(sys::state &state, dcon::province_id id)
void enable_canal(sys::state &state, int32_t id)
void add_core(sys::state &state, dcon::province_id prov, dcon::national_identity_id tag)
float state_distance(sys::state &state, dcon::state_instance_id state_id, dcon::province_id prov_id)
bool is_overseas(sys::state const &state, dcon::province_id ids)
void ve_for_each_land_province(sys::state &state, F const &func)
bool has_safe_access_to_province(sys::state &state, dcon::nation_id nation_as, dcon::province_id prov)
void remove_core(sys::state &state, dcon::province_id prov, dcon::national_identity_id tag)
bool is_colonizing(sys::state &state, dcon::nation_id n, dcon::state_definition_id d)
void for_each_province_in_state_instance(sys::state &state, dcon::state_instance_id s, F const &func)
bool can_build_province_building(sys::state &state, dcon::province_id id, dcon::nation_id n, economy::province_building_type t)
float state_accepted_bureaucrat_size(sys::state &state, dcon::state_instance_id id)
void set_rgo(sys::state &state, dcon::province_id prov, dcon::commodity_id c)
std::vector< dcon::province_id > make_path_to_nearest_coast(sys::state &state, dcon::nation_id nation_as, dcon::province_id start)
float distance(sys::state &state, dcon::province_adjacency_id pair)
bool has_province_building_being_built(sys::state &state, dcon::province_id id, economy::province_building_type t)
bool can_integrate_colony(sys::state &state, dcon::state_instance_id id)
std::vector< dcon::province_id > make_land_retreat_path(sys::state &state, dcon::nation_id nation_as, dcon::province_id start)
bool fast_can_start_colony(sys::state &state, dcon::nation_id n, dcon::state_definition_id d, int32_t free_points, dcon::province_id coastal_target, bool &adjacent)
float rgo_production_quantity(sys::state &state, dcon::province_id id, dcon::commodity_id c)
float crime_fighting_efficiency(sys::state &state, dcon::province_id id)
bool state_is_coastal(sys::state &state, dcon::state_instance_id s)
float rgo_maximum_employment(sys::state &state, dcon::province_id id)
bool has_railroads_being_built(sys::state &state, dcon::province_id id)
float land_maximum_employment(sys::state &state, dcon::province_id id)
void for_each_land_province(sys::state &state, F const &func)
bool can_build_fort(sys::state &state, dcon::province_id id, dcon::nation_id n)
bool can_start_colony(sys::state &state, dcon::nation_id n, dcon::state_definition_id d)
float rgo_size(sys::state &state, dcon::province_id prov_id)
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_land_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)
void set_province_controller(sys::state &state, dcon::province_id p, dcon::nation_id n)
void update_colonization(sys::state &state)
float land_employment(sys::state &state, dcon::province_id id)
bool has_naval_access_to_province(sys::state &state, dcon::nation_id nation_as, dcon::province_id prov)
float rgo_income(sys::state &state, dcon::province_id id)
void conquer_province(sys::state &state, dcon::province_id id, dcon::nation_id new_owner)
constexpr float world_circumference
bool state_is_coastal_non_core_nb(sys::state &state, dcon::state_instance_id s)
bool has_fort_being_built(sys::state &state, dcon::province_id id)
bool nations_are_adjacent(sys::state &state, dcon::nation_id a, dcon::nation_id b)
bool can_build_naval_base(sys::state &state, dcon::province_id id, dcon::nation_id n)
dcon::province_id get_connected_province(sys::state &state, dcon::province_adjacency_id adj, dcon::province_id curr)
float revolt_risk(sys::state &state, dcon::province_id id)
float colony_integration_cost(sys::state &state, dcon::state_instance_id id)
float state_admin_efficiency(sys::state &state, dcon::state_instance_id id)
void change_province_owner(sys::state &state, dcon::province_id id, dcon::nation_id new_owner)
std::vector< dcon::province_id > make_unowned_path_to_nearest_coast(sys::state &state, dcon::province_id start)
dcon::province_id pick_capital(sys::state &state, dcon::nation_id n)
void restore_distances(sys::state &state)
bool state_borders_nation(sys::state &state, dcon::nation_id n, dcon::state_instance_id si)
void increase_colonial_investment(sys::state &state, dcon::nation_id source, dcon::state_definition_id state_def)
bool generic_can_build_railroads(sys::state &state, dcon::province_id id, dcon::nation_id n)
void remove_pop_from_movement(sys::state &state, dcon::pop_id p)
void remove_pop_from_rebel_faction(sys::state &state, dcon::pop_id p)
random_pair get_random_pair(sys::state const &state, uint32_t value_in)
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)
bool operator<(province_and_distance const &other) const noexcept
dcon::province_id province
dcon::province_id prov_id
dcon::province_id province
bool operator<(retreat_province_and_distance const &other) const noexcept
Holds important data about the game world, state, and other data regarding windowing,...