aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2018-02-24 22:35:27 +0100
committerShauren <shauren.trinity@gmail.com>2018-03-25 19:28:36 +0300
commitbea7faa8f9d48894d836c7205b98e36126734d56 (patch)
treedf32e1a56518cb43445c5e708a6a855917bf6c62 /src/server
parent4798d9ce7abd86be381af086763d8dbc9ed67ef3 (diff)
Core/Entities: Take terrain swaps into account when calculating LoS/height/area
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Entities/Object/Object.cpp10
-rw-r--r--src/server/game/Entities/Player/Player.cpp6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp8
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp16
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp2
-rw-r--r--src/server/game/Maps/Map.cpp48
-rw-r--r--src/server/game/Maps/Map.h20
-rw-r--r--src/server/game/Maps/MapManager.h13
-rw-r--r--src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp6
-rw-r--r--src/server/game/Phasing/PhaseShift.cpp29
-rw-r--r--src/server/game/Phasing/PhaseShift.h1
-rw-r--r--src/server/game/Phasing/PhasingHandler.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp6
-rw-r--r--src/server/scripts/Commands/cs_go.cpp8
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp4
-rw-r--r--src/server/scripts/Commands/cs_tele.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp2
19 files changed, 113 insertions, 74 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 1ec8586c90f..7d27d573cac 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1622,17 +1622,17 @@ void WorldObject::RemoveFromWorld()
uint32 WorldObject::GetZoneId() const
{
- return GetBaseMap()->GetZoneId(m_positionX, m_positionY, m_positionZ);
+ return GetBaseMap()->GetZoneId(GetPhaseShift(), m_positionX, m_positionY, m_positionZ);
}
uint32 WorldObject::GetAreaId() const
{
- return GetBaseMap()->GetAreaId(m_positionX, m_positionY, m_positionZ);
+ return GetBaseMap()->GetAreaId(GetPhaseShift(), m_positionX, m_positionY, m_positionZ);
}
void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
{
- GetBaseMap()->GetZoneAndAreaId(zoneid, areaid, m_positionX, m_positionY, m_positionZ);
+ GetBaseMap()->GetZoneAndAreaId(GetPhaseShift(), zoneid, areaid, m_positionX, m_positionY, m_positionZ);
}
InstanceScript* WorldObject::GetInstanceScript()
@@ -2795,7 +2795,7 @@ float NormalizeZforCollision(WorldObject* obj, float x, float y, float z)
return z;
}
LiquidData liquid_status;
- ZLiquidStatus res = obj->GetMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
+ ZLiquidStatus res = obj->GetMap()->getLiquidStatus(obj->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
if (res && liquid_status.level > helper) // water must be above ground
{
if (liquid_status.level > z) // z is underwater
@@ -2822,7 +2822,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
}
destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
- bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
+ bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetPhaseShift().GetTerrainMapId(GetMapId(), pos.m_positionX, pos.m_positionY), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
// collision occured
if (col)
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index d5da4d8e66b..68d5024e959 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -5938,7 +5938,7 @@ void Player::CheckAreaExploreAndOutdoor()
return;
bool isOutdoor;
- uint32 areaId = GetBaseMap()->GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor);
+ uint32 areaId = GetBaseMap()->GetAreaId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor);
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId);
if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor)
@@ -6946,7 +6946,7 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid)
if (!sMapStore.LookupEntry(map))
return 0;
- zone = sMapMgr->GetZoneId(map, posx, posy, posz);
+ zone = sMapMgr->GetZoneId(PhaseShift(), map, posx, posy, posz);
if (zone > 0)
{
@@ -25293,7 +25293,7 @@ int32 Player::NextGroupUpdateSequenceNumber(GroupCategory category)
void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
{
LiquidData liquid_status;
- ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
+ ZLiquidStatus res = m->getLiquidStatus(GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
if (!res)
{
m_MirrorTimerFlags &= ~(UNDERWATER_INWATER | UNDERWATER_INLAVA | UNDERWATER_INSLIME | UNDERWARER_INDARKWATER);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 75590a0c44d..1d4814f7c9b 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3045,12 +3045,12 @@ bool Unit::isInAccessiblePlaceFor(Creature const* c) const
bool Unit::IsInWater() const
{
- return GetBaseMap()->IsInWater(GetPositionX(), GetPositionY(), GetPositionZ());
+ return GetBaseMap()->IsInWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
}
bool Unit::IsUnderWater() const
{
- return GetBaseMap()->IsUnderWater(GetPositionX(), GetPositionY(), GetPositionZ());
+ return GetBaseMap()->IsUnderWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
}
void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z)
@@ -3059,7 +3059,7 @@ void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z)
return;
LiquidData liquid_status;
- ZLiquidStatus res = m->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
+ ZLiquidStatus res = m->getLiquidStatus(GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
if (!res)
{
if (_lastLiquid && _lastLiquid->SpellID)
@@ -7580,7 +7580,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
mountFlags = areaTable->MountFlags;
LiquidData liquid;
- ZLiquidStatus liquidStatus = GetMap()->getLiquidStatus(GetPositionX(), GetPositionY(), GetPositionZ(), MAP_ALL_LIQUIDS, &liquid);
+ ZLiquidStatus liquidStatus = GetMap()->getLiquidStatus(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), MAP_ALL_LIQUIDS, &liquid);
isSubmerged = (liquidStatus & LIQUID_MAP_UNDER_WATER) != 0 || HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
isInWater = (liquidStatus & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 78cd1e7e5b9..737f1952348 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -38,6 +38,7 @@
#include "MotionMaster.h"
#include "ObjectAccessor.h"
#include "ObjectDefines.h"
+#include "PhasingHandler.h"
#include "Player.h"
#include "PoolMgr.h"
#include "QuestDef.h"
@@ -1890,8 +1891,9 @@ void ObjectMgr::LoadCreatures()
for (auto& difficultyPair : mapDifficultyPair.second)
spawnMasks[mapDifficultyPair.first] |= UI64LIT(1) << difficultyPair.first;
+ PhaseShift phaseShift;
- _creatureDataStore.rehash(result->GetRowCount());
+ _creatureDataStore.reserve(result->GetRowCount());
do
{
@@ -2078,7 +2080,8 @@ void ObjectMgr::LoadCreatures()
{
uint32 zoneId = 0;
uint32 areaId = 0;
- sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
+ PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
+ sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA);
@@ -2249,7 +2252,9 @@ void ObjectMgr::LoadGameobjects()
for (auto& difficultyPair : mapDifficultyPair.second)
spawnMasks[mapDifficultyPair.first] |= UI64LIT(1) << difficultyPair.first;
- _gameObjectDataStore.rehash(result->GetRowCount());
+ PhaseShift phaseShift;
+
+ _gameObjectDataStore.reserve(result->GetRowCount());
do
{
@@ -2448,7 +2453,8 @@ void ObjectMgr::LoadGameobjects()
{
uint32 zoneId = 0;
uint32 areaId = 0;
- sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
+ PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
+ sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ);
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA);
@@ -6246,7 +6252,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& lo
uint32 MapId = location.GetMapId();
// search for zone associated closest graveyard
- uint32 zoneId = sMapMgr->GetZoneId(MapId, x, y, z);
+ uint32 zoneId = sMapMgr->GetZoneId(PhaseShift(), MapId, x, y, z);
if (!zoneId)
{
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 66373496997..3ec04849875 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -374,7 +374,7 @@ void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movem
if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
{
// now client not include swimming flag in case jumping under water
- plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
+ plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(plrMover->GetPhaseShift(), movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
}
uint32 mstime = getMSTime();
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 6ffa688ca08..6ece7791b6e 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2511,14 +2511,14 @@ float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y,
LiquidData liquid_status;
- ZLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
+ ZLiquidStatus res = getLiquidStatus(phaseShift, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
return res ? liquid_status.level : ground_z;
}
return VMAP_INVALID_HEIGHT_VALUE;
}
-float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
+float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
{
// find raw .map surface under Z coordinates
float mapHeight = VMAP_INVALID_HEIGHT_VALUE;
@@ -2535,7 +2535,7 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
if (vmgr->isHeightCalcEnabled())
- vmapHeight = vmgr->getHeight(GetId(), x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor
+ vmapHeight = vmgr->getHeight(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, z + 2.0f, maxSearchDist); // look from a bit higher pos to find the floor
}
// mapHeight set for any above raw ground Z or <= INVALID_HEIGHT
@@ -2592,13 +2592,13 @@ inline bool IsOutdoorWMO(uint32 mogpFlags, int32 /*adtId*/, int32 /*rootId*/, in
return outdoor;
}
-bool Map::IsOutdoors(float x, float y, float z) const
+bool Map::IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const
{
uint32 mogpFlags;
int32 adtId, rootId, groupId;
// no wmo found? -> outside by default
- if (!GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
+ if (!GetAreaInfo(phaseShift, x, y, z, mogpFlags, adtId, rootId, groupId))
return true;
AreaTableEntry const* atEntry = nullptr;
@@ -2611,11 +2611,11 @@ bool Map::IsOutdoors(float x, float y, float z) const
return IsOutdoorWMO(mogpFlags, adtId, rootId, groupId, wmoEntry, atEntry);
}
-bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
+bool Map::GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
{
float vmap_z = z;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
- if (vmgr->getAreaInfo(GetId(), x, y, vmap_z, flags, adtId, rootId, groupId))
+ if (vmgr->getAreaInfo(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, vmap_z, flags, adtId, rootId, groupId))
{
// check if there's terrain between player height and object height
if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
@@ -2630,7 +2630,7 @@ bool Map::GetAreaInfo(float x, float y, float z, uint32 &flags, int32 &adtId, in
return false;
}
-uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const
+uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors) const
{
uint32 mogpFlags;
int32 adtId, rootId, groupId;
@@ -2639,7 +2639,7 @@ uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const
bool haveAreaInfo = false;
uint32 areaId = 0;
- if (GetAreaInfo(x, y, z, mogpFlags, adtId, rootId, groupId))
+ if (GetAreaInfo(phaseShift, x, y, z, mogpFlags, adtId, rootId, groupId))
{
haveAreaInfo = true;
wmoEntry = sDB2Manager.GetWMOAreaTable(rootId, adtId, groupId);
@@ -2670,14 +2670,14 @@ uint32 Map::GetAreaId(float x, float y, float z, bool *isOutdoors) const
return areaId;
}
-uint32 Map::GetAreaId(float x, float y, float z) const
+uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z) const
{
- return GetAreaId(x, y, z, nullptr);
+ return GetAreaId(phaseShift, x, y, z, nullptr);
}
-uint32 Map::GetZoneId(float x, float y, float z) const
+uint32 Map::GetZoneId(PhaseShift const& phaseShift, float x, float y, float z) const
{
- uint32 areaId = GetAreaId(x, y, z);
+ uint32 areaId = GetAreaId(phaseShift, x, y, z);
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId))
if (area->ParentAreaID)
return area->ParentAreaID;
@@ -2685,9 +2685,9 @@ uint32 Map::GetZoneId(float x, float y, float z) const
return areaId;
}
-void Map::GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const
+void Map::GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z) const
{
- areaid = zoneid = GetAreaId(x, y, z);
+ areaid = zoneid = GetAreaId(phaseShift, x, y, z);
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaid))
if (area->ParentAreaID)
zoneid = area->ParentAreaID;
@@ -2701,14 +2701,14 @@ uint8 Map::GetTerrainType(float x, float y) const
return 0;
}
-ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const
+ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data) const
{
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
float liquid_level = INVALID_HEIGHT;
float ground_level = INVALID_HEIGHT;
uint32 liquid_type = 0;
- if (vmgr->GetLiquidLevel(GetId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
+ if (vmgr->GetLiquidLevel(phaseShift.GetTerrainMapId(GetId(), x, y), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type))
{
TC_LOG_DEBUG("maps", "getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type);
// Check water level and ground level
@@ -2727,7 +2727,7 @@ ZLiquidStatus Map::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
if (liquid_type && liquid_type < 21)
{
- if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(x, y, z)))
+ if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(GetAreaId(phaseShift, x, y, z)))
{
uint32 overrideLiquid = area->LiquidTypeID[liquidFlagType];
if (!overrideLiquid && area->ParentAreaID)
@@ -2796,7 +2796,7 @@ float Map::GetWaterLevel(float x, float y) const
bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2) const
{
- return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2)
+ return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(phaseShift.GetTerrainMapId(GetId(), x1, x2), x1, y1, z1, x2, y2, z2)
&& _dynamicTree.isInLineOfSight({ x1, y1, z1 }, { x2, y2, z2 }, phaseShift);
}
@@ -2816,19 +2816,19 @@ bool Map::getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, floa
float Map::GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
{
- return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift));
+ return std::max<float>(GetStaticHeight(phaseShift, x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift));
}
-bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const
+bool Map::IsInWater(PhaseShift const& phaseShift, float x, float y, float pZ, LiquidData* data) const
{
LiquidData liquid_status;
LiquidData* liquid_ptr = data ? data : &liquid_status;
- return (getLiquidStatus(x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0;
+ return (getLiquidStatus(phaseShift, x, y, pZ, MAP_ALL_LIQUIDS, liquid_ptr) & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)) != 0;
}
-bool Map::IsUnderWater(float x, float y, float z) const
+bool Map::IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const
{
- return (getLiquidStatus(x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0;
+ return (getLiquidStatus(phaseShift, x, y, z, MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN) & LIQUID_MAP_UNDER_WATER) != 0;
}
bool Map::CheckGridIntegrity(Creature* c, bool moved) const
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index ee43874fe2c..065efc203ad 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -333,23 +333,23 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
// some calls like isInWater should not use vmaps due to processor power
// can return INVALID_HEIGHT if under z+2 z coord not found height
- float GetHeight(float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
+ float GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
float GetMinHeight(float x, float y) const;
- ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const;
+ ZLiquidStatus getLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr) const;
- uint32 GetAreaId(float x, float y, float z, bool *isOutdoors) const;
- bool GetAreaInfo(float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
- uint32 GetAreaId(float x, float y, float z) const;
- uint32 GetZoneId(float x, float y, float z) const;
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const;
+ uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors) const;
+ bool GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
+ uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z) const;
+ uint32 GetZoneId(PhaseShift const& phaseShift, float x, float y, float z) const;
+ void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z) const;
- bool IsOutdoors(float x, float y, float z) const;
+ bool IsOutdoors(PhaseShift const& phaseShift, float x, float y, float z) const;
uint8 GetTerrainType(float x, float y) const;
float GetWaterLevel(float x, float y) const;
- bool IsInWater(float x, float y, float z, LiquidData* data = nullptr) const;
- bool IsUnderWater(float x, float y, float z) const;
+ bool IsInWater(PhaseShift const& phaseShift, float x, float y, float z, LiquidData* data = nullptr) const;
+ bool IsUnderWater(PhaseShift const& phaseShift, float x, float y, float z) const;
void MoveAllCreaturesInMoveList();
void MoveAllGameObjectsInMoveList();
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index 187e70d1bb2..892756db0d4 100644
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -25,6 +25,7 @@
#include "GridStates.h"
#include "MapUpdater.h"
+class PhaseShift;
class Transport;
struct TransportCreatureProto;
@@ -38,20 +39,20 @@ class TC_GAME_API MapManager
Map* CreateMap(uint32 mapId, Player* player, uint32 loginInstanceId=0);
Map* FindMap(uint32 mapId, uint32 instanceId) const;
- uint32 GetAreaId(uint32 mapid, float x, float y, float z) const
+ uint32 GetAreaId(PhaseShift const& phaseShift, uint32 mapid, float x, float y, float z) const
{
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
- return m->GetAreaId(x, y, z);
+ return m->GetAreaId(phaseShift, x, y, z);
}
- uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
+ uint32 GetZoneId(PhaseShift const& phaseShift, uint32 mapid, float x, float y, float z) const
{
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
- return m->GetZoneId(x, y, z);
+ return m->GetZoneId(phaseShift, x, y, z);
}
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
+ void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z)
{
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
- m->GetZoneAndAreaId(zoneid, areaid, x, y, z);
+ m->GetZoneAndAreaId(phaseShift, zoneid, areaid, x, y, z);
}
void Initialize(void);
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
index 05044c95523..210de91f8b0 100644
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -51,7 +51,7 @@ void FleeingMovementGenerator<T>::_setTargetLocation(T* owner)
// Add LOS check for target point
Position mypos = owner->GetPosition();
- bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetMapId(),
+ bool isInLOS = VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(owner->GetPhaseShift().GetTerrainMapId(owner->GetMapId(), mypos.m_positionX, mypos.m_positionY),
mypos.m_positionX,
mypos.m_positionY,
mypos.m_positionZ + 2.0f,
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index f6716a0f4b0..6c9e1cd01d9 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -185,7 +185,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// Check both start and end points, if they're both in water, then we can *safely* let the creature move
for (uint32 i = 0; i < _pathPoints.size(); ++i)
{
- ZLiquidStatus status = _sourceUnit->GetBaseMap()->getLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL);
+ ZLiquidStatus status = _sourceUnit->GetBaseMap()->getLiquidStatus(_sourceUnit->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL);
// One of the points is not in the water, cancel movement.
if (status == LIQUID_MAP_NO_WATER)
{
@@ -211,7 +211,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
Creature* owner = (Creature*)_sourceUnit;
G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos;
- if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z))
+ if (_sourceUnit->GetBaseMap()->IsUnderWater(_sourceUnit->GetPhaseShift(), p.x, p.y, p.z))
{
TC_LOG_DEBUG("maps", "++ BuildPolyPath :: underWater case\n");
if (owner->CanSwim())
@@ -648,7 +648,7 @@ void PathGenerator::UpdateFilter()
NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z)
{
LiquidData data;
- ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data);
+ ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->getLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &data);
if (liquidStatus == LIQUID_MAP_NO_WATER)
return NAV_GROUND;
diff --git a/src/server/game/Phasing/PhaseShift.cpp b/src/server/game/Phasing/PhaseShift.cpp
index b2885ae15bb..d543ccd1f22 100644
--- a/src/server/game/Phasing/PhaseShift.cpp
+++ b/src/server/game/Phasing/PhaseShift.cpp
@@ -17,6 +17,8 @@
#include "PhaseShift.h"
#include "Containers.h"
+#include "GridDefines.h"
+#include "VMapFactory.h"
bool PhaseShift::AddPhase(uint32 phaseId, PhaseFlags flags, std::vector<Condition*> const* areaConditions, int32 references /*= 1*/)
{
@@ -145,6 +147,33 @@ bool PhaseShift::CanSee(PhaseShift const& other) const
return checkInversePhaseShift(other, *this);
}
+uint32 PhaseShift::GetTerrainMapId(uint32 realMapId, float x, float y) const
+{
+ if (VisibleMapIds.empty())
+ return realMapId;
+
+ if (VisibleMapIds.size() == 1)
+ return VisibleMapIds.begin()->first;
+
+ GridCoord gridCoord = Trinity::ComputeGridCoord(x, y);
+ int32 gx = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.x_coord;
+ int32 gy = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.y_coord;
+
+ int32 minDistance = std::numeric_limits<int32>::max();
+ uint32 terrainMapId;
+ for (auto itr = VisibleMapIds.begin(); itr != VisibleMapIds.end(); ++itr)
+ {
+ int32 dist = VMAP::VMapFactory::createOrGetVMapManager()->GetDistanceToClosestPrimaryTile(itr->first, gx, gy);
+ if (dist < minDistance)
+ {
+ minDistance = dist;
+ terrainMapId = itr->first;
+ }
+ }
+
+ return terrainMapId;
+}
+
void PhaseShift::ModifyPhasesReferences(PhaseContainer::iterator itr, int32 references)
{
itr->References += references;
diff --git a/src/server/game/Phasing/PhaseShift.h b/src/server/game/Phasing/PhaseShift.h
index 8755868ae9d..ca38614ed45 100644
--- a/src/server/game/Phasing/PhaseShift.h
+++ b/src/server/game/Phasing/PhaseShift.h
@@ -101,6 +101,7 @@ public:
void ClearPhases();
bool CanSee(PhaseShift const& other) const;
+ uint32 GetTerrainMapId(uint32 realMapId, float x, float y) const;
protected:
friend class PhasingHandler;
diff --git a/src/server/game/Phasing/PhasingHandler.cpp b/src/server/game/Phasing/PhasingHandler.cpp
index 2f0fd7d870e..08ed3f729b0 100644
--- a/src/server/game/Phasing/PhasingHandler.cpp
+++ b/src/server/game/Phasing/PhasingHandler.cpp
@@ -422,6 +422,7 @@ void PhasingHandler::FillPartyMemberPhase(WorldPackets::Party::PartyMemberPhaseS
void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
{
+ phaseShift.ClearPhases();
phaseShift.IsDbPhaseShift = true;
EnumClassFlag<PhaseShiftFlags> flags = PhaseShiftFlags::None;
@@ -449,6 +450,7 @@ void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlag
void PhasingHandler::InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId)
{
+ phaseShift.VisibleMapIds.clear();
if (visibleMapId != -1)
phaseShift.AddVisibleMapId(visibleMapId, sObjectMgr->GetTerrainSwapInfo(visibleMapId));
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 0763be83110..e1dc6d62dfa 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1305,7 +1305,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseShift(), x, y, z, true, 50.0f);
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
LiquidData liquidData;
- if (m_caster->GetMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData))
+ if (m_caster->GetMap()->getLiquidStatus(m_caster->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquidData))
liquidLevel = liquidData.level;
if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
@@ -4909,11 +4909,11 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
if (m_caster->GetTypeId() == TYPEID_PLAYER && VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled())
{
if (m_spellInfo->HasAttribute(SPELL_ATTR0_OUTDOORS_ONLY) &&
- !m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
+ !m_caster->GetMap()->IsOutdoors(m_caster->GetPhaseShift(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
return SPELL_FAILED_ONLY_OUTDOORS;
if (m_spellInfo->HasAttribute(SPELL_ATTR0_INDOORS_ONLY) &&
- m_caster->GetMap()->IsOutdoors(m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
+ m_caster->GetMap()->IsOutdoors(m_caster->GetPhaseShift(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ()))
return SPELL_FAILED_ONLY_INDOORS;
}
diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp
index 255a0854226..09a31c885b7 100644
--- a/src/server/scripts/Commands/cs_go.cpp
+++ b/src/server/scripts/Commands/cs_go.cpp
@@ -247,7 +247,7 @@ public:
player->SaveRecallPosition();
Map const* map = sMapMgr->CreateBaseMap(mapId);
- float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
+ float z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
player->TeleportTo(mapId, x, y, z, player->GetOrientation());
return true;
@@ -369,7 +369,7 @@ public:
player->SaveRecallPosition();
Map const* map = sMapMgr->CreateBaseMap(mapId);
- z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
+ z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
player->TeleportTo(mapId, x, y, z, 0.0f);
return true;
@@ -532,7 +532,7 @@ public:
else
player->SaveRecallPosition();
- float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
+ float z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
player->TeleportTo(zoneEntry->ContinentID, x, y, z, player->GetOrientation());
return true;
@@ -580,7 +580,7 @@ public:
return false;
}
Map const* map = sMapMgr->CreateBaseMap(mapId);
- z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
+ z = std::max(map->GetStaticHeight(PhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(x, y));
}
// stop flight if need
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index c75b528521c..9be3ff64559 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -273,7 +273,7 @@ public:
if (haveVMap)
{
- if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()))
+ if (map->IsOutdoors(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()))
handler->PSendSysMessage(LANG_GPS_POSITION_OUTDOORS);
else
handler->PSendSysMessage(LANG_GPS_POSITION_INDOORS);
@@ -297,7 +297,7 @@ public:
zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap);
LiquidData liquidStatus;
- ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
+ ZLiquidStatus status = map->getLiquidStatus(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
if (status)
handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp
index b4185c7c0b3..79113971fe4 100644
--- a/src/server/scripts/Commands/cs_tele.cpp
+++ b/src/server/scripts/Commands/cs_tele.cpp
@@ -207,7 +207,7 @@ public:
SQLTransaction dummy;
Player::SavePositionInDB(WorldLocation(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation),
- sMapMgr->GetZoneId(tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy);
+ sMapMgr->GetZoneId(PhaseShift(), tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy);
}
return true;
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
index 48333ba31c6..1bfd96f0e35 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp
@@ -272,7 +272,7 @@ public:
Position pos = me->GetRandomNearPosition(10.0f);
//normalize Z-level if we can, if rift is not at ground level.
- pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY));
+ pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY));
if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000))
return summon;
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
index 05faa7524fd..64c8bb0db1d 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
@@ -309,7 +309,7 @@ public:
Position pos = me->GetRandomNearPosition(10.0f);
//normalize Z-level if we can, if rift is not at ground level.
- pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY));
+ pos.m_positionZ = std::max(me->GetMap()->GetHeight(me->GetPhaseShift(), pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY));
if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT))
if (Unit* temp = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MEDIVH)))