aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp371
-rw-r--r--src/server/game/Entities/Unit/Unit.h8
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp161
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h26
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp238
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h52
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/Spells/Spell.h10
-rw-r--r--src/server/game/Spells/SpellEffects.cpp400
-rw-r--r--src/server/game/Spells/SpellInfo.cpp425
-rw-r--r--src/server/game/Spells/SpellInfo.h20
11 files changed, 810 insertions, 905 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 89ded594990..d8ba3a8e6d7 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1427,10 +1427,10 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s
return false;
// bleeding effects are not reduced by armor
- if (effIndex != MAX_SPELL_EFFECTS)
+ if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), effIndex))
{
- if (spellInfo->Effects[effIndex].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
- spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
+ if (effect->ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
+ effect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
if (spellInfo->GetEffectMechanicMask(effIndex) & (1<<MECHANIC_BLEED))
return false;
}
@@ -1696,7 +1696,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
int32 manaReduction = currentAbsorb;
// lower absorb amount by talents
- if (float manaMultiplier = absorbAurEff->GetSpellInfo()->Effects[absorbAurEff->GetEffIndex()].CalcValueMultiplier(absorbAurEff->GetCaster()))
+ if (float manaMultiplier = absorbAurEff->GetSpellEffectInfo()->CalcValueMultiplier(absorbAurEff->GetCaster()))
manaReduction = int32(float(manaReduction) * manaMultiplier);
int32 manaTaken = -victim->ModifyPower(POWER_MANA, -manaReduction);
@@ -2166,12 +2166,12 @@ int32 Unit::GetMechanicResistChance(SpellInfo const* spellInfo) const
return 0;
int32 resistMech = 0;
- for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if (!spellInfo->Effects[eff].IsEffect())
+ if (!effect || !effect->IsEffect())
break;
- int32 effectMech = spellInfo->GetEffectMechanic(eff);
+ int32 effectMech = spellInfo->GetEffectMechanic(effect->EffectIndex, GetMap()->GetDifficulty());
if (effectMech)
{
int32 temp = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effectMech);
@@ -2990,7 +2990,7 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
-Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= 0*/)
+Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= 0*/)
{
ASSERT(!casterGUID.IsEmpty() || caster);
@@ -3016,25 +3016,25 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8
return NULL;
// update basepoints with new values - effect amount will be recalculated in ModStackAmount
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : foundAura->GetSpellEffectInfos())
{
- if (!foundAura->HasEffect(i))
+ if (!effect)
continue;
int bp;
if (baseAmount)
- bp = *(baseAmount + i);
+ bp = *(baseAmount + effect->EffectIndex);
else
- bp = foundAura->GetSpellInfo()->Effects[i].BasePoints;
+ bp = effect->BasePoints;
- int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(i)->m_baseAmount));
+ int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(effect->EffectIndex)->GetBaseAmount())); // todo 6.x review GetBaseAmount and GetCastItemGUID in this case
*oldBP = bp;
}
// correct cast item guid if needed
if (castItemGUID != foundAura->GetCastItemGUID())
{
- ObjectGuid* oldGUID = const_cast<ObjectGuid*>(&foundAura->m_castItemGuid);
+ ObjectGuid* oldGUID = const_cast<ObjectGuid*>(&foundAura->GetCastItemGUID());
*oldGUID = castItemGUID;
}
@@ -3087,7 +3087,7 @@ void Unit::_AddAura(UnitAura* aura, Unit* caster)
// creates aura application instance and registers it in lists
// aura application effects are handled separately to prevent aura list corruption
-AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint8 effMask)
+AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint32 effMask)
{
// can't apply aura on unit which is going to be deleted - to not create a memory leak
ASSERT(!m_cleanupDone);
@@ -3278,7 +3278,7 @@ void Unit::_RemoveNoStackAurasDueToAura(Aura* aura)
SpellInfo const* spellProto = aura->GetSpellInfo();
// passive spell special case (only non stackable with ranks)
- if (spellProto->IsPassiveStackableWithRanks())
+ if (spellProto->IsPassiveStackableWithRanks(GetMap()->GetDifficulty()))
return;
if (!IsHighestExclusiveAura(aura))
@@ -4196,9 +4196,9 @@ bool Unit::HasAuraWithMechanic(uint32 mechanicMask) const
if (spellInfo->Mechanic && (mechanicMask & (1 << spellInfo->Mechanic)))
return true;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (iter->second->HasEffect(i) && spellInfo->Effects[i].Effect && spellInfo->Effects[i].Mechanic)
- if (mechanicMask & (1 << spellInfo->Effects[i].Mechanic))
+ for (SpellEffectInfo const* effect : iter->second->GetBase()->GetSpellEffectInfos())
+ if (effect && effect->Effect && effect->Mechanic)
+ if (mechanicMask & (1 << effect->Mechanic))
return true;
}
@@ -4934,13 +4934,17 @@ bool Unit::HandleAuraProcOnPowerAmount(Unit* victim, uint32 /*damage*/, AuraEffe
// Get effect index used for the proc
uint32 effIndex = triggeredByAura->GetEffIndex();
+ SpellEffectInfo const* effect = triggeredByAura->GetSpellEffectInfo();
+ if (!effect)
+ return false;
+
// Power amount required to proc the spell
int32 powerAmountRequired = triggeredByAura->GetAmount();
// Power type required to proc
- Powers powerRequired = Powers(auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].MiscValue);
+ Powers powerRequired = Powers(effect->MiscValue);
// Set trigger spell id, target, custom basepoints
- uint32 trigger_spell_id = auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
+ uint32 trigger_spell_id = effect->TriggerSpell;
Unit* target = NULL;
int32 basepoints0 = 0;
@@ -5616,18 +5620,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 28810;
break;
}
- // Priest T10 Healer 2P Bonus
- case 70770:
- // Flash Heal
- if (procSpell->SpellFamilyFlags[0] & 0x800)
- {
- triggered_spell_id = 70772;
- SpellInfo const* blessHealing = sSpellMgr->GetSpellInfo(triggered_spell_id);
- if (!blessHealing)
- return false;
- basepoints0 = int32(CalculatePct(damage, triggerAmount) / (blessHealing->GetMaxDuration() / blessHealing->Effects[0].ApplyAuraPeriod));
- }
- break;
+ break;
}
break;
}
@@ -5745,7 +5738,10 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!triggeredSpell)
return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].ApplyAuraPeriod);
+ SpellEffectInfo const* effect = triggeredSpell->GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (!effect)
+ return false;
+ basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / effect->ApplyAuraPeriod);
// Add remaining ticks to damage done
basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
}
@@ -6129,7 +6125,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!triggeredSpell)
return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].ApplyAuraPeriod);
+ if (SpellEffectInfo const* effect = triggeredSpell->GetEffect(DIFFICULTY_NONE, EFFECT_0))
+ basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / effect->ApplyAuraPeriod);
}
break;
}
@@ -6143,9 +6140,12 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!triggeredSpell)
return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].ApplyAuraPeriod);
- // Add remaining ticks to healing done
- basepoints0 += GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_HEAL);
+ if (SpellEffectInfo const* effect = triggeredSpell->GetEffect(DIFFICULTY_NONE, EFFECT_0))
+ {
+ basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / effect->ApplyAuraPeriod);
+ // Add remaining ticks to healing done
+ basepoints0 += GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_HEAL);
+ }
}
break;
}
@@ -6187,53 +6187,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 63685;
break;
}
- // Flametongue Weapon (Passive)
- if (dummySpell->SpellFamilyFlags[0] & 0x200000)
- {
- if (GetTypeId() != TYPEID_PLAYER || !victim || !victim->IsAlive() || !castItem || !castItem->IsEquipped())
- return false;
-
- WeaponAttackType attType = WeaponAttackType(Player::GetAttackBySlot(castItem->GetSlot()));
- if ((attType != BASE_ATTACK && attType != OFF_ATTACK)
- || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
- || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK))
- return false;
-
- float fire_onhit = float(CalculatePct(dummySpell->Effects[EFFECT_0]. CalcValue(), 1.0f));
-
- float add_spellpower = (float)(SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE)
- + victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE));
-
- // 1.3speed = 5%, 2.6speed = 10%, 4.0 speed = 15%, so, 1.0speed = 3.84%
- ApplyPct(add_spellpower, 3.84f);
-
- // Enchant on Off-Hand and ready?
- if (castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
- {
- float BaseWeaponSpeed = GetAttackTime(OFF_ATTACK) / 1000.0f;
-
- // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed
- basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed));
- triggered_spell_id = 10444;
- }
-
- // Enchant on Main-Hand and ready?
- else if (castItem->GetSlot() == EQUIPMENT_SLOT_MAINHAND && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)
- {
- float BaseWeaponSpeed = GetAttackTime(BASE_ATTACK) / 1000.0f;
-
- // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed
- basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed));
- triggered_spell_id = 10444;
- }
-
- // If not ready, we should return, shouldn't we?!
- else
- return false;
-
- CastCustomSpell(victim, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- return true;
- }
// Static Shock
if (dummySpell->SpellIconID == 3059)
{
@@ -6255,15 +6208,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
case SPELLFAMILY_DEATHKNIGHT:
{
- // Blood-Caked Blade
- if (dummySpell->SpellIconID == 138)
- {
- if (!target || !target->IsAlive())
- return false;
-
- triggered_spell_id = dummySpell->Effects[effIndex].TriggerSpell;
- break;
- }
// Dancing Rune Weapon
if (dummySpell->Id == 49028)
{
@@ -6289,24 +6233,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
else
return false;
}
- // Unholy Blight
- if (dummySpell->Id == 49194)
- {
- triggered_spell_id = 50536;
- SpellInfo const* unholyBlight = sSpellMgr->GetSpellInfo(triggered_spell_id);
- if (!unholyBlight)
- return false;
-
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
-
- //Glyph of Unholy Blight
- if (AuraEffect* glyph=GetAuraEffect(63332, 0))
- AddPct(basepoints0, glyph->GetAmount());
-
- basepoints0 = basepoints0 / (unholyBlight->GetMaxDuration() / unholyBlight->Effects[0].ApplyAuraPeriod);
- basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
- break;
- }
// Threat of Thassarian
if (dummySpell->SpellIconID == 2023)
{
@@ -6347,26 +6273,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
case SPELLFAMILY_PET:
{
- switch (dummySpell->SpellIconID)
- {
- // Guard Dog
- case 201:
- {
- if (!victim)
- return false;
-
- triggered_spell_id = 54445;
- target = this;
- float addThreat = float(CalculatePct(procSpell->Effects[0].CalcValue(this), triggerAmount));
- victim->AddThreat(this, addThreat);
- break;
- }
- // Silverback
- case 1582:
- triggered_spell_id = dummySpell->Id == 62765 ? 62801 : 62800;
- target = this;
- break;
- }
break;
}
default:
@@ -6375,7 +6281,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// if not handled by custom case, get triggered spell from dummySpell proto
if (!triggered_spell_id)
- triggered_spell_id = dummySpell->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
+ triggered_spell_id = triggeredByAura->GetSpellEffectInfo()->TriggerSpell;
// processed charge only counting case
if (!triggered_spell_id)
@@ -6459,9 +6365,12 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
// Swift Hand of Justice
case 59906:
{
- int32 bp0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_0]. CalcValue());
- CastCustomSpell(this, 59913, &bp0, NULL, NULL, true);
- *handled = true;
+ if (SpellEffectInfo const* effect = triggeredByAura->GetSpellEffectInfo(EFFECT_0))
+ {
+ int32 bp0 = CalculatePct(GetMaxHealth(), effect->CalcValue());
+ CastCustomSpell(this, 59913, &bp0, NULL, NULL, true);
+ *handled = true;
+ }
break;
}
}
@@ -6476,49 +6385,10 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
CastSpell(victim, 68055, true);
return true;
}
- // Glyph of Divinity
- else if (dummySpell->Id == 54939)
- {
- if (!procSpell)
- return false;
- *handled = true;
- // Check if we are the target and prevent mana gain
- if (victim && triggeredByAura->GetCasterGUID() == victim->GetGUID())
- return false;
- // Lookup base amount mana restore
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
- {
- if (procSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
- {
- // value multiplied by 2 because you should get twice amount
- int32 mana = procSpell->Effects[i].CalcValue() * 2;
- CastCustomSpell(this, 54986, 0, &mana, NULL, true);
- }
- }
- return true;
- }
break;
}
case SPELLFAMILY_MAGE:
{
- switch (dummySpell->Id)
- {
- // Empowered Fire
- case 31656:
- case 31657:
- case 31658:
- {
- *handled = true;
-
- SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(67545);
- if (!spInfo)
- return false;
-
- int32 bp0 = int32(CalculatePct(GetCreateMana(), spInfo->Effects[0].CalcValue()));
- CastCustomSpell(this, 67545, &bp0, NULL, NULL, true, NULL, triggeredByAura->GetEffect(EFFECT_0), GetGUID());
- return true;
- }
- }
break;
}
case SPELLFAMILY_DEATHKNIGHT:
@@ -6603,8 +6473,11 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
// Item - Warrior T10 Protection 4P Bonus
case 70844:
{
- int32 basepoints0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_1]. CalcValue());
- CastCustomSpell(this, 70845, &basepoints0, NULL, NULL, true);
+ if (SpellEffectInfo const* effect = triggeredByAura->GetSpellEffectInfo(EFFECT_1))
+ {
+ int32 basepoints0 = CalculatePct(GetMaxHealth(), effect->CalcValue());
+ CastCustomSpell(this, 70845, &basepoints0, NULL, NULL, true);
+ }
break;
}
// Recklessness
@@ -6635,7 +6508,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
int32 triggerAmount = triggeredByAura->GetAmount();
// Set trigger spell id, target, custom basepoints
- uint32 trigger_spell_id = auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
+ uint32 trigger_spell_id = triggeredByAura->GetSpellEffectInfo()->TriggerSpell;
Unit* target = NULL;
int32 basepoints0 = 0;
@@ -6655,11 +6528,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
case SPELLFAMILY_GENERIC:
switch (auraSpellInfo->Id)
{
- case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
- // Pct value stored in dummy
- basepoints0 = victim->GetCreateHealth() * auraSpellInfo->Effects[1].CalcValue() / 100;
- target = victim;
- break;
case 57345: // Darkmoon Card: Greatness
{
float stat = 0.0f;
@@ -6760,19 +6628,9 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
case SPELLFAMILY_HUNTER:
{
- if (auraSpellInfo->SpellIconID == 3247) // Piercing Shots
+ /*if (auraSpellInfo->SpellIconID == 3247) // Piercing Shots
{
- switch (auraSpellInfo->Id)
- {
- case 53234: // Rank 1
- case 53237: // Rank 2
- case 53238: // Rank 3
- trigger_spell_id = 63468;
- break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u miss posibly Piercing Shots", auraSpellInfo->Id);
- return false;
- }
+ trigger_spell_id = 63468; // 6.x missing from dbc but it is in the tooltip
SpellInfo const* TriggerPS = sSpellMgr->GetSpellInfo(trigger_spell_id);
if (!TriggerPS)
return false;
@@ -6780,7 +6638,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
basepoints0 = CalculatePct(int32(damage), triggerAmount) / (TriggerPS->GetMaxDuration() / TriggerPS->Effects[0].ApplyAuraPeriod);
basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), trigger_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
break;
- }
+ }*/
// Item - Hunter T9 4P Bonus
if (auraSpellInfo->Id == 67151)
{
@@ -6983,10 +6841,9 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
break;
}
// Decimation
- case 63156:
- case 63158:
+ case 108869:
// Can proc only if target has hp below 25%
- if (!victim || !victim->HealthBelowPct(auraSpellInfo->Effects[EFFECT_1].CalcValue()))
+ if (!victim || !victim->HealthBelowPct(triggeredByAura->GetSpellEffectInfo()->CalcValue()))
return false;
break;
// Deathbringer Saurfang - Blood Beast's Blood Link
@@ -7961,14 +7818,14 @@ void Unit::SetMinion(Minion *minion, bool apply)
else if (minion->IsTotem())
{
// All summoned by totem minions must disappear when it is removed.
- if (SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(minion->ToTotem()->GetSpell()))
- for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
- if (spInfo->Effects[i].Effect != SPELL_EFFECT_SUMMON)
- continue;
+ if (SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(minion->ToTotem()->GetSpell()))
+ for (SpellEffectInfo const* effect : spInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
+ {
+ if (!effect || effect->Effect != SPELL_EFFECT_SUMMON)
+ continue;
- RemoveAllMinionsByEntry(spInfo->Effects[i].MiscValue);
- }
+ RemoveAllMinionsByEntry(effect->MiscValue);
+ }
}
if (GetTypeId() == TYPEID_PLAYER)
@@ -8462,32 +8319,11 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
}
// Custom scripted damage
- switch (spellProto->SpellFamilyName)
+ /*switch (spellProto->SpellFamilyName)
{
case SPELLFAMILY_DEATHKNIGHT:
- // Impurity (dummy effect)
- if (GetTypeId() == TYPEID_PLAYER)
- {
- PlayerSpellMap playerSpells = ToPlayer()->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = playerSpells.begin(); itr != playerSpells.end(); ++itr)
- {
- if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
- continue;
- switch (itr->first)
- {
- case 49220:
- case 49633:
- case 49635:
- case 49636:
- case 49638:
- if (SpellInfo const* proto = sSpellMgr->GetSpellInfo(itr->first))
- AddPct(ApCoeffMod, proto->Effects[0].CalcValue());
- break;
- }
- }
- }
break;
- }
+ }*/
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
@@ -9236,9 +9072,11 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- switch (spellProto->Effects[i].ApplyAuraName)
+ if (!effect)
+ continue;
+ switch (effect->ApplyAuraName)
{
// Bonus healing does not apply to these spells
case SPELL_AURA_PERIODIC_LEECH:
@@ -9246,7 +9084,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal = 0;
break;
}
- if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
+ if (effect->Effect == SPELL_EFFECT_HEALTH_LEECH)
DoneTotal = 0;
}
@@ -9401,17 +9239,19 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectingSpell(spellProto))
AddPct(TakenTotalMod, (*i)->GetAmount());
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- switch (spellProto->Effects[i].ApplyAuraName)
+ if (!effect)
+ continue;
+ switch (effect->ApplyAuraName)
{
// Bonus healing does not apply to these spells
- case SPELL_AURA_PERIODIC_LEECH:
- case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
- TakenTotal = 0;
- break;
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
+ TakenTotal = 0;
+ break;
}
- if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
+ if (effect->Effect == SPELL_EFFECT_HEALTH_LEECH)
TakenTotal = 0;
}
@@ -9444,7 +9284,7 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
for (AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i)
{
// stat used dependent from misc value (stat index)
- Stats usedStat = Stats((*i)->GetSpellInfo()->Effects[(*i)->GetEffIndex()].MiscValue);
+ Stats usedStat = Stats((*i)->GetSpellEffectInfo()->MiscValue);
advertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount()));
}
@@ -16693,43 +16533,40 @@ int32 Unit::GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEf
bool Unit::IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplications /*= false*/)
{
- for (uint32 i = 0 ; i < MAX_SPELL_EFFECTS; ++i)
+ for (AuraEffect* aurEff : aura->GetAuraEffects())
{
- if (AuraEffect const* aurEff = aura->GetEffect(i))
+ AuraType const auraType = AuraType(aurEff->GetSpellEffectInfo()->ApplyAuraName);
+ AuraEffectList const& auras = GetAuraEffectsByType(auraType);
+ for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end();)
{
- AuraType const auraType = AuraType(aura->GetSpellInfo()->Effects[i].ApplyAuraName);
- AuraEffectList const& auras = GetAuraEffectsByType(auraType);
- for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end();)
+ AuraEffect const* existingAurEff = (*itr);
+ ++itr;
+
+ if (sSpellMgr->CheckSpellGroupStackRules(aura->GetSpellInfo(), existingAurEff->GetSpellInfo())
+ == SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST)
{
- AuraEffect const* existingAurEff = (*itr);
- ++itr;
+ int32 diff = abs(aurEff->GetAmount()) - abs(existingAurEff->GetAmount());
+ if (!diff)
+ diff = int32(aura->GetEffectMask()) - int32(existingAurEff->GetBase()->GetEffectMask());
- if (sSpellMgr->CheckSpellGroupStackRules(aura->GetSpellInfo(), existingAurEff->GetSpellInfo())
- == SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST)
+ if (diff > 0)
{
- int32 diff = abs(aurEff->GetAmount()) - abs(existingAurEff->GetAmount());
- if (!diff)
- diff = int32(aura->GetEffectMask()) - int32(existingAurEff->GetBase()->GetEffectMask());
-
- if (diff > 0)
+ Aura const* base = existingAurEff->GetBase();
+ // no removing of area auras from the original owner, as that completely cancels them
+ if (removeOtherAuraApplications && (!base->IsArea() || base->GetOwner() != this))
{
- Aura const* base = existingAurEff->GetBase();
- // no removing of area auras from the original owner, as that completely cancels them
- if (removeOtherAuraApplications && (!base->IsArea() || base->GetOwner() != this))
+ if (AuraApplication* aurApp = existingAurEff->GetBase()->GetApplicationOfTarget(GetGUID()))
{
- if (AuraApplication* aurApp = existingAurEff->GetBase()->GetApplicationOfTarget(GetGUID()))
- {
- bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType);
- uint32 removedAuras = m_removedAurasCount;
- RemoveAura(aurApp);
- if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
- itr = auras.begin();
- }
+ bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType);
+ uint32 removedAuras = m_removedAurasCount;
+ RemoveAura(aurApp);
+ if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
+ itr = auras.begin();
}
}
- else if (diff < 0)
- return false;
}
+ else if (diff < 0)
+ return false;
}
}
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index f075578621a..5ff4bede241 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1760,11 +1760,11 @@ class Unit : public WorldObject
bool InitTamedPet(Pet* pet, uint8 level, uint32 spell_id);
// aura apply/remove helpers - you should better not use these
- Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
+ Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
void _AddAura(UnitAura* aura, Unit* caster);
- AuraApplication * _CreateAuraApplication(Aura* aura, uint8 effMask);
+ AuraApplication * _CreateAuraApplication(Aura* aura, uint32 effMask);
void _ApplyAuraEffect(Aura* aura, uint8 effIndex);
- void _ApplyAura(AuraApplication * aurApp, uint8 effMask);
+ void _ApplyAura(AuraApplication * aurApp, uint32 effMask);
void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
void _UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode);
void _RemoveNoStackAuraApplicationsDueToAura(Aura* aura);
@@ -2058,7 +2058,7 @@ class Unit : public WorldObject
bool IsImmunedToDamage(SpellInfo const* spellInfo) const;
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // redefined in Creature
- static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS);
+ bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS);
uint32 CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK);
uint32 CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) const;
void CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo = NULL);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index c55c92d296e..10221f61c71 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -431,13 +431,17 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //370 SPELL_AURA_SET_FAIR_FAR_CLIP
};
-AuraEffect::AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* caster):
+AuraEffect::AuraEffect(Aura* base, uint32 effIndex, int32 baseAmount, Unit* caster) :
m_base(base), m_spellInfo(base->GetSpellInfo()),
-m_baseAmount(baseAmount ? *baseAmount : m_spellInfo->Effects[effIndex].BasePoints),
+m_baseAmount(baseAmount),
m_damage(0), m_critChance(0.0f), m_donePct(1.0f),
m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex),
m_canBeRecalculated(true), m_isPeriodic(false)
{
+ _effectInfo = base->GetSpellEffectInfo(effIndex);
+
+ ASSERT(_effectInfo);
+
CalculatePeriodic(caster, true, false);
m_amount = CalculateAmount(caster);
@@ -476,10 +480,10 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
// default amount calculation
int32 amount = 0;
- if (!(m_spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(m_spellInfo->Effects[m_effIndex].BonusCoefficient, 0.0f))
- amount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit());
+ if (!(m_spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(GetSpellEffectInfo()->BonusCoefficient, 0.0f))
+ amount = GetSpellEffectInfo()->CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit());
else if (caster && caster->GetTypeId() == TYPEID_PLAYER)
- amount = int32(caster->GetFloatValue(PLAYER_MASTERY) * m_spellInfo->Effects[m_effIndex].BonusCoefficient);
+ amount = int32(caster->GetFloatValue(PLAYER_MASTERY) * GetSpellEffectInfo()->BonusCoefficient);
// check item enchant aura cast
if (!amount && caster)
@@ -604,7 +608,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= true*/, bool load /*= false*/)
{
- m_period = m_spellInfo->Effects[m_effIndex].ApplyAuraPeriod;
+ m_period = GetSpellEffectInfo()->ApplyAuraPeriod;
// prepare periodics
switch (GetAuraType())
@@ -694,7 +698,7 @@ void AuraEffect::CalculateSpellMod()
m_spellmod->type = SpellModType(uint32(GetAuraType())); // SpellModType value == spell aura types
m_spellmod->spellId = GetId();
- m_spellmod->mask = GetSpellInfo()->Effects[GetEffIndex()].SpellClassMask;
+ m_spellmod->mask = GetSpellEffectInfo()->SpellClassMask;
m_spellmod->charges = GetBase()->GetCharges();
}
m_spellmod->value = GetAmount();
@@ -1021,7 +1025,7 @@ bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
return false;
// Check EffectClassMask
- if (m_spellInfo->Effects[m_effIndex].SpellClassMask & spell->SpellFamilyFlags)
+ if (GetSpellEffectInfo()->SpellClassMask & spell->SpellFamilyFlags)
return true;
return false;
}
@@ -1114,7 +1118,7 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
void AuraEffect::CleanupTriggeredSpells(Unit* target)
{
- uint32 tSpellId = m_spellInfo->Effects[GetEffIndex()].TriggerSpell;
+ uint32 tSpellId = GetSpellEffectInfo()->TriggerSpell;
if (!tSpellId)
return;
@@ -1127,8 +1131,8 @@ void AuraEffect::CleanupTriggeredSpells(Unit* target)
// needed for spell 43680, maybe others
/// @todo is there a spell flag, which can solve this in a more sophisticated way?
- if (m_spellInfo->Effects[GetEffIndex()].ApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
- uint32(m_spellInfo->GetDuration()) == m_spellInfo->Effects[GetEffIndex()].ApplyAuraPeriod)
+ if (GetSpellEffectInfo()->ApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
+ uint32(m_spellInfo->GetDuration()) == GetSpellEffectInfo()->ApplyAuraPeriod)
return;
target->RemoveAurasDueToSpell(tSpellId, GetCasterGUID());
@@ -1268,30 +1272,6 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
target->CastSpell(target, 24932, true, NULL, this);
}
- // Heart of the Wild
- if (AuraEffect const* heartOfTheWild = target->GetAuraEffectOfRankedSpell(17003, EFFECT_0))
- {
- uint32 heartOfTheWildSpellId = 0;
- int32 heartOfTheWildAmount = 0;
-
- switch (GetMiscValue())
- {
- case FORM_CAT:
- heartOfTheWildSpellId = 24900;
- heartOfTheWildAmount = heartOfTheWild->GetSpellInfo()->Effects[EFFECT_1].CalcValue();
- break;
- case FORM_BEAR:
- heartOfTheWildSpellId = 24899;
- heartOfTheWildAmount = heartOfTheWild->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
- break;
- default:
- break;
- }
-
- if (heartOfTheWildSpellId)
- target->CastCustomSpell(target, heartOfTheWildSpellId, &heartOfTheWildAmount, NULL, NULL, true, NULL, this);
- }
-
switch (GetMiscValue())
{
case FORM_CAT:
@@ -1327,12 +1307,6 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
int32 bp = aurEff->GetAmount();
target->CastCustomSpell(target, 48418, &bp, NULL, NULL, true);
}
- // Survival of the Fittest
- if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DRUID, 961, EFFECT_0))
- {
- int32 bp = aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster());
- target->CastCustomSpell(target, 62069, &bp, NULL, NULL, true, 0, this);
- }
break;
case FORM_MOONKIN:
// Master Shapeshifter - Moonkin
@@ -2594,9 +2568,8 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
vehicleId = creatureInfo->VehicleId;
//some spell has one aura of mount and one of vehicle
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (GetSpellInfo()->Effects[i].Effect == SPELL_EFFECT_SUMMON
- && GetSpellInfo()->Effects[i].MiscValue == GetMiscValue())
+ for (SpellEffectInfo const* effect : GetBase()->GetSpellEffectInfos())
+ if (effect && effect->Effect == SPELL_EFFECT_SUMMON && effect->MiscValue == GetMiscValue())
displayId = 0;
}
@@ -4598,8 +4571,9 @@ 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)
- mask |= (*i)->m_spellInfo->Effects[(*i)->m_effIndex].SpellClassMask;
+ for (Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
+ if (SpellEffectInfo const* effect = (*i)->GetSpellEffectInfo())
+ mask |= effect->SpellClassMask;
target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]);
target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]);
@@ -5021,11 +4995,11 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
if (GetAmount() <= 0)
return;
- if (GetSpellInfo()->Effects[m_effIndex].ItemType == 0)
+ if (GetSpellEffectInfo()->ItemType == 0)
return;
// Soul Shard
- if (GetSpellInfo()->Effects[m_effIndex].ItemType == 6265)
+ if (GetSpellEffectInfo()->ItemType == 6265)
{
// Soul Shard only from units that grant XP or honor
if (!plCaster->isHonorOrXPTarget(target) ||
@@ -5038,16 +5012,16 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
uint32 count = m_amount;
ItemPosCountVec dest;
- InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellInfo()->Effects[m_effIndex].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, NULL, NULL, GetSpellInfo()->Effects[m_effIndex].ItemType);
+ plCaster->SendEquipError(msg, NULL, NULL, GetSpellEffectInfo()->ItemType);
if (count == 0)
return;
}
- Item* newitem = plCaster->StoreNewItem(dest, GetSpellInfo()->Effects[m_effIndex].ItemType, true);
+ Item* newitem = plCaster->StoreNewItem(dest, GetSpellEffectInfo()->ItemType, true);
if (!newitem)
{
plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
@@ -5186,19 +5160,19 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
{
Unit* target = aurApp->GetTarget();
- uint32 triggeredSpellId = sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->Effects[m_effIndex].TriggerSpell, target);
+ uint32 triggeredSpellId = GetSpellEffectInfo()->TriggerSpell;
SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggeredSpellId);
if (!triggeredSpellInfo)
return;
+ Unit* caster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? GetCaster() : target;
+ if (!caster)
+ return;
+
if (mode & AURA_EFFECT_HANDLE_REAL)
{
if (apply)
{
- Unit* caster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCaster() : target;
-
- if (!caster)
- return;
// If amount avalible cast with basepoints (Crypt Fever for example)
if (GetAmount())
caster->CastCustomSpell(target, triggeredSpellId, &m_amount, NULL, NULL, true, NULL, this);
@@ -5207,13 +5181,13 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
}
else
{
- ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCasterGUID() : target->GetGUID();
+ ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficulty()) ? GetCasterGUID() : target->GetGUID();
target->RemoveAura(triggeredSpellId, casterGUID, 0, aurApp->GetRemoveMode());
}
}
else if (mode & AURA_EFFECT_HANDLE_REAPPLY && apply)
{
- ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCasterGUID() : target->GetGUID();
+ ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficulty()) ? GetCasterGUID() : target->GetGUID();
// change the stack amount to be equal to stack amount of our aura
if (Aura* triggeredAura = target->GetAura(triggeredSpellId, casterGUID))
triggeredAura->ModStackAmount(GetBase()->GetStackAmount() - triggeredAura->GetStackAmount());
@@ -5384,7 +5358,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
}
case 62292: // Blaze (Pool of Tar)
// should we use custom damage?
- target->CastSpell((Unit*)NULL, m_spellInfo->Effects[m_effIndex].TriggerSpell, true);
+ target->CastSpell((Unit*)NULL, GetSpellEffectInfo()->TriggerSpell, true);
break;
case 62399: // Overload Circuit
if (target->GetMap()->IsDungeon() && int(target->GetAppliedAuras().count(62399)) >= (target->GetMap()->IsHeroic() ? 4 : 2))
@@ -5408,7 +5382,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
// Mirror Image
if (GetId() == 55342)
// Set name of summons to name of caster
- target->CastSpell((Unit*)NULL, m_spellInfo->Effects[m_effIndex].TriggerSpell, true);
+ target->CastSpell((Unit*)NULL, GetSpellEffectInfo()->TriggerSpell, true);
break;
}
case SPELLFAMILY_DRUID:
@@ -5501,7 +5475,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) const
{
// generic casting code with custom spells and target/caster customs
- uint32 triggerSpellId = GetSpellInfo()->Effects[GetEffIndex()].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId);
SpellInfo const* auraSpellInfo = GetSpellInfo();
@@ -5765,7 +5739,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
if (triggeredSpellInfo)
{
- if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
+ if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? caster : target)
{
triggerCaster->CastSpell(target, triggeredSpellInfo, true, NULL, this);
TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
@@ -5782,10 +5756,10 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit* caster) const
{
- uint32 triggerSpellId = GetSpellInfo()->Effects[m_effIndex].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
- if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
+ if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? caster : target)
{
int32 basepoints = GetAmount();
triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, nullptr, this);
@@ -5808,7 +5782,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
}
// Consecrate ticks can miss and will not show up in the combat log
- if (GetSpellInfo()->Effects[GetEffIndex()].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
@@ -5827,11 +5801,14 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
break;
case 38772: // Grievous Wound
{
- uint32 percent = GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster);
- if (!target->HealthBelowPct(percent))
+ if (SpellEffectInfo const* effect = GetSpellInfo()->GetEffect(DIFFICULTY_NONE, EFFECT_1))
{
- target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
- return;
+ uint32 percent = effect->CalcValue(caster);
+ if (!target->HealthBelowPct(percent))
+ {
+ target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
+ return;
+ }
}
break;
}
@@ -5843,7 +5820,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
// AOE spells are not affected by the new periodic system.
- bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
@@ -5858,7 +5835,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
// Calculate armor mitigation
- if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
+ if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
@@ -5902,7 +5879,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
damage = uint32(target->CountPctFromMaxHealth(damage));
if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
- if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
+ if (GetSpellEffectInfo()->IsTargetingArea() || isAreaAura)
{
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (caster->GetTypeId() != TYPEID_PLAYER)
@@ -5950,6 +5927,18 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
}
+bool AuraEffect::IsAreaAuraEffect() const
+{
+ if (_effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_OWNER)
+ return true;
+ return false;
+}
+
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
{
if (!caster || !target->IsAlive())
@@ -5961,7 +5950,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
return;
}
- if (GetSpellInfo()->Effects[GetEffIndex()].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
@@ -5969,7 +5958,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
uint32 resist = 0;
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
@@ -5982,7 +5971,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
// Calculate armor mitigation
- if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
+ if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
@@ -5990,7 +5979,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
}
if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
- if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
+ if (GetSpellEffectInfo()->IsTargetingArea() || isAreaAura)
{
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (caster->GetTypeId() != TYPEID_PLAYER)
@@ -6032,7 +6021,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
if (caster->IsAlive())
{
- float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
uint32 heal = uint32(caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetBase()->GetStackAmount()));
heal = uint32(caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetBase()->GetStackAmount()));
@@ -6063,7 +6052,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 = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
damage = int32(damage * gainMultiplier);
@@ -6089,7 +6078,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (GetBase()->IsPermanent() && target->IsFullHealth())
return;
- bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
int32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
@@ -6196,7 +6185,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
return;
}
- if (GetSpellInfo()->Effects[GetEffIndex()].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
@@ -6219,7 +6208,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
int32 drainedAmount = -target->ModifyPower(powerType, -drainAmount);
- float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
SpellPeriodicAuraLogInfo pInfo(this, drainedAmount, 0, 0, 0, gainMultiplier, false);
target->SendPeriodicAuraLog(&pInfo);
@@ -6336,7 +6325,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
uint32 gain = uint32(-target->ModifyPower(powerType, -damage));
- float dmgMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float dmgMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
SpellInfo const* spellProto = GetSpellInfo();
// maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
@@ -6365,7 +6354,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve
Unit* triggerCaster = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
- uint32 triggerSpellId = GetSpellInfo()->Effects[GetEffIndex()].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellAuraProc: Triggering spell %u from aura %u proc", triggeredSpellInfo->Id, GetId());
@@ -6380,7 +6369,7 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp
Unit* triggerCaster = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
- uint32 triggerSpellId = GetSpellInfo()->Effects[m_effIndex].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
int32 basepoints0 = GetAmount();
@@ -6438,7 +6427,7 @@ void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcE
{
if (Unit* caster = GetCaster())
{
- float radius = GetSpellInfo()->Effects[GetEffIndex()].CalcRadius(caster);
+ float radius = GetSpellEffectInfo()->CalcRadius(caster);
if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius))
{
@@ -6479,7 +6468,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
{
if (Unit* caster = GetCaster())
{
- float radius = GetSpellInfo()->Effects[GetEffIndex()].CalcRadius(caster);
+ float radius = GetSpellEffectInfo()->CalcRadius(caster);
if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius))
{
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 22571f4851e..2c2b0e2646f 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -29,13 +29,13 @@ typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uin
class AuraEffect
{
- friend void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount);
- friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount);
+ friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
friend Aura::~Aura();
- private:
- ~AuraEffect();
- explicit AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* caster);
+
public:
+ ~AuraEffect();
+ AuraEffect(Aura* base, uint32 effIndex, int32 baseAmount, Unit* caster);
Unit* GetCaster() const { return GetBase()->GetCaster(); }
ObjectGuid GetCasterGUID() const { return GetBase()->GetCasterGUID(); }
Aura* GetBase() const { return m_base; }
@@ -49,9 +49,9 @@ class AuraEffect
int32 GetBaseAmount() const { return m_baseAmount; }
int32 GetPeriod() const { return m_period; }
- int32 GetMiscValueB() const { return m_spellInfo->Effects[m_effIndex].MiscValueB; }
- int32 GetMiscValue() const { return m_spellInfo->Effects[m_effIndex].MiscValue; }
- AuraType GetAuraType() const { return (AuraType)m_spellInfo->Effects[m_effIndex].ApplyAuraName; }
+ int32 GetMiscValueB() const { return GetSpellEffectInfo()->MiscValueB; }
+ int32 GetMiscValue() const { return GetSpellEffectInfo()->MiscValue; }
+ AuraType GetAuraType() const { return (AuraType)GetSpellEffectInfo()->ApplyAuraName; }
int32 GetAmount() const { return m_amount; }
void SetAmount(int32 amount) { m_amount = amount; m_canBeRecalculated = false;}
@@ -87,7 +87,7 @@ class AuraEffect
bool IsPeriodic() const { return m_isPeriodic; }
void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; }
bool IsAffectingSpell(SpellInfo const* spell) const;
- bool HasSpellClassMask() const { return m_spellInfo->Effects[m_effIndex].SpellClassMask; }
+ bool HasSpellClassMask() const { return GetSpellEffectInfo()->SpellClassMask; }
void SendTickImmune(Unit* target, Unit* caster) const;
void PeriodicTick(AuraApplication * aurApp, Unit* caster) const;
@@ -98,10 +98,18 @@ class AuraEffect
// add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
void HandleShapeshiftBoosts(Unit* target, bool apply) const;
+
+ SpellEffectInfo const* GetSpellEffectInfo() const { return _effectInfo; }
+
+ bool IsEffect() const { return _effectInfo->Effect != 0; }
+ bool IsEffect(SpellEffectName effectName) const { return _effectInfo->Effect == uint32(effectName); }
+ bool IsAreaAuraEffect() const;
+
private:
Aura* const m_base;
SpellInfo const* const m_spellInfo;
+ SpellEffectInfo const* _effectInfo;
int32 const m_baseAmount;
int32 m_amount;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 67df56d892e..c244e7637dd 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -37,7 +37,7 @@
#include "Vehicle.h"
#include "Config.h"
-AuraApplication::AuraApplication(Unit* target, Unit* caster, Aura* aura, uint8 effMask):
+AuraApplication::AuraApplication(Unit* target, Unit* caster, Aura* aura, uint32 effMask):
_target(target), _base(aura), _removeMode(AURA_REMOVE_NONE), _slot(MAX_AURAS),
_flags(AFLAG_NONE), _effectsToApply(effMask), _needClientUpdate(false)
{
@@ -113,7 +113,7 @@ void AuraApplication::_Remove()
}
}
-void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
+void AuraApplication::_InitFlags(Unit* caster, uint32 effMask)
{
// mark as selfcast if needed
_flags |= (GetBase()->GetCasterGUID() == GetTarget()->GetGUID()) ? AFLAG_CASTER : AFLAG_NONE;
@@ -123,9 +123,9 @@ void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
if (IsSelfcast() || !caster || !caster->IsFriendlyTo(GetTarget()))
{
bool negativeFound = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetBase()->GetSpellEffectInfos())
{
- if (((1<<i) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(i))
+ if (effect && ((1 << effect->EffectIndex) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(effect->EffectIndex))
{
negativeFound = true;
break;
@@ -138,9 +138,9 @@ void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
else
{
bool positiveFound = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetBase()->GetSpellEffectInfos())
{
- if (((1<<i) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(i))
+ if (effect && ((1 << effect->EffectIndex) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(effect->EffectIndex))
{
positiveFound = true;
break;
@@ -212,10 +212,9 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const
}
if (flags & AFLAG_ANY_EFFECT_AMOUNT_SENT)
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (AuraEffect const* eff = aura->GetEffect(i))
- if (HasEffect(i)) // Not all of aura's effects have to be applied on every target
- data << int32(eff->GetAmount());
+ for (AuraEffect const* effect : GetBase()->GetAuraEffects())
+ if (effect && HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target
+ data << int32(effect->GetAmount());
}
void AuraApplication::ClientUpdate(bool remove)
@@ -229,26 +228,26 @@ void AuraApplication::ClientUpdate(bool remove)
_target->SendMessageToSet(&data, true);
}
-uint8 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner)
+uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibleEffectMask, WorldObject* owner)
{
ASSERT(spellProto);
ASSERT(owner);
- uint8 effMask = 0;
+ uint32 effMask = 0;
switch (owner->GetTypeId())
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
- for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficulty()))
{
- if (spellProto->Effects[i].IsUnitOwnedAuraEffect())
- effMask |= 1 << i;
+ if (effect && effect->IsUnitOwnedAuraEffect())
+ effMask |= 1 << effect->EffectIndex;
}
break;
case TYPEID_DYNAMICOBJECT:
- for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficulty()))
{
- if (spellProto->Effects[i].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
- effMask |= 1 << i;
+ if (effect && effect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ effMask |= 1 << effect->EffectIndex;
}
break;
default:
@@ -257,7 +256,7 @@ uint8 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleE
return effMask & avalibleEffectMask;
}
-Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= NULL*/)
+Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= NULL*/)
{
ASSERT(spellproto);
ASSERT(owner);
@@ -283,7 +282,7 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMas
return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
}
-Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/)
+Aura* Aura::TryCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/)
{
ASSERT(spellproto);
ASSERT(owner);
@@ -295,7 +294,7 @@ Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject
return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
}
-Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID)
+Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
{
ASSERT(effMask);
ASSERT(spellproto);
@@ -354,7 +353,6 @@ m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEven
m_duration = m_maxDuration;
m_procCharges = CalcMaxCharges(caster);
m_isUsingCharges = m_procCharges != 0;
- memset(m_effects, 0, sizeof(m_effects));
// m_casterLevel = cast item level/caster level, caster level should be saved to db, confirmed with sniffs
}
@@ -366,15 +364,25 @@ AuraScript* Aura::GetScriptByName(std::string const& scriptName) const
return NULL;
}
-void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount)
+SpellEffectInfo const* Aura::GetSpellEffectInfo(uint32 index) const
+{
+ if (index >= _spelEffectInfos.size())
+ return nullptr;
+
+ return _spelEffectInfos[index];
+}
+
+void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount)
{
// shouldn't be in constructor - functions in AuraEffect::AuraEffect use polymorphism
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ _spelEffectInfos = m_spellInfo->GetEffectsForDifficulty(GetOwner()->GetMap()->GetDifficulty());
+
+ ASSERT(!_spelEffectInfos.empty());
+
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
{
- if (effMask & (uint8(1) << i))
- m_effects[i] = new AuraEffect(this, i, baseAmount ? baseAmount + i : NULL, caster);
- else
- m_effects[i] = NULL;
+ //if (effMask & (uint8(1) << effect->EffectIndex))
+ _effects[effect->EffectIndex] = new AuraEffect(this, effect->EffectIndex, baseAmount[effect->EffectIndex], caster);
}
}
@@ -389,9 +397,9 @@ Aura::~Aura()
m_loadedScripts.erase(itr);
}
- // free effects memory
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- delete m_effects[i];
+ // free effects memory todo 6.x
+ //for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ // delete m_effects[i];
ASSERT(m_applications.empty());
_DeleteRemovedApplications();
@@ -407,6 +415,14 @@ Unit* Aura::GetCaster() const
return ObjectAccessor::GetUnit(*GetOwner(), GetCasterGUID());
}
+AuraEffect* Aura::GetEffect(uint32 index) const
+{
+ if (index >= _effects.size())
+ return nullptr;
+
+ return _effects[index];
+}
+
AuraObjectType Aura::GetType() const
{
return (m_owner->GetTypeId() == TYPEID_DYNAMICOBJECT) ? DYNOBJ_AURA_TYPE : UNIT_AURA_TYPE;
@@ -674,9 +690,9 @@ void Aura::UpdateOwner(uint32 diff, WorldObject* owner)
m_updateTargetMapInterval -= diff;
// update aura effects
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i])
- m_effects[i]->Update(diff, caster);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect)
+ effect->Update(diff, caster);
// remove spellmods after effects update
if (modSpell)
@@ -880,9 +896,9 @@ void Aura::SetStackAmount(uint8 stackAmount)
if (!(*apptItr)->GetRemoveMode())
HandleAuraSpecificMods(*apptItr, caster, false, true);
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i))
- m_effects[i]->ChangeAmount(m_effects[i]->CalculateAmount(caster), false, true);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect)
+ effect->ChangeAmount(effect->CalculateAmount(caster), false, true);
for (std::list<AuraApplication*>::const_iterator apptItr = applications.begin(); apptItr != applications.end(); ++apptItr)
if (!(*apptItr)->GetRemoveMode())
@@ -945,11 +961,11 @@ void Aura::RefreshSpellMods()
player->RestoreAllSpellMods(0, this);
}
-bool Aura::HasMoreThanOneEffectForType(AuraType auraType) const
+bool Aura::HasMoreThanOneEffectForType(AuraType auraType, uint32 difficulty) const
{
uint32 count = 0;
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i) && AuraType(GetSpellInfo()->Effects[i].ApplyAuraName) == auraType)
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
+ if (effect && HasEffect(effect->EffectIndex) && AuraType(effect->ApplyAuraName) == auraType)
++count;
return count > 1;
@@ -957,8 +973,8 @@ bool Aura::HasMoreThanOneEffectForType(AuraType auraType) const
bool Aura::IsArea() const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i) && GetSpellInfo()->Effects[i].IsAreaAuraEffect())
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
+ if (effect && HasEffect(effect->EffectIndex) && effect->IsAreaAuraEffect())
return true;
return false;
@@ -1020,7 +1036,7 @@ bool Aura::CanBeSaved() const
bool Aura::CanBeSentToClient() const
{
- return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect() || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
+ return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect(GetOwner() ? GetOwner()->GetMap()->GetDifficulty() : DIFFICULTY_NONE) || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
}
bool Aura::IsSingleTargetWith(Aura const* aura) const
@@ -1080,7 +1096,7 @@ int32 Aura::CalcDispelChance(Unit* auraTarget, bool offensive) const
return 100 - resistChance;
}
-void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount)
+void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 *amount)
{
m_maxDuration = maxduration;
m_duration = duration;
@@ -1088,22 +1104,23 @@ void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint
m_isUsingCharges = m_procCharges != 0;
m_stackAmount = stackamount;
Unit* caster = GetCaster();
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i])
- {
- m_effects[i]->SetAmount(amount[i]);
- m_effects[i]->SetCanBeRecalculated((recalculateMask & (1 << i)) != 0);
- m_effects[i]->CalculatePeriodic(caster, false, true);
- m_effects[i]->CalculateSpellMod();
- m_effects[i]->RecalculateAmount(caster);
- }
+ for (AuraEffect* effect : GetAuraEffects())
+ {
+ if (!effect)
+ continue;
+ effect->SetAmount(amount[effect->GetEffIndex()]);
+ effect->SetCanBeRecalculated((recalculateMask & (1 << effect->GetEffIndex())) != 0);
+ effect->CalculatePeriodic(caster, false, true);
+ effect->CalculateSpellMod();
+ effect->RecalculateAmount(caster);
+ }
}
bool Aura::HasEffectType(AuraType type) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (AuraEffect* effect : GetAuraEffects())
{
- if (HasEffect(i) && m_effects[i]->GetAuraType() == type)
+ if (effect && effect->GetAuraType() == type)
return true;
}
return false;
@@ -1113,17 +1130,26 @@ void Aura::RecalculateAmountOfEffects()
{
ASSERT (!IsRemoved());
Unit* caster = GetCaster();
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i))
- m_effects[i]->RecalculateAmount(caster);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect && !IsRemoved())
+ effect->RecalculateAmount(caster);
}
void Aura::HandleAllEffects(AuraApplication * aurApp, uint8 mode, bool apply)
{
ASSERT (!IsRemoved());
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i] && !IsRemoved())
- m_effects[i]->HandleEffect(aurApp, mode, apply);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect && !IsRemoved())
+ effect->HandleEffect(aurApp, mode, apply);
+}
+
+uint32 Aura::GetEffectMask() const
+{
+ uint32 effMask = 0;
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect)
+ effMask |= 1 << effect->GetEffIndex();
+ return effMask;
}
void Aura::GetApplicationList(std::list<AuraApplication*> & applicationList) const
@@ -1517,47 +1543,40 @@ void Aura::HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* cast
if (!caster || aurApp->GetRemoveMode())
return;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (AuraEffect* effect : GetAuraEffects())
{
- if (!HasEffect(i))
- continue;
-
- if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ if (!effect || effect->IsAreaAuraEffect() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
continue;
- switch (m_spellInfo->Effects[i].ApplyAuraName)
+ switch (effect->GetSpellEffectInfo()->ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
case SPELL_AURA_PERIODIC_LEECH:
{
- AuraEffect* aurEff = GetEffect(i);
-
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 damage = std::max(aurEff->GetAmount(), 0);
+ uint32 damage = std::max(effect->GetAmount(), 0);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- aurEff->SetDonePct(caster->SpellDamagePctDone(target, m_spellInfo, DOT)); // Calculate done percentage first!
- aurEff->SetDamage(caster->SpellDamageBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
- aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
+ effect->SetDonePct(caster->SpellDamagePctDone(target, m_spellInfo, DOT)); // Calculate done percentage first!
+ effect->SetDamage(caster->SpellDamageBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * effect->GetDonePct());
+ effect->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
break;
}
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_OBS_MOD_HEALTH:
{
- AuraEffect* aurEff = GetEffect(i);
-
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 damage = std::max(aurEff->GetAmount(), 0);
+ uint32 damage = std::max(effect->GetAmount(), 0);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- aurEff->SetDonePct(caster->SpellHealingPctDone(target, m_spellInfo)); // Calculate done percentage first!
- aurEff->SetDamage(caster->SpellHealingBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
- aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
+ effect->SetDonePct(caster->SpellHealingPctDone(target, m_spellInfo)); // Calculate done percentage first!
+ effect->SetDamage(caster->SpellHealingBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * effect->GetDonePct());
+ effect->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
break;
}
default:
@@ -1605,12 +1624,17 @@ bool Aura::CanStackWith(Aura const* existingAura) const
if (IsPassive() && sameCaster && m_spellInfo->IsDifferentRankOf(existingSpellInfo))
return false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : existingAura->GetSpellEffectInfos())
{
// prevent remove triggering aura by triggered aura
- if (existingSpellInfo->Effects[i].TriggerSpell == GetId()
- // prevent remove triggered aura by triggering aura refresh
- || m_spellInfo->Effects[i].TriggerSpell == existingAura->GetId())
+ if (effect->TriggerSpell == GetId())
+ return true;
+ }
+
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
+ {
+ // prevent remove triggered aura by triggering aura refresh
+ if (effect->TriggerSpell == existingAura->GetId())
return true;
}
@@ -1620,7 +1644,7 @@ bool Aura::CanStackWith(Aura const* existingAura) const
// * The minimap tracking list will only show a check mark next to the last skill activated
// Sometimes this bugs out and doesn't switch the check mark. It has no effect on the actual tracking though.
// * The minimap dots are yellow for both resources
- if (m_spellInfo->HasAura(SPELL_AURA_TRACK_RESOURCES) && existingSpellInfo->HasAura(SPELL_AURA_TRACK_RESOURCES))
+ if (m_spellInfo->HasAura(GetOwner()->GetMap()->GetDifficulty(), SPELL_AURA_TRACK_RESOURCES) && existingSpellInfo->HasAura(GetOwner()->GetMap()->GetDifficulty(), SPELL_AURA_TRACK_RESOURCES))
return sWorld->getBoolConfig(CONFIG_ALLOW_TRACK_BOTH_RESOURCES);
// check spell specific stack rules
@@ -1659,7 +1683,10 @@ bool Aura::CanStackWith(Aura const* existingAura) const
// check same periodic auras
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- switch (m_spellInfo->Effects[i].ApplyAuraName)
+ SpellEffectInfo const* effect = GetSpellEffectInfo(i);
+ if (!effect)
+ continue;
+ switch (effect->ApplyAuraName)
{
// DOT or HOT from different casters will stack
case SPELL_AURA_PERIODIC_DAMAGE:
@@ -1673,9 +1700,12 @@ bool Aura::CanStackWith(Aura const* existingAura) const
case SPELL_AURA_OBS_MOD_POWER:
case SPELL_AURA_OBS_MOD_HEALTH:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
- // periodic auras which target areas are not allowed to stack this way (replenishment for example)
- if (m_spellInfo->Effects[i].IsTargetingArea() || existingSpellInfo->Effects[i].IsTargetingArea())
- break;
+ {
+ SpellEffectInfo const* existingEffect = GetSpellEffectInfo(i);
+ // 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;
@@ -2246,7 +2276,7 @@ void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraAppli
}
}
-UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
+UnitAura::UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
: Aura(spellproto, owner, caster, castItem, casterGUID)
{
m_AuraDRGroup = DIMINISHING_NONE;
@@ -2282,29 +2312,29 @@ void UnitAura::Remove(AuraRemoveMode removeMode)
void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster)
{
- for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
{
- if (!HasEffect(effIndex))
+ if (!effect || !HasEffect(effect->EffectIndex))
continue;
UnitList targetList;
// non-area aura
- if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AURA)
+ if (effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
targetList.push_back(GetUnitOwner());
}
else
{
- float radius = GetSpellInfo()->Effects[effIndex].CalcRadius(caster);
+ float radius = effect->CalcRadius(caster);
if (!GetUnitOwner()->HasUnitState(UNIT_STATE_ISOLATED))
{
- switch (GetSpellInfo()->Effects[effIndex].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
{
targetList.push_back(GetUnitOwner());
- Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
+ Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
@@ -2342,14 +2372,14 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster)
{
std::map<Unit*, uint8>::iterator existing = targets.find(*itr);
if (existing != targets.end())
- existing->second |= 1<<effIndex;
+ existing->second |= 1 << effect->EffectIndex;
else
- targets[*itr] = 1<<effIndex;
+ targets[*itr] = 1 << effect->EffectIndex;
}
}
}
-DynObjAura::DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
+DynObjAura::DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
: Aura(spellproto, owner, caster, castItem, casterGUID)
{
LoadScripts();
@@ -2379,13 +2409,13 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster*
Unit* dynObjOwnerCaster = GetDynobjOwner()->GetCaster();
float radius = GetDynobjOwner()->GetRadius();
- for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
{
- if (!HasEffect(effIndex))
+ if (!effect || !HasEffect(effect->EffectIndex))
continue;
UnitList targetList;
- if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
- || GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
+ if (effect->TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
+ || effect->TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
{
Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
@@ -2402,9 +2432,9 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster*
{
std::map<Unit*, uint8>::iterator existing = targets.find(*itr);
if (existing != targets.end())
- existing->second |= 1<<effIndex;
+ existing->second |= 1 << effect->EffectIndex;
else
- targets[*itr] = 1<<effIndex;
+ targets[*itr] = 1 << effect->EffectIndex;
}
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index f69d9baafe0..2d40f3aeb8c 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -41,11 +41,11 @@ class ChargeDropEvent;
class AuraApplication
{
- friend void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask);
+ friend void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask);
friend void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
friend void Unit::_ApplyAuraEffect(Aura* aura, uint8 effIndex);
friend void Unit::RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode);
- friend AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint8 effMask);
+ friend AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint32 effMask);
private:
Unit* const _target;
Aura* const _base;
@@ -55,12 +55,12 @@ class AuraApplication
uint8 _effectsToApply; // Used only at spell hit to determine which effect should be applied
bool _needClientUpdate:1;
- explicit AuraApplication(Unit* target, Unit* caster, Aura* base, uint8 effMask);
void _Remove();
private:
- void _InitFlags(Unit* caster, uint8 effMask);
+ void _InitFlags(Unit* caster, uint32 effMask);
void _HandleEffect(uint8 effIndex, bool apply);
public:
+ explicit AuraApplication(Unit* target, Unit* caster, Aura* base, uint32 effMask);
Unit* GetTarget() const { return _target; }
Aura* GetBase() const { return _base; }
@@ -84,16 +84,16 @@ class AuraApplication
class Aura
{
- friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
public:
typedef std::map<ObjectGuid, AuraApplication*> ApplicationMap;
- static uint8 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner);
- static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = NULL);
- static Aura* TryCreate(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
- static Aura* Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID);
+ static uint32 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibleEffectMask, WorldObject* owner);
+ static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = NULL);
+ static Aura* TryCreate(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
+ static Aura* Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
explicit Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID);
- void _InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount);
+ void _InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount);
virtual ~Aura();
SpellInfo const* GetSpellInfo() const { return m_spellInfo; }
@@ -152,7 +152,7 @@ class Aura
uint8 GetCasterLevel() const { return m_casterLevel; }
- bool HasMoreThanOneEffectForType(AuraType auraType) const;
+ bool HasMoreThanOneEffectForType(AuraType auraType, uint32 difficulty) const;
bool IsArea() const;
bool IsPassive() const;
bool IsDeathPersistent() const;
@@ -175,13 +175,14 @@ class Aura
void UnregisterSingleTarget();
int32 CalcDispelChance(Unit* auraTarget, bool offensive) const;
- void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount);
+ void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 *baseAmount);
// helpers for aura effects
bool HasEffect(uint8 effIndex) const { return GetEffect(effIndex) != NULL; }
bool HasEffectType(AuraType type) const;
- AuraEffect* GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return m_effects[effIndex]; }
- uint8 GetEffectMask() const { uint8 effMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_effects[i]) effMask |= 1<<i; return effMask; }
+ //AuraEffect* GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return Effects[effIndex]; }
+ AuraEffect* GetEffect(uint32 index) const;
+ uint32 GetEffectMask() const;
void RecalculateAmountOfEffects();
void HandleAllEffects(AuraApplication * aurApp, uint8 mode, bool apply);
@@ -242,6 +243,12 @@ class Aura
AuraScript* GetScriptByName(std::string const& scriptName) const;
std::list<AuraScript*> m_loadedScripts;
+
+ AuraEffectVector GetAuraEffects() const { return _effects; }
+
+ SpellEffectInfoVector GetSpellEffectInfos() const { return _spelEffectInfos; }
+ SpellEffectInfo const* GetSpellEffectInfo(uint32 index) const;
+
private:
void _DeleteRemovedApplications();
protected:
@@ -260,7 +267,7 @@ class Aura
uint8 m_procCharges; // Aura charges (0 for infinite)
uint8 m_stackAmount; // Aura stack amount
- AuraEffect* m_effects[3];
+ //AuraEffect* m_effects[3];
ApplicationMap m_applications;
bool m_isRemoved:1;
@@ -271,14 +278,17 @@ class Aura
private:
Unit::AuraApplicationList m_removedApplications;
+
+ AuraEffectVector _effects;
+ SpellEffectInfoVector _spelEffectInfos;
};
class UnitAura : public Aura
{
- friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
- protected:
- explicit UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
public:
+ explicit UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+
void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
void _UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
@@ -296,10 +306,10 @@ class UnitAura : public Aura
class DynObjAura : public Aura
{
- friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
- protected:
- explicit DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
public:
+ explicit DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 5c247d86fa3..4e3ffd06a64 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -521,7 +521,7 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags,
m_spellInfo(info), m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster),
m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster))
{
- difficultyEffects = info->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty());
+ _effects = info->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty());
m_customError = SPELL_CUSTOM_ERROR_NONE;
m_skipCheck = skipCheck;
@@ -2611,7 +2611,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
{
bool refresh = false;
m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit,
- m_originalCaster, (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh);
+ m_originalCaster, (aurSpellInfo == m_spellInfo) ? m_spellValue->EffectBasePoints : basePoints, m_CastItem, ObjectGuid::Empty, &refresh);
if (m_spellAura)
{
// Set aura stack amount to desired value
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index ee31326808f..612fd18cfda 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -192,7 +192,7 @@ class SpellCastTargets
struct SpellValue
{
explicit SpellValue(SpellInfo const* proto);
- std::vector<int32> EffectBasePoints;
+ int32 EffectBasePoints[MAX_SPELL_EFFECTS];
uint32 MaxAffectedTargets;
float RadiusMod;
uint8 AuraStackAmount;
@@ -503,13 +503,13 @@ class Spell
void SetSpellValue(SpellValueMod mod, int32 value);
- SpellEffectInfoVector GetEffects() const { return difficultyEffects; }
+ SpellEffectInfoVector GetEffects() const { return _effects; }
SpellEffectInfo const* GetEffect(uint32 index) const
{
- if (index >= difficultyEffects.size())
+ if (index >= _effects.size())
return nullptr;
- return difficultyEffects[index];
+ return _effects[index];
}
bool HasEffect(SpellEffectName effect) const;
@@ -716,7 +716,7 @@ class Spell
Spell(Spell const& right) = delete;
Spell& operator=(Spell const& right) = delete;
- SpellEffectInfoVector difficultyEffects;
+ SpellEffectInfoVector _effects;
};
namespace Trinity
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index c1e588c7edf..bd577af2b5a 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -284,7 +284,7 @@ void Spell::EffectResurrectNew(SpellEffIndex effIndex)
return;
uint32 health = damage;
- uint32 mana = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 mana = GetEffect(effIndex)->MiscValue;
ExecuteLogEffectResurrect(effIndex, target);
target->SetResurrectRequestData(m_caster, health, mana, 0);
SendResurrectRequest(target);
@@ -419,23 +419,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
}
case SPELLFAMILY_PRIEST:
{
- // Improved Mind Blast (Mind Blast in shadow form bonus)
- if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
- {
- Unit::AuraEffectList const& ImprMindBlast = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_FLAT_MODIFIER);
- for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
- {
- if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
- ((*i)->GetSpellInfo()->SpellIconID == 95))
- {
- int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
- if (roll_chance_i(chance))
- // Mind Trauma
- m_caster->CastSpell(unitTarget, 48301, true, nullptr);
- break;
- }
- }
- }
break;
}
case SPELLFAMILY_DRUID:
@@ -464,31 +447,14 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x00010000, 0, 0, m_caster->GetGUID()))
{
// count consumed deadly poison doses at target
- bool needConsume = true;
uint32 spellId = aurEff->GetId();
uint32 doses = aurEff->GetBase()->GetStackAmount();
if (doses > combo)
doses = combo;
- // Master Poisoner
- Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
- for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
- {
- if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
- {
- uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
-
- if (chance && roll_chance_i(chance))
- needConsume = false;
-
- break;
- }
- }
-
- if (needConsume)
- for (uint32 i = 0; i < doses; ++i)
- unitTarget->RemoveAuraFromStack(spellId, m_caster->GetGUID());
+ for (uint32 i = 0; i < doses; ++i)
+ unitTarget->RemoveAuraFromStack(spellId, m_caster->GetGUID());
damage *= doses;
damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
@@ -618,10 +584,10 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
&& effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = GetEffect(effIndex)->TriggerSpell;
/// @todo move those to spell scripts
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
+ if (GetEffect(effIndex)->Effect == SPELL_EFFECT_TRIGGER_SPELL
&& effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
{
// special cases
@@ -718,13 +684,13 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
SpellCastTargets targets;
if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
{
- if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo))
+ if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
{
- if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
+ if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()) && (GetEffect(effIndex)->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
return;
if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION)
@@ -738,7 +704,7 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
CustomSpellValues values;
// set basepoints for trigger with value effect
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
+ if (GetEffect(effIndex)->Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
{
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
@@ -760,7 +726,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
&& effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = GetEffect(effIndex)->TriggerSpell;
// normal case
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
@@ -773,13 +739,13 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
SpellCastTargets targets;
if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET)
{
- if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo))
+ if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
{
- if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
+ if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()) && (GetEffect(effIndex)->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
return;
if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION)
@@ -790,7 +756,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
CustomSpellValues values;
// set basepoints for trigger with value effect
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE)
+ if (GetEffect(effIndex)->Effect == SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE)
{
// maybe need to set value only when basepoints == 0?
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
@@ -815,7 +781,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
if (!unitTarget)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = GetEffect(effIndex)->TriggerSpell;
// normal case
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
@@ -826,7 +792,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
return;
}
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
+ if (GetEffect(effIndex)->Effect == SPELL_EFFECT_FORCE_CAST && damage)
{
switch (m_spellInfo->Id)
{
@@ -850,7 +816,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
CustomSpellValues values;
// set basepoints for trigger with value effect
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE)
+ if (GetEffect(effIndex)->Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE)
{
// maybe need to set value only when basepoints == 0?
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
@@ -869,7 +835,7 @@ void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = GetEffect(effIndex)->TriggerSpell;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!spellInfo)
@@ -924,12 +890,16 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex)
void Spell::CalculateJumpSpeeds(uint8 i, float dist, float & speedXY, float & speedZ)
{
- if (m_spellInfo->Effects[i].MiscValue)
- speedZ = float(m_spellInfo->Effects[i].MiscValue)/10;
- else if (m_spellInfo->Effects[i].MiscValueB)
- speedZ = float(m_spellInfo->Effects[i].MiscValueB)/10;
- else
- speedZ = 10.0f;
+ SpellEffectInfo const* effect = GetEffect(i);
+ if (effect)
+ {
+ if (effect->MiscValue)
+ speedZ = float(effect->MiscValue) / 10;
+ else if (effect->MiscValueB)
+ speedZ = float(effect->MiscValueB) / 10;
+ else
+ speedZ = 10.0f;
+ }
speedXY = dist * 10.0f / speedZ;
}
@@ -1096,7 +1066,7 @@ void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex)
return;
Player* player = unitTarget->ToPlayer();
- uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 spellToUnlearn = GetEffect(effIndex)->TriggerSpell;
player->RemoveSpell(spellToUnlearn);
@@ -1108,10 +1078,10 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (GetEffect(effIndex)->MiscValue < 0 || GetEffect(effIndex)->MiscValue >= int8(MAX_POWERS))
return;
- Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers powerType = Powers(GetEffect(effIndex)->MiscValue);
if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != powerType || damage < 0)
return;
@@ -1127,7 +1097,7 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
// Don't restore from self drain
if (m_caster != unitTarget)
{
- gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
+ gainMultiplier = GetEffect(effIndex)->CalcValueMultiplier(m_originalCaster, this);
int32 gain = int32(newDamage* gainMultiplier);
@@ -1159,7 +1129,7 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex)
// this check was requested by scripters, but it has some downsides:
// now it's impossible to script (using sEventScripts) a cast which misses all targets
// or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
- if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
+ if (GetEffect(effIndex)->GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
return;
// some spells have no target entries in dbc and they use focus target
if (focusObject)
@@ -1167,14 +1137,14 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex)
/// @todo there should be a possibility to pass dest target to event script
}
- TC_LOG_DEBUG("spells", "Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
+ TC_LOG_DEBUG("spells", "Spell ScriptStart %u for spellid %u in EffectSendEvent ", GetEffect(effIndex)->MiscValue, m_spellInfo->Id);
if (ZoneScript* zoneScript = m_caster->GetZoneScript())
- zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
+ zoneScript->ProcessEvent(target, GetEffect(effIndex)->MiscValue);
else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
- instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
+ instanceScript->ProcessEvent(target, GetEffect(effIndex)->MiscValue);
- m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
+ m_caster->GetMap()->ScriptsStart(sEventScripts, GetEffect(effIndex)->MiscValue, m_caster, target);
}
void Spell::EffectPowerBurn(SpellEffIndex effIndex)
@@ -1182,10 +1152,10 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (GetEffect(effIndex)->MiscValue < 0 || GetEffect(effIndex)->MiscValue >= int8(MAX_POWERS))
return;
- Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers powerType = Powers(GetEffect(effIndex)->MiscValue);
if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != powerType || damage < 0)
return;
@@ -1201,7 +1171,7 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex)
int32 newDamage = -(unitTarget->ModifyPower(powerType, -damage));
// NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
- float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
+ float dmgMultiplier = GetEffect(effIndex)->CalcValueMultiplier(m_originalCaster, this);
// add log data before multiplication (need power amount, not damage)
ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, powerType, newDamage, 0.0f);
@@ -1356,7 +1326,7 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex)
TC_LOG_DEBUG("spells", "HealthLeech :%i", damage);
- float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
+ float healMultiplier = GetEffect(effIndex)->CalcValueMultiplier(m_originalCaster, this);
m_damage += damage;
// get max possible damage, don't count overkill for heal
@@ -1491,8 +1461,8 @@ void Spell::EffectCreateItem(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
- ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
+ DoCreateItem(effIndex, GetEffect(effIndex)->ItemType);
+ ExecuteLogEffectCreateItem(effIndex, GetEffect(effIndex)->ItemType);
}
void Spell::EffectCreateItem2(SpellEffIndex effIndex)
@@ -1505,7 +1475,7 @@ void Spell::EffectCreateItem2(SpellEffIndex effIndex)
Player* player = unitTarget->ToPlayer();
- uint32 item_id = m_spellInfo->Effects[effIndex].ItemType;
+ uint32 item_id = GetEffect(effIndex)->ItemType;
if (item_id)
DoCreateItem(effIndex, item_id);
@@ -1553,7 +1523,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
if (!m_spellAura)
{
Unit* caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
+ float radius = GetEffect(effIndex)->CalcRadius(caster);
// Caster not in world, might be spell triggered from aura removal
if (!caster->IsInWorld())
@@ -1588,10 +1558,10 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
if (!unitTarget->IsAlive())
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (GetEffect(effIndex)->MiscValue < 0 || GetEffect(effIndex)->MiscValue >= int8(MAX_POWERS))
return;
- Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers power = Powers(GetEffect(effIndex)->MiscValue);
if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !(m_spellInfo->AttributesEx7 & SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER))
return;
@@ -1697,10 +1667,10 @@ void Spell::EffectEnergizePct(SpellEffIndex effIndex)
if (!unitTarget->IsAlive())
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (GetEffect(effIndex)->MiscValue < 0 || GetEffect(effIndex)->MiscValue >= int8(MAX_POWERS))
return;
- Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers power = Powers(GetEffect(effIndex)->MiscValue);
if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !(m_spellInfo->AttributesEx7 & SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER))
return;
@@ -1905,7 +1875,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
if (m_CastItem->GetOwnerGUID() != player->GetGUID())
return;
- uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
+ uint32 newitemid = GetEffect(effIndex)->ItemType;
if (!newitemid)
return;
@@ -2022,14 +1992,14 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 entry = GetEffect(effIndex)->MiscValue;
if (!entry)
return;
- SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(GetEffect(effIndex)->MiscValueB);
if (!properties)
{
- TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type %u", m_spellInfo->Effects[effIndex].MiscValueB);
+ TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type %u", GetEffect(effIndex)->MiscValueB);
return;
}
@@ -2130,7 +2100,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
}
default:
{
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = GetEffect(effIndex)->CalcRadius();
TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
@@ -2175,8 +2145,8 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
// The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
uint32 spellId = VEHICLE_SPELL_RIDE_HARDCODED;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].CalcValue());
- if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(GetEffect(effIndex)->CalcValue());
+ if (spellInfo && spellInfo->HasAura(m_originalCaster->GetMap()->GetDifficulty(), SPELL_AURA_CONTROL_VEHICLE))
spellId = spellInfo->Id;
// Hard coded enter vehicle spell
@@ -2214,7 +2184,7 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex)
Player* player = unitTarget->ToPlayer();
- uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : GetEffect(effIndex)->TriggerSpell;
player->LearnSpell(spellToLearn, false);
TC_LOG_DEBUG("spells", "Spell: %s has learned spell %u from %s", player->GetGUID().ToString().c_str(), spellToLearn, m_caster->GetGUID().ToString().c_str());
@@ -2229,7 +2199,7 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
return;
// Create dispel mask by dispel type
- uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 dispel_type = GetEffect(effIndex)->MiscValue;
uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
DispelChargesList dispel_list;
@@ -2316,12 +2286,15 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
// Devour Magic
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == SPELLCATEGORY_DEVOUR_MAGIC)
{
- int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue(m_caster);
- m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true);
- // Glyph of Felhunter
- if (Unit* owner = m_caster->GetOwner())
+ if (SpellEffectInfo const* effect = GetEffect(EFFECT_1))
+ {
+ int32 heal_amount = effect->CalcValue(m_caster);
+ m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true);
+ // Glyph of Felhunter
+ if (Unit* owner = m_caster->GetOwner())
if (owner->GetAura(56249))
owner->CastCustomSpell(owner, 19658, &heal_amount, NULL, NULL, true);
+ }
}
}
@@ -2384,7 +2357,7 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = GetEffect(effIndex)->CalcRadius();
int32 duration = m_spellInfo->GetDuration();
// Caster not in world, might be spell triggered from aura removal
if (!m_caster->IsInWorld())
@@ -2423,7 +2396,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex effIndex)
if (unitTarget->IsInFlight())
return;
- float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ float dis = GetEffect(effIndex)->CalcRadius(m_caster);
float fx, fy, fz;
m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetObjectSize(), dis);
@@ -2442,7 +2415,7 @@ void Spell::EffectLearnSkill(SpellEffIndex effIndex)
if (damage < 0)
return;
- uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 skillid = GetEffect(effIndex)->MiscValue;
SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skillid, unitTarget->getRace(), unitTarget->getClass());
if (!rcEntry)
return;
@@ -2452,7 +2425,7 @@ void Spell::EffectLearnSkill(SpellEffIndex effIndex)
return;
uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
- unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), std::max<uint16>(skillval, 1), tier->Value[damage - 1]);
+ unitTarget->ToPlayer()->SetSkill(skillid, GetEffect(effIndex)->CalcValue(), std::max<uint16>(skillval, 1), tier->Value[damage - 1]);
}
void Spell::EffectPlayMovie(SpellEffIndex effIndex)
@@ -2462,12 +2435,14 @@ void Spell::EffectPlayMovie(SpellEffIndex effIndex)
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
+ if (SpellEffectInfo const* effect = GetEffect(effIndex))
+ {
+ uint32 movieId = effect->MiscValue;
+ if (!sMovieStore.LookupEntry(movieId))
+ return;
- uint32 movieId = GetSpellInfo()->Effects[effIndex].MiscValue;
- if (!sMovieStore.LookupEntry(movieId))
- return;
-
- unitTarget->ToPlayer()->SendMovieStart(movieId);
+ unitTarget->ToPlayer()->SendMovieStart(movieId);
+ }
}
void Spell::EffectTradeSkill(SpellEffIndex /*effIndex*/)
@@ -2502,7 +2477,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
player->DestroyItemCount(itemTarget, count, true);
unitTarget = player;
// and add a scroll
- DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
+ DoCreateItem(effIndex, GetEffect(effIndex)->ItemType);
itemTarget = NULL;
m_targets.SetItemTarget(NULL);
}
@@ -2512,7 +2487,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
if (!(m_CastItem && m_CastItem->GetTemplate()->Flags[0] & ITEM_PROTO_FLAG_TRIGGERED_CAST))
player->UpdateCraftSkill(m_spellInfo->Id);
- uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchant_id = GetEffect(effIndex)->MiscValue;
if (!enchant_id)
return;
@@ -2558,7 +2533,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)
if (!player)
return;
- uint32 enchantId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchantId = GetEffect(effIndex)->MiscValue;
if (!enchantId)
return;
@@ -2622,7 +2597,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
if (!itemTarget)
return;
- uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchant_id = GetEffect(effIndex)->MiscValue;
if (!enchant_id)
{
@@ -2757,7 +2732,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
owner = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
}
- uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 petentry = GetEffect(effIndex)->MiscValue;
if (!owner)
{
@@ -2843,7 +2818,7 @@ void Spell::EffectLearnPetSpell(SpellEffIndex effIndex)
if (!pet)
return;
- SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
+ SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(GetEffect(effIndex)->TriggerSpell);
if (!learn_spellproto)
return;
@@ -2898,9 +2873,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// multiple weapon dmg effect workaround
// execute only the last weapon damage
// and handle all effects at once
- for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- switch (m_spellInfo->Effects[j].Effect)
+ if (!effect)
+ continue;
+ switch (effect->Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
@@ -2988,48 +2965,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// Blood Strike
if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
{
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f;
- // Death Knight T8 Melee 4P Bonus
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
- AddPct(bonusPct, aurEff->GetAmount());
- AddPct(totalDamagePercentMod, bonusPct);
- break;
- }
- // Death Strike
- if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
- {
- // Glyph of Death Strike
- // 2% more damage per 5 runic power, up to a maximum of 40%
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
- if (uint32 runic = std::min<uint32>(uint32(m_caster->GetPower(POWER_RUNIC_POWER) / 2.5f), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster)))
- AddPct(totalDamagePercentMod, runic);
- break;
- }
- // Obliterate (12.5% more damage per disease)
- if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
- {
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), false) / 2.0f;
- // Death Knight T8 Melee 4P Bonus
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
- AddPct(bonusPct, aurEff->GetAmount());
- AddPct(totalDamagePercentMod, bonusPct);
- break;
- }
- // Blood-Caked Strike - Blood-Caked Blade
- if (m_spellInfo->SpellIconID == 1736)
- {
- AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
- break;
- }
- // Heart Strike
- if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
- {
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID());
- // Death Knight T8 Melee 4P Bonus
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
- AddPct(bonusPct, aurEff->GetAmount());
-
- AddPct(totalDamagePercentMod, bonusPct);
+ if (SpellEffectInfo const* effect = GetEffect(EFFECT_2))
+ {
+ float bonusPct = effect->CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f;
+ // Death Knight T8 Melee 4P Bonus
+ if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
+ AddPct(bonusPct, aurEff->GetAmount());
+ AddPct(totalDamagePercentMod, bonusPct);
+ }
break;
}
break;
@@ -3038,20 +2981,22 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
bool normalized = false;
float weaponDamagePercentMod = 1.0f;
- for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- switch (m_spellInfo->Effects[j].Effect)
+ if (!effect)
+ continue;
+ switch (effect->Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
- fixed_bonus += CalculateDamage(j, unitTarget);
+ fixed_bonus += CalculateDamage(effect->EffectIndex, unitTarget);
break;
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
- fixed_bonus += CalculateDamage(j, unitTarget);
+ fixed_bonus += CalculateDamage(effect->EffectIndex, unitTarget);
normalized = true;
break;
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
- ApplyPct(weaponDamagePercentMod, CalculateDamage(j, unitTarget));
+ ApplyPct(weaponDamagePercentMod, CalculateDamage(effect->EffectIndex, unitTarget));
break;
default:
break; // not weapon damage effect, just skip
@@ -3083,11 +3028,13 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
int32 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
// Sequence is important
- for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
+ if (!effect)
+ continue;
// We assume that a spell have at most one fixed_bonus
// and at most one weaponDamagePercentMod
- switch (m_spellInfo->Effects[j].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
@@ -3189,7 +3136,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 gameobject_id = GetEffect(effIndex)->MiscValue;
GameObject* pGameObj = new GameObject;
@@ -3321,7 +3268,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
case 55693: // Remove Collapsing Cave Aura
if (!unitTarget)
return;
- unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].CalcValue());
+ unitTarget->RemoveAurasDueToSpell(GetEffect(effIndex)->CalcValue());
break;
// Bending Shinbone
case 8856:
@@ -3455,7 +3402,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
case 45151:
{
//Workaround for Range ... should be global for every ScriptEffect
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = GetEffect(effIndex)->CalcRadius();
if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->GetDistance(m_caster) >= radius && !unitTarget->HasAura(46394) && unitTarget != m_caster)
unitTarget->CastSpell(unitTarget, 46394, true);
@@ -3567,7 +3514,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
return;
float x, y, z;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = GetEffect(effIndex)->CalcRadius();
for (uint8 i = 0; i < 15; ++i)
{
m_caster->GetRandomPoint(*destTarget, radius, x, y, z);
@@ -3613,8 +3560,9 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effIndex != 0)
return;
- uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
- uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
+ // Effects for 58418 and 58420 are all DIFFICULTY_NONE so always valid
+ uint32 spellID = GetEffect(EFFECT_0)->CalcValue();
+ uint32 questID = GetEffect(EFFECT_1)->CalcValue();
if (unitTarget->ToPlayer()->GetQuestStatus(questID) == QUEST_STATUS_COMPLETE)
unitTarget->CastSpell(unitTarget, spellID, true);
@@ -3664,7 +3612,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
{
/// @todo a hack, range = 11, should after some time cast, otherwise too far
m_caster->CastSpell(parent, 62496, true);
- unitTarget->CastSpell(parent, m_spellInfo->Effects[EFFECT_0].CalcValue());
+ unitTarget->CastSpell(parent, GetEffect(EFFECT_0)->CalcValue()); // DIFFICULTY_NONE, so effect always valid
}
}
}
@@ -3856,7 +3804,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
//CREATE DUEL FLAG OBJECT
GameObject* pGameObj = new GameObject;
- uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 gameobject_id = GetEffect(effIndex)->MiscValue;
Map* map = m_caster->GetMap();
if (!pGameObj->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), gameobject_id,
@@ -3981,7 +3929,7 @@ void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/)
ScriptInfo activateCommand;
activateCommand.command = SCRIPT_COMMAND_ACTIVATE_OBJECT;
- // int32 unk = m_spellInfo->Effects[effIndex].MiscValue; // This is set for EffectActivateObject spells; needs research
+ // int32 unk = GetEffect(effIndex)->MiscValue; // This is set for EffectActivateObject spells; needs research
gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, 0, m_caster, gameObjTarget);
}
@@ -4020,7 +3968,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
}
// apply new one
- if (uint32 newGlyph = m_spellInfo->Effects[effIndex].MiscValue)
+ if (uint32 newGlyph = GetEffect(effIndex)->MiscValue)
{
if (GlyphPropertiesEntry const* newGlyphProperties = sGlyphPropertiesStore.LookupEntry(newGlyph))
{
@@ -4078,9 +4026,9 @@ void Spell::EffectEnchantHeldItem(SpellEffIndex effIndex)
if (!item->IsEquipped())
return;
- if (m_spellInfo->Effects[effIndex].MiscValue)
+ if (GetEffect(effIndex)->MiscValue)
{
- uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchant_id = GetEffect(effIndex)->MiscValue;
int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
if (!duration)
duration = damage;//+1; //Base points after ..
@@ -4174,7 +4122,7 @@ void Spell::EffectFeedPet(SpellEffIndex effIndex)
player->DestroyItemCount(foodItem, count, true);
/// @todo fix crash when a spell has two effects, both pointed at the same item target
- m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, NULL, NULL, true);
+ m_caster->CastCustomSpell(pet, GetEffect(effIndex)->TriggerSpell, &benefit, NULL, NULL, true);
}
void Spell::EffectDismissPet(SpellEffIndex effIndex)
@@ -4196,8 +4144,8 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 go_id = m_spellInfo->Effects[effIndex].MiscValue;
- uint8 slot = m_spellInfo->Effects[effIndex].Effect - SPELL_EFFECT_SUMMON_OBJECT_SLOT1;
+ uint32 go_id = GetEffect(effIndex)->MiscValue;
+ uint8 slot = GetEffect(effIndex)->Effect - SPELL_EFFECT_SUMMON_OBJECT_SLOT1;
ObjectGuid guid = m_caster->m_ObjectSlot[slot];
if (!guid.IsEmpty())
{
@@ -4332,7 +4280,7 @@ void Spell::EffectReputation(SpellEffIndex effIndex)
int32 repChange = damage;
- uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 factionId = GetEffect(effIndex)->MiscValue;
FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
if (!factionEntry)
@@ -4352,7 +4300,7 @@ void Spell::EffectQuestComplete(SpellEffIndex effIndex)
return;
Player* player = unitTarget->ToPlayer();
- uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 questId = GetEffect(effIndex)->MiscValue;
if (questId)
{
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
@@ -4396,7 +4344,7 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex)
if (damage < 0)
{
health = uint32(-damage);
- mana = m_spellInfo->Effects[effIndex].MiscValue;
+ mana = GetEffect(effIndex)->MiscValue;
}
// percent case
else
@@ -4509,13 +4457,13 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex)
unitTarget->InterruptNonMeleeSpells(true);
float ratio = 0.1f;
- float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
+ float speedxy = float(GetEffect(effIndex)->MiscValue) * ratio;
float speedz = float(damage) * ratio;
if (speedxy < 0.1f && speedz < 0.1f)
return;
float x, y;
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
+ if (GetEffect(effIndex)->Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
{
if (m_targets.HasDst())
destTarget->GetPosition(x, y);
@@ -4538,7 +4486,7 @@ void Spell::EffectLeapBack(SpellEffIndex effIndex)
if (!unitTarget)
return;
- float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue)/10;
+ float speedxy = float(GetEffect(effIndex)->MiscValue)/10;
float speedz = float(damage/10);
//1891: Disengage
m_caster->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891);
@@ -4553,7 +4501,7 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex)
return;
Player* player = unitTarget->ToPlayer();
- uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 quest_id = GetEffect(effIndex)->MiscValue;
Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
@@ -4595,7 +4543,7 @@ void Spell::EffectSendTaxi(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
+ unitTarget->ToPlayer()->ActivateTaxiPathTo(GetEffect(effIndex)->MiscValue, m_spellInfo->Id);
}
void Spell::EffectPullTowards(SpellEffIndex effIndex)
@@ -4607,7 +4555,7 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
return;
Position pos;
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
+ if (GetEffect(effIndex)->Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
{
if (m_targets.HasDst())
pos.Relocate(*destTarget);
@@ -4619,7 +4567,7 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
pos.Relocate(m_caster);
}
- float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f;
+ float speedXY = float(GetEffect(effIndex)->MiscValue) * 0.1f;
float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
@@ -4633,7 +4581,7 @@ void Spell::EffectDispelMechanic(SpellEffIndex effIndex)
if (!unitTarget)
return;
- uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 mechanic = GetEffect(effIndex)->MiscValue;
DispelList dispel_list;
Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
@@ -4752,7 +4700,7 @@ void Spell::EffectDurabilityDamage(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
+ int32 slot = GetEffect(effIndex)->MiscValue;
// -1 means all player equipped items and -2 all items
if (slot < 0)
@@ -4781,7 +4729,7 @@ void Spell::EffectDurabilityDamagePCT(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
+ int32 slot = GetEffect(effIndex)->MiscValue;
// FIXME: some spells effects have value -1/-2
// Possibly its mean -1 all player equipped items and -2 all items
@@ -4818,7 +4766,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 name_id = GetEffect(effIndex)->MiscValue;
GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
@@ -4833,9 +4781,9 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
if (m_targets.HasDst())
destTarget->GetPosition(fx, fy, fz);
//FIXME: this can be better check for most objects but still hack
- else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
+ else if (GetEffect(effIndex)->HasRadius() && m_spellInfo->Speed == 0)
{
- float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
+ float dis = GetEffect(effIndex)->CalcRadius(m_originalCaster);
m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
}
else
@@ -5057,7 +5005,7 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
DispelChargesList steal_list;
// Create dispel mask by dispel type
- uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
+ uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(GetEffect(effIndex)->MiscValue));
Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
@@ -5157,7 +5105,7 @@ void Spell::EffectKillCreditPersonal(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
+ unitTarget->ToPlayer()->KilledMonsterCredit(GetEffect(effIndex)->MiscValue);
}
void Spell::EffectKillCredit(SpellEffIndex effIndex)
@@ -5168,7 +5116,7 @@ void Spell::EffectKillCredit(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
+ int32 creatureEntry = GetEffect(effIndex)->MiscValue;
if (!creatureEntry)
{
if (m_spellInfo->Id == 42793) // Burn Body
@@ -5187,7 +5135,7 @@ void Spell::EffectQuestFail(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
+ unitTarget->ToPlayer()->FailQuest(GetEffect(effIndex)->MiscValue);
}
void Spell::EffectQuestStart(SpellEffIndex effIndex)
@@ -5202,7 +5150,7 @@ void Spell::EffectQuestStart(SpellEffIndex effIndex)
if (!player)
return;
- if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(GetEffect(effIndex)->MiscValue))
{
if (!player->CanTakeQuest(quest, false))
return;
@@ -5234,10 +5182,10 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex)
if (count == 0) count = 1;
for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
{
- if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
+ if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(GetEffect(effIndex)->MiscValue))
{
if (m_spellInfo->Id == 45529)
- if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
+ if (player->GetBaseRune(j) != RuneType(GetEffect(effIndex)->MiscValueB))
continue;
player->SetRuneCooldown(j, 0);
--count;
@@ -5250,7 +5198,7 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex)
for (uint32 l = 0; l + 1 < MAX_RUNES && count > 0; ++l)
{
// Check if both runes are on cd as that is the only time when this needs to come into effect
- if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l+1) && player->GetCurrentRune(l+1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
+ if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(GetEffect(effIndex)->MiscValueB)) && (player->GetRuneCooldown(l+1) && player->GetCurrentRune(l+1) == RuneType(GetEffect(effIndex)->MiscValueB)))
{
// Should always update the rune with the lowest cd
if (l + 1 < MAX_RUNES && player->GetRuneCooldown(l) >= player->GetRuneCooldown(l+1))
@@ -5288,7 +5236,7 @@ void Spell::EffectCreateTamedPet(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || !unitTarget->GetPetGUID().IsEmpty() || unitTarget->getClass() != CLASS_HUNTER)
return;
- uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 creatureEntry = GetEffect(effIndex)->MiscValue;
Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
if (!pet)
return;
@@ -5320,7 +5268,7 @@ void Spell::EffectDiscoverTaxi(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 nodeid = GetEffect(effIndex)->MiscValue;
if (sTaxiNodesStore.LookupEntry(nodeid))
unitTarget->ToPlayer()->GetSession()->SendDiscoverNewTaxiNode(nodeid);
}
@@ -5382,7 +5330,7 @@ void Spell::EffectGameObjectSetDestructionState(SpellEffIndex effIndex)
return;
Player* player = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
- gameObjTarget->SetDestructibleState(GameObjectDestructibleState(m_spellInfo->Effects[effIndex].MiscValue), player, true);
+ gameObjTarget->SetDestructibleState(GameObjectDestructibleState(GetEffect(effIndex)->MiscValue), player, true);
}
void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numGuardians)
@@ -5472,7 +5420,7 @@ void Spell::EffectPlayMusic(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 soundid = GetEffect(effIndex)->MiscValue;
if (!sSoundEntriesStore.LookupEntry(soundid))
{
@@ -5529,7 +5477,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex)
break;
}
- uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 soundId = GetEffect(effIndex)->MiscValue;
if (!sSoundEntriesStore.LookupEntry(soundId))
{
@@ -5548,7 +5496,7 @@ void Spell::EffectRemoveAura(SpellEffIndex effIndex)
if (!unitTarget)
return;
// there may be need of specifying casterguid of removed auras
- unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
+ unitTarget->RemoveAurasDueToSpell(GetEffect(effIndex)->TriggerSpell);
}
void Spell::EffectDamageFromMaxHealthPCT(SpellEffIndex /*effIndex*/)
@@ -5570,7 +5518,7 @@ void Spell::EffectGiveCurrency(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->ModifyCurrency(m_spellInfo->Effects[effIndex].MiscValue, damage);
+ unitTarget->ToPlayer()->ModifyCurrency(GetEffect(effIndex)->MiscValue, damage);
}
void Spell::EffectCastButtons(SpellEffIndex effIndex)
@@ -5582,8 +5530,8 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex)
return;
Player* p_caster = m_caster->ToPlayer();
- uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
- uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
+ uint32 button_id = GetEffect(effIndex)->MiscValue + 132;
+ uint32 n_buttons = GetEffect(effIndex)->MiscValueB;
for (; n_buttons; --n_buttons, ++button_id)
{
@@ -5628,21 +5576,23 @@ void Spell::EffectRechargeManaGem(SpellEffIndex /*effIndex*/)
if (!player)
return;
-
- uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
-
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
- if (!pProto)
+ if (SpellEffectInfo const* effect = GetEffect(EFFECT_0))
{
- player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
- return;
- }
+ uint32 item_id = effect->ItemType;
- if (Item* pItem = player->GetItemByEntry(item_id))
- {
- for (int x = 0; x < pProto->Effects.size(); ++x)
- pItem->SetSpellCharges(x, pProto->Effects[x].Charges);
- pItem->SetState(ITEM_CHANGED, player);
+ ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
+ if (!pProto)
+ {
+ player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
+ return;
+ }
+
+ if (Item* pItem = player->GetItemByEntry(item_id))
+ {
+ for (int x = 0; x < pProto->Effects.size(); ++x)
+ pItem->SetSpellCharges(x, pProto->Effects[x].Charges);
+ pItem->SetState(ITEM_CHANGED, player);
+ }
}
}
@@ -5659,8 +5609,8 @@ void Spell::EffectBind(SpellEffIndex effIndex)
WorldLocation homeLoc;
uint32 areaId = player->GetAreaId();
- if (m_spellInfo->Effects[effIndex].MiscValue)
- areaId = m_spellInfo->Effects[effIndex].MiscValue;
+ if (GetEffect(effIndex)->MiscValue)
+ areaId = GetEffect(effIndex)->MiscValue;
if (m_targets.HasDst())
homeLoc.WorldRelocate(*destTarget);
@@ -5696,7 +5646,7 @@ void Spell::EffectSummonRaFFriend(SpellEffIndex effIndex)
if (m_caster->GetTypeId() != TYPEID_PLAYER || !unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- m_caster->CastSpell(unitTarget, m_spellInfo->Effects[effIndex].TriggerSpell, true);
+ m_caster->CastSpell(unitTarget, GetEffect(effIndex)->TriggerSpell, true);
}
void Spell::EffectUnlockGuildVaultTab(SpellEffIndex effIndex)
@@ -5707,7 +5657,7 @@ void Spell::EffectUnlockGuildVaultTab(SpellEffIndex effIndex)
// Safety checks done in Spell::CheckCast
Player* caster = m_caster->ToPlayer();
if (Guild* guild = caster->GetGuild())
- guild->HandleBuyBankTab(caster->GetSession(), m_spellInfo->Effects[effIndex].BasePoints - 1); // Bank tabs start at zero internally
+ guild->HandleBuyBankTab(caster->GetSession(), GetEffect(effIndex)->BasePoints - 1); // Bank tabs start at zero internally
}
void Spell::EffectResurrectWithAura(SpellEffIndex effIndex)
@@ -5731,8 +5681,8 @@ void Spell::EffectResurrectWithAura(SpellEffIndex effIndex)
uint32 health = target->CountPctFromMaxHealth(damage);
uint32 mana = CalculatePct(target->GetMaxPower(POWER_MANA), damage);
uint32 resurrectAura = 0;
- if (sSpellMgr->GetSpellInfo(GetSpellInfo()->Effects[effIndex].TriggerSpell))
- resurrectAura = GetSpellInfo()->Effects[effIndex].TriggerSpell;
+ if (sSpellMgr->GetSpellInfo(GetEffect(effIndex)->TriggerSpell))
+ resurrectAura = GetEffect(effIndex)->TriggerSpell;
if (resurrectAura && target->HasAura(resurrectAura))
return;
@@ -5754,9 +5704,9 @@ void Spell::EffectCreateAreaTrigger(SpellEffIndex effIndex)
pos = destTarget->GetPosition();
// trigger entry/miscvalue relation is currently unknown, for now use MiscValue as trigger entry
- uint32 triggerEntry = GetSpellInfo()->Effects[effIndex].MiscValue;
+ uint32 triggerEntry = GetEffect(effIndex)->MiscValue;
AreaTrigger * areaTrigger = new AreaTrigger;
if (!areaTrigger->CreateAreaTrigger(sObjectMgr->GetGenerator<HighGuid::AreaTrigger>()->Generate(), triggerEntry, GetCaster(), GetSpellInfo(), pos))
delete areaTrigger;
-}
+} \ No newline at end of file
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 3c4cf37b4e3..17517824709 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -866,7 +866,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectInfoMap effects)
{
Id = spellEntry->ID;
- Effects = effects;
+ _effects = effects;
SpellName = spellEntry->Name_lang;
//Rank = spellEntry->Rank;
@@ -1041,9 +1041,9 @@ uint32 SpellInfo::GetCategory() const
bool SpellInfo::HasEffect(uint32 difficulty, SpellEffectName effect) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectInfo const* eff : effects)
{
- if ((*itr)->IsEffect(effect))
+ if (eff && eff->IsEffect(effect))
return true;
}
return false;
@@ -1052,19 +1052,20 @@ bool SpellInfo::HasEffect(uint32 difficulty, SpellEffectName effect) const
bool SpellInfo::HasAura(uint32 difficulty, AuraType aura) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectInfo const* effect : effects)
{
- if ((*itr)->IsAura(aura))
+ if (effect && effect->IsAura(aura))
return true;
}
+ return false;
}
bool SpellInfo::HasAreaAuraEffect(uint32 difficulty) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectInfo const* effect : effects)
{
- if ((*itr)->IsAreaAuraEffect())
+ if (effect && effect->IsAreaAuraEffect())
return true;
}
return false;
@@ -1072,33 +1073,38 @@ bool SpellInfo::HasAreaAuraEffect(uint32 difficulty) const
bool SpellInfo::IsExplicitDiscovery() const
{
- return ((Effects[0].Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM
- || Effects[0].Effect == SPELL_EFFECT_CREATE_ITEM_2)
- && Effects[1].Effect == SPELL_EFFECT_SCRIPT_EFFECT)
+ SpellEffectInfo const* effect0 = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ SpellEffectInfo const* effect1 = GetEffect(DIFFICULTY_NONE, EFFECT_1);
+
+ return ((effect0 && (effect0->Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM || effect0->Effect == SPELL_EFFECT_CREATE_ITEM_2))
+ && effect1 && effect1->Effect == SPELL_EFFECT_SCRIPT_EFFECT)
|| Id == 64323;
}
bool SpellInfo::IsLootCrafting() const
{
- return (Effects[0].Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM ||
+ SpellEffectInfo const* effect0 = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ return effect0 && (effect0->Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM ||
// different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item
- (Effects[0].Effect == SPELL_EFFECT_CREATE_ITEM_2 &&
- ((TotemCategory[0] != 0 || (Totem[0] != 0 && SpellIconID == 1)) || Effects[0].ItemType == 0)));
+ (effect0->Effect == SPELL_EFFECT_CREATE_ITEM_2 &&
+ ((TotemCategory[0] != 0 || (Totem[0] != 0 && SpellIconID == 1)) || effect0->ItemType == 0)));
}
bool SpellInfo::IsQuestTame() const
{
- return Effects[0].Effect == SPELL_EFFECT_THREAT && Effects[1].Effect == SPELL_EFFECT_APPLY_AURA && Effects[1].ApplyAuraName == SPELL_AURA_DUMMY;
+ SpellEffectInfo const* effect0 = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ SpellEffectInfo const* effect1 = GetEffect(DIFFICULTY_NONE, EFFECT_1);
+ return effect0 && effect1 && effect0->Effect == SPELL_EFFECT_THREAT && effect1->Effect == SPELL_EFFECT_APPLY_AURA && effect1->ApplyAuraName == SPELL_AURA_DUMMY;
}
bool SpellInfo::IsProfessionOrRiding(uint32 difficulty) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectInfo const* effect : effects)
{
- if ((*itr)->Effect == SPELL_EFFECT_SKILL)
+ if ((effect && effect->Effect == SPELL_EFFECT_SKILL))
{
- uint32 skill = (*itr)->MiscValue;
+ uint32 skill = effect->MiscValue;
if (IsProfessionOrRidingSkill(skill))
return true;
@@ -1110,11 +1116,11 @@ bool SpellInfo::IsProfessionOrRiding(uint32 difficulty) const
bool SpellInfo::IsProfession(uint32 difficulty) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectInfo const* effect : effects)
{
- if ((*itr)->Effect == SPELL_EFFECT_SKILL)
+ if (effect && effect->Effect == SPELL_EFFECT_SKILL)
{
- uint32 skill = (*itr)->MiscValue;
+ uint32 skill = effect->MiscValue;
if (IsProfessionSkill(skill))
return true;
@@ -1126,11 +1132,11 @@ bool SpellInfo::IsProfession(uint32 difficulty) const
bool SpellInfo::IsPrimaryProfession(uint32 difficulty) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for(SpellEffectInfo const* effect : effects)
{
- if ((*itr)->Effect == SPELL_EFFECT_SKILL)
+ if (effect && effect->Effect == SPELL_EFFECT_SKILL)
{
- uint32 skill = (*itr)->MiscValue;
+ uint32 skill = effect->MiscValue;
if (IsPrimaryProfessionSkill(skill))
return true;
@@ -1175,9 +1181,9 @@ bool SpellInfo::IsAbilityOfSkillType(uint32 skillType) const
bool SpellInfo::IsAffectingArea(uint32 difficulty) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectInfo const* effect : effects)
{
- if ((*itr)->IsEffect() && ((*itr)->IsTargetingArea() || (*itr)->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || (*itr)->IsAreaAuraEffect()))
+ if (effect && effect->IsEffect() && (effect->IsTargetingArea() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect->IsAreaAuraEffect()))
return true;
}
return false;
@@ -1187,9 +1193,9 @@ bool SpellInfo::IsAffectingArea(uint32 difficulty) const
bool SpellInfo::IsTargetingArea(uint32 difficulty) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- for (SpellEffectInfoVector::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ for (SpellEffectInfo const* effect : effects)
{
- if ((*itr)->IsEffect() && (*itr)->IsTargetingArea())
+ if (effect && effect->IsEffect() && effect->IsTargetingArea())
return true;
}
return false;
@@ -1200,7 +1206,7 @@ bool SpellInfo::NeedsExplicitUnitTarget() const
return (GetExplicitTargetMask() & TARGET_FLAG_UNIT_MASK) != 0;
}
-bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const
+bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) const
{
if (NeedsExplicitUnitTarget())
return true;
@@ -1220,12 +1226,13 @@ bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) con
if (triggeringSpell->IsChanneled())
{
uint32 mask = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
{
- if (Effects[i].TargetA.GetTarget() != TARGET_UNIT_CASTER && Effects[i].TargetA.GetTarget() != TARGET_DEST_CASTER
- && Effects[i].TargetB.GetTarget() != TARGET_UNIT_CASTER && Effects[i].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 |= Effects[i].GetProvidedTargetMask();
+ mask |= effect->GetProvidedTargetMask();
}
}
@@ -1263,19 +1270,20 @@ bool SpellInfo::IsStackableWithRanks() const
return false;
// All stance spells. if any better way, change it.
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(DIFFICULTY_NONE);
+ for (SpellEffectInfo const* effect : effects)
{
switch (SpellFamilyName)
{
case SPELLFAMILY_PALADIN:
// Paladin aura Spell
- if (Effects[i].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 (Effects[i].Effect == SPELL_EFFECT_APPLY_AURA &&
- Effects[i].ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
+ if (effect->Effect == SPELL_EFFECT_APPLY_AURA &&
+ effect->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
return false;
break;
}
@@ -1283,9 +1291,9 @@ bool SpellInfo::IsStackableWithRanks() const
return true;
}
-bool SpellInfo::IsPassiveStackableWithRanks() const
+bool SpellInfo::IsPassiveStackableWithRanks(uint32 difficulty) const
{
- return IsPassive() && !HasEffect(SPELL_EFFECT_APPLY_AURA);
+ return IsPassive() && !HasEffect(difficulty, SPELL_EFFECT_APPLY_AURA);
}
bool SpellInfo::IsMultiSlotAura() const
@@ -1665,12 +1673,12 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
// aura limitations
if (player)
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(player->GetMap()->GetDifficulty()))
{
- if (!Effects[i].IsAura())
+ if (!effect || !effect->IsAura())
continue;
- switch (Effects[i].ApplyAuraName)
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_FLY:
{
@@ -1680,7 +1688,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
}
case SPELL_AURA_MOUNTED:
{
- if (Effects[i].MiscValueB && !player->GetMountCapability(Effects[i].MiscValueB))
+ if (effect->MiscValueB && !player->GetMountCapability(effect->MiscValueB))
return SPELL_FAILED_NOT_HERE;
break;
}
@@ -1829,14 +1837,14 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
return SPELL_FAILED_TARGET_AURASTATE;
}
- if (TargetAuraSpell && !unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(TargetAuraSpell, caster)))
+ if (TargetAuraSpell && !unitTarget->HasAura(TargetAuraSpell))
return SPELL_FAILED_TARGET_AURASTATE;
- if (ExcludeTargetAuraSpell && unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(ExcludeTargetAuraSpell, caster)))
+ if (ExcludeTargetAuraSpell && unitTarget->HasAura(ExcludeTargetAuraSpell))
return SPELL_FAILED_TARGET_AURASTATE;
if (unitTarget->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
- if (HasEffect(SPELL_EFFECT_SELF_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT_NEW))
+ if (HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_SELF_RESURRECT) || HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_RESURRECT) || HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_RESURRECT_NEW))
return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
return SPELL_CAST_OK;
@@ -1887,18 +1895,18 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
if (vehicle)
{
uint16 checkMask = 0;
- for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
{
- if (Effects[effIndex].ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
+ if (effect && effect->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
{
- SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(Effects[effIndex].MiscValue);
+ SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect->MiscValue);
if (shapeShiftFromEntry && (shapeShiftFromEntry->Flags & 1) == 0) // unk flag
checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
break;
}
}
- if (HasAura(SPELL_AURA_MOUNTED))
+ if (HasAura(caster->GetMap()->GetDifficulty(), SPELL_AURA_MOUNTED))
checkMask |= VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL;
if (!checkMask)
@@ -1912,12 +1920,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 (uint32 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
{
- if (Effects[i].Effect != SPELL_EFFECT_SUMMON)
+ if (!effect || effect->Effect != SPELL_EFFECT_SUMMON)
continue;
- SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(Effects[i].MiscValueB);
+ SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect->MiscValueB);
if (props && props->Category != SUMMON_CATEGORY_WILD)
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
}
@@ -1957,19 +1965,30 @@ uint32 SpellInfo::GetAllEffectsMechanicMask() const
uint32 mask = 0;
if (Mechanic)
mask |= 1 << Mechanic;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsEffect() && Effects[i].Mechanic)
- mask |= 1 << Effects[i].Mechanic;
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && effect->IsEffect() && effect->Mechanic)
+ mask |= 1 << effect->Mechanic;
+ }
+ }
return mask;
}
-uint32 SpellInfo::GetEffectMechanicMask(uint8 effIndex) const
+uint32 SpellInfo::GetEffectMechanicMask(uint32 effIndex) const
{
uint32 mask = 0;
if (Mechanic)
mask |= 1 << Mechanic;
- if (Effects[effIndex].IsEffect() && Effects[effIndex].Mechanic)
- mask |= 1 << Effects[effIndex].Mechanic;
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && effect->EffectIndex == effIndex && effect->IsEffect() && effect->Mechanic)
+ mask |= 1 << effect->Mechanic;
+ }
+ }
return mask;
}
@@ -1978,28 +1997,34 @@ uint32 SpellInfo::GetSpellMechanicMaskByEffectMask(uint32 effectMask) const
uint32 mask = 0;
if (Mechanic)
mask |= 1 << Mechanic;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if ((effectMask & (1 << i)) && Effects[i].Mechanic)
- mask |= 1 << Effects[i].Mechanic;
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && (effectMask & (1 << effect->EffectIndex)) && effect->Mechanic)
+ mask |= 1 << effect->Mechanic;
+ }
+ }
return mask;
}
-Mechanics SpellInfo::GetEffectMechanic(uint8 effIndex) const
+Mechanics SpellInfo::GetEffectMechanic(uint32 effIndex, uint32 difficulty) const
{
- if (Effects[effIndex].IsEffect() && Effects[effIndex].Mechanic)
- return Mechanics(Effects[effIndex].Mechanic);
+ SpellEffectInfo const* effect = GetEffect(difficulty, effIndex);
+ if (effect && effect->IsEffect() && effect->Mechanic)
+ return Mechanics(effect->Mechanic);
if (Mechanic)
return Mechanics(Mechanic);
return MECHANIC_NONE;
}
-bool SpellInfo::HasAnyEffectMechanic() const
+/*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
{
@@ -2020,7 +2045,7 @@ uint32 SpellInfo::GetExplicitTargetMask() const
return ExplicitTargetMask;
}
-AuraStateType SpellInfo::GetAuraState() const
+AuraStateType SpellInfo::GetAuraState(uint32 difficulty) const
{
// Seals
if (GetSpellSpecific() == SPELL_SPECIFIC_SEAL)
@@ -2063,10 +2088,10 @@ AuraStateType SpellInfo::GetAuraState() const
return AURA_STATE_BLEEDING;
if (GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsAura() && (Effects[i].ApplyAuraName == SPELL_AURA_MOD_STUN
- || Effects[i].ApplyAuraName == SPELL_AURA_MOD_ROOT))
- return AURA_STATE_FROZEN;
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(difficulty))
+ if (effect && effect->IsAura() && (effect->ApplyAuraName == SPELL_AURA_MOD_STUN
+ || effect->ApplyAuraName == SPELL_AURA_MOD_ROOT))
+ return AURA_STATE_FROZEN;
switch (Id)
{
@@ -2091,24 +2116,27 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
{
bool food = false;
bool drink = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (!Effects[i].IsAura())
- continue;
- switch (Effects[i].ApplyAuraName)
+ for (SpellEffectInfo const* effect : itr->second)
{
- // Food
+ if (!effect || !effect->IsAura())
+ continue;
+ switch (effect->ApplyAuraName)
+ {
+ // Food
case SPELL_AURA_MOD_REGEN:
case SPELL_AURA_OBS_MOD_HEALTH:
food = true;
break;
- // Drink
+ // Drink
case SPELL_AURA_MOD_POWER_REGEN:
case SPELL_AURA_OBS_MOD_POWER:
drink = true;
break;
default:
break;
+ }
}
}
@@ -2148,8 +2176,8 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
// Arcane brillance and Arcane intelect (normal check fails because of flags difference)
if (SpellFamilyFlags[0] & 0x400)
return SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE;
-
- if ((SpellFamilyFlags[0] & 0x1000000) && Effects[0].ApplyAuraName == SPELL_AURA_MOD_CONFUSE)
+ SpellEffectInfo const* effect = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (effect && (SpellFamilyFlags[0] & 0x1000000) && effect->ApplyAuraName == SPELL_AURA_MOD_CONFUSE)
return SPELL_SPECIFIC_MAGE_POLYMORPH;
break;
@@ -2235,12 +2263,14 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
break;
}
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (Effects[i].Effect == SPELL_EFFECT_APPLY_AURA)
+ for (SpellEffectInfo const* effect : itr->second)
{
- switch (Effects[i].ApplyAuraName)
+ if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
+ switch (effect->ApplyAuraName)
+ {
case SPELL_AURA_MOD_CHARM:
case SPELL_AURA_MOD_POSSESS_PET:
case SPELL_AURA_MOD_POSSESS:
@@ -2253,10 +2283,10 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
case SPELL_AURA_TRACK_RESOURCES:
case SPELL_AURA_TRACK_STEALTHED:
return SPELL_SPECIFIC_TRACKER;
+ }
}
}
}
-
return SPELL_SPECIFIC_NORMAL;
}
@@ -2326,7 +2356,7 @@ uint32 SpellInfo::CalcCastTime(uint8 level, Spell* spell /*= NULL*/) const
return (castTime > 0) ? uint32(castTime) : 0;
}
-uint32 SpellInfo::GetMaxTicks() const
+uint32 SpellInfo::GetMaxTicks(uint32 difficulty) const
{
int32 DotDuration = GetDuration();
if (DotDuration == 0)
@@ -2336,16 +2366,16 @@ uint32 SpellInfo::GetMaxTicks() const
if (DotDuration > 30000)
DotDuration = 30000;
- for (uint8 x = 0; x < MAX_SPELL_EFFECTS; x++)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(difficulty))
{
- if (Effects[x].Effect == SPELL_EFFECT_APPLY_AURA)
- switch (Effects[x].ApplyAuraName)
+ if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_PERIODIC_LEECH:
- if (Effects[x].ApplyAuraPeriod != 0)
- return DotDuration / Effects[x].ApplyAuraPeriod;
+ if (effect->ApplyAuraPeriod != 0)
+ return DotDuration / effect->ApplyAuraPeriod;
break;
}
}
@@ -2507,13 +2537,13 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const
return this;
bool needRankSelection = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (IsPositiveEffect(i) &&
- (Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
- Effects[i].Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
- Effects[i].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
- !Effects[i].ScalingMultiplier)
+ if (effect && IsPositiveEffect(effect->Effect) &&
+ (effect->Effect == SPELL_EFFECT_APPLY_AURA ||
+ effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
+ !effect->ScalingMultiplier)
{
needRankSelection = true;
break;
@@ -2565,32 +2595,35 @@ void SpellInfo::_InitializeExplicitTargetMask()
bool dstSet = false;
uint32 targetMask = Targets;
// prepare target mask using effect target entries
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (!Effects[i].IsEffect())
- continue;
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (!effect || !effect->IsEffect())
+ continue;
- targetMask |= Effects[i].TargetA.GetExplicitTargetMask(srcSet, dstSet);
- targetMask |= Effects[i].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 (Effects[i].GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
- continue;
+ // 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)
+ continue;
- // extend explicit target mask only if valid targets for effect could not be provided by target types
- uint32 effectTargetMask = Effects[i].GetMissingTargetMask(srcSet, dstSet, targetMask);
+ // extend explicit target mask only if valid targets for effect could not be provided by target types
+ 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)
- effectTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_DEST_LOCATION);
+ // don't add explicit object/dest flags when spell has no max range
+ if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
+ effectTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_DEST_LOCATION);
- targetMask |= effectTargetMask;
+ targetMask |= effectTargetMask;
+ }
}
ExplicitTargetMask = targetMask;
}
-bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
+bool SpellInfo::_IsPositiveEffect(uint32 effIndex, bool deep) const
{
// not found a single positive spell with this attribute
if (Attributes & SPELL_ATTR0_NEGATIVE_1)
@@ -2655,40 +2688,50 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
}
// Special case: effects which determine positivity of whole spell
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (Effects[i].IsAura() && Effects[i].ApplyAuraName == SPELL_AURA_MOD_STEALTH)
- return true;
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && effect->IsAura() && effect->ApplyAuraName == SPELL_AURA_MOD_STEALTH)
+ return true;
+ }
}
- switch (Effects[effIndex].Effect)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- case SPELL_EFFECT_DUMMY:
- // some explicitly required dummy effect sets
- switch (Id)
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (!effect || effect->EffectIndex != effIndex)
+ continue;
+
+ switch (effect->Effect)
{
+ case SPELL_EFFECT_DUMMY:
+ // some explicitly required dummy effect sets
+ switch (Id)
+ {
case 28441:
return false; // AB Effect 000
default:
break;
- }
- break;
- // always positive effects (check before target checks that provided non-positive result in some case for positive effects)
- case SPELL_EFFECT_HEAL:
- case SPELL_EFFECT_LEARN_SPELL:
- case SPELL_EFFECT_SKILL_STEP:
- case SPELL_EFFECT_HEAL_PCT:
- case SPELL_EFFECT_ENERGIZE_PCT:
- return true;
- case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
- return false;
+ }
+ break;
+ // always positive effects (check before target checks that provided non-positive result in some case for positive effects)
+ case SPELL_EFFECT_HEAL:
+ case SPELL_EFFECT_LEARN_SPELL:
+ case SPELL_EFFECT_SKILL_STEP:
+ case SPELL_EFFECT_HEAL_PCT:
+ case SPELL_EFFECT_ENERGIZE_PCT:
+ return true;
+ case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
+ return false;
- // non-positive aura use
- case SPELL_EFFECT_APPLY_AURA:
- case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
- {
- switch (Effects[effIndex].ApplyAuraName)
+ // non-positive aura use
+ case SPELL_EFFECT_APPLY_AURA:
+ case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
+ switch (effect->ApplyAuraName)
+ {
case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative)
case SPELL_AURA_MOD_STAT:
case SPELL_AURA_MOD_SKILL:
@@ -2696,16 +2739,16 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_MOD_HEALING_PCT:
case SPELL_AURA_MOD_HEALING_DONE:
case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE:
- if (Effects[effIndex].CalcValue() < 0)
+ if (effect->CalcValue() < 0)
return false;
break;
case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative)
- if (Effects[effIndex].CalcValue() > 0)
+ if (effect->CalcValue() > 0)
return false;
break;
case SPELL_AURA_MOD_CRIT_PCT:
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
- if (Effects[effIndex].CalcValue() > 0)
+ if (effect->CalcValue() > 0)
return true; // some expected positive spells have SPELL_ATTR1_NEGATIVE
break;
case SPELL_AURA_ADD_TARGET_TRIGGER:
@@ -2714,17 +2757,20 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
if (!deep)
{
- if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(Effects[effIndex].TriggerSpell))
+ if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect->TriggerSpell))
{
// negative targets of main spell return early
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator it = spellTriggeredProto->_effects.begin(); it != spellTriggeredProto->_effects.end(); ++it)
{
- if (!spellTriggeredProto->Effects[i].Effect)
- 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->Effects[i].TargetA.GetTarget(), spellTriggeredProto->Effects[i].TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(i, true))
- return false;
+ for (SpellEffectInfo const* eff : itr->second)
+ {
+ if (!eff || !eff->Effect)
+ 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(eff->TargetA.GetTarget(), eff->TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(eff->EffectIndex, true))
+ return false;
+ }
}
}
}
@@ -2732,9 +2778,23 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
// many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example)
break;
case SPELL_AURA_MOD_STUN: //have positive and negative spells, we can't sort its correctly at this moment.
- if (effIndex == 0 && Effects[1].Effect == 0 && Effects[2].Effect == 0)
+ {
+ bool more = false;
+ for (SpellEffectInfoMap::const_iterator i = _effects.begin(); i != _effects.end(); ++i)
+ {
+ for (SpellEffectInfo const* eff : i->second)
+ {
+ if (eff && eff->EffectIndex != 0)
+ {
+ more = true;
+ break;
+ }
+ }
+ }
+ if (effIndex == 0 && !more)
return false; // but all single stun aura spells is negative
break;
+ }
case SPELL_AURA_MOD_PACIFY_SILENCE:
if (Id == 24740) // Wisp Costume
return true;
@@ -2749,12 +2809,12 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
return false;
case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also.
// part of negative spell if cast at self (prevent cancel)
- if (Effects[effIndex].TargetA.GetTarget() == TARGET_UNIT_CASTER)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER)
return false;
break;
case SPELL_AURA_MOD_DECREASE_SPEED: // used in positive spells also
// part of positive spell if cast at self
- if (Effects[effIndex].TargetA.GetTarget() != TARGET_UNIT_CASTER)
+ if (effect->TargetA.GetTarget() != TARGET_UNIT_CASTER)
return false;
// but not this if this first effect (didn't find better check)
if (Attributes & SPELL_ATTR0_NEGATIVE_1 && effIndex == 0)
@@ -2763,7 +2823,7 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_MECHANIC_IMMUNITY:
{
// non-positive immunities
- switch (Effects[effIndex].MiscValue)
+ switch (effect->MiscValue)
{
case MECHANIC_BANDAGE:
case MECHANIC_SHIELD:
@@ -2779,10 +2839,10 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_ADD_PCT_MODIFIER:
{
// non-positive mods
- switch (Effects[effIndex].MiscValue)
+ switch (effect->MiscValue)
{
case SPELLMOD_COST: // dependent from bas point sign (negative -> positive)
- if (Effects[effIndex].CalcValue() > 0)
+ if (effect->CalcValue() > 0)
{
if (!deep)
{
@@ -2808,25 +2868,26 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
}
default:
break;
+ }
+ break;
+ }
+ default:
+ break;
}
- break;
- }
- default:
- break;
- }
-
- // non-positive targets
- if (!_IsPositiveTarget(Effects[effIndex].TargetA.GetTarget(), Effects[effIndex].TargetB.GetTarget()))
- return false;
- // negative spell if triggered spell is negative
- if (!deep && !Effects[effIndex].ApplyAuraName && Effects[effIndex].TriggerSpell)
- {
- if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(Effects[effIndex].TriggerSpell))
- if (!spellTriggeredProto->_IsPositiveSpell())
+ // non-positive targets
+ if (!_IsPositiveTarget(effect->TargetA.GetTarget(), effect->TargetB.GetTarget()))
return false;
- }
+ // negative spell if triggered spell is negative
+ if (!deep && !effect->ApplyAuraName && effect->TriggerSpell)
+ {
+ if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect->TriggerSpell))
+ if (!spellTriggeredProto->_IsPositiveSpell())
+ return false;
+ }
+ }
+ }
// ok, positive
return true;
}
@@ -2948,14 +3009,14 @@ void SpellInfo::_UnloadImplicitTargetConditionLists()
// find the same instances of ConditionList and delete them.
for (uint32 d = 0; d < DIFFICULTY_MAX; ++d)
{
- for (uint32 i = 0; i < Effects.size(); ++i)
+ for (uint32 i = 0; i < _effects.size(); ++i)
{
if (SpellEffectInfo const* effect = GetEffect(d, i))
{
ConditionList* cur = effect->ImplicitTargetConditions;
if (!cur)
continue;
- for (uint8 j = i; j < Effects.size(); ++j)
+ for (uint8 j = i; j < _effects.size(); ++j)
{
if (SpellEffectInfo const* eff = GetEffect(d, j))
{
@@ -2971,20 +3032,38 @@ void SpellInfo::_UnloadImplicitTargetConditionLists()
SpellEffectInfoVector SpellInfo::GetEffectsForDifficulty(uint32 difficulty) const
{
+ SpellEffectInfoVector effList;
+
+ // DIFFICULTY_NONE effects are the default effects, always active if current difficulty's effects don't overwrite
+ SpellEffectInfoMap::const_iterator itr = _effects.find(DIFFICULTY_NONE);
+ if (itr != _effects.end())
+ effList = itr->second;
+
// downscale difficulty if original was not found
- for (; difficulty >= DIFFICULTY_NONE; --difficulty)
+ // DIFFICULTY_NONE is already in our list
+ for (; difficulty > DIFFICULTY_NONE; --difficulty)
{
- SpellEffectInfoMap::const_iterator itr = Effects.find(difficulty);
- if (itr != Effects.end())
- return itr->second;
+ SpellEffectInfoMap::const_iterator itr = _effects.find(difficulty);
+ if (itr != _effects.end())
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ // overwrite any existing effect from DIFFICULTY_NONE
+ effList[effect->EffectIndex] = effect;
+ }
+ // if we found any effect in our difficulty then stop searching
+ break;
+ }
}
- return SpellEffectInfoVector();
+ if (effList.empty())
+ TC_LOG_ERROR("spells", "GetEffectsForDifficulty did not find any effects for spell %u in difficulty %u", Id, difficulty);
+ return effList;
}
SpellEffectInfo const* SpellInfo::GetEffect(uint32 difficulty, uint32 index) const
{
SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
- if (index >= effects.size())
+ if (index >= _effects.size())
return nullptr;
return effects[index];
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 36c8523dbf2..0383c214944 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -302,6 +302,8 @@ private:
typedef std::vector<SpellEffectInfo const*> SpellEffectInfoVector;
typedef std::unordered_map<uint32, SpellEffectInfoVector> SpellEffectInfoMap;
+typedef std::vector<AuraEffect*> AuraEffectVector;
+
class SpellInfo
{
public:
@@ -448,12 +450,12 @@ public:
bool IsAffectingArea(uint32 difficulty) const;
bool IsTargetingArea(uint32 difficulty) const;
bool NeedsExplicitUnitTarget() const;
- bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const;
+ bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) const;
bool IsPassive() const;
bool IsAutocastable() const;
bool IsStackableWithRanks() const;
- bool IsPassiveStackableWithRanks() const;
+ bool IsPassiveStackableWithRanks(uint32 difficulty) const;
bool IsMultiSlotAura() const;
bool IsStackableOnOneSlotWithDifferentCasters() const;
bool IsCooldownStartedOnEvent() const;
@@ -488,15 +490,15 @@ public:
SpellSchoolMask GetSchoolMask() const;
uint32 GetAllEffectsMechanicMask() const;
- uint32 GetEffectMechanicMask(uint8 effIndex) const;
+ uint32 GetEffectMechanicMask(uint32 effIndex) const;
uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const;
- Mechanics GetEffectMechanic(uint8 effIndex) const;
- bool HasAnyEffectMechanic() const;
+ Mechanics GetEffectMechanic(uint32 effIndex, uint32 difficulty) const;
+ //bool HasAnyEffectMechanic() const;
uint32 GetDispelMask() const;
static uint32 GetDispelMask(DispelType type);
uint32 GetExplicitTargetMask() const;
- AuraStateType GetAuraState() const;
+ AuraStateType GetAuraState(uint32 difficulty) const;
SpellSpecificType GetSpellSpecific() const;
float GetMinRange(bool positive = false) const;
@@ -505,7 +507,7 @@ public:
int32 GetDuration() const;
int32 GetMaxDuration() const;
- uint32 GetMaxTicks() const;
+ uint32 GetMaxTicks(uint32 difficulty) const;
uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
uint32 GetRecoveryTime() const;
@@ -525,7 +527,7 @@ public:
// loading helpers
void _InitializeExplicitTargetMask();
- bool _IsPositiveEffect(uint8 effIndex, bool deep) const;
+ bool _IsPositiveEffect(uint32 effIndex, bool deep) const;
bool _IsPositiveSpell() const;
static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
@@ -535,7 +537,7 @@ public:
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const;
SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const;
- SpellEffectInfoMap Effects;
+ SpellEffectInfoMap _effects;
};
#endif // _SPELLINFO_H