feat(Core/Items): Implemented elemental weapon damage. Source: Trinit… (#13050)
...yCore.
This commit is contained in:
@@ -2156,7 +2156,7 @@ void Creature::LoadSpellTemplateImmunity()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
|
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo, Spell const* spell)
|
||||||
{
|
{
|
||||||
if (!spellInfo)
|
if (!spellInfo)
|
||||||
return false;
|
return false;
|
||||||
@@ -2178,7 +2178,7 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
|
|||||||
if (immunedToAllEffects)
|
if (immunedToAllEffects)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return Unit::IsImmunedToSpell(spellInfo);
|
return Unit::IsImmunedToSpell(spellInfo, spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
|
bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public:
|
|||||||
[[nodiscard]] bool IsValidTrainerForPlayer(Player* player, uint32* npcFlags = nullptr) const;
|
[[nodiscard]] bool IsValidTrainerForPlayer(Player* player, uint32* npcFlags = nullptr) const;
|
||||||
bool CanCreatureAttack(Unit const* victim, bool skipDistCheck = false) const;
|
bool CanCreatureAttack(Unit const* victim, bool skipDistCheck = false) const;
|
||||||
void LoadSpellTemplateImmunity();
|
void LoadSpellTemplateImmunity();
|
||||||
bool IsImmunedToSpell(SpellInfo const* spellInfo) override;
|
bool IsImmunedToSpell(SpellInfo const* spellInfo, Spell const* spell = nullptr) override;
|
||||||
|
|
||||||
[[nodiscard]] bool HasMechanicTemplateImmunity(uint32 mask) const;
|
[[nodiscard]] bool HasMechanicTemplateImmunity(uint32 mask) const;
|
||||||
// redefine Unit::IsImmunedToSpell
|
// redefine Unit::IsImmunedToSpell
|
||||||
@@ -155,7 +155,7 @@ public:
|
|||||||
return (getLevel() / 2 + uint32(GetStat(STAT_STRENGTH) / 20));
|
return (getLevel() / 2 + uint32(GetStat(STAT_STRENGTH) / 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] SpellSchoolMask GetMeleeDamageSchoolMask() const override { return m_meleeDamageSchoolMask; }
|
[[nodiscard]] SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType /*attackType*/ = BASE_ATTACK, uint8 /*damageIndex*/ = 0) const override { return m_meleeDamageSchoolMask; }
|
||||||
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
|
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
|
||||||
|
|
||||||
void _AddCreatureSpellCooldown(uint32 spell_id, uint16 categoryId, uint32 end_time);
|
void _AddCreatureSpellCooldown(uint32 spell_id, uint16 categoryId, uint32 end_time);
|
||||||
@@ -178,7 +178,7 @@ public:
|
|||||||
void UpdateMaxHealth() override;
|
void UpdateMaxHealth() override;
|
||||||
void UpdateMaxPower(Powers power) override;
|
void UpdateMaxPower(Powers power) override;
|
||||||
void UpdateAttackPowerAndDamage(bool ranged = false) override;
|
void UpdateAttackPowerAndDamage(bool ranged = false) override;
|
||||||
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override;
|
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex) override;
|
||||||
|
|
||||||
void SetCanDualWield(bool value) override;
|
void SetCanDualWield(bool value) override;
|
||||||
[[nodiscard]] int8 GetOriginalEquipmentId() const { return m_originalEquipmentId; }
|
[[nodiscard]] int8 GetOriginalEquipmentId() const { return m_originalEquipmentId; }
|
||||||
|
|||||||
@@ -6740,21 +6740,11 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
|
|||||||
if (proto->ArcaneRes)
|
if (proto->ArcaneRes)
|
||||||
HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply);
|
HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply);
|
||||||
|
|
||||||
WeaponAttackType attType = BASE_ATTACK;
|
uint8 attType = Player::GetAttackBySlot(slot);
|
||||||
|
if (attType != MAX_ATTACK)
|
||||||
if (slot == EQUIPMENT_SLOT_RANGED && (
|
|
||||||
proto->InventoryType == INVTYPE_RANGED || proto->InventoryType == INVTYPE_THROWN ||
|
|
||||||
proto->InventoryType == INVTYPE_RANGEDRIGHT))
|
|
||||||
{
|
{
|
||||||
attType = RANGED_ATTACK;
|
|
||||||
}
|
|
||||||
else if (slot == EQUIPMENT_SLOT_OFFHAND)
|
|
||||||
{
|
|
||||||
attType = OFF_ATTACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CanUseAttackType(attType))
|
|
||||||
_ApplyWeaponDamage(slot, proto, ssv, apply);
|
_ApplyWeaponDamage(slot, proto, ssv, apply);
|
||||||
|
}
|
||||||
|
|
||||||
// Druids get feral AP bonus from weapon dps (also use DPS from ScalingStatValue)
|
// Druids get feral AP bonus from weapon dps (also use DPS from ScalingStatValue)
|
||||||
if (getClass() == CLASS_DRUID)
|
if (getClass() == CLASS_DRUID)
|
||||||
@@ -6797,45 +6787,56 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
|
|||||||
ssv = ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : nullptr;
|
ssv = ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
WeaponAttackType attType = BASE_ATTACK;
|
uint8 attType = Player::GetAttackBySlot(slot);
|
||||||
float damage = 0.0f;
|
if (!IsInFeralForm() && apply && !CanUseAttackType(attType))
|
||||||
|
|
||||||
if (slot == EQUIPMENT_SLOT_RANGED && (
|
|
||||||
proto->InventoryType == INVTYPE_RANGED || proto->InventoryType == INVTYPE_THROWN ||
|
|
||||||
proto->InventoryType == INVTYPE_RANGEDRIGHT))
|
|
||||||
{
|
{
|
||||||
attType = RANGED_ATTACK;
|
return;
|
||||||
}
|
|
||||||
else if (slot == EQUIPMENT_SLOT_OFFHAND)
|
|
||||||
{
|
|
||||||
attType = OFF_ATTACK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float minDamage = proto->Damage[0].DamageMin;
|
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||||
float maxDamage = proto->Damage[0].DamageMax;
|
|
||||||
|
|
||||||
// If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage
|
|
||||||
if (ssv)
|
|
||||||
{
|
{
|
||||||
int32 extraDPS = ssv->getDPSMod(ScalingStatValue);
|
float minDamage = proto->Damage[i].DamageMin;
|
||||||
if (extraDPS)
|
float maxDamage = proto->Damage[i].DamageMax;
|
||||||
|
|
||||||
|
// If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage
|
||||||
|
if (ssv)
|
||||||
{
|
{
|
||||||
float average = extraDPS * proto->Delay / 1000.0f;
|
int32 extraDPS = ssv->getDPSMod(ScalingStatValue);
|
||||||
minDamage = 0.7f * average;
|
if (extraDPS)
|
||||||
maxDamage = 1.3f * average;
|
{
|
||||||
|
float average = extraDPS * proto->Delay / 1000.0f;
|
||||||
|
minDamage = 0.7f * average;
|
||||||
|
maxDamage = 1.3f * average;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apply)
|
||||||
|
{
|
||||||
|
if (minDamage > 0.f)
|
||||||
|
{
|
||||||
|
SetBaseWeaponDamage(WeaponAttackType(attType), MINDAMAGE, minDamage, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxDamage > 0.f)
|
||||||
|
{
|
||||||
|
SetBaseWeaponDamage(WeaponAttackType(attType), MAXDAMAGE, maxDamage, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minDamage > 0)
|
if (!apply)
|
||||||
{
|
{
|
||||||
damage = apply ? minDamage : BASE_MINDAMAGE;
|
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||||
SetBaseWeaponDamage(attType, MINDAMAGE, damage);
|
{
|
||||||
}
|
SetBaseWeaponDamage(WeaponAttackType(attType), MINDAMAGE, 0.f, i);
|
||||||
|
SetBaseWeaponDamage(WeaponAttackType(attType), MAXDAMAGE, 0.f, i);
|
||||||
|
}
|
||||||
|
|
||||||
if (maxDamage > 0)
|
if (attType == BASE_ATTACK)
|
||||||
{
|
{
|
||||||
damage = apply ? maxDamage : BASE_MAXDAMAGE;
|
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, BASE_MINDAMAGE);
|
||||||
SetBaseWeaponDamage(attType, MAXDAMAGE, damage);
|
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, BASE_MAXDAMAGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proto->Delay && !IsInFeralForm())
|
if (proto->Delay && !IsInFeralForm())
|
||||||
@@ -6852,8 +6853,18 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
|
|||||||
if (IsInFeralForm())
|
if (IsInFeralForm())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CanModifyStats() && (damage || proto->Delay))
|
if (CanModifyStats() && (GetWeaponDamageRange(WeaponAttackType(attType), MAXDAMAGE) || proto->Delay))
|
||||||
UpdateDamagePhysical(attType);
|
UpdateDamagePhysical(WeaponAttackType(attType));
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/, uint8 damageIndex /*= 0*/) const
|
||||||
|
{
|
||||||
|
if (Item const* weapon = GetWeaponForAttack(attackType, true))
|
||||||
|
{
|
||||||
|
return SpellSchoolMask(1 << weapon->GetTemplate()->Damage[damageIndex].DamageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPELL_SCHOOL_MASK_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply)
|
void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply)
|
||||||
|
|||||||
@@ -1905,7 +1905,7 @@ public:
|
|||||||
void UpdateRating(CombatRating cr);
|
void UpdateRating(CombatRating cr);
|
||||||
void UpdateAllRatings();
|
void UpdateAllRatings();
|
||||||
|
|
||||||
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) override;
|
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex) override;
|
||||||
|
|
||||||
void UpdateDefenseBonusesMod();
|
void UpdateDefenseBonusesMod();
|
||||||
inline void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);}
|
inline void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);}
|
||||||
@@ -2147,6 +2147,8 @@ public:
|
|||||||
|
|
||||||
void ResetAllPowers();
|
void ResetAllPowers();
|
||||||
|
|
||||||
|
SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const override;
|
||||||
|
|
||||||
void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply);
|
void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply);
|
||||||
void _ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
|
void _ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
|
||||||
void _ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
|
void _ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
|
||||||
|
|||||||
@@ -59,25 +59,31 @@ void Unit::UpdateAllResistances()
|
|||||||
|
|
||||||
void Unit::UpdateDamagePhysical(WeaponAttackType attType)
|
void Unit::UpdateDamagePhysical(WeaponAttackType attType)
|
||||||
{
|
{
|
||||||
float minDamage = 0.0f;
|
float totalMin = 0.f;
|
||||||
float maxDamage = 0.0f;
|
float totalMax = 0.f;
|
||||||
|
|
||||||
CalculateMinMaxDamage(attType, false, true, minDamage, maxDamage);
|
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||||
|
{
|
||||||
|
float tmpMin, tmpMax;
|
||||||
|
CalculateMinMaxDamage(attType, false, true, tmpMin, tmpMax, i);
|
||||||
|
totalMin += tmpMin;
|
||||||
|
totalMax += tmpMax;
|
||||||
|
}
|
||||||
|
|
||||||
switch (attType)
|
switch (attType)
|
||||||
{
|
{
|
||||||
case BASE_ATTACK:
|
case BASE_ATTACK:
|
||||||
default:
|
default:
|
||||||
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, minDamage);
|
SetStatFloatValue(UNIT_FIELD_MINDAMAGE, totalMin);
|
||||||
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxDamage);
|
SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, totalMax);
|
||||||
break;
|
break;
|
||||||
case OFF_ATTACK:
|
case OFF_ATTACK:
|
||||||
SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, minDamage);
|
SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, totalMin);
|
||||||
SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxDamage);
|
SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, totalMax);
|
||||||
break;
|
break;
|
||||||
case RANGED_ATTACK:
|
case RANGED_ATTACK:
|
||||||
SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, minDamage);
|
SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, totalMin);
|
||||||
SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxDamage);
|
SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, totalMax);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -525,8 +531,23 @@ void Player::UpdateShieldBlockValue()
|
|||||||
SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue());
|
SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
|
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex)
|
||||||
{
|
{
|
||||||
|
// Only proto damage, not affected by any mods
|
||||||
|
if (damageIndex != 0)
|
||||||
|
{
|
||||||
|
minDamage = 0.0f;
|
||||||
|
maxDamage = 0.0f;
|
||||||
|
|
||||||
|
if (!IsInFeralForm() && CanUseAttackType(attType))
|
||||||
|
{
|
||||||
|
minDamage = GetWeaponDamageRange(attType, MINDAMAGE, damageIndex);
|
||||||
|
maxDamage = GetWeaponDamageRange(attType, MAXDAMAGE, damageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UnitMods unitMod;
|
UnitMods unitMod;
|
||||||
|
|
||||||
switch (attType)
|
switch (attType)
|
||||||
@@ -1075,8 +1096,16 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
|
void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex /*= 0*/)
|
||||||
{
|
{
|
||||||
|
// creatures only have one damage
|
||||||
|
if (damageIndex != 0)
|
||||||
|
{
|
||||||
|
minDamage = 0.f;
|
||||||
|
maxDamage = 0.f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UnitMods unitMod;
|
UnitMods unitMod;
|
||||||
float variance = 1.0f;
|
float variance = 1.0f;
|
||||||
switch (attType)
|
switch (attType)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@
|
|||||||
#include "FollowerRefMgr.h"
|
#include "FollowerRefMgr.h"
|
||||||
#include "FollowerReference.h"
|
#include "FollowerReference.h"
|
||||||
#include "HostileRefMgr.h"
|
#include "HostileRefMgr.h"
|
||||||
|
#include "ItemTemplate.h"
|
||||||
#include "MotionMaster.h"
|
#include "MotionMaster.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "Optional.h"
|
#include "Optional.h"
|
||||||
@@ -251,7 +252,9 @@ enum UnitModifierType
|
|||||||
enum WeaponDamageRange
|
enum WeaponDamageRange
|
||||||
{
|
{
|
||||||
MINDAMAGE,
|
MINDAMAGE,
|
||||||
MAXDAMAGE
|
MAXDAMAGE,
|
||||||
|
|
||||||
|
MAX_WEAPON_DAMAGE_RANGE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UnitMods
|
enum UnitMods
|
||||||
@@ -762,9 +765,14 @@ private:
|
|||||||
uint32 m_resist;
|
uint32 m_resist;
|
||||||
uint32 m_block;
|
uint32 m_block;
|
||||||
uint32 m_cleanDamage;
|
uint32 m_cleanDamage;
|
||||||
|
|
||||||
|
// amalgamation constructor (used for proc)
|
||||||
|
DamageInfo(DamageInfo const& dmg1, DamageInfo const& dmg2);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage = 0);
|
explicit DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage = 0);
|
||||||
explicit DamageInfo(CalcDamageInfo& dmgInfo);
|
explicit DamageInfo(CalcDamageInfo const& dmgInfo); // amalgamation wrapper
|
||||||
|
DamageInfo(CalcDamageInfo const& dmgInfo, uint8 damageIndex);
|
||||||
DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType);
|
DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType);
|
||||||
|
|
||||||
void ModifyDamage(int32 amount);
|
void ModifyDamage(int32 amount);
|
||||||
@@ -868,10 +876,15 @@ struct CalcDamageInfo
|
|||||||
{
|
{
|
||||||
Unit* attacker; // Attacker
|
Unit* attacker; // Attacker
|
||||||
Unit* target; // Target for damage
|
Unit* target; // Target for damage
|
||||||
uint32 damageSchoolMask;
|
|
||||||
uint32 damage;
|
struct
|
||||||
uint32 absorb;
|
{
|
||||||
uint32 resist;
|
uint32 damageSchoolMask;
|
||||||
|
uint32 damage;
|
||||||
|
uint32 absorb;
|
||||||
|
uint32 resist;
|
||||||
|
} damages[MAX_ITEM_PROTO_DAMAGES];
|
||||||
|
|
||||||
uint32 blocked_amount;
|
uint32 blocked_amount;
|
||||||
uint32 HitInfo;
|
uint32 HitInfo;
|
||||||
uint32 TargetState;
|
uint32 TargetState;
|
||||||
@@ -1331,7 +1344,7 @@ public:
|
|||||||
bool IsWithinCombatRange(Unit const* obj, float dist2compare) const;
|
bool IsWithinCombatRange(Unit const* obj, float dist2compare) const;
|
||||||
bool IsWithinMeleeRange(Unit const* obj, float dist = 0.f) const;
|
bool IsWithinMeleeRange(Unit const* obj, float dist = 0.f) const;
|
||||||
float GetMeleeRange(Unit const* target) const;
|
float GetMeleeRange(Unit const* target) const;
|
||||||
[[nodiscard]] virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;
|
virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const = 0;
|
||||||
bool GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, bool force = false) const;
|
bool GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, bool force = false) const;
|
||||||
uint32 m_extraAttacks;
|
uint32 m_extraAttacks;
|
||||||
bool m_canDualWield;
|
bool m_canDualWield;
|
||||||
@@ -1540,7 +1553,7 @@ public:
|
|||||||
void HandleEmoteCommand(uint32 emoteId);
|
void HandleEmoteCommand(uint32 emoteId);
|
||||||
void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false, bool ignoreCasting = false);
|
void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false, bool ignoreCasting = false);
|
||||||
|
|
||||||
void CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK, const bool sittingVictim = false);
|
void CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK, const bool sittingVictim = false);
|
||||||
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
|
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
|
||||||
|
|
||||||
void HandleProcExtraAttackFor(Unit* victim, uint32 count);
|
void HandleProcExtraAttackFor(Unit* victim, uint32 count);
|
||||||
@@ -1570,10 +1583,11 @@ public:
|
|||||||
|
|
||||||
static void ApplyResilience(Unit const* victim, float* crit, int32* damage, bool isCrit, CombatRating type);
|
static void ApplyResilience(Unit const* victim, float* crit, int32* damage, bool isCrit, CombatRating type);
|
||||||
|
|
||||||
float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const;
|
[[nodiscard]] float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const;
|
||||||
SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spell);
|
[[nodiscard]] SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spell);
|
||||||
SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spell);
|
[[nodiscard]] SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spell);
|
||||||
SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spell, bool canReflect = false);
|
[[nodiscard]] SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spell, bool canReflect = false);
|
||||||
|
[[nodiscard]] SpellMissInfo SpellHitResult(Unit* victim, Spell const* spell, bool canReflect = false);
|
||||||
|
|
||||||
[[nodiscard]] float GetUnitDodgeChance() const;
|
[[nodiscard]] float GetUnitDodgeChance() const;
|
||||||
[[nodiscard]] float GetUnitParryChance() const;
|
[[nodiscard]] float GetUnitParryChance() const;
|
||||||
@@ -2091,10 +2105,10 @@ public:
|
|||||||
virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0;
|
virtual void UpdateAttackPowerAndDamage(bool ranged = false) = 0;
|
||||||
virtual void UpdateDamagePhysical(WeaponAttackType attType);
|
virtual void UpdateDamagePhysical(WeaponAttackType attType);
|
||||||
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit* pVictim = nullptr) const;
|
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit* pVictim = nullptr) const;
|
||||||
[[nodiscard]] float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const;
|
[[nodiscard]] float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type, uint8 damageIndex = 0) const;
|
||||||
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
|
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value, uint8 damageIndex = 0) { m_weaponDamage[attType][damageRange][damageIndex] = value; }
|
||||||
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) = 0;
|
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex = 0) = 0;
|
||||||
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct);
|
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask = 0);
|
||||||
float GetAPMultiplier(WeaponAttackType attType, bool normalized);
|
float GetAPMultiplier(WeaponAttackType attType, bool normalized);
|
||||||
|
|
||||||
bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const;
|
bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const;
|
||||||
@@ -2179,8 +2193,8 @@ public:
|
|||||||
uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod = 0.0f, uint32 stack = 1);
|
uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod = 0.0f, uint32 stack = 1);
|
||||||
uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
|
uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
|
||||||
|
|
||||||
uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr);
|
uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL);
|
||||||
uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr);
|
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, WeaponAttackType attackType = BASE_ATTACK);
|
bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK);
|
||||||
bool isBlockCritical();
|
bool isBlockCritical();
|
||||||
@@ -2201,12 +2215,14 @@ public:
|
|||||||
|
|
||||||
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply, SpellImmuneBlockType blockType = SPELL_BLOCK_TYPE_ALL);
|
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply, SpellImmuneBlockType blockType = SPELL_BLOCK_TYPE_ALL);
|
||||||
void ApplySpellDispelImmunity(SpellInfo const* spellProto, DispelType type, bool apply);
|
void ApplySpellDispelImmunity(SpellInfo const* spellProto, DispelType type, bool apply);
|
||||||
virtual bool IsImmunedToSpell(SpellInfo const* spellInfo);
|
virtual bool IsImmunedToSpell(SpellInfo const* spellInfo, Spell const* spell = nullptr);
|
||||||
// redefined in Creature
|
// redefined in Creature
|
||||||
[[nodiscard]] bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const;
|
[[nodiscard]] bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const;
|
||||||
bool IsImmunedToDamage(SpellInfo const* spellInfo) const;
|
[[nodiscard]] bool IsImmunedToDamage(SpellInfo const* spellInfo) const;
|
||||||
|
[[nodiscard]] bool IsImmunedToDamage(Spell const* spell) const;
|
||||||
[[nodiscard]] bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const;
|
[[nodiscard]] bool IsImmunedToSchool(SpellSchoolMask meleeSchoolMask) const;
|
||||||
bool IsImmunedToSchool(SpellInfo const* spellInfo) const;
|
[[nodiscard]] bool IsImmunedToSchool(SpellInfo const* spellInfo) const;
|
||||||
|
[[nodiscard]] bool IsImmunedToSchool(Spell const* spell) const;
|
||||||
[[nodiscard]] bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const;
|
[[nodiscard]] bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const;
|
||||||
bool IsImmunedToDamageOrSchool(SpellInfo const* spellInfo) const;
|
bool IsImmunedToDamageOrSchool(SpellInfo const* spellInfo) const;
|
||||||
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const;
|
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const;
|
||||||
@@ -2484,7 +2500,7 @@ protected:
|
|||||||
uint32 m_interruptMask;
|
uint32 m_interruptMask;
|
||||||
|
|
||||||
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
|
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
|
||||||
float m_weaponDamage[MAX_ATTACK][2];
|
float m_weaponDamage[MAX_ATTACK][MAX_WEAPON_DAMAGE_RANGE][MAX_ITEM_PROTO_DAMAGES];
|
||||||
bool m_canModifyStats;
|
bool m_canModifyStats;
|
||||||
VisibleAuraMap m_visibleAuras;
|
VisibleAuraMap m_visibleAuras;
|
||||||
|
|
||||||
|
|||||||
@@ -2428,9 +2428,11 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
|
|||||||
// Calculate hit result
|
// Calculate hit result
|
||||||
if (m_originalCaster)
|
if (m_originalCaster)
|
||||||
{
|
{
|
||||||
targetInfo.missCondition = m_originalCaster->SpellHitResult(target, m_spellInfo, m_canReflect);
|
targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
|
||||||
if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
|
if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
|
||||||
|
{
|
||||||
targetInfo.missCondition = SPELL_MISS_NONE;
|
targetInfo.missCondition = SPELL_MISS_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
|
targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
|
||||||
@@ -2458,7 +2460,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
|
|||||||
if (targetInfo.missCondition == SPELL_MISS_REFLECT)
|
if (targetInfo.missCondition == SPELL_MISS_REFLECT)
|
||||||
{
|
{
|
||||||
// Calculate reflected spell result on caster
|
// Calculate reflected spell result on caster
|
||||||
targetInfo.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, m_canReflect);
|
targetInfo.reflectResult = m_caster->SpellHitResult(m_caster, this, m_canReflect);
|
||||||
|
|
||||||
if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
|
if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
|
||||||
targetInfo.reflectResult = SPELL_MISS_PARRY;
|
targetInfo.reflectResult = SPELL_MISS_PARRY;
|
||||||
@@ -2971,8 +2973,10 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
|
|||||||
return SPELL_MISS_EVADE;
|
return SPELL_MISS_EVADE;
|
||||||
|
|
||||||
// For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
|
// For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
|
||||||
if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(m_spellInfo)) || unit->IsImmunedToSchool(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))
|
if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(this)) || unit->IsImmunedToSchool(this) || unit->IsImmunedToSpell(m_spellInfo, this)))
|
||||||
|
{
|
||||||
return SPELL_MISS_IMMUNE;
|
return SPELL_MISS_IMMUNE;
|
||||||
|
}
|
||||||
|
|
||||||
// disable effects to which unit is immune
|
// disable effects to which unit is immune
|
||||||
SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
|
SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
|
||||||
|
|||||||
@@ -589,6 +589,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] TriggerCastFlags GetTriggeredCastFlags() const { return _triggeredCastFlags; }
|
[[nodiscard]] TriggerCastFlags GetTriggeredCastFlags() const { return _triggeredCastFlags; }
|
||||||
|
|
||||||
|
[[nodiscard]] SpellSchoolMask GetSpellSchoolMask() const { return m_spellSchoolMask; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool HasGlobalCooldown() const;
|
bool HasGlobalCooldown() const;
|
||||||
void TriggerGlobalCooldown();
|
void TriggerGlobalCooldown();
|
||||||
|
|||||||
@@ -593,8 +593,14 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
|
|||||||
if (Player* caster = m_caster->ToPlayer())
|
if (Player* caster = m_caster->ToPlayer())
|
||||||
{
|
{
|
||||||
// Add Ammo and Weapon damage plus RAP * 0.1
|
// Add Ammo and Weapon damage plus RAP * 0.1
|
||||||
float dmg_min = caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE);
|
float dmg_min = 0.f;
|
||||||
float dmg_max = caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE);
|
float dmg_max = 0.f;
|
||||||
|
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||||
|
{
|
||||||
|
dmg_min += caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE, i);
|
||||||
|
dmg_max += caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE, i);
|
||||||
|
}
|
||||||
|
|
||||||
if (dmg_max == 0.0f && dmg_min > dmg_max)
|
if (dmg_max == 0.0f && dmg_min > dmg_max)
|
||||||
{
|
{
|
||||||
damage += int32(dmg_min);
|
damage += int32(dmg_min);
|
||||||
@@ -616,9 +622,17 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
|
|||||||
// Add main hand dps * effect[2] amount
|
// Add main hand dps * effect[2] amount
|
||||||
if (Player* player = m_caster->ToPlayer())
|
if (Player* player = m_caster->ToPlayer())
|
||||||
{
|
{
|
||||||
float mindamage, maxdamage;
|
float minTotal = 0.f;
|
||||||
player->CalculateMinMaxDamage(BASE_ATTACK, false, false, mindamage, maxdamage);
|
float maxTotal = 0.f;
|
||||||
float average = (mindamage + maxdamage) / 2;
|
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||||
|
{
|
||||||
|
float tmpMin, tmpMax;
|
||||||
|
player->CalculateMinMaxDamage(BASE_ATTACK, false, false, tmpMin, tmpMax, i);
|
||||||
|
minTotal += tmpMin;
|
||||||
|
maxTotal += tmpMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
float average = (minTotal + maxTotal) / 2;
|
||||||
int32 count = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_2);
|
int32 count = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_2);
|
||||||
damage += count * int32(average * IN_MILLISECONDS) / m_caster->GetAttackTime(BASE_ATTACK);
|
damage += count * int32(average * IN_MILLISECONDS) / m_caster->GetAttackTime(BASE_ATTACK);
|
||||||
}
|
}
|
||||||
@@ -3644,8 +3658,8 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
|
|||||||
uint32 eff_damage(std::max(weaponDamage, 0));
|
uint32 eff_damage(std::max(weaponDamage, 0));
|
||||||
|
|
||||||
// Add melee damage bonuses (also check for negative)
|
// Add melee damage bonuses (also check for negative)
|
||||||
eff_damage = m_caster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo);
|
eff_damage = m_caster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo, m_spellSchoolMask);
|
||||||
eff_damage = unitTarget->MeleeDamageBonusTaken(m_caster, eff_damage, m_attackType, m_spellInfo);
|
eff_damage = unitTarget->MeleeDamageBonusTaken(m_caster, eff_damage, m_attackType, m_spellInfo, m_spellSchoolMask);
|
||||||
|
|
||||||
// Meteor like spells (divided damage to targets)
|
// Meteor like spells (divided damage to targets)
|
||||||
if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_SHARE_DAMAGE))
|
if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_SHARE_DAMAGE))
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Player.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "SpellScript.h"
|
#include "SpellScript.h"
|
||||||
@@ -131,13 +132,25 @@ struct boss_viscidus : public BossAI
|
|||||||
me->RemoveAurasDueToSpell(SPELL_INVIS_SELF);
|
me->RemoveAurasDueToSpell(SPELL_INVIS_SELF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType effType, SpellSchoolMask) override
|
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType effType, SpellSchoolMask spellSchoolMask) override
|
||||||
{
|
{
|
||||||
if (me->HealthBelowPct(5))
|
if (me->HealthBelowPct(5))
|
||||||
damage = 0;
|
damage = 0;
|
||||||
|
|
||||||
if (!attacker || _phase != PHASE_MELEE)
|
if (!attacker)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_phase != PHASE_MELEE)
|
||||||
|
{
|
||||||
|
if (_phase == PHASE_FROST && effType == DIRECT_DAMAGE && (spellSchoolMask & SPELL_SCHOOL_MASK_FROST) != 0)
|
||||||
|
{
|
||||||
|
++_hitcounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (effType == DIRECT_DAMAGE)
|
if (effType == DIRECT_DAMAGE)
|
||||||
++_hitcounter;
|
++_hitcounter;
|
||||||
@@ -183,14 +196,23 @@ struct boss_viscidus : public BossAI
|
|||||||
Talk(EMOTE_CRACK);
|
Talk(EMOTE_CRACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
|
||||||
{
|
{
|
||||||
if (spell->Id == SPELL_REJOIN_VISCIDUS)
|
if (spellInfo->Id == SPELL_REJOIN_VISCIDUS)
|
||||||
{
|
{
|
||||||
me->RemoveAuraFromStack(SPELL_VISCIDUS_SHRINKS);
|
me->RemoveAuraFromStack(SPELL_VISCIDUS_SHRINKS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((spell->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) && _phase == PHASE_FROST)
|
SpellSchoolMask spellSchoolMask = spellInfo->GetSchoolMask();
|
||||||
|
if (spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && spellInfo->EquippedItemSubClassMask & (1 << ITEM_SUBCLASS_WEAPON_WAND))
|
||||||
|
{
|
||||||
|
if (Item* pItem = caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK))
|
||||||
|
{
|
||||||
|
spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((spellSchoolMask & SPELL_SCHOOL_MASK_FROST) && _phase == PHASE_FROST)
|
||||||
{
|
{
|
||||||
++_hitcounter;
|
++_hitcounter;
|
||||||
|
|
||||||
|
|||||||
@@ -648,10 +648,13 @@ class spell_dk_dancing_rune_weapon : public AuraScript
|
|||||||
{
|
{
|
||||||
target = player->GetMeleeHitRedirectTarget(target);
|
target = player->GetMeleeHitRedirectTarget(target);
|
||||||
CalcDamageInfo damageInfo;
|
CalcDamageInfo damageInfo;
|
||||||
player->CalculateMeleeDamage(target, 0, &damageInfo, eventInfo.GetDamageInfo()->GetAttackType());
|
player->CalculateMeleeDamage(target, &damageInfo, eventInfo.GetDamageInfo()->GetAttackType());
|
||||||
Unit::DealDamageMods(target, damageInfo.damage, &damageInfo.absorb);
|
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||||
|
{
|
||||||
|
Unit::DealDamageMods(target, damageInfo.damages[i].damage, &damageInfo.damages[i].absorb);
|
||||||
|
damageInfo.damages[i].damage /= 2.0f;
|
||||||
|
}
|
||||||
damageInfo.attacker = dancingRuneWeapon;
|
damageInfo.attacker = dancingRuneWeapon;
|
||||||
damageInfo.damage /= 2.0f;
|
|
||||||
dancingRuneWeapon->SendAttackStateUpdate(&damageInfo);
|
dancingRuneWeapon->SendAttackStateUpdate(&damageInfo);
|
||||||
dancingRuneWeapon->DealMeleeDamage(&damageInfo, true);
|
dancingRuneWeapon->DealMeleeDamage(&damageInfo, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -567,8 +567,14 @@ class spell_warr_rend : public AuraScript
|
|||||||
// $0.2 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick
|
// $0.2 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick
|
||||||
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||||
int32 mws = caster->GetAttackTime(BASE_ATTACK);
|
int32 mws = caster->GetAttackTime(BASE_ATTACK);
|
||||||
float mwbMin = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
|
float mwbMin = 0.f;
|
||||||
float mwbMax = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
|
float mwbMax = 0.f;
|
||||||
|
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||||
|
{
|
||||||
|
mwbMin += caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE, i);
|
||||||
|
mwbMax += caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE, i);
|
||||||
|
}
|
||||||
|
|
||||||
float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.2f;
|
float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.2f;
|
||||||
amount += int32(caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), mwb));
|
amount += int32(caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), mwb));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user