aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQAston <none@none>2010-10-04 19:12:20 +0200
committerQAston <none@none>2010-10-04 19:12:20 +0200
commit69057dcaeb27daaa7bb1ecb06c22103b0a168e28 (patch)
treed7be8e8de24342a1cee33007eeea1b3faf0ca684 /src
parentcaaa77deb285d65b1bc3a0c6f7b5f88ec3508d0c (diff)
Core/ScriptSystem/SpellScripts: Runtime checks for functions working only during spell hit phase
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Spells/Spell.cpp136
-rw-r--r--src/server/game/Spells/SpellScript.cpp70
-rw-r--r--src/server/game/Spells/SpellScript.h18
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,