|
|
@@ -125,6 +125,7 @@ void CStupidAI::activeStack(const BattleID & battleID, const CStack * stack)
|
|
|
std::vector<EnemyInfo> enemiesShootable;
|
|
|
std::vector<EnemyInfo> enemiesReachable;
|
|
|
std::vector<EnemyInfo> enemiesUnreachable;
|
|
|
+ std::vector<EnemyInfo> enemiesInvincible;
|
|
|
|
|
|
if(stack->creatureId() == CreatureID::CATAPULT)
|
|
|
{
|
|
|
@@ -147,7 +148,11 @@ void CStupidAI::activeStack(const BattleID & battleID, const CStack * stack)
|
|
|
|
|
|
for (const CStack *s : cb->getBattle(battleID)->battleGetStacks(CBattleInfoEssentials::ONLY_ENEMY))
|
|
|
{
|
|
|
- if(cb->getBattle(battleID)->battleCanShoot(stack, s->getPosition()))
|
|
|
+ if (s->isInvincible())
|
|
|
+ {
|
|
|
+ enemiesInvincible.push_back(s);
|
|
|
+ }
|
|
|
+ else if(cb->getBattle(battleID)->battleCanShoot(stack, s->getPosition()))
|
|
|
{
|
|
|
enemiesShootable.push_back(s);
|
|
|
}
|
|
|
@@ -197,22 +202,35 @@ void CStupidAI::activeStack(const BattleID & battleID, const CStack * stack)
|
|
|
}
|
|
|
else if(enemiesUnreachable.size()) //due to #955 - a buggy battle may occur when there are no enemies
|
|
|
{
|
|
|
- auto closestEnemy = vstd::minElementByFun(enemiesUnreachable, [&](const EnemyInfo & ei) -> int
|
|
|
- {
|
|
|
- return dists.distToNearestNeighbour(stack, ei.s);
|
|
|
- });
|
|
|
-
|
|
|
- if(dists.distToNearestNeighbour(stack, closestEnemy->s) < GameConstants::BFIELD_SIZE)
|
|
|
- {
|
|
|
- cb->battleMakeUnitAction(battleID, goTowards(battleID, stack, closestEnemy->s->getAttackableHexes(stack)));
|
|
|
+ if(moveStackToClosestEnemy(battleID, stack, dists, enemiesUnreachable))
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if(enemiesInvincible.size())
|
|
|
+ {
|
|
|
+ if(moveStackToClosestEnemy(battleID, stack, dists, enemiesInvincible))
|
|
|
return;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
cb->battleMakeUnitAction(battleID, BattleAction::makeDefend(stack));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+bool CStupidAI::moveStackToClosestEnemy(const BattleID & battleID, const CStack * stack, const ReachabilityInfo & dists, const std::vector<EnemyInfo> &enemyInfos)
|
|
|
+{
|
|
|
+ auto closestEnemy = vstd::minElementByFun(enemyInfos,[&](const EnemyInfo & ei) -> int
|
|
|
+ {
|
|
|
+ return dists.distToNearestNeighbour(stack, ei.s);
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ if(dists.distToNearestNeighbour(stack, closestEnemy->s) < GameConstants::BFIELD_SIZE)
|
|
|
+ {
|
|
|
+ cb->battleMakeUnitAction(battleID, goTowards(battleID, stack, closestEnemy->s->getAttackableHexes(stack)));
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
void CStupidAI::battleAttack(const BattleID & battleID, const BattleAttack *ba)
|
|
|
{
|
|
|
print("battleAttack called");
|