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