diff options
Diffstat (limited to 'src/server/game/AI/SmartScripts')
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 15 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.h | 11 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 227 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 228 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 206 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 218 |
6 files changed, 471 insertions, 434 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 6d27b39ea40..18ea269fbb0 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -15,15 +15,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "DatabaseEnv.h" -#include "ObjectMgr.h" -#include "ObjectDefines.h" -#include "GridDefines.h" -#include "GridNotifiers.h" -#include "SpellMgr.h" -#include "Cell.h" -#include "Group.h" #include "SmartAI.h" +#include "Creature.h" +#include "GameObject.h" +#include "Group.h" +#include "Log.h" +#include "ObjectAccessor.h" +#include "PetDefines.h" +#include "Player.h" #include "ScriptMgr.h" SmartAI::SmartAI(Creature* c) : CreatureAI(c) diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 92793c17e58..c93bf046007 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -18,15 +18,12 @@ #ifndef TRINITY_SMARTAI_H #define TRINITY_SMARTAI_H -#include "Common.h" -#include "Creature.h" +#include "Define.h" #include "CreatureAI.h" -#include "Unit.h" -#include "Spell.h" - -#include "SmartScript.h" -#include "SmartScriptMgr.h" #include "GameObjectAI.h" +#include "SmartScript.h" + +struct WayPoint; enum SmartEscortState { diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index b3dfb149562..22597d36fab 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -15,27 +15,25 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Cell.h" +#include "SmartScript.h" #include "CellImpl.h" #include "ChatTextBuilder.h" +#include "Creature.h" #include "CreatureTextMgr.h" -#include "DatabaseEnv.h" -#include "GossipDef.h" -#include "GridDefines.h" -#include "GridNotifiers.h" +#include "GameEventMgr.h" +#include "GameObject.h" #include "GridNotifiersImpl.h" -#include "Group.h" #include "InstanceScript.h" #include "Language.h" -#include "ObjectDefines.h" -#include "ObjectMgr.h" +#include "Log.h" +#include "Map.h" +#include "ObjectAccessor.h" +#include "Random.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "SmartAI.h" -#include "SmartScript.h" -#include "SpellMgr.h" +#include "SpellAuras.h" #include "Vehicle.h" -#include "GameEventMgr.h" SmartScript::SmartScript() { @@ -64,6 +62,113 @@ SmartScript::~SmartScript() mCounterList.clear(); } +bool SmartScript::IsSmart(Creature* c /*= NULL*/) +{ + bool smart = true; + if (c && c->GetAIName() != "SmartAI") + smart = false; + + if (!me || me->GetAIName() != "SmartAI") + smart = false; + + if (!smart) + TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: " UI64FMTD " Entry: %u) is not using SmartAI, action called by Creature (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(c ? c->GetSpawnId() : UI64LIT(0)), c ? c->GetEntry() : 0, uint64(me ? me->GetSpawnId() : UI64LIT(0)), me ? me->GetEntry() : 0); + + return smart; +} + +bool SmartScript::IsSmartGO(GameObject* g /*= NULL*/) +{ + bool smart = true; + if (g && g->GetAIName() != "SmartGameObjectAI") + smart = false; + + if (!go || go->GetAIName() != "SmartGameObjectAI") + smart = false; + if (!smart) + TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: " UI64FMTD " Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(g ? g->GetSpawnId() : UI64LIT(0)), g ? g->GetEntry() : 0, uint64(go ? go->GetSpawnId() : UI64LIT(0)), go ? go->GetEntry() : 0); + + return smart; +} + +void SmartScript::StoreTargetList(ObjectList* targets, uint32 id) +{ + if (!targets) + return; + + if (mTargetStorage->find(id) != mTargetStorage->end()) + { + // check if already stored + if ((*mTargetStorage)[id]->Equals(targets)) + return; + + delete (*mTargetStorage)[id]; + } + + (*mTargetStorage)[id] = new ObjectGuidList(targets, GetBaseObject()); +} + +ObjectList* SmartScript::GetTargetList(uint32 id) +{ + ObjectListMap::iterator itr = mTargetStorage->find(id); + if (itr != mTargetStorage->end()) + return (*itr).second->GetObjectList(); + return NULL; +} + +void SmartScript::StoreCounter(uint32 id, uint32 value, uint32 reset) +{ + CounterMap::const_iterator itr = mCounterList.find(id); + if (itr != mCounterList.end()) + { + if (reset == 0) + value += GetCounterValue(id); + mCounterList.erase(id); + } + + mCounterList.insert(std::make_pair(id, value)); + ProcessEventsFor(SMART_EVENT_COUNTER_SET); +} + +uint32 SmartScript::GetCounterId(uint32 id) +{ + CounterMap::iterator itr = mCounterList.find(id); + if (itr != mCounterList.end()) + return itr->first; + return 0; +} + +uint32 SmartScript::GetCounterValue(uint32 id) +{ + CounterMap::iterator itr = mCounterList.find(id); + if (itr != mCounterList.end()) + return itr->second; + return 0; +} + +GameObject* SmartScript::FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const +{ + auto bounds = searchObject->GetMap()->GetGameObjectBySpawnIdStore().equal_range(guid); + if (bounds.first == bounds.second) + return nullptr; + + return bounds.first->second; +} + +Creature* SmartScript::FindCreatureNear(WorldObject* searchObject, ObjectGuid::LowType guid) const +{ + auto bounds = searchObject->GetMap()->GetCreatureBySpawnIdStore().equal_range(guid); + if (bounds.first == bounds.second) + return nullptr; + + auto creatureItr = std::find_if(bounds.first, bounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair) + { + return pair.second->IsAlive(); + }); + + return creatureItr != bounds.second ? creatureItr->second : bounds.first->second; +} + void SmartScript::OnReset() { SetPhase(0); @@ -81,6 +186,35 @@ void SmartScript::OnReset() mCounterList.clear(); } +void SmartScript::ResetBaseObject() +{ + WorldObject* lookupRoot = me; + if (!lookupRoot) + lookupRoot = go; + + if (lookupRoot) + { + if (!meOrigGUID.IsEmpty()) + { + if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID)) + { + me = m; + go = NULL; + } + } + if (!goOrigGUID.IsEmpty()) + { + if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID)) + { + me = NULL; + go = o; + } + } + } + goOrigGUID.Clear(); + meOrigGUID.Clear(); +} + void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob, std::string const& varString) { for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i) @@ -1814,7 +1948,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } case SMART_ACTION_CROSS_CAST: { - ObjectList* casters = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit); + ObjectList* casters = GetTargets(CreateSmartEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit); if (!casters) break; @@ -2395,7 +2529,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u case SMART_ACTION_RANDOM_SOUND: { std::vector<uint32> sounds; - std::copy_if(e.action.randomSound.sounds.begin(), e.action.randomSound.sounds.end(), + std::copy_if(std::begin(e.action.randomSound.sounds), std::end(e.action.randomSound.sounds), std::back_inserter(sounds), [](uint32 sound) { return sound != 0; }); bool onlySelf = e.action.randomSound.onlySelf != 0; @@ -2597,10 +2731,10 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e) void SmartScript::AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask) { - mInstallEvents.push_back(CreateEvent(e, event_flags, event_param1, event_param2, event_param3, event_param4, action, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, t, target_param1, target_param2, target_param3, phaseMask)); + mInstallEvents.push_back(CreateSmartEvent(e, event_flags, event_param1, event_param2, event_param3, event_param4, action, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, t, target_param1, target_param2, target_param3, phaseMask)); } -SmartScriptHolder SmartScript::CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask) +SmartScriptHolder SmartScript::CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask) { SmartScriptHolder script; script.event.type = e; @@ -3637,6 +3771,69 @@ void SmartScript::InstallEvents() } } +void SmartScript::RemoveStoredEvent(uint32 id) +{ + if (!mStoredEvents.empty()) + { + for (SmartAIEventList::iterator i = mStoredEvents.begin(); i != mStoredEvents.end(); ++i) + { + if (i->event_id == id) + { + mStoredEvents.erase(i); + return; + } + } + } +} + +WorldObject* SmartScript::GetBaseObject() +{ + WorldObject* obj = nullptr; + if (me) + obj = me; + else if (go) + obj = go; + return obj; +} + +WorldObject* SmartScript::GetBaseObjectOrUnit(Unit* unit) +{ + WorldObject* summoner = GetBaseObject(); + + if (!summoner && unit) + return unit; + + return summoner; +} + +bool SmartScript::IsUnit(WorldObject* obj) +{ + return obj && (obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_PLAYER); +} + +bool SmartScript::IsPlayer(WorldObject* obj) +{ + return obj && obj->GetTypeId() == TYPEID_PLAYER; +} + +bool SmartScript::IsCreature(WorldObject* obj) +{ + return obj && obj->GetTypeId() == TYPEID_UNIT; +} + +bool SmartScript::IsCreatureInControlOfSelf(WorldObject* obj) +{ + if (Creature* creatureObj = obj ? obj->ToCreature() : nullptr) + return !creatureObj->IsCharmed() && !creatureObj->IsControlledByPlayer(); + else + return false; +} + +bool SmartScript::IsGameObject(WorldObject* obj) +{ + return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT; +} + void SmartScript::OnUpdate(uint32 const diff) { if ((mScriptType == SMART_SCRIPT_TYPE_CREATURE || mScriptType == SMART_SCRIPT_TYPE_GAMEOBJECT) && !GetBaseObject()) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index b3294736e3f..e41e09c9f8c 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -18,17 +18,17 @@ #ifndef TRINITY_SMARTSCRIPT_H #define TRINITY_SMARTSCRIPT_H -#include "Common.h" -#include "Creature.h" -#include "CreatureAI.h" -#include "Unit.h" -#include "Spell.h" -#include "GridNotifiers.h" - +#include "Define.h" #include "SmartScriptMgr.h" -//#include "SmartAI.h" +class Creature; +class GameObject; class Player; +class SpellInfo; +class Unit; +class WorldObject; +struct AreaTriggerEntry; +struct SceneTemplate; class TC_GAME_API SmartScript { @@ -51,56 +51,18 @@ class TC_GAME_API SmartScript ObjectList* GetTargets(SmartScriptHolder const& e, Unit* invoker = nullptr); ObjectList* GetWorldObjectsInDist(float dist); void InstallTemplate(SmartScriptHolder const& e); - SmartScriptHolder CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask = 0); + SmartScriptHolder CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask = 0); void AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask = 0); void SetPathId(uint32 id) { mPathId = id; } uint32 GetPathId() const { return mPathId; } - WorldObject* GetBaseObject() - { - WorldObject* obj = nullptr; - if (me) - obj = me; - else if (go) - obj = go; - return obj; - } - WorldObject* GetBaseObjectOrUnit(Unit* unit) - { - WorldObject* summoner = GetBaseObject(); - - if (!summoner && unit) - return unit; - - return summoner; - } - - static bool IsUnit(WorldObject* obj) - { - return obj && (obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_PLAYER); - } - - static bool IsPlayer(WorldObject* obj) - { - return obj && obj->GetTypeId() == TYPEID_PLAYER; - } - static bool IsCreature(WorldObject* obj) - { - return obj && obj->GetTypeId() == TYPEID_UNIT; - } - - static bool IsCreatureInControlOfSelf(WorldObject* obj) - { - if (Creature* creatureObj = obj ? obj->ToCreature() : nullptr) - return !creatureObj->IsCharmed() && !creatureObj->IsControlledByPlayer(); - else - return false; - } - - static bool IsGameObject(WorldObject* obj) - { - return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT; - } + WorldObject* GetBaseObject(); + WorldObject* GetBaseObjectOrUnit(Unit* unit); + static bool IsUnit(WorldObject* obj); + static bool IsPlayer(WorldObject* obj); + static bool IsCreature(WorldObject* obj); + static bool IsCreatureInControlOfSelf(WorldObject* obj); + static bool IsGameObject(WorldObject* obj); void OnUpdate(const uint32 diff); void OnMoveInLineOfSight(Unit* who); @@ -110,144 +72,23 @@ class TC_GAME_API SmartScript void DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid); Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly); - void StoreTargetList(ObjectList* targets, uint32 id) - { - if (!targets) - return; - - if (mTargetStorage->find(id) != mTargetStorage->end()) - { - // check if already stored - if ((*mTargetStorage)[id]->Equals(targets)) - return; - - delete (*mTargetStorage)[id]; - } - - (*mTargetStorage)[id] = new ObjectGuidList(targets, GetBaseObject()); - } - - bool IsSmart(Creature* c = nullptr) - { - bool smart = true; - if (c && c->GetAIName() != "SmartAI") - smart = false; - - if (!me || me->GetAIName() != "SmartAI") - smart = false; - - if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: " UI64FMTD " Entry: %u) is not using SmartAI, action called by Creature (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(c ? c->GetSpawnId() : UI64LIT(0)), c ? c->GetEntry() : 0, uint64(me ? me->GetSpawnId() : UI64LIT(0)), me ? me->GetEntry() : 0); + bool IsSmart(Creature* c = NULL); + bool IsSmartGO(GameObject* g = NULL); - return smart; - } - - bool IsSmartGO(GameObject* g = nullptr) - { - bool smart = true; - if (g && g->GetAIName() != "SmartGameObjectAI") - smart = false; - - if (!go || go->GetAIName() != "SmartGameObjectAI") - smart = false; - if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: " UI64FMTD " Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(g ? g->GetSpawnId() : UI64LIT(0)), g ? g->GetEntry() : 0, uint64(go ? go->GetSpawnId() : UI64LIT(0)), go ? go->GetEntry() : 0); - - return smart; - } - - ObjectList* GetTargetList(uint32 id) - { - ObjectListMap::iterator itr = mTargetStorage->find(id); - if (itr != mTargetStorage->end()) - return (*itr).second->GetObjectList(); - return nullptr; - } - - void StoreCounter(uint32 id, uint32 value, uint32 reset) - { - CounterMap::const_iterator itr = mCounterList.find(id); - if (itr != mCounterList.end()) - { - if (reset == 0) - value += GetCounterValue(id); - mCounterList.erase(id); - } + void StoreTargetList(ObjectList* targets, uint32 id); + ObjectList* GetTargetList(uint32 id); - mCounterList.insert(std::make_pair(id, value)); - ProcessEventsFor(SMART_EVENT_COUNTER_SET); - } + void StoreCounter(uint32 id, uint32 value, uint32 reset); + uint32 GetCounterId(uint32 id); + uint32 GetCounterValue(uint32 id); - uint32 GetCounterId(uint32 id) - { - CounterMap::iterator itr = mCounterList.find(id); - if (itr != mCounterList.end()) - return itr->first; - return 0; - } - - uint32 GetCounterValue(uint32 id) - { - CounterMap::iterator itr = mCounterList.find(id); - if (itr != mCounterList.end()) - return itr->second; - return 0; - } - - GameObject* FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const - { - auto bounds = searchObject->GetMap()->GetGameObjectBySpawnIdStore().equal_range(guid); - if (bounds.first == bounds.second) - return nullptr; - - return bounds.first->second; - } - - Creature* FindCreatureNear(WorldObject* searchObject, ObjectGuid::LowType guid) const - { - auto bounds = searchObject->GetMap()->GetCreatureBySpawnIdStore().equal_range(guid); - if (bounds.first == bounds.second) - return nullptr; - - auto creatureItr = std::find_if(bounds.first, bounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair) - { - return pair.second->IsAlive(); - }); - - return creatureItr != bounds.second ? creatureItr->second : bounds.first->second; - } + GameObject* FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const; + Creature* FindCreatureNear(WorldObject* searchObject, ObjectGuid::LowType guid) const; ObjectListMap* mTargetStorage; void OnReset(); - void ResetBaseObject() - { - WorldObject* lookupRoot = me; - if (!lookupRoot) - lookupRoot = go; - - if (lookupRoot) - { - if (!meOrigGUID.IsEmpty()) - { - if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID)) - { - me = m; - go = nullptr; - } - } - if (!goOrigGUID.IsEmpty()) - { - if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID)) - { - me = nullptr; - go = o; - } - } - } - goOrigGUID.Clear(); - meOrigGUID.Clear(); - } + void ResetBaseObject(); //TIMED_ACTIONLIST (script type 9 aka script9) void SetScript9(SmartScriptHolder& e, uint32 entry); @@ -291,7 +132,7 @@ class TC_GAME_API SmartScript uint32 mPathId; SmartAIEventList mStoredEvents; - std::list<uint32>mRemIDs; + std::list<uint32> mRemIDs; uint32 mTextTimer; uint32 mLastTextID; @@ -301,20 +142,7 @@ class TC_GAME_API SmartScript SMARTAI_TEMPLATE mTemplate; void InstallEvents(); - void RemoveStoredEvent(uint32 id) - { - if (!mStoredEvents.empty()) - { - for (SmartAIEventList::iterator i = mStoredEvents.begin(); i != mStoredEvents.end(); ++i) - { - if (i->event_id == id) - { - mStoredEvents.erase(i); - return; - } - } - } - } + void RemoveStoredEvent(uint32 id); }; #endif diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index b0ef253d7b5..e20c512b93c 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -15,19 +15,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "SmartScriptMgr.h" +#include "CreatureTextMgr.h" #include "DatabaseEnv.h" -#include "ObjectMgr.h" -#include "ObjectDefines.h" -#include "GridDefines.h" -#include "GridNotifiers.h" -#include "InstanceScript.h" -#include "SpellMgr.h" -#include "Cell.h" #include "GameEventMgr.h" -#include "CreatureTextMgr.h" +#include "InstanceScript.h" +#include "Log.h" +#include "ObjectMgr.h" #include "SpellInfo.h" - -#include "SmartScriptMgr.h" +#include "SpellMgr.h" SmartWaypointMgr* SmartWaypointMgr::instance() { @@ -313,6 +309,43 @@ void SmartAIMgr::LoadSmartAIFromDB() UnLoadHelperStores(); } +SmartAIEventList SmartAIMgr::GetScript(int32 entry, SmartScriptType type) +{ + SmartAIEventList temp; + if (mEventMap[uint32(type)].find(entry) != mEventMap[uint32(type)].end()) + return mEventMap[uint32(type)][entry]; + else + { + if (entry > 0)//first search is for guid (negative), do not drop error if not found + TC_LOG_DEBUG("scripts.ai", "SmartAIMgr::GetScript: Could not load Script for Entry %d ScriptType %u.", entry, uint32(type)); + return temp; + } +} + +SmartScriptHolder& SmartAIMgr::FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId) +{ + SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), + [eventId](SmartScriptHolder& source) { return source.link == eventId; }); + + if (itr != list.end()) + return *itr; + + static SmartScriptHolder SmartScriptHolderDummy; + return SmartScriptHolderDummy; +} + +SmartScriptHolder& SmartAIMgr::FindLinkedEvent(SmartAIEventList& list, uint32 link) +{ + SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), + [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; }); + + if (itr != list.end()) + return *itr; + + static SmartScriptHolder SmartScriptHolderDummy; + return SmartScriptHolderDummy; +} + bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) { if (std::abs(e.target.o) > 2 * float(M_PI)) @@ -395,6 +428,126 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) return true; } +bool SmartAIMgr::IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max) +{ + if (max < min) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses min/max params wrong (%u/%u), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), min, max); + return false; + } + return true; +} + +bool SmartAIMgr::NotNULL(SmartScriptHolder const& e, uint32 data) +{ + if (!data) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u Parameter can not be NULL, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + return false; + } + return true; +} + +bool SmartAIMgr::IsCreatureValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sObjectMgr->GetCreatureTemplate(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Creature entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsQuestValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sObjectMgr->GetQuestTemplate(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Quest entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsGameObjectValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sObjectMgr->GetGameObjectTemplate(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent GameObject entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsSpellValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sSpellMgr->GetSpellInfo(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Spell entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsItemValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sItemStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Item entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sEmotesTextStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Text Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsEmoteValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sEmotesStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsAreaTriggerValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sAreaTriggerStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent AreaTrigger entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsSoundValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sSoundKitStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Sound entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsAnimKitValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sAnimKitStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent AnimKit entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) { if (e.event.type >= SMART_EVENT_END) @@ -869,7 +1022,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; case SMART_ACTION_RANDOM_SOUND: { - if (std::all_of(e.action.randomSound.sounds.begin(), e.action.randomSound.sounds.end(), [](uint32 sound) { return sound == 0; })) + if (std::all_of(std::begin(e.action.randomSound.sounds), std::end(e.action.randomSound.sounds), [](uint32 sound) { return sound == 0; })) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u does not have any non-zero sound", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -1438,3 +1591,34 @@ CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 i return CreateItemSpellStore.equal_range(itemId); } +ObjectGuidList::ObjectGuidList(ObjectList* objectList, WorldObject* baseObject) +{ + ASSERT(objectList != NULL); + m_objectList = objectList; + m_baseObject = baseObject; + m_guidList = new GuidList(); + + for (ObjectList::iterator itr = objectList->begin(); itr != objectList->end(); ++itr) + { + m_guidList->push_back((*itr)->GetGUID()); + } +} + +ObjectList* ObjectGuidList::GetObjectList() +{ + if (m_baseObject) + { + //sanitize list using m_guidList + m_objectList->clear(); + + for (GuidList::iterator itr = m_guidList->begin(); itr != m_guidList->end(); ++itr) + { + if (WorldObject* obj = ObjectAccessor::GetWorldObject(*m_baseObject, *itr)) + m_objectList->push_back(obj); + else + TC_LOG_DEBUG("scripts.ai", "SmartScript::mTargetStorage stores a guid to an invalid object: %s", itr->ToString().c_str()); + } + } + + return m_objectList; +} diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 6f66f19e475..171e7e4643a 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -18,15 +18,14 @@ #ifndef TRINITY_SMARTSCRIPTMGR_H #define TRINITY_SMARTSCRIPTMGR_H -#include "Common.h" -#include "Creature.h" -#include "CreatureAI.h" -#include "Unit.h" -#include "Spell.h" -#include "DB2Stores.h" +#include "Define.h" +#include "ObjectGuid.h" +#include <map> +#include <string> +#include <unordered_map> -//#include "SmartScript.h" -//#include "SmartAI.h" +class WorldObject; +enum SpellEffIndex : uint8; struct WayPoint { @@ -1075,7 +1074,7 @@ struct SmartAction struct { - std::array<uint32, SMART_ACTION_PARAM_COUNT - 1> sounds; + uint32 sounds[SMART_ACTION_PARAM_COUNT - 1]; uint32 onlySelf; } randomSound; @@ -1471,37 +1470,9 @@ class ObjectGuidList WorldObject* m_baseObject; public: - ObjectGuidList(ObjectList* objectList, WorldObject* baseObject) - { - ASSERT(objectList != NULL); - m_objectList = objectList; - m_baseObject = baseObject; - m_guidList = new GuidList(); - - for (ObjectList::iterator itr = objectList->begin(); itr != objectList->end(); ++itr) - { - m_guidList->push_back((*itr)->GetGUID()); - } - } - - ObjectList* GetObjectList() - { - if (m_baseObject) - { - //sanitize list using m_guidList - m_objectList->clear(); + ObjectGuidList(ObjectList* objectList, WorldObject* baseObject); - for (GuidList::iterator itr = m_guidList->begin(); itr != m_guidList->end(); ++itr) - { - if (WorldObject* obj = ObjectAccessor::GetWorldObject(*m_baseObject, *itr)) - m_objectList->push_back(obj); - else - TC_LOG_DEBUG("scripts.ai", "SmartScript::mTargetStorage stores a guid to an invalid object: %s", itr->ToString().c_str()); - } - } - - return m_objectList; - } + ObjectList* GetObjectList(); bool Equals(ObjectList* objectList) { @@ -1559,42 +1530,11 @@ class TC_GAME_API SmartAIMgr void LoadSmartAIFromDB(); - SmartAIEventList GetScript(int32 entry, SmartScriptType type) - { - SmartAIEventList temp; - if (mEventMap[uint32(type)].find(entry) != mEventMap[uint32(type)].end()) - return mEventMap[uint32(type)][entry]; - else - { - if (entry > 0)//first search is for guid (negative), do not drop error if not found - TC_LOG_DEBUG("scripts.ai", "SmartAIMgr::GetScript: Could not load Script for Entry %d ScriptType %u.", entry, uint32(type)); - return temp; - } - } - - static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId) - { - SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), - [eventId](SmartScriptHolder& source) { return source.link == eventId; }); - - if (itr != list.end()) - return *itr; - - static SmartScriptHolder SmartScriptHolderDummy; - return SmartScriptHolderDummy; - } - - static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link) - { - SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), - [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; }); + SmartAIEventList GetScript(int32 entry, SmartScriptType type); - if (itr != list.end()) - return *itr; + static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId); - static SmartScriptHolder SmartScriptHolderDummy; - return SmartScriptHolderDummy; - } + static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link); private: //event stores @@ -1602,16 +1542,7 @@ class TC_GAME_API SmartAIMgr bool IsEventValid(SmartScriptHolder& e); bool IsTargetValid(SmartScriptHolder const& e); - - bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max) - { - if (max < min) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses min/max params wrong (%u/%u), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), min, max); - return false; - } - return true; - } + bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max); /*inline bool IsPercentValid(SmartScriptHolder e, int32 pct) { @@ -1623,116 +1554,17 @@ class TC_GAME_API SmartAIMgr return true; }*/ - bool NotNULL(SmartScriptHolder const& e, uint32 data) - { - if (!data) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u Parameter can not be NULL, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); - return false; - } - return true; - } - - bool IsCreatureValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sObjectMgr->GetCreatureTemplate(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Creature entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsQuestValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sObjectMgr->GetQuestTemplate(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Quest entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsGameObjectValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sObjectMgr->GetGameObjectTemplate(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent GameObject entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsSpellValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sSpellMgr->GetSpellInfo(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Spell entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsItemValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sItemStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Item entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sEmotesTextStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Text Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsEmoteValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sEmotesStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsAreaTriggerValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sAreaTriggerStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent AreaTrigger entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsSoundValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sSoundKitStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent Sound entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsAnimKitValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sAnimKitStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u uses non-existent AnimKit entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - + bool NotNULL(SmartScriptHolder const& e, uint32 data); + bool IsCreatureValid(SmartScriptHolder const& e, uint32 entry); + bool IsQuestValid(SmartScriptHolder const& e, uint32 entry); + bool IsGameObjectValid(SmartScriptHolder const& e, uint32 entry); + bool IsSpellValid(SmartScriptHolder const& e, uint32 entry); + bool IsItemValid(SmartScriptHolder const& e, uint32 entry); + bool IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry); + bool IsEmoteValid(SmartScriptHolder const& e, uint32 entry); + bool IsAreaTriggerValid(SmartScriptHolder const& e, uint32 entry); + bool IsSoundValid(SmartScriptHolder const& e, uint32 entry); + bool IsAnimKitValid(SmartScriptHolder const& e, uint32 entry); bool IsTextValid(SmartScriptHolder const& e, uint32 id); // Helpers |
