mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
NKAI: fix retreat logic
This commit is contained in:
@@ -734,8 +734,8 @@ boost::optional<BattleAction> CBattleAI::considerFleeingOrSurrendering()
|
||||
bs.canFlee = cb->battleCanFlee();
|
||||
bs.canSurrender = cb->battleCanSurrender(playerID);
|
||||
bs.ourSide = cb->battleGetMySide();
|
||||
bs.ourHero = cb->battleGetMyHero();
|
||||
bs.enemyHero = cb->battleGetFightingHero(!bs.ourSide);
|
||||
bs.ourHero = cb->battleGetMyHero();
|
||||
bs.enemyHero = nullptr;
|
||||
|
||||
for(auto stack : cb->battleGetAllStacks(false))
|
||||
{
|
||||
@@ -744,7 +744,10 @@ boost::optional<BattleAction> CBattleAI::considerFleeingOrSurrendering()
|
||||
if(stack->side == bs.ourSide)
|
||||
bs.ourStacks.push_back(stack);
|
||||
else
|
||||
{
|
||||
bs.enemyStacks.push_back(stack);
|
||||
bs.enemyHero = cb->battleGetOwnerHero(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -497,7 +497,8 @@ boost::optional<BattleAction> AIGateway::makeSurrenderRetreatDecision(
|
||||
|
||||
double fightRatio = battleState.getOurStrength() / (double)battleState.getEnemyStrength();
|
||||
|
||||
if(fightRatio < 0.3 && battleState.canFlee)
|
||||
// if we have no towns - things are already bad, so retreat is not an option.
|
||||
if(cb->getTownsInfo().size() && fightRatio < 0.3 && battleState.canFlee)
|
||||
{
|
||||
return BattleAction::makeRetreat(battleState.ourSide);
|
||||
}
|
||||
@@ -1035,8 +1036,10 @@ bool AIGateway::canRecruitAnyHero(const CGTownInstance * t) const
|
||||
//TODO: make gathering gold, building tavern or conquering town (?) possible subgoals
|
||||
if(!t)
|
||||
t = findTownWithTavern();
|
||||
if(!t)
|
||||
|
||||
if(!t || !townHasFreeTavern(t))
|
||||
return false;
|
||||
|
||||
if(cb->getResourceAmount(Res::GOLD) < GameConstants::HERO_GOLD_COST) //TODO: use ResourceManager
|
||||
return false;
|
||||
if(cb->getHeroesInfo().size() >= ALLOWED_ROAMING_HEROES)
|
||||
@@ -1401,7 +1404,7 @@ void AIGateway::tryRealize(Goals::Trade & g) //trade
|
||||
const CGTownInstance * AIGateway::findTownWithTavern() const
|
||||
{
|
||||
for(const CGTownInstance * t : cb->getTownsInfo())
|
||||
if(t->hasBuilt(BuildingID::TAVERN) && (!t->visitingHero || !t->garrisonHero))
|
||||
if(townHasFreeTavern(t))
|
||||
return t;
|
||||
|
||||
return nullptr;
|
||||
|
@@ -450,4 +450,14 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
|
||||
return true;
|
||||
}
|
||||
|
||||
bool townHasFreeTavern(const CGTownInstance * town)
|
||||
{
|
||||
if(!town->hasBuilt(BuildingID::TAVERN)) return false;
|
||||
if(!town->visitingHero) return true;
|
||||
|
||||
bool canMoveVisitingHeroToGarnison = !town->getUpperArmy()->stacksCount();
|
||||
|
||||
return canMoveVisitingHeroToGarnison;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -238,6 +238,7 @@ bool isSafeToVisit(HeroPtr h, const CCreatureSet *, uint64_t dangerStrength);
|
||||
bool compareHeroStrength(HeroPtr h1, HeroPtr h2);
|
||||
bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2);
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2);
|
||||
bool townHasFreeTavern(const CGTownInstance * town);
|
||||
|
||||
uint64_t timeElapsed(std::chrono::time_point<std::chrono::high_resolution_clock> start);
|
||||
|
||||
|
@@ -53,7 +53,7 @@ Goals::TGoalVec RecruitHeroBehavior::decompose() const
|
||||
|
||||
for(auto town : towns)
|
||||
{
|
||||
if((!town->garrisonHero || !town->visitingHero) && ai->canRecruitAnyHero(town))
|
||||
if(ai->canRecruitAnyHero(town))
|
||||
{
|
||||
auto availableHeroes = cb->getAvailableHeroes(town);
|
||||
|
||||
|
@@ -65,12 +65,12 @@ void RecruitHero::accept(AIGateway * ai)
|
||||
|
||||
if(t->visitingHero)
|
||||
{
|
||||
if(t->garrisonHero)
|
||||
throw cannotFulfillGoalException("Town " + t->nodeName() + " is occupied. Cannot recruit hero!");
|
||||
|
||||
cb->swapGarrisonHero(t);
|
||||
}
|
||||
|
||||
if(t->visitingHero)
|
||||
throw cannotFulfillGoalException("Town " + t->nodeName() + " is occupied. Cannot recruit hero!");
|
||||
|
||||
cb->recruitHero(t, heroToHire);
|
||||
ai->nullkiller->heroManager->update();
|
||||
|
||||
|
Reference in New Issue
Block a user