aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2013-02-24 08:12:18 -0800
committerShauren <shauren.trinity@gmail.com>2013-02-24 08:12:18 -0800
commite3e09b93e2ad7c4d6cb821c52fe6a59d0bb339bb (patch)
tree1454385a43d0eb02e97b29ae70478b828c05c25a /src
parent06257d10348ba62ff0cb098e3cbe74aa948a261c (diff)
parentba549ddc30fd09f7591f0619a59cee1cd9e20574 (diff)
Merge pull request #9280 from horn/summons
Core/Summons: Implement summon groups system to be able to summon multiple NPCs at once without need of hardcoding the positions. Almost all hardcoded positions can now be moved to DB.
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h16
-rw-r--r--src/server/game/Entities/Object/Object.cpp37
-rw-r--r--src/server/game/Entities/Object/Object.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp86
-rw-r--r--src/server/game/Globals/ObjectMgr.h42
-rw-r--r--src/server/game/Maps/Map.h1
-rw-r--r--src/server/game/World/World.cpp3
7 files changed, 186 insertions, 0 deletions
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index a96d9ab33d0..dc3347c5b4f 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -21,6 +21,22 @@
#include "Creature.h"
+enum SummonerType
+{
+ SUMMONER_TYPE_CREATURE = 0,
+ SUMMONER_TYPE_GAMEOBJECT = 1,
+ SUMMONER_TYPE_MAP = 2
+};
+
+/// Stores data for temp summons
+struct TempSummonData
+{
+ uint32 entry; ///< Entry of summoned creature
+ Position pos; ///< Position, where should be creature spawned
+ TempSummonType type; ///< Summon type, see TempSummonType for available types
+ uint32 time; ///< Despawn time, usable only with certain temp summon types
+};
+
class TempSummon : public Creature
{
public:
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 893d4c1ea69..79bf656c318 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2315,6 +2315,24 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
return summon;
}
+/**
+* Summons group of creatures.
+*
+* @param group Id of group to summon.
+* @param list List to store pointers to summoned creatures.
+*/
+
+void Map::SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list)
+{
+ std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetId(), SUMMONER_TYPE_MAP, group);
+ if (!data)
+ return;
+
+ for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
+ if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, NULL, itr->time))
+ list.push_back(summon);
+}
+
void WorldObject::SetZoneScript()
{
if (Map* map = FindMap())
@@ -2394,6 +2412,25 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3
return summon;
}
+/**
+* Summons group of creatures. Should be called only by instances of Creature and GameObject classes.
+*
+* @param group Id of group to summon.
+* @param list List to store pointers to summoned creatures.
+*/
+void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list)
+{
+ ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!");
+
+ std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group);
+ if (!data)
+ return;
+
+ for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
+ if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, itr->type, itr->time))
+ list.push_back(summon);
+}
+
Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive) const
{
Creature* creature = NULL;
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index ae3d545b7d7..ae788621368 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -793,6 +793,7 @@ class WorldObject : public Object, public WorldLocation
}
GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime);
Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL);
+ void SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list);
Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const;
GameObject* FindNearestGameObject(uint32 entry, float range) const;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 0e657c5ea9e..222331c48f8 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1421,6 +1421,92 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow)
return true;
}
+void ObjectMgr::LoadTempSummons()
+{
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1 2 3 4 5 6 7 8 9
+ QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups");
+
+ if (!result)
+ {
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 temp summons. DB table `creature_summon_groups` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 summonerId = fields[0].GetUInt32();
+ SummonerType summonerType = SummonerType(fields[1].GetUInt8());
+ uint8 group = fields[2].GetUInt8();
+
+ switch (summonerType)
+ {
+ case SUMMONER_TYPE_CREATURE:
+ if (!GetCreatureTemplate(summonerId))
+ {
+ sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for creature summoner type, skipped.", summonerId);
+ continue;
+ }
+ break;
+ case SUMMONER_TYPE_GAMEOBJECT:
+ if (!GetGameObjectTemplate(summonerId))
+ {
+ sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for gameobject summoner type, skipped.", summonerId);
+ continue;
+ }
+ break;
+ case SUMMONER_TYPE_MAP:
+ if (!sMapStore.LookupEntry(summonerId))
+ {
+ sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has summoner with non existing entry %u for map summoner type, skipped.", summonerId);
+ continue;
+ }
+ break;
+ default:
+ sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled summoner type %u for summoner %u, skipped.", summonerType, summonerId);
+ continue;
+ }
+
+ TempSummonData data;
+ data.entry = fields[3].GetUInt32();
+
+ if (!GetCreatureTemplate(data.entry))
+ {
+ sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has creature in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] with non existing creature entry %u, skipped.", summonerId, summonerType, group, data.entry);
+ continue;
+ }
+
+ float posX = fields[4].GetFloat();
+ float posY = fields[5].GetFloat();
+ float posZ = fields[6].GetFloat();
+ float orientation = fields[7].GetFloat();
+
+ data.pos.Relocate(posX, posY, posZ, orientation);
+
+ data.type = TempSummonType(fields[8].GetUInt8());
+
+ if (data.type > TEMPSUMMON_MANUAL_DESPAWN)
+ {
+ sLog->outError(LOG_FILTER_SQL, "Table `creature_summon_groups` has unhandled temp summon type %u in group [Summoner ID: %u, Summoner Type: %u, Group ID: %u] for creature entry %u, skipped.", data.type, summonerId, summonerType, group, data.entry);
+ continue;
+ }
+
+ data.time = fields[9].GetUInt32();
+
+ TempSummonGroupKey key(summonerId, summonerType, group);
+ _tempSummonDataStore[key].push_back(data);
+
+ ++count;
+
+ } while (result->NextRow());
+
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u temp summons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
void ObjectMgr::LoadCreatures()
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 88496fa9d6e..12df01fc350 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -25,6 +25,7 @@
#include "Creature.h"
#include "DynamicObject.h"
#include "GameObject.h"
+#include "TemporarySummon.h"
#include "Corpse.h"
#include "QuestDef.h"
#include "ItemPrototype.h"
@@ -416,9 +417,29 @@ struct TrinityStringLocale
StringVector Content;
};
+/// Key for storing temp summon data in TempSummonDataContainer
+struct TempSummonGroupKey
+{
+ TempSummonGroupKey(uint32 summonerEntry, SummonerType summonerType, uint8 group)
+ : _summonerEntry(summonerEntry), _summonerType(summonerType), _summonGroup(group)
+ {
+ }
+
+ bool operator<(TempSummonGroupKey const& rhs) const
+ {
+ return memcmp(this, &rhs, sizeof(TempSummonGroupKey)) < 0;
+ }
+
+private:
+ uint32 _summonerEntry; ///< Summoner's entry
+ SummonerType _summonerType; ///< Summoner's type, see SummonerType for available types
+ uint8 _summonGroup; ///< Summon's group id
+};
+
typedef std::map<uint64, uint64> LinkedRespawnContainer;
typedef UNORDERED_MAP<uint32, CreatureData> CreatureDataContainer;
typedef UNORDERED_MAP<uint32, GameObjectData> GameObjectDataContainer;
+typedef std::map<TempSummonGroupKey, std::vector<TempSummonData> > TempSummonDataContainer;
typedef UNORDERED_MAP<uint32, CreatureLocale> CreatureLocaleContainer;
typedef UNORDERED_MAP<uint32, GameObjectLocale> GameObjectLocaleContainer;
typedef UNORDERED_MAP<uint32, ItemLocale> ItemLocaleContainer;
@@ -876,6 +897,7 @@ class ObjectMgr
void LoadCreatureTemplates();
void LoadCreatureTemplateAddons();
void CheckCreatureTemplate(CreatureTemplate const* cInfo);
+ void LoadTempSummons();
void LoadCreatures();
void LoadLinkedRespawn();
bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid);
@@ -981,6 +1003,24 @@ class ObjectMgr
return _mapObjectGuidsStore[MAKE_PAIR32(mapid, spawnMode)][cell_id];
}
+ /**
+ * Gets temp summon data for all creatures of specified group.
+ *
+ * @param summonerId Summoner's entry.
+ * @param summonerType Summoner's type, see SummonerType for available types.
+ * @param group Id of required group.
+ *
+ * @return null if group was not found, otherwise reference to the creature group data
+ */
+ std::vector<TempSummonData> const* GetSummonGroup(uint32 summonerId, SummonerType summonerType, uint8 group) const
+ {
+ TempSummonDataContainer::const_iterator itr = _tempSummonDataStore.find(TempSummonGroupKey(summonerId, summonerType, group));
+ if (itr != _tempSummonDataStore.end())
+ return &itr->second;
+
+ return NULL;
+ }
+
CreatureData const* GetCreatureData(uint32 guid) const
{
CreatureDataContainer::const_iterator itr = _creatureDataStore.find(guid);
@@ -1294,6 +1334,8 @@ class ObjectMgr
GameObjectDataContainer _gameObjectDataStore;
GameObjectLocaleContainer _gameObjectLocaleStore;
GameObjectTemplateContainer _gameObjectTemplateStore;
+ /// Stores temp summon data grouped by summoner's entry, summoner's type and group id
+ TempSummonDataContainer _tempSummonDataStore;
ItemTemplateContainer _itemTemplateStore;
ItemLocaleContainer _itemLocaleStore;
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 6bf7edf3a2f..cc47f053827 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -435,6 +435,7 @@ class Map : public GridRefManager<NGridType>
void UpdateIteratorBack(Player* player);
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0);
+ void SummonCreatureGroup(uint8 group, std::list<TempSummon*>& list);
Creature* GetCreature(uint64 guid);
GameObject* GetGameObject(uint64 guid);
DynamicObject* GetDynamicObject(uint64 guid);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 29ecdbb033e..ad2cc7699b2 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1432,6 +1432,9 @@ void World::SetInitialWorldSettings()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Creature Data...");
sObjectMgr->LoadCreatures();
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Temporary Summon Data...");
+ sObjectMgr->LoadTempSummons(); // must be after LoadCreatureTemplates() and LoadGameObjectTemplates()
+
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading pet levelup spells...");
sSpellMgr->LoadPetLevelupSpellMap();