aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Maps/Map.h
diff options
context:
space:
mode:
authorr00ty-tc <r00ty-tc@users.noreply.github.com>2017-05-07 21:48:41 +0100
committerTreeston <treeston.mmoc@gmail.com>2017-07-31 21:21:04 +0200
commit59db2eeea0a35028779fd76372ae06cc98c8086f (patch)
treea9532989868948cb309cb8d76a2e76a017fa9246 /src/server/game/Maps/Map.h
parentd24ce1739a799042d5a164794c09674227c8572c (diff)
Dynamic Creature/Go spawning:
- True blizzlike creature spawn/respawn behavior - new creature = new object - Toggleable spawn groups (with C++/SAI/command options to use them) - Custom feature: dynamic spawn rate scaling. Accelerates respawn rate based on players in the zone. - Backward compatibility mode (set via group and for summons) to support creatures/gos that currently don't work well with this (this should be removed once the exceptions are fixed) Fixes and closes #2858 Tags #8661 as fixable. Fixes and closes #13787 Fixes #15222.
Diffstat (limited to 'src/server/game/Maps/Map.h')
-rw-r--r--src/server/game/Maps/Map.h160
1 files changed, 128 insertions, 32 deletions
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index dd0e43158c1..d7613f79de5 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -21,16 +21,18 @@
#include "Define.h"
-#include "GridDefines.h"
#include "Cell.h"
-#include "Timer.h"
-#include "SharedDefines.h"
+#include "DynamicTree.h"
+#include "GridDefines.h"
#include "GridRefManager.h"
#include "MapRefManager.h"
-#include "DynamicTree.h"
#include "ObjectGuid.h"
#include "Optional.h"
-
+#include "SharedDefines.h"
+#include "SpawnData.h"
+#include "Timer.h"
+#include "Transaction.h"
+#include <boost/heap/fibonacci_heap.hpp>
#include <bitset>
#include <list>
#include <memory>
@@ -271,7 +273,37 @@ struct ZoneDynamicInfo
typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
+struct RespawnInfo; // forward declaration
+struct CompareRespawnInfo
+{
+ bool operator()(RespawnInfo const* a, RespawnInfo const* b) const;
+};
typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMap;
+typedef boost::heap::fibonacci_heap<RespawnInfo*, boost::heap::compare<CompareRespawnInfo>> RespawnListContainer;
+typedef RespawnListContainer::handle_type RespawnListHandle;
+typedef std::unordered_map<uint32, RespawnInfo*> RespawnInfoMap;
+typedef std::vector<RespawnInfo*> RespawnVector;
+struct RespawnInfo
+{
+ SpawnObjectType type;
+ ObjectGuid::LowType spawnId;
+ uint32 entry;
+ time_t respawnTime;
+ uint32 gridId;
+ uint32 zoneId;
+ RespawnListHandle handle;
+};
+inline bool CompareRespawnInfo::operator()(RespawnInfo const* a, RespawnInfo const* b) const
+{
+ if (a == b)
+ return false;
+ if (a->respawnTime != b->respawnTime)
+ return (a->respawnTime > b->respawnTime);
+ if (a->spawnId != b->spawnId)
+ return a->spawnId < b->spawnId;
+ ASSERT(a->type != b->type, "Duplicate respawn entry for spawnId (%u,%u) found!", a->type, a->spawnId);
+ return a->type < b->type;
+}
class TC_GAME_API Map : public GridRefManager<NGridType>
{
@@ -321,17 +353,19 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
GridCoord p = Trinity::ComputeGridCoord(x, y);
return !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL;
}
+ bool IsRemovalGrid(Position const& pos) const { return IsRemovalGrid(pos.GetPositionX(), pos.GetPositionY()); }
- bool IsGridLoaded(float x, float y) const
- {
- return IsGridLoaded(Trinity::ComputeGridCoord(x, y));
- }
+ bool IsGridLoaded(uint32 gridId) const { return IsGridLoaded(GridCoord(gridId % MAX_NUMBER_OF_GRIDS, gridId / MAX_NUMBER_OF_GRIDS)); }
+ bool IsGridLoaded(float x, float y) const { return IsGridLoaded(Trinity::ComputeGridCoord(x, y)); }
+ bool IsGridLoaded(Position const& pos) const { return IsGridLoaded(pos.GetPositionX(), pos.GetPositionY()); }
bool GetUnloadLock(GridCoord const& p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); }
void SetUnloadLock(GridCoord const& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); }
void LoadGrid(float x, float y);
void LoadAllCells();
bool UnloadGrid(NGridType& ngrid, bool pForce);
+ void GridMarkNoUnload(uint32 x, uint32 y);
+ void GridUnmarkNoUnload(uint32 x, uint32 y);
virtual void UnloadAll();
void ResetGridExpiry(NGridType &grid, float factor = 1) const
@@ -350,18 +384,16 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
Map const* GetParent() const { return m_parentMap; }
- // some calls like isInWater should not use vmaps due to processor power
- // can return INVALID_HEIGHT if under z+2 z coord not found height
- float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
- float GetMinHeight(float x, float y) const;
-
void GetFullTerrainStatusForPosition(float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS) const;
ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const;
bool GetAreaInfo(float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
uint32 GetAreaId(float x, float y, float z, bool *isOutdoors = nullptr) const;
+ uint32 GetAreaId(Position const& pos) { return GetAreaId(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
uint32 GetZoneId(float x, float y, float z) const;
+ uint32 GetZoneId(Position const& pos) { return GetZoneId(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const;
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, Position const& pos) { GetZoneAndAreaId(zoneid, areaid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
bool IsOutdoors(float x, float y, float z) const;
@@ -464,6 +496,9 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
Corpse* GetCorpse(ObjectGuid const& guid);
Creature* GetCreature(ObjectGuid const& guid);
GameObject* GetGameObject(ObjectGuid const& guid);
+ Creature* GetCreatureBySpawnId(ObjectGuid::LowType spawnId) const;
+ GameObject* GetGameObjectBySpawnId(ObjectGuid::LowType spawnId) const;
+ WorldObject* GetWorldObjectBySpawnId(SpawnObjectType type, ObjectGuid::LowType spawnId) const { return (type == SPAWN_TYPE_GAMEOBJECT) ? reinterpret_cast<WorldObject*>(GetGameObjectBySpawnId(spawnId)) : reinterpret_cast<WorldObject*>(GetCreatureBySpawnId(spawnId)); }
Transport* GetTransport(ObjectGuid const& guid);
DynamicObject* GetDynamicObject(ObjectGuid const& guid);
Pet* GetPet(ObjectGuid const& guid);
@@ -472,9 +507,11 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
typedef std::unordered_multimap<ObjectGuid::LowType, Creature*> CreatureBySpawnIdContainer;
CreatureBySpawnIdContainer& GetCreatureBySpawnIdStore() { return _creatureBySpawnIdStore; }
+ CreatureBySpawnIdContainer const& GetCreatureBySpawnIdStore() const { return _creatureBySpawnIdStore; }
typedef std::unordered_multimap<ObjectGuid::LowType, GameObject*> GameObjectBySpawnIdContainer;
GameObjectBySpawnIdContainer& GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; }
+ GameObjectBySpawnIdContainer const& GetGameObjectBySpawnIdStore() const { return _gameobjectBySpawnIdStore; }
std::unordered_set<Corpse*> const* GetCorpsesInCell(uint32 cellId) const
{
@@ -504,7 +541,11 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return nullptr; }
float GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
- float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
+ float GetMinHeight(float x, float y) const;
+ float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
+ float GetHeight(Position const& pos, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { return GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), vmap, maxSearchDist); }
+ float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), GetGameObjectFloor(phasemask, x, y, z, maxSearchDist)); }
+ float GetHeight(uint32 phasemask, Position const& pos, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { return GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), vmap, maxSearchDist); }
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const;
void Balance() { _dynamicTree.balance(); }
void RemoveGameObjectModel(GameObjectModel const& model) { _dynamicTree.remove(model); }
@@ -522,28 +563,24 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
time_t GetLinkedRespawnTime(ObjectGuid guid) const;
time_t GetCreatureRespawnTime(ObjectGuid::LowType dbGuid) const
{
- std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t>::const_iterator itr = _creatureRespawnTimes.find(dbGuid);
- if (itr != _creatureRespawnTimes.end())
- return itr->second;
-
- return time_t(0);
+ RespawnInfoMap::const_iterator itr = _creatureRespawnTimesBySpawnId.find(dbGuid);
+ return itr != _creatureRespawnTimesBySpawnId.end() ? itr->second->respawnTime : 0;
}
time_t GetGORespawnTime(ObjectGuid::LowType dbGuid) const
{
- std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t>::const_iterator itr = _goRespawnTimes.find(dbGuid);
- if (itr != _goRespawnTimes.end())
- return itr->second;
-
- return time_t(0);
+ RespawnInfoMap::const_iterator itr = _gameObjectRespawnTimesBySpawnId.find(dbGuid);
+ return itr != _gameObjectRespawnTimesBySpawnId.end() ? itr->second->respawnTime : 0;
}
- void SaveCreatureRespawnTime(ObjectGuid::LowType dbGuid, time_t respawnTime);
- void RemoveCreatureRespawnTime(ObjectGuid::LowType dbGuid);
- void SaveGORespawnTime(ObjectGuid::LowType dbGuid, time_t respawnTime);
- void RemoveGORespawnTime(ObjectGuid::LowType dbGuid);
+ time_t GetRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId) const { return (type == SPAWN_TYPE_GAMEOBJECT) ? GetGORespawnTime(spawnId) : GetCreatureRespawnTime(spawnId); }
+
+ void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone);
+
+ void SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 zoneId, uint32 gridId = 0, bool writeDB = true, bool replace = false, SQLTransaction dbTrans = nullptr);
+ void SaveRespawnTimeDB(SpawnObjectType type, ObjectGuid::LowType spawnId, time_t respawnTime, SQLTransaction dbTrans = nullptr);
void LoadRespawnTimes();
- void DeleteRespawnTimes();
+ void DeleteRespawnTimes() { DeleteRespawnInfo(); DeleteRespawnTimesInDB(GetId(), GetInstanceId()); }
void LoadCorpseData();
void DeleteCorpseData();
@@ -702,6 +739,59 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
typedef std::multimap<time_t, ScriptAction> ScriptScheduleMap;
ScriptScheduleMap m_scriptSchedule;
+ public:
+ void ProcessRespawns();
+ void ApplyDynamicModeRespawnScaling(WorldObject const* obj, ObjectGuid::LowType spawnId, uint32& respawnDelay, uint32 mode) const;
+
+ private:
+ // if return value is true, we can respawn
+ // if return value is false, reschedule the respawn to new value of info->respawnTime iff nonzero, delete otherwise
+ // if return value is false and info->respawnTime is nonzero, it is guaranteed to be greater than time(NULL)
+ bool CheckRespawn(RespawnInfo* info);
+ void DoRespawn(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 gridId);
+ void Respawn(RespawnInfo* info, bool force = false, SQLTransaction dbTrans = nullptr);
+ void Respawn(RespawnVector& respawnData, bool force = false, SQLTransaction dbTrans = nullptr);
+ void AddRespawnInfo(RespawnInfo& info, bool replace = false);
+ void DeleteRespawnInfo();
+ void DeleteRespawnInfo(RespawnInfo* info);
+ void DeleteRespawnInfo(RespawnVector& toDelete)
+ {
+ for (RespawnInfo* info : toDelete)
+ DeleteRespawnInfo(info);
+ toDelete.clear();
+ }
+ void DeleteRespawnInfo(SpawnObjectTypeMask types, uint32 zoneId = 0)
+ {
+ RespawnVector v;
+ GetRespawnInfo(v, types, zoneId);
+ if (!v.empty())
+ DeleteRespawnInfo(v);
+ }
+ void DeleteRespawnInfo(SpawnObjectType type, ObjectGuid::LowType spawnId)
+ {
+ if (RespawnInfo* info = GetRespawnInfo(type, spawnId))
+ DeleteRespawnInfo(info);
+ }
+
+ public:
+ void GetRespawnInfo(RespawnVector& respawnData, SpawnObjectTypeMask types, uint32 zoneId = 0) const;
+ RespawnInfo* GetRespawnInfo(SpawnObjectType type, ObjectGuid::LowType spawnId) const;
+ void RemoveRespawnTime(RespawnInfo* info, bool doRespawn = false, SQLTransaction dbTrans = nullptr);
+ void RemoveRespawnTime(RespawnVector& respawnData, bool doRespawn = false, SQLTransaction dbTrans = nullptr);
+ void RemoveRespawnTime(SpawnObjectTypeMask types = SPAWN_TYPEMASK_ALL, uint32 zoneId = 0, bool doRespawn = false, SQLTransaction dbTrans = nullptr)
+ {
+ RespawnVector v;
+ GetRespawnInfo(v, types, zoneId);
+ if (!v.empty())
+ RemoveRespawnTime(v, doRespawn, dbTrans);
+ }
+ void RemoveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, bool doRespawn = false, SQLTransaction dbTrans = nullptr)
+ {
+ if (RespawnInfo* info = GetRespawnInfo(type, spawnId))
+ RemoveRespawnTime(info, doRespawn, dbTrans);
+ }
+
+ private:
// Type specific code for add/remove to/from grid
template<class T>
void AddToGrid(T* object, Cell const& cell);
@@ -730,8 +820,14 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
m_activeNonPlayers.erase(obj);
}
- std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t> _creatureRespawnTimes;
- std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t> _goRespawnTimes;
+ RespawnListContainer _respawnTimes;
+ RespawnInfoMap _creatureRespawnTimesBySpawnId;
+ RespawnInfoMap _gameObjectRespawnTimesBySpawnId;
+ RespawnInfoMap& GetRespawnMapForType(SpawnObjectType type) { return (type == SPAWN_TYPE_GAMEOBJECT) ? _gameObjectRespawnTimesBySpawnId : _creatureRespawnTimesBySpawnId; }
+ RespawnInfoMap const& GetRespawnMapForType(SpawnObjectType type) const { return (type == SPAWN_TYPE_GAMEOBJECT) ? _gameObjectRespawnTimesBySpawnId : _creatureRespawnTimesBySpawnId; }
+
+ uint32 _respawnCheckTimer;
+ std::unordered_map<uint32, uint32> _zonePlayerCountMap;
ZoneDynamicInfoMap _zoneDynamicInfo;
uint32 _defaultLight;