Skip to content

Commit ad3a474

Browse files
authored
Merge pull request #1984 from SneakBug8/feature/unit-upgrades
Regiment & ship construction time application
2 parents 45e6d71 + fcb2bca commit ad3a474

File tree

8 files changed

+99
-27
lines changed

8 files changed

+99
-27
lines changed

docs/features/regiment-recruitment.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# US1. Regiment recruitment
2+
3+
**As a Nation,**
4+
**I want to recruit a regiment,**
5+
**So that it appears in my army.**
6+
7+
**Acceptance Criteria:**
8+
| AC1 | Regiment of a particular type is recruited in a province by a nation |
9+
| AC2 | Regiment can be recruited only if one of the province pops allow new recruitment |
10+
| AC3 | Regiment of a type can be recruited only if that type is available to the nation |
11+
| AC4 | Regiment recruitment finishes when all goods for the recruitment have been purchased and consumed by the construction |
12+
| AC5 | Regiment recruitment cannot be finished faster than unit construction time |
13+
| AC7 | When several regiment constructions happen in a province simultaneously, they all progress simultaneously |
14+
15+
**Definition of Done:**
16+
- [X] All acceptance criteria are met.
17+
- [X] Code is reviewed and approved.
18+
- [ ] Necessary tests are written and pass.
19+
- [X] Documentation is updated, if applicable.
20+
- [x] Feature is available in release versions of PA.

docs/features/ship-construction.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# US2. Ship construction
2+
3+
**As a Nation,**
4+
**I want to construct a ship,**
5+
**So that it appears in my navy.**
6+
7+
**Acceptance Criteria:**
8+
| AC1 | Ship of a particular type is recruited in a province by a nation |
9+
| AC2 | Ship can be recruited only in coastal provinces |
10+
| AC3 | Ship of a type can be recruited only if that type is available to the nation |
11+
| AC4 | Ship recruitment finishes when all goods for the recruitment have been purchased and consumed by the construction |
12+
| AC5 | Ship recruitment cannot be finished faster than unit construction time |
13+
| AC6 | Big ships can be recruited only in provinces with appropriate naval base level |
14+
| AC7 | When several ship constructions happen in a province simultaneously, they progress one at a time |
15+
16+
**Definition of Done:**
17+
- [X] All acceptance criteria are met.
18+
- [X] Code is reviewed and approved.
19+
- [ ] Necessary tests are written and pass.
20+
- [X] Documentation is updated, if applicable.
21+
- [x] Feature is available in release versions of PA.

src/ai/ai.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,7 @@ void build_ships(sys::state& state) {
537537
if((overseas_allowed || !province::is_overseas(state, owned_ports[j]))
538538
&& state.world.province_get_building_level(owned_ports[j], uint8_t(economy::province_building_type::naval_base)) >= level_req) {
539539
assert(command::can_start_naval_unit_construction(state, n, owned_ports[j], best_transport));
540-
auto c = fatten(state.world, state.world.try_create_province_naval_construction(owned_ports[j], n));
541-
c.set_type(best_transport);
540+
command::execute_start_naval_unit_construction(state, n, owned_ports[j], best_transport);
542541
constructing_fleet_cap += supply_pts;
543542
}
544543
}
@@ -551,8 +550,7 @@ void build_ships(sys::state& state) {
551550
if((overseas_allowed || !province::is_overseas(state, owned_ports[j]))
552551
&& state.world.province_get_building_level(owned_ports[j], uint8_t(economy::province_building_type::naval_base)) >= level_req) {
553552
assert(command::can_start_naval_unit_construction(state, n, owned_ports[j], best_transport));
554-
auto c = fatten(state.world, state.world.try_create_province_naval_construction(owned_ports[j], n));
555-
c.set_type(best_transport);
553+
command::execute_start_naval_unit_construction(state, n, owned_ports[j], best_transport);
556554
++num_transports;
557555
constructing_fleet_cap += supply_pts;
558556
}
@@ -577,8 +575,7 @@ void build_ships(sys::state& state) {
577575
if((overseas_allowed || !province::is_overseas(state, owned_ports[j]))
578576
&& state.world.province_get_building_level(owned_ports[j], uint8_t(economy::province_building_type::naval_base)) >= level_req) {
579577
assert(command::can_start_naval_unit_construction(state, n, owned_ports[j], best_light));
580-
auto c = fatten(state.world, state.world.try_create_province_naval_construction(owned_ports[j], n));
581-
c.set_type(best_light);
578+
command::execute_start_naval_unit_construction(state, n, owned_ports[j], best_light);
582579
free_small_points -= supply_pts;
583580
}
584581
}
@@ -592,8 +589,7 @@ void build_ships(sys::state& state) {
592589
if((overseas_allowed || !province::is_overseas(state, owned_ports[j]))
593590
&& state.world.province_get_building_level(owned_ports[j], uint8_t(economy::province_building_type::naval_base)) >= level_req) {
594591
assert(command::can_start_naval_unit_construction(state, n, owned_ports[j], best_big));
595-
auto c = fatten(state.world, state.world.try_create_province_naval_construction(owned_ports[j], n));
596-
c.set_type(best_big);
592+
command::execute_start_naval_unit_construction(state, n, owned_ports[j], best_big);
597593
free_big_points -= supply_pts;
598594
}
599595
}
@@ -2232,8 +2228,7 @@ void update_land_constructions(sys::state& state) {
22322228
while(num_to_make_local > 0 && num_to_build_nation > 0) {
22332229
auto t = decide_type(pop.get_pop().get_is_primary_or_accepted_culture());
22342230
assert(command::can_start_land_unit_construction(state, n, pop.get_province(), pop.get_pop().get_culture(), t));
2235-
auto c = fatten(state.world, state.world.try_create_province_land_construction(pop.get_pop().id, n));
2236-
c.set_type(t);
2231+
command::execute_start_land_unit_construction(state, n, pop.get_province(), pop.get_pop().get_culture(), t);
22372232
--num_to_make_local;
22382233
--num_to_build_nation;
22392234
}
@@ -2255,8 +2250,7 @@ void update_land_constructions(sys::state& state) {
22552250
while(num_to_make_local > 0 && num_to_build_nation > 0) {
22562251
auto t = decide_type(pop.get_pop().get_is_primary_or_accepted_culture());
22572252
assert(command::can_start_land_unit_construction(state, n, pop.get_province(), pop.get_pop().get_culture(), t));
2258-
auto c = fatten(state.world, state.world.try_create_province_land_construction(pop.get_pop().id, n));
2259-
c.set_type(t);
2253+
command::execute_start_land_unit_construction(state, n, pop.get_province(), pop.get_pop().get_culture(), t);
22602254
--num_to_make_local;
22612255
--num_to_build_nation;
22622256
}
@@ -2278,8 +2272,7 @@ void update_land_constructions(sys::state& state) {
22782272
while(num_to_make_local > 0 && num_to_build_nation > 0) {
22792273
auto t = decide_type(pop.get_pop().get_is_primary_or_accepted_culture());
22802274
assert(command::can_start_land_unit_construction(state, n, pop.get_province(), pop.get_pop().get_culture(), t));
2281-
auto c = fatten(state.world, state.world.try_create_province_land_construction(pop.get_pop().id, n));
2282-
c.set_type(t);
2275+
command::execute_start_land_unit_construction(state, n, pop.get_province(), pop.get_pop().get_culture(), t);
22832276
--num_to_make_local;
22842277
--num_to_build_nation;
22852278
}

src/economy/economy.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5087,7 +5087,10 @@ float unit_construction_progress(sys::state& state, dcon::province_land_construc
50875087
purchased += cgoods.commodity_amounts[i];
50885088
}
50895089

5090-
return total > 0.0f ? purchased / total : 0.0f;
5090+
auto construction_time = state.military_definitions.unit_base_definitions[state.world.province_land_construction_get_type(c)].build_time;
5091+
auto time_progress = (float) sys::days_difference(state.world.province_land_construction_get_start_date(c).to_ymd(state.start_date), state.current_date.to_ymd(state.start_date)) / (float) construction_time;
5092+
5093+
return std::min(time_progress, purchased / total);
50915094
}
50925095

50935096
float unit_construction_progress(sys::state& state, dcon::province_naval_construction_id c) {
@@ -5163,30 +5166,39 @@ void change_factory_type_in_province(sys::state& state, dcon::province_id p, dco
51635166
}
51645167

51655168
void resolve_constructions(sys::state& state) {
5166-
5169+
// US1. Regiment construction
5170+
// US1AC7.
51675171
for(auto c : state.world.in_province_land_construction) {
51685172
auto pop = state.world.province_land_construction_get_pop(c);
51695173
auto province = state.world.pop_get_province_from_pop_location(pop);
51705174
float cost_factor = economy::build_cost_multiplier(state, province, false);
51715175

51725176
auto& base_cost = state.military_definitions.unit_base_definitions[c.get_type()].build_cost;
51735177
auto& current_purchased = c.get_purchased_goods();
5174-
float construction_time = float(state.military_definitions.unit_base_definitions[c.get_type()].build_time);
5178+
auto construction_time = state.military_definitions.unit_base_definitions[c.get_type()].build_time;
51755179

5176-
bool all_finished = true;
5180+
// US1AC4. All goods costs must be built
5181+
bool ready_for_deployment = true;
51775182
if(!(c.get_nation().get_is_player_controlled() && state.cheat_data.instant_army)) {
5178-
for(uint32_t j = 0; j < commodity_set::set_size && all_finished; ++j) {
5183+
for(uint32_t j = 0; j < commodity_set::set_size && ready_for_deployment; ++j) {
51795184
if(base_cost.commodity_type[j]) {
51805185
if(current_purchased.commodity_amounts[j] < base_cost.commodity_amounts[j] * cost_factor) {
5181-
all_finished = false;
5186+
ready_for_deployment = false;
51825187
}
51835188
} else {
51845189
break;
51855190
}
51865191
}
51875192
}
51885193

5189-
if(all_finished) {
5194+
// US1AC5. But no faster than construction_time
5195+
if(!state.cheat_data.instant_army) {
5196+
if(state.current_date < c.get_start_date() + construction_time) {
5197+
ready_for_deployment = false;
5198+
}
5199+
}
5200+
5201+
if(ready_for_deployment) {
51905202
auto pop_location = c.get_pop().get_province_from_pop_location();
51915203

51925204
auto new_reg = military::create_new_regiment(state, c.get_nation(), c.get_type());
@@ -5212,6 +5224,8 @@ void resolve_constructions(sys::state& state) {
52125224
}
52135225
}
52145226

5227+
// US2 Ships construction
5228+
// US2AC7
52155229
province::for_each_land_province(state, [&](dcon::province_id p) {
52165230
auto rng = state.world.province_get_province_naval_construction(p);
52175231
if(rng.begin() != rng.end()) {
@@ -5222,22 +5236,30 @@ void resolve_constructions(sys::state& state) {
52225236

52235237
auto& base_cost = state.military_definitions.unit_base_definitions[c.get_type()].build_cost;
52245238
auto& current_purchased = c.get_purchased_goods();
5225-
float construction_time = float(state.military_definitions.unit_base_definitions[c.get_type()].build_time);
5239+
auto construction_time = state.military_definitions.unit_base_definitions[c.get_type()].build_time;
52265240

5227-
bool all_finished = true;
5241+
// US2AC4.
5242+
bool ready_for_deployment = true;
52285243
if(!(c.get_nation().get_is_player_controlled() && state.cheat_data.instant_navy)) {
5229-
for(uint32_t i = 0; i < commodity_set::set_size && all_finished; ++i) {
5244+
for(uint32_t i = 0; i < commodity_set::set_size && ready_for_deployment; ++i) {
52305245
if(base_cost.commodity_type[i]) {
52315246
if(current_purchased.commodity_amounts[i] < base_cost.commodity_amounts[i] * cost_factor) {
5232-
all_finished = false;
5247+
ready_for_deployment = false;
52335248
}
52345249
} else {
52355250
break;
52365251
}
52375252
}
52385253
}
52395254

5240-
if(all_finished) {
5255+
// US2AC5. But no faster than construction_time
5256+
if(!state.cheat_data.instant_army) {
5257+
if(state.current_date < c.get_start_date() + construction_time) {
5258+
ready_for_deployment = false;
5259+
}
5260+
}
5261+
5262+
if(ready_for_deployment) {
52415263
auto new_ship = military::create_new_ship(state, c.get_nation(), c.get_type());
52425264
auto a = fatten(state.world, state.world.create_navy());
52435265
a.set_controller_from_navy_control(c.get_nation());
@@ -5260,6 +5282,7 @@ void resolve_constructions(sys::state& state) {
52605282
}
52615283
});
52625284

5285+
// Construction of province buildings
52635286
for(auto c : state.world.in_province_building_construction) {
52645287
auto for_province = c.get_province();
52655288
float cost_factor = economy::build_cost_multiplier(state, for_province, c.get_is_pop_project());
@@ -5327,6 +5350,7 @@ void resolve_constructions(sys::state& state) {
53275350
}
53285351
}
53295352

5353+
// Construction of factories
53305354
for(auto c : state.world.in_factory_construction) {
53315355
auto n = state.world.factory_construction_get_nation(c);
53325356
auto type = state.world.factory_construction_get_type(c);

src/gamestate/commands.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,7 @@ bool can_start_naval_unit_construction(sys::state& state, dcon::nation_id source
784784
void execute_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province) {
785785
auto c = fatten(state.world, state.world.try_create_province_naval_construction(location, source));
786786
c.set_type(type);
787+
c.set_start_date(state.current_date);
787788
c.set_template_province(template_province);
788789
}
789790

@@ -833,6 +834,7 @@ void execute_start_land_unit_construction(sys::state& state, dcon::nation_id sou
833834
auto soldier = military::find_available_soldier(state, location, soldier_culture);
834835

835836
auto c = fatten(state.world, state.world.try_create_province_land_construction(soldier, source));
837+
c.set_start_date(state.current_date);
836838
c.set_type(type);
837839
c.set_template_province(template_province);
838840
}

src/gamestate/commands.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,9 +600,11 @@ bool can_cancel_factory_building_construction(sys::state& state, dcon::nation_id
600600

601601
void start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{});
602602
bool can_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{});
603+
void execute_start_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{});
603604

604605
void start_land_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::culture_id soldier_culture, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{});
605606
bool can_start_land_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::culture_id soldier_culture, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{});
607+
void execute_start_land_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::culture_id soldier_culture, dcon::unit_type_id type, dcon::province_id template_province = dcon::province_id{});
606608

607609
void cancel_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type);
608610
bool can_cancel_naval_unit_construction(sys::state& state, dcon::nation_id source, dcon::province_id location, dcon::unit_type_id type);

src/gamestate/dcon_generated.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4909,6 +4909,11 @@ relationship{
49094909
type{ province_id }
49104910
tag{ save }
49114911
}
4912+
property{
4913+
name{ start_date }
4914+
type{ sys::date }
4915+
tag{ save }
4916+
}
49124917
}
49134918

49144919
relationship{
@@ -4945,6 +4950,11 @@ relationship{
49454950
type{ province_id }
49464951
tag{ save }
49474952
}
4953+
property{
4954+
name{ start_date }
4955+
type{ sys::date }
4956+
tag{ save }
4957+
}
49484958
}
49494959

49504960
relationship{

src/military/military.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ bool will_have_shortages_building_unit(sys::state& state, dcon::nation_id n, dco
198198

199199
for(uint32_t i = 0; i < economy::commodity_set::set_size; ++i) {
200200
if(def.build_cost.commodity_type[i]) {
201-
if(m.get_demand_satisfaction(def.build_cost.commodity_type[i]) < 0.1f && m.get_demand(def.build_cost.commodity_type[i]) > 0.1f)
201+
if(m.get_demand_satisfaction(def.build_cost.commodity_type[i]) < 0.1f && m.get_demand(def.build_cost.commodity_type[i]) > 0.01f)
202202
lacking_input = true;
203203
} else {
204204
break;

0 commit comments

Comments
 (0)