fix(Core/Unit): criticals not working against sitting players. (#5872)

This commit is contained in:
Maxpro
2021-05-21 07:35:08 -07:00
committed by GitHub
parent 5b9415be5a
commit 3f6da61535
2 changed files with 19 additions and 14 deletions

View File

@@ -1298,7 +1298,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss)
}
// TODO for melee need create structure as in
void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType)
void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType, const bool sittingVictim)
{
damageInfo->attacker = this;
damageInfo->target = victim;
@@ -1368,6 +1368,11 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType);
// If the victim was a sitting player and we didn't roll a miss, then crit.
if (sittingVictim && damageInfo->hitOutCome != MELEE_HIT_MISS)
{
damageInfo->hitOutCome = MELEE_HIT_CRIT;
}
switch (damageInfo->hitOutCome)
{
case MELEE_HIT_EVADE:
@@ -2199,6 +2204,9 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
if ((attType == BASE_ATTACK || attType == OFF_ATTACK) && !IsWithinLOSInMap(victim))
return;
// CombatStart puts the target into stand state, so we need to cache sit state here to know if we should crit later
const bool sittingVictim = victim->GetTypeId() == TYPEID_PLAYER && (victim->IsSitState() || victim->getStandState() == UNIT_STAND_STATE_SLEEP) ? true : false;
CombatStart(victim);
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MELEE_ATTACK);
@@ -2212,9 +2220,9 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr
{
// attack can be redirected to another target
victim = GetMeleeHitRedirectTarget(victim);
CalcDamageInfo damageInfo;
CalculateMeleeDamage(victim, 0, &damageInfo, attType);
CalculateMeleeDamage(victim, 0, &damageInfo, attType, sittingVictim);
// Send log damage message to client
Unit::DealDamageMods(victim, damageInfo.damage, &damageInfo.absorb);
SendAttackStateUpdate(&damageInfo);
@@ -2359,7 +2367,9 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackTy
MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const
{
if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())
{
return MELEE_HIT_EVADE;
}
int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(victim);
int32 victimMaxSkillValueForLevel = victim->GetMaxSkillValueForLevel(this);
@@ -2374,25 +2384,20 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackTy
int32 sum = 0, tmp = 0;
int32 roll = urand (0, 10000);
//LOG_DEBUG("server", "RollMeleeOutcomeAgainst: skill bonus of %d for attacker", skillBonus);
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "RollMeleeOutcomeAgainst: skill bonus of %d for attacker", skillBonus);
#endif
//LOG_DEBUG("server", "RollMeleeOutcomeAgainst: rolled %d, miss %d, dodge %d, parry %d, block %d, crit %d",
// roll, miss_chance, dodge_chance, parry_chance, block_chance, crit_chance);
tmp = miss_chance;
if (tmp > 0 && roll < (sum += tmp))
{
//LOG_DEBUG("server", "RollMeleeOutcomeAgainst: MISS");
return MELEE_HIT_MISS;
}
// always crit against a sitting target (except 0 crit chance)
if (victim->GetTypeId() == TYPEID_PLAYER && crit_chance > 0 && !victim->IsStandState())
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "RollMeleeOutcomeAgainst: CRIT (sitting victim)");
LOG_DEBUG("server", "RollMeleeOutcomeAgainst: MISS");
#endif
return MELEE_HIT_CRIT;
return MELEE_HIT_MISS;
}
// Dodge chance