From 03d29047377cba797a9503e2b16435505a918fa4 Mon Sep 17 00:00:00 2001 From: killerwife Date: Sun, 26 Feb 2023 22:51:26 +0100 Subject: [PATCH] Scripts: Implement targeting using stringId for spell_script_target and dbscripts --- src/game/DBScripts/ScriptMgr.cpp | 52 +++++++++-- src/game/DBScripts/ScriptMgr.h | 5 +- src/game/Entities/Creature.cpp | 6 +- src/game/Entities/GameObject.cpp | 2 +- src/game/Entities/Object.cpp | 5 ++ src/game/Entities/Object.h | 1 + src/game/Globals/ObjectMgr.cpp | 10 +-- src/game/Maps/Map.cpp | 6 +- src/game/Maps/Map.h | 6 +- src/game/Maps/MapDataContainer.cpp | 3 +- src/game/Spells/Spell.cpp | 140 +++++++++++++++++++---------- src/game/Spells/SpellMgr.cpp | 9 ++ src/game/Spells/SpellMgr.h | 5 +- 13 files changed, 180 insertions(+), 70 deletions(-) diff --git a/src/game/DBScripts/ScriptMgr.cpp b/src/game/DBScripts/ScriptMgr.cpp index 797a0b3412..cb67ee7b96 100644 --- a/src/game/DBScripts/ScriptMgr.cpp +++ b/src/game/DBScripts/ScriptMgr.cpp @@ -164,7 +164,7 @@ void ScriptMgr::LoadScripts(ScriptMapType scriptType) } // generic command args check - if (tmp.buddyEntry && !(tmp.data_flags & SCRIPT_FLAG_BUDDY_BY_GUID)) + if (tmp.buddyEntry && !(tmp.data_flags & SCRIPT_FLAG_BUDDY_BY_GUID) && (tmp.data_flags & SCRIPT_FLAG_BUDDY_BY_STRING_ID) == 0) { if (tmp.IsCreatureBuddy() && !ObjectMgr::GetCreatureTemplate(tmp.buddyEntry)) { @@ -207,7 +207,7 @@ void ScriptMgr::LoadScripts(ScriptMapType scriptType) CreatureData const* data = sObjectMgr.GetCreatureData(tmp.searchRadiusOrGuid); if (!data) { - sLog.outErrorDb("Table `%s` has buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but no npc spawned with guid %u, skipping.", tablename, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid); + sLog.outErrorDb("Table `%s` for script id %u has buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but no npc spawned with guid %u, skipping.", tablename, tmp.id, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid); continue; } } @@ -216,7 +216,7 @@ void ScriptMgr::LoadScripts(ScriptMapType scriptType) GameObjectData const* data = sObjectMgr.GetGOData(tmp.searchRadiusOrGuid); if (!data) { - sLog.outErrorDb("Table `%s` has go-buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but no go spawned with guid %u, skipping.", tablename, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid); + sLog.outErrorDb("Table `%s` for script id %u has go-buddy defined by guid (SCRIPT_FLAG_BUDDY_BY_GUID %u set) but no go spawned with guid %u, skipping.", tablename, tmp.id, SCRIPT_FLAG_BUDDY_BY_GUID, tmp.searchRadiusOrGuid); continue; } } @@ -228,7 +228,7 @@ void ScriptMgr::LoadScripts(ScriptMapType scriptType) auto pool = sPoolMgr.GetPoolCreatures(tmp.searchRadiusOrGuid); if (pool.isEmpty()) { - sLog.outErrorDb("Table `%s` has go-buddy defined by pool (SCRIPT_FLAG_BUDDY_BY_POOL %u set) but pool %u is empty, skipping.", tablename, tmp.data_flags, tmp.searchRadiusOrGuid); + sLog.outErrorDb("Table `%s` for script id %u has go-buddy defined by pool (SCRIPT_FLAG_BUDDY_BY_POOL %u set) but pool %u is empty, skipping.", tablename, tmp.id, tmp.data_flags, tmp.searchRadiusOrGuid); continue; } } @@ -237,7 +237,7 @@ void ScriptMgr::LoadScripts(ScriptMapType scriptType) auto pool = sPoolMgr.GetPoolGameObjects(tmp.searchRadiusOrGuid); if (pool.isEmpty()) { - sLog.outErrorDb("Table `%s` has go-buddy defined by pool (SCRIPT_FLAG_BUDDY_BY_POOL %u set) but pool %u is empty, skipping.", tablename, tmp.data_flags, tmp.searchRadiusOrGuid); + sLog.outErrorDb("Table `%s` for script id %u has go-buddy defined by pool (SCRIPT_FLAG_BUDDY_BY_POOL %u set) but pool %u is empty, skipping.", tablename, tmp.id, tmp.data_flags, tmp.searchRadiusOrGuid); continue; } } @@ -247,7 +247,16 @@ void ScriptMgr::LoadScripts(ScriptMapType scriptType) uint32 groupEntry = tmp.searchRadiusOrGuid; if (sObjectMgr.GetSpawnGroupContainer()->spawnGroupMap.find(groupEntry) == sObjectMgr.GetSpawnGroupContainer()->spawnGroupMap.end()) { - sLog.outErrorDb("Table `%s` has go-buddy defined by group (SCRIPT_FLAG_BUDDY_BY_SPAWN_GROUP %u set) but group %u is empty, skipping.", tablename, tmp.data_flags, tmp.searchRadiusOrGuid); + sLog.outErrorDb("Table `%s` for script id %u has go-buddy defined by group (SCRIPT_FLAG_BUDDY_BY_SPAWN_GROUP %u set) but group %u is empty, skipping.", tablename, tmp.id, tmp.data_flags, tmp.searchRadiusOrGuid); + continue; + } + } + else if (tmp.data_flags & SCRIPT_FLAG_BUDDY_BY_STRING_ID) + { + uint32 stringId = tmp.buddyEntry; + if (stringId && !sScriptMgr.ExistsStringId(stringId)) + { + sLog.outErrorDb("Table `%s` has buddy defined by stringId (SCRIPT_FLAG_BUDDY_BY_STRING_ID) but stringId does not exist, skipping.", tablename, tmp.id, stringId); continue; } } @@ -1430,6 +1439,37 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* originalSource, WorldObj buddies.push_back(closest); } } + else if (m_script->data_flags & SCRIPT_FLAG_BUDDY_BY_STRING_ID) + { + WorldObject* origin = originalSource ? originalSource : originalTarget; + if (origin->GetTypeId() == TYPEID_PLAYER && originalSource && originalSource->GetTypeId() != TYPEID_PLAYER) + origin = originalTarget; + auto worldObjects = m_map->GetWorldObjects(m_script->buddyEntry); + if (worldObjects == nullptr) + return false; + if ((m_script->data_flags & SCRIPT_FLAG_ALL_ELIGIBLE_BUDDIES) != 0) + { + for (WorldObject* wo : *worldObjects) + buddies.push_back(wo); + } + else + { + WorldObject* closest = nullptr; + for (WorldObject* wo : *worldObjects) + { + if (!closest) + closest = wo; + else if (origin->GetDistance(wo, true, DIST_CALC_NONE) < origin->GetDistance(closest, true, DIST_CALC_NONE)) + closest = wo; + } + if (closest) + buddies.push_back(closest); + } + if (m_script->searchRadiusOrGuid > 0) + for (WorldObject* buddy : buddies) + if (buddy->IsWithinDist(origin, m_script->searchRadiusOrGuid)) + buddies.erase(std::remove(buddies.begin(), buddies.end(), buddy), buddies.end()); + } else // Buddy by entry { if (!originalSource && !originalTarget) diff --git a/src/game/DBScripts/ScriptMgr.h b/src/game/DBScripts/ScriptMgr.h index 5045adb928..871ca66609 100644 --- a/src/game/DBScripts/ScriptMgr.h +++ b/src/game/DBScripts/ScriptMgr.h @@ -156,8 +156,9 @@ enum ScriptInfoDataFlags SCRIPT_FLAG_BUDDY_BY_SPAWN_GROUP = 0x100, // buddy is from spawn group SCRIPT_FLAG_ALL_ELIGIBLE_BUDDIES = 0x200, // multisource/multitarget - will execute for each eligible SCRIPT_FLAG_BUDDY_BY_GO = 0x400, // take the buddy by GO (for commands which can target both creature and GO) + SCRIPT_FLAG_BUDDY_BY_STRING_ID = 0x800, // takes buddy from string id - creature or go }; -#define MAX_SCRIPT_FLAG_VALID (2 * SCRIPT_FLAG_BUDDY_BY_GO - 1) +#define MAX_SCRIPT_FLAG_VALID (2 * SCRIPT_FLAG_BUDDY_BY_STRING_ID - 1) struct ScriptInfo { @@ -669,6 +670,8 @@ class ScriptMgr std::shared_ptr GetScriptMap(ScriptMapType scriptMapType); bool ExistsStringId(uint32 stringId); + std::shared_ptr GetStringIdMap() { return m_stringIds; } + std::shared_ptr GetStringIdByStringMap() { return m_stringIdsByString; } private: void LoadScripts(ScriptMapType scriptType); void CheckScriptTexts(ScriptMapType scriptType); diff --git a/src/game/Entities/Creature.cpp b/src/game/Entities/Creature.cpp index eca4422b00..3f069b3277 100644 --- a/src/game/Entities/Creature.cpp +++ b/src/game/Entities/Creature.cpp @@ -1627,10 +1627,12 @@ bool Creature::LoadFromDB(uint32 dbGuid, Map* map, uint32 newGuid, uint32 forced return false; if (groupEntry) + { SetCreatureGroup(group); - if (groupEntry->StringId) - SetStringId(groupEntry->StringId, true); + if (groupEntry->StringId) + SetStringId(groupEntry->StringId, true); + } SetRespawnCoord(pos); m_respawnradius = data->spawndist; diff --git a/src/game/Entities/GameObject.cpp b/src/game/Entities/GameObject.cpp index d9838a0369..665cbab4ef 100644 --- a/src/game/Entities/GameObject.cpp +++ b/src/game/Entities/GameObject.cpp @@ -907,7 +907,7 @@ bool GameObject::LoadFromDB(uint32 dbGuid, Map* map, uint32 newGuid, uint32 forc if (group) SetGameObjectGroup(group); - if (groupEntry->StringId) + if (groupEntry && groupEntry->StringId) SetStringId(groupEntry->StringId, true); if (!GetGOInfo()->GetDespawnPossibility() && !GetGOInfo()->IsDespawnAtAction() && data->spawntimesecsmin >= 0) diff --git a/src/game/Entities/Object.cpp b/src/game/Entities/Object.cpp index 52bbd2104e..3417fb6c6a 100644 --- a/src/game/Entities/Object.cpp +++ b/src/game/Entities/Object.cpp @@ -1217,6 +1217,11 @@ void WorldObject::RemoveStringId(std::string& stringId) SetStringId(stringIdId, false); } +bool WorldObject::HasStringId(uint32 stringId) +{ + return m_stringIds.find(stringId) != m_stringIds.end(); +} + WorldObject::WorldObject() : m_transport(nullptr), m_transportInfo(nullptr), m_isOnEventNotified(false), m_visibilityData(this), m_currMap(nullptr), diff --git a/src/game/Entities/Object.h b/src/game/Entities/Object.h index 03a7cf7fb7..1aad91253f 100644 --- a/src/game/Entities/Object.h +++ b/src/game/Entities/Object.h @@ -1212,6 +1212,7 @@ class WorldObject : public Object void AddStringId(std::string& stringId); void RemoveStringId(std::string& stringId); + bool HasStringId(uint32 stringId); protected: explicit WorldObject(); diff --git a/src/game/Globals/ObjectMgr.cpp b/src/game/Globals/ObjectMgr.cpp index 0960dc6f1b..e026733073 100644 --- a/src/game/Globals/ObjectMgr.cpp +++ b/src/game/Globals/ObjectMgr.cpp @@ -1157,9 +1157,9 @@ void ObjectMgr::LoadSpawnGroups() entry.Flags = fields[5].GetUInt32(); entry.StringId = fields[6].GetUInt32(); - if (!sScriptMgr.ExistsStringId(entry.StringId)) + if (entry.StringId && !sScriptMgr.ExistsStringId(entry.StringId)) { - sLog.outErrorDb("Table spawn_group entry %u stringId %u does not exist. Setting to 0.", entry, entry.StringId); + sLog.outErrorDb("Table spawn_group entry %u stringId %u does not exist. Setting to 0.", entry.Id, entry.StringId); entry.StringId = 0; } @@ -1861,7 +1861,7 @@ void ObjectMgr::LoadCreatureSpawnDataTemplates() uint32 relayId = fields[9].GetUInt32(); uint32 stringId = fields[10].GetUInt32(); - if (!sScriptMgr.ExistsStringId(stringId)) + if (stringId && !sScriptMgr.ExistsStringId(stringId)) { stringId = 0; sLog.outErrorDb("Table creature_spawn_data_template entry %u stringId %u does not exist. Setting to 0.", entry, stringId); @@ -2339,7 +2339,7 @@ void ObjectMgr::LoadGameObjects() sLog.outString(">> Loaded " SIZEFMTD " gameobjects", mGameObjectDataMap.size()); sLog.outString(); - result.reset(WorldDatabase.PQuery("SELECT guid, animprogress, state FROM gameobject_addon")); + result.reset(WorldDatabase.PQuery("SELECT guid, animprogress, state, stringId FROM gameobject_addon")); do { Field* fields = result->Fetch(); @@ -2360,7 +2360,7 @@ void ObjectMgr::LoadGameObjects() continue; } - if (!sScriptMgr.ExistsStringId(stringId)) + if (stringId && !sScriptMgr.ExistsStringId(stringId)) { stringId = 0; sLog.outErrorDb("Table gameobject_addon guid %u stringId %u does not exist. Setting to 0.", guid, stringId); diff --git a/src/game/Maps/Map.cpp b/src/game/Maps/Map.cpp index 5eb0b813c5..695a93bcc3 100644 --- a/src/game/Maps/Map.cpp +++ b/src/game/Maps/Map.cpp @@ -2218,17 +2218,17 @@ GameObject* Map::GetGameObject(uint32 dbguid) const return static_cast((*itr).second.front()); } -std::vector const* Map::GetWorldObjects(std::string& stringId) const +std::vector const* Map::GetWorldObjects(std::string stringId) const { return GetWorldObjects(GetMapDataContainer().GetStringId(stringId)); } -std::vector const* Map::GetCreatures(std::string& stringId) const +std::vector const* Map::GetCreatures(std::string stringId) const { return GetCreatures(GetMapDataContainer().GetStringId(stringId)); } -std::vector const* Map::GetGameObjects(std::string& stringId) const +std::vector const* Map::GetGameObjects(std::string stringId) const { return GetGameObjects(GetMapDataContainer().GetStringId(stringId)); } diff --git a/src/game/Maps/Map.h b/src/game/Maps/Map.h index 9d1d095287..3a96eecc39 100644 --- a/src/game/Maps/Map.h +++ b/src/game/Maps/Map.h @@ -287,9 +287,9 @@ class Map : public GridRefManager // dbguid methods Creature* GetCreature(uint32 dbguid) const; GameObject* GetGameObject(uint32 dbguid) const; - std::vector const* GetWorldObjects(std::string& stringId) const; - std::vector const* GetCreatures(std::string& stringId) const; - std::vector const* GetGameObjects(std::string& stringId) const; + std::vector const* GetWorldObjects(std::string stringId) const; + std::vector const* GetCreatures(std::string stringId) const; + std::vector const* GetGameObjects(std::string stringId) const; std::vector const* GetWorldObjects(uint32 stringId) const; std::vector const* GetCreatures(uint32 stringId) const; std::vector const* GetGameObjects(uint32 stringId) const; diff --git a/src/game/Maps/MapDataContainer.cpp b/src/game/Maps/MapDataContainer.cpp index 493e0c8125..95bc82ccbe 100644 --- a/src/game/Maps/MapDataContainer.cpp +++ b/src/game/Maps/MapDataContainer.cpp @@ -24,7 +24,8 @@ MapDataContainer::MapDataContainer() : m_spellListContainer(sObjectMgr.GetCreatureSpellListContainer()), m_spawnGroupContainer(sObjectMgr.GetSpawnGroupContainer()), m_CreatureEventAIEventEntryMap(sEventAIMgr.GetCreatureEventEntryAIMap()), - m_CreatureEventAIEventGuidMap(sEventAIMgr.GetCreatureEventGuidAIMap()), m_creatureEventAIComputedDataMap(sEventAIMgr.GetEAIComputedDataMap()) + m_CreatureEventAIEventGuidMap(sEventAIMgr.GetCreatureEventGuidAIMap()), m_creatureEventAIComputedDataMap(sEventAIMgr.GetEAIComputedDataMap()), + m_stringIds(sScriptMgr.GetStringIdMap()), m_stringIdsByString(sScriptMgr.GetStringIdByStringMap()) { for (uint32 i = 0; i < SCRIPT_TYPE_MAX; ++i) SetScriptMap(ScriptMapType(i), sScriptMgr.GetScriptMap(ScriptMapType(i))); diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index 8c35f9e25c..8ce2c4187b 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -2853,20 +2853,7 @@ SpellCastResult Spell::CheckScriptTargeting(SpellEffectIndex effIndex, uint32 ch MaNGOS::GameObjectListSearcher checker(foundScriptGOTargets, go_check); Cell::VisitGridObjects(m_trueCaster, checker, radius); } - for (auto itr = foundScriptGOTargets.begin(); itr != foundScriptGOTargets.end();) - { - if (!OnCheckTarget(*itr, effIndex)) - itr = foundScriptGOTargets.erase(itr); - else - ++itr; - } - foundScriptGOTargets.sort([=](const GameObject* a, const GameObject* b) -> bool - { - return caster->GetDistance(a, true, DIST_CALC_NONE) < caster->GetDistance(b, true, DIST_CALC_NONE); - }); - if (foundScriptGOTargets.size() > targetCount) // if we have too many targets, we need to trim the list - foundScriptGOTargets.resize(targetCount); break; } case SPELL_TARGET_TYPE_CREATURE: @@ -2903,26 +2890,29 @@ SpellCastResult Spell::CheckScriptTargeting(SpellEffectIndex effIndex, uint32 ch if (u_check.FoundOutOfRange()) foundButOutOfRange = true; } - for (auto iter = foundScriptCreatureTargets.begin(); iter != foundScriptCreatureTargets.end();) + } + break; + } + case SPELL_TARGET_TYPE_STRING_ID: + { + for (uint32 stringId : entriesToUse) + { + auto creatures = m_trueCaster->GetMap()->GetCreatures(stringId); + for (Creature* creature : *creatures) { - bool failed = false; - if (!OnCheckTarget(*iter, effIndex)) - failed = true; - else if (m_spellInfo->HasAttribute(SPELL_ATTR_EX_EXCLUDE_CASTER) && m_trueCaster == (*iter)) - failed = true; - if (failed) - iter = foundScriptCreatureTargets.erase(iter); + if (creature->IsWithinCombatDistInMap(caster, radius, true)) + foundScriptCreatureTargets.push_back(creature); else - ++iter; + foundButOutOfRange = true; } - - foundScriptCreatureTargets.sort([=](const Creature* a, const Creature* b) -> bool + auto gameObjects = m_trueCaster->GetMap()->GetGameObjects(stringId); + for (GameObject* gameObject : *gameObjects) { - return caster->GetDistance(a, true, DIST_CALC_NONE) < caster->GetDistance(b, true, DIST_CALC_NONE); - }); - - if (foundScriptCreatureTargets.size() > targetCount) // if we have too many targets, we need to trim the list - foundScriptCreatureTargets.resize(targetCount); + if (gameObject->IsWithinDist(caster, radius, true)) + foundScriptGOTargets.push_back(gameObject); + else + foundButOutOfRange = true; + } } break; } @@ -2930,6 +2920,48 @@ SpellCastResult Spell::CheckScriptTargeting(SpellEffectIndex effIndex, uint32 ch break; } + if (!foundScriptCreatureTargets.empty()) + { + for (auto iter = foundScriptCreatureTargets.begin(); iter != foundScriptCreatureTargets.end();) + { + bool failed = false; + if (!OnCheckTarget(*iter, effIndex)) + failed = true; + else if (m_spellInfo->HasAttribute(SPELL_ATTR_EX_EXCLUDE_CASTER) && m_trueCaster == (*iter)) + failed = true; + if (failed) + iter = foundScriptCreatureTargets.erase(iter); + else + ++iter; + } + + foundScriptCreatureTargets.sort([=](const Creature* a, const Creature* b) -> bool + { + return caster->GetDistance(a, true, DIST_CALC_NONE) < caster->GetDistance(b, true, DIST_CALC_NONE); + }); + + if (foundScriptCreatureTargets.size() > targetCount) // if we have too many targets, we need to trim the list + foundScriptCreatureTargets.resize(targetCount); + } + + if (!foundScriptGOTargets.empty()) + { + for (auto itr = foundScriptGOTargets.begin(); itr != foundScriptGOTargets.end();) + { + if (!OnCheckTarget(*itr, effIndex)) + itr = foundScriptGOTargets.erase(itr); + else + ++itr; + } + foundScriptGOTargets.sort([=](const GameObject* a, const GameObject* b) -> bool + { + return caster->GetDistance(a, true, DIST_CALC_NONE) < caster->GetDistance(b, true, DIST_CALC_NONE); + }); + + if (foundScriptGOTargets.size() > targetCount) // if we have too many targets, we need to trim the list + foundScriptGOTargets.resize(targetCount); + } + if (!foundScriptCreatureTargets.empty()) { // store coordinates for TARGET_LOCATION_SCRIPT_NEAR_CASTER @@ -2988,26 +3020,42 @@ void Spell::CheckSpellScriptTargets(SQLMultiStorage::SQLMSIteratorBoundstype == SPELL_TARGET_TYPE_GAMEOBJECT || spellST->type == SPELL_TARGET_TYPE_GAMEOBJECT_GUID) continue; - if (spellST->type == SPELL_TARGET_TYPE_CREATURE_GUID ? target->GetDbGuid() == spellST->targetEntry : target->GetEntry() == spellST->targetEntry) + bool fail = false; + switch (spellST->type) { - switch (spellST->type) - { - case SPELL_TARGET_TYPE_DEAD: - if (static_cast(target)->IsCorpse()) - targetUnitMap.push_back(target); - break; - case SPELL_TARGET_TYPE_CREATURE: - if (target->IsAlive()) - targetUnitMap.push_back(target); - break; - case SPELL_TARGET_TYPE_CREATURE_GUID: + case SPELL_TARGET_TYPE_CREATURE_GUID: + fail = target->GetDbGuid() != spellST->targetEntry; + break; + case SPELL_TARGET_TYPE_STRING_ID: + break; + default: + fail = target->GetEntry() != spellST->targetEntry; + break; + } + if (fail) + continue; + + switch (spellST->type) + { + case SPELL_TARGET_TYPE_DEAD: + if (static_cast(target)->IsCorpse()) targetUnitMap.push_back(target); - break; - default: - break; - } - break; + break; + case SPELL_TARGET_TYPE_CREATURE: + if (target->IsAlive()) + targetUnitMap.push_back(target); + break; + case SPELL_TARGET_TYPE_CREATURE_GUID: + targetUnitMap.push_back(target); + break; + case SPELL_TARGET_TYPE_STRING_ID: + if (target->HasStringId(spellST->targetEntry)) + targetUnitMap.push_back(target); + break; + default: + break; } + break; } } } diff --git a/src/game/Spells/SpellMgr.cpp b/src/game/Spells/SpellMgr.cpp index 3fad137a76..bbc2bbd57c 100644 --- a/src/game/Spells/SpellMgr.cpp +++ b/src/game/Spells/SpellMgr.cpp @@ -2144,6 +2144,15 @@ void SpellMgr::LoadSpellScriptTarget() } break; } + case SPELL_TARGET_TYPE_STRING_ID: + { + if (!sScriptMgr.ExistsStringId(itr->targetEntry)) + { + sLog.outErrorDb("Table `spell_script_target`: stringId %u does not exist.", itr->targetEntry); + sSpellScriptTargetStorage.EraseEntry(itr->spellId); + } + break; + } default: if (!itr->targetEntry) { diff --git a/src/game/Spells/SpellMgr.h b/src/game/Spells/SpellMgr.h index 088a6231fb..a4490b1930 100644 --- a/src/game/Spells/SpellMgr.h +++ b/src/game/Spells/SpellMgr.h @@ -2505,8 +2505,9 @@ enum SpellTargetType SPELL_TARGET_TYPE_GAMEOBJECT = 0, SPELL_TARGET_TYPE_CREATURE = 1, SPELL_TARGET_TYPE_DEAD = 2, - SPELL_TARGET_TYPE_CREATURE_GUID = 3, - SPELL_TARGET_TYPE_GAMEOBJECT_GUID = 4, // works only for global fetch spells + SPELL_TARGET_TYPE_CREATURE_GUID = 3, // obsolete - use string id instead + SPELL_TARGET_TYPE_GAMEOBJECT_GUID = 4, // obsolete - use string id instead + SPELL_TARGET_TYPE_STRING_ID = 5, }; #define MAX_SPELL_TARGET_TYPE 5