Browse Source

make stupid AI not move to invincible unit and not do anything

kdmcser 1 month ago
parent
commit
9b588b8cd7
2 changed files with 29 additions and 10 deletions
  1. 28 10
      AI/StupidAI/StupidAI.cpp
  2. 1 0
      AI/StupidAI/StupidAI.h

+ 28 - 10
AI/StupidAI/StupidAI.cpp

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

+ 1 - 0
AI/StupidAI/StupidAI.h

@@ -51,5 +51,6 @@ public:
 
 private:
 	BattleAction goTowards(const BattleID & battleID, const CStack * stack, BattleHexArray hexes) const;
+	bool moveStackToClosestEnemy(const BattleID & battleID, const CStack * stack, const ReachabilityInfo & dists, const std::vector<EnemyInfo> & enemyInfos);
 };