From 9f4e92b5f609544bea5cb9e1f4f3b904ce11b8f5 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 4 Jan 2025 13:50:12 +0000 Subject: [PATCH] Fix computation of spell value when attacker can't reach enemies behind walls in siege combat --- AI/BattleAI/BattleEvaluator.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/AI/BattleAI/BattleEvaluator.cpp b/AI/BattleAI/BattleEvaluator.cpp index ddff6198e..33f31eb9c 100644 --- a/AI/BattleAI/BattleEvaluator.cpp +++ b/AI/BattleAI/BattleEvaluator.cpp @@ -720,6 +720,10 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack) state->makeWait(activeStack); } + float stackActionScore = 0; + float damageToHostilesScore = 0; + float damageToFriendliesScore = 0; + if(needFullEval || !cachedAttack.ap) { #if BATTLE_TRACE_LEVEL >= 1 @@ -737,11 +741,11 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack) { auto newStackAction = innerEvaluator.findBestTarget(activeStack, innerTargets, innerCache, state); - ps.value = std::max(moveTarget.score, newStackAction.score); + stackActionScore = std::max(moveTarget.score, newStackAction.score); } else { - ps.value = moveTarget.score; + stackActionScore = moveTarget.score; } } else @@ -756,7 +760,7 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack) auto updatedAttack = AttackPossibility::evaluate(updatedBai, cachedAttack.ap->from, innerCache, state); - ps.value = scoreEvaluator.evaluateExchange(updatedAttack, cachedAttack.turn, *targets, innerCache, state); + stackActionScore = scoreEvaluator.evaluateExchange(updatedAttack, cachedAttack.turn, *targets, innerCache, state); } for(const auto & unit : allUnits) { @@ -790,11 +794,11 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack) if(ourUnit && goodEffect && isMagical) continue; - ps.value += dpsReduce * scoreEvaluator.getPositiveEffectMultiplier(); + damageToHostilesScore += dpsReduce * scoreEvaluator.getPositiveEffectMultiplier(); } else // discourage AI making collateral damage with spells - ps.value -= 4 * dpsReduce * scoreEvaluator.getNegativeEffectMultiplier(); + damageToFriendliesScore -= 4 * dpsReduce * scoreEvaluator.getNegativeEffectMultiplier(); #if BATTLE_TRACE_LEVEL >= 1 // Ensure ps.dest is not empty before accessing the first element @@ -826,8 +830,17 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack) } } + if (vstd::isAlmostEqual(stackActionScore, static_cast(EvaluationResult::INEFFECTIVE_SCORE))) + { + ps.value = damageToFriendliesScore + damageToHostilesScore; + } + else + { + ps.value = stackActionScore + damageToFriendliesScore + damageToHostilesScore; + } + #if BATTLE_TRACE_LEVEL >= 1 - logAi->trace("Total score: %2f", ps.value); + logAi->trace("Total score for %s: %2f (action: %2f, friedly damage: %2f, hostile damage: %2f)", ps.spell->getJsonKey(), ps.value, stackActionScore, damageToFriendliesScore, damageToHostilesScore); #endif } #if BATTLE_TRACE_LEVEL == 0