diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 124 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 20 |
2 files changed, 88 insertions, 56 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 74d2d5c49a1..3835220b453 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -107,6 +107,8 @@ SmartWaypointMgr::~SmartWaypointMgr() void SmartAIMgr::LoadSmartAIFromDB() { + LoadHelperStores(); + uint32 oldMSTime = getMSTime(); for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; i++) @@ -118,7 +120,6 @@ void SmartAIMgr::LoadSmartAIFromDB() if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 SmartAI scripts. DB table `smartai_scripts` is empty."); - return; } @@ -236,6 +237,7 @@ void SmartAIMgr::LoadSmartAIFromDB() TC_LOG_INFO("server.loading", ">> Loaded %u SmartAI scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + UnLoadHelperStores(); } bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) @@ -769,27 +771,14 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; } case SMART_ACTION_SUMMON_CREATURE: + { if (!IsCreatureValid(e, e.action.summonCreature.creature)) return false; - for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i); - if (!spellInfo) - continue; - - for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (spellInfo->Effects[j].Effect == SPELL_EFFECT_SUMMON) - { - uint32 creatureSummonEntry = spellInfo->Effects[j].MiscValue; - - if (e.action.summonCreature.creature == creatureSummonEntry) - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u creature summon: There is a summon spell for creature entry %u (SpellId: %u, effect: %u)", - e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.summonCreature.creature, spellInfo->Id, j); - } - } - } + CacheSpellContainerBounds sBounds = GetSummonCreatureSpellContainerBounds(e.action.summonCreature.creature); + for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr) + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u creature summon: There is a summon spell for creature entry %u (SpellId: %u, effect: %u)", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.summonCreature.creature, itr->second.first, itr->second.second); if (e.action.summonCreature.type < TEMPSUMMON_TIMED_OR_DEAD_DESPAWN || e.action.summonCreature.type > TEMPSUMMON_MANUAL_DESPAWN) { @@ -797,27 +786,16 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } break; + } case SMART_ACTION_CALL_KILLEDMONSTER: + { if (!IsCreatureValid(e, e.action.killedMonster.creature)) return false; - for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i); - if (!spellInfo) - continue; - - for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (spellInfo->Effects[j].Effect == SPELL_EFFECT_KILL_CREDIT || spellInfo->Effects[j].Effect == SPELL_EFFECT_KILL_CREDIT2) - { - uint32 killCredit = spellInfo->Effects[j].MiscValue; - - if (e.action.killedMonster.creature == killCredit) - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Kill Credit: %u has already spell kill credit (SpellId: %u effect: %u)", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.killedMonster.creature, spellInfo->Id, j); - } - } - } + CacheSpellContainerBounds sBounds = GetKillCreditSpellContainerBounds(e.action.killedMonster.creature); + for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr) + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Kill Credit: There is a killcredit spell for creatureEntry %u (SpellId: %u effect: %u)", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.killedMonster.creature, itr->second.first, itr->second.second); if (e.GetTargetType() == SMART_TARGET_POSITION) { @@ -825,6 +803,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } break; + } case SMART_ACTION_UPDATE_TEMPLATE: if (e.action.updateTemplate.creature && !IsCreatureValid(e, e.action.updateTemplate.creature)) return false; @@ -846,28 +825,16 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; } case SMART_ACTION_SUMMON_GO: + { if (!IsGameObjectValid(e, e.action.summonGO.entry)) return false; - for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i); - if (!spellInfo) - continue; - - for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (spellInfo->Effects[j].Effect == SPELL_EFFECT_SUMMON_OBJECT_WILD) - { - uint32 goSummonEntry = spellInfo->Effects[j].MiscValue; - - if (e.action.summonGO.entry == goSummonEntry) - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u gameobject summon: There is a summon spell for gameobject entry %u (SpellId: %u, effect: %u)", - e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.summonGO.entry, spellInfo->Id, j); - } - } - } + CacheSpellContainerBounds sBounds = GetSummonGameObjectSpellContainerBounds(e.action.summonGO.entry); + for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr) + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u gameobject summon: There is a summon spell for gameobject entry %u (SpellId: %u, effect: %u)", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.summonGO.entry, itr->second.first, itr->second.second); break; + } case SMART_ACTION_ADD_ITEM: case SMART_ACTION_REMOVE_ITEM: if (!IsItemValid(e, e.action.item.entry)) @@ -1073,3 +1040,52 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } return true; }*/ + +void SmartAIMgr::LoadHelperStores() +{ + uint32 oldMSTime = getMSTime(); + + SpellInfo const* spellInfo = NULL; + for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) + { + spellInfo = sSpellMgr->GetSpellInfo(i); + if (!spellInfo) + continue; + + for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) + { + if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_SUMMON)) + SummonCreatureSpellStore.insert(std::make_pair(uint32(spellInfo->Effects[j].MiscValue), std::make_pair(i, SpellEffIndex(j)))); + + else if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_SUMMON_OBJECT_WILD)) + SummonGameObjectSpellStore.insert(std::make_pair(uint32(spellInfo->Effects[j].MiscValue), std::make_pair(i, SpellEffIndex(j)))); + + else if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2)) + KillCreditSpellStore.insert(std::make_pair(uint32(spellInfo->Effects[j].MiscValue), std::make_pair(i, SpellEffIndex(j)))); + } + } + + TC_LOG_INFO("server.loading", ">> Loaded SmartAIMgr Helpers in %u ms", GetMSTimeDiffToNow(oldMSTime)); +} + +void SmartAIMgr::UnLoadHelperStores() +{ + SummonCreatureSpellStore.clear(); + SummonGameObjectSpellStore.clear(); + KillCreditSpellStore.clear(); +} + +CacheSpellContainerBounds SmartAIMgr::GetSummonCreatureSpellContainerBounds(uint32 creatureEntry) const +{ + return SummonCreatureSpellStore.equal_range(creatureEntry); +} + +CacheSpellContainerBounds SmartAIMgr::GetSummonGameObjectSpellContainerBounds(uint32 gameObjectEntry) const +{ + return SummonGameObjectSpellStore.equal_range(gameObjectEntry); +} + +CacheSpellContainerBounds SmartAIMgr::GetKillCreditSpellContainerBounds(uint32 killCredit) const +{ + return KillCreditSpellStore.equal_range(killCredit); +} diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index d6bf318b8ac..2e5b3d3626f 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1345,12 +1345,16 @@ typedef std::vector<SmartScriptHolder> SmartAIEventList; // all events for all entries / guids typedef UNORDERED_MAP<int32, SmartAIEventList> SmartAIEventMap; +// Helper Stores +typedef std::map<uint32 /*entry*/, std::pair<uint32 /*spellId*/, SpellEffIndex /*effIndex*/> > CacheSpellContainer; +typedef std::pair<CacheSpellContainer::const_iterator, CacheSpellContainer::const_iterator> CacheSpellContainerBounds; + class SmartAIMgr { friend class ACE_Singleton<SmartAIMgr, ACE_Null_Mutex>; - SmartAIMgr(){ } + SmartAIMgr() { } public: - ~SmartAIMgr(){ } + ~SmartAIMgr() { } void LoadSmartAIFromDB(); @@ -1505,6 +1509,18 @@ class SmartAIMgr } //bool IsTextValid(SmartScriptHolder const& e, uint32 id); + + // Helpers + void LoadHelperStores(); + void UnLoadHelperStores(); + + CacheSpellContainerBounds GetSummonCreatureSpellContainerBounds(uint32 creatureEntry) const; + CacheSpellContainerBounds GetSummonGameObjectSpellContainerBounds(uint32 gameObjectEntry) const; + CacheSpellContainerBounds GetKillCreditSpellContainerBounds(uint32 killCredit) const; + + CacheSpellContainer SummonCreatureSpellStore; + CacheSpellContainer SummonGameObjectSpellStore; + CacheSpellContainer KillCreditSpellStore; }; #define sSmartScriptMgr ACE_Singleton<SmartAIMgr, ACE_Null_Mutex>::instance() |