aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp13
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Maps/Map.cpp13
-rw-r--r--src/server/game/Maps/TerrainMgr.cpp17
-rw-r--r--src/server/game/Maps/TerrainMgr.h5
-rw-r--r--src/server/game/Spells/SpellEffects.cpp74
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp3
7 files changed, 78 insertions, 48 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 03205c45f78..153d1136dd7 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -12801,20 +12801,24 @@ bool Unit::CanSwim() const
return HasUnitFlag(UNIT_FLAG_RENAME | UNIT_FLAG_CAN_SWIM);
}
-void Unit::NearTeleportTo(Position const& pos, bool casting /*= false*/)
+void Unit::NearTeleportTo(TeleportLocation const& target, bool casting)
{
DisableSpline();
- TeleportLocation target{ .Location = { GetMapId(), pos } };
if (GetTypeId() == TYPEID_PLAYER)
ToPlayer()->TeleportTo(target, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : TELE_TO_NONE));
else
{
SendTeleportPacket(target);
- UpdatePosition(pos, true);
+ UpdatePosition(target.Location, true);
UpdateObjectVisibility();
}
}
+void Unit::NearTeleportTo(Position const& pos, bool casting /*= false*/)
+{
+ NearTeleportTo(TeleportLocation{ .Location = { GetMapId(), pos } }, casting);
+}
+
void Unit::SendTeleportPacket(TeleportLocation const& teleportLocation)
{
// SMSG_MOVE_UPDATE_TELEPORT is sent to nearby players to signal the teleport
@@ -12856,7 +12860,10 @@ void Unit::SendTeleportPacket(TeleportLocation const& teleportLocation)
moveUpdateTeleport.Status->transport.pos.Relocate(teleportLocation.Location);
}
else
+ {
moveUpdateTeleport.Status->pos.Relocate(teleportLocation.Location);
+ moveUpdateTeleport.Status->transport.Reset();
+ }
}
// Broadcast the packet to everyone except self.
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 22a872a7020..8973b439717 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1122,6 +1122,7 @@ class TC_GAME_API Unit : public WorldObject
void SendSpellDamageResist(Unit* target, uint32 spellId);
void SendSpellDamageImmune(Unit* target, uint32 spellId, bool isPeriodic);
+ void NearTeleportTo(TeleportLocation const& target, bool casting = false);
void NearTeleportTo(Position const& pos, bool casting = false);
void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false) { NearTeleportTo(Position(x, y, z, orientation), casting); }
void SendTeleportPacket(TeleportLocation const& teleportLocation);
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index b95bd2b9359..e9e4748b440 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -138,20 +138,9 @@ i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(Inst
m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_mapRefIter(m_mapRefManager.end()),
m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD),
m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transports.end()),
-i_gridExpiry(expiry), m_terrain(sTerrainMgr.LoadTerrain(id)), m_forceEnabledNavMeshFilterFlags(0), m_forceDisabledNavMeshFilterFlags(0),
+i_gridExpiry(expiry), m_terrain(sTerrainMgr.LoadTerrain(id)), m_forceEnabledNavMeshFilterFlags(0), m_forceDisabledNavMeshFilterFlags(0), i_grids(),
i_scriptLock(false), _respawnTimes(std::make_unique<RespawnListContainer>()), _respawnCheckTimer(0), _vignetteUpdateTimer(5200, 5200)
{
- for (uint32 x = 0; x < MAX_NUMBER_OF_GRIDS; ++x)
- {
- for (uint32 y = 0; y < MAX_NUMBER_OF_GRIDS; ++y)
- {
- //z code
- setNGrid(nullptr, x, y);
- }
- }
-
- _zonePlayerCountMap.clear();
-
//lets initialize visibility distance for map
Map::InitVisibilityDistance();
diff --git a/src/server/game/Maps/TerrainMgr.cpp b/src/server/game/Maps/TerrainMgr.cpp
index 65655e6e84b..7dc70479a96 100644
--- a/src/server/game/Maps/TerrainMgr.cpp
+++ b/src/server/game/Maps/TerrainMgr.cpp
@@ -32,7 +32,7 @@
#include "World.h"
#include <G3D/g3dmath.h>
-TerrainInfo::TerrainInfo(uint32 mapId) : _mapId(mapId), _parentTerrain(nullptr), _cleanupTimer(randtime(CleanupInterval / 2, CleanupInterval))
+TerrainInfo::TerrainInfo(uint32 mapId) : _mapId(mapId), _parentTerrain(nullptr), _loadedGrids(), _cleanupTimer(randtime(CleanupInterval / 2, CleanupInterval))
{
}
@@ -180,7 +180,7 @@ void TerrainInfo::LoadMapAndVMapImpl(int32 gx, int32 gy)
for (std::shared_ptr<TerrainInfo> const& childTerrain : _childTerrain)
childTerrain->LoadMapAndVMapImpl(gx, gy);
- _loadedGrids[GetBitsetIndex(gx, gy)] = true;
+ _loadedGrids[gx] |= UI64LIT(1) << gy;
}
void TerrainInfo::LoadMMapInstanceImpl(uint32 mapId, uint32 instanceId)
@@ -279,7 +279,7 @@ void TerrainInfo::UnloadMapImpl(int32 gx, int32 gy)
for (std::shared_ptr<TerrainInfo> const& childTerrain : _childTerrain)
childTerrain->UnloadMapImpl(gx, gy);
- _loadedGrids[GetBitsetIndex(gx, gy)] = false;
+ _loadedGrids[gx] &= ~(UI64LIT(1) << gy);
}
void TerrainInfo::UnloadMMapInstanceImpl(uint32 mapId, uint32 instanceId)
@@ -294,7 +294,7 @@ GridMap* TerrainInfo::GetGrid(uint32 mapId, float x, float y, bool loadIfMissing
int32 gy = (int)(CENTER_GRID_ID - y / SIZE_OF_GRIDS); //grid y
// ensure GridMap is loaded
- if (!_loadedGrids[GetBitsetIndex(gx, gy)] && loadIfMissing)
+ if (!(_loadedGrids[gx] & (UI64LIT(1) << gy)) && loadIfMissing)
{
std::lock_guard<std::mutex> lock(_loadMutex);
LoadMapAndVMapImpl(gx, gy);
@@ -303,7 +303,7 @@ GridMap* TerrainInfo::GetGrid(uint32 mapId, float x, float y, bool loadIfMissing
GridMap* grid = _gridMap[gx][gy].get();
if (mapId != GetId())
{
- auto childMapItr = std::find_if(_childTerrain.begin(), _childTerrain.end(), [mapId](std::shared_ptr<TerrainInfo> const& childTerrain) { return childTerrain->GetId() == mapId; });
+ auto childMapItr = std::ranges::find(_childTerrain, mapId, [](std::shared_ptr<TerrainInfo> const& childTerrain) { return childTerrain->GetId(); });
if (childMapItr != _childTerrain.end() && (*childMapItr)->_gridMap[gx][gy])
grid = (*childMapItr)->GetGrid(mapId, x, y, false);
}
@@ -319,9 +319,10 @@ void TerrainInfo::CleanUpGrids(uint32 diff)
// delete those GridMap objects which have refcount = 0
for (int32 x = 0; x < MAX_NUMBER_OF_GRIDS; ++x)
- for (int32 y = 0; y < MAX_NUMBER_OF_GRIDS; ++y)
- if (_loadedGrids[GetBitsetIndex(x, y)] && !_referenceCountFromMap[x][y])
- UnloadMapImpl(x, y);
+ if (_loadedGrids[x])
+ for (int32 y = 0; y < MAX_NUMBER_OF_GRIDS; ++y)
+ if ((_loadedGrids[x] & (UI64LIT(1) << y)) && !_referenceCountFromMap[x][y])
+ UnloadMapImpl(x, y);
_cleanupTimer.Reset(CleanupInterval);
}
diff --git a/src/server/game/Maps/TerrainMgr.h b/src/server/game/Maps/TerrainMgr.h
index 6d3879043b5..ccd06b67e42 100644
--- a/src/server/game/Maps/TerrainMgr.h
+++ b/src/server/game/Maps/TerrainMgr.h
@@ -23,6 +23,7 @@
#include "MapDefines.h"
#include "Position.h"
#include "Timer.h"
+#include <array>
#include <atomic>
#include <bitset>
#include <memory>
@@ -111,8 +112,8 @@ private:
std::mutex _loadMutex;
std::unique_ptr<GridMap> _gridMap[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
std::atomic<uint16> _referenceCountFromMap[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
- std::bitset<MAX_NUMBER_OF_GRIDS* MAX_NUMBER_OF_GRIDS> _loadedGrids;
- std::bitset<MAX_NUMBER_OF_GRIDS* MAX_NUMBER_OF_GRIDS> _gridFileExists; // cache what grids are available for this map (not including parent/child maps)
+ std::array<uint64, (MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS + 63) / 64> _loadedGrids;
+ std::bitset<MAX_NUMBER_OF_GRIDS * MAX_NUMBER_OF_GRIDS> _gridFileExists; // cache what grids are available for this map (not including parent/child maps)
static constexpr Milliseconds CleanupInterval = 1min;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 8ab3c15d1a1..9954a89d928 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1010,12 +1010,12 @@ void Spell::EffectTeleportUnits()
}
// Init dest coordinates
- WorldLocation targetDest(*destTarget);
- if (targetDest.GetMapId() == MAPID_INVALID)
- targetDest.m_mapId = unitTarget->GetMapId();
+ TeleportLocation targetDest{ .Location = *destTarget };
+ if (targetDest.Location.GetMapId() == MAPID_INVALID)
+ targetDest.Location.m_mapId = unitTarget->GetMapId();
- if (!targetDest.GetOrientation() && m_targets.GetUnitTarget())
- targetDest.SetOrientation(m_targets.GetUnitTarget()->GetOrientation());
+ if (!targetDest.Location.GetOrientation() && m_targets.GetUnitTarget())
+ targetDest.Location.SetOrientation(m_targets.GetUnitTarget()->GetOrientation());
Player* player = unitTarget->ToPlayer();
@@ -1023,15 +1023,21 @@ void Spell::EffectTeleportUnits()
{
// Custom loading screen
if (uint32 customLoadingScreenId = effectInfo->MiscValue)
- if (targetDest.GetMapId() != unitTarget->GetMapId() || !unitTarget->IsInDist2d(targetDest, TELEPORT_MIN_LOAD_SCREEN_DISTANCE))
+ if (targetDest.Location.GetMapId() != unitTarget->GetMapId() || !unitTarget->IsInDist2d(targetDest.Location, TELEPORT_MIN_LOAD_SCREEN_DISTANCE))
player->SendDirectMessage(WorldPackets::Spells::CustomLoadScreen(m_spellInfo->Id, customLoadingScreenId).Write());
+ if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
+ {
+ targetDest.TransportGuid = transportGuid;
+ targetDest.Location.Relocate(m_destTargets[effectInfo->EffectIndex]._transportOffset);
+ }
+
TeleportToOptions options = GetTeleportOptions(m_caster, unitTarget, m_destTargets[effectInfo->EffectIndex]);
- player->TeleportTo(targetDest, options, {}, m_spellInfo->Id);
+ player->TeleportTo(targetDest, options, m_spellInfo->Id);
}
- else if (targetDest.GetMapId() == unitTarget->GetMapId())
- unitTarget->NearTeleportTo(targetDest, unitTarget == m_caster);
+ else if (targetDest.Location.GetMapId() == unitTarget->GetMapId())
+ unitTarget->NearTeleportTo(targetDest.Location, unitTarget == m_caster);
else
TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
}
@@ -1039,15 +1045,15 @@ void Spell::EffectTeleportUnits()
class DelayedSpellTeleportEvent : public BasicEvent
{
public:
- explicit DelayedSpellTeleportEvent(Unit* target, WorldLocation const& targetDest, TeleportToOptions options, uint32 spellId)
+ explicit DelayedSpellTeleportEvent(Unit* target, TeleportLocation const& targetDest, TeleportToOptions options, uint32 spellId)
: _target(target), _targetDest(targetDest), _options(options), _spellId(spellId){ }
bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
{
if (Player* player = _target->ToPlayer())
player->TeleportTo(_targetDest, _options);
- else if (_targetDest.GetMapId() == _target->GetMapId())
- _target->NearTeleportTo(_targetDest, (_options & TELE_TO_SPELL) != TELE_TO_NONE);
+ else if (_targetDest.Location.GetMapId() == _target->GetMapId())
+ _target->NearTeleportTo(_targetDest.Location, (_options & TELE_TO_SPELL) != TELE_TO_NONE);
else
TC_LOG_ERROR("spells", "Spell::EffectTeleportUnitsWithVisualLoadingScreen - spellId {} attempted to teleport creature to a different map.", _spellId);
@@ -1056,7 +1062,7 @@ public:
private:
Unit* _target;
- WorldLocation _targetDest;
+ TeleportLocation _targetDest;
TeleportToOptions _options;
uint32 _spellId;
};
@@ -1077,12 +1083,18 @@ void Spell::EffectTeleportUnitsWithVisualLoadingScreen()
}
// Init dest coordinates
- WorldLocation targetDest(*destTarget);
- if (targetDest.GetMapId() == MAPID_INVALID)
- targetDest.m_mapId = unitTarget->GetMapId();
+ TeleportLocation targetDest{ .Location = *destTarget };
+ if (targetDest.Location.GetMapId() == MAPID_INVALID)
+ targetDest.Location.m_mapId = unitTarget->GetMapId();
- if (!targetDest.GetOrientation() && m_targets.GetUnitTarget())
- targetDest.SetOrientation(m_targets.GetUnitTarget()->GetOrientation());
+ if (!targetDest.Location.GetOrientation() && m_targets.GetUnitTarget())
+ targetDest.Location.SetOrientation(m_targets.GetUnitTarget()->GetOrientation());
+
+ if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
+ {
+ targetDest.TransportGuid = transportGuid;
+ targetDest.Location.Relocate(m_destTargets[effectInfo->EffectIndex]._transportOffset);
+ }
if (effectInfo->MiscValueB)
if (Player* playerTarget = unitTarget->ToPlayer())
@@ -2330,8 +2342,20 @@ void Spell::EffectTeleUnitsFaceCaster()
if (unitTarget->IsInFlight())
return;
- if (m_targets.HasDst())
- unitTarget->NearTeleportTo(destTarget->GetPositionX(), destTarget->GetPositionY(), destTarget->GetPositionZ(), destTarget->GetAbsoluteAngle(m_caster), unitTarget == m_caster);
+ if (!m_targets.HasDst())
+ return;
+
+ TeleportLocation targetDest{ .Location = *destTarget };
+ if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
+ {
+ targetDest.TransportGuid = transportGuid;
+ targetDest.Location.Relocate(m_destTargets[effectInfo->EffectIndex]._transportOffset);
+ targetDest.Location.SetOrientation(destTarget->GetAbsoluteAngle(m_caster) - targetDest.Location.GetOrientation());
+ }
+ else
+ targetDest.Location.SetOrientation(destTarget->GetAbsoluteAngle(m_caster));
+
+ unitTarget->NearTeleportTo(destTarget->GetPositionX(), destTarget->GetPositionY(), destTarget->GetPositionZ(), destTarget->GetAbsoluteAngle(m_caster), unitTarget == m_caster);
}
void Spell::EffectLearnSkill()
@@ -3693,8 +3717,14 @@ void Spell::EffectLeap()
if (!m_targets.HasDst())
return;
- Position pos = destTarget->GetPosition();
- unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster);
+ TeleportLocation targetDest{ .Location = *destTarget };
+ if (ObjectGuid transportGuid = m_destTargets[effectInfo->EffectIndex]._transportGUID; !transportGuid.IsEmpty())
+ {
+ targetDest.TransportGuid = transportGuid;
+ targetDest.Location.Relocate(m_destTargets[effectInfo->EffectIndex]._transportOffset);
+ }
+
+ unitTarget->NearTeleportTo(targetDest, unitTarget == m_caster);
}
void Spell::EffectReputation()
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 2b65dd903fb..622c6d65142 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -2628,7 +2628,8 @@ class spell_pri_assured_safety : public spell_pri_prayer_of_mending_SpellScriptB
bool Load() override
{
- return GetCaster()->HasAura(SPELL_PRIEST_ASSURED_SAFETY);
+ return spell_pri_prayer_of_mending_SpellScriptBase::Load()
+ && GetCaster()->HasAura(SPELL_PRIEST_ASSURED_SAFETY);
}
void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const