mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
BattleAI: fix ap calculation in exchange variant
This commit is contained in:
parent
3d856bfa9d
commit
801e919e7e
@ -317,41 +317,42 @@ AttackPossibility AttackPossibility::evaluate(
|
||||
auto defenderState = defenderStates.at(u->unitId());
|
||||
|
||||
int64_t damageDealt;
|
||||
int64_t damageReceived;
|
||||
float defenderDamageReduce;
|
||||
float attackerDamageReduce;
|
||||
|
||||
DamageEstimation retaliation;
|
||||
auto attackDmg = state->battleEstimateDamage(ap.attack, &retaliation);
|
||||
|
||||
vstd::amin(attackDmg.damage.min, defenderState->getAvailableHealth());
|
||||
vstd::amin(attackDmg.damage.max, defenderState->getAvailableHealth());
|
||||
|
||||
vstd::amin(retaliation.damage.min, ap.attackerState->getAvailableHealth());
|
||||
vstd::amin(retaliation.damage.max, ap.attackerState->getAvailableHealth());
|
||||
|
||||
damageDealt = averageDmg(attackDmg.damage);
|
||||
vstd::amin(damageDealt, defenderState->getAvailableHealth());
|
||||
|
||||
defenderDamageReduce = calculateDamageReduce(attacker, u, damageDealt, damageCache, state);
|
||||
ap.attackerState->afterAttack(attackInfo.shooting, false);
|
||||
|
||||
//FIXME: use ranged retaliation
|
||||
damageReceived = 0;
|
||||
attackerDamageReduce = 0;
|
||||
|
||||
if (!attackInfo.shooting && u->unitId() == defender->unitId() && defenderState->ableToRetaliate() && !counterAttacksBlocked)
|
||||
{
|
||||
for(auto retaliated : retaliatedUnits)
|
||||
{
|
||||
damageReceived = averageDmg(retaliation.damage);
|
||||
|
||||
if(retaliated->unitId() == attacker->unitId())
|
||||
{
|
||||
int64_t damageReceived = averageDmg(retaliation.damage);
|
||||
|
||||
vstd::amin(damageReceived, ap.attackerState->getAvailableHealth());
|
||||
|
||||
attackerDamageReduce = calculateDamageReduce(defender, retaliated, damageReceived, damageCache, state);
|
||||
ap.attackerState->damage(damageReceived);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(state->battleMatchOwner(defender, u))
|
||||
auto retaliationCollateral = state->battleEstimateDamage(defender, retaliated, 0);
|
||||
int64_t damageReceived = averageDmg(retaliationCollateral.damage);
|
||||
|
||||
vstd::amin(damageReceived, retaliated->getAvailableHealth());
|
||||
|
||||
if(defender->unitSide() == retaliated->unitSide())
|
||||
defenderDamageReduce += calculateDamageReduce(defender, retaliated, damageReceived, damageCache, state);
|
||||
else
|
||||
ap.collateralDamageReduce += calculateDamageReduce(defender, retaliated, damageReceived, damageCache, state);
|
||||
|
@ -30,100 +30,89 @@ float BattleExchangeVariant::trackAttack(
|
||||
{
|
||||
auto attacker = hb->getForUpdate(ap.attack.attacker->unitId());
|
||||
|
||||
const std::string cachingStringBlocksRetaliation = "type_BLOCKS_RETALIATION";
|
||||
static const auto selectorBlocksRetaliation = Selector::type()(BonusType::BLOCKS_RETALIATION);
|
||||
const bool counterAttacksBlocked = attacker->hasBonus(selectorBlocksRetaliation, cachingStringBlocksRetaliation);
|
||||
|
||||
float attackValue = 0;
|
||||
float attackValue = ap.attackValue();
|
||||
auto affectedUnits = ap.affectedUnits;
|
||||
|
||||
dpsScore.ourDamageReduce += ap.attackerDamageReduce + ap.collateralDamageReduce;
|
||||
dpsScore.enemyDamageReduce += ap.defenderDamageReduce + ap.shootersBlockedDmg;
|
||||
attackerValue[attacker->unitId()].value = attackValue;
|
||||
|
||||
affectedUnits.push_back(ap.attackerState);
|
||||
|
||||
for(auto affectedUnit : affectedUnits)
|
||||
{
|
||||
auto unitToUpdate = hb->getForUpdate(affectedUnit->unitId());
|
||||
auto damageDealt = unitToUpdate->getTotalHealth() - affectedUnit->getTotalHealth();
|
||||
|
||||
if(damageDealt > 0)
|
||||
{
|
||||
unitToUpdate->damage(damageDealt);
|
||||
}
|
||||
|
||||
if(unitToUpdate->unitSide() == attacker->unitSide())
|
||||
{
|
||||
if(unitToUpdate->unitId() == attacker->unitId())
|
||||
{
|
||||
auto defender = hb->getForUpdate(ap.attack.defender->unitId());
|
||||
|
||||
if(!defender->alive() || counterAttacksBlocked || ap.attack.shooting || !defender->ableToRetaliate())
|
||||
continue;
|
||||
|
||||
auto retaliationDamage = damageCache.getDamage(defender.get(), unitToUpdate.get(), hb);
|
||||
auto attackerDamageReduce = AttackPossibility::calculateDamageReduce(defender.get(), unitToUpdate.get(), retaliationDamage, damageCache, hb);
|
||||
|
||||
attackValue -= attackerDamageReduce;
|
||||
dpsScore.ourDamageReduce += attackerDamageReduce;
|
||||
attackerValue[unitToUpdate->unitId()].isRetaliated = true;
|
||||
|
||||
unitToUpdate->damage(retaliationDamage);
|
||||
defender->afterAttack(false, true);
|
||||
unitToUpdate->afterAttack(ap.attack.shooting, false);
|
||||
|
||||
#if BATTLE_TRACE_LEVEL>=1
|
||||
logAi->trace(
|
||||
"%s -> %s, ap retaliation, %s, dps: %2f, score: %2f",
|
||||
defender->getDescription(),
|
||||
unitToUpdate->getDescription(),
|
||||
"%s -> %s, ap retaliation, %s, dps: %lld",
|
||||
ap.attack.defender->getDescription(),
|
||||
ap.attack.attacker->getDescription(),
|
||||
ap.attack.shooting ? "shot" : "mellee",
|
||||
retaliationDamage,
|
||||
attackerDamageReduce);
|
||||
damageDealt);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
auto collateralDamage = damageCache.getDamage(attacker.get(), unitToUpdate.get(), hb);
|
||||
auto collateralDamageReduce = AttackPossibility::calculateDamageReduce(attacker.get(), unitToUpdate.get(), collateralDamage, damageCache, hb);
|
||||
|
||||
attackValue -= collateralDamageReduce;
|
||||
dpsScore.ourDamageReduce += collateralDamageReduce;
|
||||
|
||||
unitToUpdate->damage(collateralDamage);
|
||||
|
||||
#if BATTLE_TRACE_LEVEL>=1
|
||||
logAi->trace(
|
||||
"%s -> %s, ap collateral, %s, dps: %2f, score: %2f",
|
||||
attacker->getDescription(),
|
||||
"%s, ap collateral, dps: %lld",
|
||||
unitToUpdate->getDescription(),
|
||||
ap.attack.shooting ? "shot" : "mellee",
|
||||
collateralDamage,
|
||||
collateralDamageReduce);
|
||||
damageDealt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t attackDamage = damageCache.getDamage(attacker.get(), unitToUpdate.get(), hb);
|
||||
float defenderDamageReduce = AttackPossibility::calculateDamageReduce(attacker.get(), unitToUpdate.get(), attackDamage, damageCache, hb);
|
||||
|
||||
attackValue += defenderDamageReduce;
|
||||
dpsScore.enemyDamageReduce += defenderDamageReduce;
|
||||
attackerValue[attacker->unitId()].value += defenderDamageReduce;
|
||||
|
||||
unitToUpdate->damage(attackDamage);
|
||||
if(unitToUpdate->unitId() == ap.attack.defender->unitId())
|
||||
{
|
||||
if(unitToUpdate->ableToRetaliate() && !affectedUnit->ableToRetaliate())
|
||||
{
|
||||
unitToUpdate->afterAttack(ap.attack.shooting, true);
|
||||
}
|
||||
|
||||
#if BATTLE_TRACE_LEVEL>=1
|
||||
logAi->trace(
|
||||
"%s -> %s, ap attack, %s, dps: %2f, score: %2f",
|
||||
attacker->getDescription(),
|
||||
unitToUpdate->getDescription(),
|
||||
ap.attack.shooting ? "shot" : "mellee",
|
||||
attackDamage,
|
||||
defenderDamageReduce);
|
||||
logAi->trace(
|
||||
"%s -> %s, ap attack, %s, dps: %lld",
|
||||
attacker->getDescription(),
|
||||
ap.attack.defender->getDescription(),
|
||||
ap.attack.shooting ? "shot" : "mellee",
|
||||
damageDealt);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if BATTLE_TRACE_LEVEL>=1
|
||||
logAi->trace(
|
||||
"%s, ap enemy collateral, dps: %lld",
|
||||
unitToUpdate->getDescription(),
|
||||
damageDealt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if BATTLE_TRACE_LEVEL >= 1
|
||||
logAi->trace("ap shooters blocking: %lld", ap.shootersBlockedDmg);
|
||||
logAi->trace(
|
||||
"ap score: our: %2f, enemy: %2f, collateral: %2f, blocked: %2f",
|
||||
ap.attackerDamageReduce,
|
||||
ap.defenderDamageReduce,
|
||||
ap.collateralDamageReduce,
|
||||
ap.shootersBlockedDmg);
|
||||
#endif
|
||||
|
||||
attackValue += ap.shootersBlockedDmg;
|
||||
dpsScore.enemyDamageReduce += ap.shootersBlockedDmg;
|
||||
attacker->afterAttack(ap.attack.shooting, false);
|
||||
|
||||
return attackValue;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user