Skip to content

Commit f3a34e5

Browse files
committed
Check warehouse acceptance before cancelling ordered troops
1 parent 37e4166 commit f3a34e5

2 files changed

Lines changed: 54 additions & 13 deletions

File tree

libs/s25main/buildings/nobMilitary.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -514,32 +514,38 @@ void nobMilitary::RegulateTroops()
514514
for(unsigned rank = 0; rank < NUM_SOLDIER_RANKS; rank++)
515515
{
516516
int excess = counts[rank] - troop_limits[rank];
517+
const bool canReturnHome =
518+
excess > 0
519+
&& world->GetPlayer(player).FindWarehouse(*this, FW::AcceptsFigure(SOLDIER_JOBS[rank]), true, false);
520+
517521
if(excess > 0)
518522
{
519523
lack[rank] = 0;
520524

521-
std::vector<nofPassiveSoldier*> notNeededSoldiers;
522-
for(auto it = ordered_troops.begin(); excess && it != ordered_troops.end();)
525+
if(canReturnHome)
523526
{
524-
if((*it)->GetRank() == rank)
525-
{
526-
notNeededSoldiers.push_back(*it);
527-
it = ordered_troops.erase(it);
528-
--excess;
529-
} else
527+
std::vector<nofPassiveSoldier*> notNeededSoldiers;
528+
for(auto it = ordered_troops.begin(); excess && it != ordered_troops.end();)
530529
{
531-
++it;
530+
if((*it)->GetRank() == rank)
531+
{
532+
notNeededSoldiers.push_back(*it);
533+
it = ordered_troops.erase(it);
534+
--excess;
535+
} else
536+
{
537+
++it;
538+
}
532539
}
540+
for(auto* notNeededSoldier : notNeededSoldiers)
541+
notNeededSoldier->NotNeeded();
533542
}
534-
for(auto* notNeededSoldier : notNeededSoldiers)
535-
notNeededSoldier->NotNeeded();
536543
} else
537544
{
538545
// This bit is for ordering troops later
539546
lack[rank] = troop_limits[rank] - counts[rank];
540547
}
541-
if(excess > 0
542-
&& world->GetPlayer(player).FindWarehouse(*this, FW::AcceptsFigure(SOLDIER_JOBS[rank]), true, false))
548+
if(excess > 0 && canReturnHome)
543549
{
544550
for(auto it = troops.begin(); excess && it != troops.end() && troops.size() > 1;)
545551
{

tests/s25Main/integration/testGameCommands.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,41 @@ BOOST_FIXTURE_TEST_CASE(SendSoldiersHomeTest, WorldWithGCExecution2P)
525525
BOOST_TEST_REQUIRE(itTroops->GetRank() == i);
526526
}
527527

528+
BOOST_FIXTURE_TEST_CASE(OrderedSoldierKeepsMilitaryGoalWhenReturnWarehouseRejectsRank, WorldWithGCExecution2P)
529+
{
530+
initGameRNG();
531+
532+
const MapPoint milPt = hqPos + MapPoint(4, 0);
533+
GamePlayer& player = world.GetPlayer(curPlayer);
534+
nobBaseWarehouse* wh = player.GetFirstWH();
535+
BOOST_TEST_REQUIRE(wh);
536+
BOOST_TEST_REQUIRE(wh->GetInventory().people[Job::General] == 0u);
537+
538+
wh->AddToInventory(PeopleCounts::make(Job::General, 1), true);
539+
540+
for(unsigned i = 0; i <= this->ggs.GetMaxMilitaryRank(); ++i)
541+
this->ChangeReserve(hqPos, i, 0);
542+
543+
this->ChangeMilitary(MILITARY_SETTINGS_SCALE);
544+
545+
auto* bld = dynamic_cast<nobMilitary*>(
546+
BuildingFactory::CreateBuilding(world, BuildingType::Watchtower, milPt, curPlayer, player.nation));
547+
BOOST_TEST_REQUIRE(bld);
548+
549+
this->BuildRoad(world.GetNeighbour(hqPos, Direction::SouthEast), false,
550+
std::vector<Direction>((milPt.x - hqPos.x), Direction::East));
551+
552+
RTTR_SKIP_GFS(40);
553+
BOOST_TEST_REQUIRE(wh->GetNumRealFigures(Job::General) == 0u);
554+
555+
this->SetInventorySetting(hqPos, Job::General, EInventorySetting::Stop);
556+
this->SetTroopLimit(milPt, getSoldierRank(Job::General), 0);
557+
558+
RTTR_EXEC_TILL(1000, bld->GetNumTroops() == 1u);
559+
BOOST_TEST_REQUIRE(bld->GetNumTroops() == 1u);
560+
BOOST_TEST_REQUIRE(bld->GetTroops().front().GetRank() == getSoldierRank(Job::General));
561+
BOOST_TEST_REQUIRE(bld->GetLeavingFigures().empty());
562+
}
528563
namespace {
529564
void FlagWorkerTest(WorldWithGCExecution2P& worldFixture, Job workerJob, GoodType toolType)
530565
{

0 commit comments

Comments
 (0)