aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp3
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp393
-rw-r--r--src/server/game/Entities/Unit/Unit.h13
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp50
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp2
-rw-r--r--src/server/game/Handlers/PetHandler.cpp6
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp84
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h12
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp90
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h3
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp33
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp7
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp11
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp13
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp17
16 files changed, 505 insertions, 236 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 3f455b69a37..b5ec850e35a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7809,7 +7809,8 @@ void Player::UpdateArea(uint32 newArea)
{
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
pvpInfo.IsInNoPvPArea = true;
- CombatStopWithPets();
+ if (!duel)
+ CombatStopWithPets();
}
else
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 8d5aa293d06..98183d9594a 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3158,6 +3158,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask)
return;
aura->HandleAuraSpecificMods(aurApp, caster, true, false);
+ aura->HandleAuraSpecificPeriodics(aurApp, caster);
// apply effects of the aura
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
@@ -6922,23 +6923,14 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
if (GetTypeId() != TYPEID_PLAYER)
return false;
+ float averageDmg = 0;
// now compute approximate weapon damage by formula from wowwiki.com
- Item* item = NULL;
if (procFlags & PROC_FLAG_DONE_OFFHAND_ATTACK)
- item = ToPlayer()->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
+ averageDmg = (GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE)) / 2;
else
- item = ToPlayer()->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
-
- // dunno if it's really needed but will prevent any possible crashes
- if (!item)
- return false;
+ averageDmg = (GetFloatValue(UNIT_FIELD_MINDAMAGE) + GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2;
- ItemTemplate const* weapon = item->GetTemplate();
-
- float weaponDPS = weapon->DPS;
- float attackPower = GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f;
- float weaponSpeed = float(weapon->Delay) / 1000.0f;
- basepoints0 = int32((weaponDPS + attackPower) * weaponSpeed);
+ basepoints0 = int32(averageDmg);
break;
}
// Persistent Shield (Scarab Brooch trinket)
@@ -8420,39 +8412,162 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
if (Unit* owner = GetOwner())
return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype);
- // Done total percent damage auras
- float DoneTotalMod = 1.0f;
float ApCoeffMod = 1.0f;
int32 DoneTotal = 0;
+ // done scripted mod (take it from owner)
+ Unit const* owner = GetOwner() ? GetOwner() : this;
+ AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ {
+ if (!(*i)->IsAffectingSpell(spellProto))
+ continue;
+
+ switch ((*i)->GetMiscValue())
+ {
+ case 4418: // Increased Shock Damage
+ case 4554: // Increased Lightning Damage
+ case 4555: // Improved Moonfire
+ case 5142: // Increased Lightning Damage
+ case 5147: // Improved Consecration / Libram of Resurgence
+ case 5148: // Idol of the Shooting Star
+ case 6008: // Increased Lightning Damage
+ case 8627: // Totem of Hex
+ {
+ DoneTotal += (*i)->GetAmount();
+ break;
+ }
+ }
+ }
+
+ // Custom scripted damage
+ switch (spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_DEATHKNIGHT:
+ // Impurity (dummy effect)
+ if (GetTypeId() == TYPEID_PLAYER)
+ {
+ PlayerSpellMap playerSpells = ToPlayer()->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = playerSpells.begin(); itr != playerSpells.end(); ++itr)
+ {
+ if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
+ continue;
+ switch (itr->first)
+ {
+ case 49220:
+ case 49633:
+ case 49635:
+ case 49636:
+ case 49638:
+ if (SpellInfo const* proto = sSpellMgr->GetSpellInfo(itr->first))
+ AddPct(ApCoeffMod, proto->Effects[0].CalcValue());
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ // Done fixed damage bonus auras
+ int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
+ // Pets just add their bonus damage to their spell damage
+ // note that their spell damage is just gain of their own auras
+ if (HasUnitTypeMask(UNIT_MASK_GUARDIAN))
+ DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage();
+
+ // Check for table values
+ float coeff = 0;
+ SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
+ if (bonus)
+ {
+ if (damagetype == DOT)
+ {
+ coeff = bonus->dot_damage;
+ if (bonus->ap_dot_bonus > 0)
+ {
+ WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
+ float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
+ APbonus += GetTotalAttackPowerValue(attType);
+ DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus);
+ }
+ }
+ else
+ {
+ coeff = bonus->direct_damage;
+ if (bonus->ap_bonus > 0)
+ {
+ WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
+ float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
+ APbonus += GetTotalAttackPowerValue(attType);
+ DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);
+ }
+ }
+ }
+ // Default calculation
+ if (DoneAdvertisedBenefit)
+ {
+ if (!bonus || coeff < 0)
+ coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
+
+ float factorMod = CalculateLevelPenalty(spellProto) * stack;
+
+ if (Player* modOwner = GetSpellModOwner())
+ {
+ coeff *= 100.0f;
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
+ coeff /= 100.0f;
+ }
+ DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
+ }
+
+ // Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
+ float tmpDamage = (int32(pdamage) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellDamagePctDone(victim, spellProto, damagetype));
+ // apply spellmod to Done damage (flat and pct)
+ if (Player* modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
+
+ return uint32(std::max(tmpDamage, 0.0f));
+}
+
+float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const
+{
+ if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
+ return 1.0f;
+
+ // Some spells don't benefit from pct done mods
+ if (spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)
+ return 1.0f;
+
+ // For totems pct done mods are calculated when its calculation is run on the player in SpellDamageBonusDone.
+ if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem())
+ return 1.0f;
+
+ // Done total percent damage auras
+ float DoneTotalMod = 1.0f;
+
// Pet damage?
if (GetTypeId() == TYPEID_UNIT && !ToCreature()->IsPet())
DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank);
- // Some spells don't benefit from pct done mods
- if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS))
+ AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
{
- AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
- {
- if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1) //prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization)
- continue;
+ if (spellProto->EquippedItemClass == -1 && (*i)->GetSpellInfo()->EquippedItemClass != -1) //prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization)
+ continue;
- if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
- {
- if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
- AddPct(DoneTotalMod, (*i)->GetAmount());
- else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo()))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- }
+ if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
+ {
+ if ((*i)->GetSpellInfo()->EquippedItemClass == -1)
+ AddPct(DoneTotalMod, (*i)->GetAmount());
+ else if (!((*i)->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && ((*i)->GetSpellInfo()->EquippedItemSubClassMask == 0))
+ AddPct(DoneTotalMod, (*i)->GetAmount());
+ else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements((*i)->GetSpellInfo()))
+ AddPct(DoneTotalMod, (*i)->GetAmount());
}
}
uint32 creatureTypeMask = victim->GetCreatureTypeMask();
- // Add flat bonus from spell damage versus
- DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
+
AuraEffectList const& mDamageDoneVersus = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
@@ -8469,7 +8584,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
- AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
if (!(*i)->IsAffectingSpell(spellProto))
@@ -8531,18 +8646,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
}
- case 4418: // Increased Shock Damage
- case 4554: // Increased Lightning Damage
- case 4555: // Improved Moonfire
- case 5142: // Increased Lightning Damage
- case 5147: // Improved Consecration / Libram of Resurgence
- case 5148: // Idol of the Shooting Star
- case 6008: // Increased Lightning Damage
- case 8627: // Totem of Hex
- {
- DoneTotal += (*i)->GetAmount();
- break;
- }
}
}
@@ -8595,81 +8698,26 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
break;
}
}
- // Drain Soul - increased damage for targets under 25 % HP
- if (spellProto->SpellFamilyFlags[0] & 0x00004000)
- if (HasAura(100001))
- DoneTotalMod *= 2;
+
// Shadow Bite (30% increase from each dot)
if (spellProto->SpellFamilyFlags[1] & 0x00400000 && IsPet())
if (uint8 count = victim->GetDoTsByCaster(GetOwnerGUID()))
AddPct(DoneTotalMod, 30 * count);
+
+ // Drain Soul - increased damage for targets under 25 % HP
+ if (spellProto->SpellFamilyFlags[0] & 0x00004000)
+ if (HasAura(100001))
+ DoneTotalMod *= 2;
break;
case SPELLFAMILY_DEATHKNIGHT:
// Sigil of the Vengeful Heart
if (spellProto->SpellFamilyFlags[0] & 0x2000)
if (AuraEffect* aurEff = GetAuraEffect(64962, EFFECT_1))
- DoneTotal += aurEff->GetAmount();
+ DoneTotalMod += aurEff->GetAmount();
break;
}
- // Done fixed damage bonus auras
- int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
- // Pets just add their bonus damage to their spell damage
- // note that their spell damage is just gain of their own auras
- if (HasUnitTypeMask(UNIT_MASK_GUARDIAN))
- DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage();
-
- // Check for table values
- float coeff = 0;
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- if (bonus)
- {
- if (damagetype == DOT)
- {
- coeff = bonus->dot_damage;
- if (bonus->ap_dot_bonus > 0)
- {
- WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
- float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
- APbonus += GetTotalAttackPowerValue(attType);
- DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus);
- }
- }
- else
- {
- coeff = bonus->direct_damage;
- if (bonus->ap_bonus > 0)
- {
- WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
- float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
- APbonus += GetTotalAttackPowerValue(attType);
- DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);
- }
- }
- }
- // Default calculation
- if (DoneAdvertisedBenefit)
- {
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
-
- float factorMod = CalculateLevelPenalty(spellProto) * stack;
-
- if (Player* modOwner = GetSpellModOwner())
- {
- coeff *= 100.0f;
- modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
- coeff /= 100.0f;
- }
- DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
- }
-
- float tmpDamage = (int32(pdamage) + DoneTotal) * DoneTotalMod;
- // apply spellmod to Done damage (flat and pct)
- if (Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
-
- return uint32(std::max(tmpDamage, 0.0f));
+ return DoneTotalMod;
}
uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) const
@@ -8699,11 +8747,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
// Cheat Death
case 2109:
if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
- {
- if (GetTypeId() != TYPEID_PLAYER)
- continue;
AddPct(TakenTotalMod, (*i)->GetAmount());
- }
break;
}
}
@@ -8825,16 +8869,21 @@ int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const
return TakenAdvertisedBenefit;
}
-bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const
+bool Unit::IsSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const
+{
+ return roll_chance_f(GetUnitSpellCriticalChance(victim, spellProto, schoolMask, attackType));
+}
+
+float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const
{
//! Mobs can't crit with spells. Player Totems can
//! Fire Elemental (from totem) can too - but this part is a hack and needs more research
- if (IS_CREATURE_GUID(GetGUID()) && !(IsTotem() && IS_PLAYER_GUID(GetOwnerGUID())) && GetEntry() != 15438)
- return false;
+ if (IS_CRE_OR_VEH_GUID(GetGUID()) && !(IsTotem() && IS_PLAYER_GUID(GetOwnerGUID())) && GetEntry() != 15438)
+ return 0.0f;
// not critting spell
if ((spellProto->AttributesEx2 & SPELL_ATTR2_CANT_CRIT))
- return false;
+ return 0.0f;
float crit_chance = 0.0f;
switch (spellProto->DmgClass)
@@ -8850,7 +8899,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
case 71646: // Item - Bauble of True Blood 25m
break;
default:
- return false;
+ return 0.0f;
}
// Do not add a break here, case fallthrough is intentional! Adding a break will make above spells unable to crit.
case SPELL_DAMAGE_CLASS_MAGIC:
@@ -8949,7 +8998,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
else if (spellProto->GetCategory() == 19)
{
if (victim->GetCreatureTypeMask() & CREATURE_TYPEMASK_DEMON_OR_UNDEAD)
- return true;
+ return 100.0f;
break;
}
break;
@@ -8959,7 +9008,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
{
if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0, 0, GetGUID()))
if (victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE) > -100)
- return true;
+ return 100.0f;
break;
}
break;
@@ -8997,7 +9046,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
break;
}
default:
- return false;
+ return 0.0f;
}
// percent done
// only players use intelligence for critical chance computations
@@ -9009,10 +9058,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectingSpell(spellProto))
crit_chance += (*i)->GetAmount();
- crit_chance = crit_chance > 0.0f ? crit_chance : 0.0f;
- if (roll_chance_f(crit_chance))
- return true;
- return false;
+ return crit_chance > 0.0f ? crit_chance : 0.0f;
}
uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* /*victim*/)
@@ -9075,14 +9121,8 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
return healamount;
- float DoneTotalMod = 1.0f;
int32 DoneTotal = 0;
- // Healing done percent
- AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
- for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i)
- AddPct(DoneTotalMod, (*i)->GetAmount());
-
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
@@ -9101,7 +9141,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
case 6935:
case 6918:
if (victim->HealthBelowPct(50))
- AddPct(DoneTotalMod, (*i)->GetAmount());
+ AddPct(DoneTotal, (*i)->GetAmount());
break;
case 8477: // Nourish Heal Boost
{
@@ -9119,7 +9159,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
continue;
modPercent += stepPercent * aura->GetStackAmount();
}
- AddPct(DoneTotalMod, modPercent);
+ AddPct(DoneTotal, modPercent);
break;
}
default:
@@ -9190,8 +9230,8 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal = 0;
}
- // use float as more appropriate for negative values and percent applying
- float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod;
+ // Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
+ float heal = float(int32(healamount) + DoneTotal) * (damagetype == DOT ? 1.0f : SpellHealingPctDone(victim, spellProto));
// apply spellmod to Done amount
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal);
@@ -9199,6 +9239,78 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
return uint32(std::max(heal, 0.0f));
}
+float Unit::SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const
+{
+ // For totems pct done mods are calculated when its calculation is run on the player in SpellHealingBonusDone.
+ if (GetTypeId() == TYPEID_UNIT && IsTotem())
+ return 1.0f;
+
+ // No bonus healing for potion spells
+ if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
+ return 1.0f;
+
+ float DoneTotalMod = 1.0f;
+
+ // Healing done percent
+ AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
+ for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i)
+ AddPct(DoneTotalMod, (*i)->GetAmount());
+
+ // done scripted mod (take it from owner)
+ Unit const* owner = GetOwner() ? GetOwner() : this;
+ AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
+ {
+ if (!(*i)->IsAffectingSpell(spellProto))
+ continue;
+
+ switch ((*i)->GetMiscValue())
+ {
+ case 21: // Test of Faith
+ case 6935:
+ case 6918:
+ if (victim->HealthBelowPct(50))
+ AddPct(DoneTotalMod, (*i)->GetAmount());
+ break;
+ case 7798: // Glyph of Regrowth
+ {
+ if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40, 0, 0))
+ AddPct(DoneTotalMod, (*i)->GetAmount());
+ break;
+ }
+ case 8477: // Nourish Heal Boost
+ {
+ int32 stepPercent = (*i)->GetAmount();
+ int32 modPercent = 0;
+ AuraApplicationMap const& victimAuras = victim->GetAppliedAuras();
+ for (AuraApplicationMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
+ {
+ Aura const* aura = itr->second->GetBase();
+ if (aura->GetCasterGUID() != GetGUID())
+ continue;
+ SpellInfo const* m_spell = aura->GetSpellInfo();
+ if (m_spell->SpellFamilyName != SPELLFAMILY_DRUID ||
+ !(m_spell->SpellFamilyFlags[1] & 0x00000010 || m_spell->SpellFamilyFlags[0] & 0x50))
+ continue;
+ modPercent += stepPercent * aura->GetStackAmount();
+ }
+ AddPct(DoneTotalMod, modPercent);
+ break;
+ }
+ case 7871: // Glyph of Lesser Healing Wave
+ {
+ if (victim->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0, 0x00000400, 0, GetGUID()))
+ AddPct(DoneTotalMod, (*i)->GetAmount());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return DoneTotalMod;
+}
+
uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) const
{
float TakenTotalMod = 1.0f;
@@ -9542,7 +9654,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType
// Some spells don't benefit from pct done mods
if (spellProto)
- if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !spellProto->IsRankOf(sSpellMgr->GetSpellInfo(12162)))
+ if (!(spellProto->AttributesEx6 & SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS))
{
AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
@@ -9658,10 +9770,11 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
case 2109:
if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
{
- if (GetTypeId() != TYPEID_PLAYER)
- continue;
- float mod = ToPlayer()->GetRatingBonusValue(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN) * (-8.0f);
- AddPct(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
+ if (Player* player = ToPlayer())
+ {
+ float mod = player->GetRatingBonusValue(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN) * (-8.0f);
+ AddPct(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
+ }
}
break;
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 21c55ffe700..a12fa54d671 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1983,13 +1983,15 @@ class Unit : public WorldObject
Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo);
Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = NULL);
- int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const;
- int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const;
+ int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const;
+ int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const;
uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1) const;
+ float SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const;
uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1) const;
- int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const;
- int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const;
+ int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const;
+ int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const;
uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const;
+ float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const;
uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const;
uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = NULL);
@@ -1997,7 +1999,8 @@ class Unit : public WorldObject
bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK);
bool isBlockCritical();
- bool isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
+ bool IsSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
+ float GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
uint32 SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
uint32 SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 2f1a726f9cf..0461d7290d1 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -239,20 +239,28 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData.ReadPackedTime(unkPackedTime);
recvData >> flags;
- CalendarEvent calendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
+ // prevent events in the past
+ // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
+ if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L)))
+ {
+ recvData.rfinish();
+ return;
+ }
+
+ CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
- if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
+ if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
if (Player* creator = ObjectAccessor::FindPlayer(guid))
- calendarEvent.SetGuildId(creator->GetGuildId());
+ calendarEvent->SetGuildId(creator->GetGuildId());
- if (calendarEvent.IsGuildAnnouncement())
+ if (calendarEvent->IsGuildAnnouncement())
{
// 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite invite(0, calendarEvent.GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
+ CalendarInvite invite(0, calendarEvent->GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
// WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind
// of storage of the pointer as it will lead to memory corruption
- sCalendarMgr->AddInvite(&calendarEvent, &invite);
+ sCalendarMgr->AddInvite(calendarEvent, &invite);
}
else
{
@@ -275,15 +283,15 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData >> status >> rank;
// 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent.GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
- sCalendarMgr->AddInvite(&calendarEvent, invite, trans);
+ CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
+ sCalendarMgr->AddInvite(calendarEvent, invite, trans);
}
if (inviteCount > 1)
CharacterDatabase.CommitTransaction(trans);
}
- sCalendarMgr->AddEvent(new CalendarEvent(calendarEvent, calendarEvent.GetEventId()), CALENDAR_SENDTYPE_ADD);
+ sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
}
void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
@@ -308,6 +316,14 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
recvData.ReadPackedTime(timeZoneTime);
recvData >> flags;
+ // prevent events in the past
+ // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
+ if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L)))
+ {
+ recvData.rfinish();
+ return;
+ }
+
TC_LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [" UI64FMTD "] EventId [" UI64FMTD
"], InviteId [" UI64FMTD "] Title %s, Description %s, type %u "
"Repeatable %u, MaxInvites %u, Dungeon ID %d, Time %u "
@@ -350,17 +366,25 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
uint64 guid = _player->GetGUID();
uint64 eventId;
uint64 inviteId;
- uint32 time;
+ uint32 eventTime;
recvData >> eventId >> inviteId;
- recvData.ReadPackedTime(time);
+ recvData.ReadPackedTime(eventTime);
TC_LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [" UI64FMTD "], EventId [" UI64FMTD
- "] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, time);
+ "] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, eventTime);
+
+ // prevent events in the past
+ // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
+ if (time_t(eventTime) < (time(NULL) - time_t(86400L)))
+ {
+ recvData.rfinish();
+ return;
+ }
if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
{
CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
- newEvent->SetEventTime(time_t(time));
+ newEvent->SetEventTime(time_t(eventTime));
sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index fa137d98272..cb6b4096226 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -530,7 +530,7 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket& recvPacket)
if (GetPlayer()->IsInWorld())
{
if (_player->m_mover->GetGUID() != guid)
- TC_LOG_ERROR("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is " UI64FMTD " (%s - Entry: %u) and should be " UI64FMTD, uint64(guid), GetLogNameForGuid(guid), GUID_ENPART(guid), _player->m_mover->GetGUID());
+ TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is " UI64FMTD " (%s - Entry: %u) and should be " UI64FMTD, uint64(guid), GetLogNameForGuid(guid), GUID_ENPART(guid), _player->m_mover->GetGUID());
}
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 301e9a7d2c8..39d18178a01 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -79,13 +79,13 @@ void WorldSession::HandlePetAction(WorldPacket& recvData)
if (!pet)
{
- TC_LOG_ERROR("network", "HandlePetAction: Pet (GUID: %u) doesn't exist for player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
+ TC_LOG_DEBUG("network", "HandlePetAction: Pet (GUID: %u) doesn't exist for player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
if (pet != GetPlayer()->GetFirstControlled())
{
- TC_LOG_ERROR("network", "HandlePetAction: Pet (GUID: %u) does not belong to player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
+ TC_LOG_DEBUG("network", "HandlePetAction: Pet (GUID: %u) does not belong to player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
@@ -149,7 +149,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint32 spellid
CharmInfo* charmInfo = pet->GetCharmInfo();
if (!charmInfo)
{
- TC_LOG_ERROR("network", "WorldSession::HandlePetAction(petGuid: " UI64FMTD ", tagGuid: " UI64FMTD ", spellId: %u, flag: %u): object (GUID: %u Entry: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!",
+ TC_LOG_DEBUG("network", "WorldSession::HandlePetAction(petGuid: " UI64FMTD ", tagGuid: " UI64FMTD ", spellId: %u, flag: %u): object (GUID: %u Entry: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!",
guid1, guid2, spellid, flag, pet->GetGUIDLow(), pet->GetEntry(), pet->GetTypeId());
return;
}
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 7226ebe12c2..7a3be387385 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -435,7 +435,7 @@ AuraEffect::AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* cast
m_base(base), m_spellInfo(base->GetSpellInfo()),
m_baseAmount(baseAmount ? *baseAmount : m_spellInfo->Effects[effIndex].BasePoints),
m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex),
-m_canBeRecalculated(true), m_isPeriodic(false)
+m_canBeRecalculated(true), m_damage(0), m_critChance(0.0f), m_donePct(1.0f), m_isPeriodic(false)
{
CalculatePeriodic(caster, true, false);
@@ -995,10 +995,11 @@ void AuraEffect::UpdatePeriodic(Unit* caster)
GetBase()->CallScriptEffectUpdatePeriodicHandlers(this);
}
-bool AuraEffect::IsPeriodicTickCrit(Unit* target, Unit const* caster) const
+bool AuraEffect::CanPeriodicTickCrit(Unit const* caster) const
{
ASSERT(caster);
- return caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask());
+
+ return caster->HasAuraTypeWithAffectMask(SPELL_AURA_ABILITY_PERIODIC_CRIT, m_spellInfo);
}
bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
@@ -5766,15 +5767,19 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
uint32 resist = 0;
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 damage = std::max(GetAmount(), 0);
+ // AOE spells are not affected by the new periodic system.
+ bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ // ignore negative values (can be result apply spellmods to aura damage
+ uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
- sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
+ if (isAreaAura)
+ sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
{
- damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
+ if (isAreaAura)
+ damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
// Calculate armor mitigation
@@ -5821,14 +5826,19 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
else
damage = uint32(target->CountPctFromMaxHealth(damage));
- if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
- {
- damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- if (caster->GetTypeId() != TYPEID_PLAYER)
- damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- }
+ if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
+ if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
+ {
+ damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
+ }
+
+ bool crit = false;
+
+ if (CanPeriodicTickCrit(caster))
+ crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : m_critChance);
- bool crit = IsPeriodicTickCrit(target, caster);
if (crit)
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
@@ -5884,23 +5894,42 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
uint32 resist = 0;
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- uint32 damage = std::max(GetAmount(), 0);
+ bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ // ignore negative values (can be result apply spellmods to aura damage
+ uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
- damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
+ if (isAreaAura)
+ {
+ // Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
+ sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
+ damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
+ }
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
- bool crit = IsPeriodicTickCrit(target, caster);
- if (crit)
- damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
-
// Calculate armor mitigation
- if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), m_effIndex))
+ if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
damage = damageReductedArmor;
}
+ if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
+ if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
+ {
+ damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
+ }
+
+ bool crit = false;
+
+ if (CanPeriodicTickCrit(caster))
+ crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : m_critChance);
+
+ if (crit)
+ damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
+
int32 dmg = damage;
if (!(GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
caster->ApplyResilience(target, &dmg);
@@ -5985,8 +6014,9 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (GetBase()->IsPermanent() && target->IsFullHealth())
return;
+ bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
- int32 damage = std::max(m_amount, 0);
+ int32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH)
{
@@ -6025,12 +6055,16 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
damage += addition;
}
-
- damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
+ if (isAreaAura)
+ damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellHealingPctDone(target, m_spellInfo);
damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
}
- bool crit = IsPeriodicTickCrit(target, caster);
+ bool crit = false;
+
+ if (CanPeriodicTickCrit(caster))
+ crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : m_critChance);
+
if (crit)
damage = caster->SpellCriticalHealingBonus(m_spellInfo, damage, target);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 2415b89c9a8..700bbb10417 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -70,6 +70,13 @@ class AuraEffect
void HandleEffect(Unit* target, uint8 mode, bool apply);
void ApplySpellMod(Unit* target, bool apply);
+ void SetDamage(int32 val) { m_damage = val; }
+ int32 GetDamage() const { return m_damage; }
+ void SetCritChance(float val) { m_critChance = val; }
+ float GetCritChance() const { return m_critChance; }
+ void SetDonePct(float val) { m_donePct = val; }
+ float GetDonePct() const { return m_donePct; }
+
void Update(uint32 diff, Unit* caster);
void UpdatePeriodic(Unit* caster);
@@ -98,6 +105,9 @@ class AuraEffect
int32 const m_baseAmount;
int32 m_amount;
+ int32 m_damage;
+ float m_critChance;
+ float m_donePct;
SpellModifier* m_spellmod;
@@ -109,7 +119,7 @@ class AuraEffect
bool m_canBeRecalculated;
bool m_isPeriodic;
private:
- bool IsPeriodicTickCrit(Unit* target, Unit const* caster) const;
+ bool CanPeriodicTickCrit(Unit const* caster) const;
public:
// aura effect apply/remove handlers
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 05b4ebfc258..f57b8dd439a 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -755,9 +755,20 @@ void Aura::SetDuration(int32 duration, bool withMods)
SetNeedClientUpdateForTargets();
}
-void Aura::RefreshDuration()
+void Aura::RefreshDuration(bool withMods)
{
- SetDuration(GetMaxDuration());
+ if (withMods)
+ {
+ int32 duration = m_spellInfo->GetMaxDuration();
+ // Calculate duration of periodics affected by haste.
+ if (GetCaster()->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
+ duration = int32(duration * GetCaster()->GetFloatValue(UNIT_MOD_CAST_SPEED));
+
+ SetMaxDuration(duration);
+ SetDuration(duration);
+ }
+ else
+ SetDuration(GetMaxDuration());
if (m_spellInfo->ManaPerSecond)
m_timeCla = 1 * IN_MILLISECONDS;
@@ -851,7 +862,10 @@ void Aura::SetStackAmount(uint8 stackAmount)
for (std::list<AuraApplication*>::const_iterator apptItr = applications.begin(); apptItr != applications.end(); ++apptItr)
if (!(*apptItr)->GetRemoveMode())
+ {
HandleAuraSpecificMods(*apptItr, caster, true, true);
+ HandleAuraSpecificPeriodics(*apptItr, caster);
+ }
SetNeedClientUpdateForTargets();
}
@@ -1459,26 +1473,62 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
break;
}
break;
- case SPELLFAMILY_WARLOCK:
- // Drain Soul - If the target is at or below 25% health, Drain Soul causes four times the normal damage
- if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000)
+ }
+}
+
+void Aura::HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* caster)
+{
+ Unit* target = aurApp->GetTarget();
+
+ if (!caster || aurApp->GetRemoveMode())
+ return;
+
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (!HasEffect(i))
+ continue;
+
+ if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ continue;
+
+ switch (m_spellInfo->Effects[i].ApplyAuraName)
+ {
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
+ case SPELL_AURA_PERIODIC_LEECH:
{
- if (!caster)
- break;
- if (apply)
- {
- if (target != caster && !target->HealthAbovePct(25))
- caster->CastSpell(caster, 100001, true);
- }
- else
- {
- if (target != caster)
- caster->RemoveAurasDueToSpell(GetId());
- else
- caster->RemoveAurasDueToSpell(100001);
- }
+ AuraEffect* aurEff = GetEffect(i);
+
+ // ignore non positive values (can be result apply spellmods to aura damage
+ uint32 damage = std::max(aurEff->GetAmount(), 0);
+
+ // Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
+ sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
+
+ aurEff->SetDonePct(caster->SpellDamagePctDone(target, m_spellInfo, DOT)); // Calculate done percentage first!
+ aurEff->SetDamage(caster->SpellDamageBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
+ aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
+ break;
}
- break;
+ case SPELL_AURA_PERIODIC_HEAL:
+ case SPELL_AURA_OBS_MOD_HEALTH:
+ {
+ AuraEffect* aurEff = GetEffect(i);
+
+ // ignore non positive values (can be result apply spellmods to aura damage
+ uint32 damage = std::max(aurEff->GetAmount(), 0);
+
+ // Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
+ sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
+
+ aurEff->SetDonePct(caster->SpellHealingPctDone(target, m_spellInfo)); // Calculate done percentage first!
+ aurEff->SetDamage(caster->SpellHealingBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
+ aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
+ break;
+ }
+ default:
+ break;
+ }
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index f62b1ff47b4..669d2a529a1 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -129,7 +129,7 @@ class Aura
int32 CalcMaxDuration(Unit* caster) const;
int32 GetDuration() const { return m_duration; }
void SetDuration(int32 duration, bool withMods = false);
- void RefreshDuration();
+ void RefreshDuration(bool withMods = false);
void RefreshTimers();
bool IsExpired() const { return !GetDuration();}
bool IsPermanent() const { return GetMaxDuration() == -1; }
@@ -190,6 +190,7 @@ class Aura
void SetNeedClientUpdateForTargets() const;
void HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, bool apply, bool onReapply);
+ void HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* caster);
bool CanBeAppliedOn(Unit* target);
bool CheckAreaTarget(Unit* target);
bool CanStackWith(Aura const* existingAura) const;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index b64ee454e2e..93bd4855585 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2346,7 +2346,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// Do healing and triggers
if (m_healing > 0)
{
- bool crit = caster->isSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
+ bool crit = caster->IsSpellCrit(unitTarget, m_spellInfo, m_spellSchoolMask);
uint32 addhealth = m_healing;
if (crit)
{
@@ -6758,7 +6758,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
}
}
- targetInfo.crit = m_caster->isSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType);
+ targetInfo.crit = m_caster->IsSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType);
}
SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue)
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 8dfa017467a..46f1413c311 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -960,7 +960,7 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/)
TC_LOG_DEBUG("spells", "Spell::EffectTeleportUnits - teleport unit to %u %f %f %f %f\n", mapid, x, y, z, orientation);
if (unitTarget->GetTypeId() == TYPEID_PLAYER)
- unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
+ unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL | TELE_TO_NOT_LEAVE_COMBAT : 0);
else if (mapid == unitTarget->GetMapId())
unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster);
else
@@ -3755,15 +3755,40 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
{
// Get diseases on target of spell
if (m_targets.GetUnitTarget() && // Glyph of Disease - cast on unit target too to refresh aura
- (m_targets.GetUnitTarget() != unitTarget || m_caster->GetAura(63334)))
+ (m_targets.GetUnitTarget() != unitTarget || m_caster->HasAura(63334)))
{
// And spread them on target
// Blood Plague
- if (m_targets.GetUnitTarget()->GetAura(55078))
+ if (m_targets.GetUnitTarget()->HasAura(55078))
+ {
+ AuraEffect* aurEffOld = m_targets.GetUnitTarget()->GetAura(55078)->GetEffect(0);
+ float donePct = aurEffOld->GetDonePct();
+ float critChance = aurEffOld->GetCritChance();
+
m_caster->CastSpell(unitTarget, 55078, true);
+
+ if (unitTarget->HasAura(55078))
+ if (AuraEffect* aurEffNew = unitTarget->GetAura(55078)->GetEffect(0))
+ {
+ aurEffNew->SetCritChance(critChance); // Blood Plague can crit if caster has T9.
+ aurEffNew->SetDonePct(donePct);
+ aurEffNew->SetDamage(m_caster->SpellDamageBonusDone(unitTarget, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT) * donePct);
+ }
+ }
// Frost Fever
- if (m_targets.GetUnitTarget()->GetAura(55095))
+ if (m_targets.GetUnitTarget()->HasAura(55095))
+ {
+ float donePct = m_targets.GetUnitTarget()->GetAura(55095)->GetEffect(0)->GetDonePct();
+
m_caster->CastSpell(unitTarget, 55095, true);
+
+ if (unitTarget->HasAura(55095))
+ if (AuraEffect* aurEffNew = unitTarget->GetAura(55095)->GetEffect(0))
+ {
+ aurEffNew->SetDonePct(donePct);
+ aurEffNew->SetDamage(m_caster->SpellDamageBonusDone(unitTarget, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT) * donePct);
+ }
+ }
}
}
break;
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 116beb3d081..cfcc05a625c 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -1813,7 +1813,6 @@ public:
enum ZuluhedChains
{
- QUEST_ZULUHED = 10866,
NPC_KARYNAKU = 22112,
};
@@ -1828,9 +1827,9 @@ class spell_unlocking_zuluheds_chains : public SpellScriptLoader
void HandleAfterHit()
{
- if (GetCaster()->GetTypeId() == TYPEID_PLAYER)
- if (Creature* karynaku = GetCaster()->FindNearestCreature(NPC_KARYNAKU, 15.0f))
- GetCaster()->ToPlayer()->KilledMonsterCredit(NPC_KARYNAKU, karynaku->GetGUID());
+ if (Player* caster = GetCaster()->ToPlayer())
+ if (Creature* karynaku = caster->FindNearestCreature(NPC_KARYNAKU, 15.0f))
+ caster->KilledMonsterCredit(NPC_KARYNAKU, karynaku->GetGUID());
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index d804c0cfc8b..ae9edfc3929 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -737,10 +737,17 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader
void HandleEffectScriptEffect(SpellEffIndex /*effIndex*/)
{
+ Unit* caster = GetCaster();
// Refresh Shadow Word: Pain on target
- if (Unit* unitTarget = GetHitUnit())
- if (AuraEffect* aur = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, GetCaster()->GetGUID()))
+ if (Unit* target = GetHitUnit())
+ if (AuraEffect* aur = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, caster->GetGUID()))
+ {
+ uint32 damage = std::max(aur->GetAmount(), 0);
+ sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
+ aur->SetDamage(caster->SpellDamageBonusDone(target, aur->GetSpellInfo(), damage, DOT) * aur->GetDonePct());
+ aur->CalculatePeriodic(caster, false, false);
aur->GetBase()->RefreshDuration();
+ }
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 2b0a5506a83..86ece72cc56 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -537,10 +537,17 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- if (Unit* unitTarget = GetHitUnit())
+ Unit* caster = GetCaster();
+ if (Unit* target = GetHitUnit())
// Refresh corruption on target
- if (AuraEffect* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, GetCaster()->GetGUID()))
- aurEff->GetBase()->RefreshDuration();
+ if (AuraEffect* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, caster->GetGUID()))
+ {
+ uint32 damage = std::max(aurEff->GetAmount(), 0);
+ sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
+ aurEff->SetDamage(caster->SpellDamageBonusDone(target, aurEff->GetSpellInfo(), damage, DOT) * aurEff->GetDonePct());
+ aurEff->CalculatePeriodic(caster, false, false);
+ aurEff->GetBase()->RefreshDuration(true);
+ }
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index 529d62b5297..e8c95c8392e 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -36,7 +36,7 @@ enum WarriorSpells
SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_2 = 12850,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868,
- SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC = 12721,
+ SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC = 12721,
SPELL_WARRIOR_EXECUTE = 20647,
SPELL_WARRIOR_GLYPH_OF_EXECUTION = 58367,
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156,
@@ -231,7 +231,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader
if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_1) ||
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_2) ||
!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_3) ||
- !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC))
+ !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC))
return false;
return true;
}
@@ -242,23 +242,18 @@ class spell_warr_deep_wounds : public SpellScriptLoader
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
{
- // apply percent damage mods
- damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
-
ApplyPct(damage, 16 * GetSpellInfo()->GetRank());
- damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
-
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC);
+ SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC);
uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude;
// Add remaining ticks to damage done
- if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC, EFFECT_0, caster->GetGUID()))
- damage += aurEff->GetAmount() * (ticks - aurEff->GetTickNumber());
+ if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC, EFFECT_0, caster->GetGUID()))
+ damage += aurEff->GetDamage() * (ticks - aurEff->GetTickNumber());
damage /= ticks;
- caster->CastCustomSpell(target, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC, &damage, NULL, NULL, true);
+ caster->CastCustomSpell(target, SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC, &damage, NULL, NULL, true);
}
}