|
@@ -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();
|
|
|
|