1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

Rework ballist and tower target acquisition

This commit is contained in:
Opuszek
2025-07-31 18:04:59 +02:00
parent 00e0173f18
commit 9f5b04c1b5

View File

@@ -451,28 +451,27 @@ bool BattleFlowProcessor::tryMakeAutomaticActionOfBallistaOrTowers(const CBattle
attack.side = next->unitSide();
attack.stackNumber = next->unitId();
// TODO: unify logic with AI?
// Find best target using logic similar to H3 AI
const auto & isBetterTarget = [&battle](const battle::Unit * candidate, const battle::Unit * current)
const auto & getAttackValue = [&battle, &next] (const battle::Unit * unit)
{
bool candidateInsideWalls = battle.battleIsInsideWalls(candidate->getPosition());
bool currentInsideWalls = battle.battleIsInsideWalls(current->getPosition());
float singleHpValue = static_cast<float>(unit->unitType()->getAIValue()) / static_cast<float>(unit->getMaxHealth());
if (candidateInsideWalls != currentInsideWalls)
return candidateInsideWalls > currentInsideWalls;
int distance = BattleHex::getDistance(next->getPosition(), unit->getPosition());
BattleAttackInfo attackInfo(next, unit, distance, true);
DamageEstimation estimation = battle.calculateDmgRange(attackInfo);
float avgDmg = (static_cast<float>(estimation.damage.max) + static_cast<float>(estimation.damage.min)) / 2;
// also check for war machines - shooters are more dangerous than war machines, ballista or catapult
bool candidateCanShoot = candidate->canShoot() && candidate->unitType()->warMachine == ArtifactID::NONE;
bool currentCanShoot = current->canShoot() && current->unitType()->warMachine == ArtifactID::NONE;
return avgDmg * singleHpValue;
};
if (candidateCanShoot != currentCanShoot)
return candidateCanShoot > currentCanShoot;
const auto & isBetterTarget = [&getAttackValue](const battle::Unit * candidate, const battle::Unit * current)
{
bool candidateIsParalyzed = candidate->hasBonusOfType(BonusType::NOT_ACTIVE);
bool currentIsParalyzed = current->hasBonusOfType(BonusType::NOT_ACTIVE);
int64_t candidateTargetValue = static_cast<int64_t>(candidate->unitType()->getAIValue() * candidate->getCount());
int64_t currentTargetValue = static_cast<int64_t>(current->unitType()->getAIValue() * current->getCount());
if (candidateIsParalyzed != currentIsParalyzed)
return currentIsParalyzed > candidateIsParalyzed;
return candidateTargetValue > currentTargetValue;
return getAttackValue(candidate) > getAttackValue(current);
};
const battle::Unit * target = nullptr;