aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Collision/DynamicTree.cpp6
-rw-r--r--src/common/Collision/Management/IVMapManager.h24
-rw-r--r--src/common/Collision/Management/VMapManager2.cpp31
-rw-r--r--src/common/Collision/Management/VMapManager2.h1
-rw-r--r--src/common/Collision/Maps/MapTree.h1
-rw-r--r--src/common/Collision/Models/WorldModel.cpp1
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/Object/Object.cpp60
-rw-r--r--src/server/game/Entities/Object/Object.h26
-rw-r--r--src/server/game/Entities/Player/Player.cpp93
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp62
-rw-r--r--src/server/game/Entities/Unit/Unit.h6
-rw-r--r--src/server/game/Maps/Map.cpp126
-rw-r--r--src/server/game/Maps/Map.h36
-rw-r--r--src/server/game/Movement/PathGenerator.cpp4
-rw-r--r--src/server/game/Spells/Spell.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
18 files changed, 329 insertions, 156 deletions
diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp
index ae215e0db4f..b1f03aace13 100644
--- a/src/common/Collision/DynamicTree.cpp
+++ b/src/common/Collision/DynamicTree.cpp
@@ -283,13 +283,13 @@ bool DynamicMapTree::getAreaInfo(float x, float y, float& z, PhaseShift const& p
return false;
}
-void DynamicMapTree::getAreaAndLiquidData(float x, float y, float z, PhaseShift const& phaseShift, uint8 /*reqLiquidType*/, VMAP::AreaAndLiquidData& /*data*/) const
+void DynamicMapTree::getAreaAndLiquidData(float x, float y, float z, PhaseShift const& phaseShift, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const
{
G3D::Vector3 v(x, y, z + 0.5f);
DynamicTreeLocationInfoCallback intersectionCallBack(phaseShift);
impl->intersectPoint(v, intersectionCallBack);
if (intersectionCallBack.GetLocationInfo().hitModel)
- {/* For future use (needs cherry-pick f6c849729b27b77228704b595de3adaf24da2c10)
+ {
data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z;
uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType();
float liquidLevel;
@@ -301,5 +301,5 @@ void DynamicMapTree::getAreaAndLiquidData(float x, float y, float z, PhaseShift
intersectionCallBack.GetLocationInfo().rootId,
intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(),
intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags());
- */}
+ }
}
diff --git a/src/common/Collision/Management/IVMapManager.h b/src/common/Collision/Management/IVMapManager.h
index 809675ec75a..296a1574c0a 100644
--- a/src/common/Collision/Management/IVMapManager.h
+++ b/src/common/Collision/Management/IVMapManager.h
@@ -21,6 +21,7 @@
#include <string>
#include "Define.h"
#include "ModelIgnoreFlags.h"
+#include "Optional.h"
//===========================================================
@@ -48,6 +49,27 @@ namespace VMAP
#define VMAP_INVALID_HEIGHT -100000.0f // for check
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
+ struct AreaAndLiquidData
+ {
+ struct AreaInfo
+ {
+ AreaInfo(int32 _adtId, int32 _rootId, int32 _groupId, uint32 _flags) : adtId(_adtId), rootId(_rootId), groupId(_groupId), mogpFlags(_flags) { }
+ int32 const adtId;
+ int32 const rootId;
+ int32 const groupId;
+ uint32 const mogpFlags;
+ };
+ struct LiquidInfo
+ {
+ LiquidInfo(uint32 _type, float _level) : type(_type), level(_level) { }
+ uint32 const type;
+ float const level;
+ };
+
+ float floorZ = VMAP_INVALID_HEIGHT;
+ Optional<AreaInfo> areaInfo;
+ Optional<LiquidInfo> liquidInfo;
+ };
//===========================================================
class TC_COMMON_API IVMapManager
{
@@ -101,6 +123,8 @@ namespace VMAP
*/
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const=0;
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0;
+ // get both area + liquid data in a single vmap lookup
+ virtual void getAreaAndLiquidData(unsigned int mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const=0;
};
}
diff --git a/src/common/Collision/Management/VMapManager2.cpp b/src/common/Collision/Management/VMapManager2.cpp
index 694a8e13bf9..20d74531dd7 100644
--- a/src/common/Collision/Management/VMapManager2.cpp
+++ b/src/common/Collision/Management/VMapManager2.cpp
@@ -311,6 +311,37 @@ namespace VMAP
return false;
}
+ void VMapManager2::getAreaAndLiquidData(unsigned int mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const
+ {
+ if (IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
+ {
+ data.floorZ = z;
+ int32 adtId, rootId, groupId;
+ uint32 flags;
+ if (getAreaInfo(mapId, x, y, data.floorZ, flags, adtId, rootId, groupId))
+ data.areaInfo = boost::in_place(adtId, rootId, groupId, flags);
+ return;
+ }
+ InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
+ if (instanceTree != iInstanceMapTrees.end())
+ {
+ LocationInfo info;
+ Vector3 pos = convertPositionToInternalRep(x, y, z);
+ if (instanceTree->second->GetLocationInfo(pos, info))
+ {
+ data.floorZ = info.ground_Z;
+ uint32 liquidType = info.hitModel->GetLiquidType();
+ float liquidLevel;
+ if (!reqLiquidType || (GetLiquidFlagsPtr(liquidType) & reqLiquidType))
+ if (info.hitInstance->GetLiquidLevel(pos, info, liquidLevel))
+ data.liquidInfo = boost::in_place(liquidType, liquidLevel);
+
+ if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
+ data.areaInfo = boost::in_place(info.hitInstance->adtId, info.rootId, info.hitModel->GetWmoID(), info.hitModel->GetMogpFlags());
+ }
+ }
+ }
+
WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags/* Only used when creating the model */)
{
//! Critical section, thread safe access to iLoadedModelFiles
diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h
index b40b1aae6fd..f16038264dc 100644
--- a/src/common/Collision/Management/VMapManager2.h
+++ b/src/common/Collision/Management/VMapManager2.h
@@ -121,6 +121,7 @@ namespace VMAP
bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const override;
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const override;
+ void getAreaAndLiquidData(unsigned int mapId, float x, float y, float z, uint8 reqLiquidType, AreaAndLiquidData& data) const override;
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags = 0);
void releaseModelInstance(const std::string& filename);
diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h
index edacfe50f7d..1a0e8965c56 100644
--- a/src/common/Collision/Maps/MapTree.h
+++ b/src/common/Collision/Maps/MapTree.h
@@ -33,6 +33,7 @@ namespace VMAP
struct TC_COMMON_API LocationInfo
{
LocationInfo(): hitInstance(nullptr), hitModel(nullptr), ground_Z(-G3D::finf()) { }
+ int32 rootId;
const ModelInstance* hitInstance;
const GroupModel* hitModel;
float ground_Z;
diff --git a/src/common/Collision/Models/WorldModel.cpp b/src/common/Collision/Models/WorldModel.cpp
index 2e81b650028..c725aea9d6c 100644
--- a/src/common/Collision/Models/WorldModel.cpp
+++ b/src/common/Collision/Models/WorldModel.cpp
@@ -558,6 +558,7 @@ namespace VMAP
groupTree.intersectPoint(p, callback);
if (callback.hit != groupModels.end())
{
+ info.rootId = RootWMOID;
info.hitModel = &(*callback.hit);
dist = callback.zDist;
return true;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index ba761b95ed0..986932856c0 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -3020,7 +3020,7 @@ void Creature::UpdateMovementFlags()
return;
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
- float ground = GetMap()->GetHeight(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
+ float ground = GetFloorZ();
bool isInAir = (G3D::fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 53aa451792e..0d6384ad52e 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -843,7 +843,7 @@ void MovementInfo::OutDebug()
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0),
m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL),
-m_transport(NULL), m_currMap(NULL), m_InstanceId(0),
+m_transport(NULL), m_zoneId(0), m_areaId(0), m_staticFloorZ(VMAP_INVALID_HEIGHT), m_currMap(NULL), m_InstanceId(0),
_dbPhase(0), m_notifyflags(0), m_executed_notifies(0)
{
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST);
@@ -920,43 +920,50 @@ void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
transport->RemovePassenger(this);
}
-void WorldObject::RemoveFromWorld()
+void WorldObject::UpdatePositionData()
{
- if (!IsInWorld())
- return;
-
- DestroyForNearbyPlayers();
-
- Object::RemoveFromWorld();
+ PositionFullTerrainStatus data;
+ GetMap()->GetFullTerrainStatusForPosition(_phaseShift, GetPositionX(), GetPositionY(), GetPositionZ(), data);
+ ProcessPositionDataChanged(data);
}
-uint32 WorldObject::GetZoneId() const
+void WorldObject::ProcessPositionDataChanged(PositionFullTerrainStatus const& data)
{
- return GetMap()->GetZoneId(GetPhaseShift(), m_positionX, m_positionY, m_positionZ);
+ m_zoneId = m_areaId = data.areaId;
+ if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(m_areaId))
+ if (area->ID)
+ m_zoneId = area->ID;
+ m_staticFloorZ = data.floorZ;
}
-uint32 WorldObject::GetAreaId() const
+void WorldObject::AddToWorld()
{
- return GetMap()->GetAreaId(GetPhaseShift(), m_positionX, m_positionY, m_positionZ);
+ Object::AddToWorld();
+ GetMap()->GetZoneAndAreaId(_phaseShift, m_zoneId, m_areaId, GetPositionX(), GetPositionY(), GetPositionZ());
}
-void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
+void WorldObject::RemoveFromWorld()
{
- GetMap()->GetZoneAndAreaId(GetPhaseShift(), zoneid, areaid, m_positionX, m_positionY, m_positionZ);
+ if (!IsInWorld())
+ return;
+
+ DestroyForNearbyPlayers();
+
+ Object::RemoveFromWorld();
}
bool WorldObject::IsInWorldPvpZone() const
{
switch (GetZoneId())
{
- case 4197: // Wintergrasp
- case 5095: // Tol Barad
- case 6941: // Ashran
- return true;
- break;
- default:
- return false;
- break;
+ case 4197: // Wintergrasp
+ case 5095: // Tol Barad
+ case 6941: // Ashran
+ return true;
+ break;
+ default:
+ return false;
+ break;
}
}
@@ -2121,7 +2128,7 @@ float NormalizeZforCollision(WorldObject* obj, float x, float y, float z)
return z;
}
LiquidData liquid_status;
- ZLiquidStatus res = obj->GetMap()->getLiquidStatus(obj->GetPhaseShift(), 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
@@ -2350,6 +2357,13 @@ ObjectGuid WorldObject::GetTransGUID() const
return ObjectGuid::Empty;
}
+float WorldObject::GetFloorZ() const
+{
+ if (!IsInWorld())
+ return m_staticFloorZ;
+ return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()));
+}
+
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>&, uint32, float) const;
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::deque<GameObject*>&, uint32, float) const;
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::vector<GameObject*>&, uint32, float) const;
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 1d48e1f2384..7339cc2df96 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -52,6 +52,7 @@ class UpdateData;
class WorldObject;
class WorldPacket;
class ZoneScript;
+struct PositionFullTerrainStatus;
struct QuaternionData;
typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
@@ -383,7 +384,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
virtual void Update (uint32 /*time_diff*/) { }
- virtual void RemoveFromWorld() override;
+ void AddToWorld() override;
+ void RemoveFromWorld() override;
void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const;
void GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const;
@@ -418,9 +420,9 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
// if negative it is used as PhaseGroupId
void SetDBPhase(int32 p) { _dbPhase = p; }
- uint32 GetZoneId() const;
- uint32 GetAreaId() const;
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const;
+ uint32 GetZoneId() const { return m_zoneId; }
+ uint32 GetAreaId() const { return m_areaId; }
+ void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const { zoneid = m_zoneId, areaid = m_areaId; }
bool IsInWorldPvpZone() const;
InstanceScript* GetInstanceScript();
@@ -527,6 +529,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
{
UpdateObjectVisibility(true);
}
+ void UpdatePositionData();
void BuildUpdate(UpdateDataMapType&) override;
void AddToObjectUpdate() override;
@@ -569,6 +572,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
virtual float GetStationaryZ() const { return GetPositionZ(); }
virtual float GetStationaryO() const { return GetOrientation(); }
+ float GetFloorZ() const;
+
virtual uint16 GetAIAnimKitId() const { return 0; }
virtual uint16 GetMovementAnimKitId() const { return 0; }
virtual uint16 GetMeleeAnimKitId() const { return 0; }
@@ -583,6 +588,11 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
// transports
Transport* m_transport;
+ virtual void ProcessPositionDataChanged(PositionFullTerrainStatus const& data);
+ uint32 m_zoneId;
+ uint32 m_areaId;
+ float m_staticFloorZ;
+
//these functions are used mostly for Relocate() and Corpse/Player specific stuff...
//use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
//mapId/instanceId should be set in SetMap() function!
@@ -595,12 +605,12 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
//difference from IsAlwaysVisibleFor: 1. after distance check; 2. use owner or charmer as seer
virtual bool IsAlwaysDetectableFor(WorldObject const* /*seer*/) const { return false; }
private:
- Map* m_currMap; //current object's Map location
+ Map* m_currMap; // current object's Map location
- //uint32 m_mapId; // object at map with map_id
- uint32 m_InstanceId; // in map copy with instance id
+ //uint32 m_mapId; // object at map with map_id
+ uint32 m_InstanceId; // in map copy with instance id
PhaseShift _phaseShift;
- PhaseShift _suppressedPhaseShift; // contains phases for current area but not applied due to conditions
+ PhaseShift _suppressedPhaseShift; // contains phases for current area but not applied due to conditions
int32 _dbPhase;
uint16 m_notifyflags;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index b76efc4023d..f771d1ee0bb 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25665,77 +25665,52 @@ int32 Player::NextGroupUpdateSequenceNumber(GroupCategory category)
return m_groupUpdateSequences[category].UpdateSequenceNumber++;
}
-void Player::UpdateUnderwaterState(Map* m, float x, float y, float z)
+void Player::ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData)
{
- LiquidData 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);
- if (_lastLiquid && _lastLiquid->SpellID)
- RemoveAurasDueToSpell(_lastLiquid->SpellID);
-
- _lastLiquid = nullptr;
+ if (IsFlying())
return;
- }
- if (uint32 liqEntry = liquid_status.entry)
- {
- LiquidTypeEntry const* liquid = sLiquidTypeStore.LookupEntry(liqEntry);
- if (_lastLiquid && _lastLiquid->SpellID && _lastLiquid != liquid)
- RemoveAurasDueToSpell(_lastLiquid->SpellID);
+ // process liquid auras using generic unit code
+ Unit::ProcessTerrainStatusUpdate(status, liquidData);
- if (liquid && liquid->SpellID)
+ // player specific logic for mirror timers
+ if (status && liquidData)
+ {
+ // Breath bar state (under water in any liquid type)
+ if (liquidData->type_flags & MAP_ALL_LIQUIDS)
{
- if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER))
- {
- if (!HasAura(liquid->SpellID))
- CastSpell(this, liquid->SpellID, true);
- }
+ if (status & LIQUID_MAP_UNDER_WATER)
+ m_MirrorTimerFlags |= UNDERWATER_INWATER;
else
- RemoveAurasDueToSpell(liquid->SpellID);
+ m_MirrorTimerFlags &= ~UNDERWATER_INWATER;
}
- _lastLiquid = liquid;
- }
- else if (_lastLiquid && _lastLiquid->SpellID)
- {
- RemoveAurasDueToSpell(_lastLiquid->SpellID);
- _lastLiquid = nullptr;
- }
-
-
- // All liquids type - check under water position
- if (liquid_status.type_flags & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN | MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME))
- {
- if (res & LIQUID_MAP_UNDER_WATER)
- m_MirrorTimerFlags |= UNDERWATER_INWATER;
+ // Fatigue bar state (if not on flight path or transport)
+ if ((liquidData->type_flags & MAP_LIQUID_TYPE_DARK_WATER) && !IsInFlight() && !GetTransport())
+ m_MirrorTimerFlags |= UNDERWARER_INDARKWATER;
else
- m_MirrorTimerFlags &= ~UNDERWATER_INWATER;
- }
+ m_MirrorTimerFlags &= ~UNDERWARER_INDARKWATER;
- // Allow travel in dark water on taxi or transport
- if ((liquid_status.type_flags & MAP_LIQUID_TYPE_DARK_WATER) && !IsInFlight() && !GetTransport())
- m_MirrorTimerFlags |= UNDERWARER_INDARKWATER;
- else
- m_MirrorTimerFlags &= ~UNDERWARER_INDARKWATER;
+ // Lava state (any contact)
+ if (liquidData->type_flags & MAP_LIQUID_TYPE_MAGMA)
+ {
+ if (status & MAP_LIQUID_STATUS_IN_CONTACT)
+ m_MirrorTimerFlags |= UNDERWATER_INLAVA;
+ else
+ m_MirrorTimerFlags &= ~UNDERWATER_INLAVA;
+ }
- // in lava check, anywhere in lava level
- if (liquid_status.type_flags & MAP_LIQUID_TYPE_MAGMA)
- {
- if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER | LIQUID_MAP_WATER_WALK))
- m_MirrorTimerFlags |= UNDERWATER_INLAVA;
- else
- m_MirrorTimerFlags &= ~UNDERWATER_INLAVA;
- }
- // in slime check, anywhere in slime level
- if (liquid_status.type_flags & MAP_LIQUID_TYPE_SLIME)
- {
- if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER | LIQUID_MAP_WATER_WALK))
- m_MirrorTimerFlags |= UNDERWATER_INSLIME;
- else
- m_MirrorTimerFlags &= ~UNDERWATER_INSLIME;
+ // Slime state (any contact)
+ if (liquidData->type_flags & MAP_LIQUID_TYPE_SLIME)
+ {
+ if (status & MAP_LIQUID_STATUS_IN_CONTACT)
+ m_MirrorTimerFlags |= UNDERWATER_INSLIME;
+ else
+ m_MirrorTimerFlags &= ~UNDERWATER_INSLIME;
+ }
}
+ else
+ m_MirrorTimerFlags &= ~(UNDERWATER_INWATER | UNDERWATER_INLAVA | UNDERWATER_INSLIME | UNDERWARER_INDARKWATER);
}
void Player::SetCanParry(bool value)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index fe557421cfc..71093b2497b 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1861,7 +1861,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override;
bool UpdatePosition(const Position &pos, bool teleport = false) override { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }
- void UpdateUnderwaterState(Map* m, float x, float y, float z) override;
+ void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData) override;
void SendMessageToSet(WorldPacket const* data, bool self) const override { SendMessageToSetInRange(data, GetVisibilityRange(), self); }
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const override;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 088e9345a44..1075e81bfdc 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -507,7 +507,6 @@ void Unit::Update(uint32 p_time)
UpdateSplineMovement(p_time);
i_motionMaster->UpdateMotion(p_time);
- UpdateUnderwaterState(GetMap(), GetPositionX(), GetPositionY(), GetPositionZ());
}
bool Unit::haveOffhandWeapon() const
@@ -3161,48 +3160,34 @@ bool Unit::IsUnderWater() const
return GetMap()->IsUnderWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
}
-void Unit::UpdateUnderwaterState(Map* m, float x, float y, float z)
+void Unit::ProcessPositionDataChanged(PositionFullTerrainStatus const& data)
{
- if (IsFlying() || (!IsPet() && !IsVehicle()))
- return;
+ WorldObject::ProcessPositionDataChanged(data);
+ ProcessTerrainStatusUpdate(data.liquidStatus, data.liquidInfo);
+}
- LiquidData liquid_status;
- ZLiquidStatus res = m->getLiquidStatus(GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
- if (!res)
- {
- if (_lastLiquid && _lastLiquid->SpellID)
- RemoveAurasDueToSpell(_lastLiquid->SpellID);
+void Unit::ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData)
+{
+ if (IsFlying() || (!IsControlledByPlayer()))
+ return;
+ // remove appropriate auras if we are swimming/not swimming respectively
+ if (status & MAP_LIQUID_STATUS_SWIMMING)
+ RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_ABOVEWATER);
+ else
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_UNDERWATER);
- _lastLiquid = NULL;
- return;
- }
- if (uint32 liqEntry = liquid_status.entry)
+ // liquid aura handling
+ LiquidTypeEntry const* curLiquid = nullptr;
+ if ((status & MAP_LIQUID_STATUS_SWIMMING) && liquidData)
+ curLiquid = sLiquidTypeStore.LookupEntry(liquidData->entry);
+ if (curLiquid != _lastLiquid)
{
- LiquidTypeEntry const* liquid = sLiquidTypeStore.LookupEntry(liqEntry);
- if (_lastLiquid && _lastLiquid->SpellID && _lastLiquid->ID != liqEntry)
+ if (_lastLiquid && _lastLiquid->SpellID)
RemoveAurasDueToSpell(_lastLiquid->SpellID);
-
- if (liquid && liquid->SpellID)
- {
- if (res & (LIQUID_MAP_UNDER_WATER | LIQUID_MAP_IN_WATER))
- {
- if (!HasAura(liquid->SpellID))
- CastSpell(this, liquid->SpellID, true);
- }
- else
- RemoveAurasDueToSpell(liquid->SpellID);
- }
-
- RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_ABOVEWATER);
- _lastLiquid = liquid;
- }
- else if (_lastLiquid && _lastLiquid->SpellID)
- {
- RemoveAurasDueToSpell(_lastLiquid->SpellID);
- RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_UNDERWATER);
- _lastLiquid = NULL;
+ if (curLiquid && curLiquid->SpellID)
+ CastSpell(this, curLiquid->SpellID, true);
+ _lastLiquid = curLiquid;
}
}
@@ -7887,7 +7872,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
mountFlags = areaTable->MountFlags;
LiquidData liquid;
- ZLiquidStatus liquidStatus = GetMap()->getLiquidStatus(GetPhaseShift(), 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;
@@ -13364,8 +13349,7 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel
else if (turn)
UpdateOrientation(orientation);
- // code block for underwater state update
- UpdateUnderwaterState(GetMap(), x, y, z);
+ UpdatePositionData();
return (relocated || turn);
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 085516b43c4..efa33a90cee 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -185,6 +185,7 @@ enum InventorySlot
};
struct FactionTemplateEntry;
+struct LiquidData;
struct LiquidTypeEntry;
struct MountCapabilityEntry;
struct SpellValue;
@@ -214,6 +215,7 @@ class Vehicle;
class VehicleJoinEvent;
enum class PetActionFeedback : uint8;
+enum ZLiquidStatus : uint32;
namespace Movement
{
@@ -1297,7 +1299,6 @@ class TC_GAME_API Unit : public WorldObject
virtual bool IsInWater() const;
virtual bool IsUnderWater() const;
- virtual void UpdateUnderwaterState(Map* m, float x, float y, float z);
bool isInAccessiblePlaceFor(Creature const* c) const;
void SendHealSpellLog(HealInfo& healInfo, bool critical = false);
@@ -2113,6 +2114,9 @@ class TC_GAME_API Unit : public WorldObject
void DisableSpline();
+ void ProcessPositionDataChanged(PositionFullTerrainStatus const& data) override;
+ virtual void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData);
+
private:
void UpdateSplineMovement(uint32 t_diff);
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 7546b298ff6..3bc765b229d 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -1131,6 +1131,7 @@ void Map::PlayerRelocation(Player* player, float x, float y, float z, float orie
AddToGrid(player, new_cell);
}
+ player->UpdatePositionData();
player->UpdateObjectVisibility(false);
}
@@ -1165,6 +1166,7 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa
if (creature->IsVehicle())
creature->GetVehicleKit()->RelocatePassengers();
creature->UpdateObjectVisibility(false);
+ creature->UpdatePositionData();
RemoveCreatureFromMoveList(creature);
}
@@ -1195,6 +1197,7 @@ void Map::GameObjectRelocation(GameObject* go, float x, float y, float z, float
{
go->Relocate(x, y, z, orientation);
go->UpdateModelPosition();
+ go->UpdatePositionData();
go->UpdateObjectVisibility(false);
RemoveGameObjectFromMoveList(go);
}
@@ -1227,6 +1230,7 @@ void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float
else
{
dynObj->Relocate(x, y, z, orientation);
+ dynObj->UpdatePositionData();
dynObj->UpdateObjectVisibility(false);
RemoveDynamicObjectFromMoveList(dynObj);
}
@@ -1372,6 +1376,7 @@ void Map::MoveAllCreaturesInMoveList()
if (c->IsVehicle())
c->GetVehicleKit()->RelocatePassengers();
//CreatureRelocationNotify(c, new_cell, new_cell.cellCoord());
+ c->UpdatePositionData();
c->UpdateObjectVisibility(false);
}
else
@@ -1426,6 +1431,7 @@ void Map::MoveAllGameObjectsInMoveList()
// update pos
go->Relocate(go->_newPosition);
go->UpdateModelPosition();
+ go->UpdatePositionData();
go->UpdateObjectVisibility(false);
}
else
@@ -1470,6 +1476,7 @@ void Map::MoveAllDynamicObjectsInMoveList()
{
// update pos
dynObj->Relocate(dynObj->_newPosition);
+ dynObj->UpdatePositionData();
dynObj->UpdateObjectVisibility(false);
}
else
@@ -1790,6 +1797,7 @@ bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly)
c->Relocate(resp_x, resp_y, resp_z, resp_o);
c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators
//CreatureRelocationNotify(c, resp_cell, resp_cell.GetCellCoord());
+ c->UpdatePositionData();
c->UpdateObjectVisibility(false);
return true;
}
@@ -1815,6 +1823,7 @@ bool Map::GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly)
if (GameObjectCellRelocation(go, resp_cell))
{
go->Relocate(resp_x, resp_y, resp_z, resp_o);
+ go->UpdatePositionData();
go->UpdateObjectVisibility(false);
return true;
}
@@ -2491,7 +2500,7 @@ uint8 GridMap::getTerrainType(float x, float y) const
}
// Get water state on map
-inline ZLiquidStatus GridMap::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
+inline ZLiquidStatus GridMap::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
{
// Check water type (if no water return)
if (!_liquidGlobalFlags && !_liquidFlags)
@@ -2616,7 +2625,7 @@ float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y,
LiquidData liquid_status;
- ZLiquidStatus res = getLiquidStatus(phaseShift, 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;
}
@@ -2805,11 +2814,6 @@ uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, b
return areaId;
}
-uint32 Map::GetAreaId(PhaseShift const& phaseShift, float x, float y, float z)
-{
- return GetAreaId(phaseShift, x, y, z, nullptr);
-}
-
uint32 Map::GetZoneId(PhaseShift const& phaseShift, float x, float y, float z)
{
uint32 areaId = GetAreaId(phaseShift, x, y, z);
@@ -2836,7 +2840,7 @@ uint8 Map::GetTerrainType(PhaseShift const& phaseShift, float x, float y)
return 0;
}
-ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
+ZLiquidStatus Map::GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data)
{
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
@@ -2846,7 +2850,7 @@ ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float
uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y);
if (vmgr->GetLiquidLevel(terrainMapId, 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);
+ 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
if (liquid_level > ground_level && z > ground_level - 2)
{
@@ -2904,7 +2908,7 @@ ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float
if (GridMap* gmap = GetGrid(terrainMapId, x, y))
{
LiquidData map_data;
- ZLiquidStatus map_result = gmap->getLiquidStatus(x, y, z, ReqLiquidType, &map_data);
+ ZLiquidStatus map_result = gmap->GetLiquidStatus(x, y, z, ReqLiquidType, &map_data);
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level))
{
@@ -2922,6 +2926,104 @@ ZLiquidStatus Map::getLiquidStatus(PhaseShift const& phaseShift, float x, float
return result;
}
+void Map::GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType)
+{
+ VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
+ VMAP::AreaAndLiquidData vmapData;
+ uint32 terrainMapId = PhasingHandler::GetTerrainMapId(phaseShift, this, x, y);
+ vmgr->getAreaAndLiquidData(terrainMapId, x, y, z, reqLiquidType, vmapData);
+ if (vmapData.areaInfo)
+ data.areaInfo = boost::in_place(vmapData.areaInfo->adtId, vmapData.areaInfo->rootId, vmapData.areaInfo->groupId, vmapData.areaInfo->mogpFlags);
+
+ GridMap* gmap = GetGrid(terrainMapId, x, y);
+ float mapHeight = gmap->getHeight(x, y);
+
+ // area lookup
+ AreaTableEntry const* areaEntry = nullptr;
+ if (vmapData.areaInfo && (z + 2.0f <= mapHeight || mapHeight <= vmapData.floorZ))
+ if (WMOAreaTableEntry const* wmoEntry = sDB2Manager.GetWMOAreaTable(vmapData.areaInfo->rootId, vmapData.areaInfo->adtId, vmapData.areaInfo->groupId))
+ areaEntry = sAreaTableStore.LookupEntry(wmoEntry->AreaTableID);
+
+ if (areaEntry)
+ {
+ data.floorZ = vmapData.floorZ;
+ data.areaId = areaEntry->ID;
+ }
+ else
+ {
+ data.floorZ = mapHeight;
+ if (gmap)
+ data.areaId = gmap->getArea(x, y);
+ else
+ data.areaId = 0;
+
+ if (!data.areaId)
+ data.areaId = i_mapEntry->AreaTableID;
+
+ if (data.areaId)
+ areaEntry = sAreaTableStore.LookupEntry(data.areaId);
+ }
+
+ // liquid processing
+ data.liquidStatus = LIQUID_MAP_NO_WATER;
+ if (vmapData.liquidInfo && vmapData.liquidInfo->level > vmapData.floorZ && z + 2.0f > vmapData.floorZ)
+ {
+ uint32 liquidType = vmapData.liquidInfo->type;
+ if (GetId() == 530 && liquidType == 2) // gotta love blizzard hacks
+ liquidType = 15;
+
+ uint32 liquidFlagType = 0;
+ if (LiquidTypeEntry const* liquidData = sLiquidTypeStore.LookupEntry(liquidType))
+ liquidFlagType = liquidData->SoundBank;
+
+ if (liquidType && liquidType < 21 && areaEntry)
+ {
+ uint32 overrideLiquid = areaEntry->LiquidTypeID[liquidFlagType];
+ if (!overrideLiquid && areaEntry->ParentAreaID)
+ {
+ AreaTableEntry const* zoneEntry = sAreaTableStore.LookupEntry(areaEntry->ParentAreaID);
+ if (zoneEntry)
+ overrideLiquid = zoneEntry->LiquidTypeID[liquidFlagType];
+ }
+
+ if (LiquidTypeEntry const* overrideData = sLiquidTypeStore.LookupEntry(overrideLiquid))
+ {
+ liquidType = overrideLiquid;
+ liquidFlagType = overrideData->SoundBank;
+ }
+ }
+
+ data.liquidInfo = boost::in_place();
+ data.liquidInfo->level = vmapData.liquidInfo->level;
+ data.liquidInfo->depth_level = vmapData.floorZ;
+ data.liquidInfo->entry = liquidType;
+ data.liquidInfo->type_flags = 1 << liquidFlagType;
+
+ float delta = vmapData.liquidInfo->level - z;
+ if (delta > 2.0f)
+ data.liquidStatus = LIQUID_MAP_UNDER_WATER;
+ else if (delta > 0.0f)
+ data.liquidStatus = LIQUID_MAP_IN_WATER;
+ else if (delta > -0.1f)
+ data.liquidStatus = LIQUID_MAP_WATER_WALK;
+ else
+ data.liquidStatus = LIQUID_MAP_ABOVE_WATER;
+ }
+ // look up liquid data from grid map
+ if (gmap && (data.liquidStatus == LIQUID_MAP_ABOVE_WATER || data.liquidStatus == LIQUID_MAP_NO_WATER))
+ {
+ LiquidData gridMapLiquid;
+ ZLiquidStatus gridMapStatus = gmap->GetLiquidStatus(x, y, z, reqLiquidType, &gridMapLiquid);
+ if (gridMapStatus != LIQUID_MAP_NO_WATER && (gridMapLiquid.level > vmapData.floorZ))
+ {
+ if (GetId() == 530 && gridMapLiquid.entry == 2)
+ gridMapLiquid.entry = 15;
+ data.liquidInfo = gridMapLiquid;
+ data.liquidStatus = gridMapStatus;
+ }
+ }
+}
+
float Map::GetWaterLevel(PhaseShift const& phaseShift, float x, float y)
{
if (GridMap* gmap = GetGrid(PhasingHandler::GetTerrainMapId(phaseShift, this, x, y), x, y))
@@ -2959,12 +3061,12 @@ bool Map::IsInWater(PhaseShift const& phaseShift, float x, float y, float pZ, Li
{
LiquidData liquid_status;
LiquidData* liquid_ptr = data ? data : &liquid_status;
- return (getLiquidStatus(phaseShift, 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(PhaseShift const& phaseShift, float x, float y, float z)
{
- return (getLiquidStatus(phaseShift, 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 7fd66491168..faf1fc4ca1b 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -28,6 +28,7 @@
#include "MapRefManager.h"
#include "DynamicTree.h"
#include "ObjectGuid.h"
+#include "Optional.h"
#include <bitset>
#include <list>
@@ -140,7 +141,7 @@ struct map_liquidHeader
float liquidLevel;
};
-enum ZLiquidStatus
+enum ZLiquidStatus : uint32
{
LIQUID_MAP_NO_WATER = 0x00000000,
LIQUID_MAP_ABOVE_WATER = 0x00000001,
@@ -149,6 +150,9 @@ enum ZLiquidStatus
LIQUID_MAP_UNDER_WATER = 0x00000008
};
+#define MAP_LIQUID_STATUS_SWIMMING (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER)
+#define MAP_LIQUID_STATUS_IN_CONTACT (MAP_LIQUID_STATUS_SWIMMING | LIQUID_MAP_WATER_WALK)
+
#define MAP_LIQUID_TYPE_NO_WATER 0x00
#define MAP_LIQUID_TYPE_WATER 0x01
#define MAP_LIQUID_TYPE_OCEAN 0x02
@@ -167,6 +171,24 @@ struct LiquidData
float depth_level;
};
+struct PositionFullTerrainStatus
+{
+ struct AreaInfo
+ {
+ AreaInfo(int32 _adtId, int32 _rootId, int32 _groupId, uint32 _flags) : adtId(_adtId), rootId(_rootId), groupId(_groupId), mogpFlags(_flags) { }
+ int32 const adtId;
+ int32 const rootId;
+ int32 const groupId;
+ uint32 const mogpFlags;
+ };
+
+ uint32 areaId;
+ float floorZ;
+ ZLiquidStatus liquidStatus;
+ Optional<AreaInfo> areaInfo;
+ Optional<LiquidData> liquidInfo;
+};
+
class TC_GAME_API GridMap
{
uint32 _flags;
@@ -232,7 +254,7 @@ public:
float getMinHeight(float x, float y) const;
float getLiquidLevel(float x, float y) const;
uint8 getTerrainType(float x, float y) const;
- ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
+ ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
};
#pragma pack(push, 1)
@@ -350,11 +372,11 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
float GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float z, bool checkVMap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH);
float GetMinHeight(PhaseShift const& phaseShift, float x, float y);
- ZLiquidStatus getLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr);
+ void GetFullTerrainStatusForPosition(PhaseShift const& phaseShift, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS);
+ ZLiquidStatus GetLiquidStatus(PhaseShift const& phaseShift, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr);
- uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors);
bool GetAreaInfo(PhaseShift const& phaseShift, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId);
- uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z);
+ uint32 GetAreaId(PhaseShift const& phaseShift, float x, float y, float z, bool *isOutdoors = nullptr);
uint32 GetZoneId(PhaseShift const& phaseShift, float x, float y, float z);
void GetZoneAndAreaId(PhaseShift const& phaseShift, uint32& zoneid, uint32& areaid, float x, float y, float z);
@@ -509,6 +531,10 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); }
void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); }
bool ContainsGameObjectModel(const GameObjectModel& model) const { return _dynamicTree.contains(model);}
+ float GetGameObjectFloor(PhaseShift const& phaseShift, float x, float y, float z, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const
+ {
+ return _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift);
+ }
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);
virtual ObjectGuid::LowType GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return UI64LIT(0); }
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 375b8b30e0c..6d8f9d8f6e0 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->GetMap()->getLiquidStatus(_sourceUnit->GetPhaseShift(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL);
+ ZLiquidStatus status = _sourceUnit->GetMap()->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)
{
@@ -648,7 +648,7 @@ void PathGenerator::UpdateFilter()
NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z)
{
LiquidData data;
- ZLiquidStatus liquidStatus = _sourceUnit->GetMap()->getLiquidStatus(_sourceUnit->GetPhaseShift(), x, y, z, MAP_ALL_LIQUIDS, &data);
+ ZLiquidStatus liquidStatus = _sourceUnit->GetMap()->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/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 94d1b67a895..938aa7da363 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1349,7 +1349,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(m_caster->GetPhaseShift(), 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
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index f2b012c4b17..77f52b219cb 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -298,7 +298,7 @@ public:
zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap, haveMMap);
LiquidData liquidStatus;
- ZLiquidStatus status = map->getLiquidStatus(object->GetPhaseShift(), 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);