aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/Spell.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r--src/server/game/Spells/Spell.cpp255
1 files changed, 134 insertions, 121 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2a7b550392a..b37a44d6e70 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -592,7 +592,7 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO
m_healing = 0;
m_procAttacker = 0;
m_procVictim = 0;
- m_procEx = 0;
+ m_hitMask = 0;
focusObject = NULL;
m_cast_count = 0;
m_glyphIndex = 0;
@@ -1481,7 +1481,7 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg
{
uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
+ modOwner->ApplySpellMod<SPELLMOD_JUMP_TARGETS>(m_spellInfo->Id, maxTargets, this);
if (maxTargets > 1)
{
@@ -1947,12 +1947,11 @@ GameObject* Spell::SearchSpellFocus()
return focus;
}
-void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
+void Spell::prepareDataForTriggerSystem()
{
//==========================================================================================
// Now fill data for trigger system, need know:
- // can spell trigger another or not (m_canTrigger)
- // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
+ // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_hitMask)
//==========================================================================================
m_procVictim = m_procAttacker = 0;
@@ -1982,7 +1981,7 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
break;
default:
if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON &&
- m_spellInfo->EquippedItemSubClassMask & (1<<ITEM_SUBCLASS_WEAPON_WAND)
+ m_spellInfo->EquippedItemSubClassMask & (1 << ITEM_SUBCLASS_WEAPON_WAND)
&& m_spellInfo->HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG)) // Wands auto attack
{
m_procAttacker = PROC_FLAG_DONE_RANGED_AUTO_ATTACK;
@@ -1991,7 +1990,7 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
// For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
// Because spell positivity is dependant on target
}
- m_procEx = PROC_EX_NONE;
+ m_hitMask = PROC_HIT_NONE;
// Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER &&
@@ -2000,29 +1999,12 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap
m_procAttacker |= PROC_FLAG_DONE_TRAP_ACTIVATION;
- /* Effects which are result of aura proc from triggered spell cannot proc
- to prevent chain proc of these spells */
-
// Hellfire Effect - trigger as DOT
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[0] & 0x00000040)
{
m_procAttacker = PROC_FLAG_DONE_PERIODIC;
m_procVictim = PROC_FLAG_TAKEN_PERIODIC;
}
-
- // Ranged autorepeat attack is set as triggered spell - ignore it
- if (!(m_procAttacker & PROC_FLAG_DONE_RANGED_AUTO_ATTACK))
- {
- if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS &&
- (m_spellInfo->HasAttribute(SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC) ||
- m_spellInfo->HasAttribute(SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2)))
- m_procEx |= PROC_EX_INTERNAL_CANT_PROC;
- else if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS)
- m_procEx |= PROC_EX_INTERNAL_TRIGGERED;
- }
- // Totem casts require spellfamilymask defined in spell_proc_event to proc
- if (m_originalCaster && m_caster != m_originalCaster && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->IsTotem() && m_caster->IsControlledByPlayer())
- m_procEx |= PROC_EX_INTERNAL_REQ_FAMILY;
}
void Spell::CleanupTargetList()
@@ -2033,6 +2015,32 @@ void Spell::CleanupTargetList()
m_delayMoment = 0;
}
+class ProcReflectDelayed : public BasicEvent
+{
+ public:
+ ProcReflectDelayed(Unit* owner, ObjectGuid casterGuid) : _victim(owner), _casterGuid(casterGuid) { }
+
+ bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
+ {
+ Unit* caster = ObjectAccessor::GetUnit(*_victim, _casterGuid);
+ if (!caster)
+ return true;
+
+ uint32 const typeMaskActor = PROC_FLAG_NONE;
+ uint32 const typeMaskActionTarget = PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG;
+ uint32 const spellTypeMask = PROC_SPELL_TYPE_DAMAGE | PROC_SPELL_TYPE_NO_DMG_HEAL;
+ uint32 const spellPhaseMask = PROC_SPELL_PHASE_NONE;
+ uint32 const hitMask = PROC_HIT_REFLECT;
+
+ caster->ProcSkillsAndAuras(_victim, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, nullptr, nullptr, nullptr);
+ return true;
+ }
+
+ private:
+ Unit* _victim;
+ ObjectGuid _casterGuid;
+};
+
void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/, Position const* losPosition /*= nullptr*/)
{
for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
@@ -2112,20 +2120,20 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
targetInfo.timeDelay = (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
// Calculate minimum incoming time
- if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
+ if (!m_delayMoment || m_delayMoment > targetInfo.timeDelay)
m_delayMoment = targetInfo.timeDelay;
}
else
- targetInfo.timeDelay = 0LL;
+ targetInfo.timeDelay = 0ULL;
// If target reflect spell back to caster
if (targetInfo.missCondition == SPELL_MISS_REFLECT)
{
// Calculate reflected spell result on caster
- targetInfo.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, m_canReflect);
+ targetInfo.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, false); // can't reflect twice
- if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
- targetInfo.reflectResult = SPELL_MISS_PARRY;
+ // Proc spell reflect aura when missile hits the original target
+ target->m_Events.AddEvent(new ProcReflectDelayed(target, m_originalCasterGUID), target->m_Events.CalculateTime(targetInfo.timeDelay));
// Increase time interval for reflected spells by 1.5
targetInfo.timeDelay += targetInfo.timeDelay >> 1;
@@ -2147,14 +2155,14 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
{
switch (m_spellInfo->Effects[effIndex].Effect)
{
- case SPELL_EFFECT_GAMEOBJECT_DAMAGE:
- case SPELL_EFFECT_GAMEOBJECT_REPAIR:
- case SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE:
- if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
- effectMask &= ~(1 << effIndex);
- break;
- default:
- break;
+ case SPELL_EFFECT_GAMEOBJECT_DAMAGE:
+ case SPELL_EFFECT_GAMEOBJECT_REPAIR:
+ case SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE:
+ if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+ effectMask &= ~(1 << effIndex);
+ break;
+ default:
+ break;
}
}
}
@@ -2189,7 +2197,7 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
if (dist < 5.0f)
dist = 5.0f;
target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
- if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
+ if (!m_delayMoment || m_delayMoment > target.timeDelay)
m_delayMoment = target.timeDelay;
}
else
@@ -2297,13 +2305,13 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// Fill base trigger info
uint32 procAttacker = m_procAttacker;
uint32 procVictim = m_procVictim;
- uint32 procEx = m_procEx;
+ uint32 hitMask = m_hitMask;
- m_spellAura = NULL; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
+ m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
- //Spells with this flag cannot trigger if effect is cast on self
- bool canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_PROC) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2);
- Unit* spellHitTarget = NULL;
+ // Spells with this flag cannot trigger if effect is cast on self
+ bool canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_PROC) && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2);
+ Unit* spellHitTarget = nullptr;
if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
spellHitTarget = unit;
@@ -2331,23 +2339,15 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
if (missInfo2 != SPELL_MISS_MISS)
m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo2);
m_damage = 0;
- spellHitTarget = NULL;
+ spellHitTarget = nullptr;
}
}
// Do not take combo points on dodge and miss
- if (missInfo != SPELL_MISS_NONE && m_needComboPoints &&
- m_targets.GetUnitTargetGUID() == target->targetGUID)
- {
+ if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
m_needComboPoints = false;
- // Restore spell mods for a miss/dodge/parry Cold Blood
- /// @todo check how broad this rule should be
- if (m_caster->GetTypeId() == TYPEID_PLAYER && (missInfo == SPELL_MISS_MISS ||
- missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
- m_caster->ToPlayer()->RestoreSpellMods(this, 14177);
- }
- // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
+ // Trigger info was not filled in Spell::prepareDataForTriggerSystem - we do it now
if (canEffectTrigger && !procAttacker && !procVictim)
{
bool positive = true;
@@ -2394,19 +2394,20 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
uint32 addhealth = m_healing;
if (crit)
{
- procEx |= PROC_EX_CRITICAL_HIT;
- addhealth = caster->SpellCriticalHealingBonus(m_spellInfo, addhealth, NULL);
+ hitMask |= PROC_HIT_CRITICAL;
+ addhealth = caster->SpellCriticalHealingBonus(m_spellInfo, addhealth, nullptr);
}
else
- procEx |= PROC_EX_NORMAL_HIT;
+ hitMask |= PROC_HIT_NORMAL;
- int32 gain = caster->HealBySpell(unitTarget, m_spellInfo, addhealth, crit);
- unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
- m_healing = gain;
+ HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
+ caster->HealBySpell(healInfo, crit);
+ unitTarget->getHostileRefManager().threatAssist(caster, float(healInfo.GetEffectiveHeal()) * 0.5f, m_spellInfo);
+ m_healing = healInfo.GetEffectiveHeal();
- // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
- caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
+ // Do triggers for unit
+ if (canEffectTrigger)
+ caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, nullptr, &healInfo);
}
// Do damage and triggers
else if (m_damage > 0)
@@ -2421,16 +2422,18 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// Send log damage message to client
caster->SendSpellNonMeleeDamageLog(&damageInfo);
- procEx |= createProcExtendMask(&damageInfo, missInfo);
+ hitMask |= createProcHitMask(&damageInfo, missInfo);
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
- // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
+ // Do triggers for unit
+ if (canEffectTrigger)
{
- caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
- if (caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET) == 0 &&
- (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED))
- caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
+ DamageInfo spellDamageInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, hitMask);
+ caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, hitMask, this, &spellDamageInfo, nullptr);
+
+ if (caster->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET) &&
+ (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED))
+ caster->ToPlayer()->CastItemCombatSpell(spellDamageInfo);
}
m_damage = damageInfo.damage;
@@ -2442,10 +2445,17 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
{
// Fill base damage struct (unitTarget - is real spell target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
- procEx |= createProcExtendMask(&damageInfo, missInfo);
- // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
- caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
+ hitMask |= createProcHitMask(&damageInfo, missInfo);
+ // Do triggers for unit
+ if (canEffectTrigger)
+ {
+ DamageInfo spellNoDamageInfo(damageInfo, NODAMAGE, m_attackType, hitMask);
+ caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_NO_DMG_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, &spellNoDamageInfo, nullptr);
+
+ if (caster->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET) &&
+ (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED))
+ caster->ToPlayer()->CastItemCombatSpell(spellNoDamageInfo);
+ }
// Failed Pickpocket, reveal rogue
if (missInfo == SPELL_MISS_RESIST && m_spellInfo->HasAttribute(SPELL_ATTR0_CU_PICKPOCKET) && unitTarget->GetTypeId() == TYPEID_UNIT)
@@ -2815,7 +2825,7 @@ bool Spell::UpdateChanneledTargetList()
{
range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive());
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
+ modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, range, this);
}
for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
@@ -2953,7 +2963,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
}
// Prepare data for triggers
- prepareDataForTriggerSystem(triggeredByAura);
+ prepareDataForTriggerSystem();
if (Player* player = m_caster->ToPlayer())
{
@@ -3061,10 +3071,6 @@ void Spell::cancel()
SendInterrupted(0);
SendCastResult(SPELL_FAILED_INTERRUPTED);
- // spell is canceled-take mods and clear list
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->RemoveSpellMods(this);
-
m_appliedMods.clear();
break;
@@ -3299,6 +3305,25 @@ void Spell::cast(bool skipCheck)
if (Creature* creatureCaster = m_caster->ToCreature())
creatureCaster->ReleaseFocus(this);
+
+ if (!m_originalCaster)
+ return;
+
+ // Handle procs on cast
+ uint32 procAttacker = m_procAttacker;
+ if (!procAttacker)
+ {
+ if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
+ procAttacker = m_spellInfo->IsPositive() ? PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG;
+ else
+ procAttacker = m_spellInfo->IsPositive() ? PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG;
+ }
+
+ uint32 hitMask = m_hitMask;
+ if (!(hitMask & PROC_HIT_CRITICAL))
+ hitMask |= PROC_HIT_NORMAL;
+
+ m_originalCaster->ProcSkillsAndAuras(nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_CAST, hitMask, this, nullptr, nullptr);
}
void Spell::handle_immediate()
@@ -3312,7 +3337,7 @@ void Spell::handle_immediate()
// First mod_duration then haste - see Missile Barrage
// Apply duration mod
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
+ modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration);
// Apply haste mods
m_caster->ModSpellDurationTime(m_spellInfo, duration, this);
@@ -3455,22 +3480,8 @@ void Spell::_handle_immediate_phase()
}
// process items
- for (std::list<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
+ for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
DoAllEffectOnTarget(&(*ihit));
-
- if (!m_originalCaster)
- return;
- // Handle procs on cast
- /// @todo finish new proc system:P
- if (m_UniqueTargetInfo.empty() && m_targets.HasDst())
- {
- uint32 procAttacker = m_procAttacker;
- if (!procAttacker)
- procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS;
-
- // Proc the spells that have DEST target
- m_originalCaster->ProcDamageAndSpell(NULL, procAttacker, 0, m_procEx | PROC_EX_NORMAL_HIT, 0, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell);
- }
}
void Spell::_handle_finish_phase()
@@ -3494,7 +3505,24 @@ void Spell::_handle_finish_phase()
m_caster->m_extraAttacks = 0;
}
- /// @todo trigger proc phase finish here
+ // Handle procs on finish
+ if (!m_originalCaster)
+ return;
+
+ uint32 procAttacker = m_procAttacker;
+ if (!procAttacker)
+ {
+ if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)
+ procAttacker = m_spellInfo->IsPositive() ? PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG;
+ else
+ procAttacker = m_spellInfo->IsPositive() ? PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS : PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG;
+ }
+
+ uint32 hitMask = m_hitMask;
+ if (!(hitMask & PROC_HIT_CRITICAL))
+ hitMask |= PROC_HIT_NORMAL;
+
+ m_originalCaster->ProcSkillsAndAuras(nullptr, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_FINISH, hitMask, this, nullptr, nullptr);
}
void Spell::SendSpellCooldown()
@@ -3658,18 +3686,6 @@ void Spell::finish(bool ok)
m_caster->ToPlayer()->UpdatePotionCooldown(this);
}
- if (Player* modOwner = m_caster->GetSpellModOwner())
- {
- // triggered spell pointer can be not set in some cases
- // this is needed for proper apply of triggered spell mods
- modOwner->SetSpellModTakingSpell(this, true);
-
- // Take mods after trigger spell (needed for 14177 to affect 48664)
- // mods are taken only on succesfull cast and independantly from targets of the spell
- modOwner->RemoveSpellMods(this);
- modOwner->SetSpellModTakingSpell(this, false);
- }
-
// Stop Attack for some spells
if (m_spellInfo->HasAttribute(SPELL_ATTR0_STOP_ATTACK_TARGET))
m_caster->AttackStop();
@@ -4387,7 +4403,7 @@ void Spell::TakePower()
hit = false;
//lower spell cost on fail (by talent aura)
if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost);
+ modOwner->ApplySpellMod<SPELLMOD_SPELL_COST_REFUND_ON_FAIL>(m_spellInfo->Id, m_powerCost);
}
break;
}
@@ -4479,7 +4495,7 @@ SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
{
runeCost[i] = src->RuneCost[i];
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
+ modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], this);
}
runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
@@ -4519,7 +4535,7 @@ void Spell::TakeRunePower(bool didHit)
{
runeCost[i] = runeCostData->RuneCost[i];
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
+ modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], this);
}
// Let's say we use a skill that requires a Frost rune. This is the order:
@@ -5896,7 +5912,7 @@ std::pair<float, float> Spell::GetMinMaxRange(bool strict)
maxRange *= ranged->GetTemplate()->RangedModRange * 0.01f;
if (Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, maxRange, this);
+ modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, maxRange, this);
maxRange += rangeMod;
@@ -6465,7 +6481,7 @@ void Spell::Delayed() // only called in DealDamage()
//check pushback reduce
int32 delaytime = 500; // spellcasting delay is normally 500ms
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
- m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
+ m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this);
delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
if (delayReduce >= 100)
return;
@@ -6503,7 +6519,7 @@ void Spell::DelayedChannel()
int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
- m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
+ m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this);
delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
if (delayReduce >= 100)
return;
@@ -7428,15 +7444,12 @@ void Spell::TriggerGlobalCooldown()
if (m_spellInfo->StartRecoveryTime >= MIN_GCD && m_spellInfo->StartRecoveryTime <= MAX_GCD)
{
// gcd modifier auras are applied only to own spells and only players have such mods
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this);
+ if (Player* modOwner = m_caster->GetSpellModOwner())
+ modOwner->ApplySpellMod<SPELLMOD_GLOBAL_COOLDOWN>(m_spellInfo->Id, gcd, this);
// Apply haste rating
gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
- if (gcd < MIN_GCD)
- gcd = MIN_GCD;
- else if (gcd > MAX_GCD)
- gcd = MAX_GCD;
+ RoundToInterval<int32>(gcd, MIN_GCD, MAX_GCD);
}
m_caster->GetSpellHistory()->AddGlobalCooldown(m_spellInfo, gcd);