aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2021-09-04 15:13:15 +0200
committerShauren <shauren.trinity@gmail.com>2021-09-04 15:13:15 +0200
commit8a4e1119ac21e2d1112d1717337597fe073e495f (patch)
tree34f3215bec2096b59e3d9b2353661e1c137ff8b4 /src/server/game/Spells
parent16ed458eeeebe436f05c43686928252992ae2a20 (diff)
Core/Spells: Unify spell effect access api in both branches
Diffstat (limited to 'src/server/game/Spells')
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp95
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h20
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp145
-rw-r--r--src/server/game/Spells/Spell.cpp689
-rw-r--r--src/server/game/Spells/Spell.h52
-rw-r--r--src/server/game/Spells/SpellEffects.cpp55
-rw-r--r--src/server/game/Spells/SpellInfo.cpp474
-rw-r--r--src/server/game/Spells/SpellInfo.h33
-rw-r--r--src/server/game/Spells/SpellMgr.cpp307
-rw-r--r--src/server/game/Spells/SpellScript.cpp76
-rw-r--r--src/server/game/Spells/SpellScript.h5
11 files changed, 900 insertions, 1051 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 159a153ab1f..740e885bd4b 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -575,9 +575,9 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //503 SPELL_AURA_MOD_PLAYER_CHOICE_REROLLS
};
-AuraEffect::AuraEffect(Aura* base, SpellEffectInfo const* spellEfffectInfo, int32 const* baseAmount, Unit* caster) :
+AuraEffect::AuraEffect(Aura* base, SpellEffectInfo const& spellEfffectInfo, int32 const* baseAmount, Unit* caster) :
m_base(base), m_spellInfo(base->GetSpellInfo()), m_effectInfo(spellEfffectInfo), m_spellmod(nullptr),
-m_baseAmount(baseAmount ? *baseAmount : spellEfffectInfo->CalcBaseValue(caster, base->GetType() == UNIT_AURA_TYPE ? base->GetOwner()->ToUnit() : nullptr, base->GetCastItemId(), base->GetCastItemLevel())),
+m_baseAmount(baseAmount ? *baseAmount : spellEfffectInfo.CalcBaseValue(caster, base->GetType() == UNIT_AURA_TYPE ? base->GetOwner()->ToUnit() : nullptr, base->GetCastItemId(), base->GetCastItemLevel())),
_amount(), _periodicTimer(0), _period(0), _ticksDone(0),
m_canBeRecalculated(true), m_isPeriodic(false)
{
@@ -621,10 +621,10 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
// default amount calculation
int32 amount = 0;
- if (!m_spellInfo->HasAttribute(SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(GetSpellEffectInfo()->BonusCoefficient, 0.0f))
- amount = GetSpellEffectInfo()->CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit(), nullptr, GetBase()->GetCastItemId(), GetBase()->GetCastItemLevel());
+ if (!m_spellInfo->HasAttribute(SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(GetSpellEffectInfo().BonusCoefficient, 0.0f))
+ amount = GetSpellEffectInfo().CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit(), nullptr, GetBase()->GetCastItemId(), GetBase()->GetCastItemLevel());
else if (caster && caster->GetTypeId() == TYPEID_PLAYER)
- amount = int32(caster->ToPlayer()->m_activePlayerData->Mastery * GetSpellEffectInfo()->BonusCoefficient);
+ amount = int32(caster->ToPlayer()->m_activePlayerData->Mastery * GetSpellEffectInfo().BonusCoefficient);
// custom amount calculations go here
switch (GetAuraType())
@@ -668,12 +668,12 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
}
GetBase()->CallScriptEffectCalcAmountHandlers(this, amount, m_canBeRecalculated);
- if (!GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack))
+ if (!GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack))
amount *= GetBase()->GetStackAmount();
if (caster && GetBase()->GetType() == UNIT_AURA_TYPE)
{
- uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
+ uint32 stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
switch (GetAuraType())
{
@@ -719,7 +719,7 @@ void AuraEffect::ResetPeriodic(bool resetPeriodicTimer /*= false*/)
void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= true*/, bool load /*= false*/)
{
- _period = GetSpellEffectInfo()->ApplyAuraPeriod;
+ _period = GetSpellEffectInfo().ApplyAuraPeriod;
// prepare periodics
switch (GetAuraType())
@@ -801,7 +801,7 @@ void AuraEffect::CalculateSpellMod()
m_spellmod->type = GetAuraType() == SPELL_AURA_ADD_PCT_MODIFIER ? SPELLMOD_PCT : SPELLMOD_FLAT;
m_spellmod->spellId = GetId();
- m_spellmod->mask = GetSpellEffectInfo()->SpellClassMask;
+ m_spellmod->mask = GetSpellEffectInfo().SpellClassMask;
}
m_spellmod->value = GetAmount();
break;
@@ -1006,7 +1006,7 @@ bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
return false;
// Check family name and EffectClassMask
- if (!spell->IsAffected(m_spellInfo->SpellFamilyName, GetSpellEffectInfo()->SpellClassMask))
+ if (!spell->IsAffected(m_spellInfo->SpellFamilyName, GetSpellEffectInfo().SpellClassMask))
return false;
return true;
@@ -1139,7 +1139,7 @@ bool AuraEffect::CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventIn
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
{
// Don't proc extra attacks while already processing extra attack spell
- uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo().TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
if (aurApp->GetTarget()->m_extraAttacks && triggeredSpellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
return false;
@@ -2527,8 +2527,8 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
}
//some spell has one aura of mount and one of vehicle
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
- if (effect && effect->Effect == SPELL_EFFECT_SUMMON && effect->MiscValue == GetMiscValue())
+ for (SpellEffectInfo const& effect : GetSpellInfo()->GetEffects())
+ if (effect.IsEffect(SPELL_EFFECT_SUMMON) && effect.MiscValue == GetMiscValue())
displayId = 0;
}
@@ -4382,8 +4382,7 @@ void AuraEffect::HandleNoReagentUseAura(AuraApplication const* aurApp, uint8 mod
flag128 mask;
Unit::AuraEffectList const& noReagent = target->GetAuraEffectsByType(SPELL_AURA_NO_REAGENT_USE);
for (Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
- if (SpellEffectInfo const* effect = (*i)->GetSpellEffectInfo())
- mask |= effect->SpellClassMask;
+ mask |= (*i)->GetSpellEffectInfo().SpellClassMask;
target->ToPlayer()->SetNoRegentCostMask(mask);
}
@@ -4750,11 +4749,11 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
if (GetAmount() <= 0)
return;
- if (GetSpellEffectInfo()->ItemType == 0)
+ if (GetSpellEffectInfo().ItemType == 0)
return;
// Soul Shard
- if (GetSpellEffectInfo()->ItemType == 6265)
+ if (GetSpellEffectInfo().ItemType == 6265)
{
// Soul Shard only from units that grant XP or honor
if (!plCaster->isHonorOrXPTarget(target) ||
@@ -4767,16 +4766,16 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
uint32 count = GetAmount();
ItemPosCountVec dest;
- InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellEffectInfo()->ItemType, count, &noSpaceForCount);
+ InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellEffectInfo().ItemType, count, &noSpaceForCount);
if (msg != EQUIP_ERR_OK)
{
count -= noSpaceForCount;
- plCaster->SendEquipError(msg, nullptr, nullptr, GetSpellEffectInfo()->ItemType);
+ plCaster->SendEquipError(msg, nullptr, nullptr, GetSpellEffectInfo().ItemType);
if (count == 0)
return;
}
- Item* newitem = plCaster->StoreNewItem(dest, GetSpellEffectInfo()->ItemType, true);
+ Item* newitem = plCaster->StoreNewItem(dest, GetSpellEffectInfo().ItemType, true);
if (!newitem)
{
plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
@@ -4902,7 +4901,7 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
{
Unit* target = aurApp->GetTarget();
- uint32 triggeredSpellId = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggeredSpellId = GetSpellEffectInfo().TriggerSpell;
SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggeredSpellId, GetBase()->GetCastDifficulty());
if (!triggeredSpellInfo)
return;
@@ -4946,7 +4945,7 @@ void AuraEffect::HandleTriggerSpellOnPowerPercent(AuraApplication const* aurApp,
Unit* target = aurApp->GetTarget();
int32 effectAmount = GetAmount();
- uint32 triggerSpell = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggerSpell = GetSpellEffectInfo().TriggerSpell;
float powerAmountPct = GetPctOf(target->GetPower(Powers(GetMiscValue())), target->GetMaxPower(Powers(GetMiscValue())));
switch (AuraTriggerOnPowerChangeDirection(GetMiscValueB()))
@@ -4974,7 +4973,7 @@ void AuraEffect::HandleTriggerSpellOnPowerAmount(AuraApplication const* aurApp,
Unit* target = aurApp->GetTarget();
int32 effectAmount = GetAmount();
- uint32 triggerSpell = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggerSpell = GetSpellEffectInfo().TriggerSpell;
float powerAmount = target->GetPower(Powers(GetMiscValue()));
switch (AuraTriggerOnPowerChangeDirection(GetMiscValueB()))
@@ -5133,7 +5132,7 @@ void AuraEffect::HandleMastery(AuraApplication const* aurApp, uint8 mode, bool /
void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) const
{
- uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo().TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
@@ -5148,7 +5147,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit* caster) const
{
- uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo().TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
@@ -5177,13 +5176,13 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
// Consecrate ticks can miss and will not show up in the combat log
// dynobj auras must always have a caster
- if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) &&
ASSERT_NOTNULL(caster)->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
+ uint32 stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = std::max(GetAmount(), 0);
@@ -5248,7 +5247,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage, target);
// Calculate armor mitigation
- if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
+ if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), &GetSpellEffectInfo()))
{
uint32 damageReducedArmor = Unit::CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetAttackType(), GetBase()->GetCasterLevel());
cleanDamage.mitigated_damage += damage - damageReducedArmor;
@@ -5257,7 +5256,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
{
- if (GetSpellEffectInfo()->IsTargetingArea() || GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, GetBase()->GetCasterGUID());
}
@@ -5302,7 +5301,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
bool AuraEffect::IsAreaAuraEffect() const
{
- return GetSpellEffectInfo()->IsAreaAuraEffect();
+ return GetSpellEffectInfo().IsAreaAuraEffect();
}
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
@@ -5317,13 +5316,13 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
}
// dynobj auras must always have a caster
- if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) &&
ASSERT_NOTNULL(caster)->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
CleanDamage cleanDamage = CleanDamage(0, 0, GetSpellInfo()->GetAttackType(), MELEE_HIT_NORMAL);
- uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
+ uint32 stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = std::max(GetAmount(), 0);
@@ -5337,7 +5336,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage, target);
// Calculate armor mitigation
- if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
+ if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), &GetSpellEffectInfo()))
{
uint32 damageReducedArmor = Unit::CalcArmorReducedDamage(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetAttackType(), GetBase()->GetCasterLevel());
cleanDamage.mitigated_damage += damage - damageReducedArmor;
@@ -5346,7 +5345,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
{
- if (GetSpellEffectInfo()->IsTargetingArea() || GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ if (GetSpellEffectInfo().IsTargetingArea() || GetSpellEffectInfo().IsAreaAuraEffect() || GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
damage = target->CalculateAOEAvoidance(damage, m_spellInfo->SchoolMask, GetBase()->GetCasterGUID());
}
@@ -5390,7 +5389,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
if (!caster || !caster->IsAlive())
return;
- float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster);
uint32 heal = caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetSpellEffectInfo(), stackAmountForBonuses);
heal = caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT);
@@ -5425,7 +5424,7 @@ void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster)
caster->ModifyHealth(-(int32)damage);
TC_LOG_DEBUG("spells", "PeriodicTick: donator %u target %u damage %u.", caster->GetEntry(), target->GetEntry(), damage);
- float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster);
damage = int32(damage * gainMultiplier);
@@ -5453,7 +5452,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (GetBase()->IsPermanent() && target->IsFullHealth())
return;
- uint32 stackAmountForBonuses = !GetSpellEffectInfo()->EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
+ uint32 stackAmountForBonuses = !GetSpellEffectInfo().EffectAttributes.HasFlag(SpellEffectAttributes::NoScaleWithStack) ? GetBase()->GetStackAmount() : 1;
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = std::max(GetAmount(), 0);
@@ -5509,7 +5508,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
return;
}
- if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo().IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) &&
caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
@@ -5521,7 +5520,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
int32 drainedAmount = -target->ModifyPower(powerType, -drainAmount);
- float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster);
SpellPeriodicAuraLogInfo pInfo(this, drainedAmount, drainAmount, 0, 0, 0, gainMultiplier, false);
@@ -5638,7 +5637,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
uint32 gain = uint32(-target->ModifyPower(powerType, -damage));
- float dmgMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
+ float dmgMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster);
SpellInfo const* spellProto = GetSpellInfo();
// maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
@@ -5703,7 +5702,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve
Unit* triggerCaster = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
- uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo().TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellAuraProc: Triggering spell %u from aura %u proc", triggeredSpellInfo->Id, GetId());
@@ -5718,7 +5717,7 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp
Unit* triggerCaster = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
- uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo().TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId, GetBase()->GetCastDifficulty()))
{
CastSpellExtraArgs args(this);
@@ -5801,9 +5800,9 @@ void AuraEffect::HandleShowConfirmationPrompt(AuraApplication const* aurApp, uin
return;
if (apply)
- player->AddTemporarySpell(GetSpellEffectInfo()->TriggerSpell);
+ player->AddTemporarySpell(GetSpellEffectInfo().TriggerSpell);
else
- player->RemoveTemporarySpell(GetSpellEffectInfo()->TriggerSpell);
+ player->RemoveTemporarySpell(GetSpellEffectInfo().TriggerSpell);
}
void AuraEffect::HandleOverridePetSpecs(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -5897,7 +5896,7 @@ void AuraEffect::HandleLinkedSummon(AuraApplication const* aurApp, uint8 mode, b
return;
Unit* target = aurApp->GetTarget();
- SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(GetSpellEffectInfo()->TriggerSpell, GetBase()->GetCastDifficulty());
+ SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(GetSpellEffectInfo().TriggerSpell, GetBase()->GetCastDifficulty());
if (!triggerSpellInfo)
return;
@@ -5914,9 +5913,9 @@ void AuraEffect::HandleLinkedSummon(AuraApplication const* aurApp, uint8 mode, b
else
{
std::vector<uint32> summonedEntries;
- for (auto spellEffect : triggerSpellInfo->GetEffects())
- if (spellEffect && spellEffect->Effect == SPELL_EFFECT_SUMMON)
- if (uint32 summonEntry = spellEffect->MiscValue)
+ for (SpellEffectInfo const& spellEffect : triggerSpellInfo->GetEffects())
+ if (spellEffect.IsEffect(SPELL_EFFECT_SUMMON))
+ if (uint32 summonEntry = spellEffect.MiscValue)
summonedEntries.push_back(summonEntry);
// we don't know if there can be multiple summons for the same effect, so consider only 1 summon for each effect
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 1a96b81ea68..476be23e451 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -33,7 +33,7 @@ class TC_GAME_API AuraEffect
private:
~AuraEffect();
- explicit AuraEffect(Aura* base, SpellEffectInfo const* spellEfffectInfo, int32 const* baseAmount, Unit* caster);
+ explicit AuraEffect(Aura* base, SpellEffectInfo const& spellEfffectInfo, int32 const* baseAmount, Unit* caster);
public:
Unit* GetCaster() const { return GetBase()->GetCaster(); }
@@ -48,13 +48,13 @@ class TC_GAME_API AuraEffect
SpellInfo const* GetSpellInfo() const { return m_spellInfo; }
uint32 GetId() const { return m_spellInfo->Id; }
- uint32 GetEffIndex() const { return m_effectInfo->EffectIndex; }
+ SpellEffIndex GetEffIndex() const { return m_effectInfo.EffectIndex; }
int32 GetBaseAmount() const { return m_baseAmount; }
int32 GetPeriod() const { return _period; }
- int32 GetMiscValueB() const { return GetSpellEffectInfo()->MiscValueB; }
- int32 GetMiscValue() const { return GetSpellEffectInfo()->MiscValue; }
- AuraType GetAuraType() const { return (AuraType)GetSpellEffectInfo()->ApplyAuraName; }
+ int32 GetMiscValueB() const { return GetSpellEffectInfo().MiscValueB; }
+ int32 GetMiscValue() const { return GetSpellEffectInfo().MiscValue; }
+ AuraType GetAuraType() const { return GetSpellEffectInfo().ApplyAuraName; }
int32 GetAmount() const { return _amount; }
void SetAmount(int32 amount) { _amount = amount; m_canBeRecalculated = false; }
@@ -86,7 +86,7 @@ class TC_GAME_API AuraEffect
bool IsPeriodic() const { return m_isPeriodic; }
void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; }
bool IsAffectingSpell(SpellInfo const* spell) const;
- bool HasSpellClassMask() const { return GetSpellEffectInfo()->SpellClassMask; }
+ bool HasSpellClassMask() const { return GetSpellEffectInfo().SpellClassMask; }
void SendTickImmune(Unit* target, Unit* caster) const;
void PeriodicTick(AuraApplication* aurApp, Unit* caster) const;
@@ -97,17 +97,17 @@ class TC_GAME_API AuraEffect
// add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
void HandleShapeshiftBoosts(Unit* target, bool apply) const;
- SpellEffectInfo const* GetSpellEffectInfo() const { return m_effectInfo; }
+ SpellEffectInfo const& GetSpellEffectInfo() const { return m_effectInfo; }
- bool IsEffect() const { return m_effectInfo->Effect != 0; }
- bool IsEffect(SpellEffectName effectName) const { return m_effectInfo->Effect == uint32(effectName); }
+ bool IsEffect() const { return m_effectInfo.Effect != 0; }
+ bool IsEffect(SpellEffectName effectName) const { return m_effectInfo.Effect == effectName; }
bool IsAreaAuraEffect() const;
private:
Aura* const m_base;
SpellInfo const* const m_spellInfo;
- SpellEffectInfo const* m_effectInfo;
+ SpellEffectInfo const& m_effectInfo;
SpellModifier* m_spellmod;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 881828cbaa5..a6959945d0d 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -115,9 +115,9 @@ void AuraApplication::_InitFlags(Unit* caster, uint32 effMask)
if (IsSelfcast() || !caster || !caster->IsFriendlyTo(GetTarget()))
{
bool negativeFound = false;
- for (SpellEffectInfo const* effect : GetBase()->GetSpellInfo()->GetEffects())
+ for (uint8 i = 0; i < GetBase()->GetSpellInfo()->GetEffects().size(); ++i)
{
- if (effect && ((1 << effect->EffectIndex) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(effect->EffectIndex))
+ if (((1 << i) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(i))
{
negativeFound = true;
break;
@@ -130,9 +130,9 @@ void AuraApplication::_InitFlags(Unit* caster, uint32 effMask)
else
{
bool positiveFound = false;
- for (SpellEffectInfo const* effect : GetBase()->GetSpellInfo()->GetEffects())
+ for (uint8 i = 0; i < GetBase()->GetSpellInfo()->GetEffects().size(); ++i)
{
- if (effect && ((1 << effect->EffectIndex) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(effect->EffectIndex))
+ if (((1 << i) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(i))
{
positiveFound = true;
break;
@@ -300,17 +300,17 @@ uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 availab
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
- for (SpellEffectInfo const* effect : spellProto->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellProto->GetEffects())
{
- if (effect && effect->IsUnitOwnedAuraEffect())
- effMask |= 1 << effect->EffectIndex;
+ if (spellEffectInfo.IsUnitOwnedAuraEffect())
+ effMask |= 1 << spellEffectInfo.EffectIndex;
}
break;
case TYPEID_DYNAMICOBJECT:
- for (SpellEffectInfo const* effect : spellProto->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellProto->GetEffects())
{
- if (effect && effect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
- effMask |= 1 << effect->EffectIndex;
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ effMask |= 1 << spellEffectInfo.EffectIndex;
}
break;
default:
@@ -482,9 +482,9 @@ void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 const* baseAmount)
// shouldn't be in constructor - functions in AuraEffect::AuraEffect use polymorphism
_effects.resize(GetSpellInfo()->GetEffects().size());
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
- if (effect && effMask & (1 << effect->EffectIndex))
- _effects[effect->EffectIndex] = new AuraEffect(this, effect, baseAmount ? baseAmount + effect->EffectIndex : nullptr, caster);
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
+ if (effMask & (1 << spellEffectInfo.EffectIndex))
+ _effects[spellEffectInfo.EffectIndex] = new AuraEffect(this, spellEffectInfo, baseAmount ? baseAmount + spellEffectInfo.EffectIndex : nullptr, caster);
}
Aura::~Aura()
@@ -643,9 +643,9 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
{
bool addUnit = true;
// check target immunities
- for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
- if (itr->first->IsImmunedToSpellEffect(GetSpellInfo(), effIndex, caster))
- itr->second &= ~(1 << effIndex);
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
+ if (itr->first->IsImmunedToSpellEffect(GetSpellInfo(), spellEffectInfo, caster))
+ itr->second &= ~(1 << spellEffectInfo.EffectIndex);
if (!itr->second || itr->first->IsImmunedToSpell(GetSpellInfo(), caster) || !CanBeAppliedOn(itr->first))
addUnit = false;
@@ -1071,8 +1071,8 @@ bool Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode /*= AURA_REMOVE_B
bool Aura::HasMoreThanOneEffectForType(AuraType auraType) const
{
uint32 count = 0;
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
- if (effect && HasEffect(effect->EffectIndex) && AuraType(effect->ApplyAuraName) == auraType)
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
+ if (HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.ApplyAuraName == auraType)
++count;
return count > 1;
@@ -1080,8 +1080,8 @@ bool Aura::HasMoreThanOneEffectForType(AuraType auraType) const
bool Aura::IsArea() const
{
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
- if (effect && HasEffect(effect->EffectIndex) && effect->IsAreaAuraEffect())
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
+ if (HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.IsAreaAuraEffect())
return true;
return false;
@@ -1117,12 +1117,12 @@ bool Aura::CanBeSaved() const
if (GetCasterGUID() != GetOwner()->GetGUID())
{
// owner == caster for area auras, check for possible bad data in DB
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
{
- if (!effect || !effect->IsEffect())
+ if (!spellEffectInfo.IsEffect())
continue;
- if (effect->IsTargetingArea() || effect->IsAreaAuraEffect())
+ if (spellEffectInfo.IsTargetingArea() || spellEffectInfo.IsAreaAuraEffect())
return false;
}
@@ -1568,17 +1568,17 @@ bool Aura::CanStackWith(Aura const* existingAura) const
if (IsPassive() && sameCaster && (m_spellInfo->IsDifferentRankOf(existingSpellInfo) || (m_spellInfo->Id == existingSpellInfo->Id && m_castItemGuid.IsEmpty())))
return false;
- for (SpellEffectInfo const* effect : existingSpellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : existingSpellInfo->GetEffects())
{
// prevent remove triggering aura by triggered aura
- if (effect && effect->TriggerSpell == GetId())
+ if (spellEffectInfo.TriggerSpell == GetId())
return true;
}
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
{
// prevent remove triggered aura by triggering aura refresh
- if (effect && effect->TriggerSpell == existingAura->GetId())
+ if (spellEffectInfo.TriggerSpell == existingAura->GetId())
return true;
}
@@ -1625,36 +1625,39 @@ bool Aura::CanStackWith(Aura const* existingAura) const
return true;
// check same periodic auras
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ auto hasPeriodicNonAreaEffect = [](SpellInfo const* spellInfo)
{
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(i);
- if (!effect)
- continue;
- switch (effect->ApplyAuraName)
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
{
- // DOT or HOT from different casters will stack
- case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_DUMMY:
- case SPELL_AURA_PERIODIC_HEAL:
- case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
- case SPELL_AURA_PERIODIC_ENERGIZE:
- case SPELL_AURA_PERIODIC_MANA_LEECH:
- case SPELL_AURA_PERIODIC_LEECH:
- case SPELL_AURA_POWER_BURN:
- case SPELL_AURA_OBS_MOD_POWER:
- case SPELL_AURA_OBS_MOD_HEALTH:
- case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
- {
- SpellEffectInfo const* existingEffect = m_spellInfo->GetEffect(i);
+ switch (spellEffectInfo.ApplyAuraName)
+ {
+ // DOT or HOT from different casters will stack
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE:
+ case SPELL_AURA_PERIODIC_DUMMY:
+ case SPELL_AURA_PERIODIC_HEAL:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ case SPELL_AURA_PERIODIC_ENERGIZE:
+ case SPELL_AURA_PERIODIC_MANA_LEECH:
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_POWER_BURN:
+ case SPELL_AURA_OBS_MOD_POWER:
+ case SPELL_AURA_OBS_MOD_HEALTH:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
// periodic auras which target areas are not allowed to stack this way (replenishment for example)
- if (effect->IsTargetingArea() || (existingEffect && existingEffect->IsTargetingArea()))
- break;
- }
- return true;
- default:
- break;
+ if (spellEffectInfo.IsTargetingArea())
+ return false;
+ return true;
+ default:
+ break;
+ }
}
- }
+ return false;
+ };
+
+ if (hasPeriodicNonAreaEffect(m_spellInfo) && hasPeriodicNonAreaEffect(existingSpellInfo))
+ return true;
}
if (HasEffectType(SPELL_AURA_CONTROL_VEHICLE) && existingAura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE))
@@ -2382,13 +2385,13 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
if (Unit* target = ObjectAccessor::GetUnit(*GetUnitOwner(), targetPair.first))
targets.emplace(target, targetPair.second);
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
{
- if (!effect || !HasEffect(effect->EffectIndex))
+ if (!HasEffect(spellEffectInfo.EffectIndex))
continue;
// area auras only
- if (effect->Effect == SPELL_EFFECT_APPLY_AURA)
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_APPLY_AURA))
continue;
// skip area update if owner is not in world!
@@ -2399,11 +2402,11 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
continue;
std::vector<Unit*> units;
- ConditionContainer* condList = effect->ImplicitTargetConditions;
+ ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
- float radius = effect->CalcRadius(ref);
+ float radius = spellEffectInfo.CalcRadius(ref);
SpellTargetCheckTypes selectionType = TARGET_CHECK_DEFAULT;
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM:
@@ -2445,6 +2448,8 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
selectionType = TARGET_CHECK_SUMMONED;
break;
}
+ default:
+ break;
}
if (selectionType != TARGET_CHECK_DEFAULT)
@@ -2458,17 +2463,17 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
}
for (Unit* unit : units)
- targets[unit] |= 1 << effect->EffectIndex;
+ targets[unit] |= 1 << spellEffectInfo.EffectIndex;
}
}
void UnitAura::AddStaticApplication(Unit* target, uint32 effMask)
{
// only valid for non-area auras
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
{
- if (effect && (effMask & (1 << effect->EffectIndex)) && effect->Effect != SPELL_EFFECT_APPLY_AURA)
- effMask &= ~(1 << effect->EffectIndex);
+ if ((effMask & (1 << spellEffectInfo.EffectIndex)) && !spellEffectInfo.IsEffect(SPELL_EFFECT_APPLY_AURA))
+ effMask &= ~(1 << spellEffectInfo.EffectIndex);
}
if (!effMask)
@@ -2500,18 +2505,18 @@ void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit*
Unit* dynObjOwnerCaster = GetDynobjOwner()->GetCaster();
float radius = GetDynobjOwner()->GetRadius();
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : GetSpellInfo()->GetEffects())
{
- if (!effect || !HasEffect(effect->EffectIndex))
+ if (!HasEffect(spellEffectInfo.EffectIndex))
continue;
// we can't use effect type like area auras to determine check type, check targets
- SpellTargetCheckTypes selectionType = effect->TargetA.GetCheckType();
- if (effect->TargetB.GetReferenceType() == TARGET_REFERENCE_TYPE_DEST)
- selectionType = effect->TargetB.GetCheckType();
+ SpellTargetCheckTypes selectionType = spellEffectInfo.TargetA.GetCheckType();
+ if (spellEffectInfo.TargetB.GetReferenceType() == TARGET_REFERENCE_TYPE_DEST)
+ selectionType = spellEffectInfo.TargetB.GetCheckType();
std::vector<Unit*> units;
- ConditionContainer* condList = effect->ImplicitTargetConditions;
+ ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
Trinity::WorldObjectSpellAreaTargetCheck check(radius, GetDynobjOwner(), dynObjOwnerCaster, dynObjOwnerCaster, m_spellInfo, selectionType, condList, TARGET_OBJECT_TYPE_UNIT);
Trinity::UnitListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(GetDynobjOwner(), units, check);
@@ -2521,6 +2526,6 @@ void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit*
units.erase(std::remove_if(units.begin(), units.end(), [this](Unit* unit) { return !unit->IsSelfOrInSameMap(GetDynobjOwner()); }), units.end());
for (Unit* unit : units)
- targets[unit] |= 1 << effect->EffectIndex;
+ targets[unit] |= 1 << spellEffectInfo.EffectIndex;
}
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 66391ecbad2..45b53f6f93b 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -473,9 +473,8 @@ void SpellCastTargets::Update(WorldObject* caster)
SpellValue::SpellValue(SpellInfo const* proto, WorldObject const* caster)
{
memset(EffectBasePoints, 0, sizeof(EffectBasePoints));
- for (SpellEffectInfo const* effect : proto->GetEffects())
- if (effect)
- EffectBasePoints[effect->EffectIndex] = effect->CalcBaseValue(caster, nullptr, 0, -1);
+ for (SpellEffectInfo const& spellEffectInfo : proto->GetEffects())
+ EffectBasePoints[spellEffectInfo.EffectIndex] = spellEffectInfo.CalcBaseValue(caster, nullptr, 0, -1);
CustomBasePointsMask = 0;
MaxAffectedTargets = proto->MaxAffectedTargets;
@@ -735,35 +734,32 @@ void Spell::SelectSpellTargets()
uint32 processedAreaEffectsMask = 0;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
-
// not call for empty effect.
// Also some spells use not used effect targets for store targets for dummy effect in triggered spells
- if (!effect->IsEffect())
+ if (!spellEffectInfo.IsEffect())
continue;
// set expected type of implicit targets to be sent to client
- uint32 implicitTargetMask = GetTargetFlagMask(effect->TargetA.GetObjectType()) | GetTargetFlagMask(effect->TargetB.GetObjectType());
+ uint32 implicitTargetMask = GetTargetFlagMask(spellEffectInfo.TargetA.GetObjectType()) | GetTargetFlagMask(spellEffectInfo.TargetB.GetObjectType());
if (implicitTargetMask & TARGET_FLAG_UNIT)
m_targets.SetTargetFlag(TARGET_FLAG_UNIT);
if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT);
- SelectEffectImplicitTargets(SpellEffIndex(effect->EffectIndex), effect->TargetA, processedAreaEffectsMask);
- SelectEffectImplicitTargets(SpellEffIndex(effect->EffectIndex), effect->TargetB, processedAreaEffectsMask);
+ SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetA, processedAreaEffectsMask);
+ SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetB, processedAreaEffectsMask);
// Select targets of effect based on effect type
// those are used when no valid target could be added for spell effect based on spell target type
// some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
// some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
// some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
- SelectEffectTypeImplicitTargets(effect->EffectIndex);
+ SelectEffectTypeImplicitTargets(spellEffectInfo);
if (m_targets.HasDst())
- AddDestTarget(*m_targets.GetDst(), effect->EffectIndex);
+ AddDestTarget(*m_targets.GetDst(), spellEffectInfo.EffectIndex);
if (m_spellInfo->IsChanneled())
{
@@ -775,7 +771,7 @@ void Spell::SelectSpellTargets()
return;
}
- uint32 mask = (1 << effect->EffectIndex);
+ uint32 mask = (1 << spellEffectInfo.EffectIndex);
for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->EffectMask & mask)
@@ -822,12 +818,12 @@ void Spell::RecalculateDelayMomentForDst()
m_caster->m_Events.ModifyEventTime(_spellEvent, GetDelayStart() + m_delayMoment);
}
-void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask)
+void Spell::SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask)
{
if (!targetType.GetTarget())
return;
- uint32 effectMask = 1 << effIndex;
+ uint32 effectMask = 1 << spellEffectInfo.EffectIndex;
// set the same target list for all effects
// some spells appear to need this, however this requires more research
switch (targetType.GetSelectionCategory())
@@ -836,30 +832,27 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
case TARGET_SELECT_CATEGORY_CONE:
case TARGET_SELECT_CATEGORY_AREA:
case TARGET_SELECT_CATEGORY_LINE:
+ {
// targets for effect already selected
if (effectMask & processedEffectMask)
return;
- if (SpellEffectInfo const* _effect = m_spellInfo->GetEffect(effIndex))
- {
- // choose which targets we can select at once
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ std::vector<SpellEffectInfo> const& effects = GetSpellInfo()->GetEffects();
+ // choose which targets we can select at once
+ for (uint32 j = spellEffectInfo.EffectIndex + 1; j < effects.size(); ++j)
+ {
+ if (effects[j].IsEffect() &&
+ spellEffectInfo.TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
+ spellEffectInfo.TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
+ spellEffectInfo.ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
+ spellEffectInfo.CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
+ CheckScriptEffectImplicitTargets(spellEffectInfo.EffectIndex, j))
{
- //for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
- if (!effect || effect->EffectIndex <= uint32(effIndex))
- continue;
- if (effect->IsEffect() &&
- _effect->TargetA.GetTarget() == effect->TargetA.GetTarget() &&
- _effect->TargetB.GetTarget() == effect->TargetB.GetTarget() &&
- _effect->ImplicitTargetConditions == effect->ImplicitTargetConditions &&
- _effect->CalcRadius(m_caster) == effect->CalcRadius(m_caster) &&
- CheckScriptEffectImplicitTargets(effIndex, effect->EffectIndex))
- {
- effectMask |= 1 << effect->EffectIndex;
- }
+ effectMask |= 1 << j;
}
}
processedEffectMask |= effectMask;
break;
+ }
default:
break;
}
@@ -867,25 +860,25 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
switch (targetType.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_CHANNEL:
- SelectImplicitChannelTargets(effIndex, targetType);
+ SelectImplicitChannelTargets(spellEffectInfo, targetType);
break;
case TARGET_SELECT_CATEGORY_NEARBY:
- SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
+ SelectImplicitNearbyTargets(spellEffectInfo, targetType, effectMask);
break;
case TARGET_SELECT_CATEGORY_CONE:
- SelectImplicitConeTargets(effIndex, targetType, effectMask);
+ SelectImplicitConeTargets(spellEffectInfo, targetType, effectMask);
break;
case TARGET_SELECT_CATEGORY_AREA:
- SelectImplicitAreaTargets(effIndex, targetType, effectMask);
+ SelectImplicitAreaTargets(spellEffectInfo, targetType, effectMask);
break;
case TARGET_SELECT_CATEGORY_TRAJ:
// just in case there is no dest, explanation in SelectImplicitDestDestTargets
CheckDst();
- SelectImplicitTrajTargets(effIndex, targetType);
+ SelectImplicitTrajTargets(spellEffectInfo, targetType);
break;
case TARGET_SELECT_CATEGORY_LINE:
- SelectImplicitLineTargets(effIndex, targetType, effectMask);
+ SelectImplicitLineTargets(spellEffectInfo, targetType, effectMask);
break;
case TARGET_SELECT_CATEGORY_DEFAULT:
switch (targetType.GetObjectType())
@@ -905,13 +898,13 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_CASTER:
- SelectImplicitCasterDestTargets(effIndex, targetType);
+ SelectImplicitCasterDestTargets(spellEffectInfo, targetType);
break;
case TARGET_REFERENCE_TYPE_TARGET:
- SelectImplicitTargetDestTargets(effIndex, targetType);
+ SelectImplicitTargetDestTargets(spellEffectInfo, targetType);
break;
case TARGET_REFERENCE_TYPE_DEST:
- SelectImplicitDestDestTargets(effIndex, targetType);
+ SelectImplicitDestDestTargets(spellEffectInfo, targetType);
break;
default:
ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
@@ -922,10 +915,10 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_CASTER:
- SelectImplicitCasterObjectTargets(effIndex, targetType);
+ SelectImplicitCasterObjectTargets(spellEffectInfo, targetType);
break;
case TARGET_REFERENCE_TYPE_TARGET:
- SelectImplicitTargetObjectTargets(effIndex, targetType);
+ SelectImplicitTargetObjectTargets(spellEffectInfo, targetType);
break;
default:
ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
@@ -935,7 +928,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
}
break;
case TARGET_SELECT_CATEGORY_NYI:
- TC_LOG_DEBUG("spells", "SPELL: target type %u, found in spellID %u, effect %u is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
+ TC_LOG_DEBUG("spells", "SPELL: target type %u, found in spellID %u, effect %u is not implemented yet!", m_spellInfo->Id, uint32(spellEffectInfo.EffectIndex), targetType.GetTarget());
break;
default:
ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
@@ -943,7 +936,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
}
}
-void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+void Spell::SelectImplicitChannelTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType)
{
if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
{
@@ -954,7 +947,7 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa
Spell* channeledSpell = m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
if (!channeledSpell)
{
- TC_LOG_DEBUG("spells", "Spell::SelectImplicitChannelTargets: cannot find channel spell for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ TC_LOG_DEBUG("spells", "Spell::SelectImplicitChannelTargets: cannot find channel spell for spell ID %u, effect %u", m_spellInfo->Id, uint32(spellEffectInfo.EffectIndex));
return;
}
switch (targetType.GetTarget())
@@ -964,13 +957,13 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa
for (ObjectGuid const& channelTarget : m_originalCaster->m_unitData->ChannelObjects)
{
WorldObject* target = ObjectAccessor::GetUnit(*m_caster, channelTarget);
- CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
+ CallScriptObjectTargetSelectHandlers(target, spellEffectInfo.EffectIndex, targetType);
// unit target may be no longer avalible - teleported out of map for example
Unit* unitTarget = target ? target->ToUnit() : nullptr;
if (unitTarget)
- AddUnitTarget(unitTarget, 1 << effIndex);
+ AddUnitTarget(unitTarget, 1 << spellEffectInfo.EffectIndex);
else
- TC_LOG_DEBUG("spells", "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ TC_LOG_DEBUG("spells", "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, uint32(spellEffectInfo.EffectIndex));
}
break;
}
@@ -983,22 +976,22 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa
WorldObject* target = !channelObjects.empty() ? ObjectAccessor::GetWorldObject(*m_caster, *channelObjects.begin()) : nullptr;
if (target)
{
- CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
+ CallScriptObjectTargetSelectHandlers(target, spellEffectInfo.EffectIndex, targetType);
if (target)
{
SpellDestination dest(*target);
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.SetDst(dest);
}
}
else
- TC_LOG_DEBUG("spells", "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ TC_LOG_DEBUG("spells", "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, uint32(spellEffectInfo.EffectIndex));
}
break;
case TARGET_DEST_CHANNEL_CASTER:
{
SpellDestination dest(*channeledSpell->GetCaster());
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.SetDst(dest);
break;
}
@@ -1008,7 +1001,7 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa
}
}
-void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+void Spell::SelectImplicitNearbyTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask)
{
if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
{
@@ -1016,10 +1009,6 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
return;
}
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
- if (!effect)
- return;
-
float range = 0.0f;
switch (targetType.GetCheckType())
{
@@ -1041,12 +1030,12 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
break;
}
- ConditionContainer* condList = effect->ImplicitTargetConditions;
+ ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
// handle emergency case - try to use other provided targets if no conditions provided
if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
{
- TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID %u, effect %u - selecting default targets", m_spellInfo->Id, effIndex);
+ TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID %u, effect %u - selecting default targets", m_spellInfo->Id, uint32(spellEffectInfo.EffectIndex));
switch (targetType.GetObjectType())
{
case TARGET_OBJECT_TYPE_GOBJ:
@@ -1068,7 +1057,7 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
if (focusObject)
{
SpellDestination dest(*focusObject);
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.SetDst(dest);
}
else
@@ -1087,16 +1076,16 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
if (!target)
{
- TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID %u, effect %u", m_spellInfo->Id, uint32(spellEffectInfo.EffectIndex));
SendCastResult(SPELL_FAILED_BAD_IMPLICIT_TARGETS);
finish(false);
return;
}
- CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
+ CallScriptObjectTargetSelectHandlers(target, spellEffectInfo.EffectIndex, targetType);
if (!target)
{
- TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id %u set NULL target, effect %u", m_spellInfo->Id, effIndex);
+ TC_LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id %u set NULL target, effect %u", m_spellInfo->Id, uint32(spellEffectInfo.EffectIndex));
SendCastResult(SPELL_FAILED_BAD_IMPLICIT_TARGETS);
finish(false);
return;
@@ -1129,7 +1118,7 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
case TARGET_OBJECT_TYPE_DEST:
{
SpellDestination dest(*target);
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.SetDst(dest);
break;
}
@@ -1138,10 +1127,10 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
break;
}
- SelectImplicitChainTargets(effIndex, targetType, target, effMask);
+ SelectImplicitChainTargets(spellEffectInfo, targetType, target, effMask);
}
-void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+void Spell::SelectImplicitConeTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask)
{
if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
{
@@ -1151,12 +1140,8 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
std::list<WorldObject*> targets;
SpellTargetObjectTypes objectType = targetType.GetObjectType();
SpellTargetCheckTypes selectionType = targetType.GetCheckType();
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
- if (!effect)
- return;
-
- ConditionContainer* condList = effect->ImplicitTargetConditions;
- float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
+ ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
+ float radius = spellEffectInfo.CalcRadius(m_caster) * m_spellValue->RadiusMod;
if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
{
@@ -1164,7 +1149,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
- CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
+ CallScriptObjectAreaTargetSelectHandlers(targets, spellEffectInfo.EffectIndex, targetType);
if (!targets.empty())
{
@@ -1183,7 +1168,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
}
-void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+void Spell::SelectImplicitAreaTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask)
{
WorldObject* referer = nullptr;
switch (targetType.GetReferenceType())
@@ -1201,7 +1186,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
// find last added target for this effect
for (auto ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
{
- if (ihit->EffectMask & (1 << effIndex))
+ if (ihit->EffectMask & (1 << spellEffectInfo.EffectIndex))
{
referer = ObjectAccessor::GetUnit(*m_caster, ihit->TargetGUID);
break;
@@ -1237,10 +1222,6 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
std::list<WorldObject*> targets;
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
- if (!effect)
- return;
-
switch (targetType.GetTarget())
{
case TARGET_UNIT_TARGET_ALLY_OR_RAID:
@@ -1250,7 +1231,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
{
targets.push_back(m_targets.GetUnitTarget());
- CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
+ CallScriptObjectAreaTargetSelectHandlers(targets, spellEffectInfo.EffectIndex, targetType);
if (!targets.empty())
{
@@ -1280,11 +1261,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
break;
}
- float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
+ float radius = spellEffectInfo.CalcRadius(m_caster) * m_spellValue->RadiusMod;
- SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), effect->ImplicitTargetConditions);
+ SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions);
- CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
+ CallScriptObjectAreaTargetSelectHandlers(targets, spellEffectInfo.EffectIndex, targetType);
if (!targets.empty())
{
@@ -1302,7 +1283,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
}
-void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+void Spell::SelectImplicitCasterDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType)
{
SpellDestination dest(*m_caster);
@@ -1315,7 +1296,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
break;
case TARGET_DEST_DB:
- if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
+ if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, spellEffectInfo.EffectIndex))
{
/// @todo fix this check
if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND))
@@ -1370,7 +1351,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
if (!unitCaster)
break;
- float dist = m_spellInfo->GetEffect(effIndex)->CalcRadius(unitCaster);
+ float dist = spellEffectInfo.CalcRadius(unitCaster);
float angle = targetType.CalcDirectionAngle();
Position pos = dest._position;
@@ -1405,52 +1386,49 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
break;
default:
{
- if (SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex))
- {
- float dist = effect->CalcRadius(m_caster);
- float angle = targetType.CalcDirectionAngle();
- float objSize = m_caster->GetCombatReach();
+ float dist = spellEffectInfo.CalcRadius(m_caster);
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = m_caster->GetCombatReach();
- switch (targetType.GetTarget())
+ switch (targetType.GetTarget())
+ {
+ case TARGET_DEST_CASTER_SUMMON:
+ dist = PET_FOLLOW_DIST;
+ break;
+ case TARGET_DEST_CASTER_RANDOM:
+ if (dist > objSize)
+ dist = objSize + (dist - objSize) * float(rand_norm());
+ break;
+ case TARGET_DEST_CASTER_FRONT_LEFT:
+ case TARGET_DEST_CASTER_BACK_LEFT:
+ case TARGET_DEST_CASTER_FRONT_RIGHT:
+ case TARGET_DEST_CASTER_BACK_RIGHT:
{
- case TARGET_DEST_CASTER_SUMMON:
- dist = PET_FOLLOW_DIST;
- break;
- case TARGET_DEST_CASTER_RANDOM:
- if (dist > objSize)
- dist = objSize + (dist - objSize) * float(rand_norm());
- break;
- case TARGET_DEST_CASTER_FRONT_LEFT:
- case TARGET_DEST_CASTER_BACK_LEFT:
- case TARGET_DEST_CASTER_FRONT_RIGHT:
- case TARGET_DEST_CASTER_BACK_RIGHT:
- {
- static float const DefaultTotemDistance = 3.0f;
- if (!effect->HasRadius() && !effect->HasMaxRadius())
- dist = DefaultTotemDistance;
- break;
- }
- default:
- break;
+ static float const DefaultTotemDistance = 3.0f;
+ if (!spellEffectInfo.HasRadius() && !spellEffectInfo.HasMaxRadius())
+ dist = DefaultTotemDistance;
+ break;
}
+ default:
+ break;
+ }
- if (dist < objSize)
- dist = objSize;
+ if (dist < objSize)
+ dist = objSize;
- Position pos = dest._position;
- m_caster->MovePositionToFirstCollision(pos, dist, angle);
+ Position pos = dest._position;
+ m_caster->MovePositionToFirstCollision(pos, dist, angle);
- dest.Relocate(pos);
- }
+ dest.Relocate(pos);
break;
}
}
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.SetDst(dest);
}
-void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+void Spell::SelectImplicitTargetDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType)
{
ASSERT(m_targets.GetObjectTarget() && "Spell::SelectImplicitTargetDestTargets - no explicit object target available!");
WorldObject* target = m_targets.GetObjectTarget();
@@ -1465,27 +1443,24 @@ void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplici
break;
default:
{
- if (SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex))
- {
- float angle = targetType.CalcDirectionAngle();
- float dist = effect->CalcRadius(nullptr);
- if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
- dist *= float(rand_norm());
+ float angle = targetType.CalcDirectionAngle();
+ float dist = spellEffectInfo.CalcRadius(nullptr);
+ if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
+ dist *= float(rand_norm());
- Position pos = dest._position;
- target->MovePositionToFirstCollision(pos, dist, angle);
+ Position pos = dest._position;
+ target->MovePositionToFirstCollision(pos, dist, angle);
- dest.Relocate(pos);
- }
+ dest.Relocate(pos);
break;
}
}
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.SetDst(dest);
}
-void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+void Spell::SelectImplicitDestDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType)
{
// set destination to caster if no dest provided
// can only happen if previous destination target could not be set for some reason
@@ -1504,27 +1479,24 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
return;
default:
{
- if (SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex))
- {
- float angle = targetType.CalcDirectionAngle();
- float dist = effect->CalcRadius(m_caster);
- if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
- dist *= float(rand_norm());
+ float angle = targetType.CalcDirectionAngle();
+ float dist = spellEffectInfo.CalcRadius(m_caster);
+ if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
+ dist *= float(rand_norm());
- Position pos = dest._position;
- m_caster->MovePositionToFirstCollision(pos, dist, angle);
+ Position pos = dest._position;
+ m_caster->MovePositionToFirstCollision(pos, dist, angle);
- dest.Relocate(pos);
- }
+ dest.Relocate(pos);
break;
}
}
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.ModDst(dest);
}
-void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+void Spell::SelectImplicitCasterObjectTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType)
{
WorldObject* target = nullptr;
bool checkIfValid = true;
@@ -1571,63 +1543,59 @@ void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImpli
break;
}
- CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
+ CallScriptObjectTargetSelectHandlers(target, spellEffectInfo.EffectIndex, targetType);
if (target)
{
if (Unit* unit = target->ToUnit())
- AddUnitTarget(unit, 1 << effIndex, checkIfValid);
+ AddUnitTarget(unit, 1 << spellEffectInfo.EffectIndex, checkIfValid);
else if (GameObject* go = target->ToGameObject())
- AddGOTarget(go, 1 << effIndex);
+ AddGOTarget(go, 1 << spellEffectInfo.EffectIndex);
}
}
-void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+void Spell::SelectImplicitTargetObjectTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType)
{
ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
WorldObject* target = m_targets.GetObjectTarget();
- CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
+ CallScriptObjectTargetSelectHandlers(target, spellEffectInfo.EffectIndex, targetType);
if (target)
{
if (Unit* unit = target->ToUnit())
- AddUnitTarget(unit, 1 << effIndex, true, false);
+ AddUnitTarget(unit, 1 << spellEffectInfo.EffectIndex, true, false);
else if (GameObject* gobj = target->ToGameObject())
- AddGOTarget(gobj, 1 << effIndex);
+ AddGOTarget(gobj, 1 << spellEffectInfo.EffectIndex);
- SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
+ SelectImplicitChainTargets(spellEffectInfo, targetType, target, 1 << spellEffectInfo.EffectIndex);
}
// Script hook can remove object target and we would wrongly land here
else if (Item* item = m_targets.GetItemTarget())
- AddItemTarget(item, 1 << effIndex);
+ AddItemTarget(item, 1 << spellEffectInfo.EffectIndex);
}
-void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask)
+void Spell::SelectImplicitChainTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask)
{
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
- if (!effect)
- return;
-
- int32 maxTargets = effect->ChainTargets;
+ int32 maxTargets = spellEffectInfo.ChainTargets;
if (Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo, SpellModOp::ChainTargets, maxTargets, this);
if (maxTargets > 1)
{
// mark damage multipliers as used
- for (SpellEffectInfo const* eff : m_spellInfo->GetEffects())
- if (eff && (effMask & (1 << eff->EffectIndex)))
- m_damageMultipliers[eff->EffectIndex] = 1.0f;
+ for (size_t k = spellEffectInfo.EffectIndex; k < m_spellInfo->GetEffects().size(); ++k)
+ if (effMask & (1 << k))
+ m_damageMultipliers[k] = 1.0f;
m_applyMultiplierMask |= effMask;
std::list<WorldObject*> targets;
SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType()
- , effect->ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
+ , spellEffectInfo.ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
// Chain primary target is added earlier
- CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
+ CallScriptObjectAreaTargetSelectHandlers(targets, spellEffectInfo.EffectIndex, targetType);
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if (Unit* unit = (*itr)->ToUnit())
@@ -1647,7 +1615,7 @@ float tangent(float x)
return 0.0f;
}
-void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+void Spell::SelectImplicitTrajTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType)
{
if (!m_targets.HasTraj())
return;
@@ -1660,9 +1628,8 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTarge
srcPos.SetOrientation(m_caster->GetOrientation());
float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
std::list<WorldObject*> targets;
- Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), effect->ImplicitTargetConditions, TARGET_OBJECT_TYPE_NONE);
+ Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions, TARGET_OBJECT_TYPE_NONE);
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> searcher(m_caster, targets, check, GRID_MAP_TYPE_MASK_ALL);
SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
if (targets.empty())
@@ -1678,7 +1645,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTarge
// We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
// limit max range to 300 yards, sometimes triggered spells can have 50000yds
float bestDist = m_spellInfo->GetMaxRange(false);
- if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(effect->TriggerSpell, GetCastDifficulty()))
+ if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, GetCastDifficulty()))
bestDist = std::min(std::max(bestDist, triggerSpellInfo->GetMaxRange(false)), std::min(dist2d, 300.0f));
// GameObjects don't cast traj
@@ -1726,20 +1693,16 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTarge
float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
SpellDestination dest(x, y, z, unitCaster->GetOrientation());
- CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
+ CallScriptDestinationTargetSelectHandlers(dest, spellEffectInfo.EffectIndex, targetType);
m_targets.ModDst(dest);
}
}
-void Spell::SelectImplicitLineTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+void Spell::SelectImplicitLineTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask)
{
std::list<WorldObject*> targets;
SpellTargetObjectTypes objectType = targetType.GetObjectType();
SpellTargetCheckTypes selectionType = targetType.GetCheckType();
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
- if (!effect)
- return;
-
Position const* dst = nullptr;
switch (targetType.GetReferenceType())
{
@@ -1760,8 +1723,8 @@ void Spell::SelectImplicitLineTargets(SpellEffIndex effIndex, SpellImplicitTarge
return;
}
- ConditionContainer* condList = effect->ImplicitTargetConditions;
- float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
+ ConditionContainer* condList = spellEffectInfo.ImplicitTargetConditions;
+ float radius = spellEffectInfo.CalcRadius(m_caster) * m_spellValue->RadiusMod;
if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
{
@@ -1769,7 +1732,7 @@ void Spell::SelectImplicitLineTargets(SpellEffIndex effIndex, SpellImplicitTarge
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellLineTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellLineTargetCheck>>(searcher, containerTypeMask, m_caster, m_caster, radius);
- CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
+ CallScriptObjectAreaTargetSelectHandlers(targets, spellEffectInfo.EffectIndex, targetType);
if (!targets.empty())
{
@@ -1794,20 +1757,17 @@ void Spell::SelectImplicitLineTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
}
-void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
+void Spell::SelectEffectTypeImplicitTargets(SpellEffectInfo const& spellEffectInfo)
{
// special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER, queue them on map for later execution
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(effIndex);
- if (!effect)
- return;
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_SUMMON_RAF_FRIEND:
case SPELL_EFFECT_SUMMON_PLAYER:
if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_caster->ToPlayer()->GetTarget().IsEmpty())
{
WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetTarget());
- CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex), SpellImplicitTargetInfo());
+ CallScriptObjectTargetSelectHandlers(target, spellEffectInfo.EffectIndex, SpellImplicitTargetInfo());
// scripts may modify the target - recheck
if (target && target->GetTypeId() == TYPEID_PLAYER)
@@ -1816,21 +1776,21 @@ void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
// since we're completely skipping AddUnitTarget logic, we need to check immunity manually
// eg. aura 21546 makes target immune to summons
Player* player = target->ToPlayer();
- if (player->IsImmunedToSpellEffect(m_spellInfo, effIndex, nullptr))
+ if (player->IsImmunedToSpellEffect(m_spellInfo, spellEffectInfo, nullptr))
return;
- target->GetMap()->AddFarSpellCallback(std::bind([](Map* map, Spell* spell, uint8 effIndex, ObjectGuid const& targetGuid)
+ target->GetMap()->AddFarSpellCallback([spell = this, &spellEffectInfo, targetGuid = target->GetGUID()](Map* map)
{
Player* player = ObjectAccessor::GetPlayer(map, targetGuid);
if (!player)
return;
// check immunity again in case it changed during update
- if (player->IsImmunedToSpellEffect(spell->GetSpellInfo(), effIndex, nullptr))
+ if (player->IsImmunedToSpellEffect(spell->GetSpellInfo(), spellEffectInfo, nullptr))
return;
- spell->HandleEffects(player, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
- }, std::placeholders::_1, this, effIndex, target->GetGUID()));
+ spell->HandleEffects(player, nullptr, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ });
}
}
return;
@@ -1839,17 +1799,17 @@ void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
}
// select spell implicit targets based on effect type
- if (!effect->GetImplicitTargetType())
+ if (!spellEffectInfo.GetImplicitTargetType())
return;
- uint32 targetMask = effect->GetMissingTargetMask();
+ uint32 targetMask = spellEffectInfo.GetMissingTargetMask();
if (!targetMask)
return;
WorldObject* target = nullptr;
- switch (effect->GetImplicitTargetType())
+ switch (spellEffectInfo.GetImplicitTargetType())
{
// add explicit object target or self to the target map
case EFFECT_IMPLICIT_TARGET_EXPLICIT:
@@ -1873,7 +1833,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
if (targetMask & TARGET_FLAG_ITEM_MASK)
{
if (Item* item = m_targets.GetItemTarget())
- AddItemTarget(item, 1 << effIndex);
+ AddItemTarget(item, 1 << spellEffectInfo.EffectIndex);
return;
}
if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
@@ -1888,14 +1848,14 @@ void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
break;
}
- CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex), SpellImplicitTargetInfo());
+ CallScriptObjectTargetSelectHandlers(target, spellEffectInfo.EffectIndex, SpellImplicitTargetInfo());
if (target)
{
if (target->ToUnit())
- AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
+ AddUnitTarget(target->ToUnit(), 1 << spellEffectInfo.EffectIndex, false);
else if (target->ToGameObject())
- AddGOTarget(target->ToGameObject(), 1 << effIndex);
+ AddGOTarget(target->ToGameObject(), 1 << spellEffectInfo.EffectIndex);
}
}
@@ -2193,12 +2153,9 @@ class ProcReflectDelayed : public BasicEvent
void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/, Position const* losPosition /*= nullptr*/)
{
- uint32 validEffectMask = 0;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect && (effectMask & (1 << effect->EffectIndex)) != 0 && CheckEffectTarget(target, effect, losPosition))
- validEffectMask |= 1 << effect->EffectIndex;
-
- effectMask &= validEffectMask;
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
+ if (!spellEffectInfo.IsEffect() || !CheckEffectTarget(target, spellEffectInfo, losPosition))
+ effectMask &= ~(1 << spellEffectInfo.EffectIndex);
// no effects left
if (!effectMask)
@@ -2209,9 +2166,9 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
return;
// Check for effect immune skip if immuned
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect && target->IsImmunedToSpellEffect(m_spellInfo, effect->EffectIndex, m_caster))
- effectMask &= ~(1 << effect->EffectIndex);
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
+ if (target->IsImmunedToSpellEffect(m_spellInfo, spellEffectInfo, m_caster))
+ effectMask &= ~(1 << spellEffectInfo.EffectIndex);
ObjectGuid targetGUID = target->GetGUID();
@@ -2285,12 +2242,9 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
{
- uint32 validEffectMask = 0;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect && (effectMask & (1 << effect->EffectIndex)) != 0 && CheckEffectTarget(go, effect))
- validEffectMask |= 1 << effect->EffectIndex;
-
- effectMask &= validEffectMask;
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
+ if (!spellEffectInfo.IsEffect() || !CheckEffectTarget(go, spellEffectInfo))
+ effectMask &= ~(1 << spellEffectInfo.EffectIndex);
// no effects left
if (!effectMask)
@@ -2341,12 +2295,9 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
void Spell::AddItemTarget(Item* item, uint32 effectMask)
{
- uint32 validEffectMask = 0;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect && (effectMask & (1 << effect->EffectIndex)) != 0 && CheckEffectTarget(item, effect))
- validEffectMask |= 1 << effect->EffectIndex;
-
- effectMask &= validEffectMask;
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
+ if (!spellEffectInfo.IsEffect() || !CheckEffectTarget(item, spellEffectInfo))
+ effectMask &= ~(1 << spellEffectInfo.EffectIndex);
// no effects left
if (!effectMask)
@@ -2442,7 +2393,7 @@ void Spell::TargetInfo::PreprocessTarget(Spell* spell)
Healing = spell->m_healing;
}
-void Spell::TargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
+void Spell::TargetInfo::DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo)
{
Unit* unit = spell->m_caster->GetGUID() == TargetGUID ? spell->m_caster->ToUnit() : ObjectAccessor::GetUnit(*spell->m_caster, TargetGUID);
if (!unit)
@@ -2464,7 +2415,7 @@ void Spell::TargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
return; // No missinfo in that case
if (_spellHitTarget)
- spell->DoSpellEffectHit(_spellHitTarget, effIndex, *this);
+ spell->DoSpellEffectHit(_spellHitTarget, spellEffectInfo, *this);
// scripts can modify damage/healing for current target, save them
Damage = spell->m_damage;
@@ -2510,7 +2461,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell)
positive = false;
else if (!spell->m_healing)
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (uint8 i = 0; i < spell->m_spellInfo->GetEffects().size(); ++i)
{
// in case of immunity, check all effects to choose correct procFlags, as none has technically hit
if (EffectMask && !(EffectMask & (1 << i)))
@@ -2704,7 +2655,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell)
spell->CallScriptAfterHitHandlers();
}
-void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
+void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo)
{
GameObject* go = spell->m_caster->GetGUID() == TargetGUID ? spell->m_caster->ToGameObject() : ObjectAccessor::GetGameObject(*spell->m_caster, TargetGUID);
if (!go)
@@ -2712,7 +2663,7 @@ void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
spell->CallScriptBeforeHitHandlers(SPELL_MISS_NONE);
- spell->HandleEffects(nullptr, nullptr, go, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ spell->HandleEffects(nullptr, nullptr, go, spellEffectInfo, SPELL_EFFECT_HANDLE_HIT_TARGET);
//AI functions
if (go->AI())
@@ -2732,11 +2683,11 @@ void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
spell->CallScriptAfterHitHandlers();
}
-void Spell::ItemTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex)
+void Spell::ItemTargetInfo::DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo)
{
spell->CallScriptBeforeHitHandlers(SPELL_MISS_NONE);
- spell->HandleEffects(nullptr, TargetItem, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ spell->HandleEffects(nullptr, TargetItem, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_HIT_TARGET);
spell->CallScriptOnHitHandlers();
spell->CallScriptAfterHitHandlers();
@@ -2812,11 +2763,10 @@ SpellMissInfo Spell::PreprocessSpellHit(Unit* unit, TargetInfo& hitInfo)
// check immunity due to diminishing returns
if (Aura::BuildEffectMaskForOwner(m_spellInfo, MAX_EFFECT_MASK, unit))
{
- for (SpellEffectInfo const* auraSpellEffect : m_spellInfo->GetEffects())
- if (auraSpellEffect)
- hitInfo.AuraBasePoints[auraSpellEffect->EffectIndex] = (m_spellValue->CustomBasePointsMask & (1 << auraSpellEffect->EffectIndex)) ?
- m_spellValue->EffectBasePoints[auraSpellEffect->EffectIndex] :
- auraSpellEffect->CalcBaseValue(m_originalCaster, unit, m_castItemEntry, m_castItemLevel);
+ for (SpellEffectInfo const& auraSpellEffect : m_spellInfo->GetEffects())
+ hitInfo.AuraBasePoints[auraSpellEffect.EffectIndex] = (m_spellValue->CustomBasePointsMask & (1 << auraSpellEffect.EffectIndex))
+ ? m_spellValue->EffectBasePoints[auraSpellEffect.EffectIndex]
+ : auraSpellEffect.CalcBaseValue(m_originalCaster, unit, m_castItemEntry, m_castItemLevel);
// Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
hitInfo.DRGroup = m_spellInfo->GetDiminishingReturnsGroupForSpell();
@@ -2836,13 +2786,12 @@ SpellMissInfo Spell::PreprocessSpellHit(Unit* unit, TargetInfo& hitInfo)
hitInfo.Positive = true;
if (origCaster == unit || !origCaster->IsFriendlyTo(unit))
{
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& auraSpellEffect : m_spellInfo->GetEffects())
{
// mod duration only for effects applying aura!
- if (effect &&
- hitInfo.EffectMask & (1 << effect->EffectIndex) &&
- effect->IsUnitOwnedAuraEffect() &&
- !m_spellInfo->IsPositiveEffect(effect->EffectIndex))
+ if (hitInfo.EffectMask & (1 << auraSpellEffect.EffectIndex) &&
+ auraSpellEffect.IsUnitOwnedAuraEffect() &&
+ !m_spellInfo->IsPositiveEffect(auraSpellEffect.EffectIndex))
{
hitInfo.Positive = false;
break;
@@ -2854,16 +2803,16 @@ SpellMissInfo Spell::PreprocessSpellHit(Unit* unit, TargetInfo& hitInfo)
// unit is immune to aura if it was diminished to 0 duration
if (!hitInfo.Positive && !unit->ApplyDiminishingToDuration(m_spellInfo, hitInfo.AuraDuration, origCaster, diminishLevel))
- if (std::all_of(std::begin(m_spellInfo->GetEffects()), std::end(m_spellInfo->GetEffects()), [](SpellEffectInfo const* effInfo) { return !effInfo || !effInfo->IsEffect() || effInfo->IsEffect(SPELL_EFFECT_APPLY_AURA); }))
+ if (std::all_of(std::begin(m_spellInfo->GetEffects()), std::end(m_spellInfo->GetEffects()), [](SpellEffectInfo const& effInfo) { return !effInfo.IsEffect() || effInfo.Effect == SPELL_EFFECT_APPLY_AURA; }))
return SPELL_MISS_IMMUNE;
}
return SPELL_MISS_NONE;
}
-void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
+void Spell::DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo, TargetInfo& hitInfo)
{
- if (uint32 aura_effmask = Aura::BuildEffectMaskForOwner(m_spellInfo, 1 << effIndex, unit))
+ if (uint32 aura_effmask = Aura::BuildEffectMaskForOwner(m_spellInfo, 1 << spellEffectInfo.EffectIndex, unit))
{
WorldObject* caster = m_caster;
if (m_originalCaster)
@@ -2919,11 +2868,10 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
{
int32 origDuration = hitInfo.AuraDuration;
hitInfo.AuraDuration = 0;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect)
- if (AuraEffect const* eff = _spellAura->GetEffect(effect->EffectIndex))
- if (int32 period = eff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED
- hitInfo.AuraDuration = std::max(std::max(origDuration / period, 1) * period, hitInfo.AuraDuration);
+ for (AuraEffect const* auraEff : _spellAura->GetAuraEffects())
+ if (auraEff)
+ if (int32 period = auraEff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED
+ hitInfo.AuraDuration = std::max(std::max(origDuration / period, 1) * period, hitInfo.AuraDuration);
// if there is no periodic effect
if (!hitInfo.AuraDuration)
@@ -2940,7 +2888,7 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
}
}
- HandleEffects(unit, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ HandleEffects(unit, nullptr, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_HIT_TARGET);
}
void Spell::DoTriggersOnSpellHit(Unit* unit, uint32 effMask)
@@ -3000,9 +2948,9 @@ bool Spell::UpdateChanneledTargetList()
uint32 channelTargetEffectMask = m_channelTargetEffectMask;
uint32 channelAuraMask = 0;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
- channelAuraMask |= 1 << effect->EffectIndex;
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_APPLY_AURA))
+ channelAuraMask |= 1 << spellEffectInfo.EffectIndex;
channelAuraMask &= channelTargetEffectMask;
@@ -3397,9 +3345,9 @@ void Spell::_cast(bool skipCheck)
if (Unit* target = m_targets.GetUnitTarget())
{
uint32 aura_effmask = 0;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect && effect->IsUnitOwnedAuraEffect())
- aura_effmask |= 1 << effect->EffectIndex;
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
+ if (spellEffectInfo.IsUnitOwnedAuraEffect())
+ aura_effmask |= 1 << spellEffectInfo.EffectIndex;
if (aura_effmask)
{
@@ -3586,10 +3534,10 @@ void Spell::DoProcessTargetContainer(Container& targetContainer)
for (TargetInfoBase& target : targetContainer)
target.PreprocessTarget(this);
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
for (TargetInfoBase& target : targetContainer)
- if (target.EffectMask & (1 << i))
- target.DoTargetSpellHit(this, i);
+ if (target.EffectMask & (1 << spellEffectInfo.EffectIndex))
+ target.DoTargetSpellHit(this, spellEffectInfo);
for (TargetInfoBase& target : targetContainer)
target.DoDamageAndTriggers(this);
@@ -3771,14 +3719,14 @@ void Spell::_handle_immediate_phase()
HandleThreatSpells();
// handle effects with SPELL_EFFECT_HANDLE_HIT mode
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
// don't do anything for empty effect
- if (!effect || !effect->IsEffect())
+ if (!spellEffectInfo.IsEffect())
continue;
// call effect handlers to handle destination hit
- HandleEffects(nullptr, nullptr, nullptr, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT);
+ HandleEffects(nullptr, nullptr, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_HIT);
}
// process items
@@ -3852,10 +3800,9 @@ void Spell::update(uint32 difftime)
// check if the player caster has moved before the spell finished
// with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(EFFECT_0);
if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
m_caster->ToPlayer()->isMoving() && (m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement)) &&
- ((effect && effect->Effect != SPELL_EFFECT_STUCK) || !m_caster->ToPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) &&
+ (!m_spellInfo->HasEffect(SPELL_EFFECT_STUCK) || !m_caster->ToPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) &&
!m_caster->ToPlayer()->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
{
// don't cancel for melee, autorepeat, triggered and instant spells
@@ -4091,9 +4038,15 @@ inline void FillSpellCastFailedArgs(T& packet, ObjectGuid castId, SpellInfo cons
else
{
uint32 item = 0;
- for (SpellEffectInfo const* effect : spellInfo->GetEffects())
- if (effect->ItemType)
- item = effect->ItemType;
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
+ {
+ if (uint32 itemType = spellEffectInfo.ItemType)
+ {
+ item = itemType;
+ break;
+ }
+ }
+
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
if (proto && proto->GetItemLimitCategory())
packet.FailedArg1 = proto->GetItemLimitCategory();
@@ -4755,9 +4708,9 @@ void Spell::SendChannelStart(uint32 duration)
explicitTargetEffectMask = explicitTargetItr->EffectMask;
}
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
- if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA && (explicitTargetEffectMask & (1u << effect->EffectIndex)))
- channelAuraMask |= 1 << effect->EffectIndex;
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_APPLY_AURA) && (explicitTargetEffectMask & (1u << spellEffectInfo.EffectIndex)))
+ channelAuraMask |= 1 << spellEffectInfo.EffectIndex;
for (TargetInfo const& target : m_UniqueTargetInfo)
{
@@ -5093,30 +5046,22 @@ void Spell::HandleThreatSpells()
TC_LOG_DEBUG("spells", "Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, IsPositive() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
}
-void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode)
+void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, SpellEffectInfo const& spellEffectInfo, SpellEffectHandleMode mode)
{
effectHandleMode = mode;
unitTarget = pUnitTarget;
itemTarget = pItemTarget;
gameObjTarget = pGOTarget;
- destTarget = &m_destTargets[i]._position;
+ destTarget = &m_destTargets[spellEffectInfo.EffectIndex]._position;
+ effectInfo = &spellEffectInfo;
unitCaster = m_originalCaster ? m_originalCaster : m_caster->ToUnit();
- effectInfo = m_spellInfo->GetEffect(i);
- if (!effectInfo)
- {
- TC_LOG_ERROR("spells", "Spell: %u HandleEffects at EffectIndex: %u missing effect", m_spellInfo->Id, i);
- return;
- }
- uint32 effect = effectInfo->Effect;
-
- damage = CalculateDamage(i, unitTarget, &variance);
+ damage = CalculateDamage(spellEffectInfo, unitTarget, &variance);
- SpellEffIndex effIndex = static_cast<SpellEffIndex>(i);
- bool preventDefault = CallScriptEffectHandlers(effIndex, mode);
+ bool preventDefault = CallScriptEffectHandlers(spellEffectInfo.EffectIndex, mode);
if (!preventDefault)
- (this->*SpellEffectHandlers[effect].Value)();
+ (this->*SpellEffectHandlers[spellEffectInfo.Effect].Value)();
}
/*static*/ Spell const* Spell::ExtractSpellFromEvent(BasicEvent* event)
@@ -5278,8 +5223,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (unitCaster->GetTypeId() == TYPEID_PLAYER && unitCaster->ToPlayer()->isMoving() && (!unitCaster->IsCharmed() || !unitCaster->GetCharmerGUID().IsCreature()) && !unitCaster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
{
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(EFFECT_0);
- if ((!unitCaster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || (effect && effect->Effect != SPELL_EFFECT_STUCK)) &&
+ if ((!unitCaster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || !m_spellInfo->HasEffect(SPELL_EFFECT_STUCK)) &&
(IsAutoRepeat() || m_spellInfo->HasAuraInterruptFlag(SpellAuraInterruptFlags::Standing)))
return SPELL_FAILED_MOVING;
}
@@ -5386,9 +5330,9 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
// check pet presence
if (Unit* unitCaster = m_caster->ToUnit())
{
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (effect && effect->TargetA.GetTarget() == TARGET_UNIT_PET)
+ if (spellEffectInfo.TargetA.GetTarget() == TARGET_UNIT_PET)
{
if (!unitCaster->GetGuardianPet())
{
@@ -5485,12 +5429,10 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (castResult != SPELL_CAST_OK)
return castResult;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
// for effects of spells that have only one target
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_DUMMY:
{
@@ -5514,14 +5456,14 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
}
case SPELL_EFFECT_LEARN_SPELL:
{
- if (effect->TargetA.GetTarget() != TARGET_UNIT_PET)
+ if (spellEffectInfo.TargetA.GetTarget() != TARGET_UNIT_PET)
break;
Pet* pet = m_caster->ToPlayer()->GetPet();
if (!pet)
return SPELL_FAILED_NO_PET;
- SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE);
+ SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE);
if (!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
@@ -5551,7 +5493,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (!pet || pet->GetOwner() != m_caster)
return SPELL_FAILED_BAD_TARGETS;
- SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE);
+ SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE);
if (!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
@@ -5570,7 +5512,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (!caster->HasSpell(m_misc.SpellId))
return SPELL_FAILED_NOT_KNOWN;
- if (uint32 glyphId = effect->MiscValue)
+ if (uint32 glyphId = spellEffectInfo.MiscValue)
{
GlyphPropertiesEntry const* glyphProperties = sGlyphPropertiesStore.LookupEntry(glyphId);
if (!glyphProperties)
@@ -5713,13 +5655,13 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
}
case SPELL_EFFECT_OPEN_LOCK:
{
- if (effect->TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
- effect->TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
+ if (spellEffectInfo.TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
+ spellEffectInfo.TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
break;
if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
// we need a go target in case of TARGET_GAMEOBJECT_TARGET
- || (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
+ || (spellEffectInfo.TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
return SPELL_FAILED_BAD_TARGETS;
Item* pTempItem = nullptr;
@@ -5732,7 +5674,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
pTempItem = m_caster->ToPlayer()->GetItemByGuid(m_targets.GetItemTargetGUID());
// we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
- if (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
+ if (spellEffectInfo.TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
!m_targets.GetGOTarget() &&
(!pTempItem || !pTempItem->GetTemplate()->GetLockID() || !pTempItem->IsLocked()))
return SPELL_FAILED_BAD_TARGETS;
@@ -5759,7 +5701,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
int32 skillValue = 0;
// check lock compatibility
- SpellCastResult res = CanOpenLock(*effect, lockId, skillId, reqSkillValue, skillValue);
+ SpellCastResult res = CanOpenLock(spellEffectInfo, lockId, skillId, reqSkillValue, skillValue);
if (res != SPELL_CAST_OK)
return res;
break;
@@ -5782,7 +5724,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (!unitCaster)
break;
- SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(effect->MiscValueB);
+ SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(spellEffectInfo.MiscValueB);
if (!SummonProperties)
break;
@@ -5982,10 +5924,10 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (!artifact)
return SPELL_FAILED_NO_ARTIFACT_EQUIPPED;
- if (effect->Effect == SPELL_EFFECT_GIVE_ARTIFACT_POWER)
+ if (spellEffectInfo.Effect == SPELL_EFFECT_GIVE_ARTIFACT_POWER)
{
ArtifactEntry const* artifactEntry = sArtifactStore.LookupEntry(artifact->GetTemplate()->GetArtifactID());
- if (!artifactEntry || artifactEntry->ArtifactCategoryID != effect->MiscValue)
+ if (!artifactEntry || artifactEntry->ArtifactCategoryID != spellEffectInfo.MiscValue)
return SPELL_FAILED_WRONG_ARTIFACT_EQUIPPED;
}
break;
@@ -5995,11 +5937,9 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
}
}
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
- switch (effect->ApplyAuraName)
+ switch (spellEffectInfo.ApplyAuraName)
{
case SPELL_AURA_MOD_POSSESS_PET:
{
@@ -6025,8 +5965,8 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (!unitCaster->GetCharmerGUID().IsEmpty())
return SPELL_FAILED_CHARMED;
- if (effect->ApplyAuraName == SPELL_AURA_MOD_CHARM
- || effect->ApplyAuraName == SPELL_AURA_MOD_POSSESS)
+ if (spellEffectInfo.ApplyAuraName == SPELL_AURA_MOD_CHARM
+ || spellEffectInfo.ApplyAuraName == SPELL_AURA_MOD_POSSESS)
{
if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET) && !unitCaster->GetPetGUID().IsEmpty())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -6049,7 +5989,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (target->GetOwner() && target->GetOwner()->GetTypeId() == TYPEID_PLAYER)
return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED;
- int32 value = CalculateDamage(effect->EffectIndex, target);
+ int32 value = CalculateDamage(spellEffectInfo, target);
if (value && int32(target->GetLevelForTarget(m_caster)) > value)
return SPELL_FAILED_HIGHLEVEL;
}
@@ -6106,7 +6046,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
}
case SPELL_AURA_PERIODIC_MANA_LEECH:
{
- if (effect->IsTargetingArea())
+ if (spellEffectInfo.IsTargetingArea())
break;
if (!m_targets.GetUnitTarget())
@@ -6243,7 +6183,7 @@ SpellCastResult Spell::CheckCasterAuras(uint32* param1) const
// fill up aura mechanic info to send client proper error message
if (param1)
{
- *param1 = aurEff->GetSpellEffectInfo()->Mechanic;
+ *param1 = aurEff->GetSpellEffectInfo().Mechanic;
if (!*param1)
*param1 = aurEff->GetSpellInfo()->Mechanic;
}
@@ -6336,7 +6276,7 @@ bool Spell::CheckSpellCancelsAuraEffect(AuraType auraType, uint32* param1) const
if (param1)
{
- *param1 = aurEff->GetSpellEffectInfo()->Mechanic;
+ *param1 = aurEff->GetSpellEffectInfo().Mechanic;
if (!*param1)
*param1 = aurEff->GetSpellInfo()->Mechanic;
}
@@ -6418,10 +6358,10 @@ SpellCastResult Spell::CheckArenaAndRatedBattlegroundCastRules()
return SPELL_CAST_OK;
}
-int32 Spell::CalculateDamage(uint8 effIndex, Unit const* target, float* var /*= nullptr*/) const
+int32 Spell::CalculateDamage(SpellEffectInfo const& spellEffectInfo, Unit const* target, float* var /*= nullptr*/) const
{
- bool needRecalculateBasePoints = !(m_spellValue->CustomBasePointsMask & (1 << effIndex));
- return m_caster->CalculateSpellDamage(target, m_spellInfo, effIndex, needRecalculateBasePoints ? nullptr : &m_spellValue->EffectBasePoints[effIndex], var, m_castItemEntry, m_castItemLevel);
+ bool needRecalculateBasePoints = !(m_spellValue->CustomBasePointsMask & (1 << spellEffectInfo.EffectIndex));
+ return m_caster->CalculateSpellDamage(target, spellEffectInfo, needRecalculateBasePoints ? nullptr : &m_spellValue->EffectBasePoints[spellEffectInfo.EffectIndex], var, m_castItemEntry, m_castItemLevel);
}
bool Spell::CanAutoCast(Unit* target)
@@ -6432,15 +6372,12 @@ bool Spell::CanAutoCast(Unit* target)
ObjectGuid targetguid = target->GetGUID();
// check if target already has the same or a more powerful aura
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
+ if (!spellEffectInfo.IsAura())
continue;
- if (!effect->IsAura())
- continue;
-
- AuraType const& auraType = AuraType(effect->ApplyAuraName);
+ AuraType const& auraType = spellEffectInfo.ApplyAuraName;
Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
{
@@ -6457,7 +6394,7 @@ bool Spell::CanAutoCast(Unit* target)
break;
case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
case SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST:
- if (abs(effect->BasePoints) <= abs((*auraIt)->GetAmount()))
+ if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
return false;
break;
case SPELL_GROUP_STACK_RULE_DEFAULT:
@@ -6669,13 +6606,13 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
{
// such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
SpellCastResult failReason = SPELL_CAST_OK;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
// skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
- if (!effect || effect->TargetA.GetTarget() == TARGET_UNIT_PET)
+ if (spellEffectInfo.TargetA.GetTarget() == TARGET_UNIT_PET)
continue;
- if (effect->Effect == SPELL_EFFECT_HEAL)
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_HEAL))
{
if (m_targets.GetUnitTarget()->IsFullHealth())
{
@@ -6690,15 +6627,15 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
}
// Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
- if (effect->Effect == SPELL_EFFECT_ENERGIZE)
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_ENERGIZE))
{
- if (effect->MiscValue < 0 || effect->MiscValue >= int8(MAX_POWERS))
+ if (spellEffectInfo.MiscValue < 0 || spellEffectInfo.MiscValue >= int8(MAX_POWERS))
{
failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
continue;
}
- Powers power = Powers(effect->MiscValue);
+ Powers power = Powers(spellEffectInfo.MiscValue);
if (m_targets.GetUnitTarget()->GetPower(power) == m_targets.GetUnitTarget()->GetMaxPower(power))
{
failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
@@ -6825,29 +6762,26 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
}
// special checks for spell effects
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
-
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_CREATE_LOOT:
{
// m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
- if (target->GetTypeId() == TYPEID_PLAYER && !IsTriggered() && effect->ItemType)
+ if (target->GetTypeId() == TYPEID_PLAYER && !IsTriggered() && spellEffectInfo.ItemType)
{
ItemPosCountVec dest;
- InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, effect->ItemType, 1);
+ InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellEffectInfo.ItemType, 1);
if (msg != EQUIP_ERR_OK)
{
- ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(effect->ItemType);
+ ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(spellEffectInfo.ItemType);
/// @todo Needs review
if (itemTemplate && !(itemTemplate->GetItemLimitCategory()))
{
- player->SendEquipError(msg, nullptr, nullptr, effect->ItemType);
+ player->SendEquipError(msg, nullptr, nullptr, spellEffectInfo.ItemType);
return SPELL_FAILED_DONT_REPORT;
}
else
@@ -6855,13 +6789,13 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
// Conjure Food/Water/Refreshment spells
if (m_spellInfo->SpellFamilyName != SPELLFAMILY_MAGE || (!(m_spellInfo->SpellFamilyFlags[0] & 0x40000000)))
return SPELL_FAILED_TOO_MANY_OF_ITEM;
- else if (!(target->ToPlayer()->HasItemCount(effect->ItemType)))
+ else if (!(target->ToPlayer()->HasItemCount(spellEffectInfo.ItemType)))
{
- player->SendEquipError(msg, nullptr, nullptr, effect->ItemType);
+ player->SendEquipError(msg, nullptr, nullptr, spellEffectInfo.ItemType);
return SPELL_FAILED_DONT_REPORT;
}
- else if (SpellEffectInfo const* efi = m_spellInfo->GetEffect(EFFECT_1))
- player->CastSpell(player, efi->CalcValue(), false); // move this to anywhere
+ else if (m_spellInfo->GetEffects().size() > EFFECT_1)
+ player->CastSpell(player, m_spellInfo->GetEffect(EFFECT_1).CalcValue(), false); // move this to anywhere
return SPELL_FAILED_DONT_REPORT;
}
}
@@ -6869,7 +6803,7 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
break;
}
case SPELL_EFFECT_ENCHANT_ITEM:
- if (effect->ItemType && m_targets.GetItemTarget()
+ if (spellEffectInfo.ItemType && m_targets.GetItemTarget()
&& (m_targets.GetItemTarget()->IsVellum()))
{
// cannot enchant vellum for other player
@@ -6879,10 +6813,10 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
if (m_CastItem && m_CastItem->GetTemplate()->GetFlags() & ITEM_FLAG_NO_REAGENT_COST)
return SPELL_FAILED_TOTEM_CATEGORY;
ItemPosCountVec dest;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, effect->ItemType, 1);
+ InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellEffectInfo.ItemType, 1);
if (msg != EQUIP_ERR_OK)
{
- player->SendEquipError(msg, nullptr, nullptr, effect->ItemType);
+ player->SendEquipError(msg, nullptr, nullptr, spellEffectInfo.ItemType);
return SPELL_FAILED_DONT_REPORT;
}
}
@@ -6907,7 +6841,7 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
}
}
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(effect->MiscValue);
+ SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(spellEffectInfo.MiscValue);
// do not allow adding usable enchantments to items that have use effect already
if (enchantEntry)
{
@@ -6952,7 +6886,7 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
// Not allow enchant in trade slot for some enchant type
if (item->GetOwner() != player)
{
- uint32 enchant_id = effect->MiscValue;
+ uint32 enchant_id = spellEffectInfo.MiscValue;
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
return SPELL_FAILED_ERROR;
@@ -7087,7 +7021,7 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 /
}
case SPELL_EFFECT_RECHARGE_ITEM:
{
- uint32 itemId = effect->ItemType;
+ uint32 itemId = spellEffectInfo.ItemType;
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
if (!proto)
@@ -7300,12 +7234,9 @@ bool Spell::UpdatePointers()
WorldObject* transport = nullptr;
// update effect destinations (in case of moved transport dest target)
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
-
- SpellDestination& dest = m_destTargets[effect->EffectIndex];
+ SpellDestination& dest = m_destTargets[spellEffectInfo.EffectIndex];
if (!dest._transportGUID)
continue;
@@ -7339,12 +7270,9 @@ Difficulty Spell::GetCastDifficulty() const
return m_caster->GetMap()->GetDifficultyID();
}
-bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, Position const* losPosition) const
+bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const& spellEffectInfo, Position const* losPosition) const
{
- if (!effect->IsEffect())
- return false;
-
- switch (effect->ApplyAuraName)
+ switch (spellEffectInfo.ApplyAuraName)
{
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CHARM:
@@ -7356,7 +7284,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect,
return false;
if (!target->GetCharmerGUID().IsEmpty())
return false;
- if (int32 value = CalculateDamage(effect->EffectIndex, target))
+ if (int32 value = CalculateDamage(spellEffectInfo, target))
if ((int32)target->GetLevelForTarget(m_caster) > value)
return false;
break;
@@ -7374,7 +7302,7 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect,
/// @todo shit below shouldn't be here, but it's temporary
//Check targets for LOS visibility
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_SKIN_PLAYER_CORPSE:
{
@@ -7422,12 +7350,9 @@ bool Spell::CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect,
return true;
}
-bool Spell::CheckEffectTarget(GameObject const* target, SpellEffectInfo const* effect) const
+bool Spell::CheckEffectTarget(GameObject const* target, SpellEffectInfo const& spellEffectInfo) const
{
- if (!effect->IsEffect())
- return false;
-
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_GAMEOBJECT_DAMAGE:
case SPELL_EFFECT_GAMEOBJECT_REPAIR:
@@ -7442,11 +7367,8 @@ bool Spell::CheckEffectTarget(GameObject const* target, SpellEffectInfo const* e
return true;
}
-bool Spell::CheckEffectTarget(Item const* /*target*/, SpellEffectInfo const* effect) const
+bool Spell::CheckEffectTarget(Item const* /*target*/, SpellEffectInfo const& /*spellEffectInfo*/) const
{
- if (!effect->IsEffect())
- return false;
-
return true;
}
@@ -7637,40 +7559,37 @@ bool Spell::IsValidDeadOrAliveTarget(Unit const* target) const
void Spell::HandleLaunchPhase()
{
// handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
// don't do anything for empty effect
- if (!effect || !effect->IsEffect())
+ if (!spellEffectInfo.IsEffect())
continue;
- HandleEffects(nullptr, nullptr, nullptr, effect->EffectIndex, SPELL_EFFECT_HANDLE_LAUNCH);
+ HandleEffects(nullptr, nullptr, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_LAUNCH);
}
PrepareTargetProcessing();
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
-
float multiplier = 1.0f;
- if (m_applyMultiplierMask & (1 << effect->EffectIndex))
- multiplier = effect->CalcDamageMultiplier(m_originalCaster, this);
+ if (m_applyMultiplierMask & (1 << spellEffectInfo.EffectIndex))
+ multiplier = spellEffectInfo.CalcDamageMultiplier(m_originalCaster, this);
for (TargetInfo& target : m_UniqueTargetInfo)
{
uint32 mask = target.EffectMask;
- if (!(mask & (1 << effect->EffectIndex)))
+ if (!(mask & (1 << spellEffectInfo.EffectIndex)))
continue;
- DoEffectOnLaunchTarget(target, multiplier, effect);
+ DoEffectOnLaunchTarget(target, multiplier, spellEffectInfo);
}
}
FinishTargetProcessing();
}
-void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, SpellEffectInfo const* effect)
+void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, SpellEffectInfo const& spellEffectInfo)
{
Unit* unit = nullptr;
// In case spell hit target, do all effect on that target
@@ -7690,30 +7609,30 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, Spe
m_damage = 0;
m_healing = 0;
- HandleEffects(unit, nullptr, nullptr, effect->EffectIndex, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
+ HandleEffects(unit, nullptr, nullptr, spellEffectInfo, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
if (m_originalCaster && m_damage > 0)
{
- if (effect->IsTargetingArea() || effect->IsAreaAuraEffect() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ if (spellEffectInfo.IsTargetingArea() || spellEffectInfo.IsAreaAuraEffect() || spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
{
m_damage = unit->CalculateAOEAvoidance(m_damage, m_spellInfo->SchoolMask, m_originalCaster->GetGUID());
if (m_originalCaster->GetTypeId() == TYPEID_PLAYER)
{
// cap damage of player AOE
- int64 targetAmount = GetUnitTargetCountForEffect(SpellEffIndex(effect->EffectIndex));
+ int64 targetAmount = GetUnitTargetCountForEffect(spellEffectInfo.EffectIndex);
if (targetAmount > 20)
m_damage = m_damage * 20 / targetAmount;
}
}
}
- if (m_applyMultiplierMask & (1 << effect->EffectIndex))
+ if (m_applyMultiplierMask & (1 << spellEffectInfo.EffectIndex))
{
- m_damage = int32(m_damage * m_damageMultipliers[effect->EffectIndex]);
- m_healing = int32(m_healing * m_damageMultipliers[effect->EffectIndex]);
+ m_damage = int32(m_damage * m_damageMultipliers[spellEffectInfo.EffectIndex]);
+ m_healing = int32(m_healing * m_damageMultipliers[spellEffectInfo.EffectIndex]);
- m_damageMultipliers[effect->EffectIndex] *= multiplier;
+ m_damageMultipliers[spellEffectInfo.EffectIndex] *= multiplier;
}
targetInfo.Damage += m_damage;
@@ -8091,9 +8010,9 @@ bool Spell::CanExecuteTriggersOnHit(uint32 effMask, SpellInfo const* triggeredBy
{
bool only_on_caster = (triggeredByAura && (triggeredByAura->HasAttribute(SPELL_ATTR4_PROC_ONLY_ON_CASTER)));
// If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a cast spell with TARGET_UNIT_CASTER
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (effect && ((effMask & (1 << effect->EffectIndex)) && (!only_on_caster || (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER))))
+ if ((effMask & (1 << spellEffectInfo.EffectIndex)) && (!only_on_caster || (spellEffectInfo.TargetA.GetTarget() == TARGET_UNIT_CASTER)))
return true;
}
return false;
@@ -8114,13 +8033,13 @@ void Spell::PrepareTriggersExecutedOnHit()
if (!aurEff->IsAffectingSpell(m_spellInfo))
continue;
- if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(aurEff->GetSpellEffectInfo()->TriggerSpell, GetCastDifficulty()))
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(aurEff->GetSpellEffectInfo().TriggerSpell, GetCastDifficulty()))
{
// calculate the chance using spell base amount, because aura amount is not updated on combo-points change
// this possibly needs fixing
int32 auraBaseAmount = aurEff->GetBaseAmount();
// proc chance is stored in effect amount
- int32 chance = unitCaster->CalculateSpellDamage(nullptr, aurEff->GetSpellInfo(), aurEff->GetEffIndex(), &auraBaseAmount);
+ int32 chance = unitCaster->CalculateSpellDamage(nullptr, aurEff->GetSpellEffectInfo(), &auraBaseAmount);
chance *= aurEff->GetBase()->GetStackAmount();
// build trigger and add to the list
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 37d6d68a187..b12fa5fd929 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -515,21 +515,21 @@ class TC_GAME_API Spell
void SelectExplicitTargets();
void SelectSpellTargets();
- void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask);
- void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
- void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
- void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
- void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
- void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
- void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
- void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
- void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
- void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
- void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask);
- void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
- void SelectImplicitLineTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
-
- void SelectEffectTypeImplicitTargets(uint32 effIndex);
+ void SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask);
+ void SelectImplicitChannelTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitNearbyTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
+ void SelectImplicitConeTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
+ void SelectImplicitAreaTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
+ void SelectImplicitCasterDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitTargetDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitDestDestTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitCasterObjectTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitTargetObjectTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitChainTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask);
+ void SelectImplicitTrajTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitLineTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
+
+ void SelectEffectTypeImplicitTargets(SpellEffectInfo const& spellEffectInfo);
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionContainer* condList);
template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, WorldObject* referer, Position const* pos, float radius);
@@ -577,7 +577,7 @@ class TC_GAME_API Spell
bool CheckSpellCancelsConfuse(uint32* param1) const;
bool CheckSpellCancelsNoActions(uint32* param1) const;
- int32 CalculateDamage(uint8 effIndex, Unit const* target, float* var = nullptr) const;
+ int32 CalculateDamage(SpellEffectInfo const& spellEffectInfo, Unit const* target, float* var = nullptr) const;
void Delayed();
void DelayedChannel();
@@ -586,9 +586,9 @@ class TC_GAME_API Spell
void DoCreateItem(uint32 itemId, ItemContext context = ItemContext::NONE, std::vector<int32> const& bonusListIDs = std::vector<int32>());
- bool CheckEffectTarget(Unit const* target, SpellEffectInfo const* effect, Position const* losPosition) const;
- bool CheckEffectTarget(GameObject const* target, SpellEffectInfo const* effect) const;
- bool CheckEffectTarget(Item const* target, SpellEffectInfo const* effect) const;
+ bool CheckEffectTarget(Unit const* target, SpellEffectInfo const& spellEffectInfo, Position const* losPosition) const;
+ bool CheckEffectTarget(GameObject const* target, SpellEffectInfo const& spellEffectInfo) const;
+ bool CheckEffectTarget(Item const* target, SpellEffectInfo const& spellEffectInfo) const;
bool CanAutoCast(Unit* target);
void CheckSrc();
void CheckDst();
@@ -626,7 +626,7 @@ class TC_GAME_API Spell
void SendChannelStart(uint32 duration);
void SendResurrectRequest(Player* target);
- void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode);
+ void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, SpellEffectInfo const& spellEffectInfo, SpellEffectHandleMode mode);
void HandleThreatSpells();
static Spell const* ExtractSpellFromEvent(BasicEvent* event);
@@ -818,7 +818,7 @@ class TC_GAME_API Spell
struct TargetInfoBase
{
virtual void PreprocessTarget(Spell* /*spell*/) { }
- virtual void DoTargetSpellHit(Spell* spell, uint8 effIndex) = 0;
+ virtual void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) = 0;
virtual void DoDamageAndTriggers(Spell* /*spell*/) { }
uint32 EffectMask = 0;
@@ -831,7 +831,7 @@ class TC_GAME_API Spell
struct TargetInfo : public TargetInfoBase
{
void PreprocessTarget(Spell* spell) override;
- void DoTargetSpellHit(Spell* spell, uint8 effIndex) override;
+ void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) override;
void DoDamageAndTriggers(Spell* spell) override;
ObjectGuid TargetGUID;
@@ -860,7 +860,7 @@ class TC_GAME_API Spell
struct GOTargetInfo : public TargetInfoBase
{
- void DoTargetSpellHit(Spell* spell, uint8 effIndex) override;
+ void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) override;
ObjectGuid TargetGUID;
uint64 TimeDelay = 0ULL;
@@ -869,7 +869,7 @@ class TC_GAME_API Spell
struct ItemTargetInfo : public TargetInfoBase
{
- void DoTargetSpellHit(Spell* spell, uint8 effIndex) override;
+ void DoTargetSpellHit(Spell* spell, SpellEffectInfo const& spellEffectInfo) override;
Item* TargetItem = nullptr;
};
@@ -886,13 +886,13 @@ class TC_GAME_API Spell
void AddDestTarget(SpellDestination const& dest, uint32 effIndex);
SpellMissInfo PreprocessSpellHit(Unit* unit, TargetInfo& targetInfo);
- void DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& targetInfo);
+ void DoSpellEffectHit(Unit* unit, SpellEffectInfo const& spellEffectInfo, TargetInfo& targetInfo);
void DoTriggersOnSpellHit(Unit* unit, uint32 effMask);
bool UpdateChanneledTargetList();
bool IsValidDeadOrAliveTarget(Unit const* target) const;
void HandleLaunchPhase();
- void DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, SpellEffectInfo const* effect);
+ void DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, SpellEffectInfo const& spellEffectInfo);
void PrepareTargetProcessing();
void FinishTargetProcessing();
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 89088dc35d2..f881bf52e15 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -527,7 +527,7 @@ void Spell::EffectSchoolDMG()
if (unitCaster && apply_direct_bonus)
{
- uint32 bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effectInfo);
+ uint32 bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, *effectInfo);
damage = bonus + uint32(bonus * variance);
damage = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
}
@@ -1061,7 +1061,7 @@ void Spell::EffectPowerDrain()
// add spell damage bonus
if (unitCaster)
{
- uint32 bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effectInfo);
+ uint32 bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, *effectInfo);
damage = bonus + uint32(bonus * variance);
damage = unitTarget->SpellDamageBonusTaken(unitCaster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
}
@@ -1183,10 +1183,10 @@ void Spell::EffectHeal()
}
// Death Pact - return pct of max health to caster
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000)
- addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(unitCaster->CountPctFromMaxHealth(damage)), HEAL, effectInfo);
+ addhealth = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(unitCaster->CountPctFromMaxHealth(damage)), HEAL, *effectInfo);
else
{
- uint32 bonus = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effectInfo);
+ uint32 bonus = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, *effectInfo);
addhealth = bonus + uint32(bonus * variance);
}
@@ -1210,7 +1210,7 @@ void Spell::EffectHealPct()
uint32 heal = unitTarget->CountPctFromMaxHealth(damage);
if (unitCaster)
{
- heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, effectInfo);
+ heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, *effectInfo);
heal = unitTarget->SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, HEAL);
}
@@ -1227,7 +1227,7 @@ void Spell::EffectHealMechanical()
uint32 heal = damage;
if (unitCaster)
- heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, effectInfo);
+ heal = unitCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, heal, HEAL, *effectInfo);
heal += uint32(heal * variance);
if (unitCaster)
@@ -1246,7 +1246,7 @@ void Spell::EffectHealthLeech()
uint32 bonus = 0;
if (unitCaster)
- bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effectInfo);
+ bonus = unitCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, *effectInfo);
damage = bonus + uint32(bonus * variance);
@@ -1263,7 +1263,7 @@ void Spell::EffectHealthLeech()
if (unitCaster && unitCaster->IsAlive())
{
- healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL, effectInfo);
+ healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL, *effectInfo);
healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL);
HealInfo healInfo(unitCaster, unitCaster, healthGain, m_spellInfo, m_spellSchoolMask);
@@ -1445,10 +1445,9 @@ void Spell::EffectPersistentAA()
return;
// only handle at last effect
- for (uint8 i = effectInfo->EffectIndex + 1; i < MAX_SPELL_EFFECTS; ++i)
- if (SpellEffectInfo const* otherEffect = m_spellInfo->GetEffect(i))
- if (otherEffect && otherEffect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
- return;
+ for (size_t i = effectInfo->EffectIndex + 1; i < m_spellInfo->GetEffects().size(); ++i)
+ if (m_spellInfo->GetEffect(SpellEffIndex(i)).IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ return;
ASSERT(!_dynObjAura);
@@ -2765,17 +2764,15 @@ void Spell::EffectWeaponDmg()
// and handle all effects at once
for (size_t j = effectInfo->EffectIndex + 1; j < m_spellInfo->GetEffects().size(); ++j)
{
- SpellEffectInfo const* effect = m_spellInfo->GetEffect(j);
- if (!effect)
- continue;
- switch (effect->Effect)
+ switch (m_spellInfo->GetEffect(SpellEffIndex(j)).Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
return; // we must calculate only at last weapon effect
- break;
+ default:
+ break;
}
}
@@ -2798,22 +2795,20 @@ void Spell::EffectWeaponDmg()
bool normalized = false;
float weaponDamagePercentMod = 1.0f;
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
- fixed_bonus += CalculateDamage(effect->EffectIndex, unitTarget);
+ fixed_bonus += CalculateDamage(spellEffectInfo, unitTarget);
break;
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
- fixed_bonus += CalculateDamage(effect->EffectIndex, unitTarget);
+ fixed_bonus += CalculateDamage(spellEffectInfo, unitTarget);
normalized = true;
break;
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
- ApplyPct(weaponDamagePercentMod, CalculateDamage(effect->EffectIndex, unitTarget));
+ ApplyPct(weaponDamagePercentMod, CalculateDamage(spellEffectInfo, unitTarget));
break;
default:
break; // not weapon damage effect, just skip
@@ -2844,13 +2839,11 @@ void Spell::EffectWeaponDmg()
int32 weaponDamage = unitCaster->CalculateDamage(m_attackType, normalized, addPctMods);
// Sequence is important
- for (SpellEffectInfo const* effect : m_spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
{
- if (!effect)
- continue;
// We assume that a spell have at most one fixed_bonus
// and at most one weaponDamagePercentMod
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
@@ -3276,8 +3269,8 @@ void Spell::EffectScriptEffect()
return;
// Effects for 58418 and 58420 are all DIFFICULTY_NONE so always valid
- uint32 spellID = m_spellInfo->GetEffect(EFFECT_0)->CalcValue();
- uint32 questID = m_spellInfo->GetEffect(EFFECT_1)->CalcValue();
+ uint32 spellID = m_spellInfo->GetEffect(EFFECT_0).CalcValue();
+ uint32 questID = m_spellInfo->GetEffect(EFFECT_1).CalcValue();
if (unitTarget->ToPlayer()->GetQuestStatus(questID) == QUEST_STATUS_COMPLETE)
unitTarget->CastSpell(unitTarget, spellID, true);
@@ -3312,7 +3305,7 @@ void Spell::EffectScriptEffect()
{
/// @todo a hack, range = 11, should after some time cast, otherwise too far
unitCaster->CastSpell(parent, 62496, true);
- unitTarget->CastSpell(parent, m_spellInfo->GetEffect(EFFECT_0)->CalcValue()); // DIFFICULTY_NONE, so effect always valid
+ unitTarget->CastSpell(parent, damage); // DIFFICULTY_NONE, so effect always valid
}
}
}
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index e343eba170d..db87c917797 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -17,6 +17,7 @@
#include "SpellInfo.h"
#include "Battleground.h"
+#include "Containers.h"
#include "Corpse.h"
#include "DB2Stores.h"
#include "GameTables.h"
@@ -377,9 +378,9 @@ SpellEffectInfo::SpellEffectInfo(SpellInfo const* spellInfo, SpellEffectEntry co
ASSERT(spellInfo);
_spellInfo = spellInfo;
- EffectIndex = _effect.EffectIndex;
- Effect = _effect.Effect;
- ApplyAuraName = _effect.EffectAura;
+ EffectIndex = SpellEffIndex(_effect.EffectIndex);
+ Effect = SpellEffectName(_effect.Effect);
+ ApplyAuraName = AuraType(_effect.EffectAura);
ApplyAuraPeriod = _effect.EffectAuraPeriod;
BasePoints = _effect.EffectBasePoints;
RealPointsPerLevel = _effect.EffectRealPointsPerLevel;
@@ -1088,11 +1089,9 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S
if (!spellEffect)
continue;
- if (uint32(spellEffect->EffectIndex) >= _effects.size())
- _effects.resize(spellEffect->EffectIndex + 1);
-
- _effects[spellEffect->EffectIndex] = new SpellEffectInfo(this, *spellEffect);
+ Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect->EffectIndex, SpellEffectInfo(this)) = SpellEffectInfo(this, *spellEffect);
}
+
_effects.shrink_to_fit();
SpellName = &spellName->Name;
@@ -1272,27 +1271,14 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, s
_effects.reserve(32);
for (SpellEffectEntry const& spellEffect : effects)
- {
- if (uint32(spellEffect.EffectIndex) >= _effects.size())
- _effects.resize(spellEffect.EffectIndex + 1);
+ Trinity::Containers::EnsureWritableVectorIndex(_effects, spellEffect.EffectIndex, SpellEffectInfo(this)) = SpellEffectInfo(this, spellEffect);
- _effects[spellEffect.EffectIndex] = new SpellEffectInfo(this, spellEffect);
- }
_effects.shrink_to_fit();
}
SpellInfo::~SpellInfo()
{
_UnloadImplicitTargetConditionLists();
- _UnloadSpellEffects();
-}
-
-void SpellInfo::_UnloadSpellEffects()
-{
- for (SpellEffectInfo const* effect : _effects)
- delete effect;
-
- _effects.clear();
}
uint32 SpellInfo::GetCategory() const
@@ -1302,8 +1288,8 @@ uint32 SpellInfo::GetCategory() const
bool SpellInfo::HasEffect(SpellEffectName effect) const
{
- for (SpellEffectInfo const* eff : _effects)
- if (eff && eff->IsEffect(effect))
+ for (SpellEffectInfo const& eff : GetEffects())
+ if (eff.IsEffect(effect))
return true;
return false;
@@ -1311,8 +1297,8 @@ bool SpellInfo::HasEffect(SpellEffectName effect) const
bool SpellInfo::HasAura(AuraType aura) const
{
- for (SpellEffectInfo const* effect : _effects)
- if (effect && effect->IsAura(aura))
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (effect.IsAura(aura))
return true;
return false;
@@ -1320,8 +1306,8 @@ bool SpellInfo::HasAura(AuraType aura) const
bool SpellInfo::HasAreaAuraEffect() const
{
- for (SpellEffectInfo const* effect : _effects)
- if (effect && effect->IsAreaAuraEffect())
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (effect.IsAreaAuraEffect())
return true;
return false;
@@ -1329,24 +1315,24 @@ bool SpellInfo::HasAreaAuraEffect() const
bool SpellInfo::HasOnlyDamageEffects() const
{
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect)
- continue;
-
- switch (effect->Effect)
+ if (effect.IsEffect())
{
- case SPELL_EFFECT_WEAPON_DAMAGE:
- case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
- case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
- case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
- case SPELL_EFFECT_SCHOOL_DAMAGE:
- case SPELL_EFFECT_ENVIRONMENTAL_DAMAGE:
- case SPELL_EFFECT_HEALTH_LEECH:
- case SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT:
- continue;
- default:
- return false;
+ switch (effect.Effect)
+ {
+ case SPELL_EFFECT_WEAPON_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
+ case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
+ case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_ENVIRONMENTAL_DAMAGE:
+ case SPELL_EFFECT_HEALTH_LEECH:
+ case SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT:
+ continue;
+ default:
+ return false;
+ }
}
}
@@ -1355,8 +1341,8 @@ bool SpellInfo::HasOnlyDamageEffects() const
bool SpellInfo::HasTargetType(::Targets target) const
{
- for (SpellEffectInfo const* effect : _effects)
- if (effect && (effect->TargetA.GetTarget() == target || effect->TargetB.GetTarget() == target))
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (effect.TargetA.GetTarget() == target || effect.TargetB.GetTarget() == target)
return true;
return false;
@@ -1381,11 +1367,12 @@ bool SpellInfo::HasAnyAuraInterruptFlag() const
bool SpellInfo::IsExplicitDiscovery() const
{
- SpellEffectInfo const* effect0 = GetEffect(EFFECT_0);
- SpellEffectInfo const* effect1 = GetEffect(EFFECT_1);
+ if (GetEffects().size() < 2)
+ return false;
- return ((effect0 && (effect0->Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM || effect0->Effect == SPELL_EFFECT_CREATE_LOOT))
- && effect1 && effect1->Effect == SPELL_EFFECT_SCRIPT_EFFECT)
+ return ((GetEffect(EFFECT_0).Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM
+ || GetEffect(EFFECT_0).Effect == SPELL_EFFECT_CREATE_LOOT)
+ && GetEffect(EFFECT_1).Effect == SPELL_EFFECT_SCRIPT_EFFECT)
|| Id == 64323;
}
@@ -1396,18 +1383,19 @@ bool SpellInfo::IsLootCrafting() const
bool SpellInfo::IsQuestTame() const
{
- SpellEffectInfo const* effect0 = GetEffect(EFFECT_0);
- SpellEffectInfo const* effect1 = GetEffect(EFFECT_1);
- return effect0 && effect1 && effect0->Effect == SPELL_EFFECT_THREAT && effect1->Effect == SPELL_EFFECT_APPLY_AURA && effect1->ApplyAuraName == SPELL_AURA_DUMMY;
+ if (GetEffects().size() < 2)
+ return false;
+
+ return GetEffect(EFFECT_0).Effect == SPELL_EFFECT_THREAT && GetEffect(EFFECT_1).Effect == SPELL_EFFECT_APPLY_AURA && GetEffect(EFFECT_1).ApplyAuraName == SPELL_AURA_DUMMY;
}
bool SpellInfo::IsProfession() const
{
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (effect && effect->Effect == SPELL_EFFECT_SKILL)
+ if (effect.Effect == SPELL_EFFECT_SKILL)
{
- uint32 skill = effect->MiscValue;
+ uint32 skill = effect.MiscValue;
if (IsProfessionSkill(skill))
return true;
@@ -1418,11 +1406,11 @@ bool SpellInfo::IsProfession() const
bool SpellInfo::IsPrimaryProfession() const
{
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (effect && effect->Effect == SPELL_EFFECT_SKILL)
+ if (effect.Effect == SPELL_EFFECT_SKILL)
{
- uint32 skill = effect->MiscValue;
+ uint32 skill = effect.MiscValue;
if (IsPrimaryProfessionSkill(skill))
return true;
@@ -1449,8 +1437,8 @@ bool SpellInfo::IsAbilityOfSkillType(uint32 skillType) const
bool SpellInfo::IsAffectingArea() const
{
- for (SpellEffectInfo const* effect : _effects)
- if (effect && effect->IsEffect() && (effect->IsTargetingArea() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect->IsAreaAuraEffect()))
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (effect.IsEffect() && (effect.IsTargetingArea() || effect.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect.IsAreaAuraEffect()))
return true;
return false;
@@ -1459,8 +1447,8 @@ bool SpellInfo::IsAffectingArea() const
// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
bool SpellInfo::IsTargetingArea() const
{
- for (SpellEffectInfo const* effect : _effects)
- if (effect && effect->IsEffect() && effect->IsTargetingArea())
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (effect.IsEffect() && effect.IsTargetingArea())
return true;
return false;
@@ -1477,12 +1465,12 @@ bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) con
return true;
/*
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (Effects[i].IsEffect())
+ if (effect.IsEffect())
{
- if (Effects[i].TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL
- || Effects[i].TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL)
+ if (effect.TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL
+ || effect.TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CHANNEL)
return true;
}
}
@@ -1491,15 +1479,12 @@ bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) con
if (triggeringSpell->IsChanneled())
{
uint32 mask = 0;
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect)
- continue;
-
- if (effect->TargetA.GetTarget() != TARGET_UNIT_CASTER && effect->TargetA.GetTarget() != TARGET_DEST_CASTER
- && effect->TargetB.GetTarget() != TARGET_UNIT_CASTER && effect->TargetB.GetTarget() != TARGET_DEST_CASTER)
+ if (effect.TargetA.GetTarget() != TARGET_UNIT_CASTER && effect.TargetA.GetTarget() != TARGET_DEST_CASTER
+ && effect.TargetB.GetTarget() != TARGET_UNIT_CASTER && effect.TargetB.GetTarget() != TARGET_DEST_CASTER)
{
- mask |= effect->GetProvidedTargetMask();
+ mask |= effect.GetProvidedTargetMask();
}
}
@@ -1530,22 +1515,19 @@ bool SpellInfo::IsStackableWithRanks() const
return false;
// All stance spells. if any better way, change it.
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect)
- continue;
-
switch (SpellFamilyName)
{
case SPELLFAMILY_PALADIN:
// Paladin aura Spell
- if (effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
+ if (effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
return false;
break;
case SPELLFAMILY_DRUID:
// Druid form Spell
- if (effect->Effect == SPELL_EFFECT_APPLY_AURA &&
- effect->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
+ if (effect.Effect == SPELL_EFFECT_APPLY_AURA &&
+ effect.ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
return false;
break;
}
@@ -1594,12 +1576,12 @@ bool SpellInfo::IsAllowingDeadTarget() const
if (HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD) || Targets & (TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_DEAD))
return true;
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect)
+ if (!effect.IsEffect())
continue;
- if (effect->TargetA.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE || effect->TargetB.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE)
+ if (effect.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE || effect.TargetB.GetObjectType() == TARGET_OBJECT_TYPE_CORPSE)
return true;
}
@@ -1608,12 +1590,9 @@ bool SpellInfo::IsAllowingDeadTarget() const
bool SpellInfo::IsGroupBuff() const
{
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect)
- continue;
-
- switch (effect->TargetA.GetCheckType())
+ switch (effect.TargetA.GetCheckType())
{
case TARGET_CHECK_PARTY:
case TARGET_CHECK_RAID:
@@ -1880,8 +1859,7 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const
// talents that learn spells can have stance requirements that need ignore
// (this requirement only for client-side stance show in talent description)
/* TODO: 6.x fix this in proper way (probably spell flags/attributes?)
- if (GetTalentSpellCost(Id) > 0 &&
- (Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL || Effects[1].Effect == SPELL_EFFECT_LEARN_SPELL || Effects[2].Effect == SPELL_EFFECT_LEARN_SPELL))
+ if (GetTalentSpellCost(Id) > 0 && HasEffect(SPELL_EFFECT_LEARN_SPELL))
return SPELL_CAST_OK;*/
//if (HasAttribute(SPELL_ATTR13_ACTIVATES_REQUIRED_SHAPESHIFT))
@@ -2063,16 +2041,16 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
// aura limitations
if (player)
{
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect || !effect->IsAura())
+ if (!effect.IsAura())
continue;
- switch (effect->ApplyAuraName)
+ switch (effect.ApplyAuraName)
{
case SPELL_AURA_MOD_SHAPESHIFT:
{
- if (SpellShapeshiftFormEntry const* spellShapeshiftForm = sSpellShapeshiftFormStore.LookupEntry(effect->MiscValue))
+ if (SpellShapeshiftFormEntry const* spellShapeshiftForm = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue))
if (uint32 mountType = spellShapeshiftForm->MountTypeID)
if (!player->GetMountCapability(mountType))
return SPELL_FAILED_NOT_HERE;
@@ -2080,13 +2058,15 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
}
case SPELL_AURA_MOUNTED:
{
- uint32 mountType = effect->MiscValueB;
+ uint32 mountType = effect.MiscValueB;
if (MountEntry const* mountEntry = sDB2Manager.GetMount(Id))
mountType = mountEntry->MountTypeID;
if (mountType && !player->GetMountCapability(mountType))
return SPELL_FAILED_NOT_HERE;
break;
}
+ default:
+ break;
}
}
}
@@ -2294,11 +2274,11 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
if (vehicle)
{
uint16 checkMask = 0;
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (effect && effect->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
+ if (effect.IsAura(SPELL_AURA_MOD_SHAPESHIFT))
{
- SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect->MiscValue);
+ SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect.MiscValue);
if (shapeShiftFromEntry && (shapeShiftFromEntry->Flags & 1) == 0) // unk flag
checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
break;
@@ -2319,12 +2299,12 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
// Can only summon uncontrolled minions/guardians when on controlled vehicle
if (vehicleSeat->Flags & (VEHICLE_SEAT_FLAG_CAN_CONTROL | VEHICLE_SEAT_FLAG_UNK2))
{
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect || effect->Effect != SPELL_EFFECT_SUMMON)
+ if (!effect.IsEffect(SPELL_EFFECT_SUMMON))
continue;
- SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect->MiscValueB);
+ SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect.MiscValueB);
if (props && props->Control != SUMMON_CATEGORY_WILD)
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
}
@@ -2365,21 +2345,21 @@ uint32 SpellInfo::GetAllEffectsMechanicMask() const
if (Mechanic)
mask |= 1 << Mechanic;
- for (SpellEffectInfo const* effect : _effects)
- if (effect && effect->IsEffect() && effect->Mechanic)
- mask |= 1 << effect->Mechanic;
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (effect.IsEffect() && effect.Mechanic)
+ mask |= 1 << effect.Mechanic;
return mask;
}
-uint32 SpellInfo::GetEffectMechanicMask(uint32 effIndex) const
+uint32 SpellInfo::GetEffectMechanicMask(SpellEffIndex effIndex) const
{
uint32 mask = 0;
if (Mechanic)
mask |= 1 << Mechanic;
- if (effIndex < _effects.size() && _effects[effIndex] && _effects[effIndex]->IsEffect() && _effects[effIndex]->Mechanic)
- mask |= 1 << _effects[effIndex]->Mechanic;
+ if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
+ mask |= 1 << GetEffect(effIndex).Mechanic;
return mask;
}
@@ -2390,18 +2370,17 @@ uint32 SpellInfo::GetSpellMechanicMaskByEffectMask(uint32 effectMask) const
if (Mechanic)
mask |= 1 << Mechanic;
- for (SpellEffectInfo const* effect : _effects)
- if (effect && (effectMask & (1 << effect->EffectIndex)) && effect->Mechanic)
- mask |= 1 << effect->Mechanic;
+ for (SpellEffectInfo const& effect : GetEffects())
+ if ((effectMask & (1 << effect.EffectIndex)) && effect.Mechanic)
+ mask |= 1 << effect.Mechanic;
return mask;
}
-Mechanics SpellInfo::GetEffectMechanic(uint32 effIndex) const
+Mechanics SpellInfo::GetEffectMechanic(SpellEffIndex effIndex) const
{
- SpellEffectInfo const* effect = GetEffect(effIndex);
- if (effect && effect->IsEffect() && effect->Mechanic)
- return Mechanics(effect->Mechanic);
+ if (GetEffect(effIndex).IsEffect() && GetEffect(effIndex).Mechanic)
+ return GetEffect(effIndex).Mechanic;
if (Mechanic)
return Mechanics(Mechanic);
@@ -2409,14 +2388,6 @@ Mechanics SpellInfo::GetEffectMechanic(uint32 effIndex) const
return MECHANIC_NONE;
}
-/*bool SpellInfo::HasAnyEffectMechanic() const
-{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].Mechanic)
- return true;
- return false;
-}*/
-
uint32 SpellInfo::GetDispelMask() const
{
return GetDispelMask(DispelType(Dispel));
@@ -2466,8 +2437,8 @@ void SpellInfo::_LoadAuraState()
return AURA_STATE_BLEED;
if (GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)
- for (SpellEffectInfo const* effect : _effects)
- if (effect && (effect->IsAura(SPELL_AURA_MOD_STUN) || effect->IsAura(SPELL_AURA_MOD_ROOT)))
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (effect.IsAura(SPELL_AURA_MOD_STUN) || effect.IsAura(SPELL_AURA_MOD_ROOT) || effect.IsAura(SPELL_AURA_MOD_ROOT_2))
return AURA_STATE_FROZEN;
switch (Id)
@@ -2539,11 +2510,11 @@ void SpellInfo::_LoadSpellSpecific()
{
bool food = false;
bool drink = false;
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect || !effect->IsAura())
+ if (!effect.IsAura())
continue;
- switch (effect->ApplyAuraName)
+ switch (effect.ApplyAuraName)
{
// Food
case SPELL_AURA_MOD_REGEN:
@@ -2595,8 +2566,8 @@ void SpellInfo::_LoadSpellSpecific()
// Arcane brillance and Arcane intelect (normal check fails because of flags difference)
if (SpellFamilyFlags[0] & 0x400)
return SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE;
- SpellEffectInfo const* effect = GetEffect(EFFECT_0);
- if (effect && (SpellFamilyFlags[0] & 0x1000000) && effect->ApplyAuraName == SPELL_AURA_MOD_CONFUSE)
+
+ if ((SpellFamilyFlags[0] & 0x1000000) && GetEffect(EFFECT_0).IsAura(SPELL_AURA_MOD_CONFUSE))
return SPELL_SPECIFIC_MAGE_POLYMORPH;
break;
@@ -2690,11 +2661,11 @@ void SpellInfo::_LoadSpellSpecific()
break;
}
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
+ if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
{
- switch (effect->ApplyAuraName)
+ switch (effect.ApplyAuraName)
{
case SPELL_AURA_MOD_CHARM:
case SPELL_AURA_MOD_POSSESS_PET:
@@ -2709,6 +2680,8 @@ void SpellInfo::_LoadSpellSpecific()
case SPELL_AURA_TRACK_RESOURCES:
case SPELL_AURA_TRACK_STEALTHED:
return SPELL_SPECIFIC_TRACKER;
+ default:
+ break;
}
}
}
@@ -3191,7 +3164,7 @@ int32 SpellInfo::GetDiminishingReturnsLimitDuration() const
void SpellInfo::_LoadImmunityInfo()
{
- auto loadImmunityInfoFn = [this](SpellEffectInfo* effectInfo)
+ for (SpellEffectInfo& effect : _effects)
{
uint32 schoolImmunityMask = 0;
uint32 applyHarmfulAuraImmunityMask = 0;
@@ -3199,12 +3172,12 @@ void SpellInfo::_LoadImmunityInfo()
uint32 dispelImmunity = 0;
uint32 damageImmunityMask = 0;
- int32 miscVal = effectInfo->MiscValue;
- int32 amount = effectInfo->CalcValue();
+ int32 miscVal = effect.MiscValue;
+ int32 amount = effect.CalcValue();
- ImmunityInfo& immuneInfo = *const_cast<ImmunityInfo*>(effectInfo->GetImmunityInfo());
+ ImmunityInfo& immuneInfo = effect._immunityInfo;
- switch (effectInfo->ApplyAuraName)
+ switch (effect.ApplyAuraName)
{
case SPELL_AURA_MECHANIC_IMMUNITY_MASK:
{
@@ -3448,14 +3421,6 @@ void SpellInfo::_LoadImmunityInfo()
immuneInfo.SpellEffectImmune.shrink_to_fit();
_allowedMechanicMask |= immuneInfo.MechanicImmuneMask;
- };
-
- for (SpellEffectInfo const* effect : _effects)
- {
- if (!effect)
- continue;
-
- loadImmunityInfoFn(const_cast<SpellEffectInfo*>(effect));
}
if (HasAttribute(SPELL_ATTR5_USABLE_WHILE_STUNNED))
@@ -3496,9 +3461,9 @@ void SpellInfo::_LoadImmunityInfo()
}
}
-void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const* effect, bool apply) const
+void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const
{
- ImmunityInfo const* immuneInfo = effect->GetImmunityInfo();
+ ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo();
if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
{
@@ -3572,12 +3537,12 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
if (!auraSpellInfo)
return false;
- for (SpellEffectInfo const* effectInfo : _effects)
+ for (SpellEffectInfo const& effectInfo : _effects)
{
- if (!effectInfo)
+ if (!effectInfo.IsEffect())
continue;
- ImmunityInfo const* immuneInfo = effectInfo->GetImmunityInfo();
+ ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo();
if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
{
@@ -3595,23 +3560,19 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
return true;
bool immuneToAllEffects = true;
- for (SpellEffectInfo const* auraSpellEffectInfo : auraSpellInfo->GetEffects())
+ for (SpellEffectInfo const& auraSpellEffectInfo : auraSpellInfo->GetEffects())
{
- if (!auraSpellEffectInfo)
- continue;
-
- uint32 effectName = auraSpellEffectInfo->Effect;
- if (!effectName)
+ if (!auraSpellEffectInfo.IsEffect())
continue;
- auto spellImmuneItr = immuneInfo->SpellEffectImmune.find(static_cast<SpellEffectName>(effectName));
+ auto spellImmuneItr = immuneInfo->SpellEffectImmune.find(auraSpellEffectInfo.Effect);
if (spellImmuneItr == immuneInfo->SpellEffectImmune.cend())
{
immuneToAllEffects = false;
break;
}
- if (uint32 mechanic = auraSpellEffectInfo->Mechanic)
+ if (uint32 mechanic = auraSpellEffectInfo.Mechanic)
{
if (!(immuneInfo->MechanicImmuneMask & (1 << mechanic)))
{
@@ -3622,14 +3583,14 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
if (!auraSpellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT))
{
- if (uint32 auraName = auraSpellEffectInfo->ApplyAuraName)
+ if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName)
{
bool isImmuneToAuraEffectApply = false;
- auto auraImmuneItr = immuneInfo->AuraTypeImmune.find(static_cast<AuraType>(auraName));
+ auto auraImmuneItr = immuneInfo->AuraTypeImmune.find(auraName);
if (auraImmuneItr != immuneInfo->AuraTypeImmune.cend())
isImmuneToAuraEffectApply = true;
- if (!isImmuneToAuraEffectApply && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo->EffectIndex) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
+ if (!isImmuneToAuraEffectApply && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
{
if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
@@ -3661,19 +3622,16 @@ bool SpellInfo::SpellCancelsAuraEffect(AuraEffect const* aurEff) const
if (aurEff->GetSpellInfo()->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY))
return false;
- for (SpellEffectInfo const* effectInfo : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effectInfo)
+ if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
continue;
- if (effectInfo->Effect != SPELL_EFFECT_APPLY_AURA)
- continue;
-
- uint32 const miscValue = static_cast<uint32>(effectInfo->MiscValue);
- switch (effectInfo->ApplyAuraName)
+ uint32 const miscValue = static_cast<uint32>(effect.MiscValue);
+ switch (effect.ApplyAuraName)
{
case SPELL_AURA_STATE_IMMUNITY:
- if (miscValue != aurEff->GetSpellEffectInfo()->ApplyAuraName)
+ if (miscValue != aurEff->GetAuraType())
continue;
break;
case SPELL_AURA_SCHOOL_IMMUNITY:
@@ -3688,7 +3646,7 @@ bool SpellInfo::SpellCancelsAuraEffect(AuraEffect const* aurEff) const
case SPELL_AURA_MECHANIC_IMMUNITY:
if (miscValue != aurEff->GetSpellInfo()->Mechanic)
{
- if (miscValue != aurEff->GetSpellEffectInfo()->Mechanic)
+ if (miscValue != aurEff->GetSpellEffectInfo().Mechanic)
continue;
}
break;
@@ -3774,11 +3732,11 @@ uint32 SpellInfo::GetMaxTicks() const
uint32 totalTicks = 0;
int32 DotDuration = GetDuration();
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
+ if (effect.IsEffect(SPELL_EFFECT_APPLY_AURA))
{
- switch (effect->ApplyAuraName)
+ switch (effect.ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
@@ -3795,13 +3753,15 @@ uint32 SpellInfo::GetMaxTicks() const
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
// skip infinite periodics
- if (effect->ApplyAuraPeriod > 0 && DotDuration > 0)
+ if (effect.ApplyAuraPeriod > 0 && DotDuration > 0)
{
- totalTicks = static_cast<uint32>(DotDuration) / effect->ApplyAuraPeriod;
+ totalTicks = static_cast<uint32>(DotDuration) / effect.ApplyAuraPeriod;
if (HasAttribute(SPELL_ATTR5_START_PERIODIC_AT_APPLY))
++totalTicks;
}
break;
+ default:
+ break;
}
}
}
@@ -4239,13 +4199,13 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const
return this;
bool needRankSelection = false;
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (effect && IsPositiveEffect(effect->EffectIndex) &&
- (effect->Effect == SPELL_EFFECT_APPLY_AURA ||
- effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
- effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
- !effect->Scaling.Coefficient)
+ if (IsPositiveEffect(effect.EffectIndex) &&
+ (effect.Effect == SPELL_EFFECT_APPLY_AURA ||
+ effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ effect.Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
+ !effect.Scaling.Coefficient)
{
needRankSelection = true;
break;
@@ -4322,20 +4282,20 @@ void SpellInfo::_InitializeExplicitTargetMask()
bool dstSet = false;
uint32 targetMask = Targets;
// prepare target mask using effect target entries
- for (SpellEffectInfo const* effect : _effects)
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect || !effect->IsEffect())
+ if (!effect.IsEffect())
continue;
- targetMask |= effect->TargetA.GetExplicitTargetMask(srcSet, dstSet);
- targetMask |= effect->TargetB.GetExplicitTargetMask(srcSet, dstSet);
+ targetMask |= effect.TargetA.GetExplicitTargetMask(srcSet, dstSet);
+ targetMask |= effect.TargetB.GetExplicitTargetMask(srcSet, dstSet);
// add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
- if (effect->GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
+ if (effect.GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
continue;
// extend explicit target mask only if valid targets for effect could not be provided by target types
- uint32 effectTargetMask = effect->GetMissingTargetMask(srcSet, dstSet, targetMask);
+ uint32 effectTargetMask = effect.GetMissingTargetMask(srcSet, dstSet, targetMask);
// don't add explicit object/dest flags when spell has no max range
if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
@@ -4347,24 +4307,22 @@ void SpellInfo::_InitializeExplicitTargetMask()
ExplicitTargetMask = targetMask;
}
-inline bool _isPositiveTarget(SpellInfo const* spellInfo, uint32 effIndex)
+inline bool _isPositiveTarget(SpellEffectInfo const& effect)
{
- SpellEffectInfo const* effect = spellInfo->GetEffect(effIndex);
- if (!effect || !effect->IsEffect())
+ if (!effect.IsEffect())
return true;
- return (effect->TargetA.GetCheckType() != TARGET_CHECK_ENEMY &&
- effect->TargetB.GetCheckType() != TARGET_CHECK_ENEMY);
+ return (effect.TargetA.GetCheckType() != TARGET_CHECK_ENEMY &&
+ effect.TargetB.GetCheckType() != TARGET_CHECK_ENEMY);
}
-bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::unordered_set<std::pair<SpellInfo const*, uint32>>& visited)
+bool _isPositiveEffectImpl(SpellInfo const* spellInfo, SpellEffectInfo const& effect, std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex>>& visited)
{
- SpellEffectInfo const* effect = spellInfo->GetEffect(effIndex);
- if (!effect || !effect->IsEffect())
+ if (!effect.IsEffect())
return true;
// attribute may be already set in DB
- if (!spellInfo->IsPositiveEffect(effIndex))
+ if (!spellInfo->IsPositiveEffect(effect.EffectIndex))
return false;
// passive auras like talents are all positive
@@ -4375,9 +4333,9 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
if (spellInfo->HasAttribute(SPELL_ATTR0_NEGATIVE_1))
return false;
- visited.insert({ spellInfo, effIndex });
+ visited.insert({ spellInfo, effect.EffectIndex });
- int32 bp = effect->CalcValue();
+ int32 bp = effect.CalcValue();
switch (spellInfo->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
@@ -4429,17 +4387,14 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
if (spellInfo->HasAttribute(SPELL_ATTR1_DONT_REFRESH_DURATION_ON_RECAST))
{
// check for targets, there seems to be an assortment of dummy triggering spells that should be negative
- for (SpellEffectInfo const* otherEffect : spellInfo->GetEffects())
- if (otherEffect && !_isPositiveTarget(spellInfo, otherEffect->EffectIndex))
+ for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
+ if (!_isPositiveTarget(otherEffect))
return false;
}
- for (SpellEffectInfo const* otherEffect : spellInfo->GetEffects())
+ for (SpellEffectInfo const& otherEffect : spellInfo->GetEffects())
{
- if (!otherEffect)
- continue;
-
- switch (otherEffect->Effect)
+ switch (otherEffect.Effect)
{
case SPELL_EFFECT_HEAL:
case SPELL_EFFECT_LEARN_SPELL:
@@ -4448,17 +4403,17 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
case SPELL_EFFECT_ENERGIZE_PCT:
return true;
case SPELL_EFFECT_INSTAKILL:
- if (otherEffect->EffectIndex != effIndex && // for spells like 38044: instakill effect is negative but auras on target must count as buff
- otherEffect->TargetA.GetTarget() == effect->TargetA.GetTarget() &&
- otherEffect->TargetB.GetTarget() == effect->TargetB.GetTarget())
+ if (otherEffect.EffectIndex != effect.EffectIndex && // for spells like 38044: instakill effect is negative but auras on target must count as buff
+ otherEffect.TargetA.GetTarget() == effect.TargetA.GetTarget() &&
+ otherEffect.TargetB.GetTarget() == effect.TargetB.GetTarget())
return false;
default:
break;
}
- if (otherEffect->IsAura())
+ if (otherEffect.IsAura())
{
- switch (otherEffect->ApplyAuraName)
+ switch (otherEffect.ApplyAuraName)
{
case SPELL_AURA_MOD_STEALTH:
case SPELL_AURA_MOD_UNATTACKABLE:
@@ -4473,7 +4428,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
}
}
- switch (effect->Effect)
+ switch (effect.Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
@@ -4506,12 +4461,12 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
case SPELL_EFFECT_ATTACK_ME:
case SPELL_EFFECT_POWER_BURN:
// check targets
- if (!_isPositiveTarget(spellInfo, effIndex))
+ if (!_isPositiveTarget(effect))
return false;
break;
case SPELL_EFFECT_DISPEL:
// non-positive dispel
- switch (effect->MiscValue)
+ switch (effect.MiscValue)
{
case DISPEL_STEALTH:
case DISPEL_INVISIBILITY:
@@ -4522,14 +4477,14 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
}
// also check targets
- if (!_isPositiveTarget(spellInfo, effIndex))
+ if (!_isPositiveTarget(effect))
return false;
break;
case SPELL_EFFECT_DISPEL_MECHANIC:
- if (!_isPositiveTarget(spellInfo, effIndex))
+ if (!_isPositiveTarget(effect))
{
// non-positive mechanic dispel on negative target
- switch (effect->MiscValue)
+ switch (effect.MiscValue)
{
case MECHANIC_BANDAGE:
case MECHANIC_SHIELD:
@@ -4544,17 +4499,17 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
case SPELL_EFFECT_THREAT:
case SPELL_EFFECT_MODIFY_THREAT_PERCENT:
// check targets AND basepoints
- if (!_isPositiveTarget(spellInfo, effIndex) && bp > 0)
+ if (!_isPositiveTarget(effect) && bp > 0)
return false;
break;
default:
break;
}
- if (effect->IsAura())
+ if (effect.IsAura())
{
// non-positive aura use
- switch (effect->ApplyAuraName)
+ switch (effect.ApplyAuraName)
{
case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from basepoint sign (negative -> negative)
case SPELL_AURA_MOD_STAT:
@@ -4589,7 +4544,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
case SPELL_AURA_MOD_ATTACK_POWER:
case SPELL_AURA_MOD_RANGED_ATTACK_POWER:
case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE:
- if (!_isPositiveTarget(spellInfo, effIndex) && bp < 0)
+ if (!_isPositiveTarget(effect) && bp < 0)
return false;
break;
case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from basepoint sign (positive -> negative)
@@ -4603,33 +4558,30 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
return false;
break;
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: // check targets and basepoints (ex Recklessness)
- if (!_isPositiveTarget(spellInfo, effIndex) && bp > 0)
+ if (!_isPositiveTarget(effect) && bp > 0)
return false;
break;
case SPELL_AURA_ADD_TARGET_TRIGGER:
return true;
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
- if (!_isPositiveTarget(spellInfo, effIndex))
+ if (!_isPositiveTarget(effect))
{
- if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect->TriggerSpell, spellInfo->Difficulty))
+ if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
{
// negative targets of main spell return early
- for (SpellEffectInfo const* spellTriggeredEffect : spellTriggeredProto->GetEffects())
+ for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
{
- if (!spellTriggeredEffect)
- continue;
-
// already seen this
- if (visited.count({ spellTriggeredProto, spellTriggeredEffect->EffectIndex }) > 0)
+ if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
continue;
- if (!spellTriggeredEffect->IsEffect())
+ if (!spellTriggeredEffect.IsEffect())
continue;
// if non-positive trigger cast targeted to positive target this main cast is non-positive
// this will place this spell auras as debuffs
- if (_isPositiveTarget(spellTriggeredProto, spellTriggeredEffect->EffectIndex) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect->EffectIndex, visited))
+ if (_isPositiveTarget(spellTriggeredEffect) && !_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
return false;
}
}
@@ -4660,7 +4612,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
case SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE:
case SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE:
// have positive and negative spells, check target
- if (!_isPositiveTarget(spellInfo, effIndex))
+ if (!_isPositiveTarget(effect))
return false;
break;
case SPELL_AURA_MOD_CONFUSE:
@@ -4682,7 +4634,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
case SPELL_AURA_MECHANIC_IMMUNITY:
{
// non-positive immunities
- switch (effect->MiscValue)
+ switch (effect.MiscValue)
{
case MECHANIC_BANDAGE:
case MECHANIC_SHIELD:
@@ -4699,7 +4651,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
case SPELL_AURA_ADD_FLAT_MODIFIER_BY_SPELL_LABEL:
case SPELL_AURA_ADD_PCT_MODIFIER_BY_SPELL_LABEL:
{
- switch (SpellModOp(effect->MiscValue))
+ switch (SpellModOp(effect.MiscValue))
{
case SpellModOp::ChangeCastTime: // dependent from basepoint sign (positive -> negative)
case SpellModOp::Period:
@@ -4745,25 +4697,22 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
}
// negative spell if triggered spell is negative
- if (!effect->ApplyAuraName && effect->TriggerSpell)
+ if (!effect.ApplyAuraName && effect.TriggerSpell)
{
- if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect->TriggerSpell, spellInfo->Difficulty))
+ if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect.TriggerSpell, spellInfo->Difficulty))
{
// spells with at least one negative effect are considered negative
// some self-applied spells have negative effects but in self casting case negative check ignored.
- for (SpellEffectInfo const* spellTriggeredEffect : spellTriggeredProto->GetEffects())
+ for (SpellEffectInfo const& spellTriggeredEffect : spellTriggeredProto->GetEffects())
{
- if (!spellTriggeredEffect)
- continue;
-
// already seen this
- if (visited.count({ spellTriggeredProto, spellTriggeredEffect->EffectIndex }) > 0)
+ if (visited.count({ spellTriggeredProto, spellTriggeredEffect.EffectIndex }) > 0)
continue;
- if (!spellTriggeredEffect->IsEffect())
+ if (!spellTriggeredEffect.IsEffect())
continue;
- if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect->EffectIndex, visited))
+ if (!_isPositiveEffectImpl(spellTriggeredProto, spellTriggeredEffect, visited))
return false;
}
}
@@ -4775,19 +4724,19 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, uint32 effIndex, std::uno
void SpellInfo::_InitializeSpellPositivity()
{
- std::unordered_set<std::pair<SpellInfo const*, uint32 /*effIndex*/>> visited;
+ std::unordered_set<std::pair<SpellInfo const*, SpellEffIndex /*effIndex*/>> visited;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (!_isPositiveEffectImpl(this, i, visited))
- NegativeEffects[i] = true;
+ for (SpellEffectInfo const& effect : GetEffects())
+ if (!_isPositiveEffectImpl(this, effect, visited))
+ NegativeEffects[effect.EffectIndex] = true;
// additional checks after effects marked
- for (SpellEffectInfo const* effect : GetEffects())
+ for (SpellEffectInfo const& effect : GetEffects())
{
- if (!effect || !effect->IsEffect() || !IsPositiveEffect(effect->EffectIndex))
+ if (!effect.IsEffect() || !IsPositiveEffect(effect.EffectIndex))
continue;
- switch (effect->ApplyAuraName)
+ switch (effect.ApplyAuraName)
{
// has other non positive effect?
// then it should be marked negative despite of targets (ex 8510, 8511, 8893, 10267)
@@ -4798,8 +4747,11 @@ void SpellInfo::_InitializeSpellPositivity()
case SPELL_AURA_TRANSFORM:
case SPELL_AURA_MOD_ATTACKSPEED:
case SPELL_AURA_MOD_DECREASE_SPEED:
- if (!IsPositive())
- NegativeEffects[effect->EffectIndex] = true;
+ for (size_t j = effect.EffectIndex + 1; j < GetEffects().size(); ++j)
+ if (!IsPositiveEffect(j)
+ && effect.TargetA.GetTarget() == GetEffect(SpellEffIndex(j)).TargetA.GetTarget()
+ && effect.TargetB.GetTarget() == GetEffect(SpellEffIndex(j)).TargetB.GetTarget())
+ NegativeEffects[effect.EffectIndex] = true;
break;
default:
break;
@@ -4810,21 +4762,17 @@ void SpellInfo::_InitializeSpellPositivity()
void SpellInfo::_UnloadImplicitTargetConditionLists()
{
// find the same instances of ConditionList and delete them.
- for (uint32 i = 0; i < _effects.size(); ++i)
+ for (SpellEffectInfo const& effect : _effects)
{
- if (SpellEffectInfo const* effect = _effects[i])
- {
- ConditionContainer* cur = effect->ImplicitTargetConditions;
- if (!cur)
- continue;
+ ConditionContainer* cur = effect.ImplicitTargetConditions;
+ if (!cur)
+ continue;
- for (uint8 j = i; j < _effects.size(); ++j)
- if (SpellEffectInfo const* eff = _effects[j])
- if (eff->ImplicitTargetConditions == cur)
- const_cast<SpellEffectInfo*>(eff)->ImplicitTargetConditions = nullptr;
+ for (size_t j = effect.EffectIndex; j < _effects.size(); ++j)
+ if (_effects[j].ImplicitTargetConditions == cur)
+ _effects[j].ImplicitTargetConditions = nullptr;
- delete cur;
- }
+ delete cur;
}
}
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index dfc169ab570..a63d6b2985c 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -27,18 +27,18 @@
#include <boost/container/flat_set.hpp>
#include <bitset>
-class Unit;
-class Player;
+class AuraEffect;
class Item;
+class Player;
class Spell;
class SpellMgr;
class SpellInfo;
+class Unit;
class WorldObject;
-class AuraEffect;
+struct Condition;
struct SpellChainNode;
struct SpellModifier;
struct SpellTargetPosition;
-struct Condition;
enum WeaponAttackType : uint8;
enum SpellCastTargetFlags : uint32
@@ -262,11 +262,12 @@ struct TC_GAME_API ImmunityInfo
class TC_GAME_API SpellEffectInfo
{
+ friend class SpellInfo;
SpellInfo const* _spellInfo;
public:
- uint32 EffectIndex;
- uint32 Effect;
- uint32 ApplyAuraName;
+ SpellEffIndex EffectIndex;
+ SpellEffectName Effect;
+ AuraType ApplyAuraName;
uint32 ApplyAuraPeriod;
int32 BasePoints;
float RealPointsPerLevel;
@@ -298,7 +299,7 @@ public:
float ResourceCoefficient;
} Scaling;
- SpellEffectInfo() : _spellInfo(nullptr), EffectIndex(0), Effect(0), ApplyAuraName(0), ApplyAuraPeriod(0),
+ SpellEffectInfo(SpellInfo const* spellInfo) : _spellInfo(spellInfo), EffectIndex(EFFECT_0), Effect(SPELL_EFFECT_NONE), ApplyAuraName(AuraType(0)), ApplyAuraPeriod(0),
BasePoints(0), RealPointsPerLevel(0), PointsPerResource(0), Amplitude(0), ChainAmplitude(0),
BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), PositionFacing(0),
RadiusEntry(nullptr), MaxRadiusEntry(nullptr), ChainTargets(0), ItemType(0), TriggerSpell(0),
@@ -346,8 +347,6 @@ private:
ImmunityInfo _immunityInfo;
};
-typedef std::vector<SpellEffectInfo const*> SpellEffectInfoVector;
-
typedef std::vector<SpellXSpellVisualEntry const*> SpellVisualVector;
typedef std::unordered_map<uint32, SpellVisualVector> SpellVisualMap;
@@ -571,10 +570,9 @@ class TC_GAME_API SpellInfo
SpellSchoolMask GetSchoolMask() const;
uint32 GetAllEffectsMechanicMask() const;
- uint32 GetEffectMechanicMask(uint32 effIndex) const;
+ uint32 GetEffectMechanicMask(SpellEffIndex effIndex) const;
uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const;
- Mechanics GetEffectMechanic(uint32 effIndex) const;
- //bool HasAnyEffectMechanic() const;
+ Mechanics GetEffectMechanic(SpellEffIndex effIndex) const;
uint32 GetDispelMask() const;
static uint32 GetDispelMask(DispelType type);
uint32 GetExplicitTargetMask() const;
@@ -614,8 +612,8 @@ class TC_GAME_API SpellInfo
uint32 GetSpellXSpellVisualId(WorldObject const* caster = nullptr) const;
uint32 GetSpellVisual(WorldObject const* caster = nullptr) const;
- SpellEffectInfoVector const& GetEffects() const { return _effects; }
- SpellEffectInfo const* GetEffect(uint32 index) const { return index < _effects.size() ? _effects[index] : nullptr; }
+ std::vector<SpellEffectInfo> const& GetEffects() const { return _effects; }
+ SpellEffectInfo const& GetEffect(SpellEffIndex index) const { ASSERT(index < _effects.size()); return _effects[index]; }
// spell diminishing returns
DiminishingGroup GetDiminishingReturnsGroupForSpell() const;
@@ -624,7 +622,7 @@ class TC_GAME_API SpellInfo
int32 GetDiminishingReturnsLimitDuration() const;
// spell immunities
- void ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const* effect, bool apply) const;
+ void ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const;
bool CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInfo) const;
bool SpellCancelsAuraEffect(AuraEffect const* aurEff) const;
@@ -646,10 +644,9 @@ class TC_GAME_API SpellInfo
// unloading helpers
void _UnloadImplicitTargetConditionLists();
- void _UnloadSpellEffects();
private:
- SpellEffectInfoVector _effects;
+ std::vector<SpellEffectInfo> _effects;
SpellVisualVector _visuals;
SpellSpecificType _spellSpecific = SPELL_SPECIFIC_NORMAL;
AuraStateType _auraState = AURA_STATE_NONE;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 1e6d3cbd5f5..472b052a56d 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -146,21 +146,15 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
bool needCheckReagents = false;
// check effects
- for (SpellEffectInfo const* effect : spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
{
- if (!effect)
- continue;
-
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
- case 0:
- continue;
-
// craft spell for crafting non-existed item (break client recipes list show)
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_CREATE_LOOT:
{
- if (effect->ItemType == 0)
+ if (spellEffectInfo.ItemType == 0)
{
// skip auto-loot crafting spells, it does not need explicit item info (but has special fake items sometimes).
if (!spellInfo->IsLootCrafting())
@@ -177,14 +171,14 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
}
// also possible IsLootCrafting case but fake items must exist anyway
- else if (!sObjectMgr->GetItemTemplate(effect->ItemType))
+ else if (!sObjectMgr->GetItemTemplate(spellEffectInfo.ItemType))
{
if (msg)
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u has created a non-existing in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType);
+ ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u has created a non-existing in DB item (Entry: %u) and then...", spellInfo->Id, spellEffectInfo.ItemType);
else
- TC_LOG_ERROR("sql.sql", "Craft spell %u has created a non-existing item in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType);
+ TC_LOG_ERROR("sql.sql", "Craft spell %u has created a non-existing item in DB item (Entry: %u) and then...", spellInfo->Id, spellEffectInfo.ItemType);
}
return false;
}
@@ -194,20 +188,22 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
}
case SPELL_EFFECT_LEARN_SPELL:
{
- SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE);
+ SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE);
if (!IsSpellValid(spellInfo2, player, msg))
{
if (msg)
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, effect->TriggerSpell);
+ ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, spellEffectInfo.TriggerSpell);
else
- TC_LOG_ERROR("sql.sql", "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, effect->TriggerSpell);
+ TC_LOG_ERROR("sql.sql", "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, spellEffectInfo.TriggerSpell);
}
return false;
}
break;
}
+ default:
+ break;
}
}
@@ -980,17 +976,14 @@ void SpellMgr::LoadSpellLearnSkills()
if (entry.Difficulty != DIFFICULTY_NONE)
continue;
- for (SpellEffectInfo const* effect : entry.GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : entry.GetEffects())
{
- if (!effect)
- continue;
-
SpellLearnSkillNode dbc_node;
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_SKILL:
- dbc_node.skill = uint16(effect->MiscValue);
- dbc_node.step = uint16(effect->CalcValue());
+ dbc_node.skill = uint16(spellEffectInfo.MiscValue);
+ dbc_node.step = uint16(spellEffectInfo.CalcValue());
if (dbc_node.skill != SKILL_RIDING)
dbc_node.value = 1;
else
@@ -1077,12 +1070,12 @@ void SpellMgr::LoadSpellLearnSpells()
if (entry.Difficulty != DIFFICULTY_NONE)
continue;
- for (SpellEffectInfo const* effect : entry.GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : entry.GetEffects())
{
- if (effect && effect->Effect == SPELL_EFFECT_LEARN_SPELL)
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_LEARN_SPELL))
{
SpellLearnSpellNode dbc_node;
- dbc_node.Spell = effect->TriggerSpell;
+ dbc_node.Spell = spellEffectInfo.TriggerSpell;
dbc_node.Active = true; // all dbc based learned spells is active (show in spell book or hide by client itself)
dbc_node.OverridesSpell = 0;
@@ -1093,7 +1086,7 @@ void SpellMgr::LoadSpellLearnSpells()
// talent or passive spells or skill-step spells auto-cast and not need dependent learning,
// pet teaching spells must not be dependent learning (cast)
// other required explicit dependent learning
- dbc_node.AutoLearned = effect->TargetA.GetTarget() == TARGET_UNIT_PET || entry.HasAttribute(SPELL_ATTR0_CU_IS_TALENT) || entry.IsPassive() || entry.HasEffect(SPELL_EFFECT_SKILL_STEP);
+ dbc_node.AutoLearned = spellEffectInfo.TargetA.GetTarget() == TARGET_UNIT_PET || entry.HasAttribute(SPELL_ATTR0_CU_IS_TALENT) || entry.IsPassive() || entry.HasEffect(SPELL_EFFECT_SKILL_STEP);
SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(entry.Id);
@@ -1216,20 +1209,19 @@ void SpellMgr::LoadSpellTargetPositions()
continue;
}
- SpellEffectInfo const* effect = spellInfo->GetEffect(effIndex);
- if (!effect)
+ if (effIndex >= spellInfo->GetEffects().size())
{
TC_LOG_ERROR("sql.sql", "Spell (Id: %u, EffectIndex: %u) listed in `spell_target_position` does not have an effect at index %u.", spellId, effIndex, effIndex);
continue;
}
// target facing is in degrees for 6484 & 9268... (blizz sucks)
- if (effect->PositionFacing > 2 * M_PI)
- st.target_Orientation = effect->PositionFacing * float(M_PI) / 180;
+ if (spellInfo->GetEffect(effIndex).PositionFacing > 2 * M_PI)
+ st.target_Orientation = spellInfo->GetEffect(effIndex).PositionFacing * float(M_PI) / 180;
else
- st.target_Orientation = effect->PositionFacing;
+ st.target_Orientation = spellInfo->GetEffect(effIndex).PositionFacing;
- if (effect->TargetA.GetTarget() == TARGET_DEST_DB || effect->TargetB.GetTarget() == TARGET_DEST_DB)
+ if (spellInfo->GetEffect(effIndex).TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->GetEffect(effIndex).TargetB.GetTarget() == TARGET_DEST_DB)
{
std::pair<uint32, SpellEffIndex> key = std::make_pair(spellId, effIndex);
mSpellTargetPositions[key] = st;
@@ -1420,12 +1412,12 @@ void SpellMgr::LoadSpellGroupStackRules()
for (uint32 spellId : spellIds)
{
SpellInfo const* spellInfo = AssertSpellInfo(spellId, DIFFICULTY_NONE);
- for (SpellEffectInfo const* effectInfo : spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
{
- if (!effectInfo->IsAura())
+ if (!spellEffectInfo.IsAura())
continue;
- uint32 auraName = effectInfo->ApplyAuraName;
+ uint32 auraName = spellEffectInfo.ApplyAuraName;
for (std::vector<uint32> const& subGroup : SubGroups)
{
if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end())
@@ -1616,18 +1608,18 @@ void SpellMgr::LoadSpellProcs()
TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `HitMask` set: %u", spellInfo->Id, procEntry.HitMask);
if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `HitMask` value defined, but it will not be used for defined `ProcFlags` and `SpellPhaseMask` values.", spellInfo->Id);
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if ((procEntry.DisableEffectsMask & (1u << i)) && (!spellInfo->GetEffect(i) || !spellInfo->GetEffect(i)->IsAura()))
- TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has DisableEffectsMask with effect %u, but effect %u is not an aura effect", spellInfo->Id, static_cast<uint32>(i), static_cast<uint32>(i));
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
+ if ((procEntry.DisableEffectsMask & (1u << spellEffectInfo.EffectIndex)) && !spellEffectInfo.IsAura())
+ TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has DisableEffectsMask with effect %u, but effect %u is not an aura effect", spellInfo->Id, static_cast<uint32>(spellEffectInfo.EffectIndex), static_cast<uint32>(spellEffectInfo.EffectIndex));
if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD)
{
bool found = false;
- for (SpellEffectInfo const* effect : spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
{
- if (!effect || !effect->IsAura())
+ if (!spellEffectInfo.IsAura())
continue;
- if (effect->ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || effect->ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER)
+ if (spellEffectInfo.ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellEffectInfo.ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER)
{
found = true;
break;
@@ -1761,19 +1753,19 @@ void SpellMgr::LoadSpellProcs()
bool addTriggerFlag = false;
uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE;
uint32 nonProcMask = 0;
- for (SpellEffectInfo const* effect : spellInfo.GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects())
{
- if (!effect || !effect->IsEffect())
+ if (!spellEffectInfo.IsEffect())
continue;
- uint32 auraName = effect->ApplyAuraName;
+ uint32 auraName = spellEffectInfo.ApplyAuraName;
if (!auraName)
continue;
if (!isTriggerAura[auraName])
{
// explicitly disable non proccing auras to avoid losing charges on self proc
- nonProcMask |= 1 << effect->EffectIndex;
+ nonProcMask |= 1 << spellEffectInfo.EffectIndex;
continue;
}
@@ -1799,9 +1791,9 @@ void SpellMgr::LoadSpellProcs()
if (!procSpellTypeMask)
{
- for (SpellEffectInfo const* effectInfo : spellInfo.GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects())
{
- if (effectInfo && effectInfo->IsAura())
+ if (spellEffectInfo.IsAura())
{
TC_LOG_ERROR("sql.sql", "Spell Id %u has DBC ProcFlags %u, but it's of non-proc aura type, it probably needs an entry in `spell_proc` table to be handled correctly.", spellInfo.Id, spellInfo.ProcFlags);
break;
@@ -1815,9 +1807,9 @@ void SpellMgr::LoadSpellProcs()
procEntry.SchoolMask = 0;
procEntry.ProcFlags = spellInfo.ProcFlags;
procEntry.SpellFamilyName = 0;
- for (SpellEffectInfo const* effect : spellInfo.GetEffects())
- if (effect && effect->IsEffect() && isTriggerAura[effect->ApplyAuraName])
- procEntry.SpellFamilyMask |= effect->SpellClassMask;
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects())
+ if (spellEffectInfo.IsEffect() && isTriggerAura[spellEffectInfo.ApplyAuraName])
+ procEntry.SpellFamilyMask |= spellEffectInfo.SpellClassMask;
if (procEntry.SpellFamilyMask)
procEntry.SpellFamilyName = spellInfo.SpellFamilyName;
@@ -1826,12 +1818,12 @@ void SpellMgr::LoadSpellProcs()
procEntry.SpellPhaseMask = PROC_SPELL_PHASE_HIT;
procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent
- for (SpellEffectInfo const* effect : spellInfo.GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects())
{
- if (!effect || !effect->IsAura())
+ if (!spellEffectInfo.IsAura())
continue;
- switch (effect->ApplyAuraName)
+ switch (spellEffectInfo.ApplyAuraName)
{
// Reflect auras should only proc off reflects
case SPELL_AURA_REFLECT_SPELLS:
@@ -1951,7 +1943,7 @@ void SpellMgr::LoadSpellPetAuras()
Field* fields = result->Fetch();
uint32 spell = fields[0].GetUInt32();
- uint8 eff = fields[1].GetUInt8();
+ SpellEffIndex eff = SpellEffIndex(fields[1].GetUInt8());
uint32 pet = fields[2].GetUInt32();
uint32 aura = fields[3].GetUInt32();
@@ -1966,18 +1958,17 @@ void SpellMgr::LoadSpellPetAuras()
TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_pet_auras` does not exist.", spell);
continue;
}
- SpellEffectInfo const* effect = spellInfo->GetEffect(eff);
- if (!effect)
+ if (eff >= spellInfo->GetEffects().size())
{
TC_LOG_ERROR("spells", "The spell %u listed in `spell_pet_auras` does not have any effect at index %u", spell, uint32(eff));
continue;
}
- if (effect->Effect != SPELL_EFFECT_DUMMY &&
- (effect->Effect != SPELL_EFFECT_APPLY_AURA ||
- effect->ApplyAuraName != SPELL_AURA_DUMMY))
+ if (spellInfo->GetEffect(eff).Effect != SPELL_EFFECT_DUMMY &&
+ (spellInfo->GetEffect(eff).Effect != SPELL_EFFECT_APPLY_AURA ||
+ spellInfo->GetEffect(eff).ApplyAuraName != SPELL_AURA_DUMMY))
{
- TC_LOG_ERROR("spells", "Spell %u listed in `spell_pet_auras` does not have any dummy aura or dummy effect", spell);
+ TC_LOG_ERROR("spells", "The spell %u listed in `spell_pet_auras` does not have any dummy aura or dummy effect.", spell);
continue;
}
@@ -1988,7 +1979,7 @@ void SpellMgr::LoadSpellPetAuras()
continue;
}
- PetAura pa(pet, aura, effect->TargetA.GetTarget() == TARGET_UNIT_PET, effect->CalcValue());
+ PetAura pa(pet, aura, spellInfo->GetEffect(eff).TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->GetEffect(eff).CalcValue());
mSpellPetAuraMap[(spell<<8) + eff] = pa;
}
@@ -2016,11 +2007,11 @@ void SpellMgr::LoadEnchantCustomAttr()
if (!spellInfo.HasAttribute(SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !spellInfo.HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT))
continue;
- for (SpellEffectInfo const* effect : spellInfo.GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects())
{
- if (effect && effect->Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
+ if (spellEffectInfo.Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
{
- uint32 enchId = effect->MiscValue;
+ uint32 enchId = spellEffectInfo.MiscValue;
SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
if (!ench)
continue;
@@ -2108,10 +2099,10 @@ void SpellMgr::LoadSpellLinked()
}
if (effect >= 0)
- for (SpellEffectInfo const* eff : spellInfo->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
{
- if (eff && eff->CalcValue() == abs(effect))
- TC_LOG_ERROR("sql.sql", "The spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), eff->EffectIndex);
+ if (spellEffectInfo.CalcValue() == abs(effect))
+ TC_LOG_ERROR("sql.sql", "The spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack).", abs(trigger), abs(effect), uint32(spellEffectInfo.EffectIndex));
}
spellInfo = GetSpellInfo(abs(effect), DIFFICULTY_NONE);
@@ -2252,11 +2243,11 @@ void SpellMgr::LoadPetDefaultSpells()
{
if (spellEntry.Difficulty != DIFFICULTY_NONE)
- for (SpellEffectInfo const* effect : spellEntry.GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellEntry.GetEffects())
{
- if (effect && (effect->Effect == SPELL_EFFECT_SUMMON || effect->Effect == SPELL_EFFECT_SUMMON_PET))
+ if (spellEffectInfo.IsEffect(SPELL_EFFECT_SUMMON) || spellEffectInfo.IsEffect(SPELL_EFFECT_SUMMON_PET))
{
- uint32 creature_id = effect->MiscValue;
+ uint32 creature_id = spellEffectInfo.MiscValue;
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
if (!cInfo)
continue;
@@ -2952,12 +2943,9 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
for (SpellInfo const& spellInfo : mSpellInfoMap)
{
SpellInfo* spellInfoMutable = const_cast<SpellInfo*>(&spellInfo);
- for (SpellEffectInfo const* effect : spellInfoMutable->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfoMutable->GetEffects())
{
- if (!effect)
- continue;
-
- switch (effect->ApplyAuraName)
+ switch (spellEffectInfo.ApplyAuraName)
{
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CONFUSE:
@@ -2979,9 +2967,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
case SPELL_AURA_POWER_BURN:
spellInfoMutable->AttributesCu |= SPELL_ATTR0_CU_NO_INITIAL_THREAT;
break;
+ default:
+ break;
}
- switch (effect->ApplyAuraName)
+ switch (spellEffectInfo.ApplyAuraName)
{
case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway.
// Auras that require both caster & target to be in world cannot be saved
@@ -2996,9 +2986,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
case SPELL_AURA_BATTLEGROUND_PLAYER_POSITION_FACTIONAL:
spellInfoMutable->AttributesCu |= SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED;
break;
+ default:
+ break;
}
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_SCHOOL_DAMAGE:
case SPELL_EFFECT_HEALTH_LEECH:
@@ -3013,9 +3005,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
case SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT:
spellInfoMutable->AttributesCu |= SPELL_ATTR0_CU_CAN_CRIT;
break;
+ default:
+ break;
}
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_SCHOOL_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE:
@@ -3053,7 +3047,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
// only enchanting profession enchantments procs can stack
if (IsPartOfSkillLine(SKILL_ENCHANTING, spellInfo.Id))
{
- uint32 enchantId = effect->MiscValue;
+ uint32 enchantId = spellEffectInfo.MiscValue;
SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
if (!enchant)
break;
@@ -3077,6 +3071,8 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
}
break;
}
+ default:
+ break;
}
}
@@ -3084,67 +3080,64 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
if (!spellInfoMutable->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT))
{
bool setFlag = false;
- for (SpellEffectInfo const* effect : spellInfoMutable->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfoMutable->GetEffects())
{
- if (!effect)
- continue;
-
- if (effect->IsEffect())
+ if (spellEffectInfo.IsEffect())
{
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
- case SPELL_EFFECT_SCHOOL_DAMAGE:
- case SPELL_EFFECT_WEAPON_DAMAGE:
- case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
- case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
- case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
- case SPELL_EFFECT_TRIGGER_SPELL:
- case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE:
- break;
- case SPELL_EFFECT_PERSISTENT_AREA_AURA:
- case SPELL_EFFECT_APPLY_AURA:
- case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
- case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
- case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
- case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
- case SPELL_EFFECT_APPLY_AREA_AURA_PET:
- case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
- case SPELL_EFFECT_APPLY_AURA_ON_PET:
- case SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS:
- case SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM:
- if (effect->ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
- effect->ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
- effect->ApplyAuraName == SPELL_AURA_DUMMY ||
- effect->ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
- effect->ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
- effect->ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
- break;
- /* fallthrough */
- default:
- {
- // No value and not interrupt cast or crowd control without SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY flag
- if (!effect->CalcValue() && !((effect->Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfoMutable->HasAttribute(SPELL_ATTR0_CU_AURA_CC)) && !spellInfoMutable->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)))
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE:
+ case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
+ case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
+ case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
+ case SPELL_EFFECT_TRIGGER_SPELL:
+ case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE:
break;
+ case SPELL_EFFECT_PERSISTENT_AREA_AURA:
+ case SPELL_EFFECT_APPLY_AURA:
+ case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
+ case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
+ case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
+ case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
+ case SPELL_EFFECT_APPLY_AREA_AURA_PET:
+ case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
+ case SPELL_EFFECT_APPLY_AURA_ON_PET:
+ case SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS:
+ case SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM:
+ if (spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT ||
+ spellEffectInfo.ApplyAuraName == SPELL_AURA_DUMMY ||
+ spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_LEECH ||
+ spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL ||
+ spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY)
+ break;
+ /* fallthrough */
+ default:
+ {
+ // No value and not interrupt cast or crowd control without SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY flag
+ if (!spellEffectInfo.CalcValue() && !((spellEffectInfo.Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfoMutable->HasAttribute(SPELL_ATTR0_CU_AURA_CC)) && !spellInfoMutable->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)))
+ break;
- // Sindragosa Frost Breath
- if (spellInfoMutable->Id == 69649 || spellInfoMutable->Id == 71056 || spellInfoMutable->Id == 71057 || spellInfoMutable->Id == 71058 || spellInfoMutable->Id == 73061 || spellInfoMutable->Id == 73062 || spellInfoMutable->Id == 73063 || spellInfoMutable->Id == 73064)
- break;
+ // Sindragosa Frost Breath
+ if (spellInfoMutable->Id == 69649 || spellInfoMutable->Id == 71056 || spellInfoMutable->Id == 71057 || spellInfoMutable->Id == 71058 || spellInfoMutable->Id == 73061 || spellInfoMutable->Id == 73062 || spellInfoMutable->Id == 73063 || spellInfoMutable->Id == 73064)
+ break;
- // Frostbolt
- if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfoMutable->SpellFamilyFlags[0] & 0x20))
- break;
+ // Frostbolt
+ if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfoMutable->SpellFamilyFlags[0] & 0x20))
+ break;
- // Frost Fever
- if (spellInfoMutable->Id == 55095)
- break;
+ // Frost Fever
+ if (spellInfoMutable->Id == 55095)
+ break;
- // Haunt
- if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellInfoMutable->SpellFamilyFlags[1] & 0x40000))
- break;
+ // Haunt
+ if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellInfoMutable->SpellFamilyFlags[1] & 0x40000))
+ break;
- setFlag = true;
- break;
- }
+ setFlag = true;
+ break;
+ }
}
if (setFlag)
@@ -3203,18 +3196,15 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
{
bool allNonBinary = true;
bool overrideAttr = false;
- for (SpellEffectInfo const* effect : spellInfoMutable->GetEffects())
+ for (SpellEffectInfo const& spellEffectInfo : spellInfoMutable->GetEffects())
{
- if (!effect)
- continue;
-
- if (effect->IsAura() && effect->TriggerSpell)
+ if (spellEffectInfo.IsAura() && spellEffectInfo.TriggerSpell)
{
- switch (effect->ApplyAuraName)
+ switch (spellEffectInfo.ApplyAuraName)
{
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
- if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE))
+ if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE))
{
overrideAttr = true;
if (triggerSpell->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL))
@@ -3259,14 +3249,13 @@ inline void ApplySpellFix(std::initializer_list<uint32> spellIds, void(*fix)(Spe
inline void ApplySpellEffectFix(SpellInfo* spellInfo, SpellEffIndex effectIndex, void(*fix)(SpellEffectInfo*))
{
- SpellEffectInfo const* effect = spellInfo->GetEffect(effectIndex);
- if (!effect)
+ if (spellInfo->GetEffects().size() <= effectIndex)
{
TC_LOG_ERROR("server.loading", "Spell effect info correction specified for non-existing effect %u of spell %u", uint32(effectIndex), spellInfo->Id);
return;
}
- fix(const_cast<SpellEffectInfo*>(effect));
+ fix(const_cast<SpellEffectInfo*>(&spellInfo->GetEffect(effectIndex)));
}
void SpellMgr::LoadSpellInfoCorrections()
@@ -3427,7 +3416,7 @@ void SpellMgr::LoadSpellInfoCorrections()
{
ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo)
{
- spellEffectInfo->Effect = 0;
+ spellEffectInfo->Effect = SPELL_EFFECT_NONE;
});
});
@@ -3765,7 +3754,7 @@ void SpellMgr::LoadSpellInfoCorrections()
//! HACK: This spell break quest complete for alliance and on retail not used
ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo)
{
- spellEffectInfo->Effect = 0;
+ spellEffectInfo->Effect = SPELL_EFFECT_NONE;
});
});
@@ -4056,7 +4045,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
ApplySpellEffectFix(spellInfo, EFFECT_2, [](SpellEffectInfo* spellEffectInfo)
{
- spellEffectInfo->Effect = 0;
+ spellEffectInfo->Effect = SPELL_EFFECT_NONE;
});
});
@@ -4098,7 +4087,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS WERE NOT IMPLEMENTED WHEN THE SCRIPT WAS WRITTEN
ApplySpellEffectFix(spellInfo, EFFECT_1, [](SpellEffectInfo* spellEffectInfo)
{
- spellEffectInfo->Effect = 0;
+ spellEffectInfo->Effect = SPELL_EFFECT_NONE;
});
});
@@ -4477,7 +4466,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Until we figure out what it's actually used for we disable it.
ApplySpellEffectFix(spellInfo, EFFECT_2, [](SpellEffectInfo* spellEffectInfo)
{
- spellEffectInfo->Effect = 0;
+ spellEffectInfo->Effect = SPELL_EFFECT_NONE;
});
});
@@ -4498,26 +4487,24 @@ void SpellMgr::LoadSpellInfoCorrections()
if (!spellInfo)
continue;
- for (SpellEffectInfo const* effect : spellInfo->GetEffects())
+ // Fix range for trajectory triggered spell
+ for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects())
{
- if (!effect)
- continue;
-
- if (effect->IsEffect() && (effect->TargetA.GetTarget() == TARGET_DEST_TRAJ || effect->TargetB.GetTarget() == TARGET_DEST_TRAJ))
+ if (spellEffectInfo.IsEffect() && (spellEffectInfo.TargetA.GetTarget() == TARGET_DEST_TRAJ || spellEffectInfo.TargetB.GetTarget() == TARGET_DEST_TRAJ))
{
// Get triggered spell if any
- if (SpellInfo* spellInfoTrigger = const_cast<SpellInfo*>(GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE)))
+ for (SpellInfo const& spellInfoTrigger : _GetSpellInfo(spellEffectInfo.TriggerSpell))
{
float maxRangeMain = spellInfo->GetMaxRange();
- float maxRangeTrigger = spellInfoTrigger->GetMaxRange();
+ float maxRangeTrigger = spellInfoTrigger.GetMaxRange();
// check if triggered spell has enough max range to cover trajectory
if (maxRangeTrigger < maxRangeMain)
- spellInfoTrigger->RangeEntry = spellInfo->RangeEntry;
+ const_cast<SpellInfo&>(spellInfoTrigger).RangeEntry = spellInfo->RangeEntry;
}
}
- switch (effect->Effect)
+ switch (spellEffectInfo.Effect)
{
case SPELL_EFFECT_CHARGE:
case SPELL_EFFECT_CHARGE_DEST:
@@ -4527,17 +4514,19 @@ void SpellMgr::LoadSpellInfoCorrections()
if (!spellInfo->Speed && !spellInfo->SpellFamilyName && !spellInfo->HasAttribute(SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
spellInfo->Speed = SPEED_CHARGE;
break;
+ default:
+ break;
}
- if (effect->TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE || effect->TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE)
+ if (spellEffectInfo.TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE || spellEffectInfo.TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE)
if (G3D::fuzzyEq(spellInfo->ConeAngle, 0.f))
spellInfo->ConeAngle = 90.f;
// Area auras may not target area (they're self cast)
- if (effect->IsAreaAuraEffect() && effect->IsTargetingArea())
+ if (spellEffectInfo.IsAreaAuraEffect() && spellEffectInfo.IsTargetingArea())
{
- const_cast<SpellEffectInfo*>(effect)->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- const_cast<SpellEffectInfo*>(effect)->TargetB = SpellImplicitTargetInfo(0);
+ const_cast<SpellEffectInfo&>(spellEffectInfo).TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
+ const_cast<SpellEffectInfo&>(spellEffectInfo).TargetB = SpellImplicitTargetInfo(0);
}
}
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 3012aeffba5..cc397652093 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -118,32 +118,25 @@ bool _SpellScript::EffectHook::IsEffectAffected(SpellInfo const* spellEntry, uin
std::string _SpellScript::EffectHook::EffIndexToString() const
{
- switch (effIndex)
- {
- case EFFECT_ALL:
- return "EFFECT_ALL";
- case EFFECT_FIRST_FOUND:
- return "EFFECT_FIRST_FOUND";
- case EFFECT_0:
- return "EFFECT_0";
- case EFFECT_1:
- return "EFFECT_1";
- case EFFECT_2:
- return "EFFECT_2";
- }
+ if (effIndex == EFFECT_ALL)
+ return "EFFECT_ALL";
+ if (effIndex == EFFECT_FIRST_FOUND)
+ return "EFFECT_FIRST_FOUND";
+ if (effIndex < MAX_SPELL_EFFECTS)
+ return Trinity::StringFormat("EFFECT_%u", uint32(effIndex));
return "Invalid Value";
}
bool _SpellScript::EffectNameCheck::Check(SpellInfo const* spellEntry, uint8 effIndex) const
{
- SpellEffectInfo const* effect = spellEntry->GetEffect(effIndex);
- if (!effect)
+ if (spellEntry->GetEffects().size() <= effIndex)
return false;
- if (!effect->Effect && !effName)
+ SpellEffectInfo const& spellEffectInfo = spellEntry->GetEffect(SpellEffIndex(effIndex));
+ if (!spellEffectInfo.Effect && !effName)
return true;
- if (!effect->Effect)
+ if (!spellEffectInfo.Effect)
return false;
- return (effName == SPELL_EFFECT_ANY) || (effect->Effect == effName);
+ return (effName == SPELL_EFFECT_ANY) || (spellEffectInfo.Effect == effName);
}
std::string _SpellScript::EffectNameCheck::ToString() const
@@ -161,14 +154,14 @@ std::string _SpellScript::EffectNameCheck::ToString() const
bool _SpellScript::EffectAuraNameCheck::Check(SpellInfo const* spellEntry, uint8 effIndex) const
{
- SpellEffectInfo const* effect = spellEntry->GetEffect(effIndex);
- if (!effect)
+ if (spellEntry->GetEffects().size() <= effIndex)
return false;
- if (!effect->ApplyAuraName && !effAurName)
+ SpellEffectInfo const& spellEffectInfo = spellEntry->GetEffect(SpellEffIndex(effIndex));
+ if (!spellEffectInfo.ApplyAuraName && !effAurName)
return true;
- if (!effect->ApplyAuraName)
+ if (!spellEffectInfo.ApplyAuraName)
return false;
- return (effAurName == SPELL_AURA_ANY) || (effect->ApplyAuraName == effAurName);
+ return (effAurName == SPELL_AURA_ANY) || (spellEffectInfo.ApplyAuraName == effAurName);
}
std::string _SpellScript::EffectAuraNameCheck::ToString() const
@@ -270,12 +263,12 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff
if (!targetType)
return false;
- SpellEffectInfo const* effect = spellEntry->GetEffect(effIndexToCheck);
- if (!effect)
+ if (spellEntry->GetEffects().size() <= effIndexToCheck)
return false;
- if (effect->TargetA.GetTarget() != targetType &&
- effect->TargetB.GetTarget() != targetType)
+ SpellEffectInfo const& spellEffectInfo = spellEntry->GetEffect(SpellEffIndex(effIndexToCheck));
+ if (spellEffectInfo.TargetA.GetTarget() != targetType &&
+ spellEffectInfo.TargetB.GetTarget() != targetType)
return false;
SpellImplicitTargetInfo targetInfo(targetType);
@@ -485,6 +478,16 @@ SpellInfo const* SpellScript::GetSpellInfo() const
return m_spell->GetSpellInfo();
}
+SpellEffectInfo const& SpellScript::GetEffectInfo(SpellEffIndex effIndex) const
+{
+ return GetSpellInfo()->GetEffect(effIndex);
+}
+
+SpellValue const* SpellScript::GetSpellValue() const
+{
+ return m_spell->m_spellValue;
+}
+
WorldLocation const* SpellScript::GetExplTargetDest() const
{
if (m_spell->m_targets.HasDst())
@@ -706,11 +709,11 @@ void SpellScript::PreventHitDefaultEffect(SpellEffIndex effIndex)
m_hitPreventDefaultEffectMask |= 1 << effIndex;
}
-SpellEffectInfo const* SpellScript::GetEffectInfo() const
+SpellEffectInfo const& SpellScript::GetEffectInfo() const
{
ASSERT(IsInEffectHook(), "Script: `%s` Spell: `%u`: function SpellScript::GetEffectInfo was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
- return m_spell->effectInfo;
+ return *m_spell->effectInfo;
}
int32 SpellScript::GetEffectValue() const
@@ -772,16 +775,6 @@ Difficulty SpellScript::GetCastDifficulty() const
return m_spell->GetCastDifficulty();
}
-SpellValue const* SpellScript::GetSpellValue() const
-{
- return m_spell->m_spellValue;
-}
-
-SpellEffectInfo const* SpellScript::GetEffectInfo(SpellEffIndex effIndex) const
-{
- return GetSpellInfo()->GetEffect(effIndex);
-}
-
bool AuraScript::_Validate(SpellInfo const* entry)
{
for (auto itr = DoCheckAreaTarget.begin(); itr != DoCheckAreaTarget.end(); ++itr)
@@ -1154,6 +1147,11 @@ SpellInfo const* AuraScript::GetSpellInfo() const
return m_aura->GetSpellInfo();
}
+SpellEffectInfo const& AuraScript::GetEffectInfo(SpellEffIndex effIndex) const
+{
+ return m_aura->GetSpellInfo()->GetEffect(effIndex);
+}
+
uint32 AuraScript::GetId() const
{
return m_aura->GetId();
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index e4c3cca9387..b217764b552 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -413,8 +413,8 @@ class TC_GAME_API SpellScript : public _SpellScript
GameObject* GetGObjCaster() const;
Unit* GetOriginalCaster() const;
SpellInfo const* GetSpellInfo() const;
+ SpellEffectInfo const& GetEffectInfo(SpellEffIndex effIndex) const;
SpellValue const* GetSpellValue() const;
- SpellEffectInfo const* GetEffectInfo(SpellEffIndex effIndex) const;
// methods useable after spell is prepared
// accessors to the explicit targets of the spell
@@ -490,7 +490,7 @@ class TC_GAME_API SpellScript : public _SpellScript
void PreventHitDefaultEffect(SpellEffIndex effIndex);
// method available only in EffectHandler method
- SpellEffectInfo const* GetEffectInfo() const;
+ SpellEffectInfo const& GetEffectInfo() const;
int32 GetEffectValue() const;
void SetEffectValue(int32 value);
@@ -927,6 +927,7 @@ class TC_GAME_API AuraScript : public _SpellScript
// returns proto of the spell
SpellInfo const* GetSpellInfo() const;
+ SpellEffectInfo const& GetEffectInfo(SpellEffIndex effIndex) const;
// returns spellid of the spell
uint32 GetId() const;