@@ -508,6 +508,20 @@ 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;
@@ -521,7 +535,7 @@ void nobMilitary::RegulateTroops()
521535 std::vector<nofPassiveSoldier*> notNeededSoldiers;
522536 for (auto it = ordered_troops.begin (); excess && it != ordered_troops.end ();)
523537 {
524- if ((*it)->GetRank () == rank)
538+ if ((*it)->GetRank () == rank && canReturnHome (**it) )
525539 {
526540 notNeededSoldiers.push_back (*it);
527541 it = ordered_troops.erase (it);
@@ -538,12 +552,11 @@ void nobMilitary::RegulateTroops()
538552 // This bit is for ordering troops later
539553 lack[rank] = troop_limits[rank] - counts[rank];
540554 }
541- if (excess > 0
542- && world->GetPlayer (player).FindWarehouse (*this , FW::AcceptsFigure (SOLDIER_JOBS[rank]), true , false ))
555+ if (excess > 0 )
543556 {
544557 for (auto it = troops.begin (); excess && it != troops.end () && troops.size () > 1 ;)
545558 {
546- if ((*it)->GetRank () == rank)
559+ if ((*it)->GetRank () == rank && canReturnHome (**it) )
547560 {
548561 (*it)->LeaveBuilding ();
549562 AddLeavingFigure (std::move (*it));
@@ -565,22 +578,35 @@ void nobMilitary::RegulateTroops()
565578 // Zuerst die bestellten Soldaten wegschicken
566579 // Weak ones first
567580 std::vector<nofPassiveSoldier*> notNeededSoldiers;
568- GamePlayer& owner = world->GetPlayer (player);
569581 if (owner.GetMilitarySetting (1 ) > MILITARY_SETTINGS_SCALE[1 ] / 2 )
570582 {
571- for (auto it = ordered_troops.begin (); diff && ! ordered_troops.empty (); ++diff )
583+ for (auto it = ordered_troops.begin (); diff && it != ordered_troops.end ();)
572584 {
573- notNeededSoldiers.push_back (*it);
574- 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+ }
575594 }
576595 }
577596 // Strong ones first
578597 else
579598 {
580- for (auto it = ordered_troops.rbegin (); diff && ! ordered_troops.empty (); ++diff )
599+ for (auto it = ordered_troops.rbegin (); diff && it != ordered_troops.rend ();)
581600 {
582- notNeededSoldiers.push_back (*it);
583- 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+ }
584610 }
585611 }
586612
@@ -590,32 +616,41 @@ void nobMilitary::RegulateTroops()
590616 notNeededSoldier->NotNeeded ();
591617 }
592618
593- // Nur rausschicken, wenn es einen Weg zu einem Lagerhaus gibt!
594- 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 )
595622 {
596- // Dann den Rest (einer muss immer noch drinbleiben!)
597- // erst die schwachen Soldaten raus
598- if (owner.GetMilitarySetting (1 ) > MILITARY_SETTINGS_SCALE[1 ] / 2 )
623+ for (auto it = troops.begin (); diff && it != troops.end () && troops.size () > 1 ;)
599624 {
600- for ( auto it = troops. begin (); diff && troops. size () > 1 ; ++diff )
625+ if ( canReturnHome (**it) )
601626 {
602627 (*it)->LeaveBuilding ();
603628 AddLeavingFigure (std::move (*it));
604629 it = troops.erase (it);
630+ ++diff;
631+ } else
632+ {
633+ ++it;
605634 }
606635 }
607- // erst die starken Soldaten raus
608- else
636+ }
637+ // erst die starken Soldaten raus
638+ else
639+ {
640+ for (auto it = troops.rbegin (); diff && it != troops.rend () && troops.size () > 1 ;)
609641 {
610- for ( auto it = troops. rbegin (); diff && troops. size () > 1 ; ++diff )
642+ if ( canReturnHome (**it) )
611643 {
612644 (*it)->LeaveBuilding ();
613645 AddLeavingFigure (std::move (*it));
614646 it = helpers::erase_reverse (troops, it);
647+ ++diff;
648+ } else
649+ {
650+ ++it;
615651 }
616652 }
617653 }
618-
619654 } else if (diff > 0 )
620655 {
621656 // Zu wenig Truppen
0 commit comments