1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Being less dismissive

Reduced the amount of circumstances under which the AI dismisses heroes. Among others to prevent a loop through all passes where it repeatedly hires and dismisses heroes.
This commit is contained in:
Xilmi
2024-10-01 17:20:54 +02:00
parent 3d9892f6b3
commit f2b8b40925
3 changed files with 9 additions and 17 deletions

View File

@@ -284,7 +284,7 @@ const CGHeroInstance * HeroManager::findHeroWithGrail() const
return nullptr; return nullptr;
} }
const CGHeroInstance * HeroManager::findWeakHeroToDismiss(uint64_t armyLimit) const const CGHeroInstance * HeroManager::findWeakHeroToDismiss(uint64_t armyLimit, const CGTownInstance* townToSpare) const
{ {
const CGHeroInstance * weakestHero = nullptr; const CGHeroInstance * weakestHero = nullptr;
auto myHeroes = ai->cb->getHeroesInfo(); auto myHeroes = ai->cb->getHeroesInfo();
@@ -295,6 +295,7 @@ const CGHeroInstance * HeroManager::findWeakHeroToDismiss(uint64_t armyLimit) co
|| existingHero->getArmyStrength() >armyLimit || existingHero->getArmyStrength() >armyLimit
|| getHeroRole(existingHero) == HeroRole::MAIN || getHeroRole(existingHero) == HeroRole::MAIN
|| existingHero->movementPointsRemaining() || existingHero->movementPointsRemaining()
|| (townToSpare != nullptr && existingHero->visitedTown == townToSpare)
|| existingHero->artifactsWorn.size() > (existingHero->hasSpellbook() ? 2 : 1)) || existingHero->artifactsWorn.size() > (existingHero->hasSpellbook() ? 2 : 1))
{ {
continue; continue;

View File

@@ -58,7 +58,7 @@ public:
bool canRecruitHero(const CGTownInstance * t = nullptr) const; bool canRecruitHero(const CGTownInstance * t = nullptr) const;
bool heroCapReached(bool includeGarrisoned = true) const; bool heroCapReached(bool includeGarrisoned = true) const;
const CGHeroInstance * findHeroWithGrail() const; const CGHeroInstance * findHeroWithGrail() const;
const CGHeroInstance * findWeakHeroToDismiss(uint64_t armyLimit) const; const CGHeroInstance * findWeakHeroToDismiss(uint64_t armyLimit, const CGTownInstance * townToSpare = nullptr) const;
float getMagicStrength(const CGHeroInstance * hero) const; float getMagicStrength(const CGHeroInstance * hero) const;
float getFightingStrengthCached(const CGHeroInstance * hero) const; float getFightingStrengthCached(const CGHeroInstance * hero) const;

View File

@@ -354,21 +354,12 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
{ {
if(town->garrisonHero && town->garrisonHero != path.targetHero) if(town->garrisonHero && town->garrisonHero != path.targetHero)
{ {
if(ai->heroManager->getHeroRole(town->visitingHero.get()) == HeroRole::SCOUT
&& town->visitingHero->getArmyStrength() < path.heroArmy->getArmyStrength() / 20)
{
if(path.turn() == 0)
sequence.push_back(sptr(DismissHero(town->visitingHero.get())));
}
else
{
#if NKAI_TRACE_LEVEL >= 1 #if NKAI_TRACE_LEVEL >= 1
logAi->trace("Cancel moving %s to defend town %s as the town has garrison hero", logAi->trace("Cancel moving %s to defend town %s as the town has garrison hero",
path.targetHero->getObjectName(), path.targetHero->getObjectName(),
town->getObjectName()); town->getObjectName());
#endif #endif
continue; continue;
}
} }
else if(path.turn() == 0) else if(path.turn() == 0)
{ {
@@ -414,7 +405,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitMapInfo & threat, const CGTownInstance * town, const Nullkiller * ai) const void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitMapInfo & threat, const CGTownInstance * town, const Nullkiller * ai) const
{ {
if (threat.turn > 0) if (threat.turn > 0 || town->garrisonHero || town->visitingHero)
return; return;
if(town->hasBuilt(BuildingID::TAVERN) if(town->hasBuilt(BuildingID::TAVERN)
@@ -463,7 +454,7 @@ void DefenceBehavior::evaluateRecruitingHero(Goals::TGoalVec & tasks, const HitM
} }
else if(ai->heroManager->heroCapReached()) else if(ai->heroManager->heroCapReached())
{ {
heroToDismiss = ai->heroManager->findWeakHeroToDismiss(hero->getArmyStrength()); heroToDismiss = ai->heroManager->findWeakHeroToDismiss(hero->getArmyStrength(), town);
if(!heroToDismiss) if(!heroToDismiss)
continue; continue;