From 29fddba8fd6586de1641fd371cbb3f5b8854e9d5 Mon Sep 17 00:00:00 2001 From: ariel- Date: Sat, 7 May 2022 15:52:56 +0200 Subject: [PATCH] Core/Entities: Port some refactors from f1986c6aafdf2457902a7a4cc7acc903cbbdc7bb --- src/server/game/Entities/Creature/Creature.h | 2 +- src/server/game/Entities/Player/Player.cpp | 8 + src/server/game/Entities/Player/Player.h | 2 + src/server/game/Entities/Unit/Unit.cpp | 261 +++++++++---------- src/server/game/Entities/Unit/Unit.h | 37 +-- 5 files changed, 160 insertions(+), 150 deletions(-) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 0acd4959d6..2897aa1a8e 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -146,7 +146,7 @@ class TC_GAME_API Creature : public Unit, public GridObject, public Ma CreatureAI* AI() const { return reinterpret_cast(GetAI()); } - SpellSchoolMask GetMeleeDamageSchoolMask() const override { return m_meleeDamageSchoolMask; } + SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType /*attackType*/ = BASE_ATTACK) const override { return m_meleeDamageSchoolMask; } void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); } bool HasSpell(uint32 spellID) const override; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 4d607a8547..313467b2b6 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7702,6 +7702,14 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt UpdateDamagePhysical(attType); } +SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/) const +{ + if (Item const* weapon = GetWeaponForAttack(attackType, true)) + return SpellSchoolMask(1 << weapon->GetTemplate()->GetDamageType()); + + return SPELL_SCHOOL_MASK_NORMAL; +} + void Player::CastAllObtainSpells() { for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index f6b519914c..9de69bbe72 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2021,6 +2021,8 @@ class TC_GAME_API Player : public Unit, public GridObject void ResetAllPowers(); + SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK) const override; + void CastAllObtainSpells(); void ApplyItemObtainSpells(Item* item, bool apply); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 643db9c80c..78013d70c9 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -119,8 +119,8 @@ DamageInfo::DamageInfo(Unit* attacker, Unit* victim, uint32 damage, SpellInfo co } DamageInfo::DamageInfo(CalcDamageInfo const& dmgInfo) - : m_attacker(dmgInfo.attacker), m_victim(dmgInfo.target), m_damage(dmgInfo.damage), m_spellInfo(nullptr), m_schoolMask(SpellSchoolMask(dmgInfo.damageSchoolMask)), - m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType), m_absorb(dmgInfo.absorb), m_resist(dmgInfo.resist), m_block(dmgInfo.blocked_amount), m_hitMask(0) + : m_attacker(dmgInfo.Attacker), m_victim(dmgInfo.Target), m_damage(dmgInfo.Damage), m_spellInfo(nullptr), m_schoolMask(SpellSchoolMask(dmgInfo.DamageSchoolMask)), + m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.AttackType), m_absorb(dmgInfo.Absorb), m_resist(dmgInfo.Resist), m_block(dmgInfo.Blocked), m_hitMask(0) { switch (dmgInfo.TargetState) { @@ -143,7 +143,7 @@ DamageInfo::DamageInfo(CalcDamageInfo const& dmgInfo) bool const damageNullified = (dmgInfo.HitInfo & (HITINFO_FULL_ABSORB | HITINFO_FULL_RESIST)) != 0 || (m_hitMask & (PROC_HIT_IMMUNE | PROC_HIT_FULL_BLOCK)) != 0; - switch (dmgInfo.hitOutCome) + switch (dmgInfo.HitOutCome) { case MELEE_HIT_MISS: m_hitMask |= PROC_HIT_MISS; @@ -1229,23 +1229,26 @@ 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, CalcDamageInfo* damageInfo, WeaponAttackType attackType /*= BASE_ATTACK*/) { - damageInfo->attacker = this; - damageInfo->target = victim; - damageInfo->damageSchoolMask = GetMeleeDamageSchoolMask(); - damageInfo->attackType = attackType; - damageInfo->damage = 0; - damageInfo->cleanDamage = 0; - damageInfo->absorb = 0; - damageInfo->resist = 0; - damageInfo->blocked_amount = 0; + damageInfo->Attacker = this; + damageInfo->Target = victim; - damageInfo->TargetState = VICTIMSTATE_INTACT; - damageInfo->HitInfo = 0; - damageInfo->procAttacker = PROC_FLAG_NONE; - damageInfo->procVictim = PROC_FLAG_NONE; - damageInfo->hitOutCome = MELEE_HIT_EVADE; + damageInfo->DamageSchoolMask = GetMeleeDamageSchoolMask(attackType); + damageInfo->Damage = 0; + damageInfo->OriginalDamage = 0; + damageInfo->Absorb = 0; + damageInfo->Resist = 0; + + damageInfo->Blocked = 0; + damageInfo->HitInfo = 0; + damageInfo->TargetState = 0; + + damageInfo->AttackType = attackType; + damageInfo->ProcAttacker = PROC_FLAG_NONE; + damageInfo->ProcVictim = PROC_FLAG_NONE; + damageInfo->CleanDamage = 0; + damageInfo->HitOutCome = MELEE_HIT_EVADE; if (!victim) return; @@ -1257,12 +1260,12 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam switch (attackType) { case BASE_ATTACK: - damageInfo->procAttacker = PROC_FLAG_DEAL_MELEE_SWING | PROC_FLAG_MAIN_HAND_WEAPON_SWING; - damageInfo->procVictim = PROC_FLAG_TAKE_MELEE_SWING; + damageInfo->ProcAttacker = PROC_FLAG_DEAL_MELEE_SWING | PROC_FLAG_MAIN_HAND_WEAPON_SWING; + damageInfo->ProcVictim = PROC_FLAG_TAKE_MELEE_SWING; break; case OFF_ATTACK: - damageInfo->procAttacker = PROC_FLAG_DEAL_MELEE_SWING | PROC_FLAG_OFF_HAND_WEAPON_SWING; - damageInfo->procVictim = PROC_FLAG_TAKE_MELEE_SWING; + damageInfo->ProcAttacker = PROC_FLAG_DEAL_MELEE_SWING | PROC_FLAG_OFF_HAND_WEAPON_SWING; + damageInfo->ProcVictim = PROC_FLAG_TAKE_MELEE_SWING; damageInfo->HitInfo = HITINFO_OFFHAND; break; default: @@ -1270,47 +1273,57 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam } // Physical Immune check - if (damageInfo->target->IsImmunedToDamage(SpellSchoolMask(damageInfo->damageSchoolMask))) + if (damageInfo->Target->IsImmunedToDamage(SpellSchoolMask(damageInfo->DamageSchoolMask))) { damageInfo->HitInfo |= HITINFO_NORMALSWING; damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE; + + damageInfo->Damage = 0; + damageInfo->CleanDamage = 0; return; } - damage += CalculateDamage(damageInfo->attackType, false, true); + uint32 damage = 0; + damage += CalculateDamage(damageInfo->AttackType, false, true); // Add melee damage bonus - damage = MeleeDamageBonusDone(damageInfo->target, damage, damageInfo->attackType); - damage = damageInfo->target->MeleeDamageBonusTaken(this, damage, damageInfo->attackType); + damage = MeleeDamageBonusDone(damageInfo->Target, damage, damageInfo->AttackType, nullptr, true, SpellSchoolMask(damageInfo->DamageSchoolMask)); + damage = damageInfo->Target->MeleeDamageBonusTaken(this, damage, damageInfo->AttackType, nullptr, SpellSchoolMask(damageInfo->DamageSchoolMask)); // Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations - sScriptMgr->ModifyMeleeDamage(damageInfo->target, damageInfo->attacker, damage); + sScriptMgr->ModifyMeleeDamage(damageInfo->Target, damageInfo->Attacker, damage); // Calculate armor reduction - if (Unit::IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask))) + if (Unit::IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->DamageSchoolMask))) { - damageInfo->damage = Unit::CalcArmorReducedDamage(damageInfo->attacker, damageInfo->target, damage, nullptr, damageInfo->attackType); - damageInfo->cleanDamage += damage - damageInfo->damage; + damageInfo->Damage = Unit::CalcArmorReducedDamage(damageInfo->Attacker, damageInfo->Target, damage, nullptr, damageInfo->AttackType); + damageInfo->CleanDamage += damage - damageInfo->Damage; } else - damageInfo->damage = damage; + damageInfo->Damage = damage; - damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType); + damageInfo->HitOutCome = RollMeleeOutcomeAgainst(damageInfo->Target, damageInfo->AttackType); - switch (damageInfo->hitOutCome) + switch (damageInfo->HitOutCome) { case MELEE_HIT_EVADE: damageInfo->HitInfo |= HITINFO_MISS | HITINFO_SWINGNOHITSOUND; damageInfo->TargetState = VICTIMSTATE_EVADES; - damageInfo->damage = 0; - damageInfo->cleanDamage = 0; + damageInfo->OriginalDamage = damageInfo->Damage; + + damageInfo->Damage = 0; + damageInfo->CleanDamage = 0; return; case MELEE_HIT_MISS: damageInfo->HitInfo |= HITINFO_MISS; - damageInfo->damage = 0; - damageInfo->cleanDamage = 0; + damageInfo->TargetState = VICTIMSTATE_INTACT; + damageInfo->OriginalDamage = damageInfo->Damage; + + damageInfo->Damage = 0; + damageInfo->CleanDamage = 0; break; case MELEE_HIT_NORMAL: damageInfo->TargetState = VICTIMSTATE_HIT; + damageInfo->OriginalDamage = damageInfo->Damage; break; case MELEE_HIT_CRIT: { @@ -1318,67 +1331,69 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damageInfo->TargetState = VICTIMSTATE_HIT; // Crit bonus calc - damageInfo->damage += damageInfo->damage; + damageInfo->Damage *= 2; float mod = 0.0f; // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE - if (damageInfo->attackType == RANGED_ATTACK) - mod += damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE); + if (damageInfo->AttackType == RANGED_ATTACK) + mod += damageInfo->Target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE); else - mod += damageInfo->target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE); + mod += damageInfo->Target->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE); // Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS - mod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, damageInfo->damageSchoolMask) - 1.0f) * 100; + mod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, damageInfo->DamageSchoolMask) - 1.0f) * 100; if (mod != 0) - AddPct(damageInfo->damage, mod); + AddPct(damageInfo->Damage, mod); + + damageInfo->OriginalDamage = damageInfo->Damage; break; } case MELEE_HIT_PARRY: damageInfo->TargetState = VICTIMSTATE_PARRY; - damageInfo->cleanDamage += damageInfo->damage; - damageInfo->damage = 0; + damageInfo->CleanDamage += damageInfo->Damage; + + damageInfo->OriginalDamage = damageInfo->Damage; + damageInfo->Damage = 0; break; case MELEE_HIT_DODGE: - damageInfo->TargetState = VICTIMSTATE_DODGE; - damageInfo->cleanDamage += damageInfo->damage; - damageInfo->damage = 0; + damageInfo->TargetState = VICTIMSTATE_DODGE; + damageInfo->CleanDamage += damageInfo->Damage; + + damageInfo->OriginalDamage = damageInfo->Damage; + damageInfo->Damage = 0; break; case MELEE_HIT_BLOCK: damageInfo->TargetState = VICTIMSTATE_HIT; - damageInfo->HitInfo |= HITINFO_BLOCK; + damageInfo->HitInfo |= HITINFO_BLOCK; // 30% damage blocked, double blocked amount if block is critical - damageInfo->blocked_amount = CalculatePct(damageInfo->damage, damageInfo->target->isBlockCritical() ? damageInfo->target->GetBlockPercent() * 2 : damageInfo->target->GetBlockPercent()); - damageInfo->damage -= damageInfo->blocked_amount; - damageInfo->cleanDamage += damageInfo->blocked_amount; + damageInfo->Blocked = CalculatePct(damageInfo->Damage, damageInfo->Target->GetBlockPercent()); + if (damageInfo->Target->isBlockCritical()) + damageInfo->Blocked *= 2; + + damageInfo->OriginalDamage = damageInfo->Damage; + damageInfo->Damage -= damageInfo->Blocked; + damageInfo->CleanDamage += damageInfo->Blocked; break; case MELEE_HIT_GLANCING: { damageInfo->HitInfo |= HITINFO_GLANCING; damageInfo->TargetState = VICTIMSTATE_HIT; - int32 leveldif = int32(victim->getLevelForTarget(this)) - int32(getLevel()); - if (leveldif < 0) - { - TC_LOG_DEBUG("entities.unit", "Unit::CalculateMeleeDamage: (Player) %s attacked %s. Glancing should never happen against lower level target", GetGUID().ToString().c_str(), victim->GetGUID().ToString().c_str()); - break; - } - if (leveldif == 0) - leveldif = 1; - else if (leveldif > 3) + int32 leveldif = int32(victim->getLevel()) - int32(getLevel()); + if (leveldif > 3) leveldif = 3; - int32 const reductionMax = leveldif * 10; - int32 const reductionMin = std::max(1, reductionMax - 10); - float reducePercent = 1.f - irand(reductionMin, reductionMax) / 100.0f; - - damageInfo->cleanDamage += damageInfo->damage - uint32(reducePercent * damageInfo->damage); - damageInfo->damage = uint32(reducePercent * damageInfo->damage); + damageInfo->OriginalDamage = damageInfo->Damage; + float reducePercent = 1.f - leveldif * 0.1f; + damageInfo->CleanDamage += damageInfo->Damage - uint32(reducePercent * damageInfo->Damage); + damageInfo->Damage = uint32(reducePercent * damageInfo->Damage); break; } case MELEE_HIT_CRUSHING: damageInfo->HitInfo |= HITINFO_CRUSHING; damageInfo->TargetState = VICTIMSTATE_HIT; // 150% normal damage - damageInfo->damage += (damageInfo->damage / 2); + damageInfo->Damage += (damageInfo->Damage / 2); + damageInfo->OriginalDamage = damageInfo->Damage; break; default: break; @@ -1388,38 +1403,38 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam if (!(damageInfo->HitInfo & HITINFO_MISS)) damageInfo->HitInfo |= HITINFO_AFFECTS_VICTIM; - int32 resilienceReduction = damageInfo->damage; + int32 resilienceReduction = damageInfo->Damage; if (CanApplyResilience()) Unit::ApplyResilience(victim, &resilienceReduction); - resilienceReduction = damageInfo->damage - resilienceReduction; - damageInfo->damage -= resilienceReduction; - damageInfo->cleanDamage += resilienceReduction; + resilienceReduction = damageInfo->Damage - resilienceReduction; + damageInfo->Damage -= resilienceReduction; + damageInfo->CleanDamage += resilienceReduction; // Calculate absorb resist - if (int32(damageInfo->damage) > 0) + if (int32(damageInfo->Damage) > 0) { - damageInfo->procVictim |= PROC_FLAG_TAKE_ANY_DAMAGE; + damageInfo->ProcVictim |= PROC_FLAG_TAKE_ANY_DAMAGE; // Calculate absorb & resists DamageInfo dmgInfo(*damageInfo); Unit::CalcAbsorbResist(dmgInfo); - damageInfo->absorb = dmgInfo.GetAbsorb(); - damageInfo->resist = dmgInfo.GetResist(); + damageInfo->Absorb = dmgInfo.GetAbsorb(); + damageInfo->Resist = dmgInfo.GetResist(); - if (damageInfo->absorb) - damageInfo->HitInfo |= (damageInfo->damage - damageInfo->absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB); + if (damageInfo->Absorb) + damageInfo->HitInfo |= (damageInfo->Damage - damageInfo->Absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB); - if (damageInfo->resist) - damageInfo->HitInfo |= (damageInfo->damage - damageInfo->resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST); + if (damageInfo->Resist) + damageInfo->HitInfo |= (damageInfo->Damage - damageInfo->Resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST); - damageInfo->damage = dmgInfo.GetDamage(); + damageInfo->Damage = dmgInfo.GetDamage(); } else // Impossible get negative result but.... - damageInfo->damage = 0; + damageInfo->Damage = 0; } void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) { - Unit* victim = damageInfo->target; + Unit* victim = damageInfo->Target; if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())) return; @@ -1458,11 +1473,11 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) } // Call default DealDamage - CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, damageInfo->attackType, damageInfo->hitOutCome); - Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damageSchoolMask), nullptr, durabilityLoss); + CleanDamage cleanDamage(damageInfo->CleanDamage, damageInfo->Absorb, damageInfo->AttackType, damageInfo->HitOutCome); + Unit::DealDamage(this, victim, damageInfo->Damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->DamageSchoolMask), nullptr, durabilityLoss); // If this is a creature and it attacks from behind it has a probability to daze it's victim - if ((damageInfo->hitOutCome == MELEE_HIT_CRIT || damageInfo->hitOutCome == MELEE_HIT_CRUSHING || damageInfo->hitOutCome == MELEE_HIT_NORMAL || damageInfo->hitOutCome == MELEE_HIT_GLANCING) && + if ((damageInfo->HitOutCome == MELEE_HIT_CRIT || damageInfo->HitOutCome == MELEE_HIT_CRUSHING || damageInfo->HitOutCome == MELEE_HIT_NORMAL || damageInfo->HitOutCome == MELEE_HIT_GLANCING) && GetTypeId() != TYPEID_PLAYER && !ToCreature()->IsControlledByPlayer() && !victim->HasInArc(float(M_PI), this) && (victim->GetTypeId() == TYPEID_PLAYER || !victim->ToCreature()->isWorldBoss())&& !victim->IsVehicle()) { @@ -1491,7 +1506,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) } // Do effect if any damage done to target - if (damageInfo->damage) + if (damageInfo->Damage) { // We're going to call functions which can modify content of the list during iteration over it's elements // Let's copy the list so we can prevent iterator invalidation @@ -1627,7 +1642,7 @@ static float GetArmorReduction(float armor, uint8 attackerLevel) float armorReduction = 100.f - GetArmorReduction(armor, attacker ? attacker->getLevel() : attackerLevel); - return std::max(CalculatePct(damage, armorReduction), 1); + return std::max(CalculatePct(damage, armorReduction), 0); } /*static*/ uint32 Unit::CalcSpellResistedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) @@ -2069,9 +2084,9 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr if (!meleeAttackAuraEffect) { CalcDamageInfo damageInfo; - CalculateMeleeDamage(victim, 0, &damageInfo, attType); + CalculateMeleeDamage(victim, &damageInfo, attType); // Send log damage message to client - Unit::DealDamageMods(victim, damageInfo.damage, &damageInfo.absorb); + Unit::DealDamageMods(victim, damageInfo.Damage, &damageInfo.Absorb); // Sparring Checks if (Creature* target = victim->ToCreature()) @@ -2085,14 +2100,10 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType, bool extr DealMeleeDamage(&damageInfo, true); DamageInfo dmgInfo(damageInfo); - Unit::ProcSkillsAndAuras(damageInfo.attacker, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr); + Unit::ProcSkillsAndAuras(damageInfo.Attacker, damageInfo.Target, damageInfo.ProcAttacker, damageInfo.ProcVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr); - if (GetTypeId() == TYPEID_PLAYER) - TC_LOG_DEBUG("entities.unit", "AttackerStateUpdate: (Player) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", - GetGUID().GetCounter(), victim->GetGUID().GetCounter(), victim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); - else - TC_LOG_DEBUG("entities.unit", "AttackerStateUpdate: (NPC) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", - GetGUID().GetCounter(), victim->GetGUID().GetCounter(), victim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); + TC_LOG_DEBUG("entities.unit", "AttackerStateUpdate: %s attacked %s for %u dmg, absorbed %u, blocked %u, resisted %u.", + GetGUID().ToString().c_str(), victim->GetGUID().ToString().c_str(), damageInfo.Damage, damageInfo.Absorb, damageInfo.Blocked, damageInfo.Resist); } else { @@ -2273,9 +2284,6 @@ uint32 Unit::CalculateDamage(WeaponAttackType attType, bool normalized, bool add if (minDamage > maxDamage) std::swap(minDamage, maxDamage); - if (maxDamage == 0.0f) - maxDamage = 5.0f; - return urand(uint32(minDamage), uint32(maxDamage)); } @@ -5322,21 +5330,21 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo) { WorldPackets::CombatLog::AttackerStateUpdate packet; packet.HitInfo = damageInfo->HitInfo; - packet.AttackerGUID = damageInfo->attacker->GetGUID(); - packet.VictimGUID = damageInfo->target->GetGUID(); - packet.Damage = damageInfo->damage; - int32 overkill = damageInfo->damage - damageInfo->target->GetHealth(); + packet.AttackerGUID = damageInfo->Attacker->GetGUID(); + packet.VictimGUID = damageInfo->Target->GetGUID(); + packet.Damage = damageInfo->Damage; + int32 overkill = damageInfo->Damage - damageInfo->Target->GetHealth(); packet.OverDamage = (overkill < 0 ? -1 : overkill); packet.SubDmg.emplace(); - packet.SubDmg->SchoolMask = damageInfo->damageSchoolMask; // School of sub damage - packet.SubDmg->FDamage = damageInfo->damage; // sub damage - packet.SubDmg->Damage = damageInfo->damage; // Sub Damage - packet.SubDmg->Absorbed = damageInfo->absorb; - packet.SubDmg->Resisted = damageInfo->resist; + packet.SubDmg->SchoolMask = damageInfo->DamageSchoolMask; // School of sub damage + packet.SubDmg->FDamage = damageInfo->Damage; // sub damage + packet.SubDmg->Damage = damageInfo->Damage; // Sub Damage + packet.SubDmg->Absorbed = damageInfo->Absorb; + packet.SubDmg->Resisted = damageInfo->Resist; packet.VictimState = damageInfo->TargetState; - packet.BlockAmount = damageInfo->blocked_amount; + packet.BlockAmount = damageInfo->Blocked; SendMessageToSet(packet.Write(), true); } @@ -5345,14 +5353,14 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType { CalcDamageInfo dmgInfo; dmgInfo.HitInfo = HitInfo; - dmgInfo.attacker = this; - dmgInfo.target = target; - dmgInfo.damage = Damage - AbsorbDamage - Resist - BlockedAmount; - dmgInfo.damageSchoolMask = damageSchoolMask; - dmgInfo.absorb = AbsorbDamage; - dmgInfo.resist = Resist; + dmgInfo.Attacker = this; + dmgInfo.Target = target; + dmgInfo.Damage = Damage - AbsorbDamage - Resist - BlockedAmount; + dmgInfo.DamageSchoolMask = damageSchoolMask; + dmgInfo.Absorb = AbsorbDamage; + dmgInfo.Resist = Resist; dmgInfo.TargetState = TargetState; - dmgInfo.blocked_amount = BlockedAmount; + dmgInfo.Blocked = BlockedAmount; SendAttackStateUpdate(&dmgInfo); } @@ -7942,7 +7950,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit return false; } -uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto /*= nullptr*/, bool useSpellBonusData /*= true*/) +uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto /*= nullptr*/, bool useSpellBonusData /*= true*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/) { if (!victim || pdamage == 0) return 0; @@ -7997,6 +8005,8 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType // Done total percent damage auras float DoneTotalMod = 1.0f; + SpellSchoolMask schoolMask = spellProto ? spellProto->GetSchoolMask() : damageSchoolMask; + // Some spells don't benefit from pct done mods if (spellProto && !spellProto->HasAttribute(SPELL_ATTR6_LIMIT_PCT_DAMAGE_MODS)) { @@ -8054,7 +8064,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType return uint32(std::max(tmpDamage, 0.0f)); } -uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto) +uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto /*= nullptr*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/) { if (pdamage == 0) return 0; @@ -8176,7 +8186,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT // Sanctified Wrath (bypass damage reduction) if (TakenTotalMod < 1.0f) { - SpellSchoolMask const attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL; + SpellSchoolMask const attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : damageSchoolMask; float damageReduction = 1.0f - TakenTotalMod; Unit::AuraEffectList const& casterIgnoreResist = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST); @@ -10979,12 +10989,6 @@ void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTrigg } } -void Unit::TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo) -{ - DamageInfo dmgInfo = DamageInfo(damageInfo); - TriggerAurasProcOnEvent(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr); -} - void Unit::TriggerAurasProcOnEvent(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) { // prepare data for self trigger @@ -11051,11 +11055,6 @@ void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProc SetCantProc(false); } -SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const -{ - return SPELL_SCHOOL_MASK_NORMAL; -} - ObjectGuid Unit::GetCharmerOrOwnerOrOwnGUID() const { if (ObjectGuid guid = GetCharmerOrOwnerGUID()) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4860a37c64..ed218c23cd 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -539,21 +539,23 @@ class TC_GAME_API ProcEventInfo // Need create structure like in SMSG_ATTACKERSTATEUPDATE opcode struct CalcDamageInfo { - Unit *attacker; // Attacker - Unit *target; // Target for damage - uint32 damageSchoolMask; - uint32 damage; - uint32 absorb; - uint32 resist; - uint32 blocked_amount; + Unit* Attacker; + Unit* Target; + uint32 DamageSchoolMask; + uint32 Damage; + uint32 OriginalDamage; + uint32 Absorb; + uint32 Resist; + uint32 Blocked; uint32 HitInfo; uint32 TargetState; -// Helper - WeaponAttackType attackType; // - uint32 procAttacker; - uint32 procVictim; - uint32 cleanDamage; // Used only for rage calculation - MeleeHitOutcome hitOutCome; /// @todo remove this field (need use TargetState) + + // Helpers + WeaponAttackType AttackType; // + uint32 ProcAttacker; + uint32 ProcVictim; + uint32 CleanDamage; // Used only for rage calculation + MeleeHitOutcome HitOutCome; /// @todo remove this field (need use TargetState) }; // Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode @@ -877,7 +879,7 @@ class TC_GAME_API Unit : public WorldObject bool IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const; bool IsWithinBoundaryRadius(const Unit* obj) const; float GetMeleeRange(Unit const* target) const; - virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; + virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK) const = 0; uint32 m_extraAttacks; bool m_canDualWield; @@ -1047,7 +1049,6 @@ class TC_GAME_API Unit : public WorldObject DamageInfo* damageInfo, HealInfo* healInfo); void GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTriggeringProc, AuraApplicationList* procAuras, ProcEventInfo& eventInfo); - void TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo); void TriggerAurasProcOnEvent(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); @@ -1056,7 +1057,7 @@ class TC_GAME_API Unit : public WorldObject void HandleEmoteCommand(uint32 anim_id); void AttackerStateUpdate(Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false); - void CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK); + void CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK); void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss); void HandleProcExtraAttackFor(Unit* victim); @@ -1643,8 +1644,8 @@ class TC_GAME_API Unit : public WorldObject float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const; uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const; - uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr, bool useSpellBonusData = true); - uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr); + uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr, bool useSpellBonusData = true, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL); + uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL); bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto); bool isBlockCritical();