aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp8
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp289
-rw-r--r--src/server/game/Entities/Unit/Unit.h38
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();