1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

NKAI: fix crash

This commit is contained in:
Andrii Danylchenko
2023-03-11 13:54:05 +02:00
parent 4bf570763a
commit fa9e1d2d83
3 changed files with 25 additions and 15 deletions

View File

@@ -182,8 +182,10 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
{ {
auto weakest = getWeakestCreature(resultingArmy); auto weakest = getWeakestCreature(resultingArmy);
if(weakest != resultingArmy.end() && weakest->count == 1) //we check iterator validity for playing with settings that allow 0 stacks armies if(weakest->count == 1)
{ {
assert(resultingArmy.size() > 1);
resultingArmy.erase(weakest); resultingArmy.erase(weakest);
} }
else else

View File

@@ -250,10 +250,13 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const CGTownInstance * upgrader)
auto upgrade = ai->nullkiller->armyManager->calculateCreaturesUpgrade(path.heroArmy, upgrader, availableResources); auto upgrade = ai->nullkiller->armyManager->calculateCreaturesUpgrade(path.heroArmy, upgrader, availableResources);
if(ai->nullkiller->heroManager->getHeroRole(path.targetHero) == HeroRole::MAIN) if(!upgrader->garrisonHero && ai->nullkiller->heroManager->getHeroRole(path.targetHero) == HeroRole::MAIN)
{ {
upgrade.upgradeValue += upgrade.upgradeValue +=
ai->nullkiller->armyManager->howManyReinforcementsCanGet(path.targetHero, path.heroArmy, upgrader); ai->nullkiller->armyManager->howManyReinforcementsCanGet(
path.targetHero,
path.heroArmy,
upgrader->getUpperArmy());
} }
auto armyValue = (float)upgrade.upgradeValue / path.getHeroStrength(); auto armyValue = (float)upgrade.upgradeValue / path.getHeroStrength();

View File

@@ -274,12 +274,12 @@ ExchangeResult HeroExchangeMap::tryExchangeNoLock(const ChainActor * other)
return result; return result;
} }
if(other->isMovable && other->armyValue <= actor->armyValue / 10 && other->armyValue < MIN_ARMY_STRENGTH_FOR_CHAIN) if(other->isMovable && other->armyValue <= actor->armyValue / 10 && other->armyValue < MIN_ARMY_STRENGTH_FOR_CHAIN)
return result; return result;
TResources availableResources = resources - actor->armyCost - other->armyCost; TResources availableResources = resources - actor->armyCost - other->armyCost;
HeroExchangeArmy * upgradedInitialArmy = tryUpgrade(actor->creatureSet, other->getActorObject(), availableResources); HeroExchangeArmy * upgradedInitialArmy = tryUpgrade(actor->creatureSet, other->getActorObject(), availableResources);
HeroExchangeArmy * newArmy; HeroExchangeArmy * newArmy;
if(other->creatureSet->Slots().size()) if(other->creatureSet->Slots().size())
{ {
@@ -303,20 +303,25 @@ ExchangeResult HeroExchangeMap::tryExchangeNoLock(const ChainActor * other)
if(!newArmy) return result; if(!newArmy) return result;
auto reinforcement = newArmy->getArmyStrength() - actor->creatureSet->getArmyStrength(); auto newArmyStrength = newArmy->getArmyStrength();
auto oldArmyStrength = actor->creatureSet->getArmyStrength();
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2 if(newArmyStrength <= oldArmyStrength) return result;
auto reinforcement = newArmyStrength - oldArmyStrength;
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
logAi->trace( logAi->trace(
"Exchange %s->%s reinforcement: %d, %f%%", "Exchange %s->%s reinforcement: %d, %f%%",
actor->toString(), actor->toString(),
other->toString(), other->toString(),
reinforcement, reinforcement,
100.0f * reinforcement / actor->armyValue); 100.0f * reinforcement / actor->armyValue);
#endif #endif
if(reinforcement <= actor->armyValue / 10 && reinforcement < MIN_ARMY_STRENGTH_FOR_CHAIN) if(reinforcement <= actor->armyValue / 10 && reinforcement < MIN_ARMY_STRENGTH_FOR_CHAIN)
{ {
delete newArmy; delete newArmy;
return result; return result;
} }
@@ -365,7 +370,7 @@ HeroExchangeArmy * HeroExchangeMap::tryUpgrade(
{ {
auto buyArmy = ai->armyManager->getArmyAvailableToBuy(target, ai->cb->getTown(upgrader->id), resources); auto buyArmy = ai->armyManager->getArmyAvailableToBuy(target, ai->cb->getTown(upgrader->id), resources);
for(auto creatureToBuy : buyArmy) for(auto & creatureToBuy : buyArmy)
{ {
auto targetSlot = target->getSlotFor(creatureToBuy.cre); auto targetSlot = target->getSlotFor(creatureToBuy.cre);