diff options
Diffstat (limited to 'src')
67 files changed, 2111 insertions, 1794 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 442da862b8a..5a0c199a4c0 100755 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -141,13 +141,8 @@ void PetAI::UpdateAI(const uint32 diff) if (me->GetCharmInfo() && me->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) continue; - // ignore some combinations of combat state and combat/noncombat spells - if (!me->getVictim()) + if (spellInfo->IsPositive()) { - // ignore attacking spells, and allow only self/around spells - if (!spellInfo->IsPositive()) - continue; - // non combat spells allowed // only pet spells have IsNonCombatSpell and not fit this reqs: // Consume Shadows, Lesser Invisibility, so ignore checks for its @@ -163,36 +158,21 @@ void PetAI::UpdateAI(const uint32 diff) if (cooldown >= 0 && duration >= 0 && cooldown > duration) continue; } - } - else - { - // just ignore non-combat spells - if (!spellInfo->CanBeUsedInCombat()) - continue; - } - Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0); + Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0); - // Fix to allow pets on STAY to autocast - if (me->getVictim() && _CanAttack(me->getVictim()) && spell->CanAutoCast(me->getVictim())) - { - targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(me->getVictim(), spell)); - continue; - } - else - { bool spellUsed = false; for (std::set<uint64>::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar) { - Unit* Target = ObjectAccessor::GetUnit(*me, *tar); + Unit* target = ObjectAccessor::GetUnit(*me, *tar); //only buff targets that are in combat, unless the spell can only be cast while out of combat - if (!Target) + if (!target) continue; - if (spell->CanAutoCast(Target)) + if (spell->CanAutoCast(target)) { - targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(Target, spell)); + targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(target, spell)); spellUsed = true; break; } @@ -200,6 +180,14 @@ void PetAI::UpdateAI(const uint32 diff) if (!spellUsed) delete spell; } + else if (me->getVictim() && _CanAttack(me->getVictim()) && spellInfo->CanBeUsedInCombat()) + { + Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0); + if (spell->CanAutoCast(me->getVictim())) + targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(me->getVictim(), spell)); + else + delete spell; + } } //found units to cast on to diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 476c4fb9c70..e11be0612a2 100755 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -23,6 +23,7 @@ #include "SpellAuraEffects.h" #include "SpellMgr.h" #include "SpellInfo.h" +#include "Spell.h" #include "CreatureAIImpl.h" void UnitAI::AttackStart(Unit* victim) @@ -245,3 +246,57 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/) if (!target || !charmer->IsValidAttackTarget(target)) AttackStart(charmer->SelectNearestTargetInAttackDistance()); } + +SpellTargetSelector::SpellTargetSelector(Unit* caster, uint32 spellId) : + _caster(caster), _spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(sSpellMgr->GetSpellInfo(spellId), caster)) +{ + ASSERT(_spellInfo); +} + +bool SpellTargetSelector::operator()(Unit const* target) const +{ + if (!target) + return false; + + if (_spellInfo->CheckTarget(_caster, target) != SPELL_CAST_OK) + return false; + + // copypasta from Spell::CheckRange + uint32 range_type = _spellInfo->RangeEntry ? _spellInfo->RangeEntry->type : 0; + float max_range = _caster->GetSpellMaxRangeForTarget(target, _spellInfo); + float min_range = _caster->GetSpellMinRangeForTarget(target, _spellInfo); + + + if (target && target != _caster) + { + if (range_type == SPELL_RANGE_MELEE) + { + // Because of lag, we can not check too strictly here. + if (!_caster->IsWithinMeleeRange(target, max_range)) + return false; + } + else if (!_caster->IsWithinCombatRange(target, max_range)) + return false; + + if (range_type == SPELL_RANGE_RANGED) + { + if (_caster->IsWithinMeleeRange(target)) + return false; + } + else if (min_range && _caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0 + return false; + } + + return true; +} + +bool NonTankTargetSelector::operator()(Unit const* target) const +{ + if (!target) + return false; + + if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER) + return false; + + return target != _source->getVictim(); +} diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 98f0e4bb1a4..8485559c7fa 100755 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -97,6 +97,33 @@ struct DefaultTargetSelector : public std::unary_function<Unit* , bool> } }; +// Target selector for spell casts checking range, auras and attributes +// TODO: Add more checks from Spell::CheckCast +struct SpellTargetSelector : public std::unary_function<Unit*, bool> +{ + public: + SpellTargetSelector(Unit* caster, uint32 spellId); + bool operator()(Unit const* target) const; + + private: + Unit const* _caster; + SpellInfo const* _spellInfo; +}; + +// Very simple target selector, will just skip main target +// NOTE: When passing to UnitAI::SelectTarget remember to use 0 as position for random selection +// because tank will not be in the temporary list +struct NonTankTargetSelector : public std::unary_function<Unit*, bool> +{ + public: + NonTankTargetSelector(Creature* source, bool playerOnly = true) : _source(source), _playerOnly(playerOnly) { } + bool operator()(Unit const* target) const; + + private: + Creature const* _source; + bool _playerOnly; +}; + class UnitAI { protected: diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index a7176e3b550..a5feac09ea4 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -220,7 +220,12 @@ Battleground::~Battleground() sBattlegroundMgr->RemoveBattleground(GetInstanceID(), GetTypeID()); // unload map if (m_Map) + { m_Map->SetUnload(); + //unlink to prevent crash, always unlink all pointer reference before destruction + m_Map->SetBG(NULL); + m_Map = NULL; + } // remove from bg free slot queue RemoveFromBGFreeSlotQueue(); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 4305f90d7a3..8bd464a4820 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1526,17 +1526,22 @@ bool Position::HasInArc(float arc, const Position* obj) const bool WorldObject::IsInBetween(const WorldObject* obj1, const WorldObject* obj2, float size) const { - if (GetPositionX() > std::max(obj1->GetPositionX(), obj2->GetPositionX()) - || GetPositionX() < std::min(obj1->GetPositionX(), obj2->GetPositionX()) - || GetPositionY() > std::max(obj1->GetPositionY(), obj2->GetPositionY()) - || GetPositionY() < std::min(obj1->GetPositionY(), obj2->GetPositionY())) + if (!obj1 || !obj2) + return false; + + float dist = GetExactDist2d(obj1->GetPositionX(), obj1->GetPositionY()); + + // not using sqrt() for performance + if ((dist * dist) >= obj1->GetExactDist2dSq(obj2->GetPositionX(), obj2->GetPositionY())) return false; if (!size) size = GetObjectSize() / 2; - float angle = obj1->GetAngle(this) - obj1->GetAngle(obj2); - return fabs(sin(angle)) * GetExactDist2d(obj1->GetPositionX(), obj1->GetPositionY()) < size; + float angle = obj1->GetAngle(obj2); + + // not using sqrt() for performance + return (size * size) >= GetExactDist2dSq(obj1->GetPositionX() + cos(angle) * dist, obj1->GetPositionY() + sin(angle) * dist); } bool WorldObject::isInFront(WorldObject const* target, float distance, float arc) const diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp index 245ad83bd20..10c54720350 100755 --- a/src/server/game/Entities/Totem/Totem.cpp +++ b/src/server/game/Entities/Totem/Totem.cpp @@ -86,8 +86,9 @@ void Totem::InitStats(uint32 duration) void Totem::InitSummon() { + // use AddAura instead of CastSpell - this in fact should be an AddSpell equivalent for creatures, but nothing like that exists so far. if (m_type == TOTEM_PASSIVE) - CastSpell(this, GetSpell(), true); + AddAura(GetSpell(), this); // Some totems can have both instant effect and passive spell if (GetSpell(1)) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d6199cbd910..5301b647bea 100755..100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -874,6 +874,33 @@ void Unit::CastStop(uint32 except_spellid) InterruptSpell(CurrentSpellTypes(i), false); } +void Unit::CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) +{ + if (!spellInfo) + { + sLog->outError("CastSpell: unknown spell by caster: %s %u)", (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + return; + } + + // TODO: this is a workaround and needs removal + if (!originalCaster && GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem() && IsControlledByPlayer()) + if (Unit* owner = GetOwner()) + originalCaster=owner->GetGUID(); + + // TODO: this is a workaround - not needed anymore, but required for some scripts :( + if (!originalCaster && triggeredByAura) + originalCaster = triggeredByAura->GetCasterGUID(); + + Spell* spell = new Spell(this, spellInfo, triggerFlags, originalCaster); + + if (value) + for (CustomSpellValues::const_iterator itr = value->begin(); itr != value->end(); ++itr) + spell->SetSpellValue(itr->first, itr->second); + + spell->m_CastItem = castItem; + spell->prepare(&targets, triggeredByAura); +} + void Unit::CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) { CastSpell(victim, spellId, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); @@ -882,10 +909,9 @@ void Unit::CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castIte void Unit::CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags /*= TRIGGER_NONE*/, Item* castItem /*= NULL*/, AuraEffect const* triggeredByAura /*= NULL*/, uint64 originalCaster /*= 0*/) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo) { - sLog->outError("CastSpell: unknown spell id %i by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + sLog->outError("CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } @@ -899,29 +925,9 @@ void Unit::CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, I void Unit::CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) { - if (!spellInfo) - { - sLog->outError("CastSpell: unknown spell by caster: %s %u)", (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); - return; - } - - if (!originalCaster && GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem() && IsControlledByPlayer()) - if (Unit* owner = GetOwner()) - originalCaster=owner->GetGUID(); - SpellCastTargets targets; targets.SetUnitTarget(victim); - - if (castItem) - sLog->outStaticDebug("WORLD: cast Item spellId - %i", spellInfo->Id); - - if (!originalCaster && triggeredByAura) - originalCaster = triggeredByAura->GetCasterGUID(); - - Spell* spell = new Spell(this, spellInfo, triggerFlags, originalCaster); - - spell->m_CastItem = castItem; - spell->prepare(&targets, triggeredByAura); + CastSpell(targets, spellInfo, NULL, triggerFlags, castItem, triggeredByAura, originalCaster); } void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) @@ -948,81 +954,41 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { - sLog->outError("CastSpell: unknown spell id %i by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + sLog->outError("CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } - SpellCastTargets targets; targets.SetUnitTarget(victim); - if (!originalCaster && triggeredByAura) - originalCaster = triggeredByAura->GetCasterGUID(); - - Spell* spell = new Spell(this, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, originalCaster); - - if (castItem) - { - sLog->outStaticDebug("WORLD: cast Item spellId - %i", spellInfo->Id); - spell->m_CastItem = castItem; - } - - for (CustomSpellValues::const_iterator itr = value.begin(); itr != value.end(); ++itr) - spell->SetSpellValue(itr->first, itr->second); - - spell->prepare(&targets, triggeredByAura); + CastSpell(targets, spellInfo, &value, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); } -// used for scripting void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo) { - sLog->outError("CastSpell(x, y, z): unknown spell id %i by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + sLog->outError("CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } - - if (castItem) - sLog->outStaticDebug("WORLD: cast Item spellId - %i", spellInfo->Id); - - if (!originalCaster && triggeredByAura) - originalCaster = triggeredByAura->GetCasterGUID(); - - Spell* spell = new Spell(this, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, originalCaster); - SpellCastTargets targets; targets.SetDst(x, y, z, GetOrientation()); - spell->m_CastItem = castItem; - spell->prepare(&targets, triggeredByAura); + + CastSpell(targets, spellInfo, NULL, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); } -// used for scripting void Unit::CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castItem, AuraEffect* triggeredByAura, uint64 originalCaster) { - if (!go) - return; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo) { - sLog->outError("CastSpell(x, y, z): unknown spell id %i by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + sLog->outError("CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } - - if (castItem) - sLog->outStaticDebug("WORLD: cast Item spellId - %i", spellInfo->Id); - - if (!originalCaster && triggeredByAura) - originalCaster = triggeredByAura->GetCasterGUID(); - - Spell* spell = new Spell(this, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, originalCaster); - SpellCastTargets targets; targets.SetGOTarget(go); - spell->m_CastItem = castItem; - spell->prepare(&targets, triggeredByAura); + + CastSpell(targets, spellInfo, NULL, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); } // Obsolete func need remove, here only for comotability vs another patches @@ -1968,7 +1934,7 @@ void Unit::AttackerStateUpdate (Unit* victim, WeaponAttackType attType, bool ext return; // ignore ranged case // melee attack spell casted at main hand attack only - no normal melee dmg dealt - if (attType == BASE_ATTACK && m_currentSpells[CURRENT_MELEE_SPELL]) + if (attType == BASE_ATTACK && m_currentSpells[CURRENT_MELEE_SPELL] && !extra) m_currentSpells[CURRENT_MELEE_SPELL]->cast(); else { @@ -1993,15 +1959,14 @@ void Unit::AttackerStateUpdate (Unit* victim, WeaponAttackType attType, bool ext sLog->outStaticDebug("AttackerStateUpdate: (NPC) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", GetGUIDLow(), victim->GetGUIDLow(), victim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); } +} - if (!extra && m_extraAttacks) +void Unit::HandleProcExtraAttackFor(Unit* victim) +{ + while (m_extraAttacks) { - while(m_extraAttacks) - { - AttackerStateUpdate(victim, BASE_ATTACK, true); - if (m_extraAttacks > 0) - --m_extraAttacks; - } + AttackerStateUpdate(victim, BASE_ATTACK, true); + --m_extraAttacks; } } @@ -5632,6 +5597,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere instance->DoCastSpellOnPlayers(65037); // Achievement criteria marker break; } + // Dark Hunger (The Lich King encounter) + case 69383: + { + basepoints0 = CalculatePctN(int32(damage), 50); + triggered_spell_id = 69384; + break; + } } break; } @@ -8792,25 +8764,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg break; } - // Sword Specialization - if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_GENERIC && auraSpellInfo->SpellIconID == 1462 && procSpell) - { - if (Player* plr = ToPlayer()) - { - if (cooldown && plr->HasSpellCooldown(16459)) - return false; - - // this required for attacks like Mortal Strike - plr->RemoveSpellCooldown(procSpell->Id); - - CastSpell(victim, procSpell->Id, true); - - if (cooldown) - plr->AddSpellCooldown(16459, 0, time(NULL) + cooldown); - return true; - } - } - // Blade Barrier if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && auraSpellInfo->SpellIconID == 85) { @@ -9278,7 +9231,7 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const if (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP && target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP) return REP_HOSTILE; - + if (selfPlayerOwner) { if (FactionTemplateEntry const* targetFactionTemplateEntry = target->getFactionTemplateEntry()) @@ -9360,234 +9313,12 @@ ReputationRank Unit::GetFactionReactionTo(FactionTemplateEntry const* factionTem bool Unit::IsHostileTo(Unit const* unit) const { - if (!unit) - return false; - // always non-hostile to self - if (unit == this) - return false; - - // always non-hostile to GM in GM mode - if (unit->GetTypeId() == TYPEID_PLAYER && ((Player const*)unit)->isGameMaster()) - return false; - - // always hostile to enemy - if (getVictim() == unit || unit->getVictim() == this) - return true; - - // test pet/charm masters instead pers/charmeds - Unit const* testerOwner = GetCharmerOrOwner(); - Unit const* targetOwner = unit->GetCharmerOrOwner(); - - // always hostile to owner's enemy - if (testerOwner && (testerOwner->getVictim() == unit || unit->getVictim() == testerOwner)) - return true; - - // always hostile to enemy owner - if (targetOwner && (getVictim() == targetOwner || targetOwner->getVictim() == this)) - return true; - - // always hostile to owner of owner's enemy - if (testerOwner && targetOwner && (testerOwner->getVictim() == targetOwner || targetOwner->getVictim() == testerOwner)) - return true; - - Unit const* tester = testerOwner ? testerOwner : this; - Unit const* target = targetOwner ? targetOwner : unit; - - // always non-hostile to target with common owner, or to owner/pet - if (tester == target) - return false; - - // special cases (Duel, etc) - if (tester->GetTypeId() == TYPEID_PLAYER && target->GetTypeId() == TYPEID_PLAYER) - { - Player const* pTester = (Player const*)tester; - Player const* pTarget = (Player const*)target; - - // Duel - if (pTester->duel && pTester->duel->opponent == pTarget && pTester->duel->startTime != 0) - return true; - - // Group - if (pTester->GetGroup() && pTester->GetGroup() == pTarget->GetGroup()) - return false; - - // Sanctuary - if (pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY)) - return false; - - // PvP FFA state - if (pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) - return true; - - // = PvP states - // Green/Blue (can't attack) - if (!pTester->HasAuraType(SPELL_AURA_MOD_FACTION) && !pTarget->HasAuraType(SPELL_AURA_MOD_FACTION)) - { - if (pTester->GetTeam() == pTarget->GetTeam()) - return false; - - // Red (can attack) if true, Blue/Yellow (can't attack) in another case - return pTester->IsPvP() && pTarget->IsPvP(); - } - } - - // faction base cases - FactionTemplateEntry const*tester_faction = tester->getFactionTemplateEntry(); - FactionTemplateEntry const*target_faction = target->getFactionTemplateEntry(); - if (!tester_faction || !target_faction) - return false; - - if (target->isAttackingPlayer() && tester->IsContestedGuard()) - return true; - - // PvC forced reaction and reputation case - if (tester->GetTypeId() == TYPEID_PLAYER && !tester->HasAuraType(SPELL_AURA_MOD_FACTION)) - { - // forced reaction - if (target_faction->faction) - { - if (ReputationRank const* force = tester->ToPlayer()->GetReputationMgr().GetForcedRankIfAny(target_faction)) - return *force <= REP_HOSTILE; - - // if faction have reputation then hostile state for tester at 100% dependent from at_war state - if (FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction)) - if (FactionState const* factionState = tester->ToPlayer()->GetReputationMgr().GetState(raw_target_faction)) - return (factionState->Flags & FACTION_FLAG_AT_WAR); - } - } - // CvP forced reaction and reputation case - else if (target->GetTypeId() == TYPEID_PLAYER && !target->HasAuraType(SPELL_AURA_MOD_FACTION)) - { - // forced reaction - if (tester_faction->faction) - { - if (ReputationRank const* force = target->ToPlayer()->GetReputationMgr().GetForcedRankIfAny(tester_faction)) - return *force <= REP_HOSTILE; - - // apply reputation state - FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction); - if (raw_tester_faction && raw_tester_faction->reputationListID >= 0) - return ((Player const*)target)->GetReputationMgr().GetRank(raw_tester_faction) <= REP_HOSTILE; - } - } - - // common faction based case (CvC, PvC, CvP) - return tester_faction->IsHostileTo(*target_faction); + return GetReactionTo(unit) <= REP_HOSTILE; } bool Unit::IsFriendlyTo(Unit const* unit) const { - // always friendly to self - if (unit == this) - return true; - - // always friendly to GM in GM mode - if (unit->GetTypeId() == TYPEID_PLAYER && ((Player const*)unit)->isGameMaster()) - return true; - - // always non-friendly to enemy - if (getVictim() == unit || unit->getVictim() == this) - return false; - - // test pet/charm masters instead pers/charmeds - Unit const* testerOwner = GetCharmerOrOwner(); - Unit const* targetOwner = unit->GetCharmerOrOwner(); - - // always non-friendly to owner's enemy - if (testerOwner && (testerOwner->getVictim() == unit || unit->getVictim() == testerOwner)) - return false; - - // always non-friendly to enemy owner - if (targetOwner && (getVictim() == targetOwner || targetOwner->getVictim() == this)) - return false; - - // always non-friendly to owner of owner's enemy - if (testerOwner && targetOwner && (testerOwner->getVictim() == targetOwner || targetOwner->getVictim() == testerOwner)) - return false; - - Unit const* tester = testerOwner ? testerOwner : this; - Unit const* target = targetOwner ? targetOwner : unit; - - // always friendly to target with common owner, or to owner/pet - if (tester == target) - return true; - - // special cases (Duel) - if (tester->GetTypeId() == TYPEID_PLAYER && target->GetTypeId() == TYPEID_PLAYER) - { - Player const* pTester = (Player const*)tester; - Player const* pTarget = (Player const*)target; - - // Duel - if (pTester->duel && pTester->duel->opponent == target && pTester->duel->startTime != 0) - return false; - - // Group - if (pTester->GetGroup() && pTester->GetGroup() == pTarget->GetGroup()) - return true; - - // Sanctuary - if (pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY)) - return true; - - // PvP FFA state - if (pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP) && pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) - return false; - - // = PvP states - // Green/Blue (non-attackable) - if (!pTester->HasAuraType(SPELL_AURA_MOD_FACTION) && !pTarget->HasAuraType(SPELL_AURA_MOD_FACTION)) - { - if (pTester->GetTeam() == pTarget->GetTeam()) - return true; - - // Blue (friendly/non-attackable) if not PVP, or Yellow/Red in another case (attackable) - return !pTarget->IsPvP(); - } - } - - // faction base cases - FactionTemplateEntry const* tester_faction = tester->getFactionTemplateEntry(); - FactionTemplateEntry const* target_faction = target->getFactionTemplateEntry(); - if (!tester_faction || !target_faction) - return false; - - if (target->isAttackingPlayer() && tester->IsContestedGuard()) - return false; - - // PvC forced reaction and reputation case - if (tester->GetTypeId() == TYPEID_PLAYER && !tester->HasAuraType(SPELL_AURA_MOD_FACTION)) - { - // forced reaction - if (target_faction->faction) - { - if (ReputationRank const* force = tester->ToPlayer()->GetReputationMgr().GetForcedRankIfAny(target_faction)) - return *force >= REP_FRIENDLY; - - // if faction have reputation then friendly state for tester at 100% dependent from at_war state - if (FactionEntry const* raw_target_faction = sFactionStore.LookupEntry(target_faction->faction)) - if (FactionState const* factionState = tester->ToPlayer()->GetReputationMgr().GetState(raw_target_faction)) - return !(factionState->Flags & FACTION_FLAG_AT_WAR); - } - } - // CvP forced reaction and reputation case - else if (target->GetTypeId() == TYPEID_PLAYER && !target->HasAuraType(SPELL_AURA_MOD_FACTION)) - { - // forced reaction - if (tester_faction->faction) - { - if (ReputationRank const* force = target->ToPlayer()->GetReputationMgr().GetForcedRankIfAny(tester_faction)) - return *force >= REP_FRIENDLY; - - // apply reputation state - if (FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction)) - if (raw_tester_faction->reputationListID >= 0) - return ((Player const*)target)->GetReputationMgr().GetRank(raw_tester_faction) >= REP_FRIENDLY; - } - } - - // common faction based case (CvC, PvC, CvP) - return tester_faction->IsFriendlyTo(*target_faction); + return GetReactionTo(unit) >= REP_FRIENDLY; } bool Unit::IsHostileToPlayers() const @@ -11158,6 +10889,13 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas // Custom crit by class switch (spellProto->SpellFamilyName) { + case SPELLFAMILY_MAGE: + // Glyph of Fire Blast + if (spellProto->SpellFamilyFlags[0] == 0x2 && spellProto->SpellIconID == 12) + if (victim->HasAuraWithMechanic((1<<MECHANIC_STUN) | (1<<MECHANIC_KNOCKOUT))) + if (AuraEffect const* aurEff = GetAuraEffect(56369, EFFECT_0)) + crit_chance += aurEff->GetAmount(); + break; case SPELLFAMILY_DRUID: // Improved Faerie Fire if (victim->HasAuraState(AURA_STATE_FAERIE_FIRE)) @@ -12390,8 +12128,8 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co if (IsOnVehicle(target) || m_vehicle->GetBase()->IsOnVehicle(target)) return false; - // can't attack invisible - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !canSeeOrDetect(target)) + // can't attack invisible (ignore stealth for aoe spells) + if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !canSeeOrDetect(target, bySpell && bySpell->IsAOE())) return false; // can't attack dead @@ -12454,7 +12192,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co && target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP) return true; - return (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_UNK1) + return (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_UNK1) || (target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_UNK1); } return true; @@ -12485,7 +12223,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co return false; // can't assist invisible - if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !canSeeOrDetect(target)) + if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !canSeeOrDetect(target, bySpell && bySpell->IsAOE())) return false; // can't assist dead @@ -13517,7 +13255,7 @@ void Unit::ApplyDiminishingAura(DiminishingGroup group, bool apply) } } -float Unit::GetSpellMaxRangeForTarget(Unit* target, SpellInfo const* spellInfo) +float Unit::GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const { if (!spellInfo->RangeEntry) return 0; @@ -13526,7 +13264,7 @@ float Unit::GetSpellMaxRangeForTarget(Unit* target, SpellInfo const* spellInfo) return spellInfo->GetMaxRange(!IsHostileTo(target)); } -float Unit::GetSpellMinRangeForTarget(Unit* target, SpellInfo const* spellInfo) +float Unit::GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const { if (!spellInfo->RangeEntry) return 0; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index c54a627fa27..8f68cd3e9e6 100755 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1255,8 +1255,8 @@ class Unit : public WorldObject void ClearDiminishings() { m_Diminishing.clear(); } // target dependent range checks - float GetSpellMaxRangeForTarget(Unit* target, SpellInfo const* spellInfo); - float GetSpellMinRangeForTarget(Unit* target, SpellInfo const* spellInfo); + float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const; + float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const; virtual void Update(uint32 time); @@ -1455,6 +1455,7 @@ class Unit : public WorldObject void CalculateMeleeDamage(Unit* pVictim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK); void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss); + void HandleProcExtraAttackFor(Unit* victim); void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false); void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss); @@ -1569,10 +1570,12 @@ class Unit : public WorldObject void SendEnergizeSpellLog(Unit* pVictim, uint32 SpellID, uint32 Damage, Powers powertype); void EnergizeBySpell(Unit* pVictim, uint32 SpellID, uint32 Damage, Powers powertype); uint32 SpellNonMeleeDamageLog(Unit* pVictim, uint32 spellID, uint32 damage); + + void CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); - void CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); + void CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* Victim = NULL, bool triggered = true, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c076450e98d..c81eb8b61b0 100755 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2593,6 +2593,12 @@ BattlegroundMap::BattlegroundMap(uint32 id, time_t expiry, uint32 InstanceId, Ma BattlegroundMap::~BattlegroundMap() { + if(m_bg) + { + //unlink to prevent crash, always unlink all pointer reference before destruction + m_bg->SetBgMap(NULL); + m_bg = NULL; + } } void BattlegroundMap::InitVisibilityDistance() diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index f3857c07cee..9d015a5284d 100755 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -803,7 +803,7 @@ enum SpellEffects SPELL_EFFECT_PULL_TOWARDS_DEST = 145, SPELL_EFFECT_ACTIVATE_RUNE = 146, SPELL_EFFECT_QUEST_FAIL = 147, - SPELL_EFFECT_148 = 148, + SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE = 148, SPELL_EFFECT_CHARGE_DEST = 149, SPELL_EFFECT_QUEST_START = 150, SPELL_EFFECT_TRIGGER_SPELL_2 = 151, diff --git a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp index 69c1cc5edfe..1810016d22e 100755 --- a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp @@ -339,7 +339,7 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recv_data) BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId); if (!bl) { - sLog->outError("Battleground: invalid bgtype received."); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "BattlegroundHandler: invalid bgtype (%u) with player (Name: %s, GUID: %u) received.", bgTypeId, _player->GetName(), _player->GetGUIDLow()); return; } @@ -362,12 +362,13 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recv_data) if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { - sLog->outError("BattlegroundHandler: invalid bgtype (%u) with player (Name: %s, GUID: %u) received.", bgTypeId_, _player->GetName(), _player->GetGUIDLow()); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "BattlegroundHandler: invalid bgtype (%u) with player (Name: %s, GUID: %u) received.", bgTypeId_, _player->GetName(), _player->GetGUIDLow()); return; } + if (!_player->InBattlegroundQueue()) { - sLog->outError("BattlegroundHandler: Invalid CMSG_BATTLEFIELD_PORT received from player (%u), he is not in bg_queue.", _player->GetGUIDLow()); + sLog->outDebug(LOG_FILTER_BATTLEGROUND, "BattlegroundHandler: Invalid CMSG_BATTLEFIELD_PORT received from player (Name: %s, GUID: %u), he is not in bg_queue.", _player->GetName(), _player->GetGUIDLow()); return; } diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp index f8752d9b167..125fba6db91 100755 --- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp @@ -339,6 +339,12 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) if ((matchcount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO)) continue; + if (itr->second->isGameMaster()) + { + pname = "<GM>"; + pname.append(itr->second->GetName()); + } + data << pname; // player name data << gname; // guild name data << uint32(lvl); // player level diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index e8de9c4c773..ccd7b8da79f 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -742,11 +742,6 @@ int32 AuraEffect::CalculateAmount(Unit* caster) if (GetId() == 55233) amount = GetBase()->GetUnitOwner()->CountPctFromMaxHealth(amount); break; - case SPELL_AURA_MOD_INCREASE_ENERGY: - // Hymn of Hope - if (GetId() == 64904) - ApplyPctU(amount, GetBase()->GetUnitOwner()->GetMaxPower(GetBase()->GetUnitOwner()->getPowerType())); - break; case SPELL_AURA_MOD_INCREASE_SPEED: // Dash - do not set speed if not in cat form if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellInfo()->SpellFamilyFlags[2] & 0x00000008) @@ -3989,19 +3984,6 @@ void AuraEffect::HandleAuraModIncreaseEnergy(AuraApplication const* aurApp, uint UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType); - // Special case with temporary increase max/current power (percent) - if (GetId() == 64904) // Hymn of Hope - { - if (mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK) - { - int32 change = target->GetPower(powerType) + (apply ? GetAmount() : -GetAmount()); - if (change < 0) - change = 0; - target->SetPower(powerType, change); - } - } - - // generic flat case target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply); } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index c5392a0e55b..6b874a6907f 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -483,7 +483,6 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme m_delayAtDamageCount = 0; m_applyMultiplierMask = 0; - m_effectMask = 0; m_auraScaleMask = 0; // Get data for type of attack @@ -656,7 +655,7 @@ void Spell::InitExplicitTargets(SpellCastTargets const& targets) else if ((m_caster->GetTypeId() == TYPEID_UNIT) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT)) target = m_caster->getVictim(); // didn't find anything - let's use self as target - if (!target && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT)) + if (!target && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY)) target = m_caster; m_targets.SetUnitTarget(target); @@ -709,121 +708,21 @@ void Spell::SelectSpellTargets() if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM)) m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT); - uint32 effectTargetType = m_spellInfo->Effects[i].GetRequiredTargetType(); - - // is it possible that areaaura is not applied to caster? - if (effectTargetType == SPELL_REQUIRE_NONE) - continue; - uint32 targetA = m_spellInfo->Effects[i].TargetA.GetTarget(); uint32 targetB = m_spellInfo->Effects[i].TargetB.GetTarget(); if (targetA) processedTargets |= SelectEffectTargets(i, m_spellInfo->Effects[i].TargetA); - if (targetB) // In very rare case !A && B + if (targetB) processedTargets |= SelectEffectTargets(i, m_spellInfo->Effects[i].TargetB); - if (effectTargetType != SPELL_REQUIRE_UNIT) - { - if (effectTargetType == SPELL_REQUIRE_CASTER) - AddUnitTarget(m_caster, 1 << i, false); - else if (effectTargetType == SPELL_REQUIRE_ITEM) - if (m_targets.GetItemTarget()) - AddItemTarget(m_targets.GetItemTarget(), 1 << i); - continue; - } - - if (!targetA && !targetB) - { - if (!m_spellInfo->GetMaxRange(true)) - { - AddUnitTarget(m_caster, 1 << i, false); - continue; - } + // Select targets of effect based on effect type + // those are used when no valid target could be added for spell effect based on spell target type + // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL) + // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON) + // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS) + SelectEffectTypeImplicitTargets(i); - // add here custom effects that need default target. - // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!! - switch (m_spellInfo->Effects[i].Effect) - { - case SPELL_EFFECT_DUMMY: - { - if (m_targets.GetUnitTarget()) - AddUnitTarget(m_targets.GetUnitTarget(), 1 << i, false); - else - AddUnitTarget(m_caster, 1 << i, false); - break; - } - case SPELL_EFFECT_BIND: - case SPELL_EFFECT_RESURRECT: - case SPELL_EFFECT_CREATE_ITEM: - case SPELL_EFFECT_TRIGGER_SPELL: - case SPELL_EFFECT_SKILL_STEP: - case SPELL_EFFECT_PROFICIENCY: - case SPELL_EFFECT_SUMMON_OBJECT_WILD: - case SPELL_EFFECT_SELF_RESURRECT: - case SPELL_EFFECT_REPUTATION: - case SPELL_EFFECT_LEARN_SPELL: - case SPELL_EFFECT_SEND_TAXI: - if (m_targets.GetUnitTarget()) - AddUnitTarget(m_targets.GetUnitTarget(), 1 << i, false); - // Triggered spells have additional spell targets - cast them even if no explicit unit target is given (required for spell 50516 for example) - else if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_TRIGGER_SPELL) - AddUnitTarget(m_caster, 1 << i, false); - break; - case SPELL_EFFECT_SUMMON_RAF_FRIEND: - case SPELL_EFFECT_SUMMON_PLAYER: - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection()) - { - Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); - if (target) - AddUnitTarget(target, 1 << i, false); - } - break; - case SPELL_EFFECT_SKIN_PLAYER_CORPSE: - case SPELL_EFFECT_RESURRECT_NEW: - if (WorldObject* target = m_targets.GetObjectTarget()) - { - if (Unit* unitTarget = target->ToUnit()) - AddUnitTarget(unitTarget, 1 << i, false); - else if (Corpse* corpseTarget = target->ToCorpse()) - { - Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()); - if (owner) - AddUnitTarget(owner, 1 << i, false); - } - } - break; - case SPELL_EFFECT_SUMMON_CHANGE_ITEM: - case SPELL_EFFECT_ADD_FARSIGHT: - case SPELL_EFFECT_APPLY_GLYPH: - case SPELL_EFFECT_STUCK: - case SPELL_EFFECT_FEED_PET: - case SPELL_EFFECT_DESTROY_ALL_TOTEMS: - case SPELL_EFFECT_KILL_CREDIT2: // only one spell: 42793 - AddUnitTarget(m_caster, 1 << i, false); - break; - case SPELL_EFFECT_LEARN_PET_SPELL: - if (Guardian* pet = m_caster->GetGuardianPet()) - AddUnitTarget(pet, 1 << i); - break; - case SPELL_EFFECT_APPLY_AURA: - switch (m_spellInfo->Effects[i].ApplyAuraName) - { - case SPELL_AURA_ADD_FLAT_MODIFIER: // some spell mods auras have 0 target modes instead expected TARGET_UNIT_CASTER(1) (and present for other ranks for same spell for example) - case SPELL_AURA_ADD_PCT_MODIFIER: - AddUnitTarget(m_caster, 1 << i, false); - break; - default: // apply to target in other case - if (m_targets.GetUnitTarget()) - AddUnitTarget(m_targets.GetUnitTarget(), 1 << i, false); - break; - } - break; - default: - AddUnitTarget(m_caster, 1 << i, false); - break; - } - } if (m_spellInfo->IsChanneled()) { uint8 mask = (1 << i); @@ -877,6 +776,76 @@ void Spell::SelectSpellTargets() } } +void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) +{ + // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER + // TODO: this is a workaround - target shouldn't be stored in target map for those spells + switch (m_spellInfo->Effects[effIndex].Effect) + { + case SPELL_EFFECT_SUMMON_RAF_FRIEND: + case SPELL_EFFECT_SUMMON_PLAYER: + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection()) + { + Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); + if (target) + AddUnitTarget(target, 1 << effIndex, false); + } + return; + default: + break; + } + + // select spell implicit targets based on effect type + if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType()) + return; + + uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask(); + + if (!targetMask) + return; + + switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType()) + { + // add explicit object target or self to the target map + case EFFECT_IMPLICIT_TARGET_EXPLICIT: + // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK + if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)) + { + if (Unit* unitTarget = m_targets.GetUnitTarget()) + AddUnitTarget(unitTarget, 1 << effIndex, false); + else if (targetMask & TARGET_FLAG_CORPSE_MASK) + { + if (Corpse* corpseTarget = m_targets.GetCorpseTarget()) + { + // TODO: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead + if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID())) + AddUnitTarget(owner, 1 << effIndex, false); + } + } + else //if (targetMask & TARGET_FLAG_UNIT_MASK) + { + AddUnitTarget(m_caster, 1 << effIndex, false); + } + } + if (targetMask & TARGET_FLAG_ITEM_MASK) + { + if (Item* itemTarget = m_targets.GetItemTarget()) + AddItemTarget(itemTarget, 1 << effIndex); + } + if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK) + { + if (GameObject* gObjTarget = m_targets.GetGOTarget()) + AddGOTarget(gObjTarget, 1 << effIndex); + } + break; + // add self to the target map + case EFFECT_IMPLICIT_TARGET_CASTER: + if (targetMask & TARGET_FLAG_UNIT_MASK) + AddUnitTarget(m_caster, 1 << effIndex, false); + break; + } +} + void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) { //========================================================================================== @@ -1196,7 +1165,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // can't use default call because of threading, do stuff as fast as possible for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (farMask & (1 << i)) - HandleEffects(unit, NULL, NULL, i); + HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_HIT_TARGET); return; } @@ -1593,7 +1562,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, const uint32 effectMask, bool for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) if (effectMask & (1 << effectNumber)) - HandleEffects(unit, NULL, NULL, effectNumber); + HandleEffects(unit, NULL, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); return SPELL_MISS_NONE; } @@ -1685,7 +1654,7 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo* target) for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) if (effectMask & (1 << effectNumber)) - HandleEffects(NULL, NULL, go, effectNumber); + HandleEffects(NULL, NULL, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); CallScriptOnHitHandlers(); @@ -1708,7 +1677,7 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo* target) for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) if (effectMask & (1 << effectNumber)) - HandleEffects(NULL, target->item, NULL, effectNumber); + HandleEffects(NULL, target->item, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); CallScriptOnHitHandlers(); @@ -2505,10 +2474,6 @@ uint32 Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur) } else if (pushType) { - // Dummy, just for client - if (m_spellInfo->Effects[i].GetRequiredTargetType() != SPELL_REQUIRE_UNIT) - return 0; - float radius; SpellTargets targetType; switch (cur.GetTarget()) @@ -3015,7 +2980,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered { m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST); for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_spellInfo->Effects[i].GetRequiredTargetType() == SPELL_REQUIRE_UNIT) + if (m_spellInfo->Effects[i].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT) { m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_SPELL_ATTACK); break; @@ -3221,29 +3186,12 @@ void Spell::cast(bool skipCheck) TakeReagents(); } - if (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE) - CalculateDamageDoneForAllTargets(); - // CAST SPELL SendSpellCooldown(); PrepareScriptHitHandlers(); - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - switch (m_spellInfo->Effects[i].Effect) - { - case SPELL_EFFECT_CHARGE: - case SPELL_EFFECT_CHARGE_DEST: - case SPELL_EFFECT_JUMP: - case SPELL_EFFECT_JUMP_DEST: - case SPELL_EFFECT_LEAP_BACK: - case SPELL_EFFECT_ACTIVATE_RUNE: - HandleEffects(NULL, NULL, NULL, i); - m_effectMask |= (1<<i); - break; - } - } + HandleLaunchPhase(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... SendSpellGo(); @@ -3406,67 +3354,40 @@ uint64 Spell::handle_delayed(uint64 t_offset) void Spell::_handle_immediate_phase() { m_spellAura = NULL; + // initialize Diminishing Returns Data + m_diminishLevel = DIMINISHING_LEVEL_1; + m_diminishGroup = DIMINISHING_NONE; + // handle some immediate features of the spell here HandleThreatSpells(); PrepareScriptHitHandlers(); + // handle effects with SPELL_EFFECT_HANDLE_HIT mode for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) { - if (m_spellInfo->Effects[j].Effect == 0) + // don't do anything for empty effect + if (!m_spellInfo->Effects[j].IsEffect()) continue; - // apply Send Event effect to ground in case empty target lists - if (m_spellInfo->Effects[j].Effect == SPELL_EFFECT_SEND_EVENT && !HaveTargetsForEffect(j)) - { - HandleEffects(NULL, NULL, NULL, j); - continue; - } + // call effect handlers to handle destination hit + HandleEffects(NULL, NULL, NULL, j, SPELL_EFFECT_HANDLE_HIT); } - // initialize Diminishing Returns Data - m_diminishLevel = DIMINISHING_LEVEL_1; - m_diminishGroup = DIMINISHING_NONE; - // process items for (std::list<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit) DoAllEffectOnTarget(&(*ihit)); if (!m_originalCaster) return; - uint8 oldEffMask = m_effectMask; - // process ground - for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (m_spellInfo->Effects[j].Effect == 0) - continue; - - if (m_spellInfo->Effects[j].GetRequiredTargetType() == SPELL_REQUIRE_DEST) - { - if (!m_targets.HasDst()) // FIXME: this will ignore dest set in effect - m_targets.SetDst(*m_caster); - HandleEffects(m_originalCaster, NULL, NULL, j); - m_effectMask |= (1<<j); - } - else if (m_spellInfo->Effects[j].GetRequiredTargetType() == SPELL_REQUIRE_NONE) - { - HandleEffects(m_originalCaster, NULL, NULL, j); - m_effectMask |= (1<<j); - } - } - if (oldEffMask != m_effectMask && m_UniqueTargetInfo.empty()) + // Handle procs on cast + // TODO: finish new proc system:P + if (m_UniqueTargetInfo.empty()) { uint32 procAttacker = m_procAttacker; if (!procAttacker) { - bool positive = true; - for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i) - // If at least one effect negative spell is negative hit - if (m_effectMask & (1<<i) && !m_spellInfo->IsPositiveEffect(i)) - { - positive = false; - break; - } + bool positive = m_spellInfo->IsPositive(); switch (m_spellInfo->DmgClass) { case SPELL_DAMAGE_CLASS_MAGIC: @@ -3500,6 +3421,10 @@ void Spell::_handle_finish_phase() if (m_comboPointGain) m_caster->m_movedPlayer->GainSpellComboPoints(m_comboPointGain); } + + if (m_caster->m_extraAttacks && GetSpellInfo()->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) + m_caster->HandleProcExtraAttackFor(m_caster->getVictim()); + // TODO: trigger proc phase finish here } @@ -4605,12 +4530,9 @@ void Spell::HandleThreatSpells() sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size())); } -void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i) +void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode) { - //effect has been handled, skip it - if (m_effectMask & (1<<i)) - return; - + effectHandleMode = mode; unitTarget = pUnitTarget; itemTarget = pItemTarget; gameObjTarget = pGOTarget; @@ -4619,10 +4541,10 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell: %u Effect : %u", m_spellInfo->Id, eff); - //we do not need DamageMultiplier here. + // we do not need DamageMultiplier here. damage = CalculateDamage(i, NULL); - bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i); + bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode); if (!preventDefault && eff < TOTAL_SPELL_EFFECTS) { @@ -4978,21 +4900,24 @@ SpellCastResult Spell::CheckCast(bool strict) } case SPELL_EFFECT_LEARN_PET_SPELL: { - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return SPELL_FAILED_BAD_TARGETS; - - Pet* pet = m_caster->ToPlayer()->GetPet(); - if (!pet) - return SPELL_FAILED_NO_PET; + // check target only for unit target case + if (Unit* unitTarget = m_targets.GetUnitTarget()) + { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_BAD_TARGETS; - SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell); + Pet* pet = unitTarget->ToPet(); + if (!pet || pet->GetOwner() != m_caster) + return SPELL_FAILED_BAD_TARGETS; - if (!learn_spellproto) - return SPELL_FAILED_NOT_KNOWN; + SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell); - if (m_spellInfo->SpellLevel > pet->getLevel()) - return SPELL_FAILED_LOWLEVEL; + if (!learn_spellproto) + return SPELL_FAILED_NOT_KNOWN; + if (m_spellInfo->SpellLevel > pet->getLevel()) + return SPELL_FAILED_LOWLEVEL; + } break; } case SPELL_EFFECT_APPLY_GLYPH: @@ -5703,16 +5628,7 @@ SpellCastResult Spell::CheckRange(bool strict) if (!strict && m_casttime == 0) return SPELL_CAST_OK; - uint32 range_type = 0; - - if (m_spellInfo->RangeEntry) - { - // self cast doesn't need range checking -- also for Starshards fix - if (m_spellInfo->RangeEntry->ID == 1) - return SPELL_CAST_OK; - - range_type = m_spellInfo->RangeEntry->type; - } + uint32 range_type = m_spellInfo->RangeEntry ? m_spellInfo->RangeEntry->type : 0; Unit* target = m_targets.GetUnitTarget(); float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo); @@ -6638,14 +6554,24 @@ bool Spell::IsValidDeadOrAliveTarget(Unit const* target) const return false; } -void Spell::CalculateDamageDoneForAllTargets() +void Spell::HandleLaunchPhase() { + // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + // don't do anything for empty effect + if (!m_spellInfo->Effects[i].IsEffect()) + continue; + + HandleEffects(NULL, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH); + } + float multiplier[MAX_SPELL_EFFECTS]; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_applyMultiplierMask & (1 << i)) multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this); - bool usesAmmo = true; + bool usesAmmo = m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE; Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO); for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j) { @@ -6655,16 +6581,12 @@ void Spell::CalculateDamageDoneForAllTargets() for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { - TargetInfo &target = *ihit; + TargetInfo& target = *ihit; uint32 mask = target.effectMask; if (!mask) continue; - Unit* unit = m_caster->GetGUID() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID); - if (!unit) // || !unit->isAlive()) do we need to check alive here? - continue; - // do not consume ammo anymore for Hunter's volley spell if (IsTriggered() && m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->IsAOE()) usesAmmo = false; @@ -6690,49 +6612,30 @@ void Spell::CalculateDamageDoneForAllTargets() break; } } - - if (target.missCondition == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target - { - target.damage += CalculateDamageDone(unit, mask, multiplier); - target.crit = m_caster->isSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType); - } - else if (target.missCondition == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit) - { - if (target.reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him - { - target.damage += CalculateDamageDone(m_caster, mask, multiplier); - target.crit = m_caster->isSpellCrit(m_caster, m_spellInfo, m_spellSchoolMask, m_attackType); - } - } + DoAllEffectOnLaunchTarget(target, multiplier); } } -int32 Spell::CalculateDamageDone(Unit* unit, const uint32 effectMask, float * multiplier) +void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) { - int32 damageDone = 0; - unitTarget = unit; + Unit* unit = NULL; + // In case spell hit target, do all effect on that target + if (targetInfo.missCondition == SPELL_MISS_NONE) + unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID); + // In case spell reflect from target, do all effect on caster (if hit) + else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE) + unit = m_caster; + if (!unit) + return; + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (effectMask & (1<<i)) + if (targetInfo.effectMask & (1<<i)) { m_damage = 0; - damage = CalculateDamage(i, NULL); + m_healing = 0; - switch (m_spellInfo->Effects[i].Effect) - { - case SPELL_EFFECT_SCHOOL_DAMAGE: - SpellDamageSchoolDmg((SpellEffIndex)i); - break; - case SPELL_EFFECT_WEAPON_DAMAGE: - case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: - case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: - case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: - SpellDamageWeaponDmg((SpellEffIndex)i); - break; - case SPELL_EFFECT_HEAL: - SpellDamageHeal((SpellEffIndex)i); - break; - } + HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET); if (m_damage > 0) { @@ -6756,12 +6659,11 @@ int32 Spell::CalculateDamageDone(Unit* unit, const uint32 effectMask, float * mu m_damage = int32(m_damage * m_damageMultipliers[i]); m_damageMultipliers[i] *= multiplier[i]; } - - damageDone += m_damage; + targetInfo.damage += m_damage; } } - return damageDone; + targetInfo.crit = m_caster->isSpellCrit(unit, m_spellInfo, m_spellSchoolMask, m_attackType); } SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& skillId, int32& reqSkillValue, int32& skillValue) @@ -7071,14 +6973,41 @@ SpellCastResult Spell::CallScriptCheckCastHandlers() return retVal; } -bool Spell::CallScriptEffectHandlers(SpellEffIndex effIndex) +bool Spell::CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode) { // execute script effect handler hooks and check if effects was prevented bool preventDefault = false; for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr) { - (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_EFFECT); - std::list<SpellScript::EffectHandler>::iterator effEndItr = (*scritr)->OnEffect.end(), effItr = (*scritr)->OnEffect.begin(); + std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr; + SpellScriptHookType hookType; + switch (mode) + { + case SPELL_EFFECT_HANDLE_LAUNCH: + effItr = (*scritr)->OnEffectLaunch.begin(); + effEndItr = (*scritr)->OnEffectLaunch.end(); + hookType = SPELL_SCRIPT_HOOK_EFFECT_LAUNCH; + break; + case SPELL_EFFECT_HANDLE_LAUNCH_TARGET: + effItr = (*scritr)->OnEffectLaunchTarget.begin(); + effEndItr = (*scritr)->OnEffectLaunchTarget.end(); + hookType = SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET; + break; + case SPELL_EFFECT_HANDLE_HIT: + effItr = (*scritr)->OnEffectHit.begin(); + effEndItr = (*scritr)->OnEffectHit.end(); + hookType = SPELL_SCRIPT_HOOK_EFFECT_HIT; + break; + case SPELL_EFFECT_HANDLE_HIT_TARGET: + effItr = (*scritr)->OnEffectHitTarget.begin(); + effEndItr = (*scritr)->OnEffectHitTarget.end(); + hookType = SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET; + break; + default: + ASSERT(false); + break; + } + (*scritr)->_PrepareScriptCall(hookType); for (; effItr != effEndItr ; ++effItr) // effect execution can be prevented if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex)) diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index be6e16b30d2..6070df7e0aa 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -202,6 +202,14 @@ enum SpellState SPELL_STATE_DELAYED = 5 }; +enum SpellEffectHandleMode +{ + SPELL_EFFECT_HANDLE_LAUNCH, + SPELL_EFFECT_HANDLE_LAUNCH_TARGET, + SPELL_EFFECT_HANDLE_HIT, + SPELL_EFFECT_HANDLE_HIT_TARGET, +}; + enum SpellTargets { SPELL_TARGETS_NONE = 0, @@ -274,7 +282,6 @@ class Spell void EffectLearnPetSpell(SpellEffIndex effIndex); void EffectWeaponDmg(SpellEffIndex effIndex); void EffectForceCast(SpellEffIndex effIndex); - void EffectForceCastWithValue(SpellEffIndex effIndex); void EffectTriggerSpell(SpellEffIndex effIndex); void EffectTriggerMissileSpell(SpellEffIndex effIndex); void EffectThreat(SpellEffIndex effIndex); @@ -329,7 +336,6 @@ class Spell void EffectUnlearnSpecialization(SpellEffIndex effIndex); void EffectHealPct(SpellEffIndex effIndex); void EffectEnergizePct(SpellEffIndex effIndex); - void EffectTriggerSpellWithValue(SpellEffIndex effIndex); void EffectTriggerRitualOfSummoning(SpellEffIndex effIndex); void EffectSummonRaFFriend(SpellEffIndex effIndex); void EffectKillCreditPersonal(SpellEffIndex effIndex); @@ -400,6 +406,7 @@ class Spell void InitExplicitTargets(SpellCastTargets const& targets); void SelectSpellTargets(); + void SelectEffectTypeImplicitTargets(uint8 effIndex); uint32 SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur); void SelectTrajTargets(); @@ -431,7 +438,7 @@ class Spell void SendChannelStart(uint32 duration); void SendResurrectRequest(Player* target); - void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i); + void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode); void HandleThreatSpells(); SpellInfo const* const m_spellInfo; @@ -530,6 +537,7 @@ class Spell Item* itemTarget; GameObject* gameObjTarget; int32 damage; + SpellEffectHandleMode effectHandleMode; // used in effects handlers Aura* m_spellAura; @@ -603,11 +611,8 @@ class Spell void SearchChainTarget(std::list<Unit*> &unitList, float radius, uint32 unMaxTargets, SpellTargets TargetType); WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType, SpellEffIndex effIndex); bool IsValidDeadOrAliveTarget(Unit const* target) const; - void CalculateDamageDoneForAllTargets(); - int32 CalculateDamageDone(Unit* unit, const uint32 effectMask, float *multiplier); - void SpellDamageSchoolDmg(SpellEffIndex effIndex); - void SpellDamageWeaponDmg(SpellEffIndex effIndex); - void SpellDamageHeal(SpellEffIndex effIndex); + void HandleLaunchPhase(); + void DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier); void PrepareTargetProcessing(); void FinishTargetProcessing(); @@ -621,7 +626,7 @@ class Spell void LoadScripts(); SpellCastResult CallScriptCheckCastHandlers(); void PrepareScriptHitHandlers(); - bool CallScriptEffectHandlers(SpellEffIndex effIndex); + bool CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMode mode); void CallScriptBeforeHitHandlers(); void CallScriptOnHitHandlers(); void CallScriptAfterHitHandlers(); @@ -652,7 +657,6 @@ class Spell SpellInfo const* m_triggeredByAuraSpell; bool m_skipCheck; - uint32 m_effectMask; uint8 m_auraScaleMask; ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index f0e63398b8f..43136555c7a 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -206,14 +206,14 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectLeapBack, //138 SPELL_EFFECT_LEAP_BACK Leap back &Spell::EffectQuestClear, //139 SPELL_EFFECT_CLEAR_QUEST Reset quest status (miscValue - quest ID) &Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST - &Spell::EffectForceCastWithValue, //141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE - &Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE + &Spell::EffectForceCast, //141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE + &Spell::EffectTriggerSpell, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE &Spell::EffectApplyAreaAura, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER &Spell::EffectKnockBack, //144 SPELL_EFFECT_KNOCK_BACK_DEST &Spell::EffectPullTowards, //145 SPELL_EFFECT_PULL_TOWARDS_DEST Black Hole Effect &Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE &Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail - &Spell::EffectUnused, //148 SPELL_EFFECT_148 1 spell - 43509 + &Spell::EffectTriggerMissileSpell, //148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE &Spell::EffectChargeDest, //149 SPELL_EFFECT_CHARGE_DEST &Spell::EffectQuestStart, //150 SPELL_EFFECT_QUEST_START &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2 @@ -244,6 +244,9 @@ void Spell::EffectUnused(SpellEffIndex /*effIndex*/) void Spell::EffectResurrectNew(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->isAlive()) return; @@ -267,6 +270,9 @@ void Spell::EffectResurrectNew(SpellEffIndex effIndex) void Spell::EffectInstaKill(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive()) return; @@ -284,6 +290,9 @@ void Spell::EffectInstaKill(SpellEffIndex /*effIndex*/) void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive()) return; @@ -297,12 +306,11 @@ void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/) unitTarget->ToPlayer()->EnvironmentalDamage(DAMAGE_FIRE, damage); } -void Spell::EffectSchoolDMG(SpellEffIndex /*effIndex*/) +void Spell::EffectSchoolDMG(SpellEffIndex effIndex) { -} + if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + return; -void Spell::SpellDamageSchoolDmg(SpellEffIndex effIndex) -{ bool apply_direct_bonus = true; if (unitTarget && unitTarget->isAlive()) @@ -744,6 +752,9 @@ void Spell::SpellDamageSchoolDmg(SpellEffIndex effIndex) void Spell::EffectDummy(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget && !gameObjTarget && !itemTarget) return; @@ -1540,44 +1551,230 @@ void Spell::EffectDummy(SpellEffIndex effIndex) sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget); } -void Spell::EffectTriggerSpellWithValue(SpellEffIndex effIndex) +void Spell::EffectTriggerSpell(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET + && effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) + return; + uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell; + // todo: move those to spell scripts + if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL + && effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + { + // special cases + switch(triggered_spell_id) + { + // Mirror Image + case 58832: + { + // Glyph of Mirror Image + if (m_caster->HasAura(63093)) + m_caster->CastSpell(m_caster, 65047, true); // Mirror Image + + break; + } + // Vanish (not exist) + case 18461: + { + unitTarget->RemoveMovementImpairingAuras(); + unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STALKED); + + // If this spell is given to an NPC, it must handle the rest using its own AI + if (unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + // See if we already are stealthed. If so, we're done. + if (unitTarget->HasAura(1784)) + return; + + // Reset cooldown on stealth if needed + if (unitTarget->ToPlayer()->HasSpellCooldown(1784)) + unitTarget->ToPlayer()->RemoveSpellCooldown(1784); + + unitTarget->CastSpell(unitTarget, 1784, true); + return; + } + // Demonic Empowerment -- succubus + case 54437: + { + unitTarget->RemoveMovementImpairingAuras(); + unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STALKED); + unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STUN); + + // Cast Lesser Invisibility + unitTarget->CastSpell(unitTarget, 7870, true); + return; + } + // just skip + case 23770: // Sayge's Dark Fortune of * + // not exist, common cooldown can be implemented in scripts if need. + return; + // Brittle Armor - (need add max stack of 24575 Brittle Armor) + case 29284: + { + // Brittle Armor + SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575); + if (!spell) + return; + + for (uint32 j = 0; j < spell->StackAmount; ++j) + m_caster->CastSpell(unitTarget, spell->Id, true); + return; + } + // Mercurial Shield - (need add max stack of 26464 Mercurial Shield) + case 29286: + { + // Mercurial Shield + SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464); + if (!spell) + return; + + for (uint32 j = 0; j < spell->StackAmount; ++j) + m_caster->CastSpell(unitTarget, spell->Id, true); + return; + } + // Righteous Defense + case 31980: + { + m_caster->CastSpell(unitTarget, 31790, true); + return; + } + // Cloak of Shadows + case 35729: + { + uint32 dispelMask = SpellInfo::GetDispelMask(DISPEL_ALL); + Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); + for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();) + { + // remove all harmful spells on you... + SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo(); + if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC // only affect magic spells + || ((spell->GetDispelMask()) & dispelMask)) + // ignore positive and passive auras + && !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive()) + { + m_caster->RemoveAura(iter); + } + else + ++iter; + } + return; + } + // Priest Shadowfiend (34433) need apply mana gain trigger aura on pet + case 41967: + { + if (Unit* pet = unitTarget->GetGuardianPet()) + pet->CastSpell(pet, 28305, true); + return; + } + } + } + // normal case SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (!spellInfo) { - sLog->outError("EffectTriggerSpellWithValue of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id); + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::EffectTriggerSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id); return; } - int32 bp = damage; + SpellCastTargets targets; + if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + { + if (!spellInfo->NeedsToBeTriggeredByCaster()) + return; + targets.SetUnitTarget(unitTarget); + } + else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH) + { + if (spellInfo->NeedsToBeTriggeredByCaster() && !(m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK)) + return; + + if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION) + targets.SetDst(m_targets); - Unit* caster = spellInfo->NeedsToBeTriggeredByCaster() ? m_caster : unitTarget; + targets.SetUnitTarget(m_caster); + } - caster->CastCustomSpell(unitTarget, triggered_spell_id, &bp, &bp, &bp, true); + CustomSpellValues values; + // set basepoints for trigger with value effect + if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE) + { + // maybe need to set value only when basepoints == 0? + values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage); + values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage); + values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage); + } + + // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime + && m_spellInfo->Category == spellInfo->Category) + m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id); + + // original caster guid only for GO cast + m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID); } -void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex) +void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET + && effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id); + // normal case + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id); if (!spellInfo) { - sLog->outError("EffectTriggerRitualOfSummoning of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id); + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::EffectTriggerSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id); return; } - finish(); + SpellCastTargets targets; + if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) + { + if (!spellInfo->NeedsToBeTriggeredByCaster()) + return; + targets.SetUnitTarget(unitTarget); + } + else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT) + { + if (spellInfo->NeedsToBeTriggeredByCaster() && !(m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK)) + return; + + if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION) + targets.SetDst(m_targets); - m_caster->CastSpell(unitTarget, spellInfo, false); + targets.SetUnitTarget(m_caster); + } + + CustomSpellValues values; + // set basepoints for trigger with value effect + if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE) + { + // maybe need to set value only when basepoints == 0? + values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage); + values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage); + values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage); + } + + // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime + && m_spellInfo->Category == spellInfo->Category) + m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id); + + // original caster guid only for GO cast + m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID); } void Spell::EffectForceCast(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -1588,11 +1785,11 @@ void Spell::EffectForceCast(SpellEffIndex effIndex) if (!spellInfo) { - sLog->outError("EffectForceCast of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id); + sLog->outError("Spell::EffectForceCast of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id); return; } - if (damage) + if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage) { switch (m_spellInfo->Id) { @@ -1610,224 +1807,55 @@ void Spell::EffectForceCast(SpellEffIndex effIndex) break; } } - unitTarget->CastSpell(m_caster, spellInfo, true); -} -void Spell::EffectForceCastWithValue(SpellEffIndex effIndex) -{ - if (!unitTarget) - return; - - uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell; - - // normal case - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id); - - if (!spellInfo) + CustomSpellValues values; + // set basepoints for trigger with value effect + if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE) { - sLog->outError("EffectForceCastWithValue of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id); - return; + // maybe need to set value only when basepoints == 0? + values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage); + values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage); + values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage); } - int32 bp = damage; - unitTarget->CastCustomSpell(m_caster, spellInfo->Id, &bp, &bp, &bp, true); + SpellCastTargets targets; + targets.SetUnitTarget(m_caster); + + unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK); } -void Spell::EffectTriggerSpell(SpellEffIndex effIndex) +void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex) { - // only unit case known - if (!unitTarget) - { - if (gameObjTarget || itemTarget) - sLog->outError("Spell::EffectTriggerSpell (Spell: %u): Unsupported non-unit case!", m_spellInfo->Id); + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - } uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell; - Unit* originalCaster = NULL; - - // special cases - switch(triggered_spell_id) - { - // Mirror Image - case 58832: - { - // Glyph of Mirror Image - if (m_caster->HasAura(63093)) - m_caster->CastSpell(m_caster, 65047, true); // Mirror Image - - break; - } - // Vanish (not exist) - case 18461: - { - unitTarget->RemoveMovementImpairingAuras(); - unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STALKED); - - // If this spell is given to an NPC, it must handle the rest using its own AI - if (unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - // See if we already are stealthed. If so, we're done. - if (unitTarget->HasAura(1784)) - return; - - // Reset cooldown on stealth if needed - if (unitTarget->ToPlayer()->HasSpellCooldown(1784)) - unitTarget->ToPlayer()->RemoveSpellCooldown(1784); - - triggered_spell_id = 1784; - break; - } - // Demonic Empowerment -- succubus - case 54437: - { - unitTarget->RemoveMovementImpairingAuras(); - unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STALKED); - unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STUN); - - // Cast Lesser Invisibility - triggered_spell_id = 7870; - break; - } - // just skip - case 23770: // Sayge's Dark Fortune of * - // not exist, common cooldown can be implemented in scripts if need. - return; - // Brittle Armor - (need add max stack of 24575 Brittle Armor) - case 29284: - { - // Brittle Armor - SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575); - if (!spell) - return; - - for (uint32 j = 0; j < spell->StackAmount; ++j) - m_caster->CastSpell(unitTarget, spell->Id, true); - return; - } - // Mercurial Shield - (need add max stack of 26464 Mercurial Shield) - case 29286: - { - // Mercurial Shield - SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464); - if (!spell) - return; - - for (uint32 j = 0; j < spell->StackAmount; ++j) - m_caster->CastSpell(unitTarget, spell->Id, true); - return; - } - // Righteous Defense - case 31980: - { - m_caster->CastSpell(unitTarget, 31790, true); - return; - } - // Cloak of Shadows - case 35729: - { - uint32 dispelMask = SpellInfo::GetDispelMask(DISPEL_ALL); - Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); - for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();) - { - // remove all harmful spells on you... - SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo(); - if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC // only affect magic spells - || ((spell->GetDispelMask()) & dispelMask)) - // ignore positive and passive auras - && !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive()) - { - m_caster->RemoveAura(iter); - } - else - ++iter; - } - return; - } - // Priest Shadowfiend (34433) need apply mana gain trigger aura on pet - case 41967: - { - if (Unit* pet = unitTarget->GetGuardianPet()) - pet->CastSpell(pet, 28305, true); - return; - } - // Empower Rune Weapon - case 53258: - return; // skip, hack-added in spell effect - // Snake Trap - case 57879: - originalCaster = m_originalCaster; - break; - // Coldflame - case 33801: - return; // just make the core stfu - } - - // normal case - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id); - if (!spellInfo) - { - sLog->outError("EffectTriggerSpell of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id); - return; - } - - // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category - // Needed by freezing arrow and few other spells - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime - && m_spellInfo->Category == spellInfo->Category) - m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id); - - // Note: not exist spells with weapon req. and IsSpellHaveCasterSourceTargets == true - // so this just for speedup places in else - Unit* caster = spellInfo->NeedsToBeTriggeredByCaster() ? m_caster : unitTarget; - - caster->CastSpell(unitTarget, spellInfo, true, 0, 0, (originalCaster ? originalCaster->GetGUID() : 0)); -} - -void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex) -{ - uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell; - - // normal case SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id); if (!spellInfo) { - sLog->outError("EffectTriggerMissileSpell of spell %u (eff: %u): triggering unknown spell id %u", - m_spellInfo->Id, effIndex, triggered_spell_id); + sLog->outError("EffectTriggerRitualOfSummoning of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id); return; } - if (m_CastItem) - sLog->outStaticDebug("WORLD: cast Item spellId - %i", spellInfo->Id); - - // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category - // Needed by freezing arrow and few other spells - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime - && m_spellInfo->Category == spellInfo->Category) - m_caster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id); + finish(); - float x, y, z; - m_targets.GetDst()->GetPosition(x, y, z); - m_caster->CastSpell(x, y, z, spellInfo->Id, true, m_CastItem, 0, m_originalCasterGUID); + m_caster->CastSpell((Unit*)NULL, spellInfo, false); } void Spell::EffectJump(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + return; + if (m_caster->isInFlight()) return; - float x, y, z; - if (m_targets.GetUnitTarget()) - m_targets.GetUnitTarget()->GetContactPoint(m_caster, x, y, z, CONTACT_DISTANCE); - else if (m_targets.GetGOTarget()) - m_targets.GetGOTarget()->GetContactPoint(m_caster, x, y, z, CONTACT_DISTANCE); - else - { - sLog->outError("Spell::EffectJump - unsupported target mode for spell ID %u", m_spellInfo->Id); + if (!unitTarget) return; - } + + float x, y, z; + unitTarget->GetContactPoint(m_caster, x, y, z, CONTACT_DISTANCE); float speedXY, speedZ; CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(x, y), speedXY, speedZ); @@ -1836,34 +1864,18 @@ void Spell::EffectJump(SpellEffIndex effIndex) void Spell::EffectJumpDest(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) + return; + if (m_caster->isInFlight()) return; + if (!m_targets.HasDst()) + return; + // Init dest coordinates float x, y, z; - if (m_targets.HasDst()) - { - m_targets.GetDst()->GetPosition(x, y, z); - - if (m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_TARGET_BACK) - { - // explicit cast data from client or server-side cast - // some spell at client send caster - Unit* pTarget = NULL; - if (m_targets.GetUnitTarget() && m_targets.GetUnitTarget() != m_caster) - pTarget = m_targets.GetUnitTarget(); - else if (m_caster->getVictim()) - pTarget = m_caster->getVictim(); - else if (m_caster->GetTypeId() == TYPEID_PLAYER) - pTarget = ObjectAccessor::GetUnit(*m_caster, m_caster->ToPlayer()->GetSelection()); - - } - } - else - { - sLog->outError("Spell::EffectJumpDest - unsupported target mode for spell ID %u", m_spellInfo->Id); - return; - } + m_targets.GetDst()->GetPosition(x, y, z); float speedXY, speedZ; CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(x, y), speedXY, speedZ); @@ -1883,6 +1895,9 @@ void Spell::CalculateJumpSpeeds(uint8 i, float dist, float & speedXY, float & sp void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->isInFlight()) return; @@ -2046,6 +2061,9 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) void Spell::EffectApplyAura(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!m_spellAura || !unitTarget) return; ASSERT(unitTarget == m_spellAura->GetOwner()); @@ -2054,6 +2072,9 @@ void Spell::EffectApplyAura(SpellEffIndex effIndex) void Spell::EffectApplyAreaAura(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!m_spellAura || !unitTarget) return; ASSERT (unitTarget == m_spellAura->GetOwner()); @@ -2062,6 +2083,9 @@ void Spell::EffectApplyAreaAura(SpellEffIndex effIndex) void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -2075,6 +2099,9 @@ void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex) void Spell::EffectPowerDrain(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS)) return; @@ -2109,18 +2136,30 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex) void Spell::EffectSendEvent(SpellEffIndex effIndex) { - /* - we do not handle a flag dropping or clicking on flag in battleground by sendevent system - */ - sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id); + // we do not handle a flag dropping or clicking on flag in battleground by sendevent system + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET + && effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; Object* target = NULL; - if (focusObject) - target = focusObject; - else if (unitTarget) - target = unitTarget; - else if (gameObjTarget) - target = gameObjTarget; + + // call events for target if present + if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) + { + if (unitTarget) + target = unitTarget; + else if (gameObjTarget) + target = gameObjTarget; + } + // call event with no target or focus target when no targets could be found due to no dbc entry + else if (!m_spellInfo->Effects[effIndex].GetProvidedTargetMask()) + { + if (focusObject) + target = focusObject; + // TODO: there should be a possibility to pass dest target to event script + } + + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id); if (ZoneScript* zoneScript = m_caster->GetZoneScript()) zoneScript->ProcessEvent(unitTarget, m_spellInfo->Effects[effIndex].MiscValue); @@ -2130,6 +2169,9 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex) void Spell::EffectPowerBurn(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS)) return; @@ -2166,10 +2208,9 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex) void Spell::EffectHeal(SpellEffIndex /*effIndex*/) { -} + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + return; -void Spell::SpellDamageHeal(SpellEffIndex /*effIndex*/) -{ if (unitTarget && unitTarget->isAlive() && damage >= 0) { // Try to get original caster @@ -2284,6 +2325,9 @@ void Spell::SpellDamageHeal(SpellEffIndex /*effIndex*/) void Spell::EffectHealPct(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive() || damage < 0) return; @@ -2300,6 +2344,9 @@ void Spell::EffectHealPct(SpellEffIndex /*effIndex*/) void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive() || damage < 0) return; @@ -2312,6 +2359,9 @@ void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/) void Spell::EffectHealthLeech(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive() || damage < 0) return; @@ -2337,7 +2387,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - Player* player = (Player*)unitTarget; + Player* player = unitTarget->ToPlayer(); uint32 newitemid = itemtype; ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid); @@ -2445,15 +2495,22 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) void Spell::EffectCreateItem(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType); ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType); } void Spell::EffectCreateItem2(SpellEffIndex effIndex) { - if (m_caster->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - Player* player = (Player*)m_caster; + + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + Player* player = unitTarget->ToPlayer(); uint32 item_id = m_spellInfo->Effects[effIndex].ItemType; @@ -2483,9 +2540,12 @@ void Spell::EffectCreateItem2(SpellEffIndex effIndex) void Spell::EffectCreateRandomItem(SpellEffIndex /*effIndex*/) { - if (m_caster->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - Player* player = (Player*)m_caster; + + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + Player* player = unitTarget->ToPlayer(); // create some random items player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); @@ -2494,6 +2554,9 @@ void Spell::EffectCreateRandomItem(SpellEffIndex /*effIndex*/) void Spell::EffectPersistentAA(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + if (!m_spellAura) { Unit* caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster; @@ -2526,6 +2589,9 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex) void Spell::EffectEnergize(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; if (!unitTarget->isAlive()) @@ -2628,6 +2694,9 @@ void Spell::EffectEnergize(SpellEffIndex effIndex) void Spell::EffectEnergizePct(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; if (!unitTarget->isAlive()) @@ -2717,13 +2786,16 @@ void Spell::SendLoot(uint64 guid, LootType loottype) void Spell::EffectOpenLock(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) { sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "WORLD: Open Lock - No Player Caster!"); return; } - Player* player = (Player*)m_caster; + Player* player = m_caster->ToPlayer(); uint32 lockId = 0; uint64 guid = 0; @@ -2819,10 +2891,13 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - Player* player = (Player*)m_caster; + Player* player = m_caster->ToPlayer(); // applied only to using item if (!m_CastItem) @@ -2918,9 +2993,12 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) void Spell::EffectProficiency(SpellEffIndex /*effIndex*/) { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - Player* p_target = unitTarget->ToPlayer(); + Player* p_target = m_caster->ToPlayer(); uint32 subClassMask = m_spellInfo->EquippedItemSubClassMask; if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask)) @@ -2937,6 +3015,9 @@ void Spell::EffectProficiency(SpellEffIndex /*effIndex*/) void Spell::EffectSummonType(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + uint32 entry = m_spellInfo->Effects[effIndex].MiscValue; if (!entry) return; @@ -3086,18 +3167,20 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) void Spell::EffectLearnSpell(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; if (unitTarget->GetTypeId() != TYPEID_PLAYER) { - if (m_caster->GetTypeId() == TYPEID_PLAYER) + if (unitTarget->ToPet()) EffectLearnPetSpell(effIndex); - return; } - Player* player = (Player*)unitTarget; + Player* player = unitTarget->ToPlayer(); uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell; player->learnSpell(spellToLearn, false); @@ -3109,6 +3192,9 @@ typedef std::list< std::pair<uint32, uint64> > DispelList; typedef std::list< std::pair<Aura* , uint8> > DispelChargesList; void Spell::EffectDispel(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -3247,6 +3333,9 @@ void Spell::EffectDispel(SpellEffIndex effIndex) void Spell::EffectDualWield(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + unitTarget->SetCanDualWield(true); if (unitTarget->GetTypeId() == TYPEID_UNIT) unitTarget->ToCreature()->UpdateDamagePhysical(OFF_ATTACK); @@ -3260,6 +3349,9 @@ void Spell::EffectPull(SpellEffIndex effIndex) void Spell::EffectDistract(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + // Check for possible target if (!unitTarget || unitTarget->isInCombat()) return; @@ -3288,6 +3380,9 @@ void Spell::EffectDistract(SpellEffIndex /*effIndex*/) void Spell::EffectPickPocket(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -3302,6 +3397,9 @@ void Spell::EffectPickPocket(SpellEffIndex /*effIndex*/) void Spell::EffectAddFarsight(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -3327,6 +3425,9 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex) void Spell::EffectUntrainTalents(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || m_caster->GetTypeId() == TYPEID_PLAYER) return; @@ -3336,6 +3437,9 @@ void Spell::EffectUntrainTalents(SpellEffIndex /*effIndex*/) void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -3352,6 +3456,9 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex effIndex) void Spell::EffectLearnSkill(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -3365,6 +3472,9 @@ void Spell::EffectLearnSkill(SpellEffIndex effIndex) void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -3393,15 +3503,21 @@ void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/) void Spell::EffectTradeSkill(SpellEffIndex /*effIndex*/) { - if (unitTarget->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; // uint32 skillid = m_spellInfo->Effects[i].MiscValue; // uint16 skillmax = unitTarget->ToPlayer()->(skillid); - // unitTarget->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75); + // m_caster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75); } void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; if (!itemTarget) @@ -3462,6 +3578,9 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex) void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; if (!itemTarget) @@ -3522,6 +3641,9 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex) void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -3529,7 +3651,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex) // Rockbiter Weapon apply to both weapon if (!itemTarget) - return; + return; if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & 0x400000) { uint32 spell_id = 0; @@ -3650,6 +3772,9 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex) void Spell::EffectTameCreature(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetPetGUID()) return; @@ -3703,6 +3828,9 @@ void Spell::EffectTameCreature(SpellEffIndex /*effIndex*/) void Spell::EffectSummonPet(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + Player* owner = NULL; if (m_originalCaster) { @@ -3782,15 +3910,19 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex) void Spell::EffectLearnPetSpell(SpellEffIndex effIndex) { - if (m_caster->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - Player* _player = m_caster->ToPlayer(); + if (!unitTarget) + return; - Pet* pet = _player->GetPet(); - if (!pet) + if (unitTarget->ToPlayer()) + { + EffectLearnSpell(effIndex); return; - if (!pet->isAlive()) + } + Pet* pet = unitTarget->ToPet(); + if (!pet) return; SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell); @@ -3798,13 +3930,15 @@ void Spell::EffectLearnPetSpell(SpellEffIndex effIndex) return; pet->learnSpell(learn_spellproto->Id); - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - _player->PetSpellInitialize(); + pet->GetOwner()->PetSpellInitialize(); } void Spell::EffectTaunt(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -3838,12 +3972,11 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/) unitTarget->ToCreature()->AI()->AttackStart(m_caster); } -void Spell::EffectWeaponDmg(SpellEffIndex /*effIndex*/) +void Spell::EffectWeaponDmg(SpellEffIndex effIndex) { -} + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + return; -void Spell::SpellDamageWeaponDmg(SpellEffIndex effIndex) -{ if (!unitTarget || !unitTarget->isAlive()) return; @@ -4133,6 +4266,9 @@ void Spell::SpellDamageWeaponDmg(SpellEffIndex effIndex) void Spell::EffectThreat(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive() || !m_caster->isAlive()) return; @@ -4144,6 +4280,9 @@ void Spell::EffectThreat(SpellEffIndex /*effIndex*/) void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive()) return; @@ -4170,6 +4309,9 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/) void Spell::EffectInterruptCast(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive()) return; @@ -4199,6 +4341,9 @@ void Spell::EffectInterruptCast(SpellEffIndex effIndex) void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue; GameObject* pGameObj = new GameObject; @@ -4288,6 +4433,9 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) void Spell::EffectScriptEffect(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + // TODO: we must implement hunter pet summon at login there (spell 6962) switch(m_spellInfo->SpellFamilyName) @@ -5328,6 +5476,9 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) void Spell::EffectSanctuary(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -5358,6 +5509,9 @@ void Spell::EffectSanctuary(SpellEffIndex /*effIndex*/) void Spell::EffectAddComboPoints(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -5372,6 +5526,9 @@ void Spell::EffectAddComboPoints(SpellEffIndex /*effIndex*/) void Spell::EffectDuel(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5456,13 +5613,16 @@ void Spell::EffectDuel(SpellEffIndex effIndex) void Spell::EffectStuck(SpellEffIndex /*effIndex*/) { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + if (!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER) return; if (!sWorld->getBoolConfig(CONFIG_CAST_UNSTUCK)) return; - Player* pTarget = (Player*)unitTarget; + Player* pTarget = (Player*)m_caster; sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell Effect: Stuck"); sLog->outDetail("Player %s (guid %u) used auto-unstuck future at map %u (%f, %f, %f)", pTarget->GetName(), pTarget->GetGUIDLow(), m_caster->GetMapId(), m_caster->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ()); @@ -5470,9 +5630,9 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/) if (pTarget->isInFlight()) return; - pTarget->TeleportTo(pTarget->GetStartPosition(), unitTarget == m_caster ? TELE_TO_SPELL : 0); + pTarget->TeleportTo(pTarget->GetStartPosition(), m_caster == m_caster ? TELE_TO_SPELL : 0); // homebind location is loaded always - // pTarget->TeleportTo(pTarget->m_homebindMapId, pTarget->m_homebindX, pTarget->m_homebindY, pTarget->m_homebindZ, pTarget->GetOrientation(), (unitTarget == m_caster ? TELE_TO_SPELL : 0)); + // pTarget->TeleportTo(pTarget->m_homebindMapId, pTarget->m_homebindX, pTarget->m_homebindY, pTarget->m_homebindZ, pTarget->GetOrientation(), (m_caster == m_caster ? TELE_TO_SPELL : 0)); // Stuck spell trigger Hearthstone cooldown SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(8690); @@ -5484,6 +5644,10 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/) void Spell::EffectSummonPlayer(SpellEffIndex /*effIndex*/) { + // workaround - this effect should not use target map + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5505,6 +5669,9 @@ void Spell::EffectSummonPlayer(SpellEffIndex /*effIndex*/) void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!gameObjTarget) return; @@ -5518,6 +5685,9 @@ void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/) void Spell::EffectApplyGlyph(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER || m_glyphIndex >= MAX_GLYPH_SLOT_INDEX) return; @@ -5573,6 +5743,9 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex) void Spell::EffectEnchantHeldItem(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + // this is only item spell effect applied to main-hand weapon of target player (players in area) if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5615,6 +5788,9 @@ void Spell::EffectEnchantHeldItem(SpellEffIndex effIndex) void Spell::EffectDisEnchant(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -5631,6 +5807,9 @@ void Spell::EffectDisEnchant(SpellEffIndex /*effIndex*/) void Spell::EffectInebriate(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -5646,12 +5825,15 @@ void Spell::EffectInebriate(SpellEffIndex /*effIndex*/) void Spell::EffectFeedPet(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; Player* _player = m_caster->ToPlayer(); - Item* foodItem = m_targets.GetItemTarget(); + Item* foodItem = itemTarget; if (!foodItem) return; @@ -5677,21 +5859,23 @@ void Spell::EffectFeedPet(SpellEffIndex effIndex) void Spell::EffectDismissPet(SpellEffIndex effIndex) { - if (m_caster->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - Pet* pet = m_caster->ToPlayer()->GetPet(); - - // not let dismiss dead pet - if (!pet||!pet->isAlive()) + if (!unitTarget || !unitTarget->isPet()) return; + Pet* pet = unitTarget->ToPet(); + ExecuteLogEffectUnsummonObject(effIndex, pet); - m_caster->ToPlayer()->RemovePet(pet, PET_SAVE_NOT_IN_SLOT); + pet->GetOwner()->RemovePet(pet, PET_SAVE_NOT_IN_SLOT); } void Spell::EffectSummonObject(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + uint32 go_id = m_spellInfo->Effects[effIndex].MiscValue; uint8 slot = 0; @@ -5754,6 +5938,9 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) void Spell::EffectResurrect(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; if (unitTarget->GetTypeId() != TYPEID_PLAYER) @@ -5809,6 +5996,9 @@ void Spell::EffectResurrect(SpellEffIndex effIndex) void Spell::EffectAddExtraAttacks(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || !unitTarget->isAlive() || !unitTarget->getVictim()) return; @@ -5822,19 +6012,28 @@ void Spell::EffectAddExtraAttacks(SpellEffIndex effIndex) void Spell::EffectParry(SpellEffIndex /*effIndex*/) { - if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) - unitTarget->ToPlayer()->SetCanParry(true); + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + m_caster->ToPlayer()->SetCanParry(true); } void Spell::EffectBlock(SpellEffIndex /*effIndex*/) { - if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) - unitTarget->ToPlayer()->SetCanBlock(true); + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + m_caster->ToPlayer()->SetCanBlock(true); } void Spell::EffectLeap(SpellEffIndex /*effIndex*/) { - if (unitTarget->isInFlight()) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + + if (!unitTarget || unitTarget->isInFlight()) return; if (!m_targets.HasDst()) @@ -5845,12 +6044,15 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/) void Spell::EffectReputation(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; Player* _player = unitTarget->ToPlayer(); - int32 rep_change = damage;//+1; // field store reputation change -1 + int32 rep_change = damage; uint32 faction_id = m_spellInfo->Effects[effIndex].MiscValue; @@ -5873,13 +6075,12 @@ void Spell::EffectReputation(SpellEffIndex effIndex) void Spell::EffectQuestComplete(SpellEffIndex effIndex) { - Player* player = NULL; - if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) - player = (Player*)unitTarget; - else if (m_caster->GetTypeId() == TYPEID_PLAYER) - player = (Player*)m_caster; - else + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; + Player* player = unitTarget->ToPlayer(); uint32 questId = m_spellInfo->Effects[effIndex].MiscValue; if (questId) @@ -5898,6 +6099,9 @@ void Spell::EffectQuestComplete(SpellEffIndex effIndex) void Spell::EffectForceDeselect(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + WorldPacket data(SMSG_CLEAR_TARGET, 8); data << uint64(m_caster->GetGUID()); m_caster->SendMessageToSet(&data, true); @@ -5905,11 +6109,14 @@ void Spell::EffectForceDeselect(SpellEffIndex /*effIndex*/) void Spell::EffectSelfResurrect(SpellEffIndex effIndex) { - if (!unitTarget || unitTarget->isAlive()) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - if (unitTarget->GetTypeId() != TYPEID_PLAYER) + + if (!m_caster || m_caster->isAlive()) return; - if (!unitTarget->IsInWorld()) + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return; + if (!m_caster->IsInWorld()) return; uint32 health = 0; @@ -5924,12 +6131,12 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex) // percent case else { - health = unitTarget->CountPctFromMaxHealth(damage); - if (unitTarget->GetMaxPower(POWER_MANA) > 0) - mana = CalculatePctN(unitTarget->GetMaxPower(POWER_MANA), damage); + health = m_caster->CountPctFromMaxHealth(damage); + if (m_caster->GetMaxPower(POWER_MANA) > 0) + mana = CalculatePctN(m_caster->GetMaxPower(POWER_MANA), damage); } - Player* plr = unitTarget->ToPlayer(); + Player* plr = m_caster->ToPlayer(); plr->ResurrectPlayer(0.0f); plr->SetHealth(health); @@ -5942,6 +6149,9 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex) void Spell::EffectSkinning(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (unitTarget->GetTypeId() != TYPEID_UNIT) return; if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -5965,21 +6175,32 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/) void Spell::EffectCharge(SpellEffIndex /*effIndex*/) { - Unit* target = m_targets.GetUnitTarget(); - if (!target) - return; + if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + { + if (!unitTarget) + return; - float x, y, z; - target->GetContactPoint(m_caster, x, y, z); - m_caster->GetMotionMaster()->MoveCharge(x, y, z); + float x, y, z; + unitTarget->GetContactPoint(m_caster, x, y, z); + m_caster->GetMotionMaster()->MoveCharge(x, y, z); + } - // not all charge effects used in negative spells - if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->Attack(target, true); + if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) + { + if (!unitTarget) + return; + + // not all charge effects used in negative spells + if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER) + m_caster->Attack(unitTarget, true); + } } void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) + return; + if (m_targets.HasDst()) { float x, y, z; @@ -5990,6 +6211,9 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/) void Spell::EffectKnockBack(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -6045,30 +6269,26 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex) void Spell::EffectLeapBack(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET) + return; + + if (!unitTarget) + return; + float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue)/10; float speedz = float(damage/10); - if (!speedxy) - { - if (m_targets.GetUnitTarget()) - m_caster->JumpTo(m_targets.GetUnitTarget(), speedz); - } - else - { - //1891: Disengage - m_caster->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891); - } + //1891: Disengage + m_caster->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891); } void Spell::EffectQuestClear(SpellEffIndex effIndex) { - Player* pPlayer = NULL; - if (m_caster->GetTypeId() == TYPEID_PLAYER) - pPlayer = m_caster->ToPlayer(); - else if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) - pPlayer = unitTarget->ToPlayer(); + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; - if (!pPlayer) + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; + Player* pPlayer = unitTarget->ToPlayer(); uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue; @@ -6100,6 +6320,9 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex) void Spell::EffectSendTaxi(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6108,6 +6331,9 @@ void Spell::EffectSendTaxi(SpellEffIndex effIndex) void Spell::EffectPullTowards(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -6131,6 +6357,9 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex) void Spell::EffectDispelMechanic(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -6157,6 +6386,9 @@ void Spell::EffectDispelMechanic(SpellEffIndex effIndex) void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; Player* _player = m_caster->ToPlayer(); @@ -6185,6 +6417,9 @@ void Spell::EffectSummonDeadPet(SpellEffIndex /*effIndex*/) void Spell::EffectDestroyAllTotems(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + int32 mana = 0; for (uint8 slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot) { @@ -6211,6 +6446,9 @@ void Spell::EffectDestroyAllTotems(SpellEffIndex /*effIndex*/) void Spell::EffectDurabilityDamage(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6236,6 +6474,9 @@ void Spell::EffectDurabilityDamage(SpellEffIndex effIndex) void Spell::EffectDurabilityDamagePCT(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6262,6 +6503,9 @@ void Spell::EffectDurabilityDamagePCT(SpellEffIndex effIndex) void Spell::EffectModifyThreatPercent(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; @@ -6270,6 +6514,9 @@ void Spell::EffectModifyThreatPercent(SpellEffIndex /*effIndex*/) void Spell::EffectTransmitted(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue; GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id); @@ -6412,6 +6659,9 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) void Spell::EffectProspecting(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -6434,6 +6684,9 @@ void Spell::EffectProspecting(SpellEffIndex /*effIndex*/) void Spell::EffectMilling(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -6456,6 +6709,9 @@ void Spell::EffectMilling(SpellEffIndex /*effIndex*/) void Spell::EffectSkill(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "WORLD: SkillEFFECT"); } @@ -6465,9 +6721,10 @@ void Spell::EffectSkill(SpellEffIndex /*effIndex*/) This is why we use a half sec delay between the visual effect and the resurrection itself */ void Spell::EffectSpiritHeal(SpellEffIndex /*effIndex*/) { - /* - if (!unitTarget || unitTarget->isAlive()) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; + + /* if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; if (!unitTarget->IsInWorld()) @@ -6483,6 +6740,9 @@ void Spell::EffectSpiritHeal(SpellEffIndex /*effIndex*/) // remove insignia spell effect void Spell::EffectSkinPlayerCorpse(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Effect: SkinPlayerCorpse"); if ((m_caster->GetTypeId() != TYPEID_PLAYER) || (unitTarget->GetTypeId() != TYPEID_PLAYER) || (unitTarget->isAlive())) return; @@ -6492,6 +6752,9 @@ void Spell::EffectSkinPlayerCorpse(SpellEffIndex /*effIndex*/) void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Effect: StealBeneficialBuff"); if (!unitTarget || unitTarget == m_caster) // can't steal from self @@ -6594,6 +6857,9 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex) void Spell::EffectKillCreditPersonal(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6602,6 +6868,9 @@ void Spell::EffectKillCreditPersonal(SpellEffIndex effIndex) void Spell::EffectKillCredit(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6618,6 +6887,9 @@ void Spell::EffectKillCredit(SpellEffIndex effIndex) void Spell::EffectQuestFail(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6626,6 +6898,9 @@ void Spell::EffectQuestFail(SpellEffIndex effIndex) void Spell::EffectQuestStart(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6641,6 +6916,9 @@ void Spell::EffectQuestStart(SpellEffIndex effIndex) void Spell::EffectActivateRune(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) + return; + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -6679,6 +6957,9 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex) void Spell::EffectCreateTamedPet(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || unitTarget->GetPetGUID() || unitTarget->getClass() != CLASS_HUNTER) return; @@ -6704,6 +6985,9 @@ void Spell::EffectCreateTamedPet(SpellEffIndex effIndex) void Spell::EffectDiscoverTaxi(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue; @@ -6713,18 +6997,27 @@ void Spell::EffectDiscoverTaxi(SpellEffIndex effIndex) void Spell::EffectTitanGrip(SpellEffIndex /*effIndex*/) { - if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) - unitTarget->ToPlayer()->SetCanTitanGrip(true); + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + m_caster->ToPlayer()->SetCanTitanGrip(true); } void Spell::EffectRedirectThreat(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (unitTarget) m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID()); } void Spell::EffectGameObjectDamage(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!gameObjTarget) return; @@ -6741,6 +7034,9 @@ void Spell::EffectGameObjectDamage(SpellEffIndex /*effIndex*/) void Spell::EffectGameObjectRepair(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!gameObjTarget) return; @@ -6749,6 +7045,9 @@ void Spell::EffectGameObjectRepair(SpellEffIndex /*effIndex*/) void Spell::EffectGameObjectSetDestructionState(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!gameObjTarget || !m_originalCaster) return; @@ -6869,6 +7168,9 @@ void Spell::GetSummonPosition(uint32 i, Position &pos, float radius, uint32 coun void Spell::EffectRenamePet(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || !unitTarget->ToCreature()->isPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET) return; @@ -6878,6 +7180,9 @@ void Spell::EffectRenamePet(SpellEffIndex /*effIndex*/) void Spell::EffectPlayMusic(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6896,6 +7201,9 @@ void Spell::EffectPlayMusic(SpellEffIndex effIndex) void Spell::EffectSpecCount(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6904,6 +7212,9 @@ void Spell::EffectSpecCount(SpellEffIndex /*effIndex*/) void Spell::EffectActivateSpec(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6912,6 +7223,9 @@ void Spell::EffectActivateSpec(SpellEffIndex /*effIndex*/) void Spell::EffectPlayerNotification(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -6938,6 +7252,9 @@ void Spell::EffectPlayerNotification(SpellEffIndex effIndex) void Spell::EffectRemoveAura(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget) return; // there may be need of specifying casterguid of removed auras @@ -6946,7 +7263,10 @@ void Spell::EffectRemoveAura(SpellEffIndex effIndex) void Spell::EffectCastButtons(SpellEffIndex effIndex) { - if (!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER) + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + if (m_caster->GetTypeId() != TYPEID_PLAYER) return; Player* p_caster = m_caster->ToPlayer(); @@ -6980,12 +7300,15 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex) continue; TriggerCastFlags triggerFlags = TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_CAST_DIRECTLY); - m_caster->CastSpell(unitTarget, spell_id, triggerFlags); + m_caster->CastSpell(m_caster, spell_id, triggerFlags); } } void Spell::EffectRechargeManaGem(SpellEffIndex /*effIndex*/) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -7013,6 +7336,9 @@ void Spell::EffectRechargeManaGem(SpellEffIndex /*effIndex*/) void Spell::EffectBind(SpellEffIndex effIndex) { + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; @@ -7066,7 +7392,10 @@ void Spell::EffectBind(SpellEffIndex effIndex) player->SendDirectMessage(&data); } -void Spell::EffectSummonRaFFriend(SpellEffIndex effIndex) { +void Spell::EffectSummonRaFFriend(SpellEffIndex effIndex) +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; if (m_caster->GetTypeId() != TYPEID_PLAYER || !unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index d880b9524b2..b7bcf02f86c 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -29,7 +29,12 @@ uint32 GetTargetFlagMask(SpellTargetObjectTypes objType) return TARGET_FLAG_DEST_LOCATION; case TARGET_OBJECT_TYPE_UNIT_AND_DEST: return TARGET_FLAG_DEST_LOCATION | TARGET_FLAG_UNIT; + case TARGET_OBJECT_TYPE_CORPSE_ALLY: + return TARGET_FLAG_CORPSE_ALLY; + case TARGET_OBJECT_TYPE_CORPSE_ENEMY: + return TARGET_FLAG_CORPSE_ENEMY; case TARGET_OBJECT_TYPE_CORPSE: + return TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY; case TARGET_OBJECT_TYPE_UNIT: return TARGET_FLAG_UNIT; case TARGET_OBJECT_TYPE_GOBJ: @@ -199,20 +204,6 @@ uint32 SpellImplicitTargetInfo::GetExplicitTargetMask(bool& srcSet, bool& dstSet return targetMask; } -bool SpellImplicitTargetInfo::IsPosition(uint32 targetType) -{ - switch (SpellImplicitTargetInfo::Type[targetType]) - { - case TARGET_TYPE_DEST_CASTER: - case TARGET_TYPE_DEST_TARGET: - case TARGET_TYPE_DEST_DEST: - return true; - default: - break; - } - return false; -} - bool SpellImplicitTargetInfo::InitStaticData() { InitTypeData(); @@ -531,7 +522,11 @@ bool SpellEffectInfo::IsAreaAuraEffect() const bool SpellEffectInfo::IsFarUnitTargetEffect() const { - return Effect == SPELL_EFFECT_SUMMON_PLAYER; + return (Effect == SPELL_EFFECT_SUMMON_PLAYER) + || (Effect == SPELL_EFFECT_SUMMON_RAF_FRIEND) + || (Effect == SPELL_EFFECT_RESURRECT) + || (Effect == SPELL_EFFECT_RESURRECT_NEW) + || (Effect == SPELL_EFFECT_SKIN_PLAYER_CORPSE); } bool SpellEffectInfo::IsFarDestTargetEffect() const @@ -647,265 +642,213 @@ float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const return radius; } -SpellEffectTargetTypes SpellEffectInfo::GetRequiredTargetType() const +uint32 SpellEffectInfo::GetProvidedTargetMask() const { - return RequiredTargetType[Effect]; + return GetTargetFlagMask(TargetA.GetObjectType()) | GetTargetFlagMask(TargetB.GetObjectType()); } -SpellTargetObjectTypes SpellEffectInfo::GetImplicitTargetObjectType() const +uint32 SpellEffectInfo::GetMissingTargetMask(bool srcSet /*= false*/, bool dstSet /*= false*/, uint32 mask /*=0*/) const { - return _data[Effect].ImplicitObjectType; -} + uint32 effImplicitTargetMask = GetTargetFlagMask(GetUsedTargetObjectType()); + uint32 providedTargetMask = GetTargetFlagMask(TargetA.GetObjectType()) | GetTargetFlagMask(TargetB.GetObjectType()) | mask; -SpellTargetObjectTypes SpellEffectInfo::GetRequiredTargetObjectType() const -{ - return _data[Effect].RequiredObjectType; + // remove all flags covered by effect target mask + if (providedTargetMask & TARGET_FLAG_UNIT_MASK) + effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK); + if (providedTargetMask & TARGET_FLAG_CORPSE_MASK) + effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK); + if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_ITEM) + effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT_ITEM | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_ITEM); + if (providedTargetMask & TARGET_FLAG_GAMEOBJECT) + effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM); + if (providedTargetMask & TARGET_FLAG_ITEM) + effImplicitTargetMask &= ~(TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM); + if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION) + effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION); + if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION) + effImplicitTargetMask &= ~(TARGET_FLAG_SOURCE_LOCATION); + + return effImplicitTargetMask; } -bool SpellEffectInfo::InitStaticData() +SpellEffectImplicitTargetTypes SpellEffectInfo::GetImplicitTargetType() const { - InitRequiredTargetTypeData(); - return true; + return _data[Effect].ImplicitTargetType; } -void SpellEffectInfo::InitRequiredTargetTypeData() +SpellTargetObjectTypes SpellEffectInfo::GetUsedTargetObjectType() const { - for (uint8 i = 0; i < TOTAL_SPELL_EFFECTS; ++i) - { - switch (i) - { - case SPELL_EFFECT_PERSISTENT_AREA_AURA: //27 - case SPELL_EFFECT_SUMMON: //28 - case SPELL_EFFECT_TRIGGER_MISSILE: //32 - case SPELL_EFFECT_TRANS_DOOR: //50 summon object - case SPELL_EFFECT_SUMMON_PET: //56 - case SPELL_EFFECT_ADD_FARSIGHT: //72 - case SPELL_EFFECT_SUMMON_OBJECT_WILD: //76 - //case SPELL_EFFECT_SUMMON_CRITTER: //97 not 303 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: //104 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: //105 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: //106 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: //107 - case SPELL_EFFECT_SUMMON_DEAD_PET: //109 - case SPELL_EFFECT_TRIGGER_SPELL_2: //151 ritual of summon - RequiredTargetType[i] = SPELL_REQUIRE_DEST; - break; - case SPELL_EFFECT_PARRY: // 0 - case SPELL_EFFECT_BLOCK: // 0 - case SPELL_EFFECT_SKILL: // always with dummy 3 as A - //case SPELL_EFFECT_LEARN_SPELL: // 0 may be 5 pet - case SPELL_EFFECT_TRADE_SKILL: // 0 or 1 - case SPELL_EFFECT_PROFICIENCY: // 0 - RequiredTargetType[i] = SPELL_REQUIRE_NONE; - break; - case SPELL_EFFECT_ENCHANT_ITEM: - case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY: - case SPELL_EFFECT_DISENCHANT: - //in 243 this is 0, in 309 it is 1 - //so both item target and unit target is pushed, and cause crash - //case SPELL_EFFECT_FEED_PET: - case SPELL_EFFECT_PROSPECTING: - case SPELL_EFFECT_MILLING: - case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC: - RequiredTargetType[i] = SPELL_REQUIRE_ITEM; - break; - //caster must be pushed otherwise no sound - case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: - case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: - case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: - case SPELL_EFFECT_APPLY_AREA_AURA_PET: - case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: - case SPELL_EFFECT_APPLY_AREA_AURA_RAID: - case SPELL_EFFECT_CHARGE: - case SPELL_EFFECT_CHARGE_DEST: - case SPELL_EFFECT_JUMP: - case SPELL_EFFECT_JUMP_DEST: - case SPELL_EFFECT_LEAP_BACK: - RequiredTargetType[i] = SPELL_REQUIRE_CASTER; - break; - //case SPELL_EFFECT_WMO_DAMAGE: - //case SPELL_EFFECT_WMO_REPAIR: - //case SPELL_EFFECT_WMO_CHANGE: - // RequiredTargetType[i] = SPELL_REQUIRE_GOBJECT; - // break; - default: - RequiredTargetType[i] = SPELL_REQUIRE_UNIT; - break; - } - } + return _data[Effect].UsedTargetObjectType; } -bool SpellEffectInfo::Init = SpellEffectInfo::InitStaticData(); -SpellEffectTargetTypes SpellEffectInfo::RequiredTargetType[TOTAL_SPELL_EFFECTS]; - SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = { - // implicit target required target - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 0 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 5 SPELL_EFFECT_TELEPORT_UNITS - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 10 SPELL_EFFECT_HEAL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 11 SPELL_EFFECT_BIND - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 13 SPELL_EFFECT_RITUAL_BASE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL - {TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE}, // 18 SPELL_EFFECT_RESURRECT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON - {TARGET_OBJECT_TYPE_UNIT_AND_DEST, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 29 SPELL_EFFECT_LEAP - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 32 SPELL_EFFECT_TRIGGER_MISSILE - {TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_GOBJ_ITEM}, // 33 SPELL_EFFECT_OPEN_LOCK - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 41 SPELL_EFFECT_JUMP - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 42 SPELL_EFFECT_JUMP_DEST - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_GUARANTEE_HIT - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_CREATE_MANA_GEM - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 69 SPELL_EFFECT_DISTRACT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_PULL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_ADD_COMBO_POINTS - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 81 SPELL_EFFECT_CREATE_HOUSE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 83 SPELL_EFFECT_DUEL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_SUMMON_DEAD_PET - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 112 SPELL_EFFECT_112 - {TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE}, // 113 SPELL_EFFECT_RESURRECT_NEW - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT - {TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_131 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 144 SPELL_EFFECT_KNOCK_BACK_DEST - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 145 SPELL_EFFECT_PULL_TOWARDS_DEST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_ACTIVATE_RUNE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_148 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2 - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_ITEM_2 - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_160 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 163 SPELL_EFFECT_163 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA + // implicit target type used target object type + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 0 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 5 SPELL_EFFECT_TELEPORT_UNITS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 10 SPELL_EFFECT_HEAL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 11 SPELL_EFFECT_BIND + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 13 SPELL_EFFECT_RITUAL_BASE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 18 SPELL_EFFECT_RESURRECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 29 SPELL_EFFECT_LEAP + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 32 SPELL_EFFECT_TRIGGER_MISSILE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ_ITEM}, // 33 SPELL_EFFECT_OPEN_LOCK + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 41 SPELL_EFFECT_JUMP + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 42 SPELL_EFFECT_JUMP_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_GUARANTEE_HIT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_CREATE_MANA_GEM + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 69 SPELL_EFFECT_DISTRACT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_PULL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_ADD_COMBO_POINTS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 81 SPELL_EFFECT_CREATE_HOUSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 83 SPELL_EFFECT_DUEL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_SUMMON_DEAD_PET + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 112 SPELL_EFFECT_112 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 113 SPELL_EFFECT_RESURRECT_NEW + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ENEMY}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_131 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 144 SPELL_EFFECT_KNOCK_BACK_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 145 SPELL_EFFECT_PULL_TOWARDS_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_ACTIVATE_RUNE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_ITEM_2 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_160 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 163 SPELL_EFFECT_163 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA }; SpellInfo::SpellInfo(SpellEntry const* spellEntry) @@ -1121,7 +1064,7 @@ bool SpellInfo::IsAbilityOfSkillType(uint32 skillType) const bool SpellInfo::IsAOE() const { for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].IsArea()) + if (Effects[i].IsEffect() && Effects[i].IsArea()) return true; return false; } @@ -1595,6 +1538,8 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a // aura limitations for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { + if (!Effects[i].IsAura()) + continue; switch (Effects[i].ApplyAuraName) { case SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED: @@ -1775,7 +1720,7 @@ uint32 SpellInfo::GetAllEffectsMechanicMask() const if (Mechanic) mask |= 1 << Mechanic; for (int i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].Mechanic) + if (Effects[i].IsEffect() && Effects[i].Mechanic) mask |= 1 << Effects[i].Mechanic; return mask; } @@ -1785,14 +1730,14 @@ uint32 SpellInfo::GetEffectMechanicMask(uint8 effIndex) const uint32 mask = 0; if (Mechanic) mask |= 1<< Mechanic; - if (Effects[effIndex].Mechanic) + if (Effects[effIndex].IsEffect() && Effects[effIndex].Mechanic) mask |= 1<< Effects[effIndex].Mechanic; return mask; } Mechanics SpellInfo::GetEffectMechanic(uint8 effIndex) const { - if (Effects[effIndex].Mechanic) + if (Effects[effIndex].IsEffect() && Effects[effIndex].Mechanic) return Mechanics(Effects[effIndex].Mechanic); if (Mechanic) return Mechanics(Mechanic); @@ -1862,8 +1807,8 @@ AuraStateType SpellInfo::GetAuraState() const if (GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (Effects[i].ApplyAuraName == SPELL_AURA_MOD_STUN - || Effects[i].ApplyAuraName == SPELL_AURA_MOD_ROOT) + if (Effects[i].IsAura() && (Effects[i].ApplyAuraName == SPELL_AURA_MOD_STUN + || Effects[i].ApplyAuraName == SPELL_AURA_MOD_ROOT)) return AURA_STATE_FROZEN; switch (Id) @@ -1890,6 +1835,8 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const bool drink = false; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { + if (!Effects[i].IsAura()) + continue; switch (Effects[i].ApplyAuraName) { // Food @@ -2277,65 +2224,18 @@ uint32 SpellInfo::_GetExplicitTargetMask() const continue; targetMask |= Effects[i].TargetA.GetExplicitTargetMask(srcSet, dstSet); targetMask |= Effects[i].TargetB.GetExplicitTargetMask(srcSet, dstSet); - } - // spells with range may need explicit targets, even if target entries not set - // for example many SPELL_EFFECT_LEARN_SPELL spells need to have unit target - if (GetMaxRange(true) > 0.0f || GetMaxRange(false) > 0.0f) - { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (!Effects[i].IsEffect()) - continue; - uint32 effImplicitTargetMask = GetTargetFlagMask(Effects[i].GetImplicitTargetObjectType()); - uint32 providedTargetMask = GetTargetFlagMask(Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(Effects[i].TargetB.GetObjectType()) | targetMask; + // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided + if (Effects[i].GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT) + continue; - // check if valid targets already present, prevent adding redundant flags - switch (Effects[i].GetImplicitTargetObjectType()) - { - case TARGET_OBJECT_TYPE_UNIT_AND_DEST: - if (providedTargetMask & TARGET_FLAG_UNIT_MASK) - effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK); - if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION) - effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION); - if (!effImplicitTargetMask) - continue; - break; - case TARGET_OBJECT_TYPE_SRC: - if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION) - continue; - break; - case TARGET_OBJECT_TYPE_DEST: - if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION) - continue; - break; - case TARGET_OBJECT_TYPE_UNIT: - if (providedTargetMask & TARGET_FLAG_UNIT_MASK) - continue; - break; - case TARGET_OBJECT_TYPE_CORPSE: - if (providedTargetMask & (TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_UNIT_MASK)) - continue; - break; - case TARGET_OBJECT_TYPE_ITEM: - if (providedTargetMask & (TARGET_FLAG_GAMEOBJECT_ITEM | TARGET_FLAG_ITEM)) - continue; - break; - case TARGET_OBJECT_TYPE_GOBJ: - if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_MASK) - continue; - break; - case TARGET_OBJECT_TYPE_GOBJ_ITEM: - if (providedTargetMask & (TARGET_FLAG_GAMEOBJECT_ITEM | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_ITEM)) - continue; - break; - default: - continue; - } + // extend explicit target mask only if valid targets for effect could not be provided by target types + uint32 effectTargetMask = Effects[i].GetMissingTargetMask(srcSet, dstSet, targetMask); - // extend explicit target mask only if valid targets for effect could not be provided by target types - targetMask |= effImplicitTargetMask &~(providedTargetMask); - } + // don't add explicit object/dest flags when spell has no max range + if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f) + effectTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_DEST_LOCATION); + targetMask |= effectTargetMask; } return targetMask; } @@ -2408,7 +2308,7 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const // Special case: effects which determine positivity of whole spell for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (Effects[i].ApplyAuraName == SPELL_AURA_MOD_STEALTH) + if (Effects[i].IsAura() && Effects[i].ApplyAuraName == SPELL_AURA_MOD_STEALTH) return true; } diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 77d27a908d3..9b29120ef1c 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -66,16 +66,7 @@ enum SpellCastTargetFlags | TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT_DEAD | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_UNIT_PASSENGER, TARGET_FLAG_GAMEOBJECT_MASK = TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM, TARGET_FLAG_CORPSE_MASK = TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY, -}; - -enum SpellEffectTargetTypes -{ - SPELL_REQUIRE_NONE, - SPELL_REQUIRE_UNIT, - SPELL_REQUIRE_DEST, - SPELL_REQUIRE_ITEM, - SPELL_REQUIRE_CASTER, - SPELL_REQUIRE_GOBJECT, + TARGET_FLAG_ITEM_MASK = TARGET_FLAG_TRADE_ITEM | TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM, }; enum SpellTargetSelectionCategories @@ -100,7 +91,7 @@ enum SpellTargetReferenceTypes enum SpellTargetObjectTypes { - TARGET_OBJECT_TYPE_NONE, + TARGET_OBJECT_TYPE_NONE = 0, TARGET_OBJECT_TYPE_SRC, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_UNIT, @@ -109,6 +100,9 @@ enum SpellTargetObjectTypes TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_CORPSE, + // only for effect target type + TARGET_OBJECT_TYPE_CORPSE_ENEMY, + TARGET_OBJECT_TYPE_CORPSE_ALLY, }; enum SpellTargetSelectionCheckTypes @@ -153,6 +147,13 @@ enum SpellSelectTargetTypes TARGET_TYPE_CHANNEL, }; +enum SpellEffectImplicitTargetTypes +{ + EFFECT_IMPLICIT_TARGET_NONE = 0, + EFFECT_IMPLICIT_TARGET_EXPLICIT, + EFFECT_IMPLICIT_TARGET_CASTER, +}; + // Spell clasification enum SpellSpecificType { @@ -227,9 +228,7 @@ public: uint32 GetExplicitTargetMask(bool& srcSet, bool& dstSet) const; // temporarily avalible to public - static bool IsPosition(uint32 targetType); static SpellSelectTargetTypes Type[TOTAL_SPELL_TARGETS]; - private: static bool InitStaticData(); static void InitTypeData(); @@ -294,22 +293,17 @@ public: bool HasRadius() const; float CalcRadius(Unit* caster = NULL, Spell* = NULL) const; - SpellEffectTargetTypes GetRequiredTargetType() const; + uint32 GetProvidedTargetMask() const; + uint32 GetMissingTargetMask(bool srcSet = false, bool destSet = false, uint32 mask = 0) const; - SpellTargetObjectTypes GetImplicitTargetObjectType() const; - SpellTargetObjectTypes GetRequiredTargetObjectType() const; + SpellEffectImplicitTargetTypes GetImplicitTargetType() const; + SpellTargetObjectTypes GetUsedTargetObjectType() const; private: - static bool InitStaticData(); - static void InitRequiredTargetTypeData(); - - static bool Init; - static SpellEffectTargetTypes RequiredTargetType[TOTAL_SPELL_EFFECTS]; - struct StaticData { - SpellTargetObjectTypes ImplicitObjectType; // defines if explicit target can be added to effect target list if there's no valid target type provided for effect - SpellTargetObjectTypes RequiredObjectType; // defines valid target object type for spell effect + SpellEffectImplicitTargetTypes ImplicitTargetType; // defines what target can be added to effect target list if there's no valid target type provided for effect + SpellTargetObjectTypes UsedTargetObjectType; // defines valid target object type for spell effect }; static StaticData _data[TOTAL_SPELL_EFFECTS]; }; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index a0098237e18..57fa113dec8 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2846,6 +2846,10 @@ void SpellMgr::LoadSpellCustomAttr() case 69293: // Wing Buffet case 74439: // Machine Gun case 63278: // Mark of the Faceless (General Vezax) + case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang) + case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang) + case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang) + case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang) spellInfo->AttributesCu |= SPELL_ATTR0_CU_IGNORE_ARMOR; break; case 64422: // Sonic Screech (Auriaya) @@ -2905,11 +2909,6 @@ void SpellMgr::LoadDbcDataCorrections() if (!spellInfo->speed && !spellInfo->SpellFamilyName) spellInfo->speed = SPEED_CHARGE; break; - case SPELL_EFFECT_TRIGGER_SPELL: - if (SpellImplicitTargetInfo::IsPosition(spellInfo->EffectImplicitTargetA[j]) || - spellInfo->Targets & (TARGET_FLAG_SOURCE_LOCATION | TARGET_FLAG_DEST_LOCATION)) - spellInfo->Effect[j] = SPELL_EFFECT_TRIGGER_MISSILE; - break; } } @@ -2956,20 +2955,10 @@ void SpellMgr::LoadDbcDataCorrections() case 59372: // Energize Cores spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_SRC_AREA_ENEMY; break; - case 3286: // Bind - spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY; - spellInfo->EffectImplicitTargetA[1] = TARGET_UNIT_TARGET_ENEMY; - break; case 8494: // Mana Shield (rank 2) // because of bug in dbc spellInfo->procChance = 0; break; - case 32182: // Heroism - spellInfo->excludeCasterAuraSpell = 57723; // Exhaustion - break; - case 2825: // Bloodlust - spellInfo->excludeCasterAuraSpell = 57724; // Sated - break; case 20335: // Heart of the Crusader case 20336: case 20337: @@ -2977,14 +2966,6 @@ void SpellMgr::LoadDbcDataCorrections() // Entries were not updated after spell effect change, we have to do that manually :/ spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED; break; - case 16007: // Draco-Incarcinatrix 900 - // was 46, but effect is aura effect - spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_NEARBY_ENTRY; - spellInfo->EffectImplicitTargetB[0] = TARGET_DEST_NEARBY_ENTRY; - break; - case 19465: // Improved Stings, only rank 2 of this spell has target for effect 2 = TARGET_DST_DB - spellInfo->EffectImplicitTargetA[2] = TARGET_UNIT_CASTER; - break; case 59725: // Improved Spell Reflection - aoe aura // Target entry seems to be wrong for this spell :/ spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER_AREA_PARTY; @@ -3007,13 +2988,8 @@ void SpellMgr::LoadDbcDataCorrections() case 42611: // Shoot case 62374: // Pursued case 61588: // Blazing Harpoon - spellInfo->MaxAffectedTargets = 1; - break; case 52479: // Gift of the Harvester spellInfo->MaxAffectedTargets = 1; - // a trap always has dst = src? - spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER; - spellInfo->EffectImplicitTargetA[1] = TARGET_DEST_CASTER; break; case 41376: // Spite case 39992: // Needle Spine @@ -3091,15 +3067,10 @@ void SpellMgr::LoadDbcDataCorrections() // add corruption to affected spells spellInfo->EffectSpellClassMask[1][0] |= 2; break; - case 49305: // Teleport to Boss 1 DND - case 64981: // Summon Random Vanquished Tentacle - spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_CASTER; - break; case 51852: // The Eye of Acherus (no spawn in phase 2 in db) spellInfo->EffectMiscValue[0] |= 1; break; - case 18541: // Ritual of Doom Effect (temp hack, current targeting system requires implicit targets to be set. Was target_dest_caster) - case 51904: // Summon Ghouls On Scarlet Crusade (core does not know the triggered spell is summon spell) + case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed) spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER; break; case 29809: // Desecration Arm - 36 instead of 37 - typo? :/ @@ -3120,6 +3091,9 @@ void SpellMgr::LoadDbcDataCorrections() // with this spell atrribute aura can be stacked several times spellInfo->Attributes &= ~SPELL_ATTR0_NOT_SHAPESHIFT; break; + case 64904: //Hymn of Hope + spellInfo->EffectApplyAuraName[EFFECT_1] = SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT; + break; case 30421: // Nether Portal - Perseverence spellInfo->EffectBasePoints[2] += 30000; break; @@ -3151,10 +3125,6 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_SRC_AREA_ALLY; spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_SRC_AREA_ALLY; break; - case 31687: // Summon Water Elemental - // 322-330 switch - effect changed to dummy, target entry not changed in client:( - spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER; - break; case 57994: // Wind Shear - improper data for EFFECT_1 in 3.3.5 DBC, but is correct in 4.x spellInfo->Effect[EFFECT_1] = SPELL_EFFECT_MODIFY_THREAT_PERCENT; spellInfo->EffectBasePoints[EFFECT_1] = -6; // -5% @@ -3173,12 +3143,12 @@ void SpellMgr::LoadDbcDataCorrections() case 53246: // Marked for Death (Rank 5) spellInfo->EffectSpellClassMask[0] = flag96(423937, 276955137, 2049); break; - case 70728: // Exploit Weakness - case 70840: // Devious Minds + case 70728: // Exploit Weakness (needs target selection script) + case 70840: // Devious Minds (needs target selection script) spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER; spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_PET; break; - case 70893: // Culling The Herd + case 70893: // Culling The Herd (needs target selection script) spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER; spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_MASTER; break; @@ -3310,10 +3280,10 @@ void SpellMgr::LoadDbcDataCorrections() case 72507: // Mutated Plague (Professor Putricide) spellInfo->EffectRadiusIndex[0] = 28; // 50000yd break; - case 70911: // Unbound Plague (Professor Putricide) - case 72854: // Unbound Plague (Professor Putricide) - case 72855: // Unbound Plague (Professor Putricide) - case 72856: // Unbound Plague (Professor Putricide) + case 70911: // Unbound Plague (Professor Putricide) (needs target selection script) + case 72854: // Unbound Plague (Professor Putricide) (needs target selection script) + case 72855: // Unbound Plague (Professor Putricide) (needs target selection script) + case 72856: // Unbound Plague (Professor Putricide) (needs target selection script) spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY; break; case 71518: // Unholy Infusion Quest Credit (Professor Putricide) @@ -3340,7 +3310,7 @@ void SpellMgr::LoadDbcDataCorrections() case 71085: // Mana Void (periodic aura) spellInfo->DurationIndex = 9; // 30 seconds (missing) break; - case 70936: // Summon Suppressor + case 70936: // Summon Suppressor (needs target selection script) spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ANY; spellInfo->EffectImplicitTargetB[0] = 0; break; diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 5c9a6a23304..2d83b2e8f1a 100755 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -215,9 +215,21 @@ void SpellScript::UnitTargetHandler::Call(SpellScript* spellScript, std::list<Un bool SpellScript::_Validate(SpellInfo const* entry) { - for (std::list<EffectHandler>::iterator itr = OnEffect.begin(); itr != OnEffect.end(); ++itr) + for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) - sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunch` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + + for (std::list<EffectHandler>::iterator itr = OnEffectLaunchTarget.begin(); itr != OnEffectLaunchTarget.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunchTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + + for (std::list<EffectHandler>::iterator itr = OnEffectHit.begin(); itr != OnEffectHit.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHit` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + + for (std::list<EffectHandler>::iterator itr = OnEffectHitTarget.begin(); itr != OnEffectHitTarget.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHitTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); for (std::list<UnitTargetHandler>::iterator itr = OnUnitTargetSelect.begin(); itr != OnUnitTargetSelect.end(); ++itr) if (!(*itr).GetAffectedEffectsMask(entry)) @@ -251,6 +263,33 @@ void SpellScript::_FinishScriptCall() m_currentScriptState = SPELL_SCRIPT_STATE_NONE; } +bool SpellScript::IsInCheckCastHook() const +{ + return m_currentScriptState == SPELL_SCRIPT_HOOK_CHECK_CAST; +} +bool SpellScript::IsInTargetHook() const +{ + switch (m_currentScriptState) + { + case SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET: + case SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET: + case SPELL_SCRIPT_HOOK_BEFORE_HIT: + case SPELL_SCRIPT_HOOK_HIT: + case SPELL_SCRIPT_HOOK_AFTER_HIT: + return true; + } + return false; +} +bool SpellScript::IsInHitPhase() const +{ + return (m_currentScriptState >= HOOK_SPELL_HIT_START && m_currentScriptState < HOOK_SPELL_HIT_END); +} + +bool SpellScript::IsInEffectHook() const +{ + return (m_currentScriptState >= SPELL_SCRIPT_HOOK_EFFECT_LAUNCH && m_currentScriptState <= SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET); +} + Unit* SpellScript::GetCaster() { return m_spell->GetCaster(); @@ -295,9 +334,9 @@ Item* SpellScript::GetTargetItem() Unit* SpellScript::GetHitUnit() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitUnit was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitUnit was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return NULL; } return m_spell->unitTarget; @@ -305,9 +344,9 @@ Unit* SpellScript::GetHitUnit() Creature* SpellScript::GetHitCreature() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitCreature was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitCreature was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return NULL; } if (m_spell->unitTarget) @@ -318,9 +357,9 @@ Creature* SpellScript::GetHitCreature() Player* SpellScript::GetHitPlayer() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitPlayer was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitPlayer was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return NULL; } if (m_spell->unitTarget) @@ -331,9 +370,9 @@ Player* SpellScript::GetHitPlayer() Item* SpellScript::GetHitItem() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitItem was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitItem was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return NULL; } return m_spell->itemTarget; @@ -341,9 +380,9 @@ Item* SpellScript::GetHitItem() GameObject* SpellScript::GetHitGObj() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return NULL; } return m_spell->gameObjTarget; @@ -351,9 +390,9 @@ GameObject* SpellScript::GetHitGObj() int32 SpellScript::GetHitDamage() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitDamage was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitDamage was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return 0; } return m_spell->m_damage; @@ -361,9 +400,9 @@ int32 SpellScript::GetHitDamage() void SpellScript::SetHitDamage(int32 damage) { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::SetHitDamage was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::SetHitDamage was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return; } m_spell->m_damage = damage; @@ -371,9 +410,9 @@ void SpellScript::SetHitDamage(int32 damage) int32 SpellScript::GetHitHeal() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitHeal was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitHeal was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return 0; } return m_spell->m_healing; @@ -381,9 +420,9 @@ int32 SpellScript::GetHitHeal() void SpellScript::SetHitHeal(int32 heal) { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::SetHitHeal was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::SetHitHeal was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return; } m_spell->m_healing = heal; @@ -391,9 +430,9 @@ void SpellScript::SetHitHeal(int32 heal) Aura* SpellScript::GetHitAura() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitAura was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitAura was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return NULL; } if (!m_spell->m_spellAura) @@ -405,9 +444,9 @@ Aura* SpellScript::GetHitAura() void SpellScript::PreventHitAura() { - if (!IsInHitPhase()) + if (!IsInTargetHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitAura was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitAura was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return; } if (m_spell->m_spellAura) @@ -416,9 +455,9 @@ void SpellScript::PreventHitAura() void SpellScript::PreventHitEffect(SpellEffIndex effIndex) { - if (!IsInHitPhase()) + if (!IsInHitPhase() && !IsInEffectHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitEffect was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitEffect was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return; } m_hitPreventEffectMask |= 1 << effIndex; @@ -427,9 +466,9 @@ void SpellScript::PreventHitEffect(SpellEffIndex effIndex) void SpellScript::PreventHitDefaultEffect(SpellEffIndex effIndex) { - if (!IsInHitPhase()) + if (!IsInHitPhase() && !IsInEffectHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitDefaultEffect was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitDefaultEffect was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return; } m_hitPreventDefaultEffectMask |= 1 << effIndex; @@ -439,7 +478,7 @@ int32 SpellScript::GetEffectValue() { if (!IsInEffectHook()) { - sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitDefaultEffect was called while spell not in hit phase!", m_scriptName->c_str(), m_scriptSpellId); + sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitDefaultEffect was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); return 0; } return m_spell->damage; diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 8a742cbd118..af814798a3a 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -122,7 +122,10 @@ class _SpellScript // SpellScript interface - enum used for runtime checks of script function calls enum SpellScriptHookType { - SPELL_SCRIPT_HOOK_EFFECT = SPELL_SCRIPT_STATE_END, + SPELL_SCRIPT_HOOK_EFFECT_LAUNCH = SPELL_SCRIPT_STATE_END, + SPELL_SCRIPT_HOOK_EFFECT_LAUNCH_TARGET, + SPELL_SCRIPT_HOOK_EFFECT_HIT, + SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET, SPELL_SCRIPT_HOOK_BEFORE_HIT, SPELL_SCRIPT_HOOK_HIT, SPELL_SCRIPT_HOOK_AFTER_HIT, @@ -130,7 +133,7 @@ enum SpellScriptHookType SPELL_SCRIPT_HOOK_CHECK_CAST, }; -#define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT +#define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT_HIT #define HOOK_SPELL_HIT_END SPELL_SCRIPT_HOOK_AFTER_HIT + 1 #define HOOK_SPELL_START SPELL_SCRIPT_HOOK_EFFECT #define HOOK_SPELL_END SPELL_SCRIPT_HOOK_CHECK_CAST + 1 @@ -205,9 +208,10 @@ class SpellScript : public _SpellScript bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) { return m_hitPreventDefaultEffectMask & (1<<effIndex); } void _PrepareScriptCall(SpellScriptHookType hookType); void _FinishScriptCall(); - bool IsInCheckCastHook() const { return m_currentScriptState == SPELL_SCRIPT_HOOK_CHECK_CAST; } - bool IsInHitPhase() const { return (m_currentScriptState >= HOOK_SPELL_HIT_START && m_currentScriptState < HOOK_SPELL_HIT_END); } - bool IsInEffectHook() const { return (m_currentScriptState == SPELL_SCRIPT_HOOK_EFFECT); } + bool IsInCheckCastHook() const; + bool IsInTargetHook() const; + bool IsInHitPhase() const; + bool IsInEffectHook() const; private: Spell* m_spell; uint8 m_hitPreventEffectMask; @@ -223,9 +227,12 @@ class SpellScript : public _SpellScript HookList<CheckCastHandler> OnCheckCast; #define SpellCheckCastFn(F) CheckCastHandlerFunction(&F) - // example: OnEffect += SpellEffectFn(class::function, EffectIndexSpecifier, EffectNameSpecifier); + // example: OnEffect**** += SpellEffectFn(class::function, EffectIndexSpecifier, EffectNameSpecifier); // where function is void function(SpellEffIndex effIndex) - HookList<EffectHandler> OnEffect; + HookList<EffectHandler> OnEffectLaunch; + HookList<EffectHandler> OnEffectLaunchTarget; + HookList<EffectHandler> OnEffectHit; + HookList<EffectHandler> OnEffectHitTarget; #define SpellEffectFn(F, I, N) EffectHandlerFunction(&F, I, N) // example: BeforeHit += SpellHitFn(class::function); @@ -244,10 +251,13 @@ class SpellScript : public _SpellScript // hooks are executed in following order, at specified event of spell: // 1. OnUnitTargetSelect - executed just before adding selected targets to final target list - // 2. BeforeHit - executed just before spell hits a target - // 3. OnEffect - executed just before specified effect handler call - // 4. OnHit - executed just before spell deals damage and procs auras - // 5. AfterHit - executed just after spell finishes all it's jobs for target + // 2. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched + // 3. OnEffectLaunchTarget - executed just before specified effect handler call - when spell missile is launched - called for each target from spell target map + // 4. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest + // 5. BeforeHit - executed just before spell hits a target - called for each target from spell target map + // 6. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map + // 7. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map + // 8. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map // // methods allowing interaction with Spell object @@ -275,7 +285,7 @@ class SpellScript : public _SpellScript // returns: Item which was selected as a spell target or NULL Item* GetTargetItem(); - // methods useable only during spell hit on target phase: + // methods useable only during spell hit on target, or during spell launch on target: // returns: target of current effect if it was Unit otherwise NULL Unit* GetHitUnit(); diff --git a/src/server/scripts/Examples/example_spell.cpp b/src/server/scripts/Examples/example_spell.cpp index aafddbd0884..372abc45268 100644 --- a/src/server/scripts/Examples/example_spell.cpp +++ b/src/server/scripts/Examples/example_spell.cpp @@ -76,10 +76,28 @@ class spell_ex_5581 : public SpellScriptLoader delete localVariable2; } - void HandleDummy(SpellEffIndex /*effIndex*/) + void HandleDummyLaunch(SpellEffIndex /*effIndex*/) { + sLog->outString("Spell %u with SPELL_EFFECT_DUMMY is just launched!", GetSpellInfo()->Id); + } + + void HandleDummyLaunchTarget(SpellEffIndex /*effIndex*/) + { + uint64 targetGUID = 0; + if (Unit* unitTarget = GetHitUnit()) + targetGUID = unitTarget->GetGUID(); // we're handling SPELL_EFFECT_DUMMY in effIndex 0 here - sLog->outString("SPELL_EFFECT_DUMMY is executed on target!"); + sLog->outString("Spell %u with SPELL_EFFECT_DUMMY is just launched at it's target: " UI64FMTD "!", GetSpellInfo()->Id, targetGUID); + } + + void HandleDummyHit(SpellEffIndex /*effIndex*/) + { + sLog->outString("Spell %u with SPELL_EFFECT_DUMMY has hit!", GetSpellInfo()->Id); + } + + void HandleDummyHitTarget(SpellEffIndex /*effIndex*/) + { + sLog->outString("SPELL_EFFECT_DUMMY is hits it's target!"); // make caster cast a spell on a unit target of effect if (Unit* target = GetHitUnit()) GetCaster()->CastSpell(target, SPELL_TRIGGERED, true); @@ -110,15 +128,20 @@ class spell_ex_5581 : public SpellScriptLoader void Register() { // we're registering our function here - // function HandleDummy will be called when unit is hit by spell, just before default effect 0 handler - //OnEffect += SpellEffectFn(spell_ex_5581SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - OnEffect += SpellEffectFn(spell_ex_5581SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + // function HandleDummy will be called when spell is launched, independant from targets selected for spell, just before default effect 0 launch handler + OnEffectLaunch += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyLaunch, EFFECT_0, SPELL_EFFECT_DUMMY); + // function HandleDummy will be called when spell is launched at target, just before default effect 0 launch at target handler + OnEffectLaunchTarget += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyLaunchTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + // function HandleDummy will be called when spell hits it's destination, independant from targets selected for spell, just before default effect 0 hit handler + OnEffectHit += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyHit, EFFECT_0, SPELL_EFFECT_DUMMY); + // function HandleDummy will be called when unit is hit by spell, just before default effect 0 hit target handler + OnEffectHitTarget += SpellEffectFn(spell_ex_5581SpellScript::HandleDummyHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); // this will prompt an error on startup because effect 0 of spell 49375 is set to SPELL_EFFECT_DUMMY, not SPELL_EFFECT_APPLY_AURA - //OnEffect += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + //OnEffectHitTarget += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); // this will make HandleDummy function to be called on first != 0 effect of spell 49375 - //OnEffect += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_FIRST_FOUND, SPELL_EFFECT_ANY); + //OnEffectHitTarget += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_FIRST_FOUND, SPELL_EFFECT_ANY); // this will make HandleDummy function to be called on all != 0 effect of spell 49375 - //OnEffect += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY); + //OnEffectHitTarget += SpellEffectFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY); // bind handler to BeforeHit event of the spell BeforeHit += SpellHitFn(spell_ex_5581SpellScript::HandleBeforeHit); // bind handler to OnHit event of the spell diff --git a/src/server/scripts/Kalimdor/durotar.cpp b/src/server/scripts/Kalimdor/durotar.cpp index e92faa5cde7..1f64353901c 100644 --- a/src/server/scripts/Kalimdor/durotar.cpp +++ b/src/server/scripts/Kalimdor/durotar.cpp @@ -499,7 +499,7 @@ class spell_voljin_war_drums : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_voljin_war_drums_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_voljin_war_drums_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -553,7 +553,7 @@ class spell_voodoo : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_voodoo_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_voodoo_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp index 1de4f115f36..f0f27db8095 100644 --- a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp @@ -728,7 +728,7 @@ class spell_ooze_zap : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_ooze_zap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); OnCheckCast += SpellCheckCastFn(spell_ooze_zap_SpellScript::CheckRequirement); } }; @@ -765,7 +765,7 @@ class spell_ooze_zap_channel_end : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_ooze_zap_channel_end_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_channel_end_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -811,7 +811,7 @@ class spell_energize_aoe : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp index d0c59627be7..3a50838fff9 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp @@ -219,7 +219,7 @@ class spell_saviana_conflagration_init : public SpellScriptLoader void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffect += SpellEffectFn(spell_saviana_conflagration_init_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_saviana_conflagration_init_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -247,7 +247,7 @@ class spell_saviana_conflagration_throwback : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_saviana_conflagration_throwback_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_saviana_conflagration_throwback_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index 1c32debc45a..b9348e572ca 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -774,7 +774,7 @@ class spell_powering_up : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_powering_up_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_powering_up_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index 289371907ee..5c3249949b8 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -282,7 +282,7 @@ class spell_bronjahm_consume_soul : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_bronjahm_consume_soul_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_bronjahm_consume_soul_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp index 87015dfc0cb..33ce2ac71fd 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp @@ -647,7 +647,7 @@ class spell_krick_pursuit : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_krick_pursuit_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_krick_pursuit_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index 35c2d40494a..b351d7de9d7 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -1419,7 +1419,7 @@ class spell_taldaram_glittering_sparks : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_taldaram_glittering_sparks_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_taldaram_glittering_sparks_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1446,7 +1446,7 @@ class spell_taldaram_summon_flame_ball : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_taldaram_summon_flame_ball_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_taldaram_summon_flame_ball_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -1546,7 +1546,7 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_valanar_kinetic_bomb_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); + OnEffectHit += SpellEffectFn(spell_valanar_kinetic_bomb_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 9b062761edf..332c52f55b6 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -673,7 +673,7 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffect += SpellEffectFn(spell_blood_queen_bloodbolt_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_blood_queen_bloodbolt_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 0962dbf35a4..cb7c25e152b 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -985,7 +985,7 @@ class spell_deathbringer_blood_link : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_deathbringer_blood_link_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_link_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -1112,7 +1112,7 @@ class spell_deathbringer_rune_of_blood : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_deathbringer_rune_of_blood_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_deathbringer_rune_of_blood_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1147,7 +1147,7 @@ class spell_deathbringer_blood_nova : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_deathbringer_blood_nova_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp index 6a58924f938..b117dadf045 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp @@ -368,7 +368,7 @@ class spell_festergut_pungent_blight : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_festergut_pungent_blight_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_festergut_pungent_blight_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -406,7 +406,7 @@ class spell_festergut_gastric_bloat : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_festergut_gastric_bloat_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_festergut_gastric_bloat_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp index ab4e6b8a4ce..9e4079a7a15 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp @@ -891,7 +891,7 @@ class npc_darnavan : public CreatureScript if (me->HasUnitState(UNIT_STAT_CASTING)) return; - if (_canShatter && me->getVictim()->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL)) + if (_canShatter && me->getVictim() && me->getVictim()->IsImmunedToDamage(SPELL_SCHOOL_MASK_NORMAL)) { DoCastVictim(SPELL_SHATTERING_THROW); _canShatter = false; @@ -1004,7 +1004,7 @@ class spell_cultist_dark_martyrdom : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_cultist_dark_martyrdom_SpellScript::HandleEffect, EFFECT_2, SPELL_EFFECT_FORCE_DESELECT); + OnEffectHitTarget += SpellEffectFn(spell_cultist_dark_martyrdom_SpellScript::HandleEffect, EFFECT_2, SPELL_EFFECT_FORCE_DESELECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index f418726aedf..b19042b3669 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -438,7 +438,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); - OnEffect += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -466,7 +466,7 @@ class spell_marrowgar_coldflame_bonestorm : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -545,7 +545,7 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader void Register() { OnCheckCast += SpellCheckCastFn(spell_marrowgar_bone_spike_graveyard_SpellScript::CheckCast); - OnEffect += SpellEffectFn(spell_marrowgar_bone_spike_graveyard_SpellScript::HandleSpikes, EFFECT_1, SPELL_EFFECT_APPLY_AURA); + OnEffectHitTarget += SpellEffectFn(spell_marrowgar_bone_spike_graveyard_SpellScript::HandleSpikes, EFFECT_1, SPELL_EFFECT_APPLY_AURA); } }; @@ -571,7 +571,7 @@ class spell_marrowgar_bone_storm : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_marrowgar_bone_storm_SpellScript::RecalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_marrowgar_bone_storm_SpellScript::RecalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index ec5318be15b..72b5f8f918c 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -908,7 +908,7 @@ class spell_putricide_unstable_experiment : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_putricide_unstable_experiment_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_putricide_unstable_experiment_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -975,7 +975,7 @@ class spell_putricide_ooze_eruption_searcher : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_putricide_ooze_eruption_searcher_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_putricide_ooze_eruption_searcher_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -1009,7 +1009,7 @@ class spell_putricide_choking_gas_bomb : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_putricide_choking_gas_bomb_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_putricide_choking_gas_bomb_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1072,7 +1072,7 @@ class spell_putricide_unbound_plague : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_putricide_unbound_plague_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_putricide_unbound_plague_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1123,7 +1123,7 @@ class spell_putricide_eat_ooze : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_putricide_eat_ooze_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_putricide_eat_ooze_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY); } }; @@ -1352,7 +1352,7 @@ class spell_putricide_mutated_transformation : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_putricide_mutated_transformation_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); + OnEffectHitTarget += SpellEffectFn(spell_putricide_mutated_transformation_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); } }; @@ -1407,7 +1407,7 @@ class spell_putricide_regurgitated_ooze : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_putricide_regurgitated_ooze_SpellScript::ExtraEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + OnEffectHitTarget += SpellEffectFn(spell_putricide_regurgitated_ooze_SpellScript::ExtraEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); } }; @@ -1438,7 +1438,7 @@ class spell_stinky_precious_decimate : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_stinky_precious_decimate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_stinky_precious_decimate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index b46c0653c09..24738fe0155 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -460,7 +460,7 @@ class spell_rotface_ooze_flood : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_rotface_ooze_flood_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_rotface_ooze_flood_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_ooze_flood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); } }; @@ -553,7 +553,7 @@ class spell_rotface_little_ooze_combine : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_rotface_little_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_rotface_little_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -595,7 +595,7 @@ class spell_rotface_large_ooze_combine : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_rotface_large_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_rotface_large_ooze_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -650,7 +650,7 @@ class spell_rotface_large_ooze_buff_combine : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_rotface_large_ooze_buff_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_rotface_large_ooze_buff_combine_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -690,7 +690,7 @@ class spell_rotface_unstable_ooze_explosion_init : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_rotface_unstable_ooze_explosion_init_SpellScript::HandleCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_rotface_unstable_ooze_explosion_init_SpellScript::HandleCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); } }; @@ -727,7 +727,7 @@ class spell_rotface_unstable_ooze_explosion : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_rotface_unstable_ooze_explosion_SpellScript::CheckTarget, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); + OnEffectHit += SpellEffectFn(spell_rotface_unstable_ooze_explosion_SpellScript::CheckTarget, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index bf2ef447cb4..65edd4cca37 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -985,7 +985,7 @@ class spell_sindragosa_s_fury : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_sindragosa_s_fury_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_sindragosa_s_fury_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_s_fury_SpellScript::CountTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); } @@ -1253,7 +1253,7 @@ class spell_sindragosa_icy_grip : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_sindragosa_icy_grip_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_sindragosa_icy_grip_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1289,7 +1289,7 @@ class spell_rimefang_icy_blast : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_rimefang_icy_blast_SpellScript::HandleTriggerMissile, EFFECT_1, SPELL_EFFECT_TRIGGER_MISSILE); + OnEffectHit += SpellEffectFn(spell_rimefang_icy_blast_SpellScript::HandleTriggerMissile, EFFECT_1, SPELL_EFFECT_TRIGGER_MISSILE); } }; @@ -1360,7 +1360,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_frostwarden_handler_order_whelp_SpellScript::HandleForcedCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_frostwarden_handler_order_whelp_SpellScript::HandleForcedCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); OnUnitTargetSelect += SpellUnitTargetFn(spell_frostwarden_handler_order_whelp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); } }; @@ -1389,7 +1389,7 @@ class spell_frostwarden_handler_focus_fire : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_frostwarden_handler_focus_fire_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_frostwarden_handler_focus_fire_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index fd8f2b3714a..8b2153b2006 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -1208,7 +1208,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnEffect += SpellEffectFn(spell_dreamwalker_summoner_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_summoner_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); } }; @@ -1286,7 +1286,7 @@ class spell_dreamwalker_summon_suppresser_effect : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dreamwalker_summon_suppresser_effect_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_summon_suppresser_effect_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); } }; @@ -1317,7 +1317,7 @@ class spell_dreamwalker_summon_dream_portal : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dreamwalker_summon_dream_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_summon_dream_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1348,7 +1348,7 @@ class spell_dreamwalker_summon_nightmare_portal : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dreamwalker_summon_nightmare_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_summon_nightmare_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1415,7 +1415,7 @@ class spell_dreamwalker_twisted_nightmares : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dreamwalker_twisted_nightmares_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_twisted_nightmares_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_FORCE_CAST); } }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 16cb0c50beb..25e77fb4506 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -1765,7 +1765,7 @@ class spell_icc_sprit_alarm : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_icc_sprit_alarm_SpellScript::HandleEvent, EFFECT_2, SPELL_EFFECT_SEND_EVENT); + OnEffectHit += SpellEffectFn(spell_icc_sprit_alarm_SpellScript::HandleEvent, EFFECT_2, SPELL_EFFECT_SEND_EVENT); } }; @@ -1848,7 +1848,7 @@ class spell_frost_giant_death_plague : public SpellScriptLoader { OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY); - OnEffect += SpellEffectFn(spell_frost_giant_death_plague_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_frost_giant_death_plague_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } bool _failed; @@ -1882,8 +1882,8 @@ class spell_icc_harvest_blight_specimen : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_icc_harvest_blight_specimen_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - OnEffect += SpellEffectFn(spell_icc_harvest_blight_specimen_SpellScript::HandleQuestComplete, EFFECT_1, SPELL_EFFECT_QUEST_COMPLETE); + OnEffectHitTarget += SpellEffectFn(spell_icc_harvest_blight_specimen_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_icc_harvest_blight_specimen_SpellScript::HandleQuestComplete, EFFECT_1, SPELL_EFFECT_QUEST_COMPLETE); } }; @@ -1947,7 +1947,7 @@ class spell_svalna_remove_spear : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_svalna_remove_spear_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_svalna_remove_spear_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp index 4da9e661087..c214141cd32 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp @@ -191,7 +191,7 @@ class spell_heigan_eruption : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_heigan_eruption_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_heigan_eruption_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); } }; diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 7ecd9c84cbf..46bf017eb42 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -646,7 +646,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_malygos_vortex_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_malygos_vortex_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp index 7d355b2f71a..1a153474416 100644 --- a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp @@ -237,12 +237,13 @@ class spell_intense_cold : public SpellScriptLoader void HandlePeriodicTick(AuraEffect const* aurEff) { + if (aurEff->GetBase()->GetStackAmount() < 2) + return; Unit* caster = GetCaster(); - if (!caster) + //TODO: the caster should be boss but not the player + if (!caster || !caster->GetAI()) return; - - if (aurEff->GetBase()->GetStackAmount() >= 2) - caster->GetAI()->SetGUID(GetTarget()->GetGUID(), DATA_INTENSE_COLD); + caster->GetAI()->SetGUID(GetTarget()->GetGUID(), DATA_INTENSE_COLD); } void Register() diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp index a7abfcf42be..828cf65beec 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_assembly_of_iron.cpp @@ -787,7 +787,7 @@ class spell_assembly_meltdown : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_assembly_meltdown_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL); + OnEffectHitTarget += SpellEffectFn(spell_assembly_meltdown_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL); } }; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp index 53d5fe22db6..256b03c7754 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_flame_leviathan.cpp @@ -32,6 +32,7 @@ #include "SpellInfo.h" #include "SpellScript.h" #include "Vehicle.h" +#include "VehicleDefines.h" #include "ulduar.h" enum Spells @@ -139,7 +140,6 @@ enum Vehicles #define EMOTE_OVERLOAD "Flame Leviathan's circuits overloaded." #define EMOTE_REPAIR "Automatic repair sequence initiated." #define DATA_SHUTOUT 29112912 // 2911, 2912 are achievement IDs -#define DATA_UNBROKEN 29052906 // 2905, 2906 are achievement IDs #define DATA_ORBIT_ACHIEVEMENTS 1 #define VEHICLE_SPAWNS 5 #define FREYA_SPAWNS 4 @@ -235,6 +235,7 @@ class boss_flame_leviathan : public CreatureScript ASSERT(vehicle); if (!me->isDead()) Reset(); + ActiveTowersCount = 4; Shutdown = 0; ActiveTowers = false; @@ -267,14 +268,16 @@ class boss_flame_leviathan : public CreatureScript _Reset(); //resets shutdown counter to 0. 2 or 4 depending on raid mode Shutdown = 0; + _pursueTarget = 0; + me->SetReactState(REACT_DEFENSIVE); } void EnterCombat(Unit* /*who*/) { _EnterCombat(); - me->SetReactState(REACT_AGGRESSIVE); - events.ScheduleEvent(EVENT_PURSUE, 30*IN_MILLISECONDS); + me->SetReactState(REACT_PASSIVE); + events.ScheduleEvent(EVENT_PURSUE, 1); events.ScheduleEvent(EVENT_MISSILE, urand(1500, 4*IN_MILLISECONDS)); events.ScheduleEvent(EVENT_VENT, 20*IN_MILLISECONDS); events.ScheduleEvent(EVENT_SHUTDOWN, 150*IN_MILLISECONDS); @@ -320,14 +323,6 @@ class boss_flame_leviathan : public CreatureScript DoScriptText(SAY_AGGRO, me); } - //TODO: effect 0 and effect 1 may be on different target - //TODO: Move to spellscript - void SpellHitTarget(Unit* target, SpellInfo const* spell) - { - if (spell->Id == SPELL_PURSUED) - AttackStart(target); - } - void JustDied(Unit* /*victim*/) { _JustDied(); @@ -389,21 +384,6 @@ class boss_flame_leviathan : public CreatureScript return; } - if (me->HasAura(SPELL_SYSTEMS_SHUTDOWN)) - { - me->SetReactState(REACT_PASSIVE); - me->AddUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); - if (Shutout) - Shutout = false; - return; - } - else - { - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); - } - if (me->HasUnitState(UNIT_STAT_CASTING)) return; @@ -413,12 +393,8 @@ class boss_flame_leviathan : public CreatureScript { case EVENT_PURSUE: DoScriptText(RAND(SAY_TARGET_1, SAY_TARGET_2, SAY_TARGET_3), me); - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 75, true)) - { - me->CastSpell(target, SPELL_PURSUED, true); - me->MonsterTextEmote(EMOTE_PURSUE, target->GetGUID(), true); - } - events.ScheduleEvent(EVENT_PURSUE, 30*IN_MILLISECONDS); + DoCast(SPELL_PURSUED); // Will select target in spellscript + events.ScheduleEvent(EVENT_PURSUE, 35*IN_MILLISECONDS); break; case EVENT_MISSILE: DoCast(me, SPELL_MISSILE_BARRAGE, true); @@ -442,9 +418,10 @@ class boss_flame_leviathan : public CreatureScript DoScriptText(RAND(SAY_OVERLOAD_1, SAY_OVERLOAD_2, SAY_OVERLOAD_3), me); me->MonsterTextEmote(EMOTE_OVERLOAD, 0, true); me->CastSpell(me, SPELL_SYSTEMS_SHUTDOWN, true); - me->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED); + if (Shutout) + Shutout = false; events.ScheduleEvent(EVENT_REPAIR, 4000); - events.CancelEvent(EVENT_SHUTDOWN); + events.DelayEvents(20 * IN_MILLISECONDS, 0); break; case EVENT_REPAIR: me->MonsterTextEmote(EMOTE_REPAIR, 0, true); @@ -486,10 +463,14 @@ class boss_flame_leviathan : public CreatureScript break; } } - //TODO: Fix this spell, gets applied on players who are on leviathan should be excluded? - /*if (me->IsWithinMeleeRange(me->getVictim())) //bugged spell casts on units that are boarded on leviathan - DoSpellAttackIfReady(SPELL_BATTERING_RAM);*/ - DoMeleeAttackIfReady(); + + DoBatteringRamIfReady(); + } + + void SpellHitTarget(Unit* target, SpellInfo const* spell) + { + if (spell->Id == SPELL_PURSUED) + _pursueTarget = target->GetGUID(); } void DoAction(int32 const action) @@ -554,6 +535,27 @@ class boss_flame_leviathan : public CreatureScript break; } } + + private: + //! Copypasta from DoSpellAttackIfReady, only difference is the target - it cannot be selected trough getVictim this way - + //! I also removed the spellInfo check + void DoBatteringRamIfReady() + { + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + if (me->isAttackReady()) + { + Unit* target = ObjectAccessor::GetUnit(*me, _pursueTarget); + if (me->IsWithinCombatRange(target, 30.0f)) + { + DoCast(target, SPELL_BATTERING_RAM); + me->resetAttackTimer(); + } + } + } + + uint64 _pursueTarget; }; CreatureAI* GetAI(Creature* creature) const @@ -1296,28 +1298,6 @@ class go_ulduar_tower : public GameObjectScript } }; -class at_RX_214_repair_o_matic_station : public AreaTriggerScript -{ - public: - at_RX_214_repair_o_matic_station() : AreaTriggerScript("at_RX_214_repair_o_matic_station") { } - - bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) - { - InstanceScript* instance = player->GetInstanceScript(); - if (Creature* vehicle = player->GetVehicleCreatureBase()) - { - if (!vehicle->HasAura(SPELL_AUTO_REPAIR)) - { - player->MonsterTextEmote(EMOTE_REPAIR, player->GetGUID(), true); - player->CastSpell(vehicle, SPELL_AUTO_REPAIR, true); - if (Creature* leviathan = ObjectAccessor::GetCreature(*player, instance ? instance->GetData64(BOSS_LEVIATHAN) : 0)) - leviathan->AI()->SetData(DATA_UNBROKEN, 0); // set bool to false thats checked in leviathan getdata - } - } - return true; - } -}; - class achievement_three_car_garage_demolisher : public AchievementCriteriaScript { public: @@ -1393,9 +1373,8 @@ class achievement_unbroken : public AchievementCriteriaScript bool OnCheck(Player* /*source*/, Unit* target) { if (target) - if (Creature* leviathan = target->ToCreature()) - if (leviathan->AI()->GetData(DATA_UNBROKEN)) - return true; + if (InstanceScript* instance = target->GetInstanceScript()) + return instance->GetData(DATA_UNBROKEN); return false; } @@ -1518,6 +1497,206 @@ class spell_load_into_catapult : public SpellScriptLoader } }; +class spell_auto_repair : public SpellScriptLoader +{ + enum Spells + { + SPELL_AUTO_REPAIR = 62705, + }; + + public: + spell_auto_repair() : SpellScriptLoader("spell_auto_repair") {} + + class spell_auto_repair_SpellScript : public SpellScript + { + PrepareSpellScript(spell_auto_repair_SpellScript); + + void CheckCooldownForTarget() + { + if (GetHitUnit()->HasAuraEffect(SPELL_AUTO_REPAIR, EFFECT_2)) // Check presence of dummy aura indicating cooldown + { + PreventHitEffect(EFFECT_0); + PreventHitDefaultEffect(EFFECT_1); + PreventHitDefaultEffect(EFFECT_2); + //! Currently this doesn't work: if we call PreventHitAura(), the existing aura will be removed + //! because of recent aura refreshing changes. Since removing the existing aura negates the idea + //! of a cooldown marker, we just let the dummy aura refresh itself without executing the other spelleffects. + //! The spelleffects can be executed by letting the dummy aura expire naturally. + //! This is a temporary solution only. + //PreventHitAura(); + } + } + + void HandleScript(SpellEffIndex /*eff*/) + { + Vehicle* vehicle = GetHitUnit()->GetVehicleKit(); + if (!vehicle) + return; + + Player* driver = vehicle->GetPassenger(0) ? vehicle->GetPassenger(0)->ToPlayer() : NULL; + if (!driver) + return; + + driver->MonsterTextEmote(EMOTE_REPAIR, driver->GetGUID(), true); + + InstanceScript* instance = driver->GetInstanceScript(); + if (!instance) + return; + + // Actually should/could use basepoints (100) for this spell effect as percentage of health, but oh well. + vehicle->GetBase()->SetFullHealth(); + + // For achievement + instance->SetData(DATA_UNBROKEN, 0); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_auto_repair_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + BeforeHit += SpellHitFn(spell_auto_repair_SpellScript::CheckCooldownForTarget); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_auto_repair_SpellScript(); + } +}; + +class spell_systems_shutdown : public SpellScriptLoader +{ + public: + spell_systems_shutdown() : SpellScriptLoader("spell_systems_shutdown") { } + + class spell_systems_shutdown_AuraScript : public AuraScript + { + PrepareAuraScript(spell_systems_shutdown_AuraScript); + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Creature* owner = GetOwner()->ToCreature(); + if (!owner) + return; + + //! This could probably in the SPELL_EFFECT_SEND_EVENT handler too: + owner->AddUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT); + owner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + owner->RemoveAurasDueToSpell(SPELL_GATHERING_SPEED); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Creature* owner = GetOwner()->ToCreature(); + if (!owner) + return; + + owner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_systems_shutdown_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_systems_shutdown_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_systems_shutdown_AuraScript(); + } +}; + +class FlameLeviathanPursuedTargetSelector +{ + enum Area + { + AREA_FORMATION_GROUNDS = 4652, + }; + + public: + explicit FlameLeviathanPursuedTargetSelector(Unit* unit) : _me(unit) {}; + + bool operator()(Unit* target) const + { + //! No players, only vehicles (todo: check if blizzlike) + Creature* creatureTarget = target->ToCreature(); + if (!creatureTarget) + return true; + + //! NPC entries must match + if (creatureTarget->GetEntry() != NPC_SALVAGED_DEMOLISHER && creatureTarget->GetEntry() != NPC_SALVAGED_SIEGE_ENGINE) + return true; + + //! NPC must be a valid vehicle installation + Vehicle* vehicle = creatureTarget->GetVehicleKit(); + if (!vehicle) + return true; + + //! Entity needs to be in appropriate area + if (target->GetAreaId() != AREA_FORMATION_GROUNDS) + return true; + + //! Vehicle must be in use by player + bool playerFound = false; + for (SeatMap::const_iterator itr = vehicle->Seats.begin(); itr != vehicle->Seats.end() && !playerFound; ++itr) + if (IS_PLAYER_GUID(itr->second.Passenger)) + playerFound = true; + + return !playerFound; + } + + private: + Unit const* _me; +}; + +class spell_pursue : public SpellScriptLoader +{ + public: + spell_pursue() : SpellScriptLoader("spell_pursue") {} + + class spell_pursue_SpellScript : public SpellScript + { + PrepareSpellScript(spell_pursue_SpellScript); + + void FilterTargets(std::list<Unit*>& targets) + { + targets.remove_if(FlameLeviathanPursuedTargetSelector(GetCaster())); + if (targets.empty()) + if (Creature* caster = GetCaster()->ToCreature()) + caster->AI()->EnterEvadeMode(); + } + + void HandleScript(SpellEffIndex eff) + { + Creature* caster = GetCaster()->ToCreature(); + if (!caster) + return; + + caster->AI()->AttackStart(GetHitUnit()); // Chase target + + for (SeatMap::const_iterator itr = caster->GetVehicleKit()->Seats.begin(); itr != caster->GetVehicleKit()->Seats.end(); ++itr) + { + if (IS_PLAYER_GUID(itr->second.Passenger)) + { + caster->MonsterTextEmote(EMOTE_PURSUE, itr->second.Passenger, true); + return; + } + } + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_pursue_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_pursue_SpellScript(); + } +}; + void AddSC_boss_flame_leviathan() { new boss_flame_leviathan(); @@ -1537,7 +1716,7 @@ void AddSC_boss_flame_leviathan() new npc_lorekeeper(); // new npc_brann_bronzebeard(); new go_ulduar_tower(); - new at_RX_214_repair_o_matic_station(); + new achievement_three_car_garage_demolisher(); new achievement_three_car_garage_chopper(); new achievement_three_car_garage_siege(); @@ -1549,4 +1728,7 @@ void AddSC_boss_flame_leviathan() new achievement_orbit_uary(); new spell_load_into_catapult(); + new spell_auto_repair(); + new spell_systems_shutdown(); + new spell_pursue(); } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp index 1ae51c01a9a..761eed86382 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_freya.cpp @@ -1565,7 +1565,7 @@ class spell_freya_attuned_to_nature_dose_reduction : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_freya_attuned_to_nature_dose_reduction_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_freya_attuned_to_nature_dose_reduction_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1600,7 +1600,7 @@ class spell_freya_iron_roots : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_freya_iron_roots_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); + OnEffectHit += SpellEffectFn(spell_freya_iron_roots_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); } }; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp index aa419c2fdbc..bdabaddfcf9 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp @@ -341,7 +341,7 @@ class spell_ulduar_rubble_summon : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_ulduar_rubble_summonSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_ulduar_rubble_summonSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -461,7 +461,7 @@ class spell_ulduar_cancel_stone_grip : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_ulduar_cancel_stone_gripSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_ulduar_cancel_stone_gripSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -497,7 +497,7 @@ class spell_ulduar_squeezed_lifeless : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_ulduar_squeezed_lifeless_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL); + OnEffectHitTarget += SpellEffectFn(spell_ulduar_squeezed_lifeless_SpellScript::HandleInstaKill, EFFECT_1, SPELL_EFFECT_INSTAKILL); } }; @@ -633,8 +633,8 @@ class spell_kologarn_summon_focused_eyebeam : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_kologarn_summon_focused_eyebeam_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); - OnEffect += SpellEffectFn(spell_kologarn_summon_focused_eyebeam_SpellScript::HandleForceCast, EFFECT_1, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_kologarn_summon_focused_eyebeam_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_kologarn_summon_focused_eyebeam_SpellScript::HandleForceCast, EFFECT_1, SPELL_EFFECT_FORCE_CAST); } }; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_mimiron.cpp index 7d25f22cd59..11b7c54975e 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_mimiron.cpp @@ -104,7 +104,7 @@ class spell_ulduar_proximity_mines : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_ulduar_proximity_minesSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_ulduar_proximity_minesSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp index b3f77e893c3..d99ccc7a386 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_razorscale.cpp @@ -1015,7 +1015,7 @@ class spell_razorscale_devouring_flame : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_razorscale_devouring_flame_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); + OnEffectHit += SpellEffectFn(spell_razorscale_devouring_flame_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON); } }; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp index e012cb4ca48..c58f2a24b9c 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp @@ -258,7 +258,7 @@ class boss_xt002 : public CreatureScript void UpdateAI(const uint32 diff) { - if (!UpdateVictim()) + if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); @@ -860,7 +860,7 @@ class spell_xt002_gravity_bomb_damage : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_xt002_gravity_bomb_damage_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_xt002_gravity_bomb_damage_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); } }; @@ -926,7 +926,7 @@ class spell_xt002_heart_overload_periodic : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_xt002_heart_overload_periodic_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_xt002_heart_overload_periodic_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -984,7 +984,7 @@ class spell_xt002_submerged : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_xt002_submerged_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_xt002_submerged_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1015,7 +1015,7 @@ class spell_xt002_stand : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_xt002_stand_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_xt002_stand_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp index 70d7b5108b3..e1c64499df2 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp @@ -22,8 +22,9 @@ static DoorData const doorData[] = { - { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S }, - { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S }, + { GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }, }; class instance_ulduar : public InstanceMapScript @@ -79,6 +80,7 @@ class instance_ulduar : public InstanceMapScript uint32 ColossusData; uint8 elderCount; bool conSpeedAtory; + bool Unbroken; std::set<uint64> mRubbleSpawns; @@ -117,6 +119,7 @@ class instance_ulduar : public InstanceMapScript ColossusData = 0; elderCount = 0; conSpeedAtory = false; + Unbroken = true; memset(Encounter, 0, sizeof(Encounter)); memset(XTToyPileGUIDs, 0, sizeof(XTToyPileGUIDs)); @@ -312,6 +315,9 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_LEVIATHAN) == DONE) gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); break; + case GO_XT_002_DOOR: + AddDoor(gameObject, true); + break; case GO_VEZAX_DOOR: VezaxDoorGUID = gameObject->GetGUID(); HandleGameObject(0, false, gameObject); @@ -352,6 +358,8 @@ class instance_ulduar : public InstanceMapScript case GO_LEVIATHAN_DOOR: AddDoor(gameObject, false); break; + case GO_XT_002_DOOR: + AddDoor(gameObject, false); default: break; } @@ -493,6 +501,9 @@ class instance_ulduar : public InstanceMapScript Hodir->RemoveGameObject(gameObject, false); } break; + case DATA_UNBROKEN: + Unbroken = bool(data); + break; default: break; } @@ -580,6 +591,8 @@ class instance_ulduar : public InstanceMapScript return ColossusData; case DATA_HODIR_RARE_CACHE: return HodirRareCacheData; + case DATA_UNBROKEN: + return uint32(Unbroken); default: break; } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h index 5602018f782..cff57563843 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h @@ -51,6 +51,8 @@ enum UlduarNPCs { // General NPC_LEVIATHAN = 33113, + NPC_SALVAGED_DEMOLISHER = 33109, + NPC_SALVAGED_SIEGE_ENGINE = 33060, NPC_IGNIS = 33118, NPC_RAZORSCALE = 33186, NPC_RAZORSCALE_CONTROLLER = 33233, @@ -131,6 +133,7 @@ enum UlduarGameObjects GO_FREYA_CHEST = 194324, GO_LEVIATHAN_DOOR = 194905, GO_LEVIATHAN_GATE = 194630, + GO_XT_002_DOOR = 194631, GO_VEZAX_DOOR = 194750, GO_MOLE_MACHINE = 194316, GO_RAZOR_HARPOON_1 = 194542, @@ -166,7 +169,7 @@ enum UlduarData { // Collosus (Leviathan) DATA_COLOSSUS = 20, - + // Razorscale DATA_EXPEDITION_COMMANDER, DATA_RAZORSCALE_CONTROL, @@ -177,14 +180,16 @@ enum UlduarData DATA_TOY_PILE_2, DATA_TOY_PILE_3, - // Kologarn - DATA_LEFT_ARM, - DATA_RIGHT_ARM, - // Hodir DATA_HODIR_RARE_CACHE, }; +enum UlduarAchievementData +{ + // FL Achievement boolean + DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs, +}; + template<class AI> CreatureAI* GetUlduarAI(Creature* creature) { diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 98faef9e00a..b30841e19cc 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -167,9 +167,11 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader { SpellInfo const* talentSpell = sSpellMgr->GetSpellInfo(DK_SPELL_ANTI_MAGIC_SHELL_TALENT); amount = talentSpell->Effects[EFFECT_0].CalcValue(GetCaster()); - // assume caster is a player here - if (Unit* caster = GetCaster()) - amount += int32(2 * caster->ToPlayer()->GetTotalAttackPowerValue(BASE_ATTACK)); + Unit* caster = GetCaster(); + if(!caster) + return; + if(Player* player = caster->ToPlayer()) + amount += int32(2 * player->GetTotalAttackPowerValue(BASE_ATTACK)); } void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) @@ -233,7 +235,7 @@ class spell_dk_corpse_explosion : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -266,7 +268,7 @@ class spell_dk_ghoul_explode : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::Suicide, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::Suicide, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); } }; @@ -307,7 +309,7 @@ class spell_dk_death_gate : public SpellScriptLoader void Register() { OnCheckCast += SpellCheckCastFn(spell_dk_death_gate_SpellScript::CheckClass); - OnEffect += SpellEffectFn(spell_dk_death_gate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_dk_death_gate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -393,7 +395,7 @@ class spell_dk_scourge_strike : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index cd256931532..6a8a942f7ae 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -74,7 +74,7 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_dru_glyph_of_starfire_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_dru_glyph_of_starfire_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 248dd31c2a8..f90fe53a9e2 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -205,7 +205,7 @@ class spell_gen_cannibalize : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_cannibalize_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_gen_cannibalize_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); OnCheckCast += SpellCheckCastFn(spell_gen_cannibalize_SpellScript::CheckIfCorpseNear); } }; @@ -320,7 +320,7 @@ class spell_gen_pet_summoned : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_pet_summoned_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_gen_pet_summoned_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -349,7 +349,7 @@ class spell_gen_remove_flight_auras : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_remove_flight_auras_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_gen_remove_flight_auras_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -491,7 +491,7 @@ class spell_gen_trick : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_trick_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_gen_trick_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -540,7 +540,7 @@ class spell_gen_trick_or_treat : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_trick_or_treat_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_gen_trick_or_treat_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -620,7 +620,7 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -709,7 +709,7 @@ class spell_gen_divine_storm_cd_reset : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_divine_storm_cd_reset_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_gen_divine_storm_cd_reset_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -741,7 +741,7 @@ class spell_gen_gunship_portal : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_gunship_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_gen_gunship_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -882,8 +882,8 @@ class spell_generic_clone : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_generic_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - OnEffect += SpellEffectFn(spell_generic_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_generic_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_generic_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -990,7 +990,7 @@ class spell_generic_clone_weapon : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_generic_clone_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_generic_clone_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1038,7 +1038,7 @@ class spell_gen_seaforium_blast : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_seaforium_blast_SpellScript::AchievementCredit, EFFECT_1, SPELL_EFFECT_GAMEOBJECT_DAMAGE); + OnEffectHitTarget += SpellEffectFn(spell_gen_seaforium_blast_SpellScript::AchievementCredit, EFFECT_1, SPELL_EFFECT_GAMEOBJECT_DAMAGE); } }; @@ -1170,7 +1170,7 @@ class spell_gen_magic_rooster : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_magic_rooster_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_gen_magic_rooster_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -1250,7 +1250,7 @@ class spell_gen_launch : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_gen_launch_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST); + OnEffectHitTarget += SpellEffectFn(spell_gen_launch_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST); AfterHit += SpellHitFn(spell_gen_launch_SpellScript::Launch); } }; @@ -1349,7 +1349,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_gen_oracle_wolvar_reputation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_gen_oracle_wolvar_reputation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index d0e62b9b758..1318a9aa333 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -179,7 +179,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_hun_chimera_shot_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_hun_chimera_shot_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -215,7 +215,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_hun_invigoration_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_hun_invigoration_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -250,7 +250,7 @@ public: void Register() { // add dummy effect spell handler to pet's Last Stand - OnEffect += SpellEffectFn(spell_hun_last_stand_pet_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_hun_last_stand_pet_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -300,7 +300,7 @@ class spell_hun_masters_call : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_hun_masters_call_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -345,7 +345,7 @@ public: void Register() { // add dummy effect spell handler to Readiness - OnEffect += SpellEffectFn(spell_hun_readiness_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_hun_readiness_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -378,7 +378,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_hun_scatter_shot_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_hun_scatter_shot_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -489,7 +489,7 @@ public: void Register() { // add dummy effect spell handler to pet's Last Stand - OnEffect += SpellEffectFn(spell_hun_pet_heart_of_the_phoenix_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_hun_pet_heart_of_the_phoenix_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } bool Load() @@ -544,7 +544,7 @@ public: void Register() { // add dummy effect spell handler to pet's Last Stand - OnEffect += SpellEffectFn(spell_hun_pet_carrion_feeder_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_hun_pet_carrion_feeder_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); OnCheckCast += SpellCheckCastFn(spell_hun_pet_carrion_feeder_SpellScript::CheckIfCorpseNear); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 5300849d0ec..baa998f9487 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -57,7 +57,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_trigger_spell_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_trigger_spell_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -107,7 +107,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_deviate_fish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_deviate_fish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -184,7 +184,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_flask_of_the_north_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_flask_of_the_north_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -234,7 +234,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_gnomish_death_ray_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_item_gnomish_death_ray_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -298,7 +298,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_make_a_wish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_make_a_wish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -353,7 +353,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_mingos_fortune_generator_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_mingos_fortune_generator_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -409,7 +409,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_net_o_matic_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_item_net_o_matic_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -466,7 +466,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_noggenfogger_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_noggenfogger_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -522,7 +522,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_savory_deviate_delight_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_savory_deviate_delight_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -604,7 +604,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_six_demon_bag_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_item_six_demon_bag_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -660,7 +660,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_item_underbelly_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_underbelly_elixir_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -784,7 +784,7 @@ class spell_item_red_rider_air_rifle : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_item_red_rider_air_rifle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_item_red_rider_air_rifle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -838,7 +838,7 @@ class spell_item_create_heart_candy : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_item_create_heart_candy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_item_create_heart_candy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -995,7 +995,7 @@ class spell_item_vanquished_clutches : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_item_vanquished_clutches_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_vanquished_clutches_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -1057,7 +1057,7 @@ class spell_item_ashbringer : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_item_ashbringer_SpellScript::OnDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_item_ashbringer_SpellScript::OnDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index eb889993030..339f6ed8eca 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -61,7 +61,7 @@ class spell_mage_blast_wave : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_mage_blast_wave_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); + OnEffectHitTarget += SpellEffectFn(spell_mage_blast_wave_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); } }; @@ -106,7 +106,7 @@ class spell_mage_cold_snap : public SpellScriptLoader void Register() { // add dummy effect spell handler to Cold Snap - OnEffect += SpellEffectFn(spell_mage_cold_snap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_mage_cold_snap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -145,7 +145,7 @@ class spell_mage_polymorph_cast_visual : public SpellScriptLoader void Register() { // add dummy effect spell handler to Polymorph visual - OnEffect += SpellEffectFn(spell_mage_polymorph_cast_visual_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_mage_polymorph_cast_visual_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -186,20 +186,18 @@ class spell_mage_summon_water_elemental : public SpellScriptLoader void HandleDummy(SpellEffIndex /*effIndex*/) { - if (Unit* unitTarget = GetHitUnit()) - { - // Glyph of Eternal Water - if (unitTarget->HasAura(SPELL_MAGE_GLYPH_OF_ETERNAL_WATER)) - unitTarget->CastSpell(unitTarget, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT, true); - else - unitTarget->CastSpell(unitTarget, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY, true); - } + Unit* caster = GetCaster(); + // Glyph of Eternal Water + if (caster->HasAura(SPELL_MAGE_GLYPH_OF_ETERNAL_WATER)) + caster->CastSpell(caster, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT, true); + else + caster->CastSpell(caster, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY, true); } void Register() { // add dummy effect spell handler to Summon Water Elemental - OnEffect += SpellEffectFn(spell_mage_summon_water_elemental_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_mage_summon_water_elemental_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 87c1b96a3ef..f07a13bf7db 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -157,7 +157,7 @@ public: void Register() { // add dummy effect spell handler to Blessing of Faith - OnEffect += SpellEffectFn(spell_pal_blessing_of_faith_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_pal_blessing_of_faith_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -235,7 +235,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_pal_guarded_by_the_light_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_pal_guarded_by_the_light_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -289,7 +289,7 @@ public: void Register() { // add dummy effect spell handler to Holy Shock - OnEffect += SpellEffectFn(spell_pal_holy_shock_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_pal_holy_shock_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -317,7 +317,7 @@ public: void Register() { // add dummy effect spell handler to Judgement of Command - OnEffect += SpellEffectFn(spell_pal_judgement_of_command_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_of_command_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 0e22404764b..3bcbc322e06 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -166,7 +166,7 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_pri_pain_and_suffering_proc_SpellScript::HandleEffectScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_pri_pain_and_suffering_proc_SpellScript::HandleEffectScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -221,7 +221,7 @@ class spell_pri_penance : public SpellScriptLoader void Register() { // add dummy effect spell handler to Penance - OnEffect += SpellEffectFn(spell_pri_penance_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_pri_penance_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 8f90bca5e79..6fbd33fe81b 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -56,7 +56,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_generic_quest_update_entry_SpellScript::HandleDummy, _effIndex, _spellEffect); + OnEffectHitTarget += SpellEffectFn(spell_generic_quest_update_entry_SpellScript::HandleDummy, _effIndex, _spellEffect); } }; @@ -116,7 +116,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q5206_test_fetid_skull_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_q5206_test_fetid_skull_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -174,7 +174,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q6124_6129_apply_salve_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q6124_6129_apply_salve_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -275,7 +275,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q11396_11399_scourging_crystal_controller_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q11396_11399_scourging_crystal_controller_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -310,7 +310,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q11396_11399_scourging_crystal_controller_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q11396_11399_scourging_crystal_controller_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -382,7 +382,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q11587_arcane_prisoner_rescue_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q11587_arcane_prisoner_rescue_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -466,7 +466,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q11730_ultrasonic_screwdriver_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q11730_ultrasonic_screwdriver_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -517,7 +517,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q12459_seeds_of_natures_wrath_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q12459_seeds_of_natures_wrath_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -575,7 +575,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q12634_despawn_fruit_tosser_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_q12634_despawn_fruit_tosser_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -610,7 +610,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q12683_take_sputum_sample_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_q12683_take_sputum_sample_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -718,7 +718,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q12937_relief_for_the_fallen_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q12937_relief_for_the_fallen_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -765,7 +765,7 @@ class spell_q10041_q10040_who_are_they : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_q10041_q10040_who_are_they_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_q10041_q10040_who_are_they_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -792,7 +792,7 @@ public: void HandleDummy(SpellEffIndex /*effIndex*/) { - if (Creature* target = GetTargetUnit()->ToCreature()) + if (Creature* target = GetHitCreature()) { if (target->HasAura(SPELL_PERMANENT_FEIGN_DEATH)) { @@ -807,7 +807,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_symbol_of_life_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_symbol_of_life_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -848,7 +848,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q12659_ahunaes_knife_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q12659_ahunaes_knife_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -889,7 +889,7 @@ class spell_q9874_liquid_fire : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_q9874_liquid_fire_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_q9874_liquid_fire_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -930,7 +930,7 @@ class spell_q12805_lifeblood_dummy : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_q12805_lifeblood_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_q12805_lifeblood_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -968,7 +968,7 @@ public: void Register() { - OnEffect += SpellEffectFn(spell_q13280_13283_plant_battle_standard_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_q13280_13283_plant_battle_standard_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index 079ee5ded32..3dc1ed10f29 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -198,7 +198,7 @@ class spell_rog_preparation : public SpellScriptLoader void Register() { // add dummy effect spell handler to Preparation - OnEffect += SpellEffectFn(spell_rog_preparation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_rog_preparation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -280,7 +280,7 @@ class spell_rog_shiv : public SpellScriptLoader void Register() { // add dummy effect spell handler to Shiv - OnEffect += SpellEffectFn(spell_rog_shiv_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_rog_shiv_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index cd46e0eab1c..fcb026e0232 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -30,6 +30,8 @@ enum ShamanSpells SHAMAN_SPELL_MANA_TIDE_TOTEM = 39609, SHAMAN_SPELL_FIRE_NOVA_R1 = 1535, SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1 = 8349, + SHAMAN_SPELL_SATED = 57724, + SHAMAN_SPELL_EXHAUSTION = 57723, //For Earthen Power SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM = 6474, //Spell casted by totem @@ -39,193 +41,277 @@ enum ShamanSpells // 51474 - Astral shift class spell_sha_astral_shift : public SpellScriptLoader { -public: - spell_sha_astral_shift() : SpellScriptLoader("spell_sha_astral_shift") { } + public: + spell_sha_astral_shift() : SpellScriptLoader("spell_sha_astral_shift") { } - class spell_sha_astral_shift_AuraScript : public AuraScript - { - PrepareAuraScript(spell_sha_astral_shift_AuraScript); + class spell_sha_astral_shift_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_astral_shift_AuraScript); - uint32 absorbPct; + uint32 absorbPct; - bool Load() - { - absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); - return true; - } + bool Load() + { + absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); + return true; + } - void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) - { - // Set absorbtion amount to unlimited - amount = -1; - } + void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/) + { + // Set absorbtion amount to unlimited + amount = -1; + } - void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) - { - // reduces all damage taken while stun, fear or silence - if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED) || (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))) - absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); - } + void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // reduces all damage taken while stun, fear or silence + if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED) || (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))) + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_astral_shift_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_sha_astral_shift_AuraScript::Absorb, EFFECT_0); + } + }; - void Register() + AuraScript* GetAuraScript() const { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_astral_shift_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_sha_astral_shift_AuraScript::Absorb, EFFECT_0); + return new spell_sha_astral_shift_AuraScript(); } - }; - - AuraScript* GetAuraScript() const - { - return new spell_sha_astral_shift_AuraScript(); - } }; // 1535 Fire Nova class spell_sha_fire_nova : public SpellScriptLoader { -public: - spell_sha_fire_nova() : SpellScriptLoader("spell_sha_fire_nova") { } + public: + spell_sha_fire_nova() : SpellScriptLoader("spell_sha_fire_nova") { } - class spell_sha_fire_nova_SpellScript : public SpellScript - { - PrepareSpellScript(spell_sha_fire_nova_SpellScript) - bool Validate(SpellInfo const* spellEntry) + class spell_sha_fire_nova_SpellScript : public SpellScript { - if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_FIRE_NOVA_R1)) - return false; - if (sSpellMgr->GetFirstSpellInChain(SHAMAN_SPELL_FIRE_NOVA_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id)) - return false; - - uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id); - if (!sSpellMgr->GetSpellWithRank(SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1, rank, true)) - return false; - return true; - } + PrepareSpellScript(spell_sha_fire_nova_SpellScript); - SpellCastResult CheckFireTotem() - { - // fire totem - if (!GetCaster()->m_SummonSlot[1]) + bool Validate(SpellInfo const* spellEntry) { - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_FIRE_TOTEM); - return SPELL_FAILED_CUSTOM_ERROR; + if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_FIRE_NOVA_R1)) + return false; + if (sSpellMgr->GetFirstSpellInChain(SHAMAN_SPELL_FIRE_NOVA_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id)) + return false; + + uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id); + if (!sSpellMgr->GetSpellWithRank(SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1, rank, true)) + return false; + return true; } - return SPELL_CAST_OK; - } + SpellCastResult CheckFireTotem() + { + // fire totem + if (!GetCaster()->m_SummonSlot[1]) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_FIRE_TOTEM); + return SPELL_FAILED_CUSTOM_ERROR; + } - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - uint8 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id); - if (uint32 spellId = sSpellMgr->GetSpellWithRank(SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1, rank)) + return SPELL_CAST_OK; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) { - Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[1]); - if (totem && totem->isTotem()) - totem->CastSpell(totem, spellId, true); + Unit* caster = GetCaster(); + uint8 rank = sSpellMgr->GetSpellRank(GetSpellInfo()->Id); + if (uint32 spellId = sSpellMgr->GetSpellWithRank(SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1, rank)) + { + Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[1]); + if (totem && totem->isTotem()) + totem->CastSpell(totem, spellId, true); + } } - } - void Register() + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_sha_fire_nova_SpellScript::CheckFireTotem); + OnEffectHitTarget += SpellEffectFn(spell_sha_fire_nova_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const { - OnCheckCast += SpellCheckCastFn(spell_sha_fire_nova_SpellScript::CheckFireTotem); - OnEffect += SpellEffectFn(spell_sha_fire_nova_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + return new spell_sha_fire_nova_SpellScript(); } - }; - - SpellScript* GetSpellScript() const - { - return new spell_sha_fire_nova_SpellScript(); - } }; // 39610 Mana Tide Totem class spell_sha_mana_tide_totem : public SpellScriptLoader { -public: - spell_sha_mana_tide_totem() : SpellScriptLoader("spell_sha_mana_tide_totem") { } + public: + spell_sha_mana_tide_totem() : SpellScriptLoader("spell_sha_mana_tide_totem") { } - class spell_sha_mana_tide_totem_SpellScript : public SpellScript - { - PrepareSpellScript(spell_sha_mana_tide_totem_SpellScript) - bool Validate(SpellInfo const* /*spellEntry*/) + class spell_sha_mana_tide_totem_SpellScript : public SpellScript { - if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_GLYPH_OF_MANA_TIDE)) - return false; - if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_MANA_TIDE_TOTEM)) - return false; - return true; - } + PrepareSpellScript(spell_sha_mana_tide_totem_SpellScript); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (Unit* unitTarget = GetHitUnit()) + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_GLYPH_OF_MANA_TIDE)) + return false; + if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_MANA_TIDE_TOTEM)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) { - if (unitTarget->getPowerType() == POWER_MANA) + Unit* caster = GetCaster(); + if (Unit* unitTarget = GetHitUnit()) { - int32 effValue = GetEffectValue(); - // Glyph of Mana Tide - if (Unit* owner = caster->GetOwner()) - if (AuraEffect* dummy = owner->GetAuraEffect(SHAMAN_SPELL_GLYPH_OF_MANA_TIDE, 0)) - effValue += dummy->GetAmount(); - // Regenerate 6% of Total Mana Every 3 secs - int32 effBasePoints0 = int32(CalculatePctN(unitTarget->GetMaxPower(POWER_MANA), effValue)); - caster->CastCustomSpell(unitTarget, SHAMAN_SPELL_MANA_TIDE_TOTEM, &effBasePoints0, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID()); + if (unitTarget->getPowerType() == POWER_MANA) + { + int32 effValue = GetEffectValue(); + // Glyph of Mana Tide + if (Unit* owner = caster->GetOwner()) + if (AuraEffect* dummy = owner->GetAuraEffect(SHAMAN_SPELL_GLYPH_OF_MANA_TIDE, 0)) + effValue += dummy->GetAmount(); + // Regenerate 6% of Total Mana Every 3 secs + int32 effBasePoints0 = int32(CalculatePctN(unitTarget->GetMaxPower(POWER_MANA), effValue)); + caster->CastCustomSpell(unitTarget, SHAMAN_SPELL_MANA_TIDE_TOTEM, &effBasePoints0, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID()); + } } } - } - void Register() + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_sha_mana_tide_totem_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const { - OnEffect += SpellEffectFn(spell_sha_mana_tide_totem_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + return new spell_sha_mana_tide_totem_SpellScript(); } - }; - - SpellScript* GetSpellScript() const - { - return new spell_sha_mana_tide_totem_SpellScript(); - } }; // 6474 - Earthbind Totem - Fix Talent:Earthen Power class spell_sha_earthbind_totem : public SpellScriptLoader { -public: - spell_sha_earthbind_totem() : SpellScriptLoader("spell_sha_earthbind_totem") { } + public: + spell_sha_earthbind_totem() : SpellScriptLoader("spell_sha_earthbind_totem") { } + + class spell_sha_earthbind_totem_AuraScript : public AuraScript + { + PrepareAuraScript(spell_sha_earthbind_totem_AuraScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM)) + return false; + if (!sSpellMgr->GetSpellInfo(SHAMAN_TOTEM_SPELL_EARTHEN_POWER)) + return false; + return true; + } - class spell_sha_earthbind_totem_AuraScript : public AuraScript - { - PrepareAuraScript(spell_sha_earthbind_totem_AuraScript); + void HandleEffectPeriodic(AuraEffect const* aurEff) + { + Unit* target = GetTarget(); + if (Unit* caster = aurEff->GetBase()->GetCaster()) + if (AuraEffect* aur = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) + if (roll_chance_i(aur->GetBaseAmount())) + target->CastSpell(target, SHAMAN_TOTEM_SPELL_EARTHEN_POWER, true, NULL, aurEff); + } - bool Validate(SpellInfo const* /*spellEntry*/) + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_earthbind_totem_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const { - if (!sSpellMgr->GetSpellInfo(SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM)) - return false; - if (!sSpellMgr->GetSpellInfo(SHAMAN_TOTEM_SPELL_EARTHEN_POWER)) - return false; - return true; + return new spell_sha_earthbind_totem_AuraScript(); } +}; + +class spell_sha_bloodlust : public SpellScriptLoader +{ + public: + spell_sha_bloodlust() : SpellScriptLoader("spell_sha_bloodlust") { } - void HandleEffectPeriodic(AuraEffect const* aurEff) + class spell_sha_bloodlust_SpellScript : public SpellScript { - Unit* target = GetTarget(); - if (Unit* caster = aurEff->GetBase()->GetCaster()) - if (AuraEffect* aur = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2289, 0)) - if (roll_chance_i(aur->GetBaseAmount())) - target->CastSpell(target, SHAMAN_TOTEM_SPELL_EARTHEN_POWER, true, NULL, aurEff); - } + PrepareSpellScript(spell_sha_bloodlust_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_SATED)) + return false; + return true; + } + + void RemoveInvalidTargets(std::list<Unit*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED)); + } + + void ApplyDebuff() + { + GetHitUnit()->CastSpell(GetHitUnit(), SHAMAN_SPELL_SATED, true); + } - void Register() + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); + OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); + OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); + AfterHit += SpellHitFn(spell_sha_bloodlust_SpellScript::ApplyDebuff); + } + }; + + SpellScript* GetSpellScript() const { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_earthbind_totem_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + return new spell_sha_bloodlust_SpellScript(); } - }; +}; + +class spell_sha_heroism : public SpellScriptLoader +{ + public: + spell_sha_heroism() : SpellScriptLoader("spell_sha_heroism") { } + + class spell_sha_heroism_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sha_heroism_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SHAMAN_SPELL_EXHAUSTION)) + return false; + return true; + } - AuraScript* GetAuraScript() const - { - return new spell_sha_earthbind_totem_AuraScript(); - } + void RemoveInvalidTargets(std::list<Unit*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION)); + } + + void ApplyDebuff() + { + GetHitUnit()->CastSpell(GetHitUnit(), SHAMAN_SPELL_EXHAUSTION, true); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); + OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); + OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); + AfterHit += SpellHitFn(spell_sha_heroism_SpellScript::ApplyDebuff); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_sha_heroism_SpellScript(); + } }; void AddSC_shaman_spell_scripts() @@ -234,4 +320,6 @@ void AddSC_shaman_spell_scripts() new spell_sha_fire_nova(); new spell_sha_mana_tide_totem(); new spell_sha_earthbind_totem(); + new spell_sha_bloodlust(); + new spell_sha_heroism(); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index c8329a74b47..17035c2a3d2 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -148,7 +148,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_warl_demonic_empowerment_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_warl_demonic_empowerment_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -204,7 +204,7 @@ class spell_warl_create_healthstone : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_warl_create_healthstone_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_warl_create_healthstone_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -245,7 +245,7 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader void Register() { - OnEffect += SpellEffectFn(spell_warl_everlasting_affliction_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHitTarget += SpellEffectFn(spell_warl_everlasting_affliction_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; @@ -267,12 +267,12 @@ public: void HandleDummy(SpellEffIndex /*effIndex*/) { - GetCaster()->CastSpell(GetHitUnit(), GetEffectValue(), true); + GetCaster()->CastSpell(GetCaster(), GetEffectValue(), true); } void Register() { - OnEffect += SpellEffectFn(spell_warl_ritual_of_doom_effect_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_warl_ritual_of_doom_effect_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 395673b28a2..be6e1c49ee7 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -53,7 +53,7 @@ class spell_warr_last_stand : public SpellScriptLoader void Register() { // add dummy effect spell handler to Last Stand - OnEffect += SpellEffectFn(spell_warr_last_stand_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHit += SpellEffectFn(spell_warr_last_stand_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index bd058ad25bf..b6030c62df4 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -306,7 +306,7 @@ class spell_mark_of_nature : public SpellScriptLoader void Register() { OnUnitTargetSelect += SpellUnitTargetFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffect += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); } }; diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index d7222c8564f..55bfe76cb12 100755 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -1039,3 +1039,15 @@ void Log::outChat(const char * str, ...) va_end(ap); } } + +void Log::outErrorST(const char * str, ...) +{ + va_list ap; + va_start(ap, str); + char nnew_str[MAX_QUERY_LEN]; + vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap); + va_end(ap); + + ACE_Stack_Trace st; + outError("%s [Stacktrace: %s]", nnew_str, st.c_str()); +} diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index aba1708232f..5c23616ac5c 100755 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -114,6 +114,7 @@ class Log void SetColor(bool stdout_stream, ColorTypes color); void ResetColor(bool stdout_stream); + void outErrorST( const char * err, ... ) ATTR_PRINTF(2, 3); void outDB( LogTypes type, const char * str ); void outString( const char * str, ... ) ATTR_PRINTF(2, 3); void outString( ); |
