diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 289 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 38 |
5 files changed, 175 insertions, 164 deletions
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 4bd28f76e99..442a364d1a4 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -152,7 +152,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma CreatureAI* AI() const { return reinterpret_cast<CreatureAI*>(i_AI); } - 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 4eea3a24ac6..4908d94473f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7825,6 +7825,14 @@ void Player::_ApplyWeaponDamage(uint8 slot, Item* item, bool apply) 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() { uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7d10604eea1..ed747c885ab 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2197,6 +2197,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> 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 3945343e29a..e11e1c5fa1a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -127,8 +127,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_originalDamage(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_originalDamage(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) { @@ -151,7 +151,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; @@ -1208,24 +1208,26 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilit } /// @todo for melee need create structure as in -void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType) -{ - damageInfo->attacker = this; - damageInfo->target = victim; - damageInfo->damageSchoolMask = GetMeleeDamageSchoolMask(); - damageInfo->attackType = attackType; - damageInfo->damage = 0; - damageInfo->originalDamage = 0; - damageInfo->cleanDamage = 0; - damageInfo->absorb = 0; - damageInfo->resist = 0; - damageInfo->blocked_amount = 0; +void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, WeaponAttackType attackType /*= BASE_ATTACK*/) +{ + damageInfo->Attacker = this; + damageInfo->Target = victim; - damageInfo->TargetState = 0; + damageInfo->DamageSchoolMask = GetMeleeDamageSchoolMask(attackType); + damageInfo->Damage = 0; + damageInfo->OriginalDamage = 0; + damageInfo->Absorb = 0; + damageInfo->Resist = 0; + + damageInfo->Blocked = 0; damageInfo->HitInfo = 0; - damageInfo->procAttacker = PROC_FLAG_NONE; - damageInfo->procVictim = PROC_FLAG_NONE; - damageInfo->hitOutCome = MELEE_HIT_EVADE; + 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; @@ -1237,12 +1239,12 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam switch (attackType) { case BASE_ATTACK: - damageInfo->procAttacker = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_MAINHAND_ATTACK; - damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; + damageInfo->ProcAttacker = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_MAINHAND_ATTACK; + damageInfo->ProcVictim = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; break; case OFF_ATTACK: - damageInfo->procAttacker = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK; - damageInfo->procVictim = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; + damageInfo->ProcAttacker = PROC_FLAG_DONE_MELEE_AUTO_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK; + damageInfo->ProcVictim = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK; damageInfo->HitInfo = HITINFO_OFFHAND; break; default: @@ -1250,54 +1252,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; + 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, DIRECT_DAMAGE); - damage = damageInfo->target->MeleeDamageBonusTaken(this, damage, damageInfo->attackType, DIRECT_DAMAGE); + damage = MeleeDamageBonusDone(damageInfo->Target, damage, damageInfo->AttackType, DIRECT_DAMAGE, nullptr, SpellSchoolMask(damageInfo->DamageSchoolMask)); + damage = damageInfo->Target->MeleeDamageBonusTaken(this, damage, damageInfo->AttackType, DIRECT_DAMAGE, 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->originalDamage = damageInfo->damage; - 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->TargetState = VICTIMSTATE_INTACT; - damageInfo->originalDamage = damageInfo->damage; - damageInfo->damage = 0; - damageInfo->cleanDamage = 0; + damageInfo->OriginalDamage = damageInfo->Damage; + + damageInfo->Damage = 0; + damageInfo->CleanDamage = 0; break; case MELEE_HIT_NORMAL: damageInfo->TargetState = VICTIMSTATE_HIT; - damageInfo->originalDamage = damageInfo->damage; + damageInfo->OriginalDamage = damageInfo->Damage; break; case MELEE_HIT_CRIT: { @@ -1305,58 +1310,63 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damageInfo->TargetState = VICTIMSTATE_HIT; // Crit bonus calc - damageInfo->damage += damageInfo->damage; + damageInfo->Damage *= 2; // Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS - float mod = (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, damageInfo->damageSchoolMask) - 1.0f) * 100; + float 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; + damageInfo->OriginalDamage = damageInfo->Damage; break; } case MELEE_HIT_PARRY: damageInfo->TargetState = VICTIMSTATE_PARRY; - damageInfo->originalDamage = damageInfo->damage; - 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->originalDamage = damageInfo->damage; - damageInfo->cleanDamage += damageInfo->damage; - damageInfo->damage = 0; + 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->originalDamage = damageInfo->damage; // 30% damage blocked, double blocked amount if block is critical - damageInfo->blocked_amount = CalculatePct(damageInfo->damage, damageInfo->target->isBlockCritical() ? damageInfo->target->GetBlockPercent(getLevel()) * 2 : damageInfo->target->GetBlockPercent(getLevel())); - damageInfo->damage -= damageInfo->blocked_amount; - damageInfo->cleanDamage += damageInfo->blocked_amount; + damageInfo->Blocked = CalculatePct(damageInfo->Damage, damageInfo->Target->GetBlockPercent(getLevel())); + 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; - damageInfo->originalDamage = damageInfo->damage; int32 leveldif = int32(victim->getLevel()) - int32(getLevel()); if (leveldif > 3) leveldif = 3; + 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); + 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->originalDamage = damageInfo->damage; + damageInfo->Damage += (damageInfo->Damage / 2); + damageInfo->OriginalDamage = damageInfo->Damage; break; default: break; @@ -1366,39 +1376,39 @@ 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; - damageInfo->originalDamage -= resilienceReduction; + resilienceReduction = damageInfo->Damage - resilienceReduction; + damageInfo->Damage -= resilienceReduction; + damageInfo->CleanDamage += resilienceReduction; + damageInfo->OriginalDamage -= resilienceReduction; // Calculate absorb resist - if (int32(damageInfo->damage) > 0) + if (int32(damageInfo->Damage) > 0) { - damageInfo->procVictim |= PROC_FLAG_TAKEN_DAMAGE; + damageInfo->ProcVictim |= PROC_FLAG_TAKEN_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; @@ -1406,7 +1416,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) // Hmmmm dont like this emotes client must by self do all animations if (damageInfo->HitInfo & HITINFO_CRITICALHIT) victim->HandleEmoteCommand(EMOTE_ONESHOT_WOUND_CRITICAL); - if (damageInfo->blocked_amount && damageInfo->TargetState != VICTIMSTATE_BLOCKS) + if (damageInfo->Blocked && damageInfo->TargetState != VICTIMSTATE_BLOCKS) victim->HandleEmoteCommand(EMOTE_ONESHOT_PARRY_SHIELD); if (damageInfo->TargetState == VICTIMSTATE_PARRY && @@ -1443,11 +1453,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()) { @@ -1476,7 +1486,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 @@ -1634,7 +1644,7 @@ void Unit::HandleEmoteCommand(uint32 anim_id, Trinity::IteratorPair<int32 const* return damage; float mitigation = std::min(armor / (armor + armorConstant), 0.85f); - return std::max<uint32>(damage * (1.0f - mitigation), 1); + return std::max<uint32>(damage * (1.0f - mitigation), 0); } /*static*/ uint32 Unit::CalcSpellResistedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) @@ -2072,18 +2082,18 @@ 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(damageInfo.attacker, victim, damageInfo.damage, &damageInfo.absorb); + Unit::DealDamageMods(damageInfo.Attacker, victim, damageInfo.Damage, &damageInfo.Absorb); SendAttackStateUpdate(&damageInfo); 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); 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_amount, damageInfo.resist); + GetGUID().ToString().c_str(), victim->GetGUID().ToString().c_str(), damageInfo.Damage, damageInfo.Absorb, damageInfo.Blocked, damageInfo.Resist); } else { @@ -2122,25 +2132,27 @@ void Unit::FakeAttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BA SetFacingToObject(victim, false); // update client side facing to face the target (prevents visual glitches when casting untargeted spells) CalcDamageInfo damageInfo; - damageInfo.attacker = this; - damageInfo.target = victim; - damageInfo.damageSchoolMask = GetMeleeDamageSchoolMask(); - damageInfo.attackType = attType; - damageInfo.damage = 0; - damageInfo.originalDamage = 0; - damageInfo.cleanDamage = 0; - damageInfo.absorb = 0; - damageInfo.resist = 0; - damageInfo.blocked_amount = 0; + damageInfo.Attacker = this; + damageInfo.Target = victim; + + damageInfo.DamageSchoolMask = GetMeleeDamageSchoolMask(); + damageInfo.OriginalDamage = 0; + damageInfo.Damage = 0; + damageInfo.Absorb = 0; + damageInfo.Resist = 0; + + damageInfo.AttackType = attType; + damageInfo.CleanDamage = 0; + damageInfo.Blocked = 0; damageInfo.TargetState = VICTIMSTATE_HIT; damageInfo.HitInfo = HITINFO_AFFECTS_VICTIM | HITINFO_NORMALSWING | HITINFO_FAKE_DAMAGE; if (attType == OFF_ATTACK) damageInfo.HitInfo |= HITINFO_OFFHAND; - damageInfo.procAttacker = PROC_FLAG_NONE; - damageInfo.procVictim = PROC_FLAG_NONE; - damageInfo.hitOutCome = MELEE_HIT_NORMAL; + damageInfo.ProcAttacker = PROC_FLAG_NONE; + damageInfo.ProcVictim = PROC_FLAG_NONE; + damageInfo.HitOutCome = MELEE_HIT_NORMAL; SendAttackStateUpdate(&damageInfo); } @@ -2315,9 +2327,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)); } @@ -5407,27 +5416,27 @@ 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; - packet.OriginalDamage = damageInfo->originalDamage; - int32 overkill = damageInfo->damage - damageInfo->target->GetHealth(); + packet.AttackerGUID = damageInfo->Attacker->GetGUID(); + packet.VictimGUID = damageInfo->Target->GetGUID(); + packet.Damage = damageInfo->Damage; + packet.OriginalDamage = damageInfo->OriginalDamage; + int32 overkill = damageInfo->Damage - damageInfo->Target->GetHealth(); packet.OverDamage = (overkill < 0 ? -1 : overkill); packet.SubDmg = boost::in_place(); - 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; - packet.LogData.Initialize(damageInfo->attacker); + packet.LogData.Initialize(damageInfo->Attacker); WorldPackets::Spells::ContentTuningParams contentTuningParams; - if (contentTuningParams.GenerateDataForUnits(damageInfo->attacker, damageInfo->target)) + if (contentTuningParams.GenerateDataForUnits(damageInfo->Attacker, damageInfo->Target)) packet.ContentTuning = contentTuningParams; SendCombatLogMessage(&packet); @@ -5437,15 +5446,15 @@ 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.originalDamage = Damage; - dmgInfo.damageSchoolMask = damageSchoolMask; - dmgInfo.absorb = AbsorbDamage; - dmgInfo.resist = Resist; + dmgInfo.Attacker = this; + dmgInfo.Target = target; + dmgInfo.Damage = Damage - AbsorbDamage - Resist - BlockedAmount; + dmgInfo.OriginalDamage = Damage; + dmgInfo.DamageSchoolMask = damageSchoolMask; + dmgInfo.Absorb = AbsorbDamage; + dmgInfo.Resist = Resist; dmgInfo.TargetState = TargetState; - dmgInfo.blocked_amount = BlockedAmount; + dmgInfo.Blocked = BlockedAmount; SendAttackStateUpdate(&dmgInfo); } @@ -7736,7 +7745,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit return false; } -uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/) +uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/) { if (!pVictim || damage == 0) return 0; @@ -7779,26 +7788,29 @@ uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType // Done total percent damage auras float DoneTotalMod = 1.0f; - if (spellProto) + SpellSchoolMask schoolMask = spellProto ? spellProto->GetSchoolMask() : damageSchoolMask; + + if (!(schoolMask & SPELL_SCHOOL_MASK_NORMAL)) { // Some spells don't benefit from pct done mods // mods for SPELL_SCHOOL_MASK_NORMAL are already factored in base melee damage calculation - if (!spellProto->HasAttribute(SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS) && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_NORMAL)) + if (!spellProto || !spellProto->HasAttribute(SPELL_ATTR6_IGNORE_CASTER_DAMAGE_MODIFIERS)) { float maxModDamagePercentSchool = 0.0f; if (Player const* thisPlayer = ToPlayer()) { for (uint32 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - if (spellProto->GetSchoolMask() & (1 << i)) + if (schoolMask & (1 << i)) maxModDamagePercentSchool = std::max(maxModDamagePercentSchool, thisPlayer->m_activePlayerData->ModDamageDonePercent[i]); } else - maxModDamagePercentSchool = GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, spellProto->GetSchoolMask()); + maxModDamagePercentSchool = GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, schoolMask); DoneTotalMod *= maxModDamagePercentSchool; } } - else + + if (!spellProto) { // melee attack for (AuraEffect const* autoAttackDamage : GetAuraEffectsByType(SPELL_AURA_MOD_AUTOATTACK_DAMAGE)) @@ -7837,7 +7849,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType return uint32(std::max(tmpDamage, 0.0f)); } -uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto) +uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/) { if (pdamage == 0) return 0; @@ -7917,7 +7929,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT // Sanctified Wrath (bypass damage reduction) if (attacker && 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); @@ -10569,12 +10581,6 @@ void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTrigg } } -void Unit::TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo) -{ - DamageInfo dmgInfo = DamageInfo(damageInfo); - TriggerAurasProcOnEvent(nullptr, nullptr, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr); -} - void Unit::TriggerAurasProcOnEvent(AuraApplicationList* myProcAuras, AuraApplicationList* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) { // prepare data for self trigger @@ -10642,11 +10648,6 @@ void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProc SetCantProc(false); } -SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const -{ - return SPELL_SCHOOL_MASK_NORMAL; -} - ObjectGuid Unit::GetCharmerOrOwnerGUID() const { return !GetCharmerGUID().IsEmpty() ? GetCharmerGUID() : GetOwnerGUID(); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index dcae62ea32e..040b49cb70f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -522,22 +522,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 originalDamage; - 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 @@ -808,7 +809,7 @@ class TC_GAME_API Unit : public WorldObject bool IsWithinCombatRange(Unit const* obj, float dist2compare) const; bool IsWithinMeleeRange(Unit const* obj) const; float GetMeleeRange(Unit const* target) const; - virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; + virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK) const = 0; bool IsWithinBoundaryRadius(const Unit* obj) const; void GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, float distance2dMin, float distance2dMax) const; uint32 m_extraAttacks; @@ -1030,7 +1031,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(AuraApplicationList* myProcAuras, AuraApplicationList* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, @@ -1041,7 +1041,7 @@ class TC_GAME_API Unit : public WorldObject void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false); void FakeAttackerStateUpdate(Unit* victim, WeaponAttackType attType = BASE_ATTACK); - 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); @@ -1701,8 +1701,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, SpellEffectInfo const* effect, uint32 stack = 1) const; - uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr); - uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr); + uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL); + uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL); bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK); bool isBlockCritical(); |