diff options
author | QAston <none@none> | 2010-10-04 19:12:20 +0200 |
---|---|---|
committer | QAston <none@none> | 2010-10-04 19:12:20 +0200 |
commit | 69057dcaeb27daaa7bb1ecb06c22103b0a168e28 (patch) | |
tree | d7be8e8de24342a1cee33007eeea1b3faf0ca684 | |
parent | caaa77deb285d65b1bc3a0c6f7b5f88ec3508d0c (diff) |
Core/ScriptSystem/SpellScripts: Runtime checks for functions working only during spell hit phase
--HG--
branch : trunk
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 136 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.cpp | 70 | ||||
-rw-r--r-- | src/server/game/Spells/SpellScript.h | 18 |
3 files changed, 87 insertions, 137 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 861cc57dc01..15b1b2069c0 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4857,7 +4857,6 @@ SpellCastResult Spell::CheckCast(bool strict) } else if (m_caster == target) { - if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster { // Additional check for some spells @@ -5005,141 +5004,6 @@ SpellCastResult Spell::CheckCast(bool strict) return castResult; } - /*//ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38 - if (m_UniqueTargetInfo.empty()) // skip second CheckCast apply (for delayed spells for example) - { - for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_NEARBY_ENTRY || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_UNIT_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetA[j] != TARGET_UNIT_CASTER || - m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY) - { - SpellScriptTarget::const_iterator lower = sSpellMgr.GetBeginSpellScriptTarget(m_spellInfo->Id); - SpellScriptTarget::const_iterator upper = sSpellMgr.GetEndSpellScriptTarget(m_spellInfo->Id); - if (lower == upper) - sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_UNIT_NEARBY_ENTRY or TARGET_DST_NEARBY_ENTRY, but does not have record in `spell_script_target`",m_spellInfo->Id); - - SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex); - float range = GetSpellMaxRange(srange); - - Creature* creatureScriptTarget = NULL; - GameObject* goScriptTarget = NULL; - - for (SpellScriptTarget::const_iterator i_spellST = bounds.first; i_spellST != bounds.second; ++i_spellST) - { - switch(i_spellST->second.type) - { - case SPELL_TARGET_TYPE_GAMEOBJECT: - { - GameObject* p_GameObject = NULL; - - if (i_spellST->second.targetEntry) - { - CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - - Trinity::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster,i_spellST->second.targetEntry,range); - Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck> checker(m_caster, p_GameObject,go_check); - - TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker); - CellLock<GridReadGuard> cell_lock(cell, p); - cell_lock->Visit(cell_lock, object_checker, *m_caster->GetMap()); - - if (p_GameObject) - { - // remember found target and range, next attempt will find more near target with another entry - creatureScriptTarget = NULL; - goScriptTarget = p_GameObject; - range = go_check.GetLastRange(); - } - } - else if (focusObject) // Focus Object - { - float frange = m_caster->GetDistance(focusObject); - if (range >= frange) - { - creatureScriptTarget = NULL; - goScriptTarget = focusObject; - range = frange; - } - } - break; - } - case SPELL_TARGET_TYPE_CREATURE: - case SPELL_TARGET_TYPE_DEAD: - default: - { - Creature *p_Creature = NULL; - - CellPair p(Trinity::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY())); - Cell cell(p); - cell.data.Part.reserved = ALL_DISTRICT; - cell.SetNoCreate(); // Really don't know what is that??? - - Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type != SPELL_TARGET_TYPE_DEAD,range); - Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, p_Creature, u_check); - - TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher); - - CellLock<GridReadGuard> cell_lock(cell, p); - cell_lock->Visit(cell_lock, grid_creature_searcher, *m_caster->GetMap(), *m_caster, range); - - if (p_Creature) - { - creatureScriptTarget = p_Creature; - goScriptTarget = NULL; - range = u_check.GetLastRange(); - } - break; - } - } - } - - if (creatureScriptTarget) - { - // store coordinates for TARGET_DST_NEARBY_ENTRY - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY) - { - m_targets.setDst(creatureScriptTarget->GetPositionX(),creatureScriptTarget->GetPositionY(),creatureScriptTarget->GetPositionZ()); - - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j] != SPELL_EFFECT_PERSISTENT_AREA_AURA) - AddUnitTarget(creatureScriptTarget, j); - } - // store explicit target for TARGET_UNIT_NEARBY_ENTRY - else - AddUnitTarget(creatureScriptTarget, j); - } - else if (goScriptTarget) - { - // store coordinates for TARGET_DST_NEARBY_ENTRY - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY || - m_spellInfo->EffectImplicitTargetB[j] == TARGET_DST_NEARBY_ENTRY) - { - m_targets.setDst(goScriptTarget->GetPositionX(),goScriptTarget->GetPositionY(),goScriptTarget->GetPositionZ()); - - if (m_spellInfo->EffectImplicitTargetA[j] == TARGET_DST_NEARBY_ENTRY && m_spellInfo->EffectImplicitTargetB[j] == 0 && m_spellInfo->Effect[j] != SPELL_EFFECT_PERSISTENT_AREA_AURA) - AddGOTarget(goScriptTarget, j); - } - // store explicit target for TARGET_UNIT_NEARBY_ENTRY - else - AddGOTarget(goScriptTarget, j); - } - //Missing DB Entry or targets for this spellEffect. - else - { - // not report target not existence for triggered spells - if (m_triggeredByAuraSpell || m_IsTriggeredSpell) - return SPELL_FAILED_DONT_REPORT; - else - return SPELL_FAILED_BAD_TARGETS; - } - } - } - }*/ - if (!m_IsTriggeredSpell) { SpellCastResult castResult = CheckRange(strict); diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index b79e6b28399..94adbeb5f2b 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -219,11 +219,21 @@ WorldLocation * SpellScript::GetDest() Unit * SpellScript::GetHitUnit() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitUnit was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } return m_spell->unitTarget; } Creature * SpellScript::GetHitCreature() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitCreature was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } if (m_spell->unitTarget) return m_spell->unitTarget->ToCreature(); else @@ -232,6 +242,11 @@ Creature * SpellScript::GetHitCreature() Player * SpellScript::GetHitPlayer() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitPlayer was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } if (m_spell->unitTarget) return m_spell->unitTarget->ToPlayer(); else @@ -240,36 +255,71 @@ Player * SpellScript::GetHitPlayer() Item * SpellScript::GetHitItem() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitItem was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } return m_spell->itemTarget; } GameObject * SpellScript::GetHitGObj() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } return m_spell->gameObjTarget; } int32 SpellScript::GetHitDamage() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitDamage was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } return m_spell->m_damage; } void SpellScript::SetHitDamage(int32 damage) { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::SetHitDamage was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return; + } m_spell->m_damage = damage; } int32 SpellScript::GetHitHeal() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitHeal was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } return m_spell->m_healing; } void SpellScript::SetHitHeal(int32 heal) { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::SetHitHeal was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return; + } m_spell->m_healing = heal; } Aura* SpellScript::GetHitAura() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitAura was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return NULL; + } if (!m_spell->m_spellAura) return NULL; if (m_spell->m_spellAura->IsRemoved()) @@ -279,23 +329,43 @@ Aura* SpellScript::GetHitAura() void SpellScript::PreventHitAura() { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitAura was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return; + } if (m_spell->m_spellAura) m_spell->m_spellAura->Remove(); } void SpellScript::PreventHitEffect(SpellEffIndex effIndex) { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitEffect was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return; + } m_hitPreventEffectMask |= 1 << effIndex; PreventHitDefaultEffect(effIndex); } void SpellScript::PreventHitDefaultEffect(SpellEffIndex effIndex) { + if (!IsInHitPhase()) + { + sLog.outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::PreventHitDefaultEffect was called while spell not in hit phase!", m_scriptName, m_scriptSpellId); + return; + } m_hitPreventDefaultEffectMask |= 1 << effIndex; } 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, 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 f152fe28e98..c33c2471a45 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -113,6 +113,20 @@ class _SpellScript virtual void Unload() {}; }; +// SpellScript interface - enum used for runtime checks of script function calls +enum SpellScriptHookType +{ + SPELL_SCRIPT_HOOK_EFFECT = SPELL_SCRIPT_STATE_END, + SPELL_SCRIPT_HOOK_BEFORE_HIT, + SPELL_SCRIPT_HOOK_HIT, + SPELL_SCRIPT_HOOK_AFTER_HIT, +}; +#define HOOK_SPELL_HIT_START SPELL_SCRIPT_HOOK_EFFECT +#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_AFTER_HIT + 1 +#define HOOK_SPELL_COUNT HOOK_SPELL_END - HOOK_SPELL_START + class SpellScript : public _SpellScript { // internal use classes & functions @@ -138,6 +152,8 @@ class SpellScript : public _SpellScript void _InitHit(); bool _IsEffectPrevented(SpellEffIndex effIndex) {return m_hitPreventEffectMask & (1<<effIndex);}; bool _IsDefaultEffectPrevented(SpellEffIndex effIndex) {return m_hitPreventDefaultEffectMask & (1<<effIndex);}; + bool IsInHitPhase() { return (m_currentScriptState >= HOOK_SPELL_HIT_START && m_currentScriptState < HOOK_SPELL_HIT_END); }; + bool IsInEffectHook() { return (m_currentScriptState == SPELL_SCRIPT_HOOK_EFFECT); }; private: Spell * m_spell; uint8 m_hitPreventEffectMask; @@ -226,7 +242,7 @@ class SpellScript : public _SpellScript void CreateItem(uint32 effIndex, uint32 itemId); }; -// AuraScript interface - enum used for manipulations on hooks by their type +// AuraScript interface - enum used for runtime checks of script function calls enum AuraScriptHookType { AURA_SCRIPT_HOOK_EFFECT_APPLY = SPELL_SCRIPT_STATE_END, |