Core/Spells: Implemented personal summons (#19231)
[trinitycore] / src / server / game / Maps / Map.h
1 /*
2 * Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
3 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef TRINITY_MAP_H
20 #define TRINITY_MAP_H
21
22 #include "Define.h"
23
24 #include "GridDefines.h"
25 #include "Cell.h"
26 #include "Timer.h"
27 #include "SharedDefines.h"
28 #include "GridRefManager.h"
29 #include "MapRefManager.h"
30 #include "DynamicTree.h"
31 #include "ObjectGuid.h"
32
33 #include <bitset>
34 #include <list>
35 #include <memory>
36 #include <mutex>
37 #include <set>
38 #include <unordered_set>
39
40 class Battleground;
41 class BattlegroundMap;
42 class CreatureGroup;
43 class GameObjectModel;
44 class Group;
45 class InstanceMap;
46 class InstanceSave;
47 class InstanceScript;
48 class InstanceScenario;
49 class MapInstanced;
50 class Object;
51 class PhaseShift;
52 class Player;
53 class TempSummon;
54 class Unit;
55 class Weather;
56 class WorldObject;
57 class WorldPacket;
58 struct MapDifficultyEntry;
59 struct MapEntry;
60 struct Position;
61 struct ScriptAction;
62 struct ScriptInfo;
63 struct SummonPropertiesEntry;
64 class Transport;
65 enum Difficulty : uint8;
66 enum WeatherState : uint32;
67
68 namespace Trinity { struct ObjectUpdater; }
69 namespace G3D { class Plane; }
70
71 struct ScriptAction
72 {
73 ObjectGuid sourceGUID;
74 ObjectGuid targetGUID;
75 ObjectGuid ownerGUID; ///> owner of source if source is item
76 ScriptInfo const* script; ///> pointer to static script data
77 };
78
79 /// Represents a map magic value of 4 bytes (used in versions)
80 union u_map_magic
81 {
82 char asChar[4]; ///> Non-null terminated string
83 uint32 asUInt; ///> uint32 representation
84 };
85
86 // ******************************************
87 // Map file format defines
88 // ******************************************
89 struct map_fileheader
90 {
91 u_map_magic mapMagic;
92 u_map_magic versionMagic;
93 u_map_magic buildMagic;
94 uint32 areaMapOffset;
95 uint32 areaMapSize;
96 uint32 heightMapOffset;
97 uint32 heightMapSize;
98 uint32 liquidMapOffset;
99 uint32 liquidMapSize;
100 uint32 holesOffset;
101 uint32 holesSize;
102 };
103
104 #define MAP_AREA_NO_AREA 0x0001
105
106 struct map_areaHeader
107 {
108 uint32 fourcc;
109 uint16 flags;
110 uint16 gridArea;
111 };
112
113 #define MAP_HEIGHT_NO_HEIGHT 0x0001
114 #define MAP_HEIGHT_AS_INT16 0x0002
115 #define MAP_HEIGHT_AS_INT8 0x0004
116 #define MAP_HEIGHT_HAS_FLIGHT_BOUNDS 0x0008
117
118 struct map_heightHeader
119 {
120 uint32 fourcc;
121 uint32 flags;
122 float gridHeight;
123 float gridMaxHeight;
124 };
125
126 #define MAP_LIQUID_NO_TYPE 0x0001
127 #define MAP_LIQUID_NO_HEIGHT 0x0002
128
129 struct map_liquidHeader
130 {
131 uint32 fourcc;
132 uint8 flags;
133 uint8 liquidFlags;
134 uint16 liquidType;
135 uint8 offsetX;
136 uint8 offsetY;
137 uint8 width;
138 uint8 height;
139 float liquidLevel;
140 };
141
142 enum ZLiquidStatus
143 {
144 LIQUID_MAP_NO_WATER = 0x00000000,
145 LIQUID_MAP_ABOVE_WATER = 0x00000001,
146 LIQUID_MAP_WATER_WALK = 0x00000002,
147 LIQUID_MAP_IN_WATER = 0x00000004,
148 LIQUID_MAP_UNDER_WATER = 0x00000008
149 };
150
151 #define MAP_LIQUID_TYPE_NO_WATER 0x00
152 #define MAP_LIQUID_TYPE_WATER 0x01
153 #define MAP_LIQUID_TYPE_OCEAN 0x02
154 #define MAP_LIQUID_TYPE_MAGMA 0x04
155 #define MAP_LIQUID_TYPE_SLIME 0x08
156
157 #define MAP_ALL_LIQUIDS (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)
158
159 #define MAP_LIQUID_TYPE_DARK_WATER 0x10
160
161 struct LiquidData
162 {
163 uint32 type_flags;
164 uint32 entry;
165 float level;
166 float depth_level;
167 };
168
169 class TC_GAME_API GridMap
170 {
171 uint32 _flags;
172 union{
173 float* m_V9;
174 uint16* m_uint16_V9;
175 uint8* m_uint8_V9;
176 };
177 union{
178 float* m_V8;
179 uint16* m_uint16_V8;
180 uint8* m_uint8_V8;
181 };
182 G3D::Plane* _minHeightPlanes;
183 // Height level data
184 float _gridHeight;
185 float _gridIntHeightMultiplier;
186
187 // Area data
188 uint16* _areaMap;
189
190 // Liquid data
191 float _liquidLevel;
192 uint16* _liquidEntry;
193 uint8* _liquidFlags;
194 float* _liquidMap;
195 uint16 _gridArea;
196 uint16 _liquidGlobalEntry;
197 uint8 _liquidGlobalFlags;
198 uint8 _liquidOffX;
199 uint8 _liquidOffY;
200 uint8 _liquidWidth;
201 uint8 _liquidHeight;
202 bool _fileExists;
203
204 bool loadAreaData(FILE* in, uint32 offset, uint32 size);
205 bool loadHeightData(FILE* in, uint32 offset, uint32 size);
206 bool loadLiquidData(FILE* in, uint32 offset, uint32 size);
207
208 // Get height functions and pointers
209 typedef float (GridMap::*GetHeightPtr) (float x, float y) const;
210 GetHeightPtr _gridGetHeight;
211 float getHeightFromFloat(float x, float y) const;
212 float getHeightFromUint16(float x, float y) const;
213 float getHeightFromUint8(float x, float y) const;
214 float getHeightFromFlat(float x, float y) const;
215
216 public:
217 GridMap();
218 ~GridMap();
219 bool loadData(const char* filename);
220 void unloadData();
221
222 uint16 getArea(float x, float y) const;
223 inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);}
224 float getMinHeight(float x, float y) const;
225 float getLiquidLevel(float x, float y) const;
226 uint8 getTerrainType(float x, float y) const;
227 ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
228 bool fileExists() const { return _fileExists; }
229 };
230
231 #pragma pack(push, 1)
232
233 struct ZoneDynamicInfo
234 {
235 ZoneDynamicInfo();
236
237 uint32 MusicId;
238 std::unique_ptr<Weather> DefaultWeather;
239 WeatherState WeatherId;
240 float WeatherGrade;
241 uint32 OverrideLightId;
242 uint32 LightFadeInTime;
243 };
244
245 #pragma pack(pop)
246
247 #define MAX_HEIGHT 100000.0f // can be use for find ground height at surface
248 #define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
249 #define MAX_FALL_DISTANCE 250000.0f // "unlimited fall" to find VMap ground if it is available, just larger than MAX_HEIGHT - INVALID_HEIGHT
250 #define DEFAULT_HEIGHT_SEARCH 50.0f // default search distance to find height at nearby locations
251 #define MIN_UNLOAD_DELAY 1 // immediate unload
252
253 typedef std::map<ObjectGuid::LowType/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
254
255 typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMap;
256
257 typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer;
258
259 class TC_GAME_API Map : public GridRefManager<NGridType>
260 {
261 friend class MapReference;
262 public:
263 Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL);
264 virtual ~Map();
265
266 MapEntry const* GetEntry() const { return i_mapEntry; }
267
268 // currently unused for normal maps
269 bool CanUnload(uint32 diff)
270 {
271 if (!m_unloadTimer)
272 return false;
273
274 if (m_unloadTimer <= diff)
275 return true;
276
277 m_unloadTimer -= diff;
278 return false;
279 }
280
281 virtual bool AddPlayerToMap(Player* player, bool initPlayer = true);
282 virtual void RemovePlayerFromMap(Player*, bool);
283
284 template<class T> bool AddToMap(T *);
285 template<class T> void RemoveFromMap(T *, bool);
286
287 void VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor, TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor);
288 virtual void Update(const uint32);
289
290 float GetVisibilityRange() const { return m_VisibleDistance; }
291 //function for setting up visibility distance for maps on per-type/per-Id basis
292 virtual void InitVisibilityDistance();
293
294 void PlayerRelocation(Player*, float x, float y, float z, float orientation);
295 void CreatureRelocation(Creature* creature, float x, float y, float z, float ang, bool respawnRelocationOnFail = true);
296 void GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail = true);
297 void DynamicObjectRelocation(DynamicObject* go, float x, float y, float z, float orientation);
298 void AreaTriggerRelocation(AreaTrigger* at, float x, float y, float z, float orientation);
299
300 template<class T, class CONTAINER>
301 void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor);
302
303 bool IsRemovalGrid(float x, float y) const
304 {
305 GridCoord p = Trinity::ComputeGridCoord(x, y);
306 return !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL;
307 }
308
309 bool IsGridLoaded(float x, float y) const
310 {
311 return IsGridLoaded(Trinity::ComputeGridCoord(x, y));
312 }
313
314 bool GetUnloadLock(const GridCoord &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); }
315 void SetUnloadLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); }
316 void LoadGrid(float x, float y);
317 void LoadAllCells();
318 bool UnloadGrid(NGridType& ngrid, bool pForce);
319 virtual void UnloadAll();
320
321 void ResetGridExpiry(NGridType &grid, float factor = 1) const
322 {
323 grid.ResetTimeTracker(time_t(float(i_gridExpiry)*factor));
324 }
325
326 time_t GetGridExpiry() const { return i_gridExpiry; }
327
328 bool HasGrid(uint32 mapId, int32 gx, int32 gy) const;
329 static bool ExistMap(uint32 mapid, int gx, int gy);
330 static bool ExistVMap(uint32 mapid, int gx, int gy);
331
332 static void InitStateMachine();
333 static void DeleteStateMachine();
334
335 Map const* GetParent() const { return m_parentMap; }
336 void AddChildTerrainMap(Map* map) { m_childTerrainMaps->push_back(map); map->m_parentTerrainMap = this; }
337 void UnlinkAllChildTerrainMaps() { m_childTerrainMaps->clear(); }
338
339 // some calls like isInWater should not use vmaps due to processor power
340 // can return INVALID_HEIGHT if under z+2 z coord not found height
341 float GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
342 float GetMinHeight(float x, float y) const;
343
344 ZLiquidStatus getLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const;
345
346 uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors) const;
347 bool GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
348 uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z) const;
349 uint32 GetZoneId(PhaseShift const& phaseShift, float x, float y, float z) const;
350 void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z) const;
351
352 bool IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const;
353
354 uint8 GetTerrainType(PhaseShift const& phaseShift, float x, float y) const;
355 float GetWaterLevel(PhaseShift const& phaseShift, float x, float y) const;
356 bool IsInWater(PhaseShift const& phaseShift, float x, float y, float z, LiquidData* data = nullptr) const;
357 bool IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const;
358
359 void MoveAllCreaturesInMoveList();
360 void MoveAllGameObjectsInMoveList();
361 void MoveAllDynamicObjectsInMoveList();
362 void MoveAllAreaTriggersInMoveList();
363 void RemoveAllObjectsInRemoveList();
364 virtual void RemoveAllPlayers();
365
366 // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader
367 bool CreatureRespawnRelocation(Creature* c, bool diffGridOnly);
368 bool GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly);
369
370 // assert print helper
371 bool CheckGridIntegrity(Creature* c, bool moved) const;
372
373 uint32 GetInstanceId() const { return i_InstanceId; }
374 uint8 GetSpawnMode() const { return (i_spawnMode); }
375
376 enum EnterState
377 {
378 CAN_ENTER = 0,
379 CANNOT_ENTER_ALREADY_IN_MAP = 1, // Player is already in the map
380 CANNOT_ENTER_NO_ENTRY, // No map entry was found for the target map ID
381 CANNOT_ENTER_UNINSTANCED_DUNGEON, // No instance template was found for dungeon map
382 CANNOT_ENTER_DIFFICULTY_UNAVAILABLE, // Requested instance difficulty is not available for target map
383 CANNOT_ENTER_NOT_IN_RAID, // Target instance is a raid instance and the player is not in a raid group
384 CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE, // Player is dead and their corpse is not in target instance
385 CANNOT_ENTER_INSTANCE_BIND_MISMATCH, // Player's permanent instance save is not compatible with their group's current instance bind
386 CANNOT_ENTER_TOO_MANY_INSTANCES, // Player has entered too many instances recently
387 CANNOT_ENTER_MAX_PLAYERS, // Target map already has the maximum number of players allowed
388 CANNOT_ENTER_ZONE_IN_COMBAT, // A boss encounter is currently in progress on the target map
389 CANNOT_ENTER_UNSPECIFIED_REASON
390 };
391 virtual EnterState CannotEnter(Player* /*player*/) { return CAN_ENTER; }
392 const char* GetMapName() const;
393
394 // have meaning only for instanced map (that have set real difficulty)
395 Difficulty GetDifficultyID() const { return Difficulty(GetSpawnMode()); }
396 MapDifficultyEntry const* GetMapDifficulty() const;
397 uint8 GetDifficultyLootItemContext() const;
398
399 uint32 GetId() const;
400 bool Instanceable() const;
401 bool IsDungeon() const;
402 bool IsNonRaidDungeon() const;
403 bool IsRaid() const;
404 bool IsRaidOrHeroicDungeon() const;
405 bool IsHeroic() const;
406 bool Is25ManRaid() const; // since 25man difficulties are 1 and 3, we can check them like that
407 bool IsBattleground() const;
408 bool IsBattleArena() const;
409 bool IsBattlegroundOrArena() const;
410 bool IsGarrison() const;
411 bool GetEntrancePos(int32 &mapid, float &x, float &y);
412
413 void AddObjectToRemoveList(WorldObject* obj);
414 void AddObjectToSwitchList(WorldObject* obj, bool on);
415 virtual void DelayedUpdate(const uint32 diff);
416
417 void resetMarkedCells() { marked_cells.reset(); }
418 bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); }
419 void markCell(uint32 pCellId) { marked_cells.set(pCellId); }
420
421 bool HavePlayers() const { return !m_mapRefManager.isEmpty(); }
422 uint32 GetPlayersCountExceptGMs() const;
423 bool ActiveObjectsNearGrid(NGridType const& ngrid) const;
424
425 void AddWorldObject(WorldObject* obj) { i_worldObjects.insert(obj); }
426 void RemoveWorldObject(WorldObject* obj) { i_worldObjects.erase(obj); }
427
428 void SendToPlayers(WorldPacket const* data) const;
429
430 typedef MapRefManager PlayerList;
431 PlayerList const& GetPlayers() const { return m_mapRefManager; }
432
433 //per-map script storage
434 void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target);
435 void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
436
437 // must called with AddToWorld
438 template<class T>
439 void AddToActive(T* obj);
440
441 // must called with RemoveFromWorld
442 template<class T>
443 void RemoveFromActive(T* obj);
444
445 template<class T> void SwitchGridContainers(T* obj, bool on);
446 CreatureGroupHolderType CreatureGroupHolder;
447
448 void UpdateIteratorBack(Player* player);
449
450 TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0, bool visibleOnlyBySummoner = false);
451 void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL);
452 AreaTrigger* GetAreaTrigger(ObjectGuid const& guid);
453 Conversation* GetConversation(ObjectGuid const& guid);
454 Corpse* GetCorpse(ObjectGuid const& guid);
455 Creature* GetCreature(ObjectGuid const& guid);
456 DynamicObject* GetDynamicObject(ObjectGuid const& guid);
457 GameObject* GetGameObject(ObjectGuid const& guid);
458 Pet* GetPet(ObjectGuid const& guid);
459 Transport* GetTransport(ObjectGuid const& guid);
460
461 MapStoredObjectTypesContainer& GetObjectsStore() { return _objectsStore; }
462
463 typedef std::unordered_multimap<ObjectGuid::LowType, Creature*> CreatureBySpawnIdContainer;
464 CreatureBySpawnIdContainer& GetCreatureBySpawnIdStore() { return _creatureBySpawnIdStore; }
465
466 typedef std::unordered_multimap<ObjectGuid::LowType, GameObject*> GameObjectBySpawnIdContainer;
467 GameObjectBySpawnIdContainer& GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; }
468
469 std::unordered_set<Corpse*> const* GetCorpsesInCell(uint32 cellId) const
470 {
471 auto itr = _corpsesByCell.find(cellId);
472 if (itr != _corpsesByCell.end())
473 return &itr->second;
474
475 return nullptr;
476 }
477
478 Corpse* GetCorpseByPlayer(ObjectGuid const& ownerGuid) const
479 {
480 auto itr = _corpsesByPlayer.find(ownerGuid);
481 if (itr != _corpsesByPlayer.end())
482 return itr->second;
483
484 return nullptr;
485 }
486
487 MapInstanced* ToMapInstanced() { if (Instanceable()) return reinterpret_cast<MapInstanced*>(this); return NULL; }
488 MapInstanced const* ToMapInstanced() const { if (Instanceable()) return reinterpret_cast<MapInstanced const*>(this); return NULL; }
489
490 InstanceMap* ToInstanceMap() { if (IsDungeon()) return reinterpret_cast<InstanceMap*>(this); else return NULL; }
491 InstanceMap const* ToInstanceMap() const { if (IsDungeon()) return reinterpret_cast<InstanceMap const*>(this); return NULL; }
492
493 BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return NULL; }
494 BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return NULL; }
495
496 float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
497 float GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
498 bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2) const;
499 void Balance() { _dynamicTree.balance(); }
500 void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); }
501 void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); }
502 bool ContainsGameObjectModel(const GameObjectModel& model) const { return _dynamicTree.contains(model);}
503 bool getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
504
505 virtual ObjectGuid::LowType GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return UI64LIT(0); }
506 /*
507 RESPAWN TIMES
508 */
509 time_t GetLinkedRespawnTime(ObjectGuid guid) const;
510 time_t GetCreatureRespawnTime(ObjectGuid::LowType dbGuid) const
511 {
512 std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t>::const_iterator itr = _creatureRespawnTimes.find(dbGuid);
513 if (itr != _creatureRespawnTimes.end())
514 return itr->second;
515
516 return time_t(0);
517 }
518
519 time_t GetGORespawnTime(ObjectGuid::LowType dbGuid) const
520 {
521 std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t>::const_iterator itr = _goRespawnTimes.find(dbGuid);
522 if (itr != _goRespawnTimes.end())
523 return itr->second;
524
525 return time_t(0);
526 }
527
528 void SaveCreatureRespawnTime(ObjectGuid::LowType dbGuid, time_t respawnTime);
529 void RemoveCreatureRespawnTime(ObjectGuid::LowType dbGuid);
530 void SaveGORespawnTime(ObjectGuid::LowType dbGuid, time_t respawnTime);
531 void RemoveGORespawnTime(ObjectGuid::LowType dbGuid);
532 void LoadRespawnTimes();
533 void DeleteRespawnTimes();
534
535 void LoadCorpseData();
536 void DeleteCorpseData();
537 void AddCorpse(Corpse* corpse);
538 void RemoveCorpse(Corpse* corpse);
539 Corpse* ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia = false);
540 void RemoveOldCorpses();
541
542 static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
543
544 void SendInitTransports(Player* player);
545 void SendRemoveTransports(Player* player);
546 void SendUpdateTransportVisibility(Player* player);
547 void SendZoneDynamicInfo(uint32 zoneId, Player* player) const;
548 void SendZoneWeather(uint32 zoneId, Player* player) const;
549 void SendZoneWeather(ZoneDynamicInfo const& zoneDynamicInfo, Player* player) const;
550
551 void SetZoneMusic(uint32 zoneId, uint32 musicId);
552 Weather* GetOrGenerateZoneDefaultWeather(uint32 zoneId);
553 void SetZoneWeather(uint32 zoneId, WeatherState weatherId, float weatherGrade);
554 void SetZoneOverrideLight(uint32 zoneId, uint32 lightId, uint32 fadeInTime);
555
556 void UpdateAreaDependentAuras();
557
558 template<HighGuid high>
559 inline ObjectGuid::LowType GenerateLowGuid()
560 {
561 static_assert(ObjectGuidTraits<high>::MapSpecific, "Only map specific guid can be generated in Map context");
562 return GetGuidSequenceGenerator<high>().Generate();
563 }
564
565 void AddUpdateObject(Object* obj)
566 {
567 _updateObjects.insert(obj);
568 }
569
570 void RemoveUpdateObject(Object* obj)
571 {
572 _updateObjects.erase(obj);
573 }
574
575 private:
576 void LoadMapAndVMap(int gx, int gy);
577 void LoadVMap(int gx, int gy);
578 void LoadMap(int gx, int gy, bool reload = false);
579 static void LoadMapImpl(Map* map, int gx, int gy, bool reload);
580 void UnloadMap(int gx, int gy);
581 static void UnloadMapImpl(Map* map, int gx, int gy);
582 void LoadMMap(int gx, int gy);
583 GridMap* GetGrid(float x, float y);
584 GridMap* GetGrid(uint32 mapId, float x, float y);
585
586 void SetTimer(uint32 t) { i_gridExpiry = t < MIN_GRID_DELAY ? MIN_GRID_DELAY : t; }
587
588 void SendInitSelf(Player* player);
589
590 bool CreatureCellRelocation(Creature* creature, Cell new_cell);
591 bool GameObjectCellRelocation(GameObject* go, Cell new_cell);
592 bool DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell);
593 bool AreaTriggerCellRelocation(AreaTrigger* at, Cell new_cell);
594
595 template<class T> void InitializeObject(T* obj);
596 void AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang);
597 void RemoveCreatureFromMoveList(Creature* c);
598 void AddGameObjectToMoveList(GameObject* go, float x, float y, float z, float ang);
599 void RemoveGameObjectFromMoveList(GameObject* go);
600 void AddDynamicObjectToMoveList(DynamicObject* go, float x, float y, float z, float ang);
601 void RemoveDynamicObjectFromMoveList(DynamicObject* go);
602 void AddAreaTriggerToMoveList(AreaTrigger* at, float x, float y, float z, float ang);
603 void RemoveAreaTriggerFromMoveList(AreaTrigger* at);
604
605 bool _creatureToMoveLock;
606 std::vector<Creature*> _creaturesToMove;
607
608 bool _gameObjectsToMoveLock;
609 std::vector<GameObject*> _gameObjectsToMove;
610
611 bool _dynamicObjectsToMoveLock;
612 std::vector<DynamicObject*> _dynamicObjectsToMove;
613
614 bool _areaTriggersToMoveLock;
615 std::vector<AreaTrigger*> _areaTriggersToMove;
616
617 bool IsGridLoaded(const GridCoord &) const;
618 void EnsureGridCreated(const GridCoord &);
619 void EnsureGridCreated_i(const GridCoord &);
620 bool EnsureGridLoaded(Cell const&);
621 void EnsureGridLoadedForActiveObject(Cell const&, WorldObject* object);
622
623 void buildNGridLinkage(NGridType* pNGridType) { pNGridType->link(this); }
624
625 NGridType* getNGrid(uint32 x, uint32 y) const
626 {
627 ASSERT(x < MAX_NUMBER_OF_GRIDS && y < MAX_NUMBER_OF_GRIDS);
628 return i_grids[x][y];
629 }
630
631 bool isGridObjectDataLoaded(uint32 x, uint32 y) const { return getNGrid(x, y)->isGridObjectDataLoaded(); }
632 void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x, y)->setGridObjectDataLoaded(pLoaded); }
633
634 void setNGrid(NGridType* grid, uint32 x, uint32 y);
635 void ScriptsProcess();
636
637 void SendObjectUpdates();
638
639 protected:
640 void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }
641 virtual void LoadGridObjects(NGridType* grid, Cell const& cell);
642
643 std::mutex _mapLock;
644 std::mutex _gridLock;
645
646 MapEntry const* i_mapEntry;
647 uint8 i_spawnMode;
648 uint32 i_InstanceId;
649 uint32 m_unloadTimer;
650 float m_VisibleDistance;
651 DynamicMapTree _dynamicTree;
652
653 MapRefManager m_mapRefManager;
654 MapRefManager::iterator m_mapRefIter;
655
656 int32 m_VisibilityNotifyPeriod;
657
658 typedef std::set<WorldObject*> ActiveNonPlayers;
659 ActiveNonPlayers m_activeNonPlayers;
660 ActiveNonPlayers::iterator m_activeNonPlayersIter;
661
662 // Objects that must update even in inactive grids without activating them
663 typedef std::set<Transport*> TransportsContainer;
664 TransportsContainer _transports;
665 TransportsContainer::iterator _transportsUpdateIter;
666
667 private:
668 Player* _GetScriptPlayerSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo) const;
669 Creature* _GetScriptCreatureSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo, bool bReverse = false) const;
670 Unit* _GetScriptUnit(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const;
671 Player* _GetScriptPlayer(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const;
672 Creature* _GetScriptCreature(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const;
673 WorldObject* _GetScriptWorldObject(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const;
674 void _ScriptProcessDoor(Object* source, Object* target, const ScriptInfo* scriptInfo) const;
675 GameObject* _FindGameObject(WorldObject* pWorldObject, ObjectGuid::LowType guid) const;
676
677 time_t i_gridExpiry;
678
679 //used for fast base_map (e.g. MapInstanced class object) search for
680 //InstanceMaps and BattlegroundMaps...
681 Map* m_parentMap; // points to MapInstanced* or self (always same map id)
682 Map* m_parentTerrainMap; // points to m_parentMap of MapEntry::ParentMapID
683 std::vector<Map*>* m_childTerrainMaps; // contains m_parentMap of maps that have MapEntry::ParentMapID == GetId()
684
685 NGridType* i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
686 GridMap* GridMaps[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
687 std::bitset<TOTAL_NUMBER_OF_CELLS_PER_MAP*TOTAL_NUMBER_OF_CELLS_PER_MAP> marked_cells;
688
689 //these functions used to process player/mob aggro reactions and
690 //visibility calculations. Highly optimized for massive calculations
691 void ProcessRelocationNotifies(const uint32 diff);
692
693 bool i_scriptLock;
694 std::set<WorldObject*> i_objectsToRemove;
695 std::map<WorldObject*, bool> i_objectsToSwitch;
696 std::set<WorldObject*> i_worldObjects;
697
698 typedef std::multimap<time_t, ScriptAction> ScriptScheduleMap;
699 ScriptScheduleMap m_scriptSchedule;
700
701 // Type specific code for add/remove to/from grid
702 template<class T>
703 void AddToGrid(T* object, Cell const& cell);
704
705 template<class T>
706 void DeleteFromWorld(T*);
707
708 void AddToActiveHelper(WorldObject* obj)
709 {
710 m_activeNonPlayers.insert(obj);
711 }
712
713 void RemoveFromActiveHelper(WorldObject* obj)
714 {
715 // Map::Update for active object in proccess
716 if (m_activeNonPlayersIter != m_activeNonPlayers.end())
717 {
718 ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj);
719 if (itr == m_activeNonPlayers.end())
720 return;
721 if (itr == m_activeNonPlayersIter)
722 ++m_activeNonPlayersIter;
723 m_activeNonPlayers.erase(itr);
724 }
725 else
726 m_activeNonPlayers.erase(obj);
727 }
728
729 std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t> _creatureRespawnTimes;
730 std::unordered_map<ObjectGuid::LowType /*dbGUID*/, time_t> _goRespawnTimes;
731
732 ZoneDynamicInfoMap _zoneDynamicInfo;
733 IntervalTimer _weatherUpdateTimer;
734 uint32 _defaultLight;
735
736 template<HighGuid high>
737 inline ObjectGuidGeneratorBase& GetGuidSequenceGenerator()
738 {
739 auto itr = _guidGenerators.find(high);
740 if (itr == _guidGenerators.end())
741 itr = _guidGenerators.insert(std::make_pair(high, Trinity::make_unique<ObjectGuidGenerator<high>>())).first;
742
743 return *itr->second;
744 }
745
746 std::map<HighGuid, std::unique_ptr<ObjectGuidGeneratorBase>> _guidGenerators;
747 MapStoredObjectTypesContainer _objectsStore;
748 CreatureBySpawnIdContainer _creatureBySpawnIdStore;
749 GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore;
750 std::unordered_map<uint32/*cellId*/, std::unordered_set<Corpse*>> _corpsesByCell;
751 std::unordered_map<ObjectGuid, Corpse*> _corpsesByPlayer;
752 std::unordered_set<Corpse*> _corpseBones;
753
754 std::unordered_set<Object*> _updateObjects;
755 };
756
757 enum InstanceResetMethod
758 {
759 INSTANCE_RESET_ALL,
760 INSTANCE_RESET_CHANGE_DIFFICULTY,
761 INSTANCE_RESET_GLOBAL,
762 INSTANCE_RESET_GROUP_DISBAND,
763 INSTANCE_RESET_GROUP_JOIN,
764 INSTANCE_RESET_RESPAWN_DELAY
765 };
766
767 class TC_GAME_API InstanceMap : public Map
768 {
769 public:
770 InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent);
771 ~InstanceMap();
772 bool AddPlayerToMap(Player* player, bool initPlayer = true) override;
773 void RemovePlayerFromMap(Player*, bool) override;
774 void Update(const uint32) override;
775 void CreateInstanceData(bool load);
776 bool Reset(uint8 method);
777 uint32 GetScriptId() const { return i_script_id; }
778 std::string const& GetScriptName() const;
779 InstanceScript* GetInstanceScript() { return i_data; }
780 InstanceScript const* GetInstanceScript() const { return i_data; }
781 InstanceScenario* GetInstanceScenario() { return i_scenario; }
782 InstanceScenario const* GetInstanceScenario() const { return i_scenario; }
783 void SetInstanceScenario(InstanceScenario* scenario) { i_scenario = scenario; }
784 void PermBindAllPlayers();
785 void UnloadAll() override;
786 EnterState CannotEnter(Player* player) override;
787 void SendResetWarnings(uint32 timeLeft) const;
788 void SetResetSchedule(bool on);
789
790 /* this checks if any players have a permanent bind (included reactivatable expired binds) to the instance ID
791 it needs a DB query, so use sparingly */
792 bool HasPermBoundPlayers() const;
793 uint32 GetMaxPlayers() const;
794 uint32 GetMaxResetDelay() const;
795
796 virtual void InitVisibilityDistance() override;
797 private:
798 bool m_resetAfterUnload;
799 bool m_unloadWhenEmpty;
800 InstanceScript* i_data;
801 uint32 i_script_id;
802 InstanceScenario* i_scenario;
803 };
804
805 class TC_GAME_API BattlegroundMap : public Map
806 {
807 public:
808 BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode);
809 ~BattlegroundMap();
810
811 bool AddPlayerToMap(Player* player, bool initPlayer = true) override;
812 void RemovePlayerFromMap(Player*, bool) override;
813 EnterState CannotEnter(Player* player) override;
814 void SetUnload();
815 //void UnloadAll(bool pForce);
816 void RemoveAllPlayers() override;
817
818 virtual void InitVisibilityDistance() override;
819 Battleground* GetBG() { return m_bg; }
820 void SetBG(Battleground* bg) { m_bg = bg; }
821 private:
822 Battleground* m_bg;
823 };
824
825 template<class T, class CONTAINER>
826 inline void Map::Visit(Cell const& cell, TypeContainerVisitor<T, CONTAINER>& visitor)
827 {
828 const uint32 x = cell.GridX();
829 const uint32 y = cell.GridY();
830 const uint32 cell_x = cell.CellX();
831 const uint32 cell_y = cell.CellY();
832
833 if (!cell.NoCreate() || IsGridLoaded(GridCoord(x, y)))
834 {
835 EnsureGridLoaded(cell);
836 getNGrid(x, y)->VisitGrid(cell_x, cell_y, visitor);
837 }
838 }
839 #endif