Skip to content

Commit 09ad93a

Browse files
count occupations in later wars as occupations in older wars
1 parent 6217ffe commit 09ad93a

File tree

2 files changed

+108
-66
lines changed

2 files changed

+108
-66
lines changed

src/ai/ai_campaign_values.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ int16_t calculate_desired_army_size(sys::state& state, dcon::nation_id nation) {
6060
}
6161

6262
// How many regiments it has
63-
int16_t total = 0;
63+
// assume that to win a war against an enemy,
64+
// we need at least 10 regiments just to occupy their lands:
65+
// you can't conquer the enemy with 1 regiment!
66+
int16_t total = 10;
6467
for(auto p : state.world.nation_get_army_control(greatest_neighbor)) {
6568
auto frange = p.get_army().get_army_membership();
6669
total += int16_t(frange.end() - frange.begin());

src/military/military.cpp

Lines changed: 104 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,37 @@
1616

1717
namespace military {
1818

19+
20+
// this function should be used
21+
// only for provinces owned by a war participant
22+
bool does_province_count_for_war_occupation(sys::state& state, dcon::war_id w, dcon::province_id p) {
23+
auto controller = state.world.province_get_nation_from_province_control(p);
24+
auto owner = state.world.province_get_nation_from_province_ownership(p);
25+
// province must be occupied
26+
if(owner == controller) {
27+
return false;
28+
}
29+
// rebels do not count
30+
if(!controller) {
31+
return false;
32+
}
33+
// count occupations only for wars declared after targetted war
34+
auto date = state.world.war_get_start_date(w);
35+
for(auto candidate_war : state.world.nation_get_war_participant(owner)) {
36+
auto is_attacker = candidate_war.get_is_attacker();
37+
for(auto o : candidate_war.get_war().get_war_participant()) {
38+
if(o.get_nation() == controller) {
39+
auto& candidate_date = candidate_war.get_war().get_start_date();
40+
if(candidate_date < date) {
41+
return false;
42+
}
43+
}
44+
}
45+
}
46+
return true;
47+
}
48+
49+
1950
template auto province_is_blockaded<ve::tagged_vector<dcon::province_id>>(sys::state const&, ve::tagged_vector<dcon::province_id>);
2051
template auto province_is_under_siege<ve::tagged_vector<dcon::province_id>>(sys::state const&, ve::tagged_vector<dcon::province_id>);
2152
template auto battle_is_ongoing_in_province<ve::tagged_vector<dcon::province_id>>(sys::state const&, ve::tagged_vector<dcon::province_id>);
@@ -4240,15 +4271,15 @@ void update_ticking_war_score(sys::state& state) {
42404271
for(auto prv : wg.get_associated_state().get_abstract_state_membership()) {
42414272
if(prv.get_province().get_nation_from_province_ownership() == wg.get_target_nation()) {
42424273
++total_count;
4243-
if(get_role(state, war, prv.get_province().get_nation_from_province_control()) == role) {
4274+
if(does_province_count_for_war_occupation(state, war, prv.get_province())) {
42444275
++occupied;
42454276
}
42464277
}
42474278
}
42484279
} else if((bits & cb_flag::po_annex) != 0) {
42494280
for(auto prv : wg.get_target_nation().get_province_ownership()) {
42504281
++total_count;
4251-
if(get_role(state, war, prv.get_province().get_nation_from_province_control()) == role) {
4282+
if(does_province_count_for_war_occupation(state, war, prv.get_province())) {
42524283
++occupied;
42534284
}
42544285
}
@@ -4260,7 +4291,7 @@ void update_ticking_war_score(sys::state& state) {
42604291

42614292
province::for_each_province_in_state_instance(state, st.get_state(), [&](dcon::province_id prv) {
42624293
++total_count;
4263-
if(get_role(state, war, state.world.province_get_nation_from_province_control(prv)) == role) {
4294+
if(does_province_count_for_war_occupation(state, war, prv)) {
42644295
++occupied;
42654296
}
42664297
});
@@ -4398,7 +4429,7 @@ float primary_warscore_from_occupation(sys::state& state, dcon::war_id w) {
43984429
for(auto prv : state.world.nation_get_province_ownership(pattacker)) {
43994430
auto v = province_point_cost(state, prv.get_province(), pattacker);
44004431
sum_attacker_prov_values += v;
4401-
if(get_role(state, w, prv.get_province().get_nation_from_province_control()) == war_role::defender)
4432+
if(does_province_count_for_war_occupation(state, w, prv.get_province()))
44024433
sum_attacker_occupied_values += v;
44034434
}
44044435

@@ -4407,7 +4438,7 @@ float primary_warscore_from_occupation(sys::state& state, dcon::war_id w) {
44074438
for(auto prv : state.world.nation_get_province_ownership(pdefender)) {
44084439
auto v = province_point_cost(state, prv.get_province(), pdefender);
44094440
sum_defender_prov_values += v;
4410-
if(get_role(state, w, prv.get_province().get_nation_from_province_control()) == war_role::attacker)
4441+
if(does_province_count_for_war_occupation(state, w, prv.get_province()))
44114442
sum_defender_occupied_values += v;
44124443
}
44134444

@@ -4436,100 +4467,108 @@ float primary_warscore_from_war_goals(sys::state& state, dcon::war_id w) {
44364467
return total;
44374468
}
44384469

4439-
float directed_warscore(sys::state& state, dcon::war_id w, dcon::nation_id primary, dcon::nation_id secondary) {
4470+
float directed_warscore(
4471+
sys::state& state,
4472+
dcon::war_id w,
4473+
dcon::nation_id potential_beneficiary,
4474+
dcon::nation_id target
4475+
) {
44404476
float total = 0.0f;
44414477

4442-
auto is_pattacker = state.world.war_get_primary_attacker(w) == primary;
4443-
auto is_pdefender = state.world.war_get_primary_defender(w) == primary;
4478+
auto beneficiary_is_primary_attacker = state.world.war_get_primary_attacker(w) == potential_beneficiary;
4479+
auto beneficiary_is_primary_defender = state.world.war_get_primary_defender(w) == potential_beneficiary;
4480+
4481+
auto beneficiary_is_war_leader = beneficiary_is_primary_attacker || beneficiary_is_primary_defender;
4482+
4483+
auto target_is_primary_attacker = state.world.war_get_primary_attacker(w) == target;
4484+
auto target_is_primary_defender = state.world.war_get_primary_defender(w) == target;
44444485

4445-
auto is_tpattacker = state.world.war_get_primary_attacker(w) == secondary;
4446-
auto is_tpdefender = state.world.war_get_primary_defender(w) == secondary;
4486+
auto target_is_war_leader = target_is_primary_attacker || target_is_primary_defender;
44474487

4448-
if(is_pattacker && is_tpdefender)
4488+
if(beneficiary_is_primary_attacker && target_is_primary_defender)
44494489
return primary_warscore(state, w);
4450-
if(is_pdefender && is_tpattacker)
4490+
if(target_is_primary_attacker && beneficiary_is_primary_defender)
44514491
return -primary_warscore(state, w);
44524492

4453-
int32_t sum_attacker_prov_values = 0;
4454-
int32_t sum_attacker_occupied_values = 0;
4455-
for(auto prv : state.world.nation_get_province_ownership(primary)) {
4456-
auto v = province_point_cost(state, prv.get_province(), primary);
4457-
sum_attacker_prov_values += v;
4493+
int32_t beneficiary_score_from_occupation = 0;
4494+
int32_t beneficiary_potential_score_from_occupation = 0;
4495+
for(auto prv : state.world.nation_get_province_ownership(target)) {
4496+
auto v = province_point_cost(state, prv.get_province(), target);
4497+
beneficiary_potential_score_from_occupation += v;
44584498

4459-
if(is_tpattacker) {
4460-
if(get_role(state, w, prv.get_province().get_nation_from_province_control()) == war_role::attacker)
4461-
sum_attacker_occupied_values += v;
4462-
} else if(is_tpdefender) {
4463-
if(get_role(state, w, prv.get_province().get_nation_from_province_control()) == war_role::defender)
4464-
sum_attacker_occupied_values += v;
4499+
if(beneficiary_is_primary_attacker || beneficiary_is_primary_defender) {
4500+
if(does_province_count_for_war_occupation(state, w, prv.get_province()))
4501+
beneficiary_score_from_occupation += v;
44654502
} else {
4466-
if(prv.get_province().get_nation_from_province_control() == secondary)
4467-
sum_attacker_occupied_values += v;
4503+
if(prv.get_province().get_nation_from_province_control() == potential_beneficiary)
4504+
beneficiary_score_from_occupation += v;
44684505
}
44694506
}
44704507

4471-
int32_t sum_defender_prov_values = 0;
4472-
int32_t sum_defender_occupied_values = 0;
4473-
for(auto prv : state.world.nation_get_province_ownership(secondary)) {
4474-
auto v = province_point_cost(state, prv.get_province(), secondary);
4475-
sum_defender_prov_values += v;
4508+
int32_t against_beneficiary_score_from_occupation = 0;
4509+
int32_t against_beneficiary_potential_score_from_occupation = 0;
4510+
for(auto prv : state.world.nation_get_province_ownership(potential_beneficiary)) {
4511+
auto v = province_point_cost(state, prv.get_province(), potential_beneficiary);
4512+
against_beneficiary_potential_score_from_occupation += v;
44764513

4477-
if(is_pattacker) {
4478-
if(get_role(state, w, prv.get_province().get_nation_from_province_control()) == war_role::attacker)
4479-
sum_defender_occupied_values += v;
4480-
} else if(is_pdefender) {
4481-
if(get_role(state, w, prv.get_province().get_nation_from_province_control()) == war_role::defender)
4482-
sum_defender_occupied_values += v;
4483-
} else {
4484-
if(prv.get_province().get_nation_from_province_control() == primary)
4485-
sum_defender_occupied_values += v;
4486-
}
4514+
if(does_province_count_for_war_occupation(state, w, prv.get_province()))
4515+
against_beneficiary_score_from_occupation += v;
44874516
}
44884517

4489-
if(sum_defender_prov_values > 0)
4490-
total += (float(sum_defender_occupied_values) * 100.0f) / float(sum_defender_prov_values);
4491-
if(sum_attacker_prov_values > 0)
4492-
total -= (float(sum_attacker_occupied_values) * 100.0f) / float(sum_attacker_prov_values);
4518+
if(beneficiary_potential_score_from_occupation > 0)
4519+
total +=
4520+
(float(beneficiary_score_from_occupation) * 100.0f)
4521+
/ float(beneficiary_potential_score_from_occupation);
4522+
4523+
if(against_beneficiary_potential_score_from_occupation > 0)
4524+
total -=
4525+
(float(against_beneficiary_score_from_occupation) * 100.0f)
4526+
/ float(against_beneficiary_potential_score_from_occupation);
44934527

44944528
for(auto wg : state.world.war_get_wargoals_attached(w)) {
4495-
if((wg.get_wargoal().get_added_by() == primary || is_pattacker || is_pdefender)
4496-
&& wg.get_wargoal().get_target_nation() == secondary) {
4529+
auto wargoal_is_added_by_beneficiary = wg.get_wargoal().get_added_by() == potential_beneficiary;
4530+
auto wargoal_is_added_by_target = wg.get_wargoal().get_added_by() == target;
4531+
auto wargoal_targets_beneficiary = wg.get_wargoal().get_target_nation() == potential_beneficiary;
4532+
auto wargoal_targets_target = wg.get_wargoal().get_target_nation() == target;
44974533

4534+
if(
4535+
(wargoal_is_added_by_beneficiary || beneficiary_is_war_leader) && wargoal_targets_target
4536+
) {
44984537
total += wg.get_wargoal().get_ticking_war_score();
4499-
} else if(wg.get_wargoal().get_added_by() == secondary
4500-
&& (wg.get_wargoal().get_target_nation() == primary || is_pattacker || is_pdefender)) {
4501-
4538+
} else if(
4539+
wargoal_is_added_by_target && (wargoal_targets_beneficiary || beneficiary_is_war_leader)
4540+
) {
45024541
total -= wg.get_wargoal().get_ticking_war_score();
4503-
} else if(wg.get_wargoal().get_added_by() == primary
4504-
&& (wg.get_wargoal().get_target_nation() == secondary || is_tpattacker || is_tpdefender)) {
4505-
4542+
} else if(
4543+
wargoal_is_added_by_beneficiary && (wargoal_targets_target || target_is_war_leader)
4544+
) {
45064545
total += wg.get_wargoal().get_ticking_war_score();
4507-
} else if((wg.get_wargoal().get_added_by() == secondary || is_tpattacker || is_tpdefender)
4508-
&& (wg.get_wargoal().get_target_nation() == primary)) {
4509-
4546+
} else if(
4547+
(wargoal_is_added_by_target || target_is_war_leader) && wargoal_targets_beneficiary
4548+
) {
45104549
total -= wg.get_wargoal().get_ticking_war_score();
45114550
}
45124551
}
45134552

4514-
auto d_cpc = state.world.nation_get_central_ports(secondary);
4553+
auto d_cpc = state.world.nation_get_central_ports(target);
45154554
int32_t d_blockaded_in_war = 0;
4516-
for(auto p : state.world.nation_get_province_ownership(secondary)) {
4555+
for(auto p : state.world.nation_get_province_ownership(target)) {
45174556
if(military::province_is_blockaded(state, p.get_province()) && !province::is_overseas(state, p.get_province().id)) {
45184557
for(auto v : state.world.province_get_navy_location(p.get_province().get_port_to())) {
45194558
if(!v.get_navy().get_is_retreating() && !v.get_navy().get_battle_from_navy_battle_participation()) {
45204559

4521-
if(is_pattacker) {
4560+
if(beneficiary_is_primary_attacker) {
45224561
if(get_role(state, w, v.get_navy().get_controller_from_navy_control()) == war_role::attacker) {
45234562
++d_blockaded_in_war;
45244563
break; // out of inner loop
45254564
}
4526-
} else if(is_pdefender) {
4565+
} else if(beneficiary_is_primary_defender) {
45274566
if(get_role(state, w, v.get_navy().get_controller_from_navy_control()) == war_role::defender) {
45284567
++d_blockaded_in_war;
45294568
break; // out of inner loop
45304569
}
45314570
} else {
4532-
if(v.get_navy().get_controller_from_navy_control() == primary) {
4571+
if(v.get_navy().get_controller_from_navy_control() == potential_beneficiary) {
45334572
++d_blockaded_in_war;
45344573
break; // out of inner loop
45354574
}
@@ -4541,22 +4580,22 @@ float directed_warscore(sys::state& state, dcon::war_id w, dcon::nation_id prima
45414580
auto def_b_frac = std::clamp(d_cpc > 0 ? float(d_blockaded_in_war) / float(d_cpc) : 0.0f, 0.0f, 1.0f);
45424581

45434582
int32_t a_blockaded_in_war = 0;
4544-
for(auto p : state.world.nation_get_province_ownership(primary)) {
4583+
for(auto p : state.world.nation_get_province_ownership(potential_beneficiary)) {
45454584
if(military::province_is_blockaded(state, p.get_province()) && !province::is_overseas(state, p.get_province().id)) {
45464585
for(auto v : state.world.province_get_navy_location(p.get_province().get_port_to())) {
45474586
if(!v.get_navy().get_is_retreating() && !v.get_navy().get_battle_from_navy_battle_participation()) {
4548-
if(is_tpattacker) {
4587+
if(target_is_primary_attacker) {
45494588
if(get_role(state, w, v.get_navy().get_controller_from_navy_control()) == war_role::attacker) {
45504589
++a_blockaded_in_war;
45514590
break; // out of inner loop
45524591
}
4553-
} else if(is_tpdefender) {
4592+
} else if(target_is_primary_defender) {
45544593
if(get_role(state, w, v.get_navy().get_controller_from_navy_control()) == war_role::defender) {
45554594
++a_blockaded_in_war;
45564595
break; // out of inner loop
45574596
}
45584597
} else {
4559-
if(v.get_navy().get_controller_from_navy_control() == secondary) {
4598+
if(v.get_navy().get_controller_from_navy_control() == target) {
45604599
++a_blockaded_in_war;
45614600
break; // out of inner loop
45624601
}
@@ -4565,7 +4604,7 @@ float directed_warscore(sys::state& state, dcon::war_id w, dcon::nation_id prima
45654604
}
45664605
}
45674606
}
4568-
auto a_cpc = state.world.nation_get_central_ports(primary);
4607+
auto a_cpc = state.world.nation_get_central_ports(potential_beneficiary);
45694608
auto att_b_frac = std::clamp(a_cpc > 0 ? float(a_blockaded_in_war) / float(a_cpc) : 0.0f, 0.0f, 1.0f);
45704609

45714610
total += 25.0f * (def_b_frac - att_b_frac);

0 commit comments

Comments
 (0)