aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql16
-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
8 files changed, 202 insertions, 0 deletions
diff --git a/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql b/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql
new file mode 100644
index 00000000000..409f79bb2aa
--- /dev/null
+++ b/sql/updates/world/2013_02_24_00_world_creature_summon_groups.sql
@@ -0,0 +1,16 @@
+DROP TABLE IF EXISTS `creature_summon_groups`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `creature_summon_groups` (
+ `summonerId` mediumint(8) unsigned NOT NULL DEFAULT '0',
+ `summonerType` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `groupId` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `entry` mediumint(8) unsigned NOT NULL DEFAULT '0',
+ `position_x` float NOT NULL DEFAULT '0',
+ `position_y` float NOT NULL DEFAULT '0',
+ `position_z` float NOT NULL DEFAULT '0',
+ `orientation` float NOT NULL DEFAULT '0',
+ `summonType` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `summonTime` int(10) unsigned NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
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();