diff options
-rw-r--r-- | sql/base/world_database.sql | 1 | ||||
-rw-r--r-- | sql/updates/10281_world_gameobject_template.sql | 1 | ||||
-rw-r--r-- | src/server/game/AI/CoreAI/GameObjectAI.cpp | 29 | ||||
-rw-r--r-- | src/server/game/AI/CoreAI/GameObjectAI.h | 54 | ||||
-rwxr-xr-x | src/server/game/AI/CreatureAIFactory.h | 29 | ||||
-rwxr-xr-x | src/server/game/AI/CreatureAIRegistry.cpp | 2 | ||||
-rwxr-xr-x | src/server/game/AI/CreatureAISelector.cpp | 16 | ||||
-rwxr-xr-x | src/server/game/AI/CreatureAISelector.h | 1 | ||||
-rwxr-xr-x | src/server/game/Entities/GameObject/GameObject.cpp | 23 | ||||
-rwxr-xr-x | src/server/game/Entities/GameObject/GameObject.h | 7 | ||||
-rwxr-xr-x | src/server/shared/Database/SQLStorage.cpp | 4 |
11 files changed, 163 insertions, 4 deletions
diff --git a/sql/base/world_database.sql b/sql/base/world_database.sql index a15c71f8cef..828ef681506 100644 --- a/sql/base/world_database.sql +++ b/sql/base/world_database.sql @@ -2736,6 +2736,7 @@ CREATE TABLE `gameobject_template` ( `data21` int(10) unsigned NOT NULL DEFAULT '0', `data22` int(10) unsigned NOT NULL DEFAULT '0', `data23` int(10) unsigned NOT NULL DEFAULT '0', + `AIName` char(64) NOT NULL DEFAULT '', `ScriptName` varchar(64) NOT NULL DEFAULT '', `WDBVerified` smallint(5) signed DEFAULT '1', PRIMARY KEY (`entry`), diff --git a/sql/updates/10281_world_gameobject_template.sql b/sql/updates/10281_world_gameobject_template.sql new file mode 100644 index 00000000000..568b4c21f5e --- /dev/null +++ b/sql/updates/10281_world_gameobject_template.sql @@ -0,0 +1 @@ +ALTER TABLE `gameobject_template` ADD `AIName` CHAR( 64 ) NOT NULL DEFAULT '' AFTER `data23`;
\ No newline at end of file diff --git a/src/server/game/AI/CoreAI/GameObjectAI.cpp b/src/server/game/AI/CoreAI/GameObjectAI.cpp new file mode 100644 index 00000000000..8e8509008a6 --- /dev/null +++ b/src/server/game/AI/CoreAI/GameObjectAI.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "GameObjectAI.h" + +//GameObjectAI::GameObjectAI(GameObject *g) : go(g) {} +int GameObjectAI::Permissible(const GameObject* go) +{ + if (go->GetAIName() == "GameObjectAI") + return PERMIT_BASE_SPECIAL; + return PERMIT_BASE_NO; +} + +NullGameObjectAI::NullGameObjectAI(GameObject *g) : GameObjectAI(g) {}
\ No newline at end of file diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h new file mode 100644 index 00000000000..144ded86f80 --- /dev/null +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_GAMEOBJECTAI_H +#define TRINITY_GAMEOBJECTAI_H + +#include "Define.h" +#include <list> +#include "Object.h" +#include "GameObject.h" +#include "CreatureAI.h" + +class GameObjectAI +{ + protected: + GameObject * const go; + public: + explicit GameObjectAI(GameObject *g) : go(g) {} + virtual ~GameObjectAI() {} + + virtual void UpdateAI(const uint32 diff) {} + + virtual void InitializeAI() { Reset(); } + + virtual void Reset() {}; + + static int Permissible(const GameObject* go); +}; + +class NullGameObjectAI : public GameObjectAI +{ + public: + explicit NullGameObjectAI(GameObject *g); + + void UpdateAI(const uint32) {} + + static int Permissible(const GameObject* go) { return PERMIT_BASE_IDLE; } +}; +#endif diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h index 4b7dce9d8a9..e7839dab1de 100755 --- a/src/server/game/AI/CreatureAIFactory.h +++ b/src/server/game/AI/CreatureAIFactory.h @@ -21,6 +21,7 @@ //#include "Policies/Singleton.h" #include "ObjectRegistry.h" #include "FactoryHolder.h" +#include "GameObjectAI.h" struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature> { @@ -48,4 +49,32 @@ CreatureAIFactory<REAL_AI>::Create(void *data) const typedef FactoryHolder<CreatureAI> CreatureAICreator; typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry; typedef FactoryHolder<CreatureAI>::FactoryHolderRepository CreatureAIRepository; + +//GO +struct SelectableGameObjectAI : public FactoryHolder<GameObjectAI>, public Permissible<GameObject> +{ + SelectableGameObjectAI(const char *id) : FactoryHolder<GameObjectAI>(id) {} +}; + +template<class REAL_GO_AI> +struct GameObjectAIFactory : public SelectableGameObjectAI +{ + GameObjectAIFactory(const char *name) : SelectableGameObjectAI(name) {} + + GameObjectAI* Create(void *) const; + + int Permit(const GameObject *g) const { return REAL_GO_AI::Permissible(g); } +}; + +template<class REAL_GO_AI> +inline GameObjectAI* +GameObjectAIFactory<REAL_GO_AI>::Create(void *data) const +{ + GameObject* go = reinterpret_cast<GameObject *>(data); + return (new REAL_GO_AI(go)); +} + +typedef FactoryHolder<GameObjectAI> GameObjectAICreator; +typedef FactoryHolder<GameObjectAI>::FactoryHolderRegistry GameObjectAIRegistry; +typedef FactoryHolder<GameObjectAI>::FactoryHolderRepository GameObjectAIRepository; #endif diff --git a/src/server/game/AI/CreatureAIRegistry.cpp b/src/server/game/AI/CreatureAIRegistry.cpp index 9e3c5bd9d0c..d343bdce0eb 100755 --- a/src/server/game/AI/CreatureAIRegistry.cpp +++ b/src/server/game/AI/CreatureAIRegistry.cpp @@ -52,6 +52,8 @@ namespace AIRegistry (new CreatureAIFactory<VehicleAI>("VehicleAI"))->RegisterSelf(); (new CreatureAIFactory<SmartAI>("SmartAI"))->RegisterSelf(); + (new GameObjectAIFactory<GameObjectAI>("GameObjectAI"))->RegisterSelf(); + (new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf(); (new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf(); } diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index 1989ca430ef..1fc847d3bb7 100755 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -127,5 +127,21 @@ namespace FactorySelector return (mv_factory == NULL ? NULL : mv_factory->Create(creature)); } + + GameObjectAI* SelectGameObjectAI(GameObject *go) + { + const GameObjectAICreator *ai_factory = NULL; + GameObjectAIRegistry& ai_registry(*GameObjectAIRepository::instance()); + + ai_factory = ai_registry.GetRegistryItem(go->GetAIName()); + + //future goAI types go here + + std::string ainame = (ai_factory == NULL) ? "NullGameObjectAI" : ai_factory->key(); + + sLog.outStaticDebug("GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str()); + + return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go)); + } } diff --git a/src/server/game/AI/CreatureAISelector.h b/src/server/game/AI/CreatureAISelector.h index 124bf9c63c0..d5155045aff 100755 --- a/src/server/game/AI/CreatureAISelector.h +++ b/src/server/game/AI/CreatureAISelector.h @@ -27,6 +27,7 @@ namespace FactorySelector { CreatureAI* selectAI(Creature *); MovementGenerator* selectMovementGenerator(Creature *); + GameObjectAI* SelectGameObjectAI(GameObject *go); } #endif diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 79425e6248a..d7270af5ae2 100755 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -38,8 +38,9 @@ #include "OutdoorPvPMgr.h" #include "BattlegroundAV.h" #include "ScriptMgr.h" +#include "CreatureAISelector.h" -GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue) +GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue), m_AI(NULL) { m_objectType |= TYPEMASK_GAMEOBJECT; m_objectTypeId = TYPEID_GAMEOBJECT; @@ -74,6 +75,20 @@ GameObject::~GameObject() // CleanupsBeforeDelete(); } +bool GameObject::AIM_Initialize() +{ + + m_AI = FactorySelector::SelectGameObjectAI(this); + if (!m_AI) return false; + m_AI->InitializeAI(); + return true; +} + +std::string GameObject::GetAIName() const +{ + return ObjectMgr::GetGameObjectInfo(GetEntry())->AIName; +} + void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/) { if (IsInWorld()) @@ -224,6 +239,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa void GameObject::Update(uint32 diff) { + if(!m_AI) + if (!AIM_Initialize()) + sLog.outError("Could not initialize GameObjectAI"); + if (IS_MO_TRANSPORT(GetGUID())) { //((Transport*)this)->Update(p_time); @@ -531,7 +550,7 @@ void GameObject::Update(uint32 diff) break; } } - + AI()->UpdateAI(diff); sScriptMgr.OnGameObjectUpdate(this, diff); } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 20b7ba21dee..c865631c13e 100755 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -24,6 +24,7 @@ #include "Object.h" #include "LootMgr.h" #include "DatabaseEnv.h" +#include "GameObjectAI.h" // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform #if defined(__GNUC__) @@ -398,6 +399,7 @@ struct GameObjectInfo uint32 data[24]; } raw; }; + char const* AIName; uint32 ScriptId; // helpers @@ -745,6 +747,9 @@ class GameObject : public WorldObject, public GridObject<GameObject> uint64 GetRotation() const { return m_rotation; } virtual uint32 GetScriptId() const { return GetGOInfo()->ScriptId; } + GameObjectAI* AI() const { return (GameObjectAI*)m_AI; } + + std::string GetAIName() const; protected: uint32 m_spellId; time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), @@ -772,5 +777,7 @@ class GameObject : public WorldObject, public GridObject<GameObject> uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable private: void SwitchDoorOrButton(bool activate, bool alternative = false); + GameObjectAI* m_AI; + bool AIM_Initialize(); }; #endif diff --git a/src/server/shared/Database/SQLStorage.cpp b/src/server/shared/Database/SQLStorage.cpp index 0ea69f9ebfc..5fdd11fc310 100755 --- a/src/server/shared/Database/SQLStorage.cpp +++ b/src/server/shared/Database/SQLStorage.cpp @@ -25,8 +25,8 @@ const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffbi"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; const char EquipmentInfofmt[]="iiii"; -const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisi"; -const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; +const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissi"; +const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisii"; const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiiii"; const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiii"; const char PageTextfmt[]="isii"; |