From 8a4e1119ac21e2d1112d1717337597fe073e495f Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 4 Sep 2021 15:13:15 +0200 Subject: Core/Spells: Unify spell effect access api in both branches --- src/server/game/Spells/SpellMgr.cpp | 307 +++++++++++++++++------------------- 1 file changed, 148 insertions(+), 159 deletions(-) (limited to 'src/server/game/Spells/SpellMgr.cpp') diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 1e6d3cbd5f5..472b052a56d 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -146,21 +146,15 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg bool needCheckReagents = false; // check effects - for (SpellEffectInfo const* effect : spellInfo->GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects()) { - if (!effect) - continue; - - switch (effect->Effect) + switch (spellEffectInfo.Effect) { - case 0: - continue; - // craft spell for crafting non-existed item (break client recipes list show) case SPELL_EFFECT_CREATE_ITEM: case SPELL_EFFECT_CREATE_LOOT: { - if (effect->ItemType == 0) + if (spellEffectInfo.ItemType == 0) { // skip auto-loot crafting spells, it does not need explicit item info (but has special fake items sometimes). if (!spellInfo->IsLootCrafting()) @@ -177,14 +171,14 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg } // also possible IsLootCrafting case but fake items must exist anyway - else if (!sObjectMgr->GetItemTemplate(effect->ItemType)) + else if (!sObjectMgr->GetItemTemplate(spellEffectInfo.ItemType)) { if (msg) { if (player) - ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u has created a non-existing in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType); + ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u has created a non-existing in DB item (Entry: %u) and then...", spellInfo->Id, spellEffectInfo.ItemType); else - TC_LOG_ERROR("sql.sql", "Craft spell %u has created a non-existing item in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType); + TC_LOG_ERROR("sql.sql", "Craft spell %u has created a non-existing item in DB item (Entry: %u) and then...", spellInfo->Id, spellEffectInfo.ItemType); } return false; } @@ -194,20 +188,22 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg } case SPELL_EFFECT_LEARN_SPELL: { - SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE); + SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE); if (!IsSpellValid(spellInfo2, player, msg)) { if (msg) { if (player) - ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, effect->TriggerSpell); + ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, spellEffectInfo.TriggerSpell); else - TC_LOG_ERROR("sql.sql", "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, effect->TriggerSpell); + TC_LOG_ERROR("sql.sql", "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, spellEffectInfo.TriggerSpell); } return false; } break; } + default: + break; } } @@ -980,17 +976,14 @@ void SpellMgr::LoadSpellLearnSkills() if (entry.Difficulty != DIFFICULTY_NONE) continue; - for (SpellEffectInfo const* effect : entry.GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : entry.GetEffects()) { - if (!effect) - continue; - SpellLearnSkillNode dbc_node; - switch (effect->Effect) + switch (spellEffectInfo.Effect) { case SPELL_EFFECT_SKILL: - dbc_node.skill = uint16(effect->MiscValue); - dbc_node.step = uint16(effect->CalcValue()); + dbc_node.skill = uint16(spellEffectInfo.MiscValue); + dbc_node.step = uint16(spellEffectInfo.CalcValue()); if (dbc_node.skill != SKILL_RIDING) dbc_node.value = 1; else @@ -1077,12 +1070,12 @@ void SpellMgr::LoadSpellLearnSpells() if (entry.Difficulty != DIFFICULTY_NONE) continue; - for (SpellEffectInfo const* effect : entry.GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : entry.GetEffects()) { - if (effect && effect->Effect == SPELL_EFFECT_LEARN_SPELL) + if (spellEffectInfo.IsEffect(SPELL_EFFECT_LEARN_SPELL)) { SpellLearnSpellNode dbc_node; - dbc_node.Spell = effect->TriggerSpell; + dbc_node.Spell = spellEffectInfo.TriggerSpell; dbc_node.Active = true; // all dbc based learned spells is active (show in spell book or hide by client itself) dbc_node.OverridesSpell = 0; @@ -1093,7 +1086,7 @@ void SpellMgr::LoadSpellLearnSpells() // talent or passive spells or skill-step spells auto-cast and not need dependent learning, // pet teaching spells must not be dependent learning (cast) // other required explicit dependent learning - dbc_node.AutoLearned = effect->TargetA.GetTarget() == TARGET_UNIT_PET || entry.HasAttribute(SPELL_ATTR0_CU_IS_TALENT) || entry.IsPassive() || entry.HasEffect(SPELL_EFFECT_SKILL_STEP); + dbc_node.AutoLearned = spellEffectInfo.TargetA.GetTarget() == TARGET_UNIT_PET || entry.HasAttribute(SPELL_ATTR0_CU_IS_TALENT) || entry.IsPassive() || entry.HasEffect(SPELL_EFFECT_SKILL_STEP); SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(entry.Id); @@ -1216,20 +1209,19 @@ void SpellMgr::LoadSpellTargetPositions() continue; } - SpellEffectInfo const* effect = spellInfo->GetEffect(effIndex); - if (!effect) + if (effIndex >= spellInfo->GetEffects().size()) { TC_LOG_ERROR("sql.sql", "Spell (Id: %u, EffectIndex: %u) listed in `spell_target_position` does not have an effect at index %u.", spellId, effIndex, effIndex); continue; } // target facing is in degrees for 6484 & 9268... (blizz sucks) - if (effect->PositionFacing > 2 * M_PI) - st.target_Orientation = effect->PositionFacing * float(M_PI) / 180; + if (spellInfo->GetEffect(effIndex).PositionFacing > 2 * M_PI) + st.target_Orientation = spellInfo->GetEffect(effIndex).PositionFacing * float(M_PI) / 180; else - st.target_Orientation = effect->PositionFacing; + st.target_Orientation = spellInfo->GetEffect(effIndex).PositionFacing; - if (effect->TargetA.GetTarget() == TARGET_DEST_DB || effect->TargetB.GetTarget() == TARGET_DEST_DB) + if (spellInfo->GetEffect(effIndex).TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->GetEffect(effIndex).TargetB.GetTarget() == TARGET_DEST_DB) { std::pair key = std::make_pair(spellId, effIndex); mSpellTargetPositions[key] = st; @@ -1420,12 +1412,12 @@ void SpellMgr::LoadSpellGroupStackRules() for (uint32 spellId : spellIds) { SpellInfo const* spellInfo = AssertSpellInfo(spellId, DIFFICULTY_NONE); - for (SpellEffectInfo const* effectInfo : spellInfo->GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects()) { - if (!effectInfo->IsAura()) + if (!spellEffectInfo.IsAura()) continue; - uint32 auraName = effectInfo->ApplyAuraName; + uint32 auraName = spellEffectInfo.ApplyAuraName; for (std::vector const& subGroup : SubGroups) { if (std::find(subGroup.begin(), subGroup.end(), auraName) != subGroup.end()) @@ -1616,18 +1608,18 @@ void SpellMgr::LoadSpellProcs() TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has wrong `HitMask` set: %u", spellInfo->Id, procEntry.HitMask); if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH))))) TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has `HitMask` value defined, but it will not be used for defined `ProcFlags` and `SpellPhaseMask` values.", spellInfo->Id); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if ((procEntry.DisableEffectsMask & (1u << i)) && (!spellInfo->GetEffect(i) || !spellInfo->GetEffect(i)->IsAura())) - TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has DisableEffectsMask with effect %u, but effect %u is not an aura effect", spellInfo->Id, static_cast(i), static_cast(i)); + for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects()) + if ((procEntry.DisableEffectsMask & (1u << spellEffectInfo.EffectIndex)) && !spellEffectInfo.IsAura()) + TC_LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId %u has DisableEffectsMask with effect %u, but effect %u is not an aura effect", spellInfo->Id, static_cast(spellEffectInfo.EffectIndex), static_cast(spellEffectInfo.EffectIndex)); if (procEntry.AttributesMask & PROC_ATTR_REQ_SPELLMOD) { bool found = false; - for (SpellEffectInfo const* effect : spellInfo->GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects()) { - if (!effect || !effect->IsAura()) + if (!spellEffectInfo.IsAura()) continue; - if (effect->ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || effect->ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER) + if (spellEffectInfo.ApplyAuraName == SPELL_AURA_ADD_PCT_MODIFIER || spellEffectInfo.ApplyAuraName == SPELL_AURA_ADD_FLAT_MODIFIER) { found = true; break; @@ -1761,19 +1753,19 @@ void SpellMgr::LoadSpellProcs() bool addTriggerFlag = false; uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE; uint32 nonProcMask = 0; - for (SpellEffectInfo const* effect : spellInfo.GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects()) { - if (!effect || !effect->IsEffect()) + if (!spellEffectInfo.IsEffect()) continue; - uint32 auraName = effect->ApplyAuraName; + uint32 auraName = spellEffectInfo.ApplyAuraName; if (!auraName) continue; if (!isTriggerAura[auraName]) { // explicitly disable non proccing auras to avoid losing charges on self proc - nonProcMask |= 1 << effect->EffectIndex; + nonProcMask |= 1 << spellEffectInfo.EffectIndex; continue; } @@ -1799,9 +1791,9 @@ void SpellMgr::LoadSpellProcs() if (!procSpellTypeMask) { - for (SpellEffectInfo const* effectInfo : spellInfo.GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects()) { - if (effectInfo && effectInfo->IsAura()) + if (spellEffectInfo.IsAura()) { TC_LOG_ERROR("sql.sql", "Spell Id %u has DBC ProcFlags %u, but it's of non-proc aura type, it probably needs an entry in `spell_proc` table to be handled correctly.", spellInfo.Id, spellInfo.ProcFlags); break; @@ -1815,9 +1807,9 @@ void SpellMgr::LoadSpellProcs() procEntry.SchoolMask = 0; procEntry.ProcFlags = spellInfo.ProcFlags; procEntry.SpellFamilyName = 0; - for (SpellEffectInfo const* effect : spellInfo.GetEffects()) - if (effect && effect->IsEffect() && isTriggerAura[effect->ApplyAuraName]) - procEntry.SpellFamilyMask |= effect->SpellClassMask; + for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects()) + if (spellEffectInfo.IsEffect() && isTriggerAura[spellEffectInfo.ApplyAuraName]) + procEntry.SpellFamilyMask |= spellEffectInfo.SpellClassMask; if (procEntry.SpellFamilyMask) procEntry.SpellFamilyName = spellInfo.SpellFamilyName; @@ -1826,12 +1818,12 @@ void SpellMgr::LoadSpellProcs() procEntry.SpellPhaseMask = PROC_SPELL_PHASE_HIT; procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent - for (SpellEffectInfo const* effect : spellInfo.GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects()) { - if (!effect || !effect->IsAura()) + if (!spellEffectInfo.IsAura()) continue; - switch (effect->ApplyAuraName) + switch (spellEffectInfo.ApplyAuraName) { // Reflect auras should only proc off reflects case SPELL_AURA_REFLECT_SPELLS: @@ -1951,7 +1943,7 @@ void SpellMgr::LoadSpellPetAuras() Field* fields = result->Fetch(); uint32 spell = fields[0].GetUInt32(); - uint8 eff = fields[1].GetUInt8(); + SpellEffIndex eff = SpellEffIndex(fields[1].GetUInt8()); uint32 pet = fields[2].GetUInt32(); uint32 aura = fields[3].GetUInt32(); @@ -1966,18 +1958,17 @@ void SpellMgr::LoadSpellPetAuras() TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_pet_auras` does not exist.", spell); continue; } - SpellEffectInfo const* effect = spellInfo->GetEffect(eff); - if (!effect) + if (eff >= spellInfo->GetEffects().size()) { TC_LOG_ERROR("spells", "The spell %u listed in `spell_pet_auras` does not have any effect at index %u", spell, uint32(eff)); continue; } - if (effect->Effect != SPELL_EFFECT_DUMMY && - (effect->Effect != SPELL_EFFECT_APPLY_AURA || - effect->ApplyAuraName != SPELL_AURA_DUMMY)) + if (spellInfo->GetEffect(eff).Effect != SPELL_EFFECT_DUMMY && + (spellInfo->GetEffect(eff).Effect != SPELL_EFFECT_APPLY_AURA || + spellInfo->GetEffect(eff).ApplyAuraName != SPELL_AURA_DUMMY)) { - TC_LOG_ERROR("spells", "Spell %u listed in `spell_pet_auras` does not have any dummy aura or dummy effect", spell); + TC_LOG_ERROR("spells", "The spell %u listed in `spell_pet_auras` does not have any dummy aura or dummy effect.", spell); continue; } @@ -1988,7 +1979,7 @@ void SpellMgr::LoadSpellPetAuras() continue; } - PetAura pa(pet, aura, effect->TargetA.GetTarget() == TARGET_UNIT_PET, effect->CalcValue()); + PetAura pa(pet, aura, spellInfo->GetEffect(eff).TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->GetEffect(eff).CalcValue()); mSpellPetAuraMap[(spell<<8) + eff] = pa; } @@ -2016,11 +2007,11 @@ void SpellMgr::LoadEnchantCustomAttr() if (!spellInfo.HasAttribute(SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !spellInfo.HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT)) continue; - for (SpellEffectInfo const* effect : spellInfo.GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects()) { - if (effect && effect->Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) + if (spellEffectInfo.Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) { - uint32 enchId = effect->MiscValue; + uint32 enchId = spellEffectInfo.MiscValue; SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId); if (!ench) continue; @@ -2108,10 +2099,10 @@ void SpellMgr::LoadSpellLinked() } if (effect >= 0) - for (SpellEffectInfo const* eff : spellInfo->GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects()) { - if (eff && eff->CalcValue() == abs(effect)) - TC_LOG_ERROR("sql.sql", "The spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), eff->EffectIndex); + if (spellEffectInfo.CalcValue() == abs(effect)) + TC_LOG_ERROR("sql.sql", "The spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack).", abs(trigger), abs(effect), uint32(spellEffectInfo.EffectIndex)); } spellInfo = GetSpellInfo(abs(effect), DIFFICULTY_NONE); @@ -2252,11 +2243,11 @@ void SpellMgr::LoadPetDefaultSpells() { if (spellEntry.Difficulty != DIFFICULTY_NONE) - for (SpellEffectInfo const* effect : spellEntry.GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellEntry.GetEffects()) { - if (effect && (effect->Effect == SPELL_EFFECT_SUMMON || effect->Effect == SPELL_EFFECT_SUMMON_PET)) + if (spellEffectInfo.IsEffect(SPELL_EFFECT_SUMMON) || spellEffectInfo.IsEffect(SPELL_EFFECT_SUMMON_PET)) { - uint32 creature_id = effect->MiscValue; + uint32 creature_id = spellEffectInfo.MiscValue; CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id); if (!cInfo) continue; @@ -2952,12 +2943,9 @@ void SpellMgr::LoadSpellInfoCustomAttributes() for (SpellInfo const& spellInfo : mSpellInfoMap) { SpellInfo* spellInfoMutable = const_cast(&spellInfo); - for (SpellEffectInfo const* effect : spellInfoMutable->GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfoMutable->GetEffects()) { - if (!effect) - continue; - - switch (effect->ApplyAuraName) + switch (spellEffectInfo.ApplyAuraName) { case SPELL_AURA_MOD_POSSESS: case SPELL_AURA_MOD_CONFUSE: @@ -2979,9 +2967,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes() case SPELL_AURA_POWER_BURN: spellInfoMutable->AttributesCu |= SPELL_ATTR0_CU_NO_INITIAL_THREAT; break; + default: + break; } - switch (effect->ApplyAuraName) + switch (spellEffectInfo.ApplyAuraName) { case SPELL_AURA_OPEN_STABLE: // No point in saving this, since the stable dialog can't be open on aura load anyway. // Auras that require both caster & target to be in world cannot be saved @@ -2996,9 +2986,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes() case SPELL_AURA_BATTLEGROUND_PLAYER_POSITION_FACTIONAL: spellInfoMutable->AttributesCu |= SPELL_ATTR0_CU_AURA_CANNOT_BE_SAVED; break; + default: + break; } - switch (effect->Effect) + switch (spellEffectInfo.Effect) { case SPELL_EFFECT_SCHOOL_DAMAGE: case SPELL_EFFECT_HEALTH_LEECH: @@ -3013,9 +3005,11 @@ void SpellMgr::LoadSpellInfoCustomAttributes() case SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT: spellInfoMutable->AttributesCu |= SPELL_ATTR0_CU_CAN_CRIT; break; + default: + break; } - switch (effect->Effect) + switch (spellEffectInfo.Effect) { case SPELL_EFFECT_SCHOOL_DAMAGE: case SPELL_EFFECT_WEAPON_DAMAGE: @@ -3053,7 +3047,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes() // only enchanting profession enchantments procs can stack if (IsPartOfSkillLine(SKILL_ENCHANTING, spellInfo.Id)) { - uint32 enchantId = effect->MiscValue; + uint32 enchantId = spellEffectInfo.MiscValue; SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId); if (!enchant) break; @@ -3077,6 +3071,8 @@ void SpellMgr::LoadSpellInfoCustomAttributes() } break; } + default: + break; } } @@ -3084,67 +3080,64 @@ void SpellMgr::LoadSpellInfoCustomAttributes() if (!spellInfoMutable->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT)) { bool setFlag = false; - for (SpellEffectInfo const* effect : spellInfoMutable->GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfoMutable->GetEffects()) { - if (!effect) - continue; - - if (effect->IsEffect()) + if (spellEffectInfo.IsEffect()) { - switch (effect->Effect) + switch (spellEffectInfo.Effect) { - case SPELL_EFFECT_SCHOOL_DAMAGE: - case SPELL_EFFECT_WEAPON_DAMAGE: - case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: - case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: - case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: - case SPELL_EFFECT_TRIGGER_SPELL: - case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE: - break; - case SPELL_EFFECT_PERSISTENT_AREA_AURA: - case SPELL_EFFECT_APPLY_AURA: - case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: - case SPELL_EFFECT_APPLY_AREA_AURA_RAID: - case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: - case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: - case SPELL_EFFECT_APPLY_AREA_AURA_PET: - case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: - case SPELL_EFFECT_APPLY_AURA_ON_PET: - case SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS: - case SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM: - if (effect->ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || - effect->ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT || - effect->ApplyAuraName == SPELL_AURA_DUMMY || - effect->ApplyAuraName == SPELL_AURA_PERIODIC_LEECH || - effect->ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL || - effect->ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY) - break; - /* fallthrough */ - default: - { - // No value and not interrupt cast or crowd control without SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY flag - if (!effect->CalcValue() && !((effect->Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfoMutable->HasAttribute(SPELL_ATTR0_CU_AURA_CC)) && !spellInfoMutable->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY))) + case SPELL_EFFECT_SCHOOL_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + case SPELL_EFFECT_TRIGGER_SPELL: + case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE: break; + case SPELL_EFFECT_PERSISTENT_AREA_AURA: + case SPELL_EFFECT_APPLY_AURA: + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: + case SPELL_EFFECT_APPLY_AREA_AURA_RAID: + case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: + case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: + case SPELL_EFFECT_APPLY_AREA_AURA_PET: + case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: + case SPELL_EFFECT_APPLY_AURA_ON_PET: + case SPELL_EFFECT_APPLY_AREA_AURA_SUMMONS: + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM: + if (spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || + spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE_PERCENT || + spellEffectInfo.ApplyAuraName == SPELL_AURA_DUMMY || + spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_LEECH || + spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_HEALTH_FUNNEL || + spellEffectInfo.ApplyAuraName == SPELL_AURA_PERIODIC_DUMMY) + break; + /* fallthrough */ + default: + { + // No value and not interrupt cast or crowd control without SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY flag + if (!spellEffectInfo.CalcValue() && !((spellEffectInfo.Effect == SPELL_EFFECT_INTERRUPT_CAST || spellInfoMutable->HasAttribute(SPELL_ATTR0_CU_AURA_CC)) && !spellInfoMutable->HasAttribute(SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY))) + break; - // Sindragosa Frost Breath - if (spellInfoMutable->Id == 69649 || spellInfoMutable->Id == 71056 || spellInfoMutable->Id == 71057 || spellInfoMutable->Id == 71058 || spellInfoMutable->Id == 73061 || spellInfoMutable->Id == 73062 || spellInfoMutable->Id == 73063 || spellInfoMutable->Id == 73064) - break; + // Sindragosa Frost Breath + if (spellInfoMutable->Id == 69649 || spellInfoMutable->Id == 71056 || spellInfoMutable->Id == 71057 || spellInfoMutable->Id == 71058 || spellInfoMutable->Id == 73061 || spellInfoMutable->Id == 73062 || spellInfoMutable->Id == 73063 || spellInfoMutable->Id == 73064) + break; - // Frostbolt - if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfoMutable->SpellFamilyFlags[0] & 0x20)) - break; + // Frostbolt + if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_MAGE && (spellInfoMutable->SpellFamilyFlags[0] & 0x20)) + break; - // Frost Fever - if (spellInfoMutable->Id == 55095) - break; + // Frost Fever + if (spellInfoMutable->Id == 55095) + break; - // Haunt - if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellInfoMutable->SpellFamilyFlags[1] & 0x40000)) - break; + // Haunt + if (spellInfoMutable->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellInfoMutable->SpellFamilyFlags[1] & 0x40000)) + break; - setFlag = true; - break; - } + setFlag = true; + break; + } } if (setFlag) @@ -3203,18 +3196,15 @@ void SpellMgr::LoadSpellInfoCustomAttributes() { bool allNonBinary = true; bool overrideAttr = false; - for (SpellEffectInfo const* effect : spellInfoMutable->GetEffects()) + for (SpellEffectInfo const& spellEffectInfo : spellInfoMutable->GetEffects()) { - if (!effect) - continue; - - if (effect->IsAura() && effect->TriggerSpell) + if (spellEffectInfo.IsAura() && spellEffectInfo.TriggerSpell) { - switch (effect->ApplyAuraName) + switch (spellEffectInfo.ApplyAuraName) { case SPELL_AURA_PERIODIC_TRIGGER_SPELL: case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE: - if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE)) + if (SpellInfo const* triggerSpell = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, DIFFICULTY_NONE)) { overrideAttr = true; if (triggerSpell->HasAttribute(SPELL_ATTR0_CU_BINARY_SPELL)) @@ -3259,14 +3249,13 @@ inline void ApplySpellFix(std::initializer_list spellIds, void(*fix)(Spe inline void ApplySpellEffectFix(SpellInfo* spellInfo, SpellEffIndex effectIndex, void(*fix)(SpellEffectInfo*)) { - SpellEffectInfo const* effect = spellInfo->GetEffect(effectIndex); - if (!effect) + if (spellInfo->GetEffects().size() <= effectIndex) { TC_LOG_ERROR("server.loading", "Spell effect info correction specified for non-existing effect %u of spell %u", uint32(effectIndex), spellInfo->Id); return; } - fix(const_cast(effect)); + fix(const_cast(&spellInfo->GetEffect(effectIndex))); } void SpellMgr::LoadSpellInfoCorrections() @@ -3427,7 +3416,7 @@ void SpellMgr::LoadSpellInfoCorrections() { ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo) { - spellEffectInfo->Effect = 0; + spellEffectInfo->Effect = SPELL_EFFECT_NONE; }); }); @@ -3765,7 +3754,7 @@ void SpellMgr::LoadSpellInfoCorrections() //! HACK: This spell break quest complete for alliance and on retail not used ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo) { - spellEffectInfo->Effect = 0; + spellEffectInfo->Effect = SPELL_EFFECT_NONE; }); }); @@ -4056,7 +4045,7 @@ void SpellMgr::LoadSpellInfoCorrections() // this spell initially granted Shadow damage immunity, however it was removed but the data was left in client ApplySpellEffectFix(spellInfo, EFFECT_2, [](SpellEffectInfo* spellEffectInfo) { - spellEffectInfo->Effect = 0; + spellEffectInfo->Effect = SPELL_EFFECT_NONE; }); }); @@ -4098,7 +4087,7 @@ void SpellMgr::LoadSpellInfoCorrections() // THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS WERE NOT IMPLEMENTED WHEN THE SCRIPT WAS WRITTEN ApplySpellEffectFix(spellInfo, EFFECT_1, [](SpellEffectInfo* spellEffectInfo) { - spellEffectInfo->Effect = 0; + spellEffectInfo->Effect = SPELL_EFFECT_NONE; }); }); @@ -4477,7 +4466,7 @@ void SpellMgr::LoadSpellInfoCorrections() // Until we figure out what it's actually used for we disable it. ApplySpellEffectFix(spellInfo, EFFECT_2, [](SpellEffectInfo* spellEffectInfo) { - spellEffectInfo->Effect = 0; + spellEffectInfo->Effect = SPELL_EFFECT_NONE; }); }); @@ -4498,26 +4487,24 @@ void SpellMgr::LoadSpellInfoCorrections() if (!spellInfo) continue; - for (SpellEffectInfo const* effect : spellInfo->GetEffects()) + // Fix range for trajectory triggered spell + for (SpellEffectInfo const& spellEffectInfo : spellInfo->GetEffects()) { - if (!effect) - continue; - - if (effect->IsEffect() && (effect->TargetA.GetTarget() == TARGET_DEST_TRAJ || effect->TargetB.GetTarget() == TARGET_DEST_TRAJ)) + if (spellEffectInfo.IsEffect() && (spellEffectInfo.TargetA.GetTarget() == TARGET_DEST_TRAJ || spellEffectInfo.TargetB.GetTarget() == TARGET_DEST_TRAJ)) { // Get triggered spell if any - if (SpellInfo* spellInfoTrigger = const_cast(GetSpellInfo(effect->TriggerSpell, DIFFICULTY_NONE))) + for (SpellInfo const& spellInfoTrigger : _GetSpellInfo(spellEffectInfo.TriggerSpell)) { float maxRangeMain = spellInfo->GetMaxRange(); - float maxRangeTrigger = spellInfoTrigger->GetMaxRange(); + float maxRangeTrigger = spellInfoTrigger.GetMaxRange(); // check if triggered spell has enough max range to cover trajectory if (maxRangeTrigger < maxRangeMain) - spellInfoTrigger->RangeEntry = spellInfo->RangeEntry; + const_cast(spellInfoTrigger).RangeEntry = spellInfo->RangeEntry; } } - switch (effect->Effect) + switch (spellEffectInfo.Effect) { case SPELL_EFFECT_CHARGE: case SPELL_EFFECT_CHARGE_DEST: @@ -4527,17 +4514,19 @@ void SpellMgr::LoadSpellInfoCorrections() if (!spellInfo->Speed && !spellInfo->SpellFamilyName && !spellInfo->HasAttribute(SPELL_ATTR9_SPECIAL_DELAY_CALCULATION)) spellInfo->Speed = SPEED_CHARGE; break; + default: + break; } - if (effect->TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE || effect->TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE) + if (spellEffectInfo.TargetA.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE || spellEffectInfo.TargetB.GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE) if (G3D::fuzzyEq(spellInfo->ConeAngle, 0.f)) spellInfo->ConeAngle = 90.f; // Area auras may not target area (they're self cast) - if (effect->IsAreaAuraEffect() && effect->IsTargetingArea()) + if (spellEffectInfo.IsAreaAuraEffect() && spellEffectInfo.IsTargetingArea()) { - const_cast(effect)->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER); - const_cast(effect)->TargetB = SpellImplicitTargetInfo(0); + const_cast(spellEffectInfo).TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER); + const_cast(spellEffectInfo).TargetB = SpellImplicitTargetInfo(0); } } -- cgit v1.2.3