Skip to content

Commit 53137ea

Browse files
committed
Share return warehouse check for surplus soldiers
1 parent dc98c7b commit 53137ea

1 file changed

Lines changed: 56 additions & 23 deletions

File tree

libs/s25main/buildings/nobMilitary.cpp

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -508,23 +508,34 @@ void nobMilitary::RegulateTroops()
508508

509509
is_regulating_troops = true;
510510

511+
GamePlayer& owner = world->GetPlayer(player);
512+
std::array<int, NUM_SOLDIER_RANKS> hasReturnWarehouseByRank;
513+
hasReturnWarehouseByRank.fill(-1);
514+
auto canReturnHome = [&](const nofPassiveSoldier& soldier) {
515+
const unsigned rank = soldier.GetRank();
516+
int& hasReturnWarehouse = hasReturnWarehouseByRank[rank];
517+
if(hasReturnWarehouse < 0)
518+
{
519+
hasReturnWarehouse =
520+
owner.FindWarehouse(*this, FW::AcceptsFigure(soldier.GetJobType()), true, false) ? 1 : 0;
521+
}
522+
return hasReturnWarehouse != 0;
523+
};
524+
511525
// This only has an effect if the military control addon is in use and the troop limits have been lowered.
512526
std::array<unsigned, NUM_SOLDIER_RANKS> counts = GetTotalSoldiersByRank();
513527
std::array<unsigned, NUM_SOLDIER_RANKS> lack;
514528
for(unsigned rank = 0; rank < NUM_SOLDIER_RANKS; rank++)
515529
{
516530
int excess = counts[rank] - troop_limits[rank];
517-
const bool rankHasReturnWarehouse =
518-
excess > 0
519-
&& world->GetPlayer(player).FindWarehouse(*this, FW::AcceptsFigure(SOLDIER_JOBS[rank]), true, false);
520531
if(excess > 0)
521532
{
522533
lack[rank] = 0;
523534

524535
std::vector<nofPassiveSoldier*> notNeededSoldiers;
525536
for(auto it = ordered_troops.begin(); excess && it != ordered_troops.end();)
526537
{
527-
if((*it)->GetRank() == rank && rankHasReturnWarehouse)
538+
if((*it)->GetRank() == rank && canReturnHome(**it))
528539
{
529540
notNeededSoldiers.push_back(*it);
530541
it = ordered_troops.erase(it);
@@ -541,11 +552,11 @@ void nobMilitary::RegulateTroops()
541552
// This bit is for ordering troops later
542553
lack[rank] = troop_limits[rank] - counts[rank];
543554
}
544-
if(excess > 0 && rankHasReturnWarehouse)
555+
if(excess > 0)
545556
{
546557
for(auto it = troops.begin(); excess && it != troops.end() && troops.size() > 1;)
547558
{
548-
if((*it)->GetRank() == rank)
559+
if((*it)->GetRank() == rank && canReturnHome(**it))
549560
{
550561
(*it)->LeaveBuilding();
551562
AddLeavingFigure(std::move(*it));
@@ -567,22 +578,35 @@ void nobMilitary::RegulateTroops()
567578
// Zuerst die bestellten Soldaten wegschicken
568579
// Weak ones first
569580
std::vector<nofPassiveSoldier*> notNeededSoldiers;
570-
GamePlayer& owner = world->GetPlayer(player);
571581
if(owner.GetMilitarySetting(1) > MILITARY_SETTINGS_SCALE[1] / 2)
572582
{
573-
for(auto it = ordered_troops.begin(); diff && !ordered_troops.empty(); ++diff)
583+
for(auto it = ordered_troops.begin(); diff && it != ordered_troops.end();)
574584
{
575-
notNeededSoldiers.push_back(*it);
576-
it = ordered_troops.erase(it);
585+
if(canReturnHome(**it))
586+
{
587+
notNeededSoldiers.push_back(*it);
588+
it = ordered_troops.erase(it);
589+
++diff;
590+
} else
591+
{
592+
++it;
593+
}
577594
}
578595
}
579596
// Strong ones first
580597
else
581598
{
582-
for(auto it = ordered_troops.rbegin(); diff && !ordered_troops.empty(); ++diff)
599+
for(auto it = ordered_troops.rbegin(); diff && it != ordered_troops.rend();)
583600
{
584-
notNeededSoldiers.push_back(*it);
585-
it = helpers::erase_reverse(ordered_troops, it);
601+
if(canReturnHome(**it))
602+
{
603+
notNeededSoldiers.push_back(*it);
604+
it = helpers::erase_reverse(ordered_troops, it);
605+
++diff;
606+
} else
607+
{
608+
++it;
609+
}
586610
}
587611
}
588612

@@ -592,32 +616,41 @@ void nobMilitary::RegulateTroops()
592616
notNeededSoldier->NotNeeded();
593617
}
594618

595-
// Nur rausschicken, wenn es einen Weg zu einem Lagerhaus gibt!
596-
if(owner.FindWarehouse(*this, FW::NoCondition(), true, false))
619+
// Dann den Rest (einer muss immer noch drinbleiben!)
620+
// erst die schwachen Soldaten raus
621+
if(owner.GetMilitarySetting(1) > MILITARY_SETTINGS_SCALE[1] / 2)
597622
{
598-
// Dann den Rest (einer muss immer noch drinbleiben!)
599-
// erst die schwachen Soldaten raus
600-
if(owner.GetMilitarySetting(1) > MILITARY_SETTINGS_SCALE[1] / 2)
623+
for(auto it = troops.begin(); diff && it != troops.end() && troops.size() > 1;)
601624
{
602-
for(auto it = troops.begin(); diff && troops.size() > 1; ++diff)
625+
if(canReturnHome(**it))
603626
{
604627
(*it)->LeaveBuilding();
605628
AddLeavingFigure(std::move(*it));
606629
it = troops.erase(it);
630+
++diff;
631+
} else
632+
{
633+
++it;
607634
}
608635
}
609-
// erst die starken Soldaten raus
610-
else
636+
}
637+
// erst die starken Soldaten raus
638+
else
639+
{
640+
for(auto it = troops.rbegin(); diff && it != troops.rend() && troops.size() > 1;)
611641
{
612-
for(auto it = troops.rbegin(); diff && troops.size() > 1; ++diff)
642+
if(canReturnHome(**it))
613643
{
614644
(*it)->LeaveBuilding();
615645
AddLeavingFigure(std::move(*it));
616646
it = helpers::erase_reverse(troops, it);
647+
++diff;
648+
} else
649+
{
650+
++it;
617651
}
618652
}
619653
}
620-
621654
} else if(diff > 0)
622655
{
623656
// Zu wenig Truppen

0 commit comments

Comments
 (0)