aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/world_database.sql1
-rw-r--r--sql/updates/10281_world_gameobject_template.sql1
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.cpp29
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h54
-rwxr-xr-xsrc/server/game/AI/CreatureAIFactory.h29
-rwxr-xr-xsrc/server/game/AI/CreatureAIRegistry.cpp2
-rwxr-xr-xsrc/server/game/AI/CreatureAISelector.cpp16
-rwxr-xr-xsrc/server/game/AI/CreatureAISelector.h1
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp23
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.h7
-rwxr-xr-xsrc/server/shared/Database/SQLStorage.cpp4
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";