diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 74bc059f0..c011013fc 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -44,8 +44,6 @@ #include "BattleGround.h" #include "Util.h" #include "Chat.h" -#include "DB2Stores.h" -#include "SQLStorages.h" extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; @@ -104,10 +102,8 @@ bool IsQuestTameSpell(uint32 spellId) if (!spellproto) return false; - SpellEffectEntry const* spellEffect0 = spellproto->GetSpellEffect(EFFECT_INDEX_0); - SpellEffectEntry const* spellEffect1 = spellproto->GetSpellEffect(EFFECT_INDEX_1); - return spellEffect0 && spellEffect0->Effect == SPELL_EFFECT_THREAT && - spellEffect1 && spellEffect1->Effect == SPELL_EFFECT_APPLY_AURA && spellEffect1->EffectApplyAuraName == SPELL_AURA_DUMMY; + return spellproto->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_THREAT + && spellproto->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_APPLY_AURA && spellproto->EffectApplyAuraName[EFFECT_INDEX_1] == SPELL_AURA_DUMMY; } SpellCastTargets::SpellCastTargets() @@ -121,9 +117,6 @@ SpellCastTargets::SpellCastTargets() m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0.0f; m_strTarget = ""; m_targetMask = 0; - - m_elevation = 0.0f; - m_speed = 0.0f; } SpellCastTargets::~SpellCastTargets() @@ -317,44 +310,6 @@ void SpellCastTargets::write(ByteBuffer& data) const data << m_strTarget; } -void SpellCastTargets::ReadAdditionalData(WorldPacket& data, uint8& cast_flags) -{ - if (cast_flags & 0x02) // has trajectory data - { - data >> m_elevation >> m_speed; - - bool hasMovementData; - data >> hasMovementData; - if (hasMovementData) - { - MovementInfo mi; - data >> mi; - setSource(mi.GetPos()->x, mi.GetPos()->y, mi.GetPos()->z); - } - } - else if (cast_flags & 0x08) // has archaeology weight - { - uint32 count; - uint8 type; - data >> count; - for (uint32 i = 0; i < count; ++i) - { - data >> type; - switch (type) - { - case 1: // Fragments - data >> Unused(); // Currency entry - data >> Unused(); // Currency count - break; - case 2: // Keystones - data >> Unused(); // Item entry - data >> Unused(); // Item count - break; - } - } - } -} - Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid originalCasterGUID, SpellEntry const* triggeredBy) { MANGOS_ASSERT(caster != NULL && info != NULL); @@ -371,9 +326,6 @@ Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid or m_spellInfo = info; m_triggeredBySpellInfo = triggeredBy; - - m_spellInterrupts = m_spellInfo->GetSpellInterrupts(); - m_caster = caster; m_selfContainer = NULL; m_referencedFromCurrentSpell = false; @@ -394,7 +346,7 @@ Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid or if ((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId() == TYPEID_PLAYER) { if (Item* pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK)) - m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->DamageType); + m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage[0].DamageType); } } // Set health leech amount to zero @@ -440,17 +392,14 @@ Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid or m_spellFlags = SPELL_FLAG_NORMAL; - if (m_spellInfo->GetDmgClass() == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR_EX2_CANT_REFLECTED)) + if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !m_spellInfo->HasAttribute(SPELL_ATTR_EX2_CANT_REFLECTED)) { for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); - if(!spellEffect) - continue; - if (spellEffect->Effect == 0) + if (m_spellInfo->Effect[j] == 0) continue; - if(!IsPositiveTarget(spellEffect->EffectImplicitTargetA, spellEffect->EffectImplicitTargetB)) + if (!IsPositiveTarget(m_spellInfo->EffectImplicitTargetA[j], m_spellInfo->EffectImplicitTargetB[j])) m_canReflect = true; else m_canReflect = m_spellInfo->HasAttribute(SPELL_ATTR_EX_NEGATIVE); @@ -497,40 +446,32 @@ void Spell::FillTargetMap() uint8 effToIndex[MAX_EFFECT_INDEX] = {0, 1, 2}; // Helper array, to link to another tmpUnitList, if the targets for both effects match for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; - // not call for empty effect. // Also some spells use not used effect targets for store targets for dummy effect in triggered spells - if(spellEffect->Effect == SPELL_EFFECT_NONE) + if (m_spellInfo->Effect[i] == SPELL_EFFECT_NONE) continue; // targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT // for TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT (A) all is checked in Spell::CheckCast and in Spell::CheckItem // filled in Spell::CheckCast call - if(spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || - spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || - spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || - (spellEffect->EffectImplicitTargetB == TARGET_SCRIPT && spellEffect->EffectImplicitTargetA != TARGET_SELF)) + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || + (m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF)) continue; // TODO: find a way so this is not needed? // for area auras always add caster as target (needed for totems for example) - if (IsAreaAuraEffect(spellEffect->Effect)) + if (IsAreaAuraEffect(m_spellInfo->Effect[i])) AddUnitTarget(m_caster, SpellEffectIndex(i)); // no double fill for same targets for (int j = 0; j < i; ++j) { - SpellEffectEntry const* spellEffect1 = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); - if (!spellEffect) - continue; - // Check if same target, but handle i.e. AreaAuras different - if (spellEffect->EffectImplicitTargetA == spellEffect1->EffectImplicitTargetA && spellEffect->EffectImplicitTargetB == spellEffect1->EffectImplicitTargetB - && spellEffect1->Effect != SPELL_EFFECT_NONE - && !IsAreaAuraEffect(spellEffect->Effect) && !IsAreaAuraEffect(spellEffect1->Effect)) + if (m_spellInfo->EffectImplicitTargetA[i] == m_spellInfo->EffectImplicitTargetA[j] && m_spellInfo->EffectImplicitTargetB[i] == m_spellInfo->EffectImplicitTargetB[j] + && m_spellInfo->Effect[j] != SPELL_EFFECT_NONE + && !IsAreaAuraEffect(m_spellInfo->Effect[i]) && !IsAreaAuraEffect(m_spellInfo->Effect[j])) // Add further conditions here if required { effToIndex[i] = j; // effect i has same targeting list as effect j @@ -542,10 +483,10 @@ void Spell::FillTargetMap() { // TargetA/TargetB dependent from each other, we not switch to full support this dependences // but need it support in some know cases - switch(spellEffect->EffectImplicitTargetA) + switch (m_spellInfo->EffectImplicitTargetA[i]) { case TARGET_NONE: - switch(spellEffect->EffectImplicitTargetB) + switch (m_spellInfo->EffectImplicitTargetB[i]) { case TARGET_NONE: if (m_caster->GetObjectGuid().IsPet()) @@ -554,39 +495,39 @@ void Spell::FillTargetMap() SetTargetMap(SpellEffectIndex(i), TARGET_EFFECT_SELECT, tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_SELF: - switch(spellEffect->EffectImplicitTargetB) + switch (m_spellInfo->EffectImplicitTargetB[i]) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; - case TARGET_AREAEFFECT_INSTANT: // use B case that not dependent from from A in fact - if((m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) == 0) + case TARGET_AREAEFFECT_INSTANT: // use B case that not dependent from from A in fact + if ((m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) == 0) m_targets.setDestination(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; - case TARGET_BEHIND_VICTIM: // use B case that not dependent from from A in fact - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + case TARGET_BEHIND_VICTIM: // use B case that not dependent from from A in fact + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_EFFECT_SELECT: - switch(spellEffect->EffectImplicitTargetB) + switch (m_spellInfo->EffectImplicitTargetB[i]) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; - // dest point setup required + // dest point setup required case TARGET_AREAEFFECT_INSTANT: case TARGET_AREAEFFECT_CUSTOM: case TARGET_ALL_ENEMY_IN_AREA: @@ -599,9 +540,9 @@ void Spell::FillTargetMap() if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) || m_IsTriggeredSpell) if (WorldObject* castObject = GetCastingObject()) m_targets.setDestination(castObject->GetPositionX(), castObject->GetPositionY(), castObject->GetPositionZ()); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; - // target pre-selection required + // target pre-selection required case TARGET_INNKEEPER_COORDINATES: case TARGET_TABLE_X_Y_Z_COORDINATES: case TARGET_CASTER_COORDINATES: @@ -618,107 +559,108 @@ void Spell::FillTargetMap() case TARGET_POINT_AT_SE: case TARGET_POINT_AT_SW: // need some target for processing - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_CASTER_COORDINATES: - switch(spellEffect->EffectImplicitTargetB) + switch (m_spellInfo->EffectImplicitTargetB[i]) { case TARGET_ALL_ENEMY_IN_AREA: // Note: this hack with search required until GO casting not implemented // environment damage spells already have around enemies targeting but this not help in case nonexistent GO casting support // currently each enemy selected explicitly and self cast damage - if (spellEffect->Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) + if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) { - if(m_targets.getUnitTarget()) + if (m_targets.getUnitTarget()) tmpUnitLists[i /*==effToIndex[i]*/].push_back(m_targets.getUnitTarget()); } else { - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); } break; - case 0: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + case TARGET_NONE: + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); tmpUnitLists[i /*==effToIndex[i]*/].push_back(m_caster); break; default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_TABLE_X_Y_Z_COORDINATES: - switch(spellEffect->EffectImplicitTargetB) + switch (m_spellInfo->EffectImplicitTargetB[i]) { - case 0: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + case TARGET_NONE: + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); - - // need some target for processing + // need some target for processing SetTargetMap(SpellEffectIndex(i), TARGET_EFFECT_SELECT, tmpUnitLists[i /*==effToIndex[i]*/]); break; - case TARGET_AREAEFFECT_INSTANT: // All 17/7 pairs used for dest teleportation, A processed in effect code - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + case TARGET_AREAEFFECT_INSTANT: // All 17/7 pairs used for dest teleportation, A processed in effect code + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); + break; } - case TARGET_SELF2: - switch(spellEffect->EffectImplicitTargetB) + break; + case TARGET_SELF2: + switch (m_spellInfo->EffectImplicitTargetB[i]) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; case TARGET_AREAEFFECT_CUSTOM: // triggered spells get dest point from default target set, ignore it if (!(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) || m_IsTriggeredSpell) if (WorldObject* castObject = GetCastingObject()) m_targets.setDestination(castObject->GetPositionX(), castObject->GetPositionY(), castObject->GetPositionZ()); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; - // most A/B target pairs is self->negative and not expect adding caster to target list + // most A/B target pairs is self->negative and not expect adding caster to target list default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; case TARGET_DUELVSPLAYER_COORDINATES: - switch(spellEffect->EffectImplicitTargetB) + switch (m_spellInfo->EffectImplicitTargetB[i]) { case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); if (Unit* currentTarget = m_targets.getUnitTarget()) tmpUnitLists[i /*==effToIndex[i]*/].push_back(currentTarget); break; default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; default: - switch(spellEffect->EffectImplicitTargetB) + switch (m_spellInfo->EffectImplicitTargetB[i]) { - case 0: + case TARGET_NONE: case TARGET_EFFECT_SELECT: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + break; + case TARGET_SCRIPT_COORDINATES: // B case filled in CheckCast but we need fill unit list base at A case + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; - case TARGET_SCRIPT_COORDINATES: // B case filled in CheckCast but we need fill unit list base at A case - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - break; default: - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetA, tmpUnitLists[i /*==effToIndex[i]*/]); - SetTargetMap(SpellEffectIndex(i), spellEffect->EffectImplicitTargetB, tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetA[i], tmpUnitLists[i /*==effToIndex[i]*/]); + SetTargetMap(SpellEffectIndex(i), m_spellInfo->EffectImplicitTargetB[i], tmpUnitLists[i /*==effToIndex[i]*/]); break; } break; @@ -776,14 +718,14 @@ void Spell::prepareDataForTriggerSystem() if (!m_canTrigger) // Exceptions (some periodic triggers) { - switch (m_spellInfo->GetSpellFamilyName()) + switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_MAGE: - // Arcane Missles / Blizzard triggers need do it + // Arcane Missiles / Blizzard triggers need do it if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000000000200080))) m_canTrigger = true; // Clearcasting trigger need do it - else if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000000200000000), 0x00000008)) + else if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000000200000000))) m_canTrigger = true; // Replenish Mana, item spell with triggered cases (Mana Agate, etc mana gems) else if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0000010000000000))) @@ -806,7 +748,7 @@ void Spell::prepareDataForTriggerSystem() break; case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect/Explosive Shot - if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0100200000000214), 0x200)) + if (m_spellInfo->IsFitToFamilyMask(UI64LIT(0x0100200000000214), 0x00000200)) m_canTrigger = true; break; case SPELLFAMILY_PALADIN: @@ -820,7 +762,7 @@ void Spell::prepareDataForTriggerSystem() } // Get data for type of attack and fill base info for trigger - switch (m_spellInfo->GetDmgClass()) + switch (m_spellInfo->DmgClass) { case SPELL_DAMAGE_CLASS_MELEE: m_procAttacker = PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT; @@ -869,7 +811,7 @@ void Spell::prepareDataForTriggerSystem() // Hunter traps spells (for Entrapment trigger) // Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap .... - if (m_spellInfo->IsFitToFamily(SPELLFAMILY_HUNTER, UI64LIT(0x000020000000001C))) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x000020000000001C))) m_procAttacker |= PROC_FLAG_ON_TRAP_ACTIVATION; } @@ -883,8 +825,7 @@ void Spell::CleanupTargetList() void Spell::AddUnitTarget(Unit* pVictim, SpellEffectIndex effIndex) { - SpellEffectEntry const *spellEffect = m_spellInfo->GetSpellEffect(effIndex); - if (!spellEffect || spellEffect->Effect == 0) + if (m_spellInfo->Effect[effIndex] == 0) return; // Check for effect immune skip if immuned @@ -920,24 +861,8 @@ void Spell::AddUnitTarget(Unit* pVictim, SpellEffectIndex effIndex) // spell fly from visual cast object WorldObject* affectiveObject = GetAffectiveCasterObject(); - // Spell has trajectory - need calculate incoming time - if (affectiveObject && m_targets.GetSpeed() > 0.0f) - { - float dist; - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - dist = affectiveObject->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); - else - dist = affectiveObject->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ()); - float speed = m_targets.GetSpeed() * cos(m_targets.GetElevation()); - - target.timeDelay = (uint64) floor(dist / speed * 1000.0f); - - // Calculate minimum incoming time - if (m_delayMoment == 0 || m_delayMoment>target.timeDelay) - m_delayMoment = target.timeDelay; - } - // Spell has speed - need calculate incoming time - else if (m_spellInfo->speed > 0.0f && affectiveObject && pVictim != affectiveObject) + // Spell have speed - need calculate incoming time + if (m_spellInfo->speed > 0.0f && affectiveObject && pVictim != affectiveObject) { // calculate spell incoming interval float dist = affectiveObject->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ()); @@ -949,15 +874,6 @@ void Spell::AddUnitTarget(Unit* pVictim, SpellEffectIndex effIndex) if (m_delayMoment == 0 || m_delayMoment > target.timeDelay) m_delayMoment = target.timeDelay; } - // Spell casted on self - mostly TRIGGER_MISSILE code - else if (m_spellInfo->speed > 0.0f && affectiveObject && pVictim == affectiveObject) - { - float dist = 0.0f; - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - dist = affectiveObject->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); - - target.timeDelay = (uint64) floor(dist / m_spellInfo->speed * 1000.0f); - } else target.timeDelay = UI64LIT(0); @@ -990,8 +906,7 @@ void Spell::AddUnitTarget(ObjectGuid unitGuid, SpellEffectIndex effIndex) void Spell::AddGOTarget(GameObject* pVictim, SpellEffectIndex effIndex) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(effIndex); - if (!spellEffect || spellEffect->Effect == 0) + if (m_spellInfo->Effect[effIndex] == 0) return; ObjectGuid targetGUID = pVictim->GetObjectGuid(); @@ -1016,24 +931,8 @@ void Spell::AddGOTarget(GameObject* pVictim, SpellEffectIndex effIndex) // spell fly from visual cast object WorldObject* affectiveObject = GetAffectiveCasterObject(); - // Spell has trajectory - need calculate incoming time - if (affectiveObject && m_targets.GetSpeed() > 0.0f) - { - float dist; - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - dist = affectiveObject->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); - else - dist = affectiveObject->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ()); - - float speed = m_targets.GetSpeed() * cos(m_targets.GetElevation()); - - target.timeDelay = (uint64) floor(dist / speed * 1000.0f); - - if (m_delayMoment == 0 || m_delayMoment > target.timeDelay) - m_delayMoment = target.timeDelay; - } - // Spell has speed - need calculate incoming time - else if (m_spellInfo->speed > 0.0f && affectiveObject && pVictim != affectiveObject) + // Spell have speed - need calculate incoming time + if (m_spellInfo->speed > 0.0f && affectiveObject && pVictim != affectiveObject) { // calculate spell incoming interval float dist = affectiveObject->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ()); @@ -1058,8 +957,7 @@ void Spell::AddGOTarget(ObjectGuid goGuid, SpellEffectIndex effIndex) void Spell::AddItemTarget(Item* pitem, SpellEffectIndex effIndex) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(effIndex); - if (!spellEffect || spellEffect->Effect == 0) + if (m_spellInfo->Effect[effIndex] == 0) return; // Lookup target in already in list @@ -1219,29 +1117,28 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) caster->ProcDamageAndSpell(unitTarget, real_caster ? procAttacker : PROC_FLAG_NONE, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo); // trigger weapon enchants for weapon based spells; exclude spells that stop attack, because may break CC - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->GetEquippedItemClass() == ITEM_CLASS_WEAPON && + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !m_spellInfo->HasAttribute(SPELL_ATTR_STOP_ATTACK_TARGET)) ((Player*)m_caster)->CastItemCombatSpell(unitTarget, m_attackType); // Haunt (NOTE: for avoid use additional field damage stored in dummy value (replace unused 100%) // apply before deal damage because aura can be removed at target kill - SpellClassOptionsEntry const *classOpt = m_spellInfo->GetSpellClassOptions(); - if (classOpt && classOpt->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellIconID == 3172 && - (classOpt->SpellFamilyFlags & UI64LIT(0x0004000000000000))) - if(Aura* dummy = unitTarget->GetDummyAura(m_spellInfo->Id)) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellIconID == 3172 && + (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000))) + if (Aura* dummy = unitTarget->GetDummyAura(m_spellInfo->Id)) dummy->GetModifier()->m_amount = damageInfo.damage; caster->DealSpellDamage(&damageInfo, true); // Scourge Strike, here because needs to use final damage in second part of the spell - if (classOpt && classOpt->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && classOpt->SpellFamilyFlags & UI64LIT(0x0800000000000000)) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0800000000000000)) { uint32 count = 0; Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if(itr->second->GetSpellProto()->GetDispel() == DISPEL_DISEASE && - itr->second->GetCasterGuid() == caster->GetObjectGuid()) + if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE && + itr->second->GetCasterGuid() == caster->GetObjectGuid()) ++count; } @@ -1409,12 +1306,11 @@ void Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask) { if (effectMask & (1 << effectNumber)) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(effectNumber)); HandleEffects(unit, NULL, NULL, SpellEffectIndex(effectNumber), m_damageMultipliers[effectNumber]); if (m_applyMultiplierMask & (1 << effectNumber)) { // Get multiplier - float multiplier = spellEffect ? spellEffect->DmgMultiplier : 1.0f; + float multiplier = m_spellInfo->DmgMultiplier[effectNumber]; // Apply multiplier mods if (realCaster) if (Player* modOwner = realCaster->GetSpellModOwner()) @@ -1532,12 +1428,11 @@ void Spell::HandleDelayedSpellLaunch(TargetInfo* target) { if (mask & (1 << effectNumber) && IsEffectHandledOnDelayedSpellLaunch(m_spellInfo, SpellEffectIndex(effectNumber))) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(effectNumber)); HandleEffects(unit, NULL, NULL, SpellEffectIndex(effectNumber), m_damageMultipliers[effectNumber]); if (m_applyMultiplierMask & (1 << effectNumber)) { // Get multiplier - float multiplier = spellEffect ? spellEffect->DmgMultiplier : 1.0f; + float multiplier = m_spellInfo->DmgMultiplier[effectNumber]; // Apply multiplier mods if (real_caster) if (Player* modOwner = real_caster->GetSpellModOwner()) @@ -1559,20 +1454,17 @@ void Spell::InitializeDamageMultipliers() { for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; - if (spellEffect->Effect == 0) + if (m_spellInfo->Effect[i] == 0) continue; - uint32 EffectChainTarget = spellEffect->EffectChainTarget; + uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[i]; if (Unit* realCaster = GetAffectiveCaster()) if (Player* modOwner = realCaster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, EffectChainTarget, this); m_damageMultipliers[i] = 1.0f; - if( (spellEffect->EffectImplicitTargetA == TARGET_CHAIN_DAMAGE || spellEffect->EffectImplicitTargetA == TARGET_CHAIN_HEAL) && - (EffectChainTarget > 1) ) + if ((m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_HEAL) && + (EffectChainTarget > 1)) m_applyMultiplierMask |= (1 << i); } } @@ -1671,16 +1563,13 @@ struct TargetDistanceOrderFarAway : public std::binary_functionGetSpellEffect(effIndex); - SpellClassOptionsEntry const* classOpt = m_spellInfo->GetSpellClassOptions(); - float radius; - if (spellEffect && spellEffect->EffectRadiusIndex) - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); + if (m_spellInfo->EffectRadiusIndex[effIndex]) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[effIndex])); else radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); - uint32 EffectChainTarget = spellEffect ? spellEffect->EffectChainTarget : 0; + uint32 EffectChainTarget = m_spellInfo->EffectChainTarget[effIndex]; if (Unit* realCaster = GetAffectiveCaster()) { @@ -1692,10 +1581,10 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& } // Get spell max affected targets - uint32 unMaxTargets = m_spellInfo->GetMaxAffectedTargets(); + uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets; // custom target amount cases - switch(m_spellInfo->GetSpellFamilyName()) + switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: { @@ -1714,6 +1603,8 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& case 48278: // Paralyze (Utgarde Pinnacle) case 50988: // Glare of the Tribunal (Halls of Stone) case 51146: // Searching Gaze (Halls Of Stone) + case 52438: // Summon Skittering Swarmer (Azjol Nerub, Krik'thir the Gatewatcher) + case 53457: // Impale (Azjol Nerub, Anub'arak) case 54148: // Ritual of the Sword (Utgarde Pinnacle, Svala) case 55479: // Forced Obedience (Naxxramas, Razovius) case 56140: // Summon Power Spark (Eye of Eternity, Malygos) @@ -1862,14 +1753,11 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& { // overwrite EffectChainTarget for non single target spell if (Spell* currSpell = m_caster->GetCurrentSpell(CURRENT_GENERIC_SPELL)) - { - for(int i = 0; i < MAX_EFFECT_INDEX; ++i) - if(SpellEffectEntry const* spellEffect = currSpell->m_spellInfo->GetSpellEffect(SpellEffectIndex(i))) - if(spellEffect->EffectChainTarget > 0) - EffectChainTarget = 0; // no chain targets - if (currSpell->m_spellInfo->GetMaxAffectedTargets() > 0) + if (currSpell->m_spellInfo->MaxAffectedTargets > 0 || + currSpell->m_spellInfo->EffectChainTarget[EFFECT_INDEX_0] > 0 || + currSpell->m_spellInfo->EffectChainTarget[EFFECT_INDEX_1] > 0 || + currSpell->m_spellInfo->EffectChainTarget[EFFECT_INDEX_2] > 0) EffectChainTarget = 0; // no chain targets - } } break; default: @@ -1877,7 +1765,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& } // custom radius cases - switch (m_spellInfo->GetSpellFamilyName()) + switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: { @@ -1886,7 +1774,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& case 24811: // Draw Spirit (Lethon) { if (effIndex == EFFECT_INDEX_0) // Copy range from EFF_1 to 0 - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[EFFECT_INDEX_1])); break; } case 28241: // Poison (Naxxramas, Grobbulus Cloud) @@ -2144,7 +2032,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& unMaxTargets = EffectChainTarget; float max_range; - if(m_spellInfo->GetDmgClass() == SPELL_DAMAGE_CLASS_MELEE) + if (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE) max_range = radius; else // FIXME: This very like horrible hack and wrong for most spells @@ -2260,9 +2148,9 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& } case TARGET_AREAEFFECT_CUSTOM: { - if (spellEffect && spellEffect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_PERSISTENT_AREA_AURA) break; - else if (spellEffect && spellEffect->Effect == SPELL_EFFECT_SUMMON) + else if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_SUMMON) { targetUnitMap.push_back(m_caster); break; @@ -2360,10 +2248,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& case TARGET_ALL_ENEMY_IN_AREA_INSTANT: { // targets the ground, not the units in the area - if(!spellEffect) - break; - - switch(spellEffect->Effect) + switch (m_spellInfo->Effect[effIndex]) { case SPELL_EFFECT_PERSISTENT_AREA_AURA: break; @@ -2476,7 +2361,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& targetUnitMap.push_back(target); } // Circle of Healing - else if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_PRIEST && m_spellInfo->SpellVisual[0] == 8253) + else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellVisual[0] == 8253) { Unit* target = m_targets.getUnitTarget(); if (!target) @@ -2490,7 +2375,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& FillRaidOrPartyHealthPriorityTargets(targetUnitMap, m_caster, target, radius, count, true, false, true); } // Wild Growth - else if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_DRUID && m_spellInfo->SpellIconID == 2864) + else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellIconID == 2864) { Unit* target = m_targets.getUnitTarget(); if (!target) @@ -2615,11 +2500,11 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& break; case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: // targets the ground, not the units in the area - if (spellEffect && spellEffect->Effect!=SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (m_spellInfo->Effect[effIndex] != SPELL_EFFECT_PERSISTENT_AREA_AURA) FillAreaTargets(targetUnitMap, radius, PUSH_DEST_CENTER, SPELL_TARGETS_AOE_DAMAGE); break; case TARGET_MINION: - if(spellEffect && spellEffect->Effect != SPELL_EFFECT_DUEL) + if (m_spellInfo->Effect[effIndex] != SPELL_EFFECT_DUEL) targetUnitMap.push_back(m_caster); break; case TARGET_SINGLE_ENEMY: @@ -2813,7 +2698,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& // TODO - maybe use an (internal) value for the map for neat far teleport handling // far-teleport spells are handled in SpellEffect, elsewise report an error about an unexpected map (spells are always locally) - if (st->target_mapId != m_caster->GetMapId() && spellEffect && spellEffect->Effect != SPELL_EFFECT_TELEPORT_UNITS) + if (st->target_mapId != m_caster->GetMapId() && m_spellInfo->Effect[effIndex] != SPELL_EFFECT_TELEPORT_UNITS) sLog.outError("SPELL: wrong map (%u instead %u) target coordinates for spell ID %u", st->target_mapId, m_caster->GetMapId(), m_spellInfo->Id); } else @@ -2879,7 +2764,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& // "at the base of", in difference to 0 which appear to be "directly in front of". // TODO: some summoned will make caster be half inside summoned object. Need to fix // that in the below code (nearpoint vs closepoint, etc). - if (!spellEffect || spellEffect->EffectRadiusIndex == 0) + if (m_spellInfo->EffectRadiusIndex[effIndex] == 0) radius = 0.0f; if (m_spellInfo->Id == 50019) // Hawk Hunting, problematic 50K radius @@ -2956,10 +2841,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& { // add here custom effects that need default target. // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!! - if(!spellEffect) - break; - - switch(spellEffect->Effect) + switch (m_spellInfo->Effect[effIndex]) { case SPELL_EFFECT_DUMMY: { @@ -3022,7 +2904,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& if (m_targets.getUnitTarget()) targetUnitMap.push_back(m_targets.getUnitTarget()); // Triggered spells have additional spell targets - cast them even if no explicit unit target is given (required for spell 50516 for example) - else if (spellEffect->Effect == SPELL_EFFECT_TRIGGER_SPELL) + else if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_TRIGGER_SPELL) targetUnitMap.push_back(m_caster); break; case SPELL_EFFECT_SUMMON_PLAYER: @@ -3072,7 +2954,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList& AddItemTarget(m_targets.getItemTarget(), effIndex); break; case SPELL_EFFECT_APPLY_AURA: - switch(spellEffect->EffectApplyAuraName) + switch (m_spellInfo->EffectApplyAuraName[effIndex]) { case SPELL_AURA_ADD_FLAT_MODIFIER: // some spell mods auras have 0 target modes instead expected TARGET_SELF(1) (and present for other ranks for same spell for example) case SPELL_AURA_ADD_PCT_MODIFIER: @@ -3376,31 +3258,17 @@ void Spell::cast(bool skipCheck) } } - SpellClassOptionsEntry const* classOpt = m_spellInfo->GetSpellClassOptions(); - - // different triggered (for caster) and precast (casted before apply effect to target) cases - switch(m_spellInfo->GetSpellFamilyName()) + // different triggered (for caster and main target after main cast) and pre-cast (casted before apply effect to each target) cases + switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: { // Bandages - if (m_spellInfo->GetMechanic() == MECHANIC_BANDAGE) + if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) AddPrecastSpell(11196); // Recently Bandaged // Stoneskin else if (m_spellInfo->Id == 20594) AddTriggeredSpell(65116); // Stoneskin - armor 10% for 8 sec - else if (m_spellInfo->Id == 68992) // Darkflight - { - AddPrecastSpell(96223); // Run Speed Marker - AddPrecastSpell(97709); // Altered Form - } - else if (m_spellInfo->Id == 68996) // Two Forms - { - if (m_caster->IsInWorgenForm()) - m_caster->RemoveSpellsCausingAura(SPELL_AURA_WORGEN_TRANSFORM); - else - AddPrecastSpell(97709); // Altered Form - } // Chaos Bane strength buff else if (m_spellInfo->Id == 71904) AddTriggeredSpell(73422); @@ -3409,7 +3277,7 @@ void Spell::cast(bool skipCheck) case SPELLFAMILY_MAGE: { // Ice Block - if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000008000000000)) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000008000000000)) AddPrecastSpell(41425); // Hypothermia // Icy Veins else if (m_spellInfo->Id == 12472) @@ -3429,13 +3297,13 @@ void Spell::cast(bool skipCheck) case SPELLFAMILY_WARRIOR: { // Shield Slam - if (classOpt && (classOpt->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->GetCategory()==1209) + if ((m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->Category == 1209) { if (m_caster->HasAura(58375)) // Glyph of Blocking AddTriggeredSpell(58374); // Glyph of Blocking } // Bloodrage - if (classOpt && (classOpt->SpellFamilyFlags & UI64LIT(0x0000000000000100))) + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000100)) { if (m_caster->HasAura(70844)) // Item - Warrior T10 Protection 4P Bonus AddTriggeredSpell(70845); // Stoicism @@ -3451,11 +3319,11 @@ void Spell::cast(bool skipCheck) case SPELLFAMILY_PRIEST: { // Power Word: Shield - if (m_spellInfo->GetMechanic() == MECHANIC_SHIELD && - (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000000000001))) + if (m_spellInfo->Mechanic == MECHANIC_SHIELD && + (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000001))) AddPrecastSpell(6788); // Weakened Soul // Prayer of Mending (jump animation), we need formal caster instead original for correct animation - else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000002000000000)) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000002000000000)) AddTriggeredSpell(41637); switch (m_spellInfo->Id) @@ -3528,26 +3396,25 @@ void Spell::cast(bool skipCheck) AddPrecastSpell(67485); // Hand of Rekoning (no typos in name ;) ) } // Divine Shield, Divine Protection or Hand of Protection - else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000000400080)) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000400080)) { AddPrecastSpell(25771); // Forbearance AddPrecastSpell(61987); // Avenging Wrath Marker } // Lay on Hands - else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) { // only for self cast if (m_caster == m_targets.getUnitTarget()) AddPrecastSpell(25771); // Forbearance } // Avenging Wrath - else if (classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000200000000000)) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000200000000000)) AddPrecastSpell(61987); // Avenging Wrath Marker break; } case SPELLFAMILY_SHAMAN: { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0); // Bloodlust if (m_spellInfo->Id == 2825) AddPrecastSpell(57724); // Sated @@ -3558,7 +3425,7 @@ void Spell::cast(bool skipCheck) else if (m_spellInfo->Id == 58875) AddPrecastSpell(58876); // Totem of Wrath - else if (spellEffect && spellEffect->Effect==SPELL_EFFECT_APPLY_AREA_AURA_RAID && classOpt && classOpt->SpellFamilyFlags & UI64LIT(0x0000000004000000)) + else if (m_spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_APPLY_AREA_AURA_RAID && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000004000000)) // only for main totem spell cast AddTriggeredSpell(30708); // Totem of Wrath break; @@ -3732,19 +3599,18 @@ void Spell::_handle_immediate_phase() m_needSpellLog = IsNeedSendToClient(); for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); - if(!spellEffect || spellEffect->Effect == 0) + if (m_spellInfo->Effect[j] == 0) continue; // apply Send Event effect to ground in case empty target lists - if( spellEffect->Effect == SPELL_EFFECT_SEND_EVENT && !HaveTargetsForEffect(SpellEffectIndex(j)) ) + if (m_spellInfo->Effect[j] == SPELL_EFFECT_SEND_EVENT && !HaveTargetsForEffect(SpellEffectIndex(j))) { HandleEffects(NULL, NULL, NULL, SpellEffectIndex(j)); continue; } // Don't do spell log, if is school damage spell - if(spellEffect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE || spellEffect->Effect == 0) + if (m_spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE || m_spellInfo->Effect[j] == 0) m_needSpellLog = false; } @@ -3759,11 +3625,8 @@ void Spell::_handle_immediate_phase() // process ground for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); - if(!spellEffect) - continue; // persistent area auras target only the ground - if(spellEffect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (m_spellInfo->Effect[j] == SPELL_EFFECT_PERSISTENT_AREA_AURA) HandleEffects(NULL, NULL, NULL, SpellEffectIndex(j)); } } @@ -3808,19 +3671,16 @@ void Spell::update(uint32 difftime) return; } - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0); - SpellInterruptsEntry const* spellInterrupts = m_spellInfo->GetSpellInterrupts(); - // check if the player caster has moved before the spell finished if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && - (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && - ((spellEffect && spellEffect->Effect != SPELL_EFFECT_STUCK) || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR))) + (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && + (m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR))) { // always cancel for channeled spells if (m_spellState == SPELL_STATE_CASTING) cancel(); // don't cancel for melee, autorepeat, triggered and instant spells - else if(!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (spellInterrupts && spellInterrupts->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) + else if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_IsTriggeredSpell && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)) cancel(); } @@ -3854,7 +3714,7 @@ void Spell::update(uint32 difftime) cancel(); // check if player has turned if flag is set - if( spellInterrupts && (spellInterrupts->ChannelInterruptFlags & CHANNEL_FLAG_TURNING) && m_castOrientation != m_caster->GetOrientation() ) + if (m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_TURNING && m_castOrientation != m_caster->GetOrientation()) cancel(); } @@ -3950,9 +3810,8 @@ void Spell::finish(bool ok) // Calculate chance at that moment (can be depend for example from combo points) int32 auraBasePoints = (*i)->GetBasePoints(); int32 chance = m_caster->CalculateSpellDamage(unit, auraSpellInfo, auraSpellIdx, &auraBasePoints); - if(roll_chance_i(chance)) - if(SpellEffectEntry const* spellEffect = auraSpellInfo->GetSpellEffect(auraSpellIdx)) - m_caster->CastSpell(unit, spellEffect->EffectTriggerSpell, true, NULL, (*i)); + if (roll_chance_i(chance)) + m_caster->CastSpell(unit, auraSpellInfo->EffectTriggerSpell[auraSpellIdx], true, NULL, (*i)); } } } @@ -4043,7 +3902,7 @@ void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 ca data << uint32(0); // unknown, value 1 seen for 14177 (update cooldowns on client flag) break; case SPELL_FAILED_REQUIRES_SPELL_FOCUS: - data << uint32(spellInfo->GetRequiresSpellFocus()); + data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id break; case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id // hardcode areas limitation case @@ -4066,37 +3925,21 @@ void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 ca } break; case SPELL_FAILED_TOTEMS: - { - SpellTotemsEntry const* totems = spellInfo->GetSpellTotems(); - for(int i = 0; i < MAX_SPELL_TOTEMS; ++i) - if(totems && totems->Totem[i]) - data << uint32(totems->Totem[i]); - } + for (int i = 0; i < MAX_SPELL_TOTEMS; ++i) + if (spellInfo->Totem[i]) + data << uint32(spellInfo->Totem[i]); // client needs only one id, not 2... break; case SPELL_FAILED_TOTEM_CATEGORY: - { - SpellTotemsEntry const* totems = spellInfo->GetSpellTotems(); - for(int i = 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) - if(totems && totems->TotemCategory[i]) - data << uint32(totems->TotemCategory[i]); - } + for (int i = 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) + if (spellInfo->TotemCategory[i]) + data << uint32(spellInfo->TotemCategory[i]);// client needs only one id, not 2... break; case SPELL_FAILED_EQUIPPED_ITEM_CLASS: - { - SpellEquippedItemsEntry const* eqItems = spellInfo->GetSpellEquippedItems(); - data << uint32(eqItems ? eqItems->EquippedItemClass : 0); - data << uint32(eqItems ? eqItems->EquippedItemSubClassMask : 0); - //data << uint32(eqItems ? eqItems->EquippedItemInventoryTypeMask : 0); - } - break; case SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND: case SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND: - { - SpellEquippedItemsEntry const* eqItems = spellInfo->GetSpellEquippedItems(); - data << uint32(eqItems ? eqItems->EquippedItemClass : 0); - data << uint32(eqItems ? eqItems->EquippedItemSubClassMask : 0); + data << uint32(spellInfo->EquippedItemClass); + data << uint32(spellInfo->EquippedItemSubClassMask); break; - } case SPELL_FAILED_PREVENTED_BY_MECHANIC: data << uint32(0); // SpellMechanic.dbc id break; @@ -4104,11 +3947,8 @@ void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 ca data << uint32(0); // custom error id (see enum SpellCastResultCustom) break; case SPELL_FAILED_NEED_EXOTIC_AMMO: - { - SpellEquippedItemsEntry const* eqItems = spellInfo->GetSpellEquippedItems(); - data << uint32(eqItems ? eqItems->EquippedItemSubClassMask : 0);// seems correct... + data << uint32(spellInfo->EquippedItemSubClassMask);// seems correct... break; - } case SPELL_FAILED_REAGENTS: data << uint32(0); // item id break; @@ -4140,14 +3980,12 @@ void Spell::SendSpellStart() DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id); uint32 castFlags = CAST_FLAG_UNKNOWN2; + if (IsRangedSpell()) + castFlags |= CAST_FLAG_AMMO; + if (m_spellInfo->runeCostID) castFlags |= CAST_FLAG_UNKNOWN19; - if ((m_caster->GetTypeId() == TYPEID_PLAYER || - m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->IsPet()) && - m_spellInfo->powerType != POWER_HEALTH) - castFlags |= CAST_FLAG_PREDICTED_POWER; - WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2)); if (m_CastItem) data << m_CastItem->GetPackGUID(); @@ -4159,30 +3997,24 @@ void Spell::SendSpellStart() data << uint32(m_spellInfo->Id); // spellId data << uint32(castFlags); // cast flags data << uint32(m_timer); // delay? - data << uint32(m_casttime); // m_casttime data << m_targets; if (castFlags & CAST_FLAG_PREDICTED_POWER) // predicted power - data << uint32(m_caster->GetPower(Powers(m_spellInfo->powerType))); + data << uint32(0); if (castFlags & CAST_FLAG_PREDICTED_RUNES) // predicted runes { - if (m_caster->GetTypeId() == TYPEID_PLAYER) + uint8 v1 = 0;// m_runesState; + uint8 v2 = 0;//((Player*)m_caster)->GetRunesState(); + data << uint8(v1); // runes state before + data << uint8(v2); // runes state after + for (uint8 i = 0; i < MAX_RUNES; ++i) { - Player* caster = (Player*)m_caster; - - data << uint8(m_runesState); - data << uint8(caster->GetRunesState()); - for (uint8 i = 0; i < MAX_RUNES; ++i) - data << uint8(255 - ((caster->GetRuneCooldown(i) / REGEN_TIME_FULL) * 51)); - } - else - { - data << uint8(0); - data << uint8(0); - for (uint8 i = 0; i < MAX_RUNES; ++i) - data << uint8(0); + uint8 m = (1 << i); + if (m & v1) // usable before... + if (!(m & v2)) // ...but on cooldown now... + data << uint8(0); // some unknown byte (time?) } } @@ -4195,15 +4027,6 @@ void Spell::SendSpellStart() data << uint32(0); // used for SetCastImmunities } - if (castFlags & CAST_FLAG_HEAL_PREDICTION) - { - uint8 unk = 0; - data << uint32(0); - data << uint8(unk); - if (unk == 2) - data << ObjectGuid().WriteAsPacked(); - } - m_caster->SendMessageToSet(&data, true); } @@ -4216,15 +4039,13 @@ void Spell::SendSpellGo() DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id); uint32 castFlags = CAST_FLAG_UNKNOWN9; + if (IsRangedSpell()) + castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual - if ((m_caster->GetTypeId() == TYPEID_PLAYER || - m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->IsPet()) && - m_spellInfo->powerType != POWER_HEALTH) - castFlags |= CAST_FLAG_PREDICTED_POWER; - - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_DEATH_KNIGHT && m_spellInfo->runeCostID) + if ((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID) { castFlags |= CAST_FLAG_UNKNOWN19; // same as in SMSG_SPELL_START + castFlags |= CAST_FLAG_PREDICTED_POWER; // makes cooldowns visible castFlags |= CAST_FLAG_PREDICTED_RUNES; // rune cooldowns list } @@ -4239,7 +4060,6 @@ void Spell::SendSpellGo() data << uint8(m_cast_count); // pending spell cast? data << uint32(m_spellInfo->Id); // spellId data << uint32(castFlags); // cast flags - data << uint32(m_timer); data << uint32(WorldTimer::getMSTime()); // timestamp WriteSpellGoTargets(&data); @@ -4247,32 +4067,27 @@ void Spell::SendSpellGo() data << m_targets; if (castFlags & CAST_FLAG_PREDICTED_POWER) // predicted power - data << uint32(m_caster->GetPower(Powers(m_spellInfo->powerType))); + data << uint32(0); if (castFlags & CAST_FLAG_PREDICTED_RUNES) // predicted runes { - if (m_caster->GetTypeId() == TYPEID_PLAYER) + uint8 v1 = m_runesState; + uint8 v2 = m_caster->getClass() == CLASS_DEATH_KNIGHT ? ((Player*)m_caster)->GetRunesState() : 0; + data << uint8(v1); // runes state before + data << uint8(v2); // runes state after + for (uint8 i = 0; i < MAX_RUNES; ++i) { - Player* caster = (Player*)m_caster; - - data << uint8(m_runesState); - data << uint8(caster->GetRunesState()); - for (uint8 i = 0; i < MAX_RUNES; ++i) - data << uint8(255 - ((caster->GetRuneCooldown(i) / REGEN_TIME_FULL) * 51)); - } - else - { - data << uint8(0); - data << uint8(0); - for (uint8 i = 0; i < MAX_RUNES; ++i) - data << uint8(0); + uint8 m = (1 << i); + if (m & v1) // usable before... + if (!(m & v2)) // ...but on cooldown now... + data << uint8(0); // some unknown byte (time?) } } if (castFlags & CAST_FLAG_ADJUST_MISSILE) // adjust missile trajectory duration { - data << float(m_targets.GetElevation()); - data << uint32(m_delayMoment); + data << float(0); + data << uint32(0); } if (castFlags & CAST_FLAG_AMMO) // projectile info @@ -4318,7 +4133,17 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) ammoDisplayID = pItem->GetProto()->DisplayInfoID; else { - if(m_caster->GetDummyAura(46699)) // Requires No Ammo + uint32 ammoID = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID); + if (ammoID) + { + ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(ammoID); + if (pProto) + { + ammoDisplayID = pProto->DisplayInfoID; + ammoInventoryType = pProto->InventoryType; + } + } + else if (m_caster->GetDummyAura(46699)) // Requires No Ammo { ammoDisplayID = 5996; // normal arrow ammoInventoryType = INVTYPE_AMMO; @@ -4332,15 +4157,14 @@ void Spell::WriteAmmoToPacket(WorldPacket* data) { if (uint32 item_id = m_caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i)) { - if(ItemPrototype const* itemEntry = sItemStorage.LookupEntry(item_id)) - //if(ItemEntry const * itemEntry = sItemStore.LookupEntry(item_id)) + if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id)) { if (itemEntry->Class == ITEM_CLASS_WEAPON) { switch (itemEntry->SubClass) { case ITEM_SUBCLASS_WEAPON_THROWN: - ammoDisplayID = itemEntry->DisplayInfoID; + ammoDisplayID = itemEntry->DisplayId; ammoInventoryType = itemEntry->InventoryType; break; case ITEM_SUBCLASS_WEAPON_BOW: @@ -4431,19 +4255,14 @@ void Spell::SendLogExecute() data << uint32(count1); // count1 (effect count?) for (uint32 i = 0; i < count1; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(EFFECT_INDEX_0); - data << uint32(spellEffect ? spellEffect->Effect : 0);// spell effect + data << uint32(m_spellInfo->Effect[EFFECT_INDEX_0]);// spell effect uint32 count2 = 1; data << uint32(count2); // count2 (target count?) for (uint32 j = 0; j < count2; ++j) { - if(!spellEffect) - continue; - - switch(spellEffect->Effect) + switch (m_spellInfo->Effect[EFFECT_INDEX_0]) { case SPELL_EFFECT_POWER_DRAIN: - case SPELL_EFFECT_POWER_BURN: if (Unit* unit = m_targets.getUnitTarget()) data << unit->GetPackGUID(); else @@ -4481,9 +4300,8 @@ void Spell::SendLogExecute() data << uint8(0); break; case SPELL_EFFECT_CREATE_ITEM: - case SPELL_EFFECT_CREATE_RANDOM_ITEM: case SPELL_EFFECT_CREATE_ITEM_2: - data << uint32(spellEffect->EffectItemType); + data << uint32(m_spellInfo->EffectItemType[EFFECT_INDEX_0]); break; case SPELL_EFFECT_SUMMON: case SPELL_EFFECT_TRANS_DOOR: @@ -4492,10 +4310,9 @@ void Spell::SendLogExecute() case SPELL_EFFECT_CREATE_HOUSE: case SPELL_EFFECT_DUEL: case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: - //case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: - //case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: - //case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: - case SPELL_EFFECT_171: + case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: + case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: + case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: if (Unit* unit = m_targets.getUnitTarget()) data << unit->GetPackGUID(); else if (m_targets.getItemTargetGuid()) @@ -4516,7 +4333,6 @@ void Spell::SendLogExecute() break; case SPELL_EFFECT_RESURRECT: case SPELL_EFFECT_RESURRECT_NEW: - case SPELL_EFFECT_MASS_RESSURECTION: if (Unit* unit = m_targets.getUnitTarget()) data << unit->GetPackGUID(); else @@ -4597,7 +4413,7 @@ void Spell::SendChannelUpdate(uint32 time) m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0); } - WorldPacket data(SMSG_CHANNEL_UPDATE, 8 + 4); + WorldPacket data(MSG_CHANNEL_UPDATE, 8 + 4); data << m_caster->GetPackGUID(); data << uint32(time); m_caster->SendMessageToSet(&data, true); @@ -4608,7 +4424,7 @@ void Spell::SendChannelStart(uint32 duration) WorldObject* target = NULL; // select dynobject created by first effect if any - if (m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_0) == SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (m_spellInfo->Effect[EFFECT_INDEX_0] == SPELL_EFFECT_PERSISTENT_AREA_AURA) target = m_caster->GetDynObject(m_spellInfo->Id, EFFECT_INDEX_0); // select first not resisted target from target list for _0_ effect else if (!m_UniqueTargetInfo.empty()) @@ -4635,26 +4451,10 @@ void Spell::SendChannelStart(uint32 duration) } } - WorldPacket data(SMSG_CHANNEL_START, (8 + 4 + 4)); + WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4)); data << m_caster->GetPackGUID(); data << uint32(m_spellInfo->Id); data << uint32(duration); - data << uint8(0); // unk1 - //if (unk1) - //{ - // data << uint32(0); - // data << uint32(0); - //} - data << uint8(0); // unk2 - //if (unk1) - //{ - // data << ObjectGuid().WriteAsPacked(); - // data << uint32(0); - // data << uint8(0); // unk3 - // if (unk3 == 2) - // data << ObjectGuid().WriteAsPacked(); - //} - m_caster->SendMessageToSet(&data, true); m_timer = duration; @@ -4688,9 +4488,9 @@ void Spell::SendPlaySpellVisual(uint32 SpellID) if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - WorldPacket data; - m_caster->BuildSendPlayVisualPacket(&data, SpellID, false); - + WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 8 + 4); + data << m_caster->GetObjectGuid(); + data << uint32(SpellID); // spell visual id? ((Player*)m_caster)->GetSession()->SendPacket(&data); } @@ -4894,17 +4694,13 @@ void Spell::TakeReagents() if (p_caster->CanNoReagentCast(m_spellInfo)) return; - SpellReagentsEntry const* spellReagents = m_spellInfo->GetSpellReagents(); - - for(uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x) + for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x) { - if(!spellReagents) - continue; - if(spellReagents->Reagent[x] <= 0) + if (m_spellInfo->Reagent[x] <= 0) continue; - uint32 itemid = spellReagents->Reagent[x]; - uint32 itemcount = spellReagents->ReagentCount[x]; + uint32 itemid = m_spellInfo->Reagent[x]; + uint32 itemcount = m_spellInfo->ReagentCount[x]; // if CastItem is also spell reagent if (m_CastItem) @@ -4952,9 +4748,8 @@ void Spell::HandleThreatSpells() bool positive = true; uint8 effectMask = 0; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - if (SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i))) - if (spellEffect->Effect) - effectMask |= (1<Effect[i]) + effectMask |= (1 << i); if (m_negativeEffectMask & effectMask) { @@ -5004,30 +4799,23 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT itemTarget = pItemTarget; gameObjTarget = pGOTarget; - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); + uint8 eff = m_spellInfo->Effect[i]; damage = int32(CalculateDamage(i, unitTarget) * DamageMultiplier); - if(spellEffect) - { - if(spellEffect->Effect < TOTAL_SPELL_EFFECTS) - { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u Effect%d : %u Targets: %s, %s, %s", - m_spellInfo->Id, i, spellEffect->Effect, - unitTarget ? unitTarget->GetGuidStr().c_str() : "-", - itemTarget ? itemTarget->GetGuidStr().c_str() : "-", - gameObjTarget ? gameObjTarget->GetGuidStr().c_str() : "-"); + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u Effect%d : %u Targets: %s, %s, %s", + m_spellInfo->Id, i, eff, + unitTarget ? unitTarget->GetGuidStr().c_str() : "-", + itemTarget ? itemTarget->GetGuidStr().c_str() : "-", + gameObjTarget ? gameObjTarget->GetGuidStr().c_str() : "-"); - (*this.*SpellEffects[spellEffect->Effect])(spellEffect); - } - else - { - sLog.outError("WORLD: Spell %u Effect%d : %u > TOTAL_SPELL_EFFECTS", m_spellInfo->Id, i, spellEffect->Effect); - } + if (eff < TOTAL_SPELL_EFFECTS) + { + (*this.*SpellEffects[eff])(i); } else { - sLog.outError("WORLD: Spell %u has no effect at index %u", m_spellInfo->Id, i); + sLog.outError("WORLD: Spell FX %d > TOTAL_SPELL_EFFECTS ", eff); } } @@ -5127,27 +4915,25 @@ SpellCastResult Spell::CheckCast(bool strict) } } - SpellAuraRestrictionsEntry const* auraRestrictions = m_spellInfo->GetSpellAuraRestrictions(); - // caster state requirements - if(auraRestrictions && auraRestrictions->CasterAuraState && !m_caster->HasAuraState(AuraState(auraRestrictions->CasterAuraState))) + if (m_spellInfo->CasterAuraState && !m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraState))) return SPELL_FAILED_CASTER_AURASTATE; - if(auraRestrictions && auraRestrictions->CasterAuraStateNot && m_caster->HasAuraState(AuraState(auraRestrictions->CasterAuraStateNot))) + if (m_spellInfo->CasterAuraStateNot && m_caster->HasAuraState(AuraState(m_spellInfo->CasterAuraStateNot))) return SPELL_FAILED_CASTER_AURASTATE; // Caster aura req check if need - if(auraRestrictions && auraRestrictions->casterAuraSpell && !m_caster->HasAura(auraRestrictions->casterAuraSpell)) + if (m_spellInfo->casterAuraSpell && !m_caster->HasAura(m_spellInfo->casterAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; - if(auraRestrictions && auraRestrictions->excludeCasterAuraSpell) + if (m_spellInfo->excludeCasterAuraSpell) { // Special cases of non existing auras handling - if(auraRestrictions->excludeCasterAuraSpell == 61988) + if (m_spellInfo->excludeCasterAuraSpell == 61988) { // Avenging Wrath Marker if (m_caster->HasAura(61987)) return SPELL_FAILED_CASTER_AURASTATE; } - else if(m_caster->HasAura(auraRestrictions->excludeCasterAuraSpell)) + else if (m_caster->HasAura(m_spellInfo->excludeCasterAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; } @@ -5158,44 +4944,40 @@ SpellCastResult Spell::CheckCast(bool strict) if (((Player*)m_caster)->isMoving()) { // skip stuck spell to allow use it in falling case and apply spell limitations at movement - if ((!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR) || m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_0) != SPELL_EFFECT_STUCK) && - (IsAutoRepeat() || (m_spellInfo->GetAuraInterruptFlags() & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0)) + if ((!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR) || m_spellInfo->Effect[EFFECT_INDEX_0] != SPELL_EFFECT_STUCK) && + (IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0)) return SPELL_FAILED_MOVING; } if (!m_IsTriggeredSpell && NeedsComboPoints(m_spellInfo) && !m_caster->IsIgnoreUnitState(m_spellInfo, IGNORE_UNIT_TARGET_STATE) && - (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetObjectGuid() != ((Player*)m_caster)->GetComboTargetGuid()) && - !m_spellInfo->HasAttribute(SPELL_ATTR_EX8_IGNORE_TARGET_FOR_COMBO_POINTS)) + (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetObjectGuid() != ((Player*)m_caster)->GetComboTargetGuid())) // warrior not have real combo-points at client side but use this way for mark allow Overpower use return m_caster->getClass() == CLASS_WARRIOR ? SPELL_FAILED_CASTER_AURASTATE : SPELL_FAILED_NO_COMBO_POINTS; } - SpellClassOptionsEntry const* classOptions = m_spellInfo->GetSpellClassOptions(); - - if(Unit *target = m_targets.getUnitTarget()) + if (Unit* target = m_targets.getUnitTarget()) { // target state requirements (not allowed state), apply to self also - if(auraRestrictions && auraRestrictions->TargetAuraStateNot && target->HasAuraState(AuraState(auraRestrictions->TargetAuraStateNot))) + if (m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot))) return SPELL_FAILED_TARGET_AURASTATE; if (!m_IsTriggeredSpell && IsDeathOnlySpell(m_spellInfo) && target->isAlive()) return SPELL_FAILED_TARGET_NOT_DEAD; // Target aura req check if need - if(auraRestrictions && auraRestrictions->targetAuraSpell && !target->HasAura(auraRestrictions->targetAuraSpell)) + if (m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; - - if(auraRestrictions && auraRestrictions->excludeTargetAuraSpell) + if (m_spellInfo->excludeTargetAuraSpell) { // Special cases of non existing auras handling - if (auraRestrictions->excludeTargetAuraSpell == 61988) + if (m_spellInfo->excludeTargetAuraSpell == 61988) { // Avenging Wrath Marker if (target->HasAura(61987)) return SPELL_FAILED_CASTER_AURASTATE; } - else if (target->HasAura(auraRestrictions->excludeTargetAuraSpell)) + else if (target->HasAura(m_spellInfo->excludeTargetAuraSpell)) return SPELL_FAILED_CASTER_AURASTATE; } @@ -5212,8 +4994,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (non_caster_target) { // target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds - if (auraRestrictions && auraRestrictions->TargetAuraState && !target->HasAuraStateForCaster(AuraState(auraRestrictions->TargetAuraState), m_caster->GetObjectGuid()) && - !m_caster->IsIgnoreUnitState(m_spellInfo, auraRestrictions->TargetAuraState == AURA_STATE_FROZEN ? IGNORE_UNIT_TARGET_NON_FROZEN : IGNORE_UNIT_TARGET_STATE)) + if (m_spellInfo->TargetAuraState && !target->HasAuraStateForCaster(AuraState(m_spellInfo->TargetAuraState), m_caster->GetObjectGuid()) && + !m_caster->IsIgnoreUnitState(m_spellInfo, m_spellInfo->TargetAuraState == AURA_STATE_FROZEN ? IGNORE_UNIT_TARGET_NON_FROZEN : IGNORE_UNIT_TARGET_STATE)) return SPELL_FAILED_TARGET_AURASTATE; // Not allow casting on flying player @@ -5240,7 +5022,7 @@ SpellCastResult Spell::CheckCast(bool strict) // If 0 spell effect empty - client not send target data (need use selection) // TODO: check it on next client version if (m_targets.m_targetMask == TARGET_FLAG_SELF && - m_spellInfo->GetEffectImplicitTargetAByIndex(EFFECT_INDEX_1) == TARGET_CHAIN_DAMAGE) + m_spellInfo->EffectImplicitTargetA[EFFECT_INDEX_1] == TARGET_CHAIN_DAMAGE) { target = m_caster->GetMap()->GetUnit(((Player*)m_caster)->GetSelectionGuid()); if (!target) @@ -5253,8 +5035,8 @@ SpellCastResult Spell::CheckCast(bool strict) // Some special spells with non-caster only mode // Fire Shield - if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_WARLOCK && - m_spellInfo->SpellIconID == 16) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && + m_spellInfo->SpellIconID == 16) return SPELL_FAILED_BAD_TARGETS; // Focus Magic (main spell) @@ -5262,8 +5044,8 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_BAD_TARGETS; // Lay on Hands (self cast) - if (classOptions && classOptions->SpellFamilyName == SPELLFAMILY_PALADIN && - classOptions->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && + m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) { if (target->HasAura(25771)) // Forbearance return SPELL_FAILED_CASTER_AURASTATE; @@ -5275,11 +5057,7 @@ SpellCastResult Spell::CheckCast(bool strict) // check pet presents for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); - if(!spellEffect) - continue; - - if(spellEffect->EffectImplicitTargetA == TARGET_PET) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_PET) { Pet* pet = m_caster->GetPet(); if (!pet) @@ -5315,10 +5093,7 @@ SpellCastResult Spell::CheckCast(bool strict) bool target_friendly_checked = false; for (int k = 0; k < MAX_EFFECT_INDEX; ++k) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(k)); - if(!spellEffect) - continue; - if (IsExplicitPositiveTarget(spellEffect->EffectImplicitTargetA)) + if (IsExplicitPositiveTarget(m_spellInfo->EffectImplicitTargetA[k])) { if (!target_hostile_checked) { @@ -5331,7 +5106,7 @@ SpellCastResult Spell::CheckCast(bool strict) explicit_target_mode = true; } - else if (IsExplicitNegativeTarget(spellEffect->EffectImplicitTargetA)) + else if (IsExplicitNegativeTarget(m_spellInfo->EffectImplicitTargetA[k])) { if (!target_friendly_checked) { @@ -5437,28 +5212,24 @@ SpellCastResult Spell::CheckCast(bool strict) { for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); - if(!spellEffect) - continue; - - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || - (spellEffect->EffectImplicitTargetB == TARGET_SCRIPT && spellEffect->EffectImplicitTargetA != TARGET_SELF) || - spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || - spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES || - spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || + (m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[j] != TARGET_SELF) || + m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) { SpellScriptTargetBounds bounds = sSpellMgr.GetSpellScriptTargetBounds(m_spellInfo->Id); if (bounds.first == bounds.second) { - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || spellEffect->EffectImplicitTargetB == TARGET_SCRIPT) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT) sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT, but creature are not defined in `spell_script_target`", m_spellInfo->Id, j); - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES) sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT_COORDINATES, but gameobject or creature are not defined in `spell_script_target`", m_spellInfo->Id, j); - if (spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) sLog.outErrorDb("Spell entry %u, effect %i has EffectImplicitTargetA/EffectImplicitTargetB = TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT, but gameobject are not defined in `spell_script_target`", m_spellInfo->Id, j); } @@ -5558,38 +5329,38 @@ SpellCastResult Spell::CheckCast(bool strict) if (creatureScriptTarget) { // store coordinates for TARGET_SCRIPT_COORDINATES - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || - spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES) { m_targets.setDestination(creatureScriptTarget->GetPositionX(), creatureScriptTarget->GetPositionY(), creatureScriptTarget->GetPositionZ()); - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES && spellEffect->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->Effect[j] != SPELL_EFFECT_PERSISTENT_AREA_AURA) AddUnitTarget(creatureScriptTarget, SpellEffectIndex(j)); } // store explicit target for TARGET_SCRIPT else { - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT || - spellEffect->EffectImplicitTargetB == TARGET_SCRIPT) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT) AddUnitTarget(creatureScriptTarget, SpellEffectIndex(j)); } } else if (goScriptTarget) { // store coordinates for TARGET_SCRIPT_COORDINATES - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES || - spellEffect->EffectImplicitTargetB == TARGET_SCRIPT_COORDINATES) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_SCRIPT_COORDINATES) { m_targets.setDestination(goScriptTarget->GetPositionX(), goScriptTarget->GetPositionY(), goScriptTarget->GetPositionZ()); - if (spellEffect->EffectImplicitTargetA == TARGET_SCRIPT_COORDINATES && spellEffect->Effect != SPELL_EFFECT_PERSISTENT_AREA_AURA) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_SCRIPT_COORDINATES && m_spellInfo->Effect[j] != SPELL_EFFECT_PERSISTENT_AREA_AURA) AddGOTarget(goScriptTarget, SpellEffectIndex(j)); } // store explicit target for TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT else { - if (spellEffect->EffectImplicitTargetA == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || - spellEffect->EffectImplicitTargetB == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT || + m_spellInfo->EffectImplicitTargetB[j] == TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) AddGOTarget(goScriptTarget, SpellEffectIndex(j)); } } @@ -5599,7 +5370,7 @@ SpellCastResult Spell::CheckCast(bool strict) /* For TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT makes DB targets optional not required for now * TODO: Makes more research for this target type */ - if (spellEffect->EffectImplicitTargetA != TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) + if (m_spellInfo->EffectImplicitTargetA[j] != TARGET_FOCUS_OR_SCRIPTED_GAMEOBJECT) { // not report target not existence for triggered spells if (m_triggeredByAuraSpell || m_IsTriggeredSpell) @@ -5634,11 +5405,8 @@ SpellCastResult Spell::CheckCast(bool strict) for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; // for effects of spells that have only one target - switch(spellEffect->Effect) + switch (m_spellInfo->Effect[i]) { case SPELL_EFFECT_INSTAKILL: // Death Pact @@ -5661,8 +5429,8 @@ SpellCastResult Spell::CheckCast(bool strict) if (target->GetOwnerGuid() != m_caster->GetObjectGuid()) return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); - if (!target->IsWithinDistInMap(m_caster,dist)) + float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + if (!target->IsWithinDistInMap(m_caster, dist)) return SPELL_FAILED_OUT_OF_RANGE; // will set in target selection code @@ -5675,11 +5443,6 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->IsInWater()) return SPELL_FAILED_ONLY_ABOVEWATER; } - else if (m_spellInfo->Id == 68996) // Two forms - { - if (m_caster->isInCombat()) - return SPELL_FAILED_AFFECTING_COMBAT; - } else if (m_spellInfo->SpellIconID == 156) // Holy Shock { // spell different for friends and enemies @@ -5688,7 +5451,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_UNIT_NOT_INFRONT; } // Fire Nova - if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_SHAMAN && m_spellInfo->SpellIconID == 33) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellIconID == 33) { // fire totems slot if (!m_caster->GetTotemGuid(TOTEM_SLOT_FIRE)) @@ -5770,7 +5533,7 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_LEARN_SPELL: { - if(spellEffect->EffectImplicitTargetA != TARGET_PET) + if (m_spellInfo->EffectImplicitTargetA[i] != TARGET_PET) break; Pet* pet = m_caster->GetPet(); @@ -5778,12 +5541,12 @@ SpellCastResult Spell::CheckCast(bool strict) if (!pet) return SPELL_FAILED_NO_PET; - SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(spellEffect->EffectTriggerSpell); + SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); if (!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; - if(m_spellInfo->GetSpellLevel() > pet->getLevel()) + if (m_spellInfo->spellLevel > pet->getLevel()) return SPELL_FAILED_LOWLEVEL; break; @@ -5795,20 +5558,21 @@ SpellCastResult Spell::CheckCast(bool strict) if (!pet) return SPELL_FAILED_NO_PET; - SpellEntry const *learn_spellproto = sSpellStore.LookupEntry(spellEffect->EffectTriggerSpell); + SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]); + if (!learn_spellproto) return SPELL_FAILED_NOT_KNOWN; - if(m_spellInfo->GetSpellLevel() > pet->getLevel()) + if (m_spellInfo->spellLevel > pet->getLevel()) return SPELL_FAILED_LOWLEVEL; break; } case SPELL_EFFECT_APPLY_GLYPH: { - uint32 glyphId = spellEffect->EffectMiscValue; - if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyphId)) - if(m_caster->HasAura(gp->SpellId)) + uint32 glyphId = m_spellInfo->EffectMiscValue[i]; + if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId)) + if (m_caster->HasAura(gp->SpellId)) return SPELL_FAILED_UNIQUE_GLYPH; break; } @@ -5843,7 +5607,7 @@ SpellCastResult Spell::CheckCast(bool strict) // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects) if (m_caster->GetTypeId() == TYPEID_PLAYER) if (Unit* target = m_targets.getUnitTarget()) - if (target != m_caster && int32(target->getPowerType()) != spellEffect->EffectMiscValue) + if (target != m_caster && int32(target->getPowerType()) != m_spellInfo->EffectMiscValue[i]) return SPELL_FAILED_BAD_TARGETS; break; } @@ -5890,7 +5654,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_BAD_TARGETS; // we need a go target in case of TARGET_GAMEOBJECT (for other targets acceptable GO and items) - if (spellEffect->EffectImplicitTargetA == TARGET_GAMEOBJECT) + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_GAMEOBJECT) { if (!m_targets.getGOTarget()) return SPELL_FAILED_BAD_TARGETS; @@ -5959,7 +5723,7 @@ SpellCastResult Spell::CheckCast(bool strict) // This is generic summon effect case SPELL_EFFECT_SUMMON: { - if (SummonPropertiesEntry const *summon_prop = sSummonPropertiesStore.LookupEntry(spellEffect->EffectMiscValueB)) + if (SummonPropertiesEntry const* summon_prop = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i])) { if (summon_prop->Group == SUMMON_PROP_GROUP_PETS) { @@ -6021,7 +5785,7 @@ SpellCastResult Spell::CheckCast(bool strict) case SPELL_EFFECT_LEAP: case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER: { - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->EffectRadiusIndex)); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation()); float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation()); // teleport a bit above terrain level to avoid falling below it @@ -6053,11 +5817,7 @@ SpellCastResult Spell::CheckCast(bool strict) for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; - - switch(spellEffect->EffectApplyAuraName) + switch (m_spellInfo->EffectApplyAuraName[i]) { case SPELL_AURA_DUMMY: { @@ -6159,7 +5919,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_NO_MOUNTS_ALLOWED; // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells - if (m_caster->GetTypeId() == TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->GetAreaGroupId()) + if (m_caster->GetTypeId() == TYPEID_PLAYER && !sMapStore.LookupEntry(m_caster->GetMapId())->IsMountAllowed() && !m_IsTriggeredSpell && !m_spellInfo->AreaGroupId) return SPELL_FAILED_NO_MOUNTS_ALLOWED; if (m_caster->IsInDisallowedMountForm()) @@ -6282,16 +6042,12 @@ SpellCastResult Spell::CheckPetCast(Unit* target) bool need = false; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; - - if (spellEffect->EffectImplicitTargetA == TARGET_CHAIN_DAMAGE || - spellEffect->EffectImplicitTargetA == TARGET_SINGLE_FRIEND || - spellEffect->EffectImplicitTargetA == TARGET_SINGLE_FRIEND_2 || - spellEffect->EffectImplicitTargetA == TARGET_DUELVSPLAYER || - spellEffect->EffectImplicitTargetA == TARGET_SINGLE_PARTY || - spellEffect->EffectImplicitTargetA == TARGET_CURRENT_ENEMY_COORDINATES) + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND_2 || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES) { need = true; if (!target) @@ -6319,8 +6075,8 @@ SpellCastResult Spell::CheckPetCast(Unit* target) bool duelvsplayertar = false; for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - //TARGET_DUELVSPLAYER is positive AND negative - duelvsplayertar |= (m_spellInfo->GetEffectImplicitTargetAByIndex(SpellEffectIndex(j)) == TARGET_DUELVSPLAYER); + // TARGET_DUELVSPLAYER is positive AND negative + duelvsplayertar |= (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DUELVSPLAYER); } if (m_caster->IsFriendlyTo(target) && !duelvsplayertar) { @@ -6356,17 +6112,14 @@ SpellCastResult Spell::CheckCasterAuras() const { for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; - if (spellEffect->EffectApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY) - school_immune |= uint32(spellEffect->EffectMiscValue); - else if (spellEffect->EffectApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY) - mechanic_immune |= 1 << uint32(spellEffect->EffectMiscValue-1); - else if (spellEffect->EffectApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY_MASK) - mechanic_immune |= uint32(spellEffect->EffectMiscValue); - else if (spellEffect->EffectApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY) - dispel_immune |= GetDispellMask(DispelType(spellEffect->EffectMiscValue)); + if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_SCHOOL_IMMUNITY) + school_immune |= uint32(m_spellInfo->EffectMiscValue[i]); + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY) + mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i] - 1); + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY_MASK) + mechanic_immune |= uint32(m_spellInfo->EffectMiscValue[i]); + else if (m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DISPEL_IMMUNITY) + dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i])); } // immune movement impairment and loss of control (spell data have special structure for mark this case) @@ -6383,7 +6136,7 @@ SpellCastResult Spell::CheckCasterAuras() const if (unitflag & UNIT_FLAG_STUNNED) { // Pain Suppression (have SPELL_ATTR_EX5_USABLE_WHILE_STUNNED that must be used only with glyph) - if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_PRIEST && m_spellInfo->SpellIconID == 2178) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellIconID == 2178) { if (!m_caster->HasAura(63248)) // Glyph of Pain Suppression spellUsableWhileStunned = false; @@ -6410,9 +6163,9 @@ SpellCastResult Spell::CheckCasterAuras() const prevented_reason = SPELL_FAILED_CONFUSED; else if (unitflag & UNIT_FLAG_FLEEING && !m_spellInfo->HasAttribute(SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) prevented_reason = SPELL_FAILED_FLEEING; - else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE) + else if (unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) prevented_reason = SPELL_FAILED_SILENCED; - else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY) + else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) prevented_reason = SPELL_FAILED_PACIFIED; else if (m_caster->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY)) { @@ -6441,7 +6194,7 @@ SpellCastResult Spell::CheckCasterAuras() const if ((GetSpellSchoolMask(pEntry) & school_immune) && !pEntry->HasAttribute(SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE)) continue; - if ((1<<(pEntry->GetDispel())) & dispel_immune) + if ((1 << (pEntry->Dispel)) & dispel_immune) continue; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) @@ -6471,9 +6224,9 @@ SpellCastResult Spell::CheckCasterAuras() const case SPELL_AURA_MOD_SILENCE: case SPELL_AURA_MOD_PACIFY: case SPELL_AURA_MOD_PACIFY_SILENCE: - if( m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_PACIFY) + if (m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) return SPELL_FAILED_PACIFIED; - else if ( m_spellInfo->GetPreventionType() == SPELL_PREVENTION_TYPE_SILENCE) + else if (m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) return SPELL_FAILED_SILENCED; break; default: break; @@ -6494,24 +6247,21 @@ bool Spell::CanAutoCast(Unit* target) for (int j = 0; j < MAX_EFFECT_INDEX; ++j) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(j)); - if(!spellEffect) - continue; - if(spellEffect->Effect == SPELL_EFFECT_APPLY_AURA) + if (m_spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AURA) { - if( m_spellInfo->GetStackAmount() <= 1) + if (m_spellInfo->StackAmount <= 1) { if (target->HasAura(m_spellInfo->Id, SpellEffectIndex(j))) return false; } else { - if(Aura* aura = target->GetAura(m_spellInfo->Id, SpellEffectIndex(j))) - if(aura->GetStackAmount() >= m_spellInfo->GetStackAmount()) + if (Aura* aura = target->GetAura(m_spellInfo->Id, SpellEffectIndex(j))) + if (aura->GetStackAmount() >= m_spellInfo->StackAmount) return false; } } - else if ( IsAreaAuraEffect( spellEffect->Effect )) + else if (IsAreaAuraEffect(m_spellInfo->Effect[j])) { if (target->HasAura(m_spellInfo->Id, SpellEffectIndex(j))) return false; @@ -6583,8 +6333,8 @@ SpellCastResult Spell::CheckRange(bool strict) return SPELL_FAILED_OUT_OF_RANGE; if (min_range && dist < min_range) return SPELL_FAILED_TOO_CLOSE; - if( m_caster->GetTypeId() == TYPEID_PLAYER && - (m_spellInfo->GetFacingCasterFlags() & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc( M_PI_F, target ) ) + if (m_caster->GetTypeId() == TYPEID_PLAYER && + (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(M_PI_F, target)) return SPELL_FAILED_UNIT_NOT_INFRONT; } @@ -6620,23 +6370,24 @@ uint32 Spell::CalculatePowerCost(SpellEntry const* spellInfo, Unit* caster, Spel } // Base powerCost - int32 powerCost = spellInfo->GetManaCost(); + int32 powerCost = spellInfo->manaCost; // PCT cost from total amount - if (uint32 manaCostPct = spellInfo->GetManaCostPercentage()) + if (spellInfo->ManaCostPercentage) { switch (spellInfo->powerType) { // health as power used case POWER_HEALTH: - powerCost += manaCostPct * caster->GetCreateHealth() / 100; + powerCost += spellInfo->ManaCostPercentage * caster->GetCreateHealth() / 100; break; case POWER_MANA: - powerCost += manaCostPct * caster->GetCreateMana() / 100; + powerCost += spellInfo->ManaCostPercentage * caster->GetCreateMana() / 100; break; case POWER_RAGE: case POWER_FOCUS: case POWER_ENERGY: - powerCost += manaCostPct * caster->GetMaxPower(Powers(spellInfo->powerType)) / 100; + case POWER_HAPPINESS: + powerCost += spellInfo->ManaCostPercentage * caster->GetMaxPower(Powers(spellInfo->powerType)) / 100; break; case POWER_RUNE: case POWER_RUNIC_POWER: @@ -6659,7 +6410,7 @@ uint32 Spell::CalculatePowerCost(SpellEntry const* spellInfo, Unit* caster, Spel modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, powerCost, spell); if (spellInfo->HasAttribute(SPELL_ATTR_LEVEL_DAMAGE_CALCULATION)) - powerCost = int32(powerCost / (1.117f * spellInfo->GetSpellLevel() / caster->getLevel() - 0.1327f)); + powerCost = int32(powerCost / (1.117f * spellInfo->spellLevel / caster->getLevel() - 0.1327f)); // PCT mod from user auras by school powerCost = int32(powerCost * (1.0f + caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school))); @@ -6729,12 +6480,8 @@ bool Spell::IgnoreItemRequirements() const /// Some triggered spells have same reagents that have master spell /// expected in test: master spell have reagents in first slot then triggered don't must use own - if (m_triggeredBySpellInfo) - { - SpellReagentsEntry const* spellReagents = m_triggeredBySpellInfo->GetSpellReagents(); - if (!spellReagents || !spellReagents->Reagent[0]) - return false; - } + if (m_triggeredBySpellInfo && !m_triggeredBySpellInfo->Reagent[0]) + return false; return true; } @@ -6780,14 +6527,11 @@ SpellCastResult Spell::CheckItems() SpellCastResult failReason = SPELL_CAST_OK; for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; // skip check, pet not required like checks, and for TARGET_PET m_targets.getUnitTarget() is not the real target but the caster - if (spellEffect->EffectImplicitTargetA == TARGET_PET) + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_PET) continue; - if (spellEffect->Effect == SPELL_EFFECT_HEAL) + if (m_spellInfo->Effect[i] == SPELL_EFFECT_HEAL) { if (m_targets.getUnitTarget()->GetHealth() == m_targets.getUnitTarget()->GetMaxHealth()) { @@ -6802,15 +6546,15 @@ SpellCastResult Spell::CheckItems() } // Mana Potion, Rage Potion, Thistle Tea(Rogue), ... - if (spellEffect->Effect == SPELL_EFFECT_ENERGIZE) + if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENERGIZE) { - if(spellEffect->EffectMiscValue < 0 || spellEffect->EffectMiscValue >= MAX_POWERS) + if (m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS) { failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER; continue; } - Powers power = Powers(spellEffect->EffectMiscValue); + Powers power = Powers(m_spellInfo->EffectMiscValue[i]); if (m_targets.getUnitTarget()->GetPower(power) == m_targets.getUnitTarget()->GetMaxPower(power)) { failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER; @@ -6857,10 +6601,10 @@ SpellCastResult Spell::CheckItems() } // check spell focus object - if(uint32 spellFocus = m_spellInfo->GetRequiresSpellFocus()) + if (m_spellInfo->RequiresSpellFocus) { GameObject* ok = NULL; - MaNGOS::GameObjectFocusCheck go_check(m_caster, spellFocus); + MaNGOS::GameObjectFocusCheck go_check(m_caster, m_spellInfo->RequiresSpellFocus); MaNGOS::GameObjectSearcher checker(ok, go_check); Cell::VisitGridObjects(m_caster, checker, m_caster->GetMap()->GetVisibilityDistance()); @@ -6875,100 +6619,89 @@ SpellCastResult Spell::CheckItems() { if (!p_caster->CanNoReagentCast(m_spellInfo)) { - SpellReagentsEntry const* spellReagents = m_spellInfo->GetSpellReagents(); - if(spellReagents) + for (uint32 i = 0; i < MAX_SPELL_REAGENTS; ++i) { - for(uint32 i = 0; i < MAX_SPELL_REAGENTS; ++i) + if (m_spellInfo->Reagent[i] <= 0) + continue; + + uint32 itemid = m_spellInfo->Reagent[i]; + uint32 itemcount = m_spellInfo->ReagentCount[i]; + + // if CastItem is also spell reagent + if (m_CastItem && m_CastItem->GetEntry() == itemid) { - if(spellReagents->Reagent[i] <= 0) - continue; - - uint32 itemid = spellReagents->Reagent[i]; - uint32 itemcount = spellReagents->ReagentCount[i]; - - // if CastItem is also spell reagent - if (m_CastItem && m_CastItem->GetEntry() == itemid) + ItemPrototype const* proto = m_CastItem->GetProto(); + if (!proto) + return SPELL_FAILED_REAGENTS; + for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) { - ItemPrototype const *proto = m_CastItem->GetProto(); - if (!proto) - return SPELL_FAILED_REAGENTS; - for(int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s) + // CastItem will be used up and does not count as reagent + int32 charges = m_CastItem->GetSpellCharges(s); + if (proto->Spells[s].SpellCharges < 0 && !(proto->ExtraFlags & ITEM_EXTRA_NON_CONSUMABLE) && abs(charges) < 2) { - // CastItem will be used up and does not count as reagent - int32 charges = m_CastItem->GetSpellCharges(s); - if (proto->Spells[s].SpellCharges < 0 && !(proto->ExtraFlags & ITEM_EXTRA_NON_CONSUMABLE) && abs(charges) < 2) - { - ++itemcount; - break; - } + ++itemcount; + break; } } - - if (!p_caster->HasItemCount(itemid, itemcount)) - return SPELL_FAILED_REAGENTS; } + + if (!p_caster->HasItemCount(itemid, itemcount)) + return SPELL_FAILED_REAGENTS; } } // check totem-item requirements (items presence in inventory) - SpellTotemsEntry const* spellTotems = m_spellInfo->GetSpellTotems(); - if(spellTotems) + uint32 totems = MAX_SPELL_TOTEMS; + for (int i = 0; i < MAX_SPELL_TOTEMS ; ++i) { - uint32 totems = MAX_SPELL_TOTEMS; - for(int i = 0; i < MAX_SPELL_TOTEMS ; ++i) + if (m_spellInfo->Totem[i] != 0) { - if (spellTotems->Totem[i] != 0) + if (p_caster->HasItemCount(m_spellInfo->Totem[i], 1)) { - if (p_caster->HasItemCount(spellTotems->Totem[i], 1)) - { - totems -= 1; - continue; - } - } - else totems -= 1; - } - - if (totems != 0) - return SPELL_FAILED_TOTEMS; - - // Check items for TotemCategory (items presence in inventory) - uint32 TotemCategory = MAX_SPELL_TOTEM_CATEGORIES; - for(int i= 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) - { - if (spellTotems->TotemCategory[i] != 0) - { - if (p_caster->HasItemTotemCategory(spellTotems->TotemCategory[i])) - { - TotemCategory -= 1; - continue; - } + continue; } - else - TotemCategory -= 1; } - - if (TotemCategory != 0) - return SPELL_FAILED_TOTEM_CATEGORY; + else + totems -= 1; } + + if (totems != 0) + return SPELL_FAILED_TOTEMS; + + // Check items for TotemCategory (items presence in inventory) + uint32 TotemCategory = MAX_SPELL_TOTEM_CATEGORIES; + for (int i = 0; i < MAX_SPELL_TOTEM_CATEGORIES; ++i) + { + if (m_spellInfo->TotemCategory[i] != 0) + { + if (p_caster->HasItemTotemCategory(m_spellInfo->TotemCategory[i])) + { + TotemCategory -= 1; + continue; + } + } + else + TotemCategory -= 1; + } + + if (TotemCategory != 0) + return SPELL_FAILED_TOTEM_CATEGORY; } // special checks for spell effects for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; - switch (spellEffect->Effect) + switch (m_spellInfo->Effect[i]) { case SPELL_EFFECT_CREATE_ITEM: { - if (!m_IsTriggeredSpell && spellEffect->EffectItemType) + if (!m_IsTriggeredSpell && m_spellInfo->EffectItemType[i]) { // Conjure Mana Gem (skip same or low level ranks for later recharge) - if (i == EFFECT_INDEX_0 && m_spellInfo->GetSpellEffectIdByIndex(EFFECT_INDEX_1) == SPELL_EFFECT_DUMMY) + if (i == EFFECT_INDEX_0 && m_spellInfo->Effect[EFFECT_INDEX_1] == SPELL_EFFECT_DUMMY) { - if (ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(spellEffect->EffectItemType)) + if (ItemPrototype const* itemProto = ObjectMgr::GetItemPrototype(m_spellInfo->EffectItemType[i])) { if (Item* item = p_caster->GetItemByLimitedCategory(itemProto->ItemLimitCategory)) { @@ -6985,10 +6718,10 @@ SpellCastResult Spell::CheckItems() } ItemPosCountVec dest; - InventoryResult msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, spellEffect->EffectItemType, 1 ); - if (msg != EQUIP_ERR_OK ) + InventoryResult msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1); + if (msg != EQUIP_ERR_OK) { - p_caster->SendEquipError( msg, NULL, NULL, spellEffect->EffectItemType ); + p_caster->SendEquipError(msg, NULL, NULL, m_spellInfo->EffectItemType[i]); return SPELL_FAILED_DONT_REPORT; } } @@ -6996,7 +6729,7 @@ SpellCastResult Spell::CheckItems() } case SPELL_EFFECT_RESTORE_ITEM_CHARGES: { - if (Item* item = p_caster->GetItemByEntry(spellEffect->EffectItemType)) + if (Item* item = p_caster->GetItemByEntry(m_spellInfo->EffectItemType[i])) if (item->HasMaxCharges()) return SPELL_FAILED_ITEM_AT_MAX_CHARGES; @@ -7009,13 +6742,13 @@ SpellCastResult Spell::CheckItems() if (!targetItem) return SPELL_FAILED_ITEM_NOT_FOUND; - if( targetItem->GetProto()->ItemLevel < m_spellInfo->GetBaseLevel() ) + if (targetItem->GetProto()->ItemLevel < m_spellInfo->baseLevel) return SPELL_FAILED_LOWLEVEL; // Check if we can store a new scroll, enchanting vellum has implicit SPELL_EFFECT_CREATE_ITEM - if (isVellumTarget && spellEffect->EffectItemType) + if (isVellumTarget && m_spellInfo->EffectItemType[i]) { ItemPosCountVec dest; - InventoryResult msg = p_caster->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellEffect->EffectItemType, 1 ); + InventoryResult msg = p_caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1); if (msg != EQUIP_ERR_OK) { p_caster->SendEquipError(msg, NULL, NULL); @@ -7025,9 +6758,9 @@ SpellCastResult Spell::CheckItems() // Not allow enchant in trade slot for some enchant type if (targetItem->GetOwner() != m_caster) { - uint32 enchant_id = spellEffect->EffectMiscValue; - SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if(!pEnchant) + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if (!pEnchant) return SPELL_FAILED_ERROR; if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND) return SPELL_FAILED_NOT_TRADEABLE; @@ -7045,9 +6778,9 @@ SpellCastResult Spell::CheckItems() // Not allow enchant in trade slot for some enchant type if (item->GetOwner() != m_caster) { - uint32 enchant_id = spellEffect->EffectMiscValue; - SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if(!pEnchant) + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if (!pEnchant) return SPELL_FAILED_ERROR; if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND) return SPELL_FAILED_NOT_TRADEABLE; @@ -7144,6 +6877,46 @@ SpellCastResult Spell::CheckItems() if (!((Player*)m_caster)->HasItemCount(ammo, 1)) return SPELL_FAILED_NO_AMMO; }; break; + case ITEM_SUBCLASS_WEAPON_GUN: + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + { + uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID); + if (!ammo) + { + // Requires No Ammo + if (m_caster->GetDummyAura(46699)) + break; // skip other checks + + return SPELL_FAILED_NO_AMMO; + } + + ItemPrototype const* ammoProto = ObjectMgr::GetItemPrototype(ammo); + if (!ammoProto) + return SPELL_FAILED_NO_AMMO; + + if (ammoProto->Class != ITEM_CLASS_PROJECTILE) + return SPELL_FAILED_NO_AMMO; + + // check ammo ws. weapon compatibility + switch (pItem->GetProto()->SubClass) + { + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW) + return SPELL_FAILED_NO_AMMO; + break; + case ITEM_SUBCLASS_WEAPON_GUN: + if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET) + return SPELL_FAILED_NO_AMMO; + break; + default: + return SPELL_FAILED_NO_AMMO; + } + + if (!((Player*)m_caster)->HasItemCount(ammo, 1)) + return SPELL_FAILED_NO_AMMO; + }; break; case ITEM_SUBCLASS_WEAPON_WAND: break; default: @@ -7170,7 +6943,7 @@ void Spell::Delayed() return; // spells not loosing casting time ( slam, dynamites, bombs.. ) - if(!(m_spellInfo->GetInterruptFlags() & SPELL_INTERRUPT_FLAG_DAMAGE)) + if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE)) return; // check pushback reduce @@ -7272,10 +7045,10 @@ void Spell::UpdatePointers() bool Spell::CheckTargetCreatureType(Unit* target) const { - uint32 spellCreatureTargetMask = m_spellInfo->GetTargetCreatureType(); + uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType; // Curse of Doom: not find another way to fix spell target check :/ - if (m_spellInfo->GetSpellFamilyName() == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == 1179) + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == 1179) { // not allow cast at player if (target->GetTypeId() == TYPEID_PLAYER) @@ -7311,26 +7084,18 @@ CurrentSpellTypes Spell::GetCurrentContainer() bool Spell::CheckTarget(Unit* target, SpellEffectIndex eff) { - SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(eff); - if(!spellEffect) - return false; - // Check targets for creature type mask and remove not appropriate (skip explicit self target case, maybe need other explicit targets) - if(spellEffect->EffectImplicitTargetA != TARGET_SELF ) + if (m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SELF) { if (!CheckTargetCreatureType(target)) return false; } // Check Aura spell req (need for AoE spells) - SpellAuraRestrictionsEntry const* auraRestrictions = m_spellInfo->GetSpellAuraRestrictions(); - if(auraRestrictions) - { - if(auraRestrictions->targetAuraSpell && !target->HasAura(auraRestrictions->targetAuraSpell)) - return false; - if (auraRestrictions->excludeTargetAuraSpell && target->HasAura(auraRestrictions->excludeTargetAuraSpell)) - return false; - } + if (m_spellInfo->targetAuraSpell && !target->HasAura(m_spellInfo->targetAuraSpell)) + return false; + if (m_spellInfo->excludeTargetAuraSpell && target->HasAura(m_spellInfo->excludeTargetAuraSpell)) + return false; // Check targets for not_selectable unit flag and remove // A player can cast spells on his pet (or other controlled unit) though in any state @@ -7343,13 +7108,13 @@ bool Spell::CheckTarget(Unit* target, SpellEffectIndex eff) // unselectable targets skipped in all cases except TARGET_SCRIPT targeting // in case TARGET_SCRIPT target selected by server always and can't be cheated if ((!m_IsTriggeredSpell || target != m_targets.getUnitTarget()) && - target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) && - spellEffect->EffectImplicitTargetA != TARGET_SCRIPT && - spellEffect->EffectImplicitTargetB != TARGET_SCRIPT && - spellEffect->EffectImplicitTargetA != TARGET_AREAEFFECT_INSTANT && - spellEffect->EffectImplicitTargetB != TARGET_AREAEFFECT_INSTANT && - spellEffect->EffectImplicitTargetA != TARGET_AREAEFFECT_CUSTOM && - spellEffect->EffectImplicitTargetB != TARGET_AREAEFFECT_CUSTOM ) + target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE) && + m_spellInfo->EffectImplicitTargetA[eff] != TARGET_SCRIPT && + m_spellInfo->EffectImplicitTargetB[eff] != TARGET_SCRIPT && + m_spellInfo->EffectImplicitTargetA[eff] != TARGET_AREAEFFECT_INSTANT && + m_spellInfo->EffectImplicitTargetB[eff] != TARGET_AREAEFFECT_INSTANT && + m_spellInfo->EffectImplicitTargetA[eff] != TARGET_AREAEFFECT_CUSTOM && + m_spellInfo->EffectImplicitTargetB[eff] != TARGET_AREAEFFECT_CUSTOM) return false; } @@ -7364,7 +7129,7 @@ bool Spell::CheckTarget(Unit* target, SpellEffectIndex eff) } // Check targets for LOS visibility (except spells without range limitations ) - switch(spellEffect->Effect) + switch (m_spellInfo->Effect[eff]) { case SPELL_EFFECT_SUMMON_PLAYER: // from anywhere break; @@ -7421,8 +7186,8 @@ bool Spell::IsNeedSendToClient() const bool Spell::IsTriggeredSpellWithRedundentData() const { return m_triggeredByAuraSpell || m_triggeredBySpellInfo || - // possible not need after above check? - m_IsTriggeredSpell && (m_spellInfo->GetManaCost() || m_spellInfo->GetManaCostPercentage()); + // possible not need after above check? + m_IsTriggeredSpell && (m_spellInfo->manaCost || m_spellInfo->ManaCostPercentage); } bool Spell::HaveTargetsForEffect(SpellEffectIndex effect) const @@ -7590,7 +7355,7 @@ SpellCastResult Spell::CanOpenLock(SpellEffectIndex effIndex, uint32 lockId, Ski reqKey = true; // wrong locktype, skip - if(uint32(m_spellInfo->GetEffectMiscValue(effIndex)) != lockInfo->Index[j]) + if (uint32(m_spellInfo->EffectMiscValue[effIndex]) != lockInfo->Index[j]) continue; skillId = SkillByLockType(LockType(lockInfo->Index[j])); @@ -7779,11 +7544,7 @@ void Spell::SelectMountByAreaAndSkill(Unit* target, SpellEntry const* parentSpel SpellEntry const* spellInfo = sSpellStore.LookupEntry(iter->first); for (int i = 0; i < MAX_EFFECT_INDEX; ++i) { - SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(i)); - if(!spellEffect) - continue; - - if(spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) + if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) { int32 mountSpeed = spellInfo->CalculateSimpleValue(SpellEffectIndex(i)); @@ -7831,7 +7592,7 @@ bool Spell::HasGlobalCooldown() void Spell::TriggerGlobalCooldown() { - int32 gcd = m_spellInfo->GetStartRecoveryTime(); + int32 gcd = m_spellInfo->StartRecoveryTime; if (!gcd) return; @@ -7862,7 +7623,7 @@ void Spell::TriggerGlobalCooldown() void Spell::CancelGlobalCooldown() { - if (!m_spellInfo->GetStartRecoveryTime()) + if (!m_spellInfo->StartRecoveryTime) return; // cancel global cooldown when interrupting current cast