1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Battle AI: fix casting Implosion when it kills target stack, fix casting summon elementals

This commit is contained in:
Andrii Danylchenko 2024-08-26 11:30:39 +03:00
parent d55996cc46
commit ed36b1a882

View File

@ -630,7 +630,15 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
auto & ps = possibleCasts[i];
#if BATTLE_TRACE_LEVEL >= 1
logAi->trace("Evaluating %s", ps.spell->getNameTranslated());
if(ps.dest.empty())
logAi->trace("Evaluating %s", ps.spell->getNameTranslated());
else
{
auto psFirst = ps.dest.front();
auto strWhere = psFirst.unitValue ? psFirst.unitValue->getDescription() : std::to_string(psFirst.hexValue.hex);
logAi->trace("Evaluating %s at %s", ps.spell->getNameTranslated(), strWhere);
}
#endif
auto state = std::make_shared<HypotheticBattle>(env.get(), cb->getBattle(battleID));
@ -667,7 +675,7 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
innerEvaluator.updateReachabilityMap(state);
auto moveTarget = scoreEvaluator.findMoveTowardsUnreachable(activeStack, innerTargets, innerCache, state);
auto moveTarget = innerEvaluator.findMoveTowardsUnreachable(activeStack, innerTargets, innerCache, state);
if(!innerTargets.possibleAttacks.empty())
{
@ -682,12 +690,22 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
}
else
{
ps.value = scoreEvaluator.evaluateExchange(*cachedAttack.ap, cachedAttack.turn, *targets, innerCache, state);
auto updatedAttacker = state->getForUpdate(cachedAttack.ap->attack.attacker->unitId());
auto updatedDefender = state->getForUpdate(cachedAttack.ap->attack.defender->unitId());
auto updatedBai = BattleAttackInfo(
updatedAttacker.get(),
updatedDefender.get(),
cachedAttack.ap->attack.chargeDistance,
cachedAttack.ap->attack.shooting);
auto updatedAttack = AttackPossibility::evaluate(updatedBai, cachedAttack.ap->from, innerCache, state);
ps.value = scoreEvaluator.evaluateExchange(updatedAttack, cachedAttack.turn, *targets, innerCache, state);
}
for(const auto & unit : allUnits)
{
if(!unit->isValidTarget())
if(!unit->isValidTarget(true))
continue;
auto newHealth = unit->getAvailableHealth();
@ -710,13 +728,18 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
if(ourUnit * goodEffect == 1)
{
if(ourUnit && goodEffect && (unit->isClone() || unit->isGhost()))
auto isMagical = state->getForUpdate(unit->unitId())->summoned
|| unit->isClone()
|| unit->isGhost();
if(ourUnit && goodEffect && isMagical)
continue;
ps.value += dpsReduce * scoreEvaluator.getPositiveEffectMultiplier();
}
else
ps.value -= dpsReduce * scoreEvaluator.getNegativeEffectMultiplier();
// discourage AI making collateral damage with spells
ps.value -= 4 * dpsReduce * scoreEvaluator.getNegativeEffectMultiplier();
#if BATTLE_TRACE_LEVEL >= 1
logAi->trace(