TrinityCore
Loading...
Searching...
No Matches
Map.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Map.h"
19#include "Battleground.h"
20#include "BattlegroundMgr.h"
21#include "BattlegroundScript.h"
22#include "CellImpl.h"
23#include "CharacterPackets.h"
24#include "Conversation.h"
25#include "DB2Stores.h"
26#include "DatabaseEnv.h"
27#include "DynamicTree.h"
29#include "GameObjectModel.h"
30#include "GameTime.h"
31#include "GridNotifiers.h"
32#include "GridNotifiersImpl.h"
33#include "GridStates.h"
34#include "Group.h"
35#include "InstanceLockMgr.h"
36#include "InstancePackets.h"
37#include "InstanceScenario.h"
38#include "InstanceScript.h"
39#include "Log.h"
40#include "MMapManager.h"
41#include "MapManager.h"
42#include "MapUtils.h"
43#include "Metric.h"
44#include "MiscPackets.h"
45#include "MotionMaster.h"
46#include "ObjectAccessor.h"
47#include "ObjectGridLoader.h"
48#include "ObjectMgr.h"
49#include "Pet.h"
50#include "PhasingHandler.h"
51#include "PoolMgr.h"
52#include "ScriptMgr.h"
53#include "SpellAuras.h"
54#include "TerrainMgr.h"
55#include "Transport.h"
56#include "VMapFactory.h"
57#include "VMapManager.h"
58#include "Vehicle.h"
59#include "Vignette.h"
60#include "VignettePackets.h"
61#include "Weather.h"
62#include "WeatherMgr.h"
63#include "World.h"
64#include "WorldSession.h"
65#include "WorldStateMgr.h"
66#include "WorldStatePackets.h"
67#include <boost/heap/fibonacci_heap.hpp>
68#include <sstream>
69
70#define DEFAULT_GRID_EXPIRY 300
71#define MAX_GRID_LOAD_TIME 50
72#define MAX_CREATURE_ATTACK_RADIUS (45.0f * sWorld->getRate(RATE_CREATURE_AGGRO))
73
75
76ZoneDynamicInfo::ZoneDynamicInfo() : MusicId(0), DefaultWeather(nullptr), WeatherId(WEATHER_STATE_FINE),
77 Intensity(0.0f) { }
78
80
82struct RespawnListContainer : boost::heap::fibonacci_heap<RespawnInfoWithHandle*, boost::heap::compare<CompareRespawnInfo>>
83{
84};
85
87{
88 explicit RespawnInfoWithHandle(RespawnInfo const& other) : RespawnInfo(other) { }
89
90 RespawnListContainer::handle_type handle;
91};
92
94{
95 // Delete all waiting spawns, else there will be a memory leak
96 // This doesn't delete from database.
98
99 while (!i_worldObjects.empty())
100 {
101 WorldObject* obj = *i_worldObjects.begin();
103 //ASSERT(obj->GetTypeId() == TYPEID_CORPSE);
104 obj->RemoveFromWorld();
105 obj->ResetMap();
106 }
107
108 if (!m_scriptSchedule.empty())
109 sMapMgr->DecreaseScheduledScriptCount(m_scriptSchedule.size());
110
111 m_terrain->UnloadMMapInstance(GetId(), GetInstanceId());
112}
113
115{
116 for (uint32 cellX = 0; cellX < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellX++)
117 for (uint32 cellY = 0; cellY < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellY++)
119}
120
128
136
137Map::Map(uint32 id, time_t expiry, uint32 InstanceId, Difficulty SpawnMode) :
138_creatureToMoveLock(false), _gameObjectsToMoveLock(false), _dynamicObjectsToMoveLock(false), _areaTriggersToMoveLock(false),
139i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId),
140m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_mapRefIter(m_mapRefManager.end()),
141m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD),
142m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transports.end()),
143i_gridExpiry(expiry), m_terrain(sTerrainMgr.LoadTerrain(id)), m_forceEnabledNavMeshFilterFlags(0), m_forceDisabledNavMeshFilterFlags(0), i_grids(),
144i_scriptLock(false), _respawnTimes(std::make_unique<RespawnListContainer>()), _respawnCheckTimer(0), _vignetteUpdateTimer(5200, 5200)
145{
146 //lets initialize visibility distance for map
148
150
151 GetGuidSequenceGenerator(HighGuid::Transport).Set(sObjectMgr->GetGenerator<HighGuid::Transport>().GetNextAfterMaxUsed());
152
153 _poolData = sPoolMgr->InitPoolsForMap(this);
154
155 sTransportMgr->CreateTransportsForMap(this);
156
157 m_terrain->LoadMMapInstance(GetId(), GetInstanceId());
158
160 m_mmapTileRebuilder = std::make_shared<MMAP::DynamicTileBuilder>(this, MMAP::MMapManager::instance()->GetNavMesh(GetId(), GetInstanceId()));
161
163}
164
171
172// Template specialization of utility methods
173template<class T>
174void Map::AddToGrid(T* obj, Cell const& cell)
175{
176 NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
177 if constexpr (WorldTypeMapContainer::TypeExists<T> && GridTypeMapContainer::TypeExists<T>)
178 {
179 NGridType::GridType& cellType = grid->GetGridType(cell.CellX(), cell.CellY());
180 if (obj->IsStoredInWorldObjectGridContainer())
181 cellType.AddWorldObject<T>(obj);
182 else
183 cellType.AddGridObject<T>(obj);
184 }
185 else if constexpr (WorldTypeMapContainer::TypeExists<T>)
186 grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject<T>(obj);
187 else if constexpr (GridTypeMapContainer::TypeExists<T>)
188 grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject<T>(obj);
189
190 if constexpr (std::is_base_of_v<MapObject, T>)
191 obj->SetCurrentCell(cell);
192}
193
194template<>
195void Map::AddToGrid(Corpse* obj, Cell const& cell)
196{
197 NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
198 // Corpses are a special object type - they can be added to grid via a call to AddToMap
199 // or loaded through ObjectGridLoader.
200 // Both corpses loaded from database and these freshly generated by Player::CreateCoprse are added to _corpsesByCell
201 // ObjectGridLoader loads all corpses from _corpsesByCell even if they were already added to grid before it was loaded
202 // so we need to explicitly check it here (Map::AddToGrid is only called from Player::BuildPlayerRepop, not from ObjectGridLoader)
203 // to avoid failing an assertion in GridObject::AddToGrid
204 if (grid->isGridObjectDataLoaded())
205 {
206 NGridType::GridType& cellType = grid->GetGridType(cell.CellX(), cell.CellY());
208 cellType.AddWorldObject(obj);
209 else
210 cellType.AddGridObject(obj);
211 }
212}
213
214template<class T>
215void Map::SwitchGridContainers(T* /*obj*/, bool /*on*/) { }
216
217template<>
219{
222 if (!p.IsCoordValid())
223 {
224 TC_LOG_ERROR("maps", "Map::SwitchGridContainers: Object {} has invalid coordinates X:{} Y:{} grid cell [{}:{}]", obj->GetGUID().ToString(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord);
225 return;
226 }
227
228 Cell cell(p);
230 return;
231
232 if (sLog->ShouldLog("maps", LOG_LEVEL_DEBUG))
233 {
234 // Extract bitfield values
235 uint32 const grid_x = cell.data.Part.grid_x;
236 uint32 const grid_y = cell.data.Part.grid_y;
237
238 TC_LOG_DEBUG("maps", "Switch object {} from grid[{}, {}] {}", obj->GetGUID().ToString(), grid_x, grid_y, on);
239 }
240
241 NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY());
242 ASSERT(ngrid != nullptr);
243
244 GridType &grid = ngrid->GetGridType(cell.CellX(), cell.CellY());
245
246 obj->RemoveFromGrid(); //This step is not really necessary but we want to do ASSERT in remove/add
247
248 if (on)
249 {
250 grid.AddWorldObject(obj);
251 AddWorldObject(obj);
252 }
253 else
254 {
255 grid.AddGridObject(obj);
257 }
258
259 obj->m_isTempWorldObject = on;
260}
261
262template<class T>
264{
265 // Note: In case resurrectable corpse and pet its removed from global lists in own destructor
266 delete obj;
267}
268
269template<>
271{
273 RemoveUpdateObject(player);
274 delete player;
275}
276
277//Create NGrid so the object can be added to it
278//But object data is not loaded here
280{
281 if (!getNGrid(p.x_coord, p.y_coord))
282 {
283 TC_LOG_DEBUG("maps", "Creating grid[{}, {}] for map {} instance {}", p.x_coord, p.y_coord, GetId(), i_InstanceId);
284
286 setNGrid(ngrid, p.x_coord, p.y_coord);
287
288 // build a linkage between this map and NGridType
289 buildNGridLinkage(ngrid);
290
292
293 //z coord
294 int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord;
295 int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord;
296
297 m_terrain->LoadMapAndVMap(gx, gy);
298 m_terrain->LoadMMap(GetInstanceId(), gx, gy);
299 }
300}
301
302//Load NGrid and make it active
304{
305 EnsureGridLoaded(cell);
306 NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
307 ASSERT(grid != nullptr);
308
309 if (object->IsPlayer())
310 GetMultiPersonalPhaseTracker().LoadGrid(object->GetPhaseShift(), *grid, this, cell);
311
312 // refresh grid state & timer
313 if (grid->GetGridState() != GRID_STATE_ACTIVE)
314 {
315 TC_LOG_DEBUG("maps", "Active object {} triggers loading of grid [{}, {}] on map {}", object->GetGUID().ToString(), cell.GridX(), cell.GridY(), GetId());
316 ResetGridExpiry(*grid, 0.1f);
318 }
319}
320
321//Create NGrid and load the object data in it
323{
324 EnsureGridCreated(GridCoord(cell.GridX(), cell.GridY()));
325 NGridType *grid = getNGrid(cell.GridX(), cell.GridY());
326
327 ASSERT(grid != nullptr);
328 if (!isGridObjectDataLoaded(cell.GridX(), cell.GridY()))
329 {
330 TC_LOG_DEBUG("maps", "Loading grid[{}, {}] for map {} instance {}", cell.GridX(), cell.GridY(), GetId(), i_InstanceId);
331
332 setGridObjectDataLoaded(true, cell.GridX(), cell.GridY());
333
334 LoadGridObjects(grid, cell);
335
336 Balance();
337 return true;
338 }
339
340 return false;
341}
342
343void Map::LoadGridObjects(NGridType* grid, Cell const& cell)
344{
345 ObjectGridLoader loader(*grid, this, cell);
346 loader.LoadN();
347}
348
350{
351 // First make sure this grid is loaded
352 float gX = ((float(x) - 0.5f - CENTER_GRID_ID) * SIZE_OF_GRIDS) + (CENTER_GRID_OFFSET * 2);
353 float gY = ((float(y) - 0.5f - CENTER_GRID_ID) * SIZE_OF_GRIDS) + (CENTER_GRID_OFFSET * 2);
354 Cell cell = Cell(gX, gY);
355 EnsureGridLoaded(cell);
356
357 // Mark as don't unload
358 NGridType* grid = getNGrid(x, y);
359 grid->setUnloadExplicitLock(true);
360}
361
363{
364 // If grid is loaded, clear unload lock
365 if (IsGridLoaded(GridCoord(x, y)))
366 {
367 NGridType* grid = getNGrid(x, y);
368 grid->setUnloadExplicitLock(false);
369 }
370}
371
372void Map::LoadGrid(float x, float y)
373{
374 EnsureGridLoaded(Cell(x, y));
375}
376
377void Map::LoadGridForActiveObject(float x, float y, WorldObject const* object)
378{
380}
381
382bool Map::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)
383{
384 CellCoord cellCoord = Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY());
385 if (!cellCoord.IsCoordValid())
386 {
387 TC_LOG_ERROR("maps", "Map::Add: Player {} has invalid coordinates X:{} Y:{} grid cell [{}:{}]", player->GetGUID().ToString(), player->GetPositionX(), player->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
388 return false;
389 }
390
391 Cell cell(cellCoord);
393 AddToGrid(player, cell);
394
395 // Check if we are adding to correct map
396 ASSERT (player->GetMap() == this);
397 player->SetMap(this);
398 player->AddToWorld();
399
400 if (initPlayer)
401 SendInitSelf(player);
402
403 SendInitTransports(player);
404
405 if (initPlayer)
406 player->m_clientGUIDs.clear();
407
408 player->UpdateObjectVisibility(false);
410
411 if (Instanceable())
413
414 if (player->IsAlive())
415 ConvertCorpseToBones(player->GetGUID());
416
417 sScriptMgr->OnPlayerEnterMap(this, player);
418 return true;
419}
420
422{
423 Cell cell(player->GetPositionX(), player->GetPositionY());
424 GetMultiPersonalPhaseTracker().OnOwnerPhaseChanged(player, getNGrid(cell.GridX(), cell.GridY()), this, cell);
425}
426
428{
429 if (int32 const* value = Trinity::Containers::MapGetValuePtr(_worldStateValues, worldStateId))
430 return *value;
431
432 return 0;
433}
434
435void Map::SetWorldStateValue(int32 worldStateId, int32 value, bool hidden)
436{
437 auto [itr, inserted] = _worldStateValues.try_emplace(worldStateId, 0);
438 int32 oldValue = itr->second;
439 if (oldValue == value && !inserted)
440 return;
441
442 itr->second = value;
443
444 WorldStateTemplate const* worldStateTemplate = WorldStateMgr::GetWorldStateTemplate(worldStateId);
445 if (worldStateTemplate)
446 sScriptMgr->OnWorldStateValueChange(worldStateTemplate, oldValue, value, this);
447
448 // Broadcast update to all players on the map
450 updateWorldState.VariableID = worldStateId;
451 updateWorldState.Value = value;
452 updateWorldState.Hidden = hidden;
453 updateWorldState.Write();
454
455 for (MapReference const& mapReference : m_mapRefManager)
456 {
457 if (worldStateTemplate && !worldStateTemplate->AreaIds.empty())
458 {
459 bool isInAllowedArea = std::any_of(worldStateTemplate->AreaIds.begin(), worldStateTemplate->AreaIds.end(),
460 [playerAreaId = mapReference.GetSource()->GetAreaId()](uint32 requiredAreaId) { return DB2Manager::IsInArea(playerAreaId, requiredAreaId); });
461 if (!isInAllowedArea)
462 continue;
463 }
464
465 mapReference.GetSource()->SendDirectMessage(updateWorldState.GetRawPacket());
466 }
467}
468
470{
471 _infiniteAOIVignettes.push_back(vignette);
472
474 vignette->FillPacket(vignetteUpdate.Added);
475 vignetteUpdate.Write();
476
477 for (MapReference const& ref : m_mapRefManager)
478 if (Vignettes::CanSee(ref.GetSource(), *vignette))
479 ref.GetSource()->SendDirectMessage(vignetteUpdate.GetRawPacket());
480}
481
483{
484 if (!std::erase(_infiniteAOIVignettes, vignette))
485 return;
486
488 vignetteUpdate.Removed.push_back(vignette->Guid);
489 vignetteUpdate.Write();
490
491 if (vignette->Data->GetFlags().HasFlag(VignetteFlags::ZoneInfiniteAOI))
492 {
493 for (MapReference const& ref : m_mapRefManager)
494 if (ref.GetSource()->GetZoneId() == vignette->ZoneID)
495 ref.GetSource()->SendDirectMessage(vignetteUpdate.GetRawPacket());
496 }
497 else
498 SendToPlayers(vignetteUpdate.GetRawPacket());
499}
500
501template<class T>
502void Map::InitializeObject(T* /*obj*/) { }
503
504template<>
509
510template<>
515
516template<class T>
517bool Map::AddToMap(T* obj)
518{
520 if (obj->IsInWorld())
521 {
522 ASSERT(obj->IsInGrid());
523 obj->UpdateObjectVisibility(true);
524 return true;
525 }
526
527 CellCoord cellCoord = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
528 //It will create many problems (including crashes) if an object is not added to grid after creation
529 //The correct way to fix it is to make AddToMap return false and delete the object if it is not added to grid
530 //But now AddToMap is used in too many places, I will just see how many ASSERT failures it will cause
531 ASSERT(cellCoord.IsCoordValid());
532 if (!cellCoord.IsCoordValid())
533 {
534 TC_LOG_ERROR("maps", "Map::Add: Object {} has invalid coordinates X:{} Y:{} grid cell [{}:{}]", obj->GetGUID().ToString(), obj->GetPositionX(), obj->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
535 return false; //Should delete object
536 }
537
538 if (IsAlwaysActive())
539 obj->setActive(true);
540
541 Cell cell(cellCoord);
542 if (obj->isActiveObject())
544 else
545 EnsureGridCreated(GridCoord(cell.GridX(), cell.GridY()));
546 AddToGrid(obj, cell);
547 TC_LOG_DEBUG("maps", "Object {} enters grid[{}, {}]", obj->GetGUID().ToString(), cell.GridX(), cell.GridY());
548
549 //Must already be set before AddToMap. Usually during obj->Create.
550 //obj->SetMap(this);
551 obj->AddToWorld();
552
553 InitializeObject(obj);
554
555 if (obj->isActiveObject())
556 AddToActive(obj);
557
558 //something, such as vehicle, needs to be update immediately
559 //also, trigger needs to cast spell, if not update, cannot see visual
560 obj->SetIsNewObject(true);
561 obj->UpdateObjectVisibilityOnCreate();
562 obj->SetIsNewObject(false);
563 return true;
564}
565
566template<>
568{
569 //TODO: Needs clean up. An object should not be added to map twice.
570 if (obj->IsInWorld())
571 return true;
572
574 if (!cellCoord.IsCoordValid())
575 {
576 TC_LOG_ERROR("maps", "Map::Add: Object {} has invalid coordinates X:{} Y:{} grid cell [{}:{}]", obj->GetGUID().ToString(), obj->GetPositionX(), obj->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord);
577 return false; //Should delete object
578 }
579
580 _transports.insert(obj);
581
582 if (obj->GetExpectedMapId() == GetId())
583 {
584 obj->AddToWorld();
585
586 // Broadcast creation to players
587 for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
588 {
589 if (itr->GetSource()->GetTransport() != obj && itr->GetSource()->InSamePhase(obj))
590 {
591 UpdateData data(GetId());
592 obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
593 itr->GetSource()->m_visibleTransports.insert(obj->GetGUID());
594 WorldPacket packet;
595 data.BuildPacket(&packet);
596 itr->GetSource()->SendDirectMessage(&packet);
597 }
598 }
599 }
600
601 return true;
602}
603
604bool Map::IsGridLoaded(GridCoord const& p) const
605{
607}
608
610{
611 // Check for valid position
612 if (!obj->IsPositionValid())
613 return;
614
615 // Update mobs/objects in ALL visible cells around object!
617
618 for (uint32 x = area.low_bound.x_coord; x <= area.high_bound.x_coord; ++x)
619 {
620 for (uint32 y = area.low_bound.y_coord; y <= area.high_bound.y_coord; ++y)
621 {
622 // marked cells are those that have been visited
623 // don't visit the same cell twice
624 uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
625 if (isCellMarked(cell_id))
626 continue;
627
628 markCell(cell_id);
629 CellCoord pair(x, y);
630 Cell cell(pair);
631 cell.SetNoCreate();
632 Visit(cell, gridVisitor);
633 Visit(cell, worldVisitor);
634 }
635 }
636}
637
639{
640 // Nothing to do if no change
641 if (oldZone == newZone)
642 return;
643
644 if (oldZone != MAP_INVALID_ZONE)
645 {
646 uint32& oldZoneCount = _zonePlayerCountMap[oldZone];
647 ASSERT(oldZoneCount, "A player left zone %u (went to %u) - but there were no players in the zone!", oldZone, newZone);
648 --oldZoneCount;
649 }
650 ++_zonePlayerCountMap[newZone];
651}
652
653void Map::Update(uint32 t_diff)
654{
655 _dynamicTree.update(t_diff);
657 m_mmapTileRebuilder->Update(Milliseconds(t_diff));
658
661 {
662 Player* player = m_mapRefIter->GetSource();
663 if (player && player->IsInWorld())
664 {
665 //player->Update(t_diff);
666 WorldSession* session = player->GetSession();
667 MapSessionFilter updater(session);
668 session->Update(t_diff, updater);
669 }
670 }
671
673 if (_respawnCheckTimer <= t_diff)
674 {
678 }
679 else
680 _respawnCheckTimer -= t_diff;
681
684
685 Trinity::ObjectUpdater updater(t_diff);
686 // for creature
688 // for pets
690
691 // the player iterator is stored in the map object
692 // to make sure calls to Map::Remove don't invalidate it
694 {
695 Player* player = m_mapRefIter->GetSource();
696
697 if (!player || !player->IsInWorld())
698 continue;
699
700 // update players at tick
701 player->Update(t_diff);
702
703 VisitNearbyCellsOf(player, grid_object_update, world_object_update);
704
705 // If player is using far sight or mind vision, visit that object too
706 if (WorldObject* viewPoint = player->GetViewpoint())
707 VisitNearbyCellsOf(viewPoint, grid_object_update, world_object_update);
708
709 // Handle updates for creatures in combat with player and are more than 60 yards away
710 if (player->IsInCombat())
711 {
712 std::vector<Unit*> toVisit;
713 for (auto const& pair : player->GetCombatManager().GetPvECombatRefs())
714 if (Creature* unit = pair.second->GetOther(player)->ToCreature())
715 if (unit->GetMapId() == player->GetMapId() && !unit->IsWithinDistInMap(player, GetVisibilityRange(), false))
716 toVisit.push_back(unit);
717 for (Unit* unit : toVisit)
718 VisitNearbyCellsOf(unit, grid_object_update, world_object_update);
719 }
720
721 { // Update any creatures that own auras the player has applications of
722 std::unordered_set<Unit*> toVisit;
723 for (std::pair<uint32, AuraApplication*> pair : player->GetAppliedAuras())
724 {
725 if (Unit* caster = pair.second->GetBase()->GetCaster())
726 if (caster->GetTypeId() != TYPEID_PLAYER && !caster->IsWithinDistInMap(player, GetVisibilityRange(), false))
727 toVisit.insert(caster);
728 }
729 for (Unit* unit : toVisit)
730 VisitNearbyCellsOf(unit, grid_object_update, world_object_update);
731 }
732
733 { // Update player's summons
734 std::vector<Unit*> toVisit;
735
736 // Totems
737 for (ObjectGuid const& summonGuid : player->m_SummonSlot)
738 if (!summonGuid.IsEmpty())
739 if (Creature* unit = GetCreature(summonGuid))
740 if (unit->GetMapId() == player->GetMapId() && !unit->IsWithinDistInMap(player, GetVisibilityRange(), false))
741 toVisit.push_back(unit);
742
743 for (Unit* unit : toVisit)
744 VisitNearbyCellsOf(unit, grid_object_update, world_object_update);
745 }
746 }
747
748 // non-player active objects, increasing iterator in the loop in case of object removal
750 {
753
754 if (!obj || !obj->IsInWorld())
755 continue;
756
757 VisitNearbyCellsOf(obj, grid_object_update, world_object_update);
758 }
759
761 {
764 obj->Update(t_diff);
765 }
766
767 if (_vignetteUpdateTimer.Update(t_diff))
768 {
770 {
771 if (vignette->NeedUpdate)
772 {
774 vignette->FillPacket(vignetteUpdate.Updated);
775 vignetteUpdate.Write();
776 for (MapReference const& ref : m_mapRefManager)
777 if (Vignettes::CanSee(ref.GetSource(), *vignette))
778 ref.GetSource()->SendDirectMessage(vignetteUpdate.GetRawPacket());
779
780 vignette->NeedUpdate = false;
781 }
782 }
783 }
784
786
788 if (!m_scriptSchedule.empty())
789 {
790 i_scriptLock = true;
792 i_scriptLock = false;
793 }
794
797 {
798 for (auto&& zoneInfo : _zoneDynamicInfo)
799 if (zoneInfo.second.DefaultWeather && !zoneInfo.second.DefaultWeather->Update(_weatherUpdateTimer.GetInterval()))
800 zoneInfo.second.DefaultWeather.reset();
801
803 }
804
805 // update phase shift objects
806 GetMultiPersonalPhaseTracker().Update(this, t_diff);
807
811
812 if (!m_mapRefManager.empty() || !m_activeNonPlayers.empty())
814
815 sScriptMgr->OnMapUpdate(this, t_diff);
816
817 TC_METRIC_VALUE("map_creatures", uint64(GetObjectsStore().Size<Creature>()),
818 TC_METRIC_TAG("map_id", std::to_string(GetId())),
819 TC_METRIC_TAG("map_instanceid", std::to_string(GetInstanceId())));
820
821 TC_METRIC_VALUE("map_gameobjects", uint64(GetObjectsStore().Size<GameObject>()),
822 TC_METRIC_TAG("map_id", std::to_string(GetId())),
823 TC_METRIC_TAG("map_instanceid", std::to_string(GetInstanceId())));
824}
825
827{
828 template<class T>inline void resetNotify(GridRefManager<T> &m)
829 {
830 for (typename GridRefManager<T>::iterator iter=m.begin(); iter != m.end(); ++iter)
831 iter->GetSource()->ResetAllNotifies();
832 }
833 template<class T> void Visit(GridRefManager<T> &) { }
834 void Visit(CreatureMapType &m) { resetNotify<Creature>(m);}
835 void Visit(PlayerMapType &m) { resetNotify<Player>(m);}
836};
837
839{
841 {
842 NGridType *grid = i->GetSource();
843
844 if (grid->GetGridState() != GRID_STATE_ACTIVE)
845 continue;
846
848 if (!grid->getGridInfoRef()->getRelocationTimer().TPassed())
849 continue;
850
851 uint32 gx = grid->getX(), gy = grid->getY();
852
854 CellCoord cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
855
856 for (uint32 x = cell_min.x_coord; x < cell_max.x_coord; ++x)
857 {
858 for (uint32 y = cell_min.y_coord; y < cell_max.y_coord; ++y)
859 {
860 uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
861 if (!isCellMarked(cell_id))
862 continue;
863
864 CellCoord pair(x, y);
865 Cell cell(pair);
866 cell.SetNoCreate();
867
868 Trinity::DelayedUnitRelocation cell_relocation(cell, pair, *this, MAX_VISIBILITY_DISTANCE);
871 Visit(cell, grid_object_relocation);
872 Visit(cell, world_object_relocation);
873 }
874 }
875 }
876
877 ResetNotifier reset;
881 {
882 NGridType *grid = i->GetSource();
883
884 if (grid->GetGridState() != GRID_STATE_ACTIVE)
885 continue;
886
887 if (!grid->getGridInfoRef()->getRelocationTimer().TPassed())
888 continue;
889
891
892 uint32 gx = grid->getX(), gy = grid->getY();
893
895 CellCoord cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
896
897 for (uint32 x = cell_min.x_coord; x < cell_max.x_coord; ++x)
898 {
899 for (uint32 y = cell_min.y_coord; y < cell_max.y_coord; ++y)
900 {
901 uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
902 if (!isCellMarked(cell_id))
903 continue;
904
905 CellCoord pair(x, y);
906 Cell cell(pair);
907 cell.SetNoCreate();
908 Visit(cell, grid_notifier);
909 Visit(cell, world_notifier);
910 }
911 }
912 }
913}
914
915void Map::RemovePlayerFromMap(Player* player, bool remove)
916{
917 // Before leaving map, update zone/area for stats
918 player->UpdateZone(MAP_INVALID_ZONE, 0);
919 sScriptMgr->OnPlayerLeaveMap(this, player);
920
922
923 player->CombatStop();
924
925 bool const inWorld = player->IsInWorld();
926 player->RemoveFromWorld();
927 SendRemoveTransports(player);
928
929 if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
931
932 if (player->IsInGrid())
933 player->RemoveFromGrid();
934 else
935 ASSERT(remove); //maybe deleted in logoutplayer when player is not in a map
936
937 if (remove)
938 DeleteFromWorld(player);
939}
940
941template<class T>
942void Map::RemoveFromMap(T *obj, bool remove)
943{
944 bool const inWorld = obj->IsInWorld() && obj->GetTypeId() >= TYPEID_UNIT && obj->GetTypeId() <= TYPEID_GAMEOBJECT;
945 obj->RemoveFromWorld();
946 if (obj->isActiveObject())
947 RemoveFromActive(obj);
948
950
951 if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
952 obj->UpdateObjectVisibilityOnDestroy();
953
954 obj->RemoveFromGrid();
955
956 obj->ResetMap();
957
958 if (remove)
959 DeleteFromWorld(obj);
960}
961
962template<>
963void Map::RemoveFromMap(Transport* obj, bool remove)
964{
965 if (obj->IsInWorld())
966 {
967 obj->RemoveFromWorld();
968
969 UpdateData data(GetId());
970 if (obj->IsDestroyedObject())
971 obj->BuildDestroyUpdateBlock(&data);
972 else
973 obj->BuildOutOfRangeUpdateBlock(&data);
974
975 WorldPacket packet;
976 data.BuildPacket(&packet);
977 for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
978 {
979 if (itr->GetSource()->GetTransport() != obj && itr->GetSource()->m_visibleTransports.count(obj->GetGUID()))
980 {
981 itr->GetSource()->SendDirectMessage(&packet);
982 itr->GetSource()->m_visibleTransports.erase(obj->GetGUID());
983 }
984 }
985 }
986
988 {
989 TransportsContainer::iterator itr = _transports.find(obj);
990 if (itr == _transports.end())
991 return;
992 if (itr == _transportsUpdateIter)
994 _transports.erase(itr);
995 }
996 else
997 _transports.erase(obj);
998
999 obj->ResetMap();
1000
1001 if (remove)
1002 DeleteFromWorld(obj);
1003}
1004
1005template <typename T>
1006/*static*/ bool Map::CheckGridIntegrity(T* object, bool moved, char const* objType)
1007{
1008 Cell const& cur_cell = object->GetCurrentCell();
1009 Cell xy_cell(object->GetPositionX(), object->GetPositionY());
1010 if (xy_cell != cur_cell)
1011 {
1012 TC_LOG_DEBUG("maps", "{} {} X: {} Y: {} ({}) is in grid[{}, {}]cell[{}, {}] instead of grid[{}, {}]cell[{}, {}]",
1013 objType, object->GetGUID().ToString(),
1014 object->GetPositionX(), object->GetPositionY(), (moved ? "final" : "original"),
1015 cur_cell.GridX(), cur_cell.GridY(), cur_cell.CellX(), cur_cell.CellY(),
1016 xy_cell.GridX(), xy_cell.GridY(), xy_cell.CellX(), xy_cell.CellY());
1017 return true; // not crash at error, just output error in debug mode
1018 }
1019
1020 return true;
1021}
1022
1023void Map::PlayerRelocation(Player* player, float x, float y, float z, float orientation)
1024{
1025 ASSERT(player);
1026
1027 Cell old_cell(player->GetPositionX(), player->GetPositionY());
1028 Cell new_cell(x, y);
1029
1030 player->Relocate(x, y, z, orientation);
1031 if (player->IsVehicle())
1032 player->GetVehicleKit()->RelocatePassengers();
1033
1034 if (old_cell.DiffGrid(new_cell) || old_cell.DiffCell(new_cell))
1035 {
1036 TC_LOG_DEBUG("maps", "Player {} relocation grid[{}, {}]cell[{}, {}]->grid[{}, {}]cell[{}, {}]", player->GetName(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1037
1038 player->RemoveFromGrid();
1039
1040 if (old_cell.DiffGrid(new_cell))
1041 EnsureGridLoadedForActiveObject(new_cell, player);
1042
1043 AddToGrid(player, new_cell);
1044 }
1045
1046 player->UpdatePositionData();
1047 player->UpdateObjectVisibility(false);
1048}
1049
1050void Map::CreatureRelocation(Creature* creature, float x, float y, float z, float ang, bool respawnRelocationOnFail)
1051{
1052 ASSERT(CheckGridIntegrity(creature, false, "Creature"));
1053
1054 Cell new_cell(x, y);
1055
1056 if (!respawnRelocationOnFail && !getNGrid(new_cell.GridX(), new_cell.GridY()))
1057 return;
1058
1059 Cell old_cell = creature->GetCurrentCell();
1060 // delay creature move for grid/cell to grid/cell moves
1061 if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
1062 {
1063#ifdef TRINITY_DEBUG
1064 TC_LOG_DEBUG("maps", "Creature {} added to moving list from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", creature->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1065#endif
1066 AddCreatureToMoveList(creature, x, y, z, ang);
1067 // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList
1068 }
1069 else
1070 {
1071 creature->Relocate(x, y, z, ang);
1072 if (creature->IsVehicle())
1073 creature->GetVehicleKit()->RelocatePassengers();
1074 creature->UpdateObjectVisibility(false);
1075 creature->UpdatePositionData();
1077 }
1078
1079 ASSERT(CheckGridIntegrity(creature, true, "Creature"));
1080}
1081
1082void Map::GameObjectRelocation(GameObject* go, float x, float y, float z, float orientation, bool respawnRelocationOnFail)
1083{
1084 ASSERT(CheckGridIntegrity(go, false, "GameObject"));
1085 Cell new_cell(x, y);
1086
1087 if (!respawnRelocationOnFail && !getNGrid(new_cell.GridX(), new_cell.GridY()))
1088 return;
1089
1090 Cell old_cell = go->GetCurrentCell();
1091
1092 // delay creature move for grid/cell to grid/cell moves
1093 if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
1094 {
1095#ifdef TRINITY_DEBUG
1096 TC_LOG_DEBUG("maps", "GameObject {} added to moving list from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1097#endif
1098 AddGameObjectToMoveList(go, x, y, z, orientation);
1099 // in diffcell/diffgrid case notifiers called at finishing move go in Map::MoveAllGameObjectsInMoveList
1100 }
1101 else
1102 {
1103 go->Relocate(x, y, z, orientation);
1104 go->AfterRelocation();
1106 }
1107
1108 ASSERT(CheckGridIntegrity(go, true, "GameObject"));
1109}
1110
1111void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float z, float orientation)
1112{
1113 ASSERT(CheckGridIntegrity(dynObj, false, "DynamicObject"));
1114 Cell new_cell(x, y);
1115
1116 if (!getNGrid(new_cell.GridX(), new_cell.GridY()))
1117 return;
1118
1119 Cell old_cell = dynObj->GetCurrentCell();
1120
1121 // delay creature move for grid/cell to grid/cell moves
1122 if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
1123 {
1124#ifdef TRINITY_DEBUG
1125 TC_LOG_DEBUG("maps", "GameObject {} added to moving list from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", dynObj->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1126#endif
1127 AddDynamicObjectToMoveList(dynObj, x, y, z, orientation);
1128 // in diffcell/diffgrid case notifiers called at finishing move dynObj in Map::MoveAllGameObjectsInMoveList
1129 }
1130 else
1131 {
1132 dynObj->Relocate(x, y, z, orientation);
1133 dynObj->UpdatePositionData();
1134 dynObj->UpdateObjectVisibility(false);
1136 }
1137
1138 ASSERT(CheckGridIntegrity(dynObj, true, "DynamicObject"));
1139}
1140
1141void Map::AreaTriggerRelocation(AreaTrigger* at, float x, float y, float z, float orientation)
1142{
1143 ASSERT(CheckGridIntegrity(at, false, "AreaTrigger"));
1144 Cell new_cell(x, y);
1145
1146 if (!getNGrid(new_cell.GridX(), new_cell.GridY()))
1147 return;
1148
1149 Cell old_cell = at->GetCurrentCell();
1150
1151 // delay areatrigger move for grid/cell to grid/cell moves
1152 if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell))
1153 {
1154#ifdef TRINITY_DEBUG
1155 TC_LOG_DEBUG("maps", "AreaTrigger ({}) added to moving list from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", at->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1156#endif
1157 AddAreaTriggerToMoveList(at, x, y, z, orientation);
1158 // in diffcell/diffgrid case notifiers called at finishing move at in Map::MoveAllAreaTriggersInMoveList
1159 }
1160 else
1161 {
1162 at->Relocate(x, y, z, orientation);
1163 at->UpdateShape();
1164 at->UpdateObjectVisibility(false);
1166 }
1167
1168 ASSERT(CheckGridIntegrity(at, true, "AreaTrigger"));
1169}
1170
1171void Map::AddCreatureToMoveList(Creature* c, float x, float y, float z, float ang)
1172{
1173 if (_creatureToMoveLock) //can this happen?
1174 return;
1175
1177 _creaturesToMove.push_back(c);
1178 c->SetNewCellPosition(x, y, z, ang);
1179}
1180
1182{
1183 if (_creatureToMoveLock) //can this happen?
1184 return;
1185
1188}
1189
1190void Map::AddGameObjectToMoveList(GameObject* go, float x, float y, float z, float ang)
1191{
1192 if (_gameObjectsToMoveLock) //can this happen?
1193 return;
1194
1196 _gameObjectsToMove.push_back(go);
1197 go->SetNewCellPosition(x, y, z, ang);
1198}
1199
1201{
1202 if (_gameObjectsToMoveLock) //can this happen?
1203 return;
1204
1207}
1208
1209void Map::AddDynamicObjectToMoveList(DynamicObject* dynObj, float x, float y, float z, float ang)
1210{
1211 if (_dynamicObjectsToMoveLock) //can this happen?
1212 return;
1213
1215 _dynamicObjectsToMove.push_back(dynObj);
1216 dynObj->SetNewCellPosition(x, y, z, ang);
1217}
1218
1220{
1221 if (_dynamicObjectsToMoveLock) //can this happen?
1222 return;
1223
1226}
1227
1228void Map::AddAreaTriggerToMoveList(AreaTrigger* at, float x, float y, float z, float ang)
1229{
1230 if (_areaTriggersToMoveLock) //can this happen?
1231 return;
1232
1234 _areaTriggersToMove.push_back(at);
1235 at->SetNewCellPosition(x, y, z, ang);
1236}
1237
1239{
1240 if (_areaTriggersToMoveLock) //can this happen?
1241 return;
1242
1245}
1246
1248{
1249 _creatureToMoveLock = true;
1250 for (std::vector<Creature*>::iterator itr = _creaturesToMove.begin(); itr != _creaturesToMove.end(); ++itr)
1251 {
1252 Creature* c = *itr;
1253 if (c->FindMap() != this) //pet is teleported to another map
1254 continue;
1255
1257 {
1259 continue;
1260 }
1261
1263 if (!c->IsInWorld())
1264 continue;
1265
1266 // do move or do move to respawn or remove creature if previous all fail
1268 {
1269 // update pos
1270 c->Relocate(c->_newPosition);
1271 if (c->IsVehicle())
1273 //CreatureRelocationNotify(c, new_cell, new_cell.cellCoord());
1274 c->UpdatePositionData();
1275 c->UpdateObjectVisibility(false);
1276 }
1277 else
1278 {
1279 // if creature can't be move in new cell/grid (not loaded) move it to repawn cell/grid
1280 // creature coordinates will be updated and notifiers send
1281 if (!CreatureRespawnRelocation(c, false))
1282 {
1283 // ... or unload (if respawn grid also not loaded)
1284#ifdef TRINITY_DEBUG
1285 TC_LOG_DEBUG("maps", "Creature {} cannot be move to unloaded respawn grid.", c->GetGUID().ToString());
1286#endif
1287 //AddObjectToRemoveList(Pet*) should only be called in Pet::Remove
1288 //This may happen when a player just logs in and a pet moves to a nearby unloaded cell
1289 //To avoid this, we can load nearby cells when player log in
1290 //But this check is always needed to ensure safety
1292 //need to check why pet is frequently relocated to an unloaded cell
1293 if (c->IsPet())
1294 ((Pet*)c)->Remove(PET_SAVE_NOT_IN_SLOT, true);
1295 else
1297 }
1298 }
1299 }
1300 _creaturesToMove.clear();
1301 _creatureToMoveLock = false;
1302}
1303
1305{
1307 for (std::vector<GameObject*>::iterator itr = _gameObjectsToMove.begin(); itr != _gameObjectsToMove.end(); ++itr)
1308 {
1309 GameObject* go = *itr;
1310 if (go->FindMap() != this) //transport is teleported to another map
1311 continue;
1312
1314 {
1316 continue;
1317 }
1318
1320 if (!go->IsInWorld())
1321 continue;
1322
1323 // do move or do move to respawn or remove creature if previous all fail
1325 {
1326 // update pos
1327 go->Relocate(go->_newPosition);
1328 go->AfterRelocation();
1329 }
1330 else
1331 {
1332 // if GameObject can't be move in new cell/grid (not loaded) move it to repawn cell/grid
1333 // GameObject coordinates will be updated and notifiers send
1334 if (!GameObjectRespawnRelocation(go, false))
1335 {
1336 // ... or unload (if respawn grid also not loaded)
1337#ifdef TRINITY_DEBUG
1338 TC_LOG_DEBUG("maps", "GameObject {} cannot be move to unloaded respawn grid.", go->GetGUID().ToString());
1339#endif
1341 }
1342 }
1343 }
1344 _gameObjectsToMove.clear();
1345 _gameObjectsToMoveLock = false;
1346}
1347
1349{
1351 for (std::vector<DynamicObject*>::iterator itr = _dynamicObjectsToMove.begin(); itr != _dynamicObjectsToMove.end(); ++itr)
1352 {
1353 DynamicObject* dynObj = *itr;
1354 if (dynObj->FindMap() != this) //transport is teleported to another map
1355 continue;
1356
1358 {
1360 continue;
1361 }
1362
1364 if (!dynObj->IsInWorld())
1365 continue;
1366
1367 // do move or do move to respawn or remove creature if previous all fail
1369 {
1370 // update pos
1371 dynObj->Relocate(dynObj->_newPosition);
1372 dynObj->UpdatePositionData();
1373 dynObj->UpdateObjectVisibility(false);
1374 }
1375 else
1376 {
1377#ifdef TRINITY_DEBUG
1378 TC_LOG_DEBUG("maps", "DynamicObject {} cannot be moved to unloaded grid.", dynObj->GetGUID().ToString());
1379#endif
1380 }
1381 }
1382
1383 _dynamicObjectsToMove.clear();
1385}
1386
1388{
1390 for (std::vector<AreaTrigger*>::iterator itr = _areaTriggersToMove.begin(); itr != _areaTriggersToMove.end(); ++itr)
1391 {
1392 AreaTrigger* at = *itr;
1393 if (at->FindMap() != this) //transport is teleported to another map
1394 continue;
1395
1397 {
1399 continue;
1400 }
1401
1403 if (!at->IsInWorld())
1404 continue;
1405
1406 // do move or do move to respawn or remove creature if previous all fail
1408 {
1409 // update pos
1410 at->Relocate(at->_newPosition);
1411 at->UpdateShape();
1412 at->UpdateObjectVisibility(false);
1413 }
1414 else
1415 {
1416#ifdef TRINITY_DEBUG
1417 TC_LOG_DEBUG("maps", "AreaTrigger {} cannot be moved to unloaded grid.", at->GetGUID().ToString());
1418#endif
1419 }
1420 }
1421
1422 _areaTriggersToMove.clear();
1424}
1425
1426template <typename T>
1427bool Map::MapObjectCellRelocation(T* object, Cell new_cell, [[maybe_unused]] char const* objType)
1428{
1429 Cell const& old_cell = object->GetCurrentCell();
1430 if (!old_cell.DiffGrid(new_cell)) // in same grid
1431 {
1432 // if in same cell then none do
1433 if (old_cell.DiffCell(new_cell))
1434 {
1435#ifdef TRINITY_DEBUG
1436 TC_LOG_DEBUG("maps", "{} {} moved in grid[{}, {}] from cell[{}, {}] to cell[{}, {}].", objType, object->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY());
1437#endif
1438
1439 object->RemoveFromGrid();
1440 AddToGrid(object, new_cell);
1441 }
1442 else
1443 {
1444#ifdef TRINITY_DEBUG
1445 TC_LOG_DEBUG("maps", "{} {} moved in same grid[{}, {}]cell[{}, {}].", objType, object->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY());
1446#endif
1447 }
1448
1449 return true;
1450 }
1451
1452 // in diff. grids but active creature
1453 if (object->isActiveObject())
1454 {
1455 EnsureGridLoadedForActiveObject(new_cell, object);
1456
1457#ifdef TRINITY_DEBUG
1458 TC_LOG_DEBUG("maps", "Active {} {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", objType, object->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1459#endif
1460
1461 object->RemoveFromGrid();
1462 AddToGrid(object, new_cell);
1463
1464 return true;
1465 }
1466
1467 if (Creature* c = object->ToCreature())
1468 if (c->GetCharmerOrOwnerGUID().IsPlayer())
1469 EnsureGridLoaded(new_cell);
1470
1471 // in diff. loaded grid normal object
1472 if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY())))
1473 {
1474#ifdef TRINITY_DEBUG
1475 TC_LOG_DEBUG("maps", "{} {} moved from grid[{}, {}]cell[{}, {}] to grid[{}, {}]cell[{}, {}].", objType, object->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1476#endif
1477
1478 object->RemoveFromGrid();
1479 EnsureGridCreated(GridCoord(new_cell.GridX(), new_cell.GridY()));
1480 AddToGrid(object, new_cell);
1481
1482 return true;
1483 }
1484
1485 // fail to move: normal object attempt move to unloaded grid
1486#ifdef TRINITY_DEBUG
1487 TC_LOG_DEBUG("maps", "{} {} attempted to move from grid[{}, {}]cell[{}, {}] to unloaded grid[{}, {}]cell[{}, {}].", objType, object->GetGUID().ToString(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
1488#endif
1489 return false;
1490}
1491
1493{
1494 return MapObjectCellRelocation(c, new_cell, "Creature");
1495}
1496
1498{
1499 return MapObjectCellRelocation(go, new_cell, "GameObject");
1500}
1501
1503{
1504 return MapObjectCellRelocation(go, new_cell, "DynamicObject");
1505}
1506
1508{
1509 return MapObjectCellRelocation(at, new_cell, "AreaTrigger");
1510}
1511
1512bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly)
1513{
1514 Position resp = c->GetRespawnPosition();
1515 Cell resp_cell(resp.GetPositionX(), resp.GetPositionY());
1516
1517 //creature will be unloaded with grid
1518 if (diffGridOnly && !c->GetCurrentCell().DiffGrid(resp_cell))
1519 return true;
1520
1521 c->CombatStop();
1522 c->GetMotionMaster()->Clear();
1523
1524#ifdef TRINITY_DEBUG
1525 TC_LOG_DEBUG("maps", "Creature {} moved from grid[{}, {}]cell[{}, {}] to respawn grid[{}, {}]cell[{}, {}].", c->GetGUID().ToString(), c->GetCurrentCell().GridX(), c->GetCurrentCell().GridY(), c->GetCurrentCell().CellX(), c->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY());
1526#endif
1527
1528 // teleport it to respawn point (like normal respawn if player see)
1529 if (CreatureCellRelocation(c, resp_cell))
1530 {
1531 c->Relocate(resp);
1532 c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators
1533 //CreatureRelocationNotify(c, resp_cell, resp_cell.GetCellCoord());
1534 c->UpdatePositionData();
1535 c->UpdateObjectVisibility(false);
1536 return true;
1537 }
1538
1539 return false;
1540}
1541
1543{
1544 Position resp = go->GetRespawnPosition();
1545 Cell resp_cell(resp.GetPositionX(), resp.GetPositionY());
1546
1547 //GameObject will be unloaded with grid
1548 if (diffGridOnly && !go->GetCurrentCell().DiffGrid(resp_cell))
1549 return true;
1550
1551#ifdef TRINITY_DEBUG
1552 TC_LOG_DEBUG("maps", "GameObject {} moved from grid[{}, {}]cell[{}, {}] to respawn grid[{}, {}]cell[{}, {}].", go->GetGUID().ToString(), go->GetCurrentCell().GridX(), go->GetCurrentCell().GridY(), go->GetCurrentCell().CellX(), go->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY());
1553#endif
1554
1555 // teleport it to respawn point (like normal respawn if player see)
1556 if (GameObjectCellRelocation(go, resp_cell))
1557 {
1558 go->Relocate(resp);
1559 go->UpdatePositionData();
1560 go->UpdateObjectVisibility(false);
1561 return true;
1562 }
1563
1564 return false;
1565}
1566
1567bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
1568{
1569 const uint32 x = ngrid.getX();
1570 const uint32 y = ngrid.getY();
1571
1572 {
1573 if (!unloadAll)
1574 {
1575 //pets, possessed creatures (must be active), transport passengers
1576 if (ngrid.HasWorldObjectsInNGrid<Creature>())
1577 return false;
1578
1579 if (ActiveObjectsNearGrid(ngrid))
1580 return false;
1581 }
1582
1583 TC_LOG_DEBUG("maps", "Unloading grid[{}, {}] for map {}", x, y, GetId());
1584
1585 if (!unloadAll)
1586 {
1587 // Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids
1588 // Must know real mob position before move
1592
1593 // move creatures to respawn grids if this is diff.grid or to remove list
1594 ObjectGridEvacuator worker;
1596 ngrid.VisitAllGrids(visitor);
1597
1598 // Finish creature moves, remove and delete all creatures with delayed remove before unload
1602 }
1603
1604 {
1605 ObjectGridCleaner worker;
1607 ngrid.VisitAllGrids(visitor);
1608 }
1609
1611
1612 // After removing all objects from the map, purge empty tracked phases
1614
1615 {
1616 ObjectGridUnloader worker;
1618 ngrid.VisitAllGrids(visitor);
1619 }
1620
1621 ASSERT(i_objectsToRemove.empty());
1622
1623 delete &ngrid;
1624 setNGrid(nullptr, x, y);
1625 }
1626 int gx = (MAX_NUMBER_OF_GRIDS - 1) - x;
1627 int gy = (MAX_NUMBER_OF_GRIDS - 1) - y;
1628
1629 m_terrain->UnloadMap(gx, gy);
1630
1631 TC_LOG_DEBUG("maps", "Unloading grid[{}, {}] for map {} finished", x, y, GetId());
1632 return true;
1633}
1634
1636{
1637 if (HavePlayers())
1638 {
1639 for (MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
1640 {
1641 Player* player = itr->GetSource();
1642 if (!player->IsBeingTeleportedFar())
1643 {
1644 // this is happening for bg
1645 TC_LOG_ERROR("maps", "Map::UnloadAll: player {} is still in map {} during unload, this should not happen!", player->GetName(), GetId());
1646 player->TeleportTo(player->m_homebind);
1647 }
1648 }
1649 }
1650}
1651
1653{
1654 // clear all delayed moves, useless anyway do this moves before map unload.
1655 _creaturesToMove.clear();
1656 _gameObjectsToMove.clear();
1657
1659 {
1660 NGridType &grid(*i->GetSource());
1661 ++i;
1662 UnloadGrid(grid, true); // deletes the grid and removes it from the GridRefManager
1663 }
1664
1665 for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();)
1666 {
1667 Transport* transport = *itr;
1668 ++itr;
1669
1670 RemoveFromMap<Transport>(transport, true);
1671 }
1672
1673 for (auto& cellCorpsePair : _corpsesByCell)
1674 {
1675 for (Corpse* corpse : cellCorpsePair.second)
1676 {
1677 corpse->RemoveFromWorld();
1678 corpse->ResetMap();
1679 delete corpse;
1680 }
1681 }
1682
1683 _corpsesByCell.clear();
1684 _corpsesByPlayer.clear();
1685 _corpseBones.clear();
1686}
1687
1688void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data,
1689 Optional<map_liquidHeaderTypeFlags> reqLiquidType, float collisionHeight)
1690{
1691 m_terrain->GetFullTerrainStatusForPosition(phaseShift, GetId(), x, y, z, data, reqLiquidType, collisionHeight, &_dynamicTree);
1692}
1693
1694ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, Optional<map_liquidHeaderTypeFlags> ReqLiquidType, LiquidData* data,
1695 float collisionHeight)
1696{
1697 return m_terrain->GetLiquidStatus(phaseShift, GetId(), x, y, z, ReqLiquidType, data, collisionHeight);
1698}
1699
1700uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z)
1701{
1702 return m_terrain->GetAreaId(phaseShift, GetId(), x, y, z, &_dynamicTree);
1703}
1704
1705uint32 Map::GetZoneId(PhaseShift const& phaseShift, float x, float y, float z)
1706{
1707 return m_terrain->GetZoneId(phaseShift, GetId(), x, y, z, &_dynamicTree);
1708}
1709
1710void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z)
1711{
1712 return m_terrain->GetZoneAndAreaId(phaseShift, GetId(), zoneid, areaid, x, y, z, &_dynamicTree);
1713}
1714
1715float Map::GetMinHeight(PhaseShift const& phaseShift, float x, float y)
1716{
1717 return m_terrain->GetMinHeight(phaseShift, GetId(), x, y);
1718}
1719
1720float Map::GetGridHeight(PhaseShift const& phaseShift, float x, float y)
1721{
1722 return m_terrain->GetGridHeight(phaseShift, GetId(), x, y);
1723}
1724
1725float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap, float maxSearchDist)
1726{
1727 return m_terrain->GetStaticHeight(phaseShift, GetId(), x, y, z, checkVMap, maxSearchDist);
1728}
1729
1730float Map::GetWaterLevel(PhaseShift const& phaseShift, float x, float y)
1731{
1732 return m_terrain->GetWaterLevel(phaseShift, GetId(), x, y);
1733}
1734
1735bool Map::IsInWater(PhaseShift const& phaseShift, float x, float y, float z, LiquidData* data)
1736{
1737 return m_terrain->IsInWater(phaseShift, GetId(), x, y, z, data);
1738}
1739
1740bool Map::IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z)
1741{
1742 return m_terrain->IsUnderWater(phaseShift, GetId(), x, y, z);
1743}
1744
1745float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground, bool swim, float collisionHeight)
1746{
1747 return m_terrain->GetWaterOrGroundLevel(phaseShift, GetId(), x, y, z, ground, swim, collisionHeight, &_dynamicTree);
1748}
1749
1750bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const
1751{
1752 if ((checks & LINEOFSIGHT_CHECK_VMAP)
1753 && !VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(PhasingHandler::GetTerrainMapId(phaseShift, GetId(), m_terrain.get(), x1, y1), x1, y1, z1, x2, y2, z2, ignoreFlags))
1754 return false;
1755 if (sWorld->getBoolConfig(CONFIG_CHECK_GOBJECT_LOS) && (checks & LINEOFSIGHT_CHECK_GOBJECT)
1756 && !_dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phaseShift))
1757 return false;
1758 return true;
1759}
1760
1761bool Map::getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
1762{
1763 G3D::Vector3 startPos(x1, y1, z1);
1764 G3D::Vector3 dstPos(x2, y2, z2);
1765
1766 G3D::Vector3 resultPos;
1767 bool result = _dynamicTree.getObjectHitPos(startPos, dstPos, resultPos, modifyDist, phaseShift);
1768
1769 rx = resultPos.x;
1770 ry = resultPos.y;
1771 rz = resultPos.z;
1772 return result;
1773}
1774
1776{
1778 return;
1779
1780 uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, GetId(), m_terrain.get(), model.GetPosition().x, model.GetPosition().y);
1781
1782 G3D::AABox const& bounds = model.getBounds();
1783
1784 GridCoord low = Trinity::ComputeGridCoord(bounds.high().x, bounds.high().y);
1785 low.x_coord = (MAX_NUMBER_OF_GRIDS - 1) - low.x_coord;
1786 low.y_coord = (MAX_NUMBER_OF_GRIDS - 1) - low.y_coord;
1787
1788 GridCoord high = Trinity::ComputeGridCoord(bounds.low().x, bounds.low().y);
1789 high.x_coord = (MAX_NUMBER_OF_GRIDS - 1) - high.x_coord;
1790 high.y_coord = (MAX_NUMBER_OF_GRIDS - 1) - high.y_coord;
1791
1792 for (uint32 x = low.x_coord; x <= high.x_coord; ++x)
1793 for (uint32 y = low.y_coord; y <= high.y_coord; ++y)
1794 m_mmapTileRebuilder->AddTile(terrainMapId, x, y);
1795}
1796
1798{
1799 MapEntry const* entry = sMapStore.LookupEntry(mapid);
1800 if (!entry)
1802
1803 if (!entry->IsDungeon())
1804 return TRANSFER_ABORT_NONE;
1805
1806 Difficulty targetDifficulty = player->GetDifficultyID(entry);
1807 // Get the highest available difficulty if current setting is higher than the instance allows
1808 MapDifficultyEntry const* mapDiff = sDB2Manager.GetDownscaledMapDifficultyData(mapid, targetDifficulty);
1809 if (!mapDiff)
1811
1812 //Bypass checks for GMs
1813 if (player->IsGameMaster())
1814 return TRANSFER_ABORT_NONE;
1815
1816 //Other requirements
1817 {
1819 if (!player->Satisfy(sObjectMgr->GetAccessRequirement(mapid, targetDifficulty), mapid, &params, true))
1820 return params;
1821 }
1822
1823 Group* group = player->GetGroup();
1824 if (entry->IsRaid() && entry->Expansion() >= sWorld->getIntConfig(CONFIG_EXPANSION)) // can only enter in a raid group but raids from old expansion don't need a group
1825 if ((!group || !group->isRaidGroup()) && !sWorld->getBoolConfig(CONFIG_INSTANCE_IGNORE_RAID))
1827
1828 if (entry->Instanceable())
1829 {
1830 //Get instance where player's group is bound & its map
1831 uint32 instanceIdToCheck = sMapMgr->FindInstanceIdForPlayer(mapid, player);
1832 if (Map* boundMap = sMapMgr->FindMap(mapid, instanceIdToCheck))
1833 if (TransferAbortParams denyReason = boundMap->CannotEnter(player))
1834 return denyReason;
1835
1836 // players are only allowed to enter 10 instances per hour
1837 if (!entry->GetFlags2().HasFlag(MapFlags2::IgnoreInstanceFarmLimit) && entry->IsDungeon() && !player->CheckInstanceCount(instanceIdToCheck) && !player->isDead())
1839 }
1840
1841 return TRANSFER_ABORT_NONE;
1842}
1843
1844char const* Map::GetMapName() const
1845{
1846 return i_mapEntry->MapName[sWorld->GetDefaultDbcLocale()];
1847}
1848
1850{
1851 TC_LOG_DEBUG("maps", "Creating player data for himself {}", player->GetGUID().ToString());
1852
1853 UpdateData data(player->GetMapId());
1854
1855 // attach to player data current transport data
1856 if (Transport* transport = dynamic_cast<Transport*>(player->GetTransport()))
1857 {
1858 transport->BuildCreateUpdateBlockForPlayer(&data, player);
1859 player->m_visibleTransports.insert(transport->GetGUID());
1860 }
1861
1862 // build data for self presence in world at own client (one time for map)
1863 player->BuildCreateUpdateBlockForPlayer(&data, player);
1864
1865 // build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map
1866 if (Transport* transport = dynamic_cast<Transport*>(player->GetTransport()))
1867 for (WorldObject* passenger : transport->GetPassengers())
1868 if (player != passenger && player->HaveAtClient(passenger))
1869 passenger->BuildCreateUpdateBlockForPlayer(&data, player);
1870
1871 WorldPacket packet;
1872 data.BuildPacket(&packet);
1873 player->SendDirectMessage(&packet);
1874
1875 // client will respond to SMSG_UPDATE_OBJECT that contains ThisIsYou = true with CMSG_MOVE_INIT_ACTIVE_MOVER_COMPLETE
1877}
1878
1880{
1881 // Hack to send out transports
1882 UpdateData transData(GetId());
1883 for (Transport* transport : _transports)
1884 {
1885 if (transport->IsInWorld() && transport != player->GetTransport() && player->InSamePhase(transport))
1886 {
1887 transport->BuildCreateUpdateBlockForPlayer(&transData, player);
1888 player->m_visibleTransports.insert(transport->GetGUID());
1889 }
1890 }
1891
1892 if (!transData.HasData())
1893 return;
1894
1895 WorldPacket packet;
1896 transData.BuildPacket(&packet);
1897 player->SendDirectMessage(&packet);
1898}
1899
1901{
1902 // Hack to send out transports
1903 UpdateData transData(player->GetMapId());
1904 for (Transport* transport : _transports)
1905 {
1906 if (player->m_visibleTransports.count(transport->GetGUID()) && transport != player->GetTransport())
1907 {
1908 transport->BuildOutOfRangeUpdateBlock(&transData);
1909 player->m_visibleTransports.erase(transport->GetGUID());
1910 }
1911 }
1912
1913 if (!transData.HasData())
1914 return;
1915
1916 WorldPacket packet;
1917 transData.BuildPacket(&packet);
1918 player->SendDirectMessage(&packet);
1919}
1920
1922{
1923 // Hack to send out transports
1924 UpdateData transData(player->GetMapId());
1925 for (Transport* transport : _transports)
1926 {
1927 if (!transport->IsInWorld())
1928 continue;
1929
1930 auto transportItr = player->m_visibleTransports.find(transport->GetGUID());
1931 if (player->InSamePhase(transport))
1932 {
1933 if (transportItr == player->m_visibleTransports.end())
1934 {
1935 transport->BuildCreateUpdateBlockForPlayer(&transData, player);
1936 player->m_visibleTransports.insert(transport->GetGUID());
1937 }
1938 }
1939 else if (transportItr != player->m_visibleTransports.end())
1940 {
1941 transport->BuildOutOfRangeUpdateBlock(&transData);
1942 player->m_visibleTransports.erase(transportItr);
1943 }
1944 }
1945
1946 if (!transData.HasData())
1947 return;
1948
1949 WorldPacket packet;
1950 transData.BuildPacket(&packet);
1951 player->GetSession()->SendPacket(&packet);
1952}
1953
1954inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y)
1955{
1957 {
1958 TC_LOG_ERROR("maps", "map::setNGrid() Invalid grid coordinates found: {}, {}!", x, y);
1959 ABORT();
1960 }
1961 i_grids[x][y] = grid;
1962}
1963
1965{
1966 UpdateDataMapType update_players;
1967
1968 while (!_updateObjects.empty())
1969 {
1970 BaseEntity* obj = *_updateObjects.begin();
1971 ASSERT(obj->IsInWorld());
1972 _updateObjects.erase(_updateObjects.begin());
1973 obj->BuildUpdate(update_players);
1974 }
1975
1976 WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
1977 for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
1978 {
1979 iter->second.BuildPacket(&packet);
1980 iter->first->SendDirectMessage(&packet);
1981 packet.clear(); // clean the string
1982 }
1983}
1984
1985// CheckRespawn MUST do one of the following:
1986// -) return true
1987// -) set info->respawnTime to zero, which indicates the respawn time should be deleted (and will never be processed again without outside intervention)
1988// -) set info->respawnTime to a new respawn time, which must be strictly GREATER than the current time (GameTime::GetGameTime())
1990{
1991 SpawnData const* data = sObjectMgr->GetSpawnData(info->type, info->spawnId);
1992 ASSERT(data, "Invalid respawn info with type %u, spawnID " UI64FMTD " in respawn queue.", info->type, info->spawnId);
1993
1994 // First, check if this creature's spawn group is inactive
1996 {
1997 info->respawnTime = 0;
1998 return false;
1999 }
2000
2001 // Next, check if there's already an instance of this object that would block the respawn
2002 bool alreadyExists = false;
2003 switch (info->type)
2004 {
2006 {
2007 // escort check for creatures only (if the world config boolean is set)
2008 bool const isEscort = (sWorld->getBoolConfig(CONFIG_RESPAWN_DYNAMIC_ESCORTNPC) && data->spawnGroupData->flags & SPAWNGROUP_FLAG_ESCORTQUESTNPC);
2009
2010 auto range = _creatureBySpawnIdStore.equal_range(info->spawnId);
2011 for (auto it = range.first; it != range.second; ++it)
2012 {
2013 Creature* creature = it->second;
2014 if (!creature->IsAlive())
2015 continue;
2016 // escort NPCs are allowed to respawn as long as all other instances are already escorting
2017 if (isEscort && creature->IsEscorted())
2018 continue;
2019 alreadyExists = true;
2020 break;
2021 }
2022 break;
2023 }
2025 // gameobject check is simpler - they cannot be dead or escorting
2027 alreadyExists = true;
2028 break;
2029 default:
2030 ABORT_MSG("Invalid spawn type %u with spawnId " UI64FMTD " on map %u", uint32(info->type), info->spawnId, GetId());
2031 return true;
2032 }
2033 if (alreadyExists)
2034 {
2035 info->respawnTime = 0;
2036 return false;
2037 }
2038
2039 // next, check linked respawn time
2040 ObjectGuid thisGUID = info->type == SPAWN_TYPE_GAMEOBJECT
2041 ? ObjectGuid::Create<HighGuid::GameObject>(GetId(), info->entry, info->spawnId)
2042 : ObjectGuid::Create<HighGuid::Creature>(GetId(), info->entry, info->spawnId);
2043 if (time_t linkedTime = GetLinkedRespawnTime(thisGUID))
2044 {
2045 time_t now = GameTime::GetGameTime();
2046 time_t respawnTime;
2047 if (linkedTime == std::numeric_limits<time_t>::max())
2048 respawnTime = linkedTime;
2049 else if (sObjectMgr->GetLinkedRespawnGuid(thisGUID) == thisGUID) // never respawn, save "something" in DB
2050 respawnTime = now + WEEK;
2051 else // set us to check again shortly after linked unit
2052 respawnTime = std::max<time_t>(now, linkedTime) + urand(5, 15);
2053 info->respawnTime = respawnTime;
2054 return false;
2055 }
2056 // everything ok, let's spawn
2057 return true;
2058}
2059
2061{
2062 if (info->respawnTime <= GameTime::GetGameTime())
2063 return;
2065 _respawnTimes->increase(static_cast<RespawnInfoWithHandle*>(info)->handle);
2066 SaveRespawnInfoDB(*info, dbTrans);
2067}
2068
2070{
2071 std::vector<WorldObject*> toUnload;
2072 switch (type)
2073 {
2075 for (auto const& pair : Trinity::Containers::MapEqualRange(GetCreatureBySpawnIdStore(), spawnId))
2076 toUnload.push_back(pair.second);
2077 break;
2079 for (auto const& pair : Trinity::Containers::MapEqualRange(GetGameObjectBySpawnIdStore(), spawnId))
2080 toUnload.push_back(pair.second);
2081 break;
2082 default:
2083 break;
2084 }
2085
2086 for (WorldObject* o : toUnload)
2088
2089 return toUnload.size();
2090}
2091
2093{
2094 if (!info.spawnId)
2095 {
2096 TC_LOG_ERROR("maps", "Attempt to insert respawn info for zero spawn id (type {})", uint32(info.type));
2097 return false;
2098 }
2099
2100 RespawnInfoMap* bySpawnIdMap = GetRespawnMapForType(info.type);
2101 if (!bySpawnIdMap)
2102 return false;
2103
2104 // check if we already have the maximum possible number of respawns scheduled
2105 if (SpawnData::TypeHasData(info.type))
2106 {
2107 auto it = bySpawnIdMap->find(info.spawnId);
2108 if (it != bySpawnIdMap->end()) // spawnid already has a respawn scheduled
2109 {
2110 RespawnInfo* const existing = it->second;
2111 if (info.respawnTime <= existing->respawnTime) // delete existing in this case
2112 DeleteRespawnInfo(existing);
2113 else
2114 return false;
2115 }
2116 ASSERT(bySpawnIdMap->find(info.spawnId) == bySpawnIdMap->end(), "Insertion of respawn info with id (%u," UI64FMTD ") into spawn id map failed - state desync.", uint32(info.type), info.spawnId);
2117 }
2118 else
2119 ABORT_MSG("Invalid respawn info for spawn id (%u," UI64FMTD ") being inserted", uint32(info.type), info.spawnId);
2120
2122 ri->handle = _respawnTimes->push(ri);
2123 bySpawnIdMap->emplace(ri->spawnId, ri);
2124 return true;
2125}
2126
2127static void PushRespawnInfoFrom(std::vector<RespawnInfo const*>& data, RespawnInfoMap const& map)
2128{
2129 data.reserve(data.size() + map.size());
2130 for (auto const& pair : map)
2131 data.push_back(pair.second);
2132}
2133
2134void Map::GetRespawnInfo(std::vector<RespawnInfo const*>& respawnData, SpawnObjectTypeMask types) const
2135{
2136 if (types & SPAWN_TYPEMASK_CREATURE)
2138 if (types & SPAWN_TYPEMASK_GAMEOBJECT)
2140}
2141
2143{
2144 RespawnInfoMap const* map = GetRespawnMapForType(type);
2145 if (!map)
2146 return nullptr;
2147 auto it = map->find(spawnId);
2148 if (it == map->end())
2149 return nullptr;
2150 return it->second;
2151}
2152
2153void Map::UnloadAllRespawnInfos() // delete everything from memory
2154{
2155 for (RespawnInfo* info : *_respawnTimes)
2156 delete info;
2157 _respawnTimes->clear();
2160}
2161
2163{
2164 // Delete from all relevant containers to ensure consistency
2165 ASSERT(info);
2166
2167 // spawnid store
2168 auto spawnMap = GetRespawnMapForType(info->type);
2169 if (!spawnMap)
2170 return;
2171
2172 auto range = spawnMap->equal_range(info->spawnId);
2173 auto it = std::find_if(range.first, range.second, [info](RespawnInfoMap::value_type const& pair) { return (pair.second == info); });
2174 ASSERT(it != range.second, "Respawn stores inconsistent for map %u, spawnid " UI64FMTD " (type %u)", GetId(), info->spawnId, uint32(info->type));
2175 spawnMap->erase(it);
2176
2177 // respawn heap
2178 _respawnTimes->erase(static_cast<RespawnInfoWithHandle*>(info)->handle);
2179
2180 // database
2181 DeleteRespawnInfoFromDB(info->type, info->spawnId, dbTrans);
2182
2183 // then cleanup the object
2184 delete info;
2185}
2186
2188{
2189 if (Instanceable())
2190 return;
2191
2193 stmt->setUInt16(0, type);
2194 stmt->setUInt64(1, spawnId);
2195 stmt->setUInt16(2, GetId());
2196 stmt->setUInt32(3, GetInstanceId());
2197 CharacterDatabase.ExecuteOrAppend(dbTrans, stmt);
2198}
2199
2201{
2202 if (!IsGridLoaded(gridId)) // if grid isn't loaded, this will be processed in grid load handler
2203 return;
2204
2205 switch (type)
2206 {
2208 {
2209 Creature* obj = new Creature();
2210 if (!obj->LoadFromDB(spawnId, this, true, true))
2211 delete obj;
2212 break;
2213 }
2215 {
2216 GameObject* obj = new GameObject();
2217 if (!obj->LoadFromDB(spawnId, this, true))
2218 delete obj;
2219 break;
2220 }
2221 default:
2222 ABORT_MSG("Invalid spawn type %u (spawnid " UI64FMTD ") on map %u", uint32(type), spawnId, GetId());
2223 }
2224}
2225
2227{
2228 time_t now = GameTime::GetGameTime();
2229 while (!_respawnTimes->empty())
2230 {
2231 RespawnInfoWithHandle* next = _respawnTimes->top();
2232 if (now < next->respawnTime) // done for this tick
2233 break;
2234
2235 if (uint32 poolId = sPoolMgr->IsPartOfAPool(next->type, next->spawnId)) // is this part of a pool?
2236 { // if yes, respawn will be handled by (external) pooling logic, just delete the respawn time
2237 // step 1: remove entry from maps to avoid it being reachable by outside logic
2238 _respawnTimes->pop();
2239 ASSERT_NOTNULL(GetRespawnMapForType(next->type))->erase(next->spawnId);
2240
2241 // step 2: tell pooling logic to do its thing
2242 sPoolMgr->UpdatePool(GetPoolData(), poolId, next->type, next->spawnId);
2243
2244 // step 3: get rid of the actual entry
2245 RemoveRespawnTime(next->type, next->spawnId, nullptr, true);
2246 delete next;
2247 }
2248 else if (CheckRespawn(next)) // see if we're allowed to respawn
2249 { // ok, respawn
2250 // step 1: remove entry from maps to avoid it being reachable by outside logic
2251 _respawnTimes->pop();
2252 ASSERT_NOTNULL(GetRespawnMapForType(next->type))->erase(next->spawnId);
2253
2254 // step 2: do the respawn, which involves external logic
2255 DoRespawn(next->type, next->spawnId, next->gridId);
2256
2257 // step 3: get rid of the actual entry
2258 RemoveRespawnTime(next->type, next->spawnId, nullptr, true);
2259 delete next;
2260 }
2261 else if (!next->respawnTime)
2262 { // just remove this respawn entry without rescheduling
2263 _respawnTimes->pop();
2264 ASSERT_NOTNULL(GetRespawnMapForType(next->type))->erase(next->spawnId);
2265 RemoveRespawnTime(next->type, next->spawnId, nullptr, true);
2266 delete next;
2267 }
2268 else
2269 { // new respawn time, update heap position
2270 ASSERT(now < next->respawnTime); // infinite loop guard
2271 _respawnTimes->decrease(next->handle);
2272 SaveRespawnInfoDB(*next);
2273 }
2274 }
2275}
2276
2277void Map::ApplyDynamicModeRespawnScaling(WorldObject const* obj, ObjectGuid::LowType spawnId, uint32& respawnDelay, uint32 mode) const
2278{
2279 ASSERT(mode == 1);
2280 ASSERT(obj->GetMap() == this);
2281
2283 return;
2284
2285 SpawnObjectType type;
2286 switch (obj->GetTypeId())
2287 {
2288 case TYPEID_UNIT:
2289 type = SPAWN_TYPE_CREATURE;
2290 break;
2291 case TYPEID_GAMEOBJECT:
2292 type = SPAWN_TYPE_GAMEOBJECT;
2293 break;
2294 default:
2295 return;
2296 }
2297
2298 SpawnMetadata const* data = sObjectMgr->GetSpawnMetadata(type, spawnId);
2299 if (!data)
2300 return;
2301
2303 return;
2304
2305 auto it = _zonePlayerCountMap.find(obj->GetZoneId());
2306 if (it == _zonePlayerCountMap.end())
2307 return;
2308 uint32 const playerCount = it->second;
2309 if (!playerCount)
2310 return;
2311 double const adjustFactor = sWorld->getFloatConfig(type == SPAWN_TYPE_GAMEOBJECT ? CONFIG_RESPAWN_DYNAMICRATE_GAMEOBJECT : CONFIG_RESPAWN_DYNAMICRATE_CREATURE) / playerCount;
2312 if (adjustFactor >= 1.0) // nothing to do here
2313 return;
2315 if (respawnDelay <= timeMinimum)
2316 return;
2317
2318 respawnDelay = std::max<uint32>(ceil(respawnDelay * adjustFactor), timeMinimum);
2319}
2320
2322{
2324 // check if the object is on its respawn timer
2325 if (GetRespawnTime(type, spawnId))
2326 return false;
2327
2328 SpawnMetadata const* spawnData = ASSERT_NOTNULL(sObjectMgr->GetSpawnMetadata(type, spawnId));
2329 // check if the object is part of a spawn group
2330 SpawnGroupTemplateData const* spawnGroup = ASSERT_NOTNULL(spawnData->spawnGroupData);
2331 if (!(spawnGroup->flags & SPAWNGROUP_FLAG_SYSTEM))
2332 if (!IsSpawnGroupActive(spawnGroup->groupId))
2333 return false;
2334
2335 if (spawnData->ToSpawnData()->poolId)
2336 if (!GetPoolData().IsSpawnedObject(type, spawnId))
2337 return false;
2338
2339 return true;
2340}
2341
2343{
2344 SpawnGroupTemplateData const* data = sObjectMgr->GetSpawnGroupData(groupId);
2345 if (data && (data->flags & SPAWNGROUP_FLAG_SYSTEM || data->mapId == GetId()))
2346 return data;
2347 return nullptr;
2348}
2349
2350bool Map::SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn, bool force, std::vector<WorldObject*>* spawnedObjects)
2351{
2352 SpawnGroupTemplateData const* groupData = GetSpawnGroupData(groupId);
2353 if (!groupData || groupData->flags & SPAWNGROUP_FLAG_SYSTEM)
2354 {
2355 TC_LOG_ERROR("maps", "Tried to spawn non-existing (or system) spawn group {} on map {}. Blocked.", groupId, GetId());
2356 return false;
2357 }
2358
2359 SetSpawnGroupActive(groupId, true); // start processing respawns for the group
2360
2361 std::vector<SpawnData const*> toSpawn;
2362 for (auto& pair : sObjectMgr->GetSpawnMetadataForGroup(groupId))
2363 {
2364 SpawnMetadata const* data = pair.second;
2365 ASSERT(groupData->mapId == data->mapId);
2366
2367 auto respawnMap = GetRespawnMapForType(data->type);
2368 if (!respawnMap)
2369 continue;
2370
2371 if (force || ignoreRespawn)
2372 RemoveRespawnTime(data->type, data->spawnId);
2373
2374 uint32 nRespawnTimers = respawnMap->count(data->spawnId);
2375 if (SpawnData::TypeHasData(data->type))
2376 {
2377 // has a respawn timer
2378 if (nRespawnTimers)
2379 continue;
2380
2381 // has a spawn already active
2382 if (!force)
2383 if (WorldObject* obj = GetWorldObjectBySpawnId(data->type, data->spawnId))
2384 if ((data->type != SPAWN_TYPE_CREATURE) || obj->ToCreature()->IsAlive())
2385 continue;
2386
2387 toSpawn.push_back(ASSERT_NOTNULL(data->ToSpawnData()));
2388 }
2389 }
2390
2391 for (SpawnData const* data : toSpawn)
2392 {
2393 // don't spawn if the current map difficulty is not used by the spawn
2394 if (std::find(data->spawnDifficulties.begin(), data->spawnDifficulties.end(), GetDifficultyID()) == data->spawnDifficulties.end())
2395 continue;
2396
2397 // don't spawn if the grid isn't loaded (will be handled in grid loader)
2398 if (!IsGridLoaded(data->spawnPoint))
2399 continue;
2400
2401 // now do the actual (re)spawn
2402 switch (data->type)
2403 {
2405 {
2406 Creature* creature = new Creature();
2407 if (!creature->LoadFromDB(data->spawnId, this, true, force))
2408 delete creature;
2409 else if (spawnedObjects)
2410 spawnedObjects->push_back(creature);
2411 break;
2412 }
2414 {
2415 GameObject* gameobject = new GameObject();
2416 if (!gameobject->LoadFromDB(data->spawnId, this, true))
2417 delete gameobject;
2418 else if (spawnedObjects)
2419 spawnedObjects->push_back(gameobject);
2420 break;
2421 }
2423 {
2424 AreaTrigger* areaTrigger = new AreaTrigger();
2425 if (!areaTrigger->LoadFromDB(data->spawnId, this, true, false))
2426 delete areaTrigger;
2427 else if (spawnedObjects)
2428 spawnedObjects->push_back(areaTrigger);
2429 break;
2430 }
2431 default:
2432 ABORT_MSG("Invalid spawn type %u with spawnId " UI64FMTD, uint32(data->type), data->spawnId);
2433 return false;
2434 }
2435 }
2436 return true;
2437}
2438
2439bool Map::SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes, size_t* count)
2440{
2441 SpawnGroupTemplateData const* groupData = GetSpawnGroupData(groupId);
2442 if (!groupData || groupData->flags & SPAWNGROUP_FLAG_SYSTEM)
2443 {
2444 TC_LOG_ERROR("maps", "Tried to despawn non-existing (or system) spawn group {} on map {}. Blocked.", groupId, GetId());
2445 return false;
2446 }
2447
2448 for (auto const& pair : sObjectMgr->GetSpawnMetadataForGroup(groupId))
2449 {
2450 SpawnMetadata const* data = pair.second;
2451 ASSERT(groupData->mapId == data->mapId);
2452 if (deleteRespawnTimes)
2453 RemoveRespawnTime(data->type, data->spawnId);
2454 size_t c = DespawnAll(data->type, data->spawnId);
2455 if (count)
2456 *count += c;
2457 }
2458 SetSpawnGroupActive(groupId, false); // stop processing respawns for the group, too
2459 return true;
2460}
2461
2462void Map::SetSpawnGroupActive(uint32 groupId, bool state)
2463{
2464 SpawnGroupTemplateData const* const data = GetSpawnGroupData(groupId);
2465 if (!data || data->flags & SPAWNGROUP_FLAG_SYSTEM)
2466 {
2467 TC_LOG_ERROR("maps", "Tried to set non-existing (or system) spawn group {} to {} on map {}. Blocked.", groupId, state ? "active" : "inactive", GetId());
2468 return;
2469 }
2470 if (state != !(data->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN)) // toggled
2471 _toggledSpawnGroupIds.insert(groupId);
2472 else
2473 _toggledSpawnGroupIds.erase(groupId);
2474}
2475
2477{
2478 SpawnGroupTemplateData const* const data = GetSpawnGroupData(groupId);
2479 if (!data)
2480 {
2481 TC_LOG_ERROR("maps", "Tried to query state of non-existing spawn group {} on map {}.", groupId, GetId());
2482 return false;
2483 }
2484 if (data->flags & SPAWNGROUP_FLAG_SYSTEM)
2485 return true;
2486 // either manual spawn group and toggled, or not manual spawn group and not toggled...
2487 return (_toggledSpawnGroupIds.find(groupId) != _toggledSpawnGroupIds.end()) != !(data->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN);
2488}
2489
2491{
2492 std::vector<uint32> const* spawnGroups = sObjectMgr->GetSpawnGroupsForMap(GetId());
2493 if (!spawnGroups)
2494 return;
2495
2496 for (uint32 spawnGroupId : *spawnGroups)
2497 {
2498 SpawnGroupTemplateData const* spawnGroupTemplate = ASSERT_NOTNULL(GetSpawnGroupData(spawnGroupId));
2499 if (spawnGroupTemplate->flags & (SPAWNGROUP_FLAG_SYSTEM | SPAWNGROUP_FLAG_MANUAL_SPAWN))
2500 continue;
2501
2502 SetSpawnGroupActive(spawnGroupId, sConditionMgr->IsMapMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_SPAWN_GROUP, spawnGroupId, this));
2503 }
2504}
2505
2507{
2508 std::vector<uint32> const* spawnGroups = sObjectMgr->GetSpawnGroupsForMap(GetId());
2509 if (!spawnGroups)
2510 return;
2511
2512 for (uint32 spawnGroupId : *spawnGroups)
2513 {
2514 SpawnGroupTemplateData const* spawnGroupTemplate = ASSERT_NOTNULL(GetSpawnGroupData(spawnGroupId));
2515
2516 bool isActive = IsSpawnGroupActive(spawnGroupId);
2517 bool shouldBeActive = sConditionMgr->IsMapMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_SPAWN_GROUP, spawnGroupId, this);
2518
2519 if (spawnGroupTemplate->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN)
2520 {
2521 // Only despawn the group if it isn't meeting conditions
2522 if (isActive && !shouldBeActive && spawnGroupTemplate->flags & SPAWNGROUP_FLAG_DESPAWN_ON_CONDITION_FAILURE)
2523 SpawnGroupDespawn(spawnGroupId, true);
2524
2525 continue;
2526 }
2527
2528 if (isActive == shouldBeActive)
2529 continue;
2530
2531 if (shouldBeActive)
2532 SpawnGroupSpawn(spawnGroupId);
2533 else if (spawnGroupTemplate->flags & SPAWNGROUP_FLAG_DESPAWN_ON_CONDITION_FAILURE)
2534 SpawnGroupDespawn(spawnGroupId, true);
2535 else
2536 SetSpawnGroupInactive(spawnGroupId);
2537 }
2538}
2539
2541{
2542 return _guidGenerators.try_emplace(high, high).first->second;
2543}
2544
2546{
2547 _farSpellCallbacks.Enqueue(new FarSpellCallback(std::move(callback)));
2548}
2549
2551{
2552 {
2553 FarSpellCallback* callback;
2554 while (_farSpellCallbacks.Dequeue(callback))
2555 {
2556 (*callback)(this);
2557 delete callback;
2558 }
2559 }
2560
2562
2563 // Don't unload grids if it's battleground, since we may have manually added GOs, creatures, those doesn't load from DB at grid re-load !
2564 // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
2565 if (!IsBattlegroundOrArena())
2566 {
2568 {
2569 NGridType *grid = i->GetSource();
2570 GridInfo* info = i->GetSource()->getGridInfoRef();
2571 ++i; // The update might delete the map and we need the next map before the iterator gets invalid
2572 ASSERT(grid->GetGridState() >= 0 && grid->GetGridState() < MAX_GRID_STATE);
2573 si_GridStates[grid->GetGridState()]->Update(*this, *grid, *info, t_diff);
2574 }
2575 }
2576}
2577
2579{
2580 ASSERT(obj->GetMapId() == GetId() && obj->GetInstanceId() == GetInstanceId());
2581
2582 obj->SetDestroyedObject(true);
2583 obj->CleanupsBeforeDelete(false); // remove or simplify at least cross referenced links
2584
2585 i_objectsToRemove.insert(obj);
2586}
2587
2589{
2590 ASSERT(obj->GetMapId() == GetId() && obj->GetInstanceId() == GetInstanceId());
2591 // i_objectsToSwitch is iterated only in Map::RemoveAllObjectsInRemoveList() and it uses
2592 // the contained objects only if GetTypeId() == TYPEID_UNIT , so we can return in all other cases
2593 if (obj->GetTypeId() != TYPEID_UNIT)
2594 return;
2595
2596 std::map<WorldObject*, bool>::iterator itr = i_objectsToSwitch.find(obj);
2597 if (itr == i_objectsToSwitch.end())
2598 i_objectsToSwitch.insert(itr, std::make_pair(obj, on));
2599 else if (itr->second != on)
2600 i_objectsToSwitch.erase(itr);
2601 else
2602 ABORT();
2603}
2604
2606{
2607 while (!i_objectsToSwitch.empty())
2608 {
2609 std::map<WorldObject*, bool>::iterator itr = i_objectsToSwitch.begin();
2610 WorldObject* obj = itr->first;
2611 bool on = itr->second;
2612 i_objectsToSwitch.erase(itr);
2613
2615 {
2616 switch (obj->GetTypeId())
2617 {
2618 case TYPEID_UNIT:
2619 SwitchGridContainers<Creature>(obj->ToCreature(), on);
2620 break;
2621 default:
2622 break;
2623 }
2624 }
2625 }
2626
2627 //TC_LOG_DEBUG("maps", "Object remover 1 check.");
2628 while (!i_objectsToRemove.empty())
2629 {
2630 std::set<WorldObject*>::iterator itr = i_objectsToRemove.begin();
2631 WorldObject* obj = *itr;
2632
2633 switch (obj->GetTypeId())
2634 {
2635 case TYPEID_CORPSE:
2636 {
2637 Corpse* corpse = ObjectAccessor::GetCorpse(*obj, obj->GetGUID());
2638 if (!corpse)
2639 TC_LOG_ERROR("maps", "Tried to delete corpse/bones {} that is not in map.", obj->GetGUID().ToString());
2640 else
2641 RemoveFromMap(corpse, true);
2642 break;
2643 }
2645 RemoveFromMap(obj->ToDynObject(), true);
2646 break;
2647 case TYPEID_AREATRIGGER:
2648 RemoveFromMap((AreaTrigger*)obj, true);
2649 break;
2651 RemoveFromMap((Conversation*)obj, true);
2652 break;
2653 case TYPEID_GAMEOBJECT:
2654 {
2655 GameObject* go = obj->ToGameObject();
2656 if (Transport* transport = go->ToTransport())
2657 RemoveFromMap(transport, true);
2658 else
2659 RemoveFromMap(go, true);
2660 break;
2661 }
2662 case TYPEID_UNIT:
2663 // in case triggered sequence some spell can continue casting after prev CleanupsBeforeDelete call
2664 // make sure that like sources auras/etc removed before destructor start
2666 RemoveFromMap(obj->ToCreature(), true);
2667 break;
2668 default:
2669 TC_LOG_ERROR("maps", "Non-grid object (TypeId: {}) is in grid object remove list, ignored.", obj->GetTypeId());
2670 break;
2671 }
2672
2673 i_objectsToRemove.erase(itr);
2674 }
2675
2676 //TC_LOG_DEBUG("maps", "Object remover 2 check.");
2677}
2678
2680{
2681 uint32 count = 0;
2683 if (!itr->GetSource()->IsGameMaster())
2684 ++count;
2685 return count;
2686}
2687
2688void Map::SendToPlayers(WorldPacket const* data) const
2689{
2691 itr->GetSource()->SendDirectMessage(data);
2692}
2693
2695{
2696 CellCoord cell_min(ngrid.getX() * MAX_NUMBER_OF_CELLS, ngrid.getY() * MAX_NUMBER_OF_CELLS);
2697 CellCoord cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS);
2698
2699 //we must find visible range in cells so we unload only non-visible cells...
2700 float viewDist = GetVisibilityRange();
2701 int cell_range = (int)ceilf(viewDist / SIZE_OF_GRID_CELL) + 1;
2702
2703 cell_min.dec_x(cell_range);
2704 cell_min.dec_y(cell_range);
2705 cell_max.inc_x(cell_range);
2706 cell_max.inc_y(cell_range);
2707
2709 {
2710 Player* player = iter->GetSource();
2711
2713 if ((cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
2714 (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord))
2715 return true;
2716 }
2717
2718 for (ActiveNonPlayers::const_iterator iter = m_activeNonPlayers.begin(); iter != m_activeNonPlayers.end(); ++iter)
2719 {
2720 WorldObject* obj = *iter;
2721
2723 if ((cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) &&
2724 (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord))
2725 return true;
2726 }
2727
2728 return false;
2729}
2730
2732{
2733 i_worldObjects.insert(obj);
2734}
2735
2737{
2738 i_worldObjects.erase(obj);
2739}
2740
2742{
2743 m_activeNonPlayers.insert(obj);
2744
2745 Optional<Position> respawnLocation;
2746 switch (obj->GetTypeId())
2747 {
2748 case TYPEID_UNIT:
2749 if (Creature* creature = obj->ToCreature(); !creature->IsPet() && creature->GetSpawnId())
2750 respawnLocation = creature->GetRespawnPosition();
2751 break;
2752 case TYPEID_GAMEOBJECT:
2753 if (GameObject* gameObject = obj->ToGameObject(); gameObject->GetSpawnId())
2754 respawnLocation = gameObject->GetRespawnPosition();
2755 break;
2756 default:
2757 break;
2758 }
2759
2760 if (respawnLocation)
2761 {
2762 GridCoord p = Trinity::ComputeGridCoord(respawnLocation->GetPositionX(), respawnLocation->GetPositionY());
2763 if (getNGrid(p.x_coord, p.y_coord))
2765 else
2766 {
2768 TC_LOG_ERROR("maps", "Active object {} added to grid[{}, {}] but spawn grid[{}, {}] was not loaded.",
2769 obj->GetGUID().ToString(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
2770 }
2771 }
2772}
2773
2775{
2776 // Map::Update for active object in proccess
2778 {
2779 ActiveNonPlayers::iterator itr = m_activeNonPlayers.find(obj);
2780 if (itr != m_activeNonPlayers.end())
2781 {
2782 if (itr == m_activeNonPlayersIter)
2784 m_activeNonPlayers.erase(itr);
2785 }
2786 }
2787 else
2788 m_activeNonPlayers.erase(obj);
2789
2790 Optional<Position> respawnLocation;
2791 switch (obj->GetTypeId())
2792 {
2793 case TYPEID_UNIT:
2794 if (Creature* creature = obj->ToCreature(); !creature->IsPet() && creature->GetSpawnId())
2795 respawnLocation = creature->GetRespawnPosition();
2796 break;
2797 case TYPEID_GAMEOBJECT:
2798 if (GameObject* gameObject = obj->ToGameObject(); gameObject->GetSpawnId())
2799 respawnLocation = gameObject->GetRespawnPosition();
2800 break;
2801 default:
2802 break;
2803 }
2804
2805 if (respawnLocation)
2806 {
2807 GridCoord p = Trinity::ComputeGridCoord(respawnLocation->GetPositionX(), respawnLocation->GetPositionY());
2808 if (getNGrid(p.x_coord, p.y_coord))
2810 else
2811 {
2813 TC_LOG_ERROR("maps", "Active object {} removed from to grid[{}, {}] but spawn grid[{}, {}] was not loaded.",
2814 obj->GetGUID().ToString(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord);
2815 }
2816 }
2817}
2818
2819template TC_GAME_API bool Map::AddToMap(Corpse*);
2820template TC_GAME_API bool Map::AddToMap(Creature*);
2821template TC_GAME_API bool Map::AddToMap(GameObject*);
2823template TC_GAME_API bool Map::AddToMap(AreaTrigger*);
2824template TC_GAME_API bool Map::AddToMap(SceneObject*);
2825template TC_GAME_API bool Map::AddToMap(Conversation*);
2826
2827template TC_GAME_API void Map::RemoveFromMap(Corpse*, bool);
2828template TC_GAME_API void Map::RemoveFromMap(Creature*, bool);
2829template TC_GAME_API void Map::RemoveFromMap(GameObject*, bool);
2830template TC_GAME_API void Map::RemoveFromMap(DynamicObject*, bool);
2831template TC_GAME_API void Map::RemoveFromMap(AreaTrigger*, bool);
2832template TC_GAME_API void Map::RemoveFromMap(SceneObject*, bool);
2833template TC_GAME_API void Map::RemoveFromMap(Conversation*, bool);
2834
2835/* ******* Dungeon Instance Maps ******* */
2836
2837InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty SpawnMode, TeamId InstanceTeam, InstanceLock* instanceLock,
2838 Optional<uint32> lfgDungeonsId)
2839 : Map(id, expiry, InstanceId, SpawnMode),
2840 i_data(nullptr), i_script_id(0), i_instanceLock(instanceLock), i_lfgDungeonsId(lfgDungeonsId)
2841{
2842 //lets initialize visibility distance for dungeons
2844
2845 // the timer is started by default, and stopped when the first player joins
2846 // this make sure it gets unloaded if for some reason no player joins
2848
2850 WorldStateMgr::SetValue(WS_TEAM_IN_INSTANCE_HORDE, InstanceTeam == TEAM_HORDE, false, this);
2851
2852 if (i_instanceLock)
2853 {
2854 i_instanceLock->SetInUse(true);
2855 i_instanceExpireEvent = i_instanceLock->GetExpiryTime(); // ignore extension state for reset event (will ask players to accept extended save on expiration)
2856 }
2857}
2858
2860{
2861 if (i_instanceLock)
2862 i_instanceLock->SetInUse(false);
2863
2864 delete i_data;
2865}
2866
2868{
2869 //init visibility distance for instances
2872}
2873
2874/*
2875 Do map specific checks to see if the player can enter
2876*/
2878{
2879 if (player->GetMapRef().getTarget() == this)
2880 {
2881 TC_LOG_ERROR("maps", "InstanceMap::CannotEnter - player {} {} already in map {}, {}, {}!", player->GetName(), player->GetGUID().ToString(), GetId(), GetInstanceId(), GetDifficultyID());
2882 ABORT();
2883 return TRANSFER_ABORT_ERROR;
2884 }
2885
2886 // allow GM's to enter
2887 if (player->IsGameMaster())
2888 return Map::CannotEnter(player);
2889
2890 // cannot enter if the instance is full (player cap), GMs don't count
2891 uint32 maxPlayers = GetMaxPlayers();
2892 if (GetPlayersCountExceptGMs() >= maxPlayers)
2893 {
2894 TC_LOG_WARN("maps", "MAP: Instance '{}' of map '{}' cannot have more than '{}' players. Player '{}' rejected", GetInstanceId(), GetMapName(), maxPlayers, player->GetName());
2896 }
2897
2898 // cannot enter while an encounter is in progress (unless this is a relog, in which case it is permitted)
2899 if (!player->IsLoading() && IsRaid() && GetInstanceScript() && GetInstanceScript()->IsEncounterInProgress())
2901
2902 if (i_instanceLock)
2903 {
2904 // cannot enter if player is permanent saved to a different instance id
2905 TransferAbortReason lockError = sInstanceLockMgr.CanJoinInstanceLock(player->GetGUID(), { GetEntry(), GetMapDifficulty() }, i_instanceLock);
2906 if (lockError != TRANSFER_ABORT_NONE)
2907 return lockError;
2908 }
2909
2910 if (Group* owningGroup = GetOwningGroup())
2911 if (!player->IsInGroup(owningGroup->GetGUID()))
2913
2914 return Map::CannotEnter(player);
2915}
2916
2917/*
2918 Do map specific checks and add the player to the map if successful.
2919*/
2920bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)
2921{
2922 // increase current instances (hourly limit)
2924
2925 MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
2926 if (entries.MapDifficulty->HasResetSchedule() && i_instanceLock && !i_instanceLock->IsNew() && i_data)
2927 {
2928 if (!entries.MapDifficulty->IsUsingEncounterLocks())
2929 {
2930 InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries);
2931 if (!playerLock || (playerLock->IsExpired() && playerLock->IsExtended()) ||
2933 {
2935 pendingRaidLock.TimeUntilLock = 60000;
2937 pendingRaidLock.Extending = playerLock && playerLock->IsExtended();
2938 pendingRaidLock.WarningOnly = entries.Map->IsFlexLocking(); // events it triggers: 1 : INSTANCE_LOCK_WARNING 0 : INSTANCE_LOCK_STOP / INSTANCE_LOCK_START
2939 player->GetSession()->SendPacket(pendingRaidLock.Write());
2940 if (!entries.Map->IsFlexLocking())
2941 player->SetPendingBind(GetInstanceId(), 60000);
2942 }
2943 }
2944 }
2945
2946 TC_LOG_DEBUG("maps", "MAP: Player '{}' entered instance '{}' of map '{}'", player->GetName(), GetInstanceId(), GetMapName());
2947 // initialize unload state
2948 m_unloadTimer = 0;
2949
2950 // this will acquire the same mutex so it cannot be in the previous block
2951 Map::AddPlayerToMap(player, initPlayer);
2952
2953 if (i_data)
2954 i_data->OnPlayerEnter(player);
2955
2956 if (i_scenario)
2957 i_scenario->OnPlayerEnter(player);
2958
2959 return true;
2960}
2961
2963{
2964 Map::Update(t_diff);
2965
2966 if (i_data)
2967 {
2968 i_data->Update(t_diff);
2970 }
2971
2972 if (i_scenario)
2973 i_scenario->Update(t_diff);
2974
2976 {
2979 }
2980}
2981
2983{
2984 TC_LOG_DEBUG("maps", "MAP: Removing player '{}' from instance '{}' of map '{}' before relocating to another map", player->GetName(), GetInstanceId(), GetMapName());
2985
2986 if (i_data)
2987 i_data->OnPlayerLeave(player);
2988
2989 // if last player set unload timer
2990 if (!m_unloadTimer && m_mapRefManager.size() == 1)
2992
2993 if (i_scenario)
2994 i_scenario->OnPlayerExit(player);
2995
2996 Map::RemovePlayerFromMap(player, remove);
2997}
2998
3000{
3001 if (i_data != nullptr)
3002 return;
3003
3004 InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(GetId());
3005 if (mInstance)
3006 {
3007 i_script_id = mInstance->ScriptId;
3008 i_data = sScriptMgr->CreateInstanceData(this);
3009 }
3010
3011 if (!i_data)
3012 return;
3013
3015 {
3016 i_data->Create();
3017 return;
3018 }
3019
3020 MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
3021 if (!entries.IsInstanceIdBound() && !IsRaid() && !entries.MapDifficulty->IsRestoringDungeonState() && i_owningGroupRef.isValid())
3022 {
3023 i_data->Create();
3024 return;
3025 }
3026
3029 if (!lockData->Data.empty())
3030 {
3031 TC_LOG_DEBUG("maps", "Loading instance data for `{}` with id {}", sObjectMgr->GetScriptName(i_script_id), i_InstanceId);
3032 i_data->Load(lockData->Data.c_str());
3033 }
3034 else
3035 i_data->Create();
3036}
3037
3039{
3041 i_owningGroupRef.link(group, this);
3042}
3043
3044/*
3045 Returns true if there are no players in the instance
3046*/
3048{
3049 // raids can be reset if no boss was killed
3052
3053 if (HavePlayers())
3054 {
3055 switch (method)
3056 {
3058 // notify the players to leave the instance so it can be reset
3059 for (MapReference const& ref : m_mapRefManager)
3060 ref.GetSource()->SendResetFailedNotify(GetId());
3061 break;
3063 // no client notification
3064 break;
3066 {
3068 raidInstanceMessage.Type = RAID_INSTANCE_EXPIRED;
3069 raidInstanceMessage.MapID = GetId();
3070 raidInstanceMessage.DifficultyID = GetDifficultyID();
3071 raidInstanceMessage.Write();
3072
3073 for (MapReference const& ref : m_mapRefManager)
3074 ref.GetSource()->SendDirectMessage(raidInstanceMessage.GetRawPacket());
3075
3076 if (i_data)
3077 {
3079 pendingRaidLock.TimeUntilLock = 60000;
3081 pendingRaidLock.Extending = true;
3082 pendingRaidLock.WarningOnly = GetEntry()->IsFlexLocking();
3083 pendingRaidLock.Write();
3084
3085 for (MapReference const& ref : m_mapRefManager)
3086 {
3087 ref.GetSource()->SendDirectMessage(pendingRaidLock.GetRawPacket());
3088
3089 if (!pendingRaidLock.WarningOnly)
3090 ref.GetSource()->SetPendingBind(GetInstanceId(), 60000);
3091 }
3092 }
3093 break;
3094 }
3095 default:
3096 break;
3097 }
3098
3100 }
3101 else
3102 {
3103 // unloaded at next update
3105 }
3106
3108}
3109
3110std::string const& InstanceMap::GetScriptName() const
3111{
3112 return sObjectMgr->GetScriptName(i_script_id);
3113}
3114
3116{
3117 i_scenario.reset(); // sends exit packets to all players
3118
3119 if (scenario)
3120 {
3121 i_scenario.reset(scenario);
3122
3123 scenario->LoadInstanceData();
3124
3125 DoOnPlayers([scenario](Player* player)
3126 {
3127 scenario->OnPlayerEnter(player);
3128 });
3129 }
3130}
3131
3133{
3134 if (i_instanceLock)
3135 {
3136 uint32 instanceCompletedEncounters = i_instanceLock->GetData()->CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter->Bit);
3137
3138 MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
3139
3140 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
3141
3142 if (entries.IsInstanceIdBound())
3143 sInstanceLockMgr.UpdateSharedInstanceLock(trans, InstanceLockUpdateEvent(GetInstanceId(), i_data->GetSaveData(),
3144 instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter, i_data->GetEntranceLocationForCompletedEncounters(instanceCompletedEncounters)));
3145
3146 for (MapReference& mapReference : m_mapRefManager)
3147 {
3148 Player* player = mapReference.GetSource();
3149 // never instance bind GMs with GM mode enabled
3150 if (player->IsGameMaster())
3151 continue;
3152
3153 InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries);
3154 std::string const* oldData = nullptr;
3155 uint32 playerCompletedEncounters = 0;
3156 if (playerLock)
3157 {
3158 oldData = &playerLock->GetData()->Data;
3159 playerCompletedEncounters = playerLock->GetData()->CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter->Bit);
3160 }
3161
3162 bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired();
3163
3164 InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
3165 InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateBossStateSaveData(oldData ? *oldData : "", updateSaveDataEvent),
3166 instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter, i_data->GetEntranceLocationForCompletedEncounters(playerCompletedEncounters)));
3167
3168 if (isNewLock)
3169 {
3171 data.Gm = player->IsGameMaster();
3172 player->SendDirectMessage(data.Write());
3173
3174 player->GetSession()->SendCalendarRaidLockoutAdded(newLock);
3175 }
3176 }
3177
3178 CharacterDatabase.CommitTransaction(trans);
3179 }
3180}
3181
3183{
3184 if (i_instanceLock)
3185 {
3186 uint32 instanceCompletedEncounters = i_instanceLock->GetData()->CompletedEncountersMask;
3187
3188 MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
3189
3190 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
3191
3192 if (entries.IsInstanceIdBound())
3193 sInstanceLockMgr.UpdateSharedInstanceLock(trans, InstanceLockUpdateEvent(GetInstanceId(), i_data->GetSaveData(),
3194 instanceCompletedEncounters, nullptr, {}));
3195
3196 for (MapReference& mapReference : m_mapRefManager)
3197 {
3198 Player* player = mapReference.GetSource();
3199 // never instance bind GMs with GM mode enabled
3200 if (player->IsGameMaster())
3201 continue;
3202
3203 InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries);
3204 std::string const* oldData = nullptr;
3205 if (playerLock)
3206 oldData = &playerLock->GetData()->Data;
3207
3208 bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired();
3209
3210 InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
3211 InstanceLockUpdateEvent(GetInstanceId(), i_data->UpdateAdditionalSaveData(oldData ? *oldData : "", updateSaveDataEvent),
3212 instanceCompletedEncounters, nullptr, {}));
3213
3214 if (isNewLock)
3215 {
3217 data.Gm = player->IsGameMaster();
3218 player->SendDirectMessage(data.Write());
3219
3220 player->GetSession()->SendCalendarRaidLockoutAdded(newLock);
3221 }
3222 }
3223
3224 CharacterDatabase.CommitTransaction(trans);
3225 }
3226}
3227
3229{
3230 MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
3231 InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(player->GetGUID(), entries);
3232
3233 bool isNewLock = !playerLock || playerLock->IsNew() || playerLock->IsExpired();
3234
3235 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
3236
3237 InstanceLock const* newLock = sInstanceLockMgr.UpdateInstanceLockForPlayer(trans, player->GetGUID(), entries,
3239
3240 CharacterDatabase.CommitTransaction(trans);
3241
3242 if (isNewLock)
3243 {
3245 data.Gm = player->IsGameMaster();
3246 player->SendDirectMessage(data.Write());
3247
3248 player->GetSession()->SendCalendarRaidLockoutAdded(newLock);
3249 }
3250}
3251
3253{
3254 return sDB2Manager.GetMapDifficultyData(GetId(), GetDifficultyID());
3255}
3256
3258{
3259 return i_mapEntry->ID;
3260}
3261
3263{
3264 return i_mapEntry && i_mapEntry->Instanceable();
3265}
3266
3267bool Map::IsDungeon() const
3268{
3269 return i_mapEntry && i_mapEntry->IsDungeon();
3270}
3271
3273{
3275}
3276
3277bool Map::IsRaid() const
3278{
3279 return i_mapEntry && i_mapEntry->IsRaid();
3280}
3281
3282bool Map::IsLFR() const
3283{
3284 switch (i_spawnMode)
3285 {
3286 case DIFFICULTY_LFR:
3287 case DIFFICULTY_LFR_NEW:
3289 return true;
3290 default:
3291 return false;
3292 }
3293}
3294
3295bool Map::IsNormal() const
3296{
3297 switch (i_spawnMode)
3298 {
3299 case DIFFICULTY_NORMAL:
3300 case DIFFICULTY_10_N:
3301 case DIFFICULTY_25_N:
3305 return true;
3306 default:
3307 return false;
3308 }
3309}
3310
3311bool Map::IsHeroic() const
3312{
3313 if (DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(i_spawnMode))
3314 {
3315 if (difficulty->Flags & DIFFICULTY_FLAG_DISPLAY_HEROIC)
3316 return true;
3317 }
3318
3319 // compatibility purposes of old difficulties
3320 switch (i_spawnMode)
3321 {
3322 case DIFFICULTY_10_HC:
3323 case DIFFICULTY_25_HC:
3324 case DIFFICULTY_HEROIC:
3326 return true;
3327 default:
3328 return false;
3329 }
3330}
3331
3332bool Map::IsMythic() const
3333{
3334 if (DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(i_spawnMode))
3335 return difficulty->Flags & DIFFICULTY_FLAG_DISPLAY_MYTHIC;
3336 return false;
3337}
3338
3340{
3342}
3343
3345{
3346 return IsHeroic() || IsMythic() || IsMythicPlus();
3347}
3348
3350{
3352}
3353
3358
3360{
3362}
3363
3365{
3366 return i_mapEntry && i_mapEntry->IsBattleArena();
3367}
3368
3370{
3372}
3373
3375{
3376 return i_mapEntry && i_mapEntry->IsScenario();
3377}
3378
3380{
3381 return i_mapEntry && i_mapEntry->IsGarrison();
3382}
3383
3385{
3386 return IsBattlegroundOrArena();
3387}
3388
3389bool Map::GetEntrancePos(int32 &mapid, float &x, float &y)
3390{
3391 if (!i_mapEntry)
3392 return false;
3393 return i_mapEntry->GetEntrancePos(mapid, x, y);
3394}
3395
3397{
3398 MapDifficultyEntry const* mapDiff = GetMapDifficulty();
3399 if (mapDiff && mapDiff->MaxPlayers)
3400 return mapDiff->MaxPlayers;
3401
3402 return GetEntry()->MaxPlayers;
3403}
3404
3413
3414/* ******* Battleground Instance Maps ******* */
3415
3416BattlegroundMap::BattlegroundMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty spawnMode)
3417 : Map(id, expiry, InstanceId, spawnMode), m_bg(nullptr), _battlegroundScript(nullptr), _scriptId(0)
3418{
3419 //lets initialize visibility distance for BG/Arenas
3421}
3422
3424{
3425 if (m_bg)
3426 {
3427 //unlink to prevent crash, always unlink all pointer reference before destruction
3428 m_bg->SetBgMap(nullptr);
3429 m_bg = nullptr;
3430 }
3431}
3432
3439
3440std::string const& BattlegroundMap::GetScriptName() const
3441{
3442 return sObjectMgr->GetScriptName(_scriptId);
3443}
3444
3446{
3448 return;
3449
3450 ASSERT(GetBG(), "Battleground not set yet!");
3451
3452 if (BattlegroundScriptTemplate const* scriptTemplate = sBattlegroundMgr->FindBattlegroundScriptTemplate(GetId(), GetBG()->GetTypeID()))
3453 {
3454 _scriptId = scriptTemplate->ScriptId;
3455 _battlegroundScript.reset(sScriptMgr->CreateBattlegroundData(this));
3456 }
3457
3458 // Make sure every battleground has a default script
3460 {
3461 if (IsBattleArena())
3462 _battlegroundScript = std::make_unique<ArenaScript>(this);
3463 else
3464 _battlegroundScript = std::make_unique<BattlegroundScript>(this);
3465 }
3466}
3467
3469{
3470 if (player->GetMapRef().getTarget() == this)
3471 {
3472 TC_LOG_ERROR("maps", "BGMap::CannotEnter - player {} is already in map!", player->GetGUID().ToString());
3473 ABORT();
3474 return TRANSFER_ABORT_ERROR;
3475 }
3476
3477 if (player->GetBattlegroundId() != GetInstanceId())
3479
3480 // player number limit is checked in bgmgr, no need to do it here
3481
3482 return Map::CannotEnter(player);
3483}
3484
3485bool BattlegroundMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)
3486{
3487 player->m_InstanceValid = true;
3488 return Map::AddPlayerToMap(player, initPlayer);
3489}
3490
3492{
3493 TC_LOG_DEBUG("maps", "MAP: Removing player '{}' from bg '{}' of map '{}' before relocating to another map", player->GetName(), GetInstanceId(), GetMapName());
3494 Map::RemovePlayerFromMap(player, remove);
3495}
3496
3501
3503{
3504 if (HavePlayers())
3505 for (MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
3506 if (Player* player = itr->GetSource())
3507 if (!player->IsBeingTeleportedFar())
3508 player->TeleportTo(player->GetBattlegroundEntryPoint());
3509}
3510
3512{
3513 Map::Update(diff);
3514 _battlegroundScript->OnUpdate(diff);
3515}
3516
3518{
3519 return _objectsStore.Find<AreaTrigger>(guid);
3520}
3521
3523{
3524 return _objectsStore.Find<SceneObject>(guid);
3525}
3526
3528{
3529 return _objectsStore.Find<Conversation>(guid);
3530}
3531
3533{
3534 return ObjectAccessor::GetPlayer(this, guid);
3535}
3536
3538{
3539 return _objectsStore.Find<Corpse>(guid);
3540}
3541
3543{
3544 return _objectsStore.Find<Creature>(guid);
3545}
3546
3551
3553{
3554 return _objectsStore.Find<GameObject>(guid);
3555}
3556
3558{
3559 return _objectsStore.Find<Pet>(guid);
3560}
3561
3563{
3564 if (!guid.IsMOTransport())
3565 return nullptr;
3566
3567 GameObject* go = GetGameObject(guid);
3568 return go ? go->ToTransport() : nullptr;
3569}
3570
3572{
3573 auto const bounds = GetCreatureBySpawnIdStore().equal_range(spawnId);
3574 if (bounds.first == bounds.second)
3575 return nullptr;
3576
3577 std::unordered_multimap<ObjectGuid::LowType, Creature*>::const_iterator creatureItr = std::find_if(bounds.first, bounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair)
3578 {
3579 return pair.second->IsAlive();
3580 });
3581
3582 return creatureItr != bounds.second ? creatureItr->second : bounds.first->second;
3583}
3584
3586{
3587 auto const bounds = GetGameObjectBySpawnIdStore().equal_range(spawnId);
3588 if (bounds.first == bounds.second)
3589 return nullptr;
3590
3591 std::unordered_multimap<ObjectGuid::LowType, GameObject*>::const_iterator creatureItr = std::find_if(bounds.first, bounds.second, [](Map::GameObjectBySpawnIdContainer::value_type const& pair)
3592 {
3593 return pair.second->isSpawned();
3594 });
3595
3596 return creatureItr != bounds.second ? creatureItr->second : bounds.first->second;
3597}
3598
3600{
3601 auto const bounds = GetAreaTriggerBySpawnIdStore().equal_range(spawnId);
3602 if (bounds.first == bounds.second)
3603 return nullptr;
3604
3605 return bounds.first->second;
3606}
3607
3609{
3610 if (&*m_mapRefIter == &player->GetMapRef())
3611 --m_mapRefIter;
3612}
3613
3614void Map::SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 gridId, CharacterDatabaseTransaction dbTrans, bool startup)
3615{
3616 SpawnMetadata const* data = sObjectMgr->GetSpawnMetadata(type, spawnId);
3617 if (!data)
3618 {
3619 TC_LOG_ERROR("maps", "Map {} attempt to save respawn time for nonexistant spawnid ({},{}).", GetId(), type, spawnId);
3620 return;
3621 }
3622
3623 if (!respawnTime)
3624 {
3625 // Delete only
3626 RemoveRespawnTime(data->type, data->spawnId, dbTrans);
3627 return;
3628 }
3629
3630 RespawnInfo ri;
3631 ri.type = data->type;
3632 ri.spawnId = data->spawnId;
3633 ri.entry = entry;
3634 ri.respawnTime = respawnTime;
3635 ri.gridId = gridId;
3636 bool success = AddRespawnInfo(ri);
3637
3638 if (startup)
3639 {
3640 if (!success)
3641 TC_LOG_ERROR("maps", "Attempt to load saved respawn {} for ({},{}) failed - duplicate respawn? Skipped.", respawnTime, uint32(type), spawnId);
3642 }
3643 else if (success)
3644 SaveRespawnInfoDB(ri, dbTrans);
3645}
3646
3648{
3649 if (Instanceable())
3650 return;
3651
3653 stmt->setUInt16(0, info.type);
3654 stmt->setUInt64(1, info.spawnId);
3655 stmt->setInt64(2, info.respawnTime);
3656 stmt->setUInt16(3, GetId());
3657 stmt->setUInt32(4, GetInstanceId());
3658 CharacterDatabase.ExecuteOrAppend(dbTrans, stmt);
3659}
3660
3662{
3663 if (Instanceable())
3664 return;
3665
3667 stmt->setUInt16(0, GetId());
3668 stmt->setUInt32(1, GetInstanceId());
3669 if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
3670 {
3671 do
3672 {
3673 Field* fields = result->Fetch();
3674 SpawnObjectType type = SpawnObjectType(fields[0].GetUInt16());
3675 ObjectGuid::LowType spawnId = fields[1].GetUInt64();
3676 time_t respawnTime = fields[2].GetInt64();
3677
3678 if (SpawnData::TypeHasData(type))
3679 {
3680 if (SpawnData const* data = sObjectMgr->GetSpawnData(type, spawnId))
3681 SaveRespawnTime(type, spawnId, data->id, time_t(respawnTime), Trinity::ComputeGridCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY()).GetId(), nullptr, true);
3682 else
3683 TC_LOG_ERROR("maps", "Loading saved respawn time of {} for spawnid ({},{}) - spawn does not exist, ignoring", respawnTime, uint32(type), spawnId);
3684 }
3685 else
3686 {
3687 TC_LOG_ERROR("maps", "Loading saved respawn time of {} for spawnid ({},{}) - invalid spawn type, ignoring", respawnTime, uint32(type), spawnId);
3688 }
3689
3690 } while (result->NextRow());
3691 }
3692}
3693
3695{
3696 if (Instanceable())
3697 return;
3698
3700 stmt->setUInt16(0, GetId());
3701 stmt->setUInt32(1, GetInstanceId());
3702 CharacterDatabase.Execute(stmt);
3703}
3704
3706{
3707 ObjectGuid linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid);
3708 switch (linkedGuid.GetHigh())
3709 {
3710 case HighGuid::Creature:
3711 return GetCreatureRespawnTime(linkedGuid.GetCounter());
3713 return GetGORespawnTime(linkedGuid.GetCounter());
3714 default:
3715 break;
3716 }
3717
3718 return time_t(0);
3719}
3720
3722{
3724 stmt->setUInt32(0, GetId());
3725 stmt->setUInt32(1, GetInstanceId());
3726
3727 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3728 // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, race, class, gender, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? AND instanceId = ?
3729 PreparedQueryResult result = CharacterDatabase.Query(stmt);
3730 if (!result)
3731 return;
3732
3733 std::unordered_map<ObjectGuid::LowType, std::unordered_set<uint32>> phases;
3734 std::unordered_map<ObjectGuid::LowType, std::vector<UF::ChrCustomizationChoice>> customizations;
3735
3736 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_PHASES);
3737 stmt->setUInt32(0, GetId());
3738 stmt->setUInt32(1, GetInstanceId());
3739
3740 // 0 1
3741 // SELECT OwnerGuid, PhaseId FROM corpse_phases cp LEFT JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ? AND c.instanceId = ?
3742 if (PreparedQueryResult phaseResult = CharacterDatabase.Query(stmt))
3743 {
3744 do
3745 {
3746 Field* fields = phaseResult->Fetch();
3747 ObjectGuid::LowType guid = fields[0].GetUInt64();
3748 uint32 phaseId = fields[1].GetUInt32();
3749
3750 phases[guid].insert(phaseId);
3751
3752 } while (phaseResult->NextRow());
3753 }
3754
3755 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_CUSTOMIZATIONS);
3756 stmt->setUInt32(0, GetId());
3757 stmt->setUInt32(1, GetInstanceId());
3758
3759 // 0 1 2
3760 // SELECT cc.ownerGuid, cc.chrCustomizationOptionID, cc.chrCustomizationChoiceID FROM corpse_customizations cc LEFT JOIN corpse c ON cc.ownerGuid = c.guid WHERE c.mapId = ? AND c.instanceId = ?
3761 if (PreparedQueryResult customizationResult = CharacterDatabase.Query(stmt))
3762 {
3763 do
3764 {
3765 Field* fields = customizationResult->Fetch();
3766 ObjectGuid::LowType guid = fields[0].GetUInt64();
3767 std::vector<UF::ChrCustomizationChoice>& customizationsForCorpse = customizations[guid];
3768
3769 customizationsForCorpse.emplace_back();
3770 UF::ChrCustomizationChoice& choice = customizationsForCorpse.back();
3771 choice.ChrCustomizationOptionID = fields[1].GetUInt32();
3772 choice.ChrCustomizationChoiceID = fields[2].GetUInt32();
3773
3774 } while (customizationResult->NextRow());
3775 }
3776
3777 do
3778 {
3779 Field* fields = result->Fetch();
3780 CorpseType type = CorpseType(fields[13].GetUInt8());
3781 ObjectGuid::LowType guid = fields[15].GetUInt64();
3782 if (type >= MAX_CORPSE_TYPE || type == CORPSE_BONES)
3783 {
3784 TC_LOG_ERROR("misc", "Corpse (guid: {}) have wrong corpse type ({}), not loading.", guid, type);
3785 continue;
3786 }
3787
3788 Corpse* corpse = new Corpse(type);
3789 if (!corpse->LoadCorpseFromDB(GenerateLowGuid<HighGuid::Corpse>(), fields))
3790 {
3791 delete corpse;
3792 continue;
3793 }
3794
3795 for (uint32 phaseId : phases[guid])
3796 PhasingHandler::AddPhase(corpse, phaseId, false);
3797
3798 corpse->SetCustomizations(Trinity::Containers::MakeIteratorPair(customizations[guid].begin(), customizations[guid].end()));
3799
3800 AddCorpse(corpse);
3801
3802 } while (result->NextRow());
3803}
3804
3806{
3807 // DELETE cp, c FROM corpse_phases cp INNER JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ? AND c.instanceId = ?
3809 stmt->setUInt32(0, GetId());
3810 stmt->setUInt32(1, GetInstanceId());
3811 CharacterDatabase.Execute(stmt);
3812}
3813
3815{
3816 corpse->SetMap(this);
3817
3818 _corpsesByCell[corpse->GetCellCoord().GetId()].insert(corpse);
3819 if (corpse->GetType() != CORPSE_BONES)
3820 _corpsesByPlayer[corpse->GetOwnerGUID()] = corpse;
3821 else
3822 _corpseBones.insert(corpse);
3823}
3824
3826{
3827 ASSERT(corpse);
3828
3830 if (corpse->IsInGrid())
3831 RemoveFromMap(corpse, false);
3832 else
3833 {
3834 corpse->RemoveFromWorld();
3835 corpse->ResetMap();
3836 }
3837
3838 _corpsesByCell[corpse->GetCellCoord().GetId()].erase(corpse);
3839 if (corpse->GetType() != CORPSE_BONES)
3840 _corpsesByPlayer.erase(corpse->GetOwnerGUID());
3841 else
3842 _corpseBones.erase(corpse);
3843}
3844
3845Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= false*/)
3846{
3847 Corpse* corpse = GetCorpseByPlayer(ownerGuid);
3848 if (!corpse)
3849 return nullptr;
3850
3851 RemoveCorpse(corpse);
3852
3853 // remove corpse from DB
3854 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
3855 corpse->DeleteFromDB(trans);
3856 CharacterDatabase.CommitTransaction(trans);
3857
3858 Corpse* bones = nullptr;
3859
3860 // create the bones only if the map and the grid is loaded at the corpse's location
3861 // ignore bones creating option in case insignia
3862 if ((insignia ||
3864 !IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY()))
3865 {
3866 // Create bones, don't change Corpse
3867 bones = new Corpse();
3868 bones->Create(corpse->GetGUID().GetCounter(), this);
3869
3871 bones->SetOwnerGUID(corpse->m_corpseData->Owner);
3872 bones->SetPartyGUID(corpse->m_corpseData->PartyGUID);
3873 bones->SetGuildGUID(corpse->m_corpseData->GuildGUID);
3874 bones->SetDisplayId(corpse->m_corpseData->DisplayID);
3875 bones->SetRace(corpse->m_corpseData->RaceID);
3876 bones->SetSex(corpse->m_corpseData->Sex);
3877 bones->SetClass(corpse->m_corpseData->Class);
3878 bones->SetCustomizations(Trinity::Containers::MakeIteratorPair(corpse->m_corpseData->Customizations.begin(), corpse->m_corpseData->Customizations.end()));
3879 bones->ReplaceAllFlags(corpse->m_corpseData->Flags | CORPSE_FLAG_BONES);
3880 bones->SetFactionTemplate(corpse->m_corpseData->FactionTemplate);
3881
3882 bones->SetCellCoord(corpse->GetCellCoord());
3883 bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
3884
3885 PhasingHandler::InheritPhaseShift(bones, corpse);
3886
3887 AddCorpse(bones);
3888
3889 bones->UpdatePositionData();
3890 bones->SetZoneScript();
3891
3892 // add bones in grid store if grid loaded where corpse placed
3893 AddToMap(bones);
3894 }
3895
3896 // all references to the corpse should be removed at this point
3897 delete corpse;
3898
3899 return bones;
3900}
3901
3903{
3904 time_t now = GameTime::GetGameTime();
3905
3906 std::vector<ObjectGuid> corpses;
3907 corpses.reserve(_corpsesByPlayer.size());
3908
3909 for (auto const& p : _corpsesByPlayer)
3910 if (p.second->IsExpired(now))
3911 corpses.push_back(p.first);
3912
3913 for (ObjectGuid const& ownerGuid : corpses)
3914 ConvertCorpseToBones(ownerGuid);
3915
3916 std::vector<Corpse*> expiredBones;
3917 for (Corpse* bones : _corpseBones)
3918 if (bones->IsExpired(now))
3919 expiredBones.push_back(bones);
3920
3921 for (Corpse* bones : expiredBones)
3922 {
3923 RemoveCorpse(bones);
3924 delete bones;
3925 }
3926}
3927
3928void Map::SendZoneDynamicInfo(uint32 zoneId, Player* player) const
3929{
3930 auto itr = _zoneDynamicInfo.find(zoneId);
3931 if (itr == _zoneDynamicInfo.end())
3932 return;
3933
3934 if (uint32 music = itr->second.MusicId)
3935 player->SendDirectMessage(WorldPackets::Misc::PlayMusic(music).Write());
3936
3937 SendZoneWeather(itr->second, player);
3938
3939 for (ZoneDynamicInfo::LightOverride const& lightOverride : itr->second.LightOverrides)
3940 {
3942 overrideLight.AreaLightID = lightOverride.AreaLightId;
3943 overrideLight.OverrideLightID = lightOverride.OverrideLightId;
3944 overrideLight.TransitionMilliseconds = lightOverride.TransitionMilliseconds;
3945 player->SendDirectMessage(overrideLight.Write());
3946 }
3947}
3948
3949void Map::SendZoneWeather(uint32 zoneId, Player* player) const
3950{
3952 {
3953 auto itr = _zoneDynamicInfo.find(zoneId);
3954 if (itr == _zoneDynamicInfo.end())
3955 return;
3956
3957 SendZoneWeather(itr->second, player);
3958 }
3959}
3960
3961void Map::SendZoneWeather(ZoneDynamicInfo const& zoneDynamicInfo, Player* player) const
3962{
3963 if (WeatherState weatherId = zoneDynamicInfo.WeatherId)
3964 {
3965 WorldPackets::Misc::Weather weather(weatherId, zoneDynamicInfo.Intensity);
3966 player->SendDirectMessage(weather.Write());
3967 }
3968 else if (zoneDynamicInfo.DefaultWeather)
3969 {
3970 zoneDynamicInfo.DefaultWeather->SendWeatherUpdateToPlayer(player);
3971 }
3972 else
3974}
3975
3976void Map::SetZoneMusic(uint32 zoneId, uint32 musicId)
3977{
3978 _zoneDynamicInfo[zoneId].MusicId = musicId;
3979
3980 Map::PlayerList const& players = GetPlayers();
3981 if (!players.empty())
3982 {
3983 WorldPackets::Misc::PlayMusic playMusic(musicId);
3984 playMusic.Write();
3985
3986 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
3987 if (Player* player = itr->GetSource())
3988 if (player->GetZoneId() == zoneId && !player->HasAuraType(SPELL_AURA_FORCE_WEATHER))
3989 player->SendDirectMessage(playMusic.GetRawPacket());
3990 }
3991}
3992
3994{
3995 WeatherData const* weatherData = WeatherMgr::GetWeatherData(zoneId);
3996 if (!weatherData)
3997 return nullptr;
3998
3999 ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId];
4000 if (!info.DefaultWeather)
4001 {
4002 info.DefaultWeather = std::make_unique<Weather>(zoneId, weatherData);
4003 info.DefaultWeather->ReGenerate();
4004 info.DefaultWeather->UpdateWeather();
4005 }
4006
4007 return info.DefaultWeather.get();
4008}
4009
4011{
4013 if (zoneDynamicInfo)
4014 {
4015 if (WeatherState weatherId = zoneDynamicInfo->WeatherId)
4016 return weatherId;
4017
4018 if (zoneDynamicInfo->DefaultWeather)
4019 return zoneDynamicInfo->DefaultWeather->GetWeatherState();
4020 }
4021
4022 return WEATHER_STATE_FINE;
4023}
4024
4025void Map::SetZoneWeather(uint32 zoneId, WeatherState weatherId, float intensity)
4026{
4027 ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId];
4028 info.WeatherId = weatherId;
4029 info.Intensity = intensity;
4030
4031 Map::PlayerList const& players = GetPlayers();
4032 if (!players.empty())
4033 {
4034 WorldPackets::Misc::Weather weather(weatherId, intensity);
4035 weather.Write();
4036
4037 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
4038 if (Player* player = itr->GetSource())
4039 if (player->GetZoneId() == zoneId)
4040 player->SendDirectMessage(weather.GetRawPacket());
4041 }
4042}
4043
4044void Map::SetZoneOverrideLight(uint32 zoneId, uint32 areaLightId, uint32 overrideLightId, Milliseconds transitionTime)
4045{
4046 ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId];
4047 // client can support only one override for each light (zone independent)
4048 info.LightOverrides.erase(std::remove_if(info.LightOverrides.begin(), info.LightOverrides.end(), [areaLightId](ZoneDynamicInfo::LightOverride const& lightOverride)
4049 {
4050 return lightOverride.AreaLightId == areaLightId;
4051 }), info.LightOverrides.end());
4052
4053 // set new override (if any)
4054 if (overrideLightId)
4055 {
4056 ZoneDynamicInfo::LightOverride& lightOverride = info.LightOverrides.emplace_back();
4057 lightOverride.AreaLightId = areaLightId;
4058 lightOverride.OverrideLightId = overrideLightId;
4059 lightOverride.TransitionMilliseconds = static_cast<uint32>(transitionTime.count());
4060 }
4061
4062 Map::PlayerList const& players = GetPlayers();
4063 if (!players.empty())
4064 {
4066 overrideLight.AreaLightID = areaLightId;
4067 overrideLight.OverrideLightID = overrideLightId;
4068 overrideLight.TransitionMilliseconds = static_cast<uint32>(transitionTime.count());
4069 overrideLight.Write();
4070
4071 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
4072 if (Player* player = itr->GetSource())
4073 if (player->GetZoneId() == zoneId)
4074 player->SendDirectMessage(overrideLight.GetRawPacket());
4075 }
4076}
4077
4079{
4080 Map::PlayerList const& players = GetPlayers();
4081 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
4082 {
4083 if (Player* player = itr->GetSource())
4084 {
4085 if (player->IsInWorld())
4086 {
4087 player->UpdateAreaDependentAuras(player->GetAreaId());
4088 player->UpdateZoneDependentAuras(player->GetZoneId());
4089 }
4090 }
4091 }
4092}
4093
4094std::string Map::GetDebugInfo() const
4095{
4096 std::stringstream sstr;
4097 sstr << std::boolalpha
4098 << "Id: " << GetId() << " InstanceId: " << GetInstanceId() << " Difficulty: " << std::to_string(GetDifficultyID())
4099 << " HasPlayers: " << HavePlayers();
4100 return sstr.str();
4101}
4102
4103std::string InstanceMap::GetDebugInfo() const
4104{
4105 std::stringstream sstr;
4106 sstr << Map::GetDebugInfo() << "\n"
4107 << std::boolalpha
4108 << "ScriptId: " << GetScriptId() << " ScriptName: " << GetScriptName();
4109 return sstr.str();
4110}
4111
std::unordered_map< Player *, UpdateData > UpdateDataMapType
Definition BaseEntity.h:32
#define sBattlegroundMgr
@ CHAR_SEL_CORPSE_CUSTOMIZATIONS
@ CHAR_DEL_ALL_RESPAWNS
@ CHAR_REP_RESPAWN
@ CHAR_SEL_CORPSE_PHASES
@ CHAR_DEL_RESPAWN
@ CHAR_SEL_CORPSES
@ CHAR_DEL_CORPSES_FROM_MAP
@ CHAR_SEL_RESPAWNS
@ IN_MILLISECONDS
Definition Common.h:38
@ WEEK
Definition Common.h:35
#define sConditionMgr
@ CONDITION_SOURCE_TYPE_SPAWN_GROUP
CorpseType
Definition Corpse.h:30
@ CORPSE_BONES
Definition Corpse.h:31
@ CORPSE_FLAG_BONES
Definition Corpse.h:43
#define MAX_CORPSE_TYPE
Definition Corpse.h:35
DB2Storage< DifficultyEntry > sDifficultyStore("Difficulty.db2", &DifficultyLoadInfo::Instance)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
@ DIFFICULTY_FLAG_DISPLAY_MYTHIC
Definition DBCEnums.h:982
@ DIFFICULTY_FLAG_DISPLAY_HEROIC
Definition DBCEnums.h:981
Difficulty
Definition DBCEnums.h:932
@ DIFFICULTY_25_HC
Definition DBCEnums.h:939
@ DIFFICULTY_NORMAL_RAID
Definition DBCEnums.h:945
@ DIFFICULTY_NORMAL
Definition DBCEnums.h:934
@ DIFFICULTY_LFR_15TH_ANNIVERSARY
Definition DBCEnums.h:968
@ DIFFICULTY_HEROIC
Definition DBCEnums.h:935
@ DIFFICULTY_MYTHIC_KEYSTONE
Definition DBCEnums.h:941
@ DIFFICULTY_3_MAN_SCENARIO_HC
Definition DBCEnums.h:943
@ DIFFICULTY_TIMEWALKING_RAID
Definition DBCEnums.h:960
@ DIFFICULTY_TIMEWALKING
Definition DBCEnums.h:953
@ DIFFICULTY_10_N
Definition DBCEnums.h:936
@ DIFFICULTY_25_N
Definition DBCEnums.h:937
@ DIFFICULTY_NORMAL_WARFRONT
Definition DBCEnums.h:966
@ DIFFICULTY_NORMAL_ISLAND
Definition DBCEnums.h:962
@ DIFFICULTY_LFR_NEW
Definition DBCEnums.h:948
@ DIFFICULTY_10_HC
Definition DBCEnums.h:938
@ DIFFICULTY_LFR
Definition DBCEnums.h:940
@ IgnoreInstanceFarmLimit
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
#define UI64FMTD
Definition Define.h:138
#define TC_GAME_API
Definition Define.h:129
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint32_t uint32
Definition Define.h:154
std::unordered_set< uint32 > params[2]
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
#define ABORT_MSG
Definition Errors.h:88
#define ABORT
Definition Errors.h:87
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:82
#define ASSERT
Definition Errors.h:80
#define MAX_NUMBER_OF_CELLS
Definition GridDefines.h:36
#define TOTAL_NUMBER_OF_CELLS_PER_MAP
Definition GridDefines.h:53
#define SIZE_OF_GRIDS
Definition GridDefines.h:40
CoordPair< MAX_NUMBER_OF_GRIDS > GridCoord
#define MAX_NUMBER_OF_GRIDS
Definition GridDefines.h:38
#define CENTER_GRID_CELL_ID
Definition GridDefines.h:50
#define SIZE_OF_GRID_CELL
Definition GridDefines.h:48
#define CENTER_GRID_ID
Definition GridDefines.h:41
NGrid< MAX_NUMBER_OF_CELLS, WorldTypeMapContainer, GridTypeMapContainer > NGridType
Definition GridDefines.h:98
#define CENTER_GRID_OFFSET
Definition GridDefines.h:43
#define sInstanceLockMgr
@ LOG_LEVEL_DEBUG
Definition LogCommon.h:28
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
#define sLog
Definition Log.h:156
#define TC_LOG_WARN(filterType__, message__,...)
Definition Log.h:187
ZLiquidStatus
Definition MapDefines.h:133
#define sMapMgr
Definition MapManager.h:186
@ MAP_OBJECT_CELL_MOVE_INACTIVE
Definition MapObject.h:32
@ MAP_OBJECT_CELL_MOVE_ACTIVE
Definition MapObject.h:31
@ MAP_OBJECT_CELL_MOVE_NONE
Definition MapObject.h:30
static void PushRespawnInfoFrom(std::vector< RespawnInfo const * > &data, RespawnInfoMap const &map)
Definition Map.cpp:2127
GridState * si_GridStates[MAX_GRID_STATE]
Definition Map.cpp:74
#define MIN_UNLOAD_DELAY
Definition Map.h:156
InstanceResetMethod
Definition Map.h:864
std::unordered_map< ObjectGuid::LowType, RespawnInfo * > RespawnInfoMap
Definition Map.h:166
InstanceResetResult
Definition Map.h:871
#define MAP_INVALID_ZONE
Definition Map.h:157
TransferAbortReason
Definition Map.h:90
@ TRANSFER_ABORT_TOO_MANY_INSTANCES
Definition Map.h:95
@ TRANSFER_ABORT_DIFFICULTY
Definition Map.h:98
@ TRANSFER_ABORT_MAP_NOT_ALLOWED
Definition Map.h:106
@ TRANSFER_ABORT_MAX_PLAYERS
Definition Map.h:93
@ TRANSFER_ABORT_ZONE_IN_COMBAT
Definition Map.h:96
@ TRANSFER_ABORT_NONE
Definition Map.h:91
@ TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE
Definition Map.h:107
@ TRANSFER_ABORT_NEED_GROUP
Definition Map.h:101
@ TRANSFER_ABORT_ERROR
Definition Map.h:92
#define TC_METRIC_VALUE(category, value,...)
Definition Metric.h:206
#define TC_METRIC_TAG(name, value)
Definition Metric.h:187
@ GRID_STATE_REMOVAL
Definition NGrid.h:59
@ GRID_STATE_INVALID
Definition NGrid.h:56
@ GRID_STATE_IDLE
Definition NGrid.h:58
@ GRID_STATE_ACTIVE
Definition NGrid.h:57
@ MAX_GRID_STATE
Definition NGrid.h:60
#define DEFAULT_VISIBILITY_NOTIFY_PERIOD
Definition NGrid.h:29
#define MAX_VISIBILITY_DISTANCE
#define DEFAULT_VISIBILITY_DISTANCE
@ TYPEID_AREATRIGGER
Definition ObjectGuid.h:49
@ TYPEID_DYNAMICOBJECT
Definition ObjectGuid.h:47
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:46
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_CORPSE
Definition ObjectGuid.h:48
@ TYPEID_CONVERSATION
Definition ObjectGuid.h:51
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
HighGuid
Definition ObjectGuid.h:109
#define sObjectMgr
Definition ObjectMgr.h:1885
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:48
@ RAID_INSTANCE_EXPIRED
Definition Player.h:889
#define sPoolMgr
Definition PoolMgr.h:179
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
#define sScriptMgr
Definition ScriptMgr.h:1449
@ TEAM_NEUTRAL
@ TEAM_ALLIANCE
@ TEAM_HORDE
LineOfSightChecks
@ LINEOFSIGHT_CHECK_VMAP
@ LINEOFSIGHT_CHECK_GOBJECT
@ WS_TEAM_IN_INSTANCE_ALLIANCE
@ WS_TEAM_IN_INSTANCE_HORDE
@ SPAWNGROUP_FLAG_DYNAMIC_SPAWN_RATE
Definition SpawnData.h:59
@ SPAWNGROUP_FLAG_MANUAL_SPAWN
Definition SpawnData.h:58
@ SPAWNGROUP_FLAG_DESPAWN_ON_CONDITION_FAILURE
Definition SpawnData.h:61
@ SPAWNGROUP_FLAG_SYSTEM
Definition SpawnData.h:56
@ SPAWNGROUP_FLAG_ESCORTQUESTNPC
Definition SpawnData.h:60
SpawnObjectTypeMask
Definition SpawnData.h:44
@ SPAWN_TYPEMASK_CREATURE
Definition SpawnData.h:45
@ SPAWN_TYPEMASK_GAMEOBJECT
Definition SpawnData.h:46
SpawnObjectType
Definition SpawnData.h:35
@ SPAWN_TYPE_GAMEOBJECT
Definition SpawnData.h:37
@ SPAWN_TYPE_AREATRIGGER
Definition SpawnData.h:38
@ SPAWN_TYPE_CREATURE
Definition SpawnData.h:36
@ SPELL_AURA_FORCE_WEATHER
#define sTerrainMgr
Definition TerrainMgr.h:167
#define sTransportMgr
bool LoadFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap, bool allowDuplicate)
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
void SetDestroyedObject(bool destroyed)
Definition BaseEntity.h:199
bool IsInWorld() const
Definition BaseEntity.h:158
void BuildDestroyUpdateBlock(UpdateData *data) const
virtual void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
bool IsPlayer() const
Definition BaseEntity.h:173
bool IsDestroyedObject() const
Definition BaseEntity.h:198
TypeID GetTypeId() const
Definition BaseEntity.h:166
void BuildOutOfRangeUpdateBlock(UpdateData *data) const
virtual void BuildUpdate(UpdateDataMapType &data_map)
Definition BaseEntity.h:200
TransferAbortParams CannotEnter(Player *player) override
Definition Map.cpp:3468
BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Difficulty spawnMode)
Definition Map.cpp:3416
void SetUnload()
Definition Map.cpp:3497
void RemoveAllPlayers() override
Definition Map.cpp:3502
std::unique_ptr< BattlegroundScript > _battlegroundScript
Definition Map.h:948
Battleground * GetBG() const
Definition Map.h:937
void InitScriptData()
Definition Map.cpp:3445
std::string const & GetScriptName() const
Definition Map.cpp:3440
bool AddPlayerToMap(Player *player, bool initPlayer=true) override
Definition Map.cpp:3485
Battleground * m_bg
Definition Map.h:947
void RemovePlayerFromMap(Player *, bool) override
Definition Map.cpp:3491
virtual void InitVisibilityDistance() override
Definition Map.cpp:3433
uint32 _scriptId
Definition Map.h:949
void Update(uint32 diff) override
Definition Map.cpp:3511
void SetBgMap(BattlegroundMap *map)
void clear()
Definition ByteBuffer.h:120
std::unordered_map< ObjectGuid, CombatReference * > const & GetPvECombatRefs() const
void ReplaceAllFlags(uint32 flags)
Definition Corpse.h:107
void SetRace(uint8 race)
Definition Corpse.h:104
void SetClass(uint8 playerClass)
Definition Corpse.h:105
void SetSex(uint8 sex)
Definition Corpse.h:106
void SetGuildGUID(ObjectGuid guildGuid)
Definition Corpse.h:102
void SetDisplayId(uint32 displayId)
Definition Corpse.h:103
void SetCustomizations(Trinity::IteratorPair< Iter > customizations)
Definition Corpse.h:114
CorpseDynFlags GetCorpseDynamicFlags() const
Definition Corpse.h:93
void SetFactionTemplate(int32 factionTemplate)
Definition Corpse.h:108
void RemoveFromWorld() override
Definition Corpse.cpp:58
void SetOwnerGUID(ObjectGuid owner)
Definition Corpse.h:100
void SetPartyGUID(ObjectGuid partyGuid)
Definition Corpse.h:101
UF::UpdateField< UF::CorpseData, int32(WowCS::EntityFragment::CGObject), TYPEID_CORPSE > m_corpseData
Definition Corpse.h:139
CellCoord const & GetCellCoord() const
Definition Corpse.h:129
void ReplaceAllCorpseDynamicFlags(CorpseDynFlags dynamicFlags)
Definition Corpse.h:96
ObjectGuid GetOwnerGUID() const override
Definition Corpse.h:99
bool LoadCorpseFromDB(ObjectGuid::LowType guid, Field *fields)
Definition Corpse.cpp:183
void SetCellCoord(CellCoord const &cellCoord)
Definition Corpse.h:130
bool Create(ObjectGuid::LowType guidlow, Map *map)
Definition Corpse.cpp:67
CorpseType GetType() const
Definition Corpse.h:127
void DeleteFromDB(CharacterDatabaseTransaction trans)
Definition Corpse.cpp:158
bool LoadFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap, bool allowDuplicate)
bool IsEscorted() const
Position GetRespawnPosition(float *dist=nullptr) const
bool m_isTempWorldObject
Definition Creature.h:429
bool isInLineOfSight(G3D::Vector3 const &startPos, G3D::Vector3 const &endPos, PhaseShift const &phaseShift) const
bool getObjectHitPos(G3D::Vector3 const &startPos, G3D::Vector3 const &endPos, G3D::Vector3 &resultHitPos, float modifyDist, PhaseShift const &phaseShift) const
void update(uint32 diff)
Class used to access individual fields of database query result.
Definition Field.h:94
uint64 GetUInt64() const noexcept
Definition Field.cpp:71
uint32 GetUInt32() const noexcept
Definition Field.cpp:57
int64 GetInt64() const noexcept
Definition Field.cpp:78
const G3D::AABox & getBounds() const
G3D::Vector3 const & GetPosition() const
bool LoadFromDB(ObjectGuid::LowType spawnId, Map *map, bool addToMap, bool=true)
void RemoveFromWorld() override
ObjectGuid::LowType GetSpawnId() const
Definition GameObject.h:212
void AfterRelocation()
Transport * ToTransport()
Definition GameObject.h:406
void AddToWorld() override
Position GetRespawnPosition() const
PeriodicTimer & getRelocationTimer()
Definition NGrid.h:45
void RemoveFromGrid()
Definition GridObject.h:32
bool IsInGrid() const
Definition GridObject.h:30
virtual void Update(Map &, NGridType &, GridInfo &, uint32 t_diff) const =0
Definition Grid.h:42
void AddWorldObject(SPECIFIC_OBJECT *obj)
Definition Grid.h:53
void AddGridObject(SPECIFIC_OBJECT *obj)
Definition Grid.h:95
Definition Group.h:205
bool isRaidGroup() const
Definition Group.cpp:1628
virtual InstanceLockData const * GetInstanceInitializationData() const
bool IsExtended() const
void SetInUse(bool inUse)
InstanceResetTimePoint GetExpiryTime() const
bool IsNew() const
bool IsExpired() const
InstanceLockData * GetData()
Optional< SystemTimePoint > i_instanceExpireEvent
Definition Map.h:913
InstanceLock * i_instanceLock
Definition Map.h:917
TransferAbortParams CannotEnter(Player *player) override
Definition Map.cpp:2877
void Update(uint32) override
Definition Map.cpp:2962
InstanceResetResult Reset(InstanceResetMethod method)
Definition Map.cpp:3047
TeamId GetTeamIdInInstance() const
Definition Map.cpp:3405
std::unique_ptr< InstanceScenario > i_scenario
Definition Map.h:916
void TrySetOwningGroup(Group *group)
Definition Map.cpp:3038
void CreateInstanceLockForPlayer(Player *player)
Definition Map.cpp:3228
uint32 GetMaxPlayers() const
Definition Map.cpp:3396
virtual void InitVisibilityDistance() override
Definition Map.cpp:2867
uint32 GetScriptId() const
Definition Map.h:888
void RemovePlayerFromMap(Player *, bool) override
Definition Map.cpp:2982
InstanceMap(uint32 id, time_t, uint32 InstanceId, Difficulty SpawnMode, TeamId InstanceTeam, InstanceLock *instanceLock, Optional< uint32 > lfgDungeonsId)
Definition Map.cpp:2837
GroupInstanceReference i_owningGroupRef
Definition Map.h:918
bool AddPlayerToMap(Player *player, bool initPlayer=true) override
Definition Map.cpp:2920
InstanceScript * i_data
Definition Map.h:914
std::string const & GetScriptName() const
Definition Map.cpp:3110
void SetInstanceScenario(InstanceScenario *scenario)
Definition Map.cpp:3115
std::string GetDebugInfo() const override
Definition Map.cpp:4103
void CreateInstanceData()
Definition Map.cpp:2999
uint32 i_script_id
Definition Map.h:915
Group * GetOwningGroup() const
Definition Map.h:908
InstanceScript * GetInstanceScript()
Definition Map.h:890
void UpdateInstanceLock(UpdateBossStateSaveDataEvent const &updateSaveDataEvent)
Definition Map.cpp:3132
~InstanceMap()
Definition Map.cpp:2859
std::string GetSaveData()
Optional< uint32 > GetEntranceLocationForCompletedEncounters(uint32 completedEncountersMask) const
void Load(char const *data)
virtual void OnPlayerLeave(Player *)
void UpdateCombatResurrection(uint32 diff)
virtual void Create()
void SetEntranceLocation(uint32 worldSafeLocationId)
std::string UpdateAdditionalSaveData(std::string const &oldData, UpdateAdditionalSaveDataEvent const &event)
virtual void OnPlayerEnter(Player *)
virtual void Update(uint32)
std::string UpdateBossStateSaveData(std::string const &oldData, UpdateBossStateSaveDataEvent const &event)
uint32 size() const
Definition LinkedList.h:129
bool empty() const
Definition LinkedList.h:107
static bool isRebuildingTilesEnabledOnMap(uint32 mapId)
static MMapManager * instance()
MapObjectCellMoveState _moveState
Definition MapObject.h:51
Position _newPosition
Definition MapObject.h:52
void SetNewCellPosition(float x, float y, float z, float o)
Definition MapObject.h:53
Cell const & GetCurrentCell() const
Definition MapObject.h:48
Definition Map.h:225
MapEntry const * i_mapEntry
Definition Map.h:648
void DynamicObjectRelocation(DynamicObject *go, float x, float y, float z, float orientation)
Definition Map.cpp:1111
bool _creatureToMoveLock
Definition Map.h:612
std::map< WorldObject *, bool > i_objectsToSwitch
Definition Map.h:697
WorldObject * GetWorldObjectBySpawnId(SpawnObjectType type, ObjectGuid::LowType spawnId) const
Definition Map.h:443
std::unordered_map< uint32, uint32 > _zonePlayerCountMap
Definition Map.h:808
std::vector< Creature * > _creaturesToMove
Definition Map.h:613
void AddFarSpellCallback(FarSpellCallback &&callback)
Definition Map.cpp:2545
void GameObjectRelocation(GameObject *go, float x, float y, float z, float orientation, bool respawnRelocationOnFail=true)
Definition Map.cpp:1082
void AddGameObjectToMoveList(GameObject *go, float x, float y, float z, float ang)
Definition Map.cpp:1190
void RemoveDynamicObjectFromMoveList(DynamicObject *go)
Definition Map.cpp:1219
bool IsDungeon() const
Definition Map.cpp:3267
void CreatureRelocation(Creature *creature, float x, float y, float z, float ang, bool respawnRelocationOnFail=true)
Definition Map.cpp:1050
ZLiquidStatus GetLiquidStatus(PhaseShift const &phaseShift, float x, float y, float z, Optional< map_liquidHeaderTypeFlags > ReqLiquidType={}, LiquidData *data=nullptr, float collisionHeight=2.03128f)
Definition Map.cpp:1694
void SetZoneMusic(uint32 zoneId, uint32 musicId)
Definition Map.cpp:3976
bool IsBattlegroundOrArena() const
Definition Map.cpp:3369
void RemoveInfiniteAOIVignette(Vignettes::VignetteData *vignette)
Definition Map.cpp:482
bool UnloadGrid(NGridType &ngrid, bool pForce)
Definition Map.cpp:1567
void SetSpawnGroupInactive(uint32 groupId)
Definition Map.h:753
std::unordered_map< ObjectGuid, Corpse * > _corpsesByPlayer
Definition Map.h:822
void UpdateSpawnGroupConditions()
Definition Map.cpp:2506
void SetZoneWeather(uint32 zoneId, WeatherState weatherId, float intensity)
Definition Map.cpp:4025
Pet * GetPet(ObjectGuid const &guid)
Definition Map.cpp:3557
MapStoredObjectTypesContainer & GetObjectsStore()
Definition Map.h:458
TransportsContainer::iterator _transportsUpdateIter
Definition Map.h:669
bool IsNormal() const
Definition Map.cpp:3295
void InitializeObject(T *obj)
Definition Map.cpp:502
bool SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn=false, bool force=false, std::vector< WorldObject * > *spawnedObjects=nullptr)
Definition Map.cpp:2350
void SwitchGridContainers(T *obj, bool on)
Definition Map.cpp:215
void AddObjectToRemoveList(WorldObject *obj)
Definition Map.cpp:2578
std::map< HighGuid, ObjectGuidGenerator > _guidGenerators
Definition Map.h:815
void SendZoneWeather(uint32 zoneId, Player *player) const
Definition Map.cpp:3949
virtual void RemovePlayerFromMap(Player *, bool)
Definition Map.cpp:915
virtual bool AddPlayerToMap(Player *player, bool initPlayer=true)
Definition Map.cpp:382
void MoveAllGameObjectsInMoveList()
Definition Map.cpp:1304
Creature * GetCreatureBySpawnId(ObjectGuid::LowType spawnId) const
Definition Map.cpp:3571
void RemoveAreaTriggerFromMoveList(AreaTrigger *at)
Definition Map.cpp:1238
void DeleteRespawnInfoFromDB(SpawnObjectType type, ObjectGuid::LowType spawnId, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:2187
size_t DespawnAll(SpawnObjectType type, ObjectGuid::LowType spawnId)
Definition Map.cpp:2069
void AddAreaTriggerToMoveList(AreaTrigger *at, float x, float y, float z, float ang)
Definition Map.cpp:1228
std::function< void(Map *)> FarSpellCallback
Definition Map.h:758
void SetSpawnGroupActive(uint32 groupId, bool state)
Definition Map.cpp:2462
void LoadGrid(float x, float y)
Definition Map.cpp:372
bool IsUnderWater(PhaseShift const &phaseShift, float x, float y, float z)
Definition Map.cpp:1740
void SendZoneDynamicInfo(uint32 zoneId, Player *player) const
Definition Map.cpp:3928
void RemoveFromActive(WorldObject *obj)
Definition Map.cpp:2774
MapDifficultyEntry const * GetMapDifficulty() const
Definition Map.cpp:3252
PeriodicTimer _vignetteUpdateTimer
Definition Map.h:860
std::shared_ptr< MMAP::DynamicTileBuilder > m_mmapTileRebuilder
Definition Map.h:655
bool AddToMap(T *)
Definition Map.cpp:517
void DeleteCorpseData()
Definition Map.cpp:3805
void AddInfiniteAOIVignette(Vignettes::VignetteData *vignette)
Definition Map.cpp:469
RespawnInfoMap * GetRespawnMapForType(SpawnObjectType type)
Definition Map.h:775
void EnsureGridCreated(GridCoord const &)
Definition Map.cpp:279
virtual TransferAbortParams CannotEnter(Player *)
Definition Map.h:356
RespawnInfoMap _gameObjectRespawnTimesBySpawnId
Definition Map.h:774
NGridType * i_grids[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS]
Definition Map.h:688
void UpdatePersonalPhasesForPlayer(Player const *player)
Definition Map.cpp:421
void ProcessRespawns()
Definition Map.cpp:2226
Weather * GetOrGenerateZoneDefaultWeather(uint32 zoneId)
Definition Map.cpp:3993
uint32 m_unloadTimer
Definition Map.h:652
virtual void DelayedUpdate(uint32 diff)
Definition Map.cpp:2550
Player * GetPlayer(ObjectGuid const &guid)
Definition Map.cpp:3532
AreaTriggerBySpawnIdContainer & GetAreaTriggerBySpawnIdStore()
Definition Map.h:469
bool IsLFR() const
Definition Map.cpp:3282
void RemoveUpdateObject(BaseEntity *obj)
Definition Map.h:576
bool isInLineOfSight(PhaseShift const &phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const
Definition Map.cpp:1750
bool IsNonRaidDungeon() const
Definition Map.cpp:3272
time_t GetLinkedRespawnTime(ObjectGuid guid) const
Definition Map.cpp:3705
void AddCorpse(Corpse *corpse)
Definition Map.cpp:3814
bool IsBattleground() const
Definition Map.cpp:3359
void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone)
Definition Map.cpp:638
WorldStateValueContainer _worldStateValues
Definition Map.h:848
IntervalTimer _weatherUpdateTimer
Definition Map.h:811
bool CheckRespawn(RespawnInfo *info)
Definition Map.cpp:1989
std::unordered_set< BaseEntity * > _updateObjects
Definition Map.h:825
bool IsRaid() const
Definition Map.cpp:3277
void ProcessRelocationNotifies(const uint32 diff)
Definition Map.cpp:838
void UnloadAllRespawnInfos()
Definition Map.cpp:2153
void UnloadAll()
Definition Map.cpp:1652
void RemoveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, CharacterDatabaseTransaction dbTrans=nullptr, bool alwaysDeleteFromDB=false)
Definition Map.h:727
bool GetEntrancePos(int32 &mapid, float &x, float &y)
Definition Map.cpp:3389
bool _dynamicObjectsToMoveLock
Definition Map.h:618
NGridType * getNGrid(uint32 x, uint32 y) const
Definition Map.h:631
std::shared_ptr< TerrainInfo > m_terrain
Definition Map.h:684
bool Is25ManRaid() const
Definition Map.cpp:3349
bool _gameObjectsToMoveLock
Definition Map.h:615
void RemoveOldCorpses()
Definition Map.cpp:3902
bool IsMythicPlus() const
Definition Map.cpp:3339
uint32 _respawnCheckTimer
Definition Map.h:807
Corpse * ConvertCorpseToBones(ObjectGuid const &ownerGuid, bool insignia=false)
Definition Map.cpp:3845
bool HavePlayers() const
Definition Map.h:393
bool IsRemovalGrid(float x, float y) const
Definition Map.h:268
std::unordered_map< uint32, std::unordered_set< Corpse * > > _corpsesByCell
Definition Map.h:821
MapRefManager m_mapRefManager
Definition Map.h:657
void resetMarkedCells()
Definition Map.h:389
bool ActiveObjectsNearGrid(NGridType const &ngrid) const
Definition Map.cpp:2694
void RemoveCreatureFromMoveList(Creature *c)
Definition Map.cpp:1181
void GetZoneAndAreaId(PhaseShift const &phaseShift, uint32 &zoneid, uint32 &areaid, float x, float y, float z)
Definition Map.cpp:1710
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)
Definition Map.cpp:1761
void ScriptsProcess()
Process queued scripts.
void Visit(Cell const &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:953
ScriptScheduleMap m_scriptSchedule
Definition Map.h:701
void AddWorldObject(WorldObject *obj)
Definition Map.cpp:2731
void GetFullTerrainStatusForPosition(PhaseShift const &phaseShift, float x, float y, float z, PositionFullTerrainStatus &data, Optional< map_liquidHeaderTypeFlags > reqLiquidType={}, float collisionHeight=2.03128f)
Definition Map.cpp:1688
void ResetGridExpiry(NGridType &grid, float factor=1) const
Definition Map.h:289
DynamicMapTree _dynamicTree
Definition Map.h:654
std::vector< GameObject * > _gameObjectsToMove
Definition Map.h:616
void DeleteRespawnInfo(RespawnInfo *info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:2162
bool IsTimewalking() const
Definition Map.cpp:3354
void ApplyDynamicModeRespawnScaling(WorldObject const *obj, ObjectGuid::LowType spawnId, uint32 &respawnDelay, uint32 mode) const
Definition Map.cpp:2277
void LoadRespawnTimes()
Definition Map.cpp:3661
bool GameObjectRespawnRelocation(GameObject *go, bool diffGridOnly)
Definition Map.cpp:1542
void DoOnPlayers(T &&fn)
Definition Map.h:406
float GetWaterOrGroundLevel(PhaseShift const &phaseShift, float x, float y, float z, float *ground=nullptr, bool swim=false, float collisionHeight=2.03128f)
Definition Map.cpp:1745
SceneObject * GetSceneObject(ObjectGuid const &guid)
Definition Map.cpp:3522
time_t i_gridExpiry
Definition Map.h:682
void DeleteRespawnTimesInDB()
Definition Map.cpp:3694
int32 m_VisibilityNotifyPeriod
Definition Map.h:660
float GetMinHeight(PhaseShift const &phaseShift, float x, float y)
Definition Map.cpp:1715
std::unordered_set< Corpse * > _corpseBones
Definition Map.h:823
void RequestRebuildNavMeshOnGameObjectModelChange(GameObjectModel const &model, PhaseShift const &phaseShift)
Definition Map.cpp:1775
void SetWorldStateValue(int32 worldStateId, int32 value, bool hidden)
Definition Map.cpp:435
void AreaTriggerRelocation(AreaTrigger *at, float x, float y, float z, float orientation)
Definition Map.cpp:1141
MPSCQueue< FarSpellCallback > _farSpellCallbacks
Definition Map.h:827
Difficulty i_spawnMode
Definition Map.h:649
int32 GetWorldStateValue(int32 worldStateId) const
Definition Map.cpp:427
AreaTrigger * GetAreaTriggerBySpawnId(ObjectGuid::LowType spawnId) const
Definition Map.cpp:3599
time_t GetGORespawnTime(ObjectGuid::LowType spawnId) const
Definition Map.h:525
void EnsureGridLoadedForActiveObject(Cell const &, WorldObject const *object)
Definition Map.cpp:303
bool i_scriptLock
Definition Map.h:695
static bool CheckGridIntegrity(T *object, bool moved, char const *objType)
Definition Map.cpp:1006
void SendInitSelf(Player *player)
Definition Map.cpp:1849
void DoRespawn(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 gridId)
Definition Map.cpp:2200
virtual void RemoveAllPlayers()
Definition Map.cpp:1635
std::unordered_set< uint32 > _toggledSpawnGroupIds
Definition Map.h:805
bool isCellMarked(uint32 pCellId)
Definition Map.h:390
SpawnGroupTemplateData const * GetSpawnGroupData(uint32 groupId) const
Definition Map.cpp:2342
bool GameObjectCellRelocation(GameObject *go, Cell new_cell)
Definition Map.cpp:1497
void SendToPlayers(WorldPacket const *data) const
Definition Map.cpp:2688
bool AreaTriggerCellRelocation(AreaTrigger *at, Cell new_cell)
Definition Map.cpp:1507
time_t GetCreatureRespawnTime(ObjectGuid::LowType spawnId) const
Definition Map.h:524
MultiPersonalPhaseTracker & GetMultiPersonalPhaseTracker()
Definition Map.h:833
static TransferAbortParams PlayerCannotEnter(uint32 mapid, Player *player)
Definition Map.cpp:1797
bool IsHeroicOrHigher() const
Definition Map.cpp:3344
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:3552
void SetZoneOverrideLight(uint32 zoneId, uint32 areaLightId, uint32 overrideLightId, Milliseconds transitionTime)
Definition Map.cpp:4044
virtual std::string GetDebugInfo() const
Definition Map.cpp:4094
static void DeleteStateMachine()
Definition Map.cpp:129
void SaveRespawnInfoDB(RespawnInfo const &info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:3647
bool IsSpawnGroupActive(uint32 groupId) const
Definition Map.cpp:2476
MapRefManager::iterator m_mapRefIter
Definition Map.h:658
bool CreatureCellRelocation(Creature *creature, Cell new_cell)
Definition Map.cpp:1492
void LoadCorpseData()
Definition Map.cpp:3721
std::unique_ptr< RespawnListContainer > _respawnTimes
Definition Map.h:772
Corpse * GetCorpse(ObjectGuid const &guid)
Definition Map.cpp:3537
time_t GetRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId) const
Definition Map.h:515
void Balance()
Definition Map.h:497
virtual void Update(uint32)
Definition Map.cpp:653
uint32 GetZoneId(PhaseShift const &phaseShift, float x, float y, float z)
Definition Map.cpp:1705
ZoneDynamicInfoMap _zoneDynamicInfo
Definition Map.h:810
bool _areaTriggersToMoveLock
Definition Map.h:621
virtual ~Map()
Definition Map.cpp:93
DynamicObject * GetDynamicObject(ObjectGuid const &guid)
Definition Map.cpp:3547
std::vector< Vignettes::VignetteData * > _infiniteAOIVignettes
Definition Map.h:859
std::vector< AreaTrigger * > _areaTriggersToMove
Definition Map.h:622
void RemoveGameObjectFromMoveList(GameObject *go)
Definition Map.cpp:1200
void LoadGridForActiveObject(float x, float y, WorldObject const *object)
Definition Map.cpp:377
Conversation * GetConversation(ObjectGuid const &guid)
Definition Map.cpp:3527
void RemoveWorldObject(WorldObject *obj)
Definition Map.cpp:2736
std::set< WorldObject * > i_worldObjects
Definition Map.h:698
Difficulty GetDifficultyID() const
Definition Map.h:360
ActiveNonPlayers m_activeNonPlayers
Definition Map.h:663
void SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 gridId, CharacterDatabaseTransaction dbTrans=nullptr, bool startup=false)
Definition Map.cpp:3614
void SendUpdateTransportVisibility(Player *player)
Definition Map.cpp:1921
bool MapObjectCellRelocation(T *object, Cell new_cell, char const *objType)
Definition Map.cpp:1427
void UpdateIteratorBack(Player *player)
Definition Map.cpp:3608
GameObjectBySpawnIdContainer & GetGameObjectBySpawnIdStore()
Definition Map.h:465
bool Instanceable() const
Definition Map.cpp:3262
ObjectGuidGenerator & GetGuidSequenceGenerator(HighGuid high)
Definition Map.cpp:2540
void AddDynamicObjectToMoveList(DynamicObject *go, float x, float y, float z, float ang)
Definition Map.cpp:1209
bool IsScenario() const
Definition Map.cpp:3374
void buildNGridLinkage(NGridType *pNGridType)
Definition Map.h:629
MapEntry const * GetEntry() const
Definition Map.h:231
std::set< WorldObject * > i_objectsToRemove
Definition Map.h:696
bool SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes=false, size_t *count=nullptr)
Definition Map.cpp:2439
MapStoredObjectTypesContainer _objectsStore
Definition Map.h:817
void AddToGrid(T *object, Cell const &cell)
Definition Map.cpp:174
void MoveAllDynamicObjectsInMoveList()
Definition Map.cpp:1348
uint32 GetPlayersCountExceptGMs() const
Definition Map.cpp:2679
void DeleteFromWorld(T *)
Definition Map.cpp:263
void UpdateAreaDependentAuras()
Definition Map.cpp:4078
uint32 GetId() const
Definition Map.cpp:3257
void SendInitTransports(Player *player)
Definition Map.cpp:1879
float m_VisibleDistance
Definition Map.h:653
float GetVisibilityRange() const
Definition Map.h:255
char const * GetMapName() const
Definition Map.cpp:1844
float GetWaterLevel(PhaseShift const &phaseShift, float x, float y)
Definition Map.cpp:1730
Corpse * GetCorpseByPlayer(ObjectGuid const &ownerGuid) const
Definition Map.h:481
void RemoveAllObjectsInRemoveList()
Definition Map.cpp:2605
void MoveAllCreaturesInMoveList()
Definition Map.cpp:1247
bool IsGridLoaded(uint32 gridId) const
Definition Map.h:275
uint32 GetAreaId(PhaseShift const &phaseShift, float x, float y, float z)
Definition Map.cpp:1700
void InitSpawnGroupState()
Definition Map.cpp:2490
void markCell(uint32 pCellId)
Definition Map.h:391
virtual void LoadGridObjects(NGridType *grid, Cell const &cell)
Definition Map.cpp:343
void VisitNearbyCellsOf(WorldObject *obj, TypeContainerVisitor< Trinity::ObjectUpdater, GridTypeMapContainer > &gridVisitor, TypeContainerVisitor< Trinity::ObjectUpdater, WorldTypeMapContainer > &worldVisitor)
Definition Map.cpp:609
WeatherState GetZoneWeather(uint32 zoneId) const
Definition Map.cpp:4010
void AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang)
Definition Map.cpp:1171
void GridUnmarkNoUnload(uint32 x, uint32 y)
Definition Map.cpp:362
void MoveAllAreaTriggersInMoveList()
Definition Map.cpp:1387
CreatureBySpawnIdContainer & GetCreatureBySpawnIdStore()
Definition Map.h:461
float GetGridHeight(PhaseShift const &phaseShift, float x, float y)
Definition Map.cpp:1720
virtual void InitVisibilityDistance()
Definition Map.cpp:165
Map(uint32 id, time_t, uint32 InstanceId, Difficulty SpawnMode)
Definition Map.cpp:137
float GetStaticHeight(PhaseShift const &phaseShift, float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH)
Definition Map.cpp:1725
bool IsHeroic() const
Definition Map.cpp:3311
RespawnInfo * GetRespawnInfo(SpawnObjectType type, ObjectGuid::LowType spawnId) const
Definition Map.cpp:2142
void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y)
Definition Map.h:638
void SendObjectUpdates()
Definition Map.cpp:1964
bool EnsureGridLoaded(Cell const &)
Definition Map.cpp:322
void RemoveFromMap(T *, bool)
Definition Map.cpp:942
std::vector< DynamicObject * > _dynamicObjectsToMove
Definition Map.h:619
uint32 GetInstanceId() const
Definition Map.h:350
TransportsContainer _transports
Definition Map.h:668
void SendRemoveTransports(Player *player)
Definition Map.cpp:1900
PlayerList const & GetPlayers() const
Definition Map.h:403
void AddToActive(WorldObject *obj)
Definition Map.cpp:2741
static void InitStateMachine()
Definition Map.cpp:121
SpawnedPoolData & GetPoolData()
Definition Map.h:755
AreaTrigger * GetAreaTrigger(ObjectGuid const &guid)
Definition Map.cpp:3517
void PlayerRelocation(Player *, float x, float y, float z, float orientation)
Definition Map.cpp:1023
RespawnInfoMap _creatureRespawnTimesBySpawnId
Definition Map.h:773
bool CreatureRespawnRelocation(Creature *c, bool diffGridOnly)
Definition Map.cpp:1512
CreatureBySpawnIdContainer _creatureBySpawnIdStore
Definition Map.h:818
void AddObjectToSwitchList(WorldObject *obj, bool on)
Definition Map.cpp:2588
uint32 i_InstanceId
Definition Map.h:650
bool AddRespawnInfo(RespawnInfo const &info)
Definition Map.cpp:2092
ActiveNonPlayers::iterator m_activeNonPlayersIter
Definition Map.h:664
bool IsMythic() const
Definition Map.cpp:3332
bool IsInWater(PhaseShift const &phaseShift, float x, float y, float z, LiquidData *data=nullptr)
Definition Map.cpp:1735
void RemoveCorpse(Corpse *corpse)
Definition Map.cpp:3825
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:3542
Transport * GetTransport(ObjectGuid const &guid)
Definition Map.cpp:3562
void LoadAllCells()
Definition Map.cpp:114
GameObject * GetGameObjectBySpawnId(ObjectGuid::LowType spawnId) const
Definition Map.cpp:3585
bool isGridObjectDataLoaded(uint32 x, uint32 y) const
Definition Map.h:637
void GridMarkNoUnload(uint32 x, uint32 y)
Definition Map.cpp:349
bool IsGarrison() const
Definition Map.cpp:3379
bool DynamicObjectCellRelocation(DynamicObject *go, Cell new_cell)
Definition Map.cpp:1502
bool IsAlwaysActive() const
Definition Map.cpp:3384
GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore
Definition Map.h:819
void Respawn(RespawnInfo *info, CharacterDatabaseTransaction dbTrans=nullptr)
Definition Map.cpp:2060
void setNGrid(NGridType *grid, uint32 x, uint32 y)
Definition Map.cpp:1954
std::unique_ptr< SpawnedPoolData > _poolData
Definition Map.h:816
bool IsBattleArena() const
Definition Map.cpp:3364
bool ShouldBeSpawnedOnGridLoad(SpawnObjectType type, ObjectGuid::LowType spawnId) const
Definition Map.cpp:2321
Definition NGrid.h:70
void decUnloadActiveLock()
Definition NGrid.h:108
void setUnloadExplicitLock(bool on)
Definition NGrid.h:106
void SetGridState(grid_state_t s)
Definition NGrid.h:92
grid_state_t GetGridState(void) const
Definition NGrid.h:91
void VisitAllGrids(TypeContainerVisitor< VISITOR, WORLD_OBJECT_CONTAINER > &visitor)
Definition NGrid.h:136
GridType & GetGridType(const uint32 x, const uint32 y)
Definition NGrid.h:78
bool HasWorldObjectsInNGrid() const
Definition NGrid.h:185
bool isGridObjectDataLoaded() const
Definition NGrid.h:100
int32 getX() const
Definition NGrid.h:93
GridInfo * getGridInfoRef()
Definition NGrid.h:103
int32 getY() const
Definition NGrid.h:94
void incUnloadActiveLock()
Definition NGrid.h:107
void Set(ObjectGuid::LowType val)
LowType GetCounter() const
Definition ObjectGuid.h:336
bool IsMOTransport() const
Definition ObjectGuid.h:376
std::string ToString() const
uint64 LowType
Definition ObjectGuid.h:321
HighGuid GetHigh() const
Definition ObjectGuid.h:331
DynamicObject * ToDynObject()
Definition Object.h:141
GameObject * ToGameObject()
Definition Object.h:131
Creature * ToCreature()
Definition Object.h:121
Definition Pet.h:40
static uint32 GetTerrainMapId(PhaseShift const &phaseShift, uint32 mapId, TerrainInfo const *terrain, float x, float y)
static void AddPhase(WorldObject *object, uint32 phaseId, bool updateVisibility)
static void InheritPhaseShift(WorldObject *target, WorldObject const *source)
static void SendToPlayer(Player const *player, PhaseShift const &phaseShift)
bool Satisfy(AccessRequirement const *ar, uint32 target_map, TransferAbortParams *params=nullptr, bool report=false)
Definition Player.cpp:20074
bool m_InstanceValid
Definition Player.h:2761
bool IsBeingTeleportedFar() const
Definition Player.h:2405
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:6283
void Update(uint32 time) override
Definition Player.cpp:915
void UpdateZone(uint32 newZone, uint32 newArea)
Definition Player.cpp:7602
void AddInstanceEnterTime(uint32 instanceId, time_t enterTime)
Definition Player.cpp:20220
GuidUnorderedSet m_clientGUIDs
Definition Player.h:2699
bool IsLoading() const override
Definition Player.cpp:17958
bool CheckInstanceCount(uint32 instanceId) const
Definition Player.cpp:20213
bool HaveAtClient(BaseEntity const *u) const
Definition Player.cpp:24475
WorldLocation m_homebind
Definition Player.h:2693
WorldSession * GetSession() const
Definition Player.h:2272
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const override
Definition Player.cpp:3593
WorldObject * GetViewpoint() const
Definition Player.cpp:26968
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={}, uint32 teleportSpellId=0)
Definition Player.cpp:1226
bool IsGameMaster() const
Definition Player.h:1309
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition Player.cpp:20041
GuidUnorderedSet m_visibleTransports
Definition Player.h:2700
bool IsInGroup(ObjectGuid groupGuid) const
Definition Player.cpp:24910
MapReference & GetMapRef()
Definition Player.h:2823
uint32 GetBattlegroundId() const
Definition Player.h:2586
void AddToWorld() override
Definition Player.cpp:1534
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2796
void UpdateObjectVisibility(bool forced=true) override
Definition Player.cpp:24822
void SetMap(Map *map) override
Definition Player.cpp:28458
void RemoveFromWorld() override
Definition Player.cpp:1548
Difficulty GetDifficultyID(MapEntry const *mapEntry) const
Definition Player.cpp:30627
void setUInt16(uint8 index, uint16 value)
void setUInt32(uint8 index, uint32 value)
void setInt64(uint8 index, int64 value)
void setUInt64(uint8 index, uint64 value)
iterator end()
Definition RefManager.h:36
iterator begin()
Definition RefManager.h:35
bool isValid() const
Definition Reference.h:79
TO * getTarget() const
Definition Reference.h:85
void link(TO *toObj, FROM *fromObj)
Definition Reference.h:47
virtual void OnPlayerEnter(Player *player)
Definition Scenario.cpp:118
uint32 GetExpectedMapId() const
Returns id of the map that transport is expected to be on, according to current path progress.
Definition Unit.h:635
bool IsVehicle() const
Definition Unit.h:754
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition Unit.cpp:6012
void UpdateObjectVisibility(bool forced=true) override
Definition Unit.cpp:12467
std::array< ObjectGuid, MAX_SUMMON_SLOT > m_SummonSlot
Definition Unit.h:1501
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
bool IsPet() const
Definition Unit.h:751
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition Unit.cpp:10328
bool IsAlive() const
Definition Unit.h:1185
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4814
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4241
CombatManager & GetCombatManager()
Definition Unit.h:1038
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1295
Vehicle * GetVehicleKit() const
Definition Unit.h:1782
bool IsInCombat() const
Definition Unit.h:1058
bool isDead() const
Definition Unit.h:1187
bool HasData() const
Definition UpdateData.h:49
bool BuildPacket(WorldPacket *packet)
static VMapManager * createOrGetVMapManager()
void RelocatePassengers()
Relocate passengers. Must be called after m_base::Relocate.
Definition Vehicle.cpp:579
Weather for one zone.
Definition Weather.h:66
constexpr uint32 GetMapId() const
Definition Position.h:216
bool InSamePhase(PhaseShift const &phaseShift) const
Definition Object.h:314
Map * GetMap() const
Definition Object.h:411
virtual void ResetMap()
Definition Object.cpp:1162
Map * FindMap() const
Definition Object.h:412
void RemoveFromWorld() override
Definition Object.cpp:371
virtual void UpdateObjectVisibilityOnDestroy()
Definition Object.h:511
float GetGridActivationRange() const
Definition Object.cpp:771
PhaseShift & GetPhaseShift()
Definition Object.h:310
void SetZoneScript()
Definition Object.cpp:1384
TransportBase * GetTransport() const
Definition Object.h:537
uint32 GetInstanceId() const
Definition Object.h:308
std::string const & GetName() const
Definition Object.h:342
virtual void SetMap(Map *map)
Definition Object.cpp:1144
void UpdatePositionData()
Definition Object.cpp:346
bool IsStoredInWorldObjectGridContainer() const
Definition Object.cpp:265
uint32 GetZoneId() const
Definition Object.h:332
bool IsAlwaysStoredInWorldObjectGridContainer() const
Definition Object.h:531
virtual void Update(uint32 diff)
Definition Object.cpp:245
virtual void UpdateObjectVisibility(bool forced=true)
Definition Object.cpp:3047
virtual void CleanupsBeforeDelete(bool finalCleanup=true)
Definition Object.cpp:335
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * GetRawPacket() const
Definition Packet.h:38
WorldPacket const * Write() override
Player session in the World.
bool Update(uint32 diff, PacketFilter &updater)
Update the WorldSession (triggered by World update)
static constexpr uint32 SPECIAL_INIT_ACTIVE_MOVER_TIME_SYNC_COUNTER
void SendCalendarRaidLockoutAdded(InstanceLock const *lock)
void RegisterTimeSync(uint32 counter)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
#define sWorld
Definition World.h:916
WeatherState
Definition Weather.h:46
WeatherData const * GetWeatherData(uint32 zone_id)
static void SendFineWeatherUpdateToPlayer(Player *player)
Definition Weather.cpp:199
@ CONFIG_VISIBILITY_NOTIFY_PERIOD_CONTINENT
Definition World.h:430
@ CONFIG_VISIBILITY_NOTIFY_PERIOD_BATTLEGROUND
Definition World.h:432
@ CONFIG_RESPAWN_DYNAMICMINIMUM_CREATURE
Definition World.h:423
@ CONFIG_VISIBILITY_NOTIFY_PERIOD_ARENA
Definition World.h:433
@ CONFIG_INSTANCE_UNLOAD_DELAY
Definition World.h:276
@ CONFIG_EXPANSION
Definition World.h:306
@ CONFIG_VISIBILITY_NOTIFY_PERIOD_INSTANCE
Definition World.h:431
@ CONFIG_RESPAWN_DYNAMICMINIMUM_GAMEOBJECT
Definition World.h:424
@ CONFIG_RESPAWN_MINCHECKINTERVALMS
Definition World.h:418
@ WEATHER_STATE_FINE
Definition Weather.h:47
@ CONFIG_RESPAWN_DYNAMICRATE_CREATURE
Definition World.h:223
@ CONFIG_MAX_VISIBILITY_DISTANCE_ARENA
Definition World.h:231
@ CONFIG_MAX_VISIBILITY_DISTANCE_INSTANCE
Definition World.h:229
@ CONFIG_MAX_VISIBILITY_DISTANCE_BATTLEGROUND
Definition World.h:230
@ CONFIG_MAX_VISIBILITY_DISTANCE_CONTINENT
Definition World.h:228
@ CONFIG_RESPAWN_DYNAMICRATE_GAMEOBJECT
Definition World.h:224
@ CONFIG_CHECK_GOBJECT_LOS
Definition World.h:193
@ CONFIG_GRID_UNLOAD
Definition World.h:108
@ CONFIG_DEATH_BONES_BG_OR_ARENA
Definition World.h:134
@ CONFIG_INSTANCE_IGNORE_RAID
Definition World.h:119
@ CONFIG_RESPAWN_DYNAMIC_ESCORTNPC
Definition World.h:194
@ CONFIG_DEATH_BONES_WORLD
Definition World.h:133
SystemTimePoint GetSystemTime()
Current chrono system_clock time point.
Definition GameTime.cpp:62
time_t GetGameTime()
Definition GameTime.cpp:52
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
void RemoveObject(T *object)
TC_GAME_API Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
auto MapEqualRange(M &map, typename M::key_type const &key)
constexpr IteratorPair< iterator, end_iterator > MakeIteratorPair(iterator first, end_iterator second)
auto MapGetValuePtr(M &map, typename M::key_type const &key)
Definition MapUtils.h:37
GridCoord ComputeGridCoord(float x, float y)
CellCoord ComputeCellCoord(float x, float y)
bool CanSee(Player const *player, VignetteData const &vignette)
Definition Vignette.cpp:125
TC_GAME_API void SetValue(int32 worldStateId, int32 value, bool hidden, Map *map)
TC_GAME_API WorldStateTemplate const * GetWorldStateTemplate(int32 worldStateId)
TC_GAME_API int32 GetValue(int32 worldStateId, Map const *map)
WorldStateValueContainer GetInitialWorldStatesForMap(Map const *map)
STL namespace.
CellCoord high_bound
Definition Cell.h:43
CellCoord low_bound
Definition Cell.h:42
Definition Cell.h:47
uint32 GridX() const
Definition Cell.h:73
struct Cell::@299::@300 Part
void SetNoCreate()
Definition Cell.h:76
unsigned grid_y
Definition Cell.h:97
uint32 GridY() const
Definition Cell.h:74
bool DiffGrid(Cell const &cell) const
Definition Cell.h:65
bool DiffCell(Cell const &cell) const
Definition Cell.h:59
unsigned grid_x
Definition Cell.h:96
uint32 CellX() const
Definition Cell.h:71
uint32 CellY() const
Definition Cell.h:72
static CellArea CalculateCellArea(float x, float y, float radius)
Definition CellImpl.h:46
union Cell::@299 data
bool IsCoordValid() const
uint32 x_coord
void inc_y(uint32 val)
void dec_x(uint32 val)
void inc_x(uint32 val)
uint32 y_coord
uint32 GetId() const
void dec_y(uint32 val)
uint32 EntranceWorldSafeLocId
uint32 CompletedEncountersMask
void SetInterval(time_t interval)
Definition Timer.h:94
time_t GetInterval() const
Definition Timer.h:99
bool Passed()
Definition Timer.h:78
void Update(time_t diff)
Definition Timer.h:71
void Reset()
Definition Timer.h:83
bool IsBattleground() const
bool IsScenario() const
bool GetEntrancePos(int32 &mapid, float &x, float &y) const
bool IsNonRaidDungeon() const
bool IsFlexLocking() const
bool IsBattlegroundOrArena() const
EnumFlag< MapFlags2 > GetFlags2() const
LocalizedString MapName
bool IsGarrison() const
uint8 Expansion() const
bool IsDungeon() const
bool IsRaid() const
bool IsBattleArena() const
bool Instanceable() const
uint8 MaxPlayers
void Update(Map *map, uint32 diff)
void MarkAllPhasesForDeletion(ObjectGuid const &phaseOwner)
void LoadGrid(PhaseShift const &phaseShift, NGridType &grid, Map *map, Cell const &cell)
void UnregisterTrackedObject(WorldObject *object)
void OnOwnerPhaseChanged(WorldObject const *phaseOwner, NGridType *grid, Map *map, Cell const &cell)
void TUpdate(int32 diff)
Definition Timer.h:180
bool TPassed() const
Definition Timer.h:181
bool Update(const uint32 diff)
Definition Timer.h:164
void TReset(int32 diff, int32 period)
Definition Timer.h:182
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
float m_positionX
Definition Position.h:64
float m_positionY
Definition Position.h:65
bool IsPositionValid() const
Definition Position.cpp:42
constexpr void Relocate(float x, float y)
Definition Position.h:74
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
void resetNotify(GridRefManager< T > &m)
Definition Map.cpp:828
void Visit(PlayerMapType &m)
Definition Map.cpp:835
void Visit(GridRefManager< T > &)
Definition Map.cpp:833
void Visit(CreatureMapType &m)
Definition Map.cpp:834
RespawnInfoWithHandle(RespawnInfo const &other)
Definition Map.cpp:88
RespawnListContainer::handle_type handle
Definition Map.cpp:90
uint32 gridId
Definition Map.h:175
ObjectGuid::LowType spawnId
Definition Map.h:172
time_t respawnTime
Definition Map.h:174
virtual ~RespawnInfo()
uint32 entry
Definition Map.h:173
SpawnObjectType type
Definition Map.h:171
uint32 poolId
Definition SpawnData.h:141
SpawnGroupFlags flags
Definition SpawnData.h:72
SpawnObjectType const type
Definition SpawnData.h:120
static constexpr bool TypeHasData(SpawnObjectType type)
Definition SpawnData.h:113
SpawnGroupTemplateData const * spawnGroupData
Definition SpawnData.h:124
uint64 spawnId
Definition SpawnData.h:121
SpawnData const * ToSpawnData() const
Definition SpawnData.h:118
ValueType< ObjectType > Find(typename UnderlyingContainer< ObjectType >::KeyType const &key) const
DungeonEncounterEntry const * DungeonEncounter
EnumFlag< VignetteFlags > GetFlags() const
VignetteEntry const * Data
Definition Vignette.h:41
void FillPacket(WorldPackets::Vignette::VignetteDataSet &dataSet) const
Definition Vignette.cpp:67
std::unordered_set< uint32 > AreaIds
ZoneDynamicInfo()
Definition Map.cpp:76
std::vector< LightOverride > LightOverrides
Definition Map.h:153
WeatherState WeatherId
Definition Map.h:144
std::unique_ptr< Weather > DefaultWeather
Definition Map.h:143
float Intensity
Definition Map.h:145