mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-29 23:07:48 +02:00
NKAI: improve army gathering
This commit is contained in:
@@ -45,8 +45,7 @@ Goals::TGoalVec GatherArmyBehavior::decompose() const
|
||||
|
||||
for(const CGHeroInstance * hero : heroes)
|
||||
{
|
||||
if(ai->nullkiller->heroManager->getHeroRole(hero) == HeroRole::MAIN
|
||||
&& hero->getArmyStrength() >= 300)
|
||||
if(ai->nullkiller->heroManager->getHeroRole(hero) == HeroRole::MAIN)
|
||||
{
|
||||
vstd::concatenate(tasks, deliverArmyToHero(hero));
|
||||
}
|
||||
@@ -70,13 +69,6 @@ Goals::TGoalVec GatherArmyBehavior::deliverArmyToHero(const CGHeroInstance * her
|
||||
#if NKAI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Checking ways to gaher army for hero %s, %s", hero->getObjectName(), pos.toString());
|
||||
#endif
|
||||
if(ai->nullkiller->isHeroLocked(hero))
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Skipping locked hero %s, %s", hero->getObjectName(), pos.toString());
|
||||
#endif
|
||||
return tasks;
|
||||
}
|
||||
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(pos);
|
||||
|
||||
@@ -92,6 +84,14 @@ Goals::TGoalVec GatherArmyBehavior::deliverArmyToHero(const CGHeroInstance * her
|
||||
|
||||
if(path.containsHero(hero)) continue;
|
||||
|
||||
if(path.turn() == 0 && hero->inTownGarrison)
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Skipping garnisoned hero %s, %s", hero->getObjectName(), pos.toString());
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ai->nullkiller->dangerHitMap->enemyCanKillOurHeroesAlongThePath(path))
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
@@ -124,14 +124,32 @@ Goals::TGoalVec GatherArmyBehavior::deliverArmyToHero(const CGHeroInstance * her
|
||||
// avoid trying to move bigger army to the weaker one.
|
||||
if(armyValue > 1)
|
||||
{
|
||||
bool hasOtherMainInPath = false;
|
||||
|
||||
for(auto node : path.nodes)
|
||||
{
|
||||
if(!node.targetHero) continue;
|
||||
|
||||
auto heroRole = ai->nullkiller->heroManager->getHeroRole(node.targetHero);
|
||||
|
||||
if(heroRole == HeroRole::MAIN)
|
||||
{
|
||||
hasOtherMainInPath = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(hasOtherMainInPath)
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
logAi->trace("Army value is too large.");
|
||||
logAi->trace("Army value is too large.");
|
||||
#endif
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto danger = path.getTotalDanger();
|
||||
|
||||
auto isSafe = isSafeToVisit(hero, path.heroArmy, danger);
|
||||
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
@@ -194,7 +212,7 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const CGTownInstance * upgrader)
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
logAi->trace("Path found %s", path.toString());
|
||||
#endif
|
||||
if(upgrader->visitingHero != path.targetHero)
|
||||
if(upgrader->visitingHero && upgrader->visitingHero.get() != path.targetHero)
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
logAi->trace("Ignore path. Town has visiting hero.");
|
||||
@@ -219,7 +237,10 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const CGTownInstance * upgrader)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ai->nullkiller->dangerHitMap->enemyCanKillOurHeroesAlongThePath(path))
|
||||
auto heroRole = ai->nullkiller->heroManager->getHeroRole(path.targetHero);
|
||||
|
||||
if(heroRole == HeroRole::SCOUT
|
||||
&& ai->nullkiller->dangerHitMap->enemyCanKillOurHeroesAlongThePath(path))
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
logAi->trace("Ignore path. Target hero can be killed by enemy. Our power %lld", path.heroArmy->getArmyStrength());
|
||||
@@ -228,16 +249,22 @@ Goals::TGoalVec GatherArmyBehavior::upgradeArmy(const CGTownInstance * upgrader)
|
||||
}
|
||||
|
||||
auto upgrade = ai->nullkiller->armyManager->calculateCreaturesUpgrade(path.heroArmy, upgrader, availableResources);
|
||||
auto armyValue = (float)upgrade.upgradeValue / path.getHeroStrength();
|
||||
|
||||
if(ai->nullkiller->heroManager->getHeroRole(path.targetHero) == HeroRole::MAIN)
|
||||
{
|
||||
upgrade.upgradeValue +=
|
||||
ai->nullkiller->armyManager->howManyReinforcementsCanGet(path.targetHero, path.heroArmy, upgrader);
|
||||
upgrade.upgradeValue +=
|
||||
ai->nullkiller->armyManager->howManyReinforcementsCanGet(path.targetHero, path.heroArmy, upgrader);
|
||||
}
|
||||
|
||||
if(armyValue < 0.1f || upgrade.upgradeValue < 300) // avoid small upgrades
|
||||
auto armyValue = (float)upgrade.upgradeValue / path.getHeroStrength();
|
||||
|
||||
if(armyValue < 0.25f || upgrade.upgradeValue < 300) // avoid small upgrades
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
logAi->trace("Ignore path. Army value is too small (%f)", armyValue);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
auto danger = path.getTotalDanger();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user