1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

#3824 - fix empty army with only commander issues

This commit is contained in:
Andrii Danylchenko 2024-04-26 23:18:20 +03:00
parent 0fc17da164
commit 6e641dbdea
7 changed files with 41 additions and 5 deletions

View File

@ -911,6 +911,9 @@ void AIGateway::moveCreaturesToHero(const CGTownInstance * t)
void AIGateway::pickBestCreatures(const CArmedInstance * destinationArmy, const CArmedInstance * source)
{
if(source->stacksCount() == 0)
return;
const CArmedInstance * armies[] = {destinationArmy, source};
auto bestArmy = nullkiller->armyManager->getBestArmy(destinationArmy, destinationArmy, source);

View File

@ -439,4 +439,16 @@ bool townHasFreeTavern(const CGTownInstance * town)
return canMoveVisitingHeroToGarnison;
}
uint64_t getHeroArmyStrengthWithCommander(const CGHeroInstance * hero, const CCreatureSet * heroArmy)
{
auto armyStrength = heroArmy->getArmyStrength();
if(hero && hero->commander && hero->commander->alive)
{
armyStrength += 100 * hero->commander->level;
}
return armyStrength;
}
}

View File

@ -238,6 +238,8 @@ bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2);
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2);
bool townHasFreeTavern(const CGTownInstance * town);
uint64_t getHeroArmyStrengthWithCommander(const CGHeroInstance * hero, const CCreatureSet * heroArmy);
uint64_t timeElapsed(std::chrono::time_point<std::chrono::high_resolution_clock> start);
// todo: move to obj manager

View File

@ -136,6 +136,10 @@ public:
std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const
{
auto sortedSlots = getSortedSlots(target, source);
if(source->stacksCount() == 0)
return sortedSlots;
std::map<FactionID, uint64_t> alignmentMap;
for(auto & slot : sortedSlots)
@ -348,6 +352,11 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
ui64 ArmyManager::howManyReinforcementsCanGet(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const
{
if(source->stacksCount() == 0)
{
return 0;
}
auto bestArmy = getBestArmy(armyCarrier, target, source);
uint64_t newArmy = 0;
uint64_t oldArmy = target->getArmyStrength();

View File

@ -145,6 +145,12 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj)
return danger;
}
case Obj::HERO:
{
const CGHeroInstance * hero = dynamic_cast<const CGHeroInstance *>(obj);
return getHeroArmyStrengthWithCommander(hero, hero);
}
case Obj::ARTIFACT:
case Obj::RESOURCE:
{
@ -153,7 +159,6 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj)
[[fallthrough]];
}
case Obj::MONSTER:
case Obj::HERO:
case Obj::GARRISON:
case Obj::GARRISON2:
case Obj::CREATURE_GENERATOR1:

View File

@ -1354,7 +1354,12 @@ void AINodeStorage::calculateChainInfo(std::vector<AIPath> & paths, const int3 &
path.heroArmy = node.actor->creatureSet;
path.armyLoss = node.armyLoss;
path.targetObjectDanger = evaluateDanger(pos, path.targetHero, !node.actor->allowBattle);
path.targetObjectArmyLoss = evaluateArmyLoss(path.targetHero, path.heroArmy->getArmyStrength(), path.targetObjectDanger);
path.targetObjectArmyLoss = evaluateArmyLoss(
path.targetHero,
getHeroArmyStrengthWithCommander(path.targetHero, path.heroArmy),
path.targetObjectDanger);
path.chainMask = node.actor->chainMask;
path.exchangeCount = node.actor->actorExchangeCount;
@ -1473,7 +1478,7 @@ uint8_t AIPath::turn() const
uint64_t AIPath::getHeroStrength() const
{
return targetHero->getFightingStrength() * heroArmy->getArmyStrength();
return targetHero->getFightingStrength() * getHeroArmyStrengthWithCommander(targetHero, heroArmy);
}
uint64_t AIPath::getTotalDanger() const

View File

@ -45,7 +45,7 @@ ChainActor::ChainActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t
layer = hero->boat ? hero->boat->layer : EPathfindingLayer::LAND;
initialMovement = hero->movementPointsRemaining();
initialTurn = 0;
armyValue = hero->getArmyStrength();
armyValue = getHeroArmyStrengthWithCommander(hero, hero);
heroFightingStrength = hero->getFightingStrength();
tiCache.reset(new TurnInfo(hero));
}
@ -55,7 +55,7 @@ ChainActor::ChainActor(const ChainActor * carrier, const ChainActor * other, con
baseActor(this), carrierParent(carrier), otherParent(other), heroFightingStrength(carrier->heroFightingStrength),
actorExchangeCount(carrier->actorExchangeCount + other->actorExchangeCount), armyCost(carrier->armyCost + other->armyCost), actorAction()
{
armyValue = heroArmy->getArmyStrength();
armyValue = getHeroArmyStrengthWithCommander(hero, heroArmy);
}
ChainActor::ChainActor(const CGObjectInstance * obj, const CCreatureSet * creatureSet, uint64_t chainMask, int initialTurn)