diff options
| author | r00ty-tc <r00ty-tc@users.noreply.github.com> | 2017-05-07 21:48:41 +0100 |
|---|---|---|
| committer | Treeston <treeston.mmoc@gmail.com> | 2017-07-31 21:21:04 +0200 |
| commit | 59db2eeea0a35028779fd76372ae06cc98c8086f (patch) | |
| tree | a9532989868948cb309cb8d76a2e76a017fa9246 /src/server/game/Maps/Map.h | |
| parent | d24ce1739a799042d5a164794c09674227c8572c (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.h | 160 |
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; |
