@@ -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