aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Collision/DynamicTree.cpp86
-rw-r--r--src/common/Collision/DynamicTree.h7
-rw-r--r--src/common/Collision/Models/GameObjectModel.cpp64
-rw-r--r--src/common/Collision/Models/GameObjectModel.h12
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp26
-rw-r--r--src/server/game/Entities/Object/Object.cpp10
-rw-r--r--src/server/game/Entities/Object/Object.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp6
-rw-r--r--src/server/game/Groups/Group.cpp2
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp2
-rw-r--r--src/server/game/Maps/Map.cpp116
-rw-r--r--src/server/game/Maps/Map.h21
-rw-r--r--src/server/game/Maps/MapManager.h24
-rw-r--r--src/server/game/Movement/PathGenerator.cpp6
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp2
-rw-r--r--src/server/scripts/Commands/cs_list.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
-rw-r--r--src/server/scripts/Commands/cs_tele.cpp2
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp2
-rw-r--r--src/server/shared/DataStores/DBCStructure.h36
23 files changed, 321 insertions, 118 deletions
diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp
index 40acfb6c49b..bae8ab38dc1 100644
--- a/src/common/Collision/DynamicTree.cpp
+++ b/src/common/Collision/DynamicTree.cpp
@@ -16,17 +16,16 @@
*/
#include "DynamicTree.h"
-//#include "QuadTree.h"
-//#include "RegularGrid.h"
#include "BoundingIntervalHierarchyWrapper.h"
-
+#include "GameObjectModel.h"
#include "Log.h"
+#include "MapTree.h"
+#include "ModelIgnoreFlags.h"
+#include "ModelInstance.h"
#include "RegularGrid.h"
#include "Timer.h"
-#include "GameObjectModel.h"
-#include "ModelInstance.h"
-#include "ModelIgnoreFlags.h"
-
+#include "VMapFactory.h"
+#include "VMapManager2.h"
#include <G3D/AABox.h>
#include <G3D/Ray.h>
#include <G3D/Vector3.h>
@@ -174,6 +173,41 @@ struct DynamicTreeIntersectionCallback_WithLogger
bool didHit() const { return did_hit;}
};
+struct DynamicTreeAreaInfoCallback
+{
+ DynamicTreeAreaInfoCallback(uint32 phaseMask) : _phaseMask(phaseMask) {}
+
+ void operator()(G3D::Vector3 const& p, GameObjectModel const& obj)
+ {
+ obj.intersectPoint(p, _areaInfo, _phaseMask);
+ }
+
+ VMAP::AreaInfo const& GetAreaInfo() const { return _areaInfo; }
+
+private:
+ uint32 _phaseMask;
+ VMAP::AreaInfo _areaInfo;
+};
+
+struct DynamicTreeLocationInfoCallback
+{
+ DynamicTreeLocationInfoCallback(uint32 phaseMask) : _phaseMask(phaseMask), _hitModel(nullptr) {}
+
+ void operator()(G3D::Vector3 const& p, GameObjectModel const& obj)
+ {
+ if (obj.GetLocationInfo(p, _locationInfo, _phaseMask))
+ _hitModel = &obj;
+ }
+
+ VMAP::LocationInfo& GetLocationInfo() { return _locationInfo; }
+ GameObjectModel const* GetHitModel() const { return _hitModel; }
+
+private:
+ uint32 _phaseMask;
+ VMAP::LocationInfo _locationInfo;
+ GameObjectModel const* _hitModel;
+};
+
bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray,
const G3D::Vector3& endPos, float& maxDist) const
{
@@ -253,3 +287,41 @@ float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist,
else
return -G3D::finf();
}
+
+bool DynamicMapTree::getAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
+{
+ G3D::Vector3 v(x, y, z + 0.5f);
+ DynamicTreeAreaInfoCallback intersectionCallBack(phasemask);
+ impl->intersectPoint(v, intersectionCallBack);
+ if (intersectionCallBack.GetAreaInfo().result)
+ {
+ flags = intersectionCallBack.GetAreaInfo().flags;
+ adtId = intersectionCallBack.GetAreaInfo().adtId;
+ rootId = intersectionCallBack.GetAreaInfo().rootId;
+ groupId = intersectionCallBack.GetAreaInfo().groupId;
+ z = intersectionCallBack.GetAreaInfo().ground_Z;
+ return true;
+ }
+ return false;
+}
+
+void DynamicMapTree::getAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const
+{
+ G3D::Vector3 v(x, y, z + 0.5f);
+ DynamicTreeLocationInfoCallback intersectionCallBack(phasemask);
+ impl->intersectPoint(v, intersectionCallBack);
+ if (intersectionCallBack.GetLocationInfo().hitModel)
+ {
+ data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z;
+ uint32 liquidType = intersectionCallBack.GetLocationInfo().hitModel->GetLiquidType();
+ float liquidLevel;
+ if (!reqLiquidType || (dynamic_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())->GetLiquidFlagsPtr(liquidType) & reqLiquidType))
+ if (intersectionCallBack.GetHitModel()->GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), liquidLevel))
+ data.liquidInfo = boost::in_place(liquidType, liquidLevel);
+
+ data.areaInfo = boost::in_place(0,
+ intersectionCallBack.GetLocationInfo().rootId,
+ intersectionCallBack.GetLocationInfo().hitModel->GetWmoID(),
+ intersectionCallBack.GetLocationInfo().hitModel->GetMogpFlags());
+ }
+}
diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h
index 8f2729cb76a..a890f828b96 100644
--- a/src/common/Collision/DynamicTree.h
+++ b/src/common/Collision/DynamicTree.h
@@ -30,6 +30,11 @@ namespace G3D
class GameObjectModel;
struct DynTreeImpl;
+namespace VMAP
+{
+ struct AreaAndLiquidData;
+}
+
class TC_COMMON_API DynamicMapTree
{
DynTreeImpl *impl;
@@ -44,6 +49,8 @@ public:
bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray,
const G3D::Vector3& endPos, float& maxDist) const;
+ bool getAreaInfo(float x, float y, float& z, uint32 phasemask, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
+ void getAreaAndLiquidData(float x, float y, float z, uint32 phasemask, uint8 reqLiquidType, VMAP::AreaAndLiquidData& data) const;
bool getObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1,
const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos,
diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp
index 54b48714c90..2c95187fbb2 100644
--- a/src/common/Collision/Models/GameObjectModel.cpp
+++ b/src/common/Collision/Models/GameObjectModel.cpp
@@ -146,6 +146,7 @@ bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> model
#endif
owner = std::move(modelOwner);
+ isWmo = it->second.isWmo;
return true;
}
@@ -183,6 +184,69 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
return hit;
}
+void GameObjectModel::intersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const
+{
+ if (!(phasemask & ph_mask) || !owner->IsSpawned() || !isMapObject())
+ return;
+
+ if (!iBound.contains(point))
+ return;
+
+ // child bounds are defined in object space:
+ Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
+ Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
+ float zDist;
+ if (iModel->IntersectPoint(pModel, zDirModel, zDist, info))
+ {
+ Vector3 modelGround = pModel + zDist * zDirModel;
+ float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
+ if (info.ground_Z < world_Z)
+ info.ground_Z = world_Z;
+ }
+}
+
+bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const
+{
+ if (!(phasemask & ph_mask) || !owner->IsSpawned() || !isMapObject())
+ return false;
+
+ if (!iBound.contains(point))
+ return false;
+
+ // child bounds are defined in object space:
+ Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
+ Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
+ float zDist;
+ if (iModel->GetLocationInfo(pModel, zDirModel, zDist, info))
+ {
+ Vector3 modelGround = pModel + zDist * zDirModel;
+ float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
+ if (info.ground_Z < world_Z)
+ {
+ info.ground_Z = world_Z;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool GameObjectModel::GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const
+{
+ // child bounds are defined in object space:
+ Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
+ //Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
+ float zDist;
+ if (info.hitModel->GetLiquidLevel(pModel, zDist))
+ {
+ // calculate world height (zDist in model coords):
+ // assume WMO not tilted (wouldn't make much sense anyway)
+ liqHeight = zDist * iScale + iPos.z;
+ return true;
+ }
+ return false;
+}
+
bool GameObjectModel::UpdatePosition()
{
if (!iModel)
diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h
index 99ffef0ee98..78f17b75391 100644
--- a/src/common/Collision/Models/GameObjectModel.h
+++ b/src/common/Collision/Models/GameObjectModel.h
@@ -29,6 +29,8 @@
namespace VMAP
{
class WorldModel;
+ struct AreaInfo;
+ struct LocationInfo;
enum class ModelIgnoreFlags : uint32;
}
@@ -38,6 +40,8 @@ struct GameObjectDisplayInfoEntry;
class TC_COMMON_API GameObjectModelOwnerBase
{
public:
+ virtual ~GameObjectModelOwnerBase() = default;
+
virtual bool IsSpawned() const = 0;
virtual uint32 GetDisplayId() const = 0;
virtual uint32 GetPhaseMask() const = 0;
@@ -45,12 +49,11 @@ public:
virtual float GetOrientation() const = 0;
virtual float GetScale() const = 0;
virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const = 0;
- virtual ~GameObjectModelOwnerBase() { }
};
class TC_COMMON_API GameObjectModel /*, public Intersectable*/
{
- GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(nullptr) { }
+ GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(nullptr), isWmo(false) { }
public:
std::string name;
@@ -65,8 +68,12 @@ public:
void enable(uint32 ph_mask) { phasemask = ph_mask;}
bool isEnabled() const {return phasemask != 0;}
+ bool isMapObject() const { return isWmo; }
bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask, VMAP::ModelIgnoreFlags ignoreFlags) const;
+ void intersectPoint(G3D::Vector3 const& point, VMAP::AreaInfo& info, uint32 ph_mask) const;
+ bool GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const;
+ bool GetLiquidLevel(G3D::Vector3 const& point, VMAP::LocationInfo& info, float& liqHeight) const;
static GameObjectModel* Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
@@ -83,6 +90,7 @@ private:
float iScale;
VMAP::WorldModel* iModel;
std::unique_ptr<GameObjectModelOwnerBase> owner;
+ bool isWmo;
};
TC_COMMON_API void LoadGameObjectModelList(std::string const& dataPath);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 9a6c9db819f..8228ef5a3ba 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1048,7 +1048,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, u
{
// area/zone id is needed immediately for ZoneScript::GetCreatureEntry hook before it is known which creature template to load (no model/scale available yet)
PositionFullTerrainStatus data;
- GetMap()->GetFullTerrainStatusForPosition(GetPositionX(), GetPositionY(), GetPositionZ(), data, MAP_ALL_LIQUIDS, DEFAULT_COLLISION_HEIGHT);
+ GetMap()->GetFullTerrainStatusForPosition(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ(), data, MAP_ALL_LIQUIDS, DEFAULT_COLLISION_HEIGHT);
ProcessPositionDataChanged(data);
}
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index f15780362d1..0cb8ab61365 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2280,8 +2280,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, WorldOb
uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
- if (modelData->DamagedDisplayId)
- modelId = modelData->DamagedDisplayId;
+ if (modelData->State1Wmo)
+ modelId = modelData->State1Wmo;
SetDisplayId(modelId);
if (setHealth)
@@ -2309,8 +2309,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, WorldOb
uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
- if (modelData->DestroyedDisplayId)
- modelId = modelData->DestroyedDisplayId;
+ if (modelData->State2Wmo)
+ modelId = modelData->State2Wmo;
SetDisplayId(modelId);
if (setHealth)
@@ -2328,8 +2328,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, WorldOb
uint32 modelId = m_goInfo->displayId;
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
- if (modelData->RebuildingDisplayId)
- modelId = modelData->RebuildingDisplayId;
+ if (modelData->State3Wmo)
+ modelId = modelData->State3Wmo;
SetDisplayId(modelId);
// restores to full health
@@ -2662,13 +2662,13 @@ class GameObjectModelOwnerImpl : public GameObjectModelOwnerBase
public:
explicit GameObjectModelOwnerImpl(GameObject const* owner) : _owner(owner) { }
- virtual bool IsSpawned() const override { return _owner->isSpawned(); }
- virtual uint32 GetDisplayId() const override { return _owner->GetDisplayId(); }
- virtual uint32 GetPhaseMask() const override { return _owner->GetPhaseMask(); }
- virtual G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); }
- virtual float GetOrientation() const override { return _owner->GetOrientation(); }
- virtual float GetScale() const override { return _owner->GetObjectScale(); }
- virtual void DebugVisualizeCorner(G3D::Vector3 const& corner) const override { const_cast<GameObject*>(_owner)->SummonCreature(1, corner.x, corner.y, corner.z, 0, TEMPSUMMON_MANUAL_DESPAWN); }
+ bool IsSpawned() const override { return _owner->isSpawned(); }
+ uint32 GetDisplayId() const override { return _owner->GetDisplayId(); }
+ uint32 GetPhaseMask() const override { return _owner->GetPhaseMask(); }
+ G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); }
+ float GetOrientation() const override { return _owner->GetOrientation(); }
+ float GetScale() const override { return _owner->GetObjectScale(); }
+ void DebugVisualizeCorner(G3D::Vector3 const& corner) const override { const_cast<GameObject*>(_owner)->SummonCreature(1, corner.x, corner.y, corner.z, 0, TEMPSUMMON_MANUAL_DESPAWN); }
private:
GameObject const* _owner;
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 44fdec8c563..a149c484276 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1058,7 +1058,7 @@ void WorldObject::_Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32
void WorldObject::UpdatePositionData()
{
PositionFullTerrainStatus data;
- GetMap()->GetFullTerrainStatusForPosition(GetPositionX(), GetPositionY(), GetPositionZ(), data, MAP_ALL_LIQUIDS, GetCollisionHeight());
+ GetMap()->GetFullTerrainStatusForPosition(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ(), data, MAP_ALL_LIQUIDS, GetCollisionHeight());
ProcessPositionDataChanged(data);
}
@@ -1076,7 +1076,7 @@ void WorldObject::ProcessPositionDataChanged(PositionFullTerrainStatus const& da
void WorldObject::AddToWorld()
{
Object::AddToWorld();
- GetBaseMap()->GetZoneAndAreaId(m_zoneId, m_areaId, GetPositionX(), GetPositionY(), GetPositionZ());
+ GetMap()->GetZoneAndAreaId(GetPhaseMask(), m_zoneId, m_areaId, GetPositionX(), GetPositionY(), GetPositionZ());
}
void WorldObject::RemoveFromWorld()
@@ -1827,12 +1827,6 @@ void WorldObject::ResetMap()
//m_InstanceId = 0;
}
-Map const* WorldObject::GetBaseMap() const
-{
- ASSERT(m_currMap);
- return m_currMap->GetParent();
-}
-
void WorldObject::AddObjectToRemoveList()
{
ASSERT(m_uint32Values);
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 7b735e5b2c7..c648b1d2914 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -394,9 +394,6 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
Map* FindMap() const { return m_currMap; }
//used to check all object's GetMap() calls when object is not in world!
- //this function should be removed in nearest time...
- Map const* GetBaseMap() const;
-
void SetZoneScript();
void ClearZoneScript();
ZoneScript* GetZoneScript() const { return m_zoneScript; }
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index b7064c67b9c..1ef6a79e4f8 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1280,7 +1280,7 @@ void Player::Update(uint32 p_time)
}
// not auto-free ghost from body in instances or if its affected by risen ally
- if (m_deathTimer > 0 && !GetBaseMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION) && !IsGhouled())
+ if (m_deathTimer > 0 && !GetMap()->Instanceable() && !HasAuraType(SPELL_AURA_PREVENT_RESURRECTION) && !IsGhouled())
{
if (p_time >= m_deathTimer)
{
@@ -6980,7 +6980,7 @@ uint32 Player::GetZoneIdFromDB(ObjectGuid guid)
if (!sMapStore.LookupEntry(map))
return 0;
- zone = sMapMgr->GetZoneId(map, posx, posy, posz);
+ zone = sMapMgr->GetZoneId(PHASEMASK_NORMAL, map, posx, posy, posz);
if (zone > 0)
{
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 9a88a8bc782..c44b56b62e2 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2215,7 +2215,7 @@ void ObjectMgr::LoadCreatures()
{
uint32 zoneId = 0;
uint32 areaId = 0;
- sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapId, data.spawnPoint);
+ sMapMgr->GetZoneAndAreaId(data.phaseMask, zoneId, areaId, data.mapId, data.spawnPoint);
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA);
@@ -2522,7 +2522,7 @@ void ObjectMgr::LoadGameObjects()
{
uint32 zoneId = 0;
uint32 areaId = 0;
- sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapId, data.spawnPoint);
+ sMapMgr->GetZoneAndAreaId(data.phaseMask, zoneId, areaId, data.mapId, data.spawnPoint);
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA);
@@ -6856,7 +6856,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetDefaultGraveyard(uint32 team) const
WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveyard(float x, float y, float z, uint32 MapId, uint32 team) const
{
// search for zone associated closest graveyard
- uint32 zoneId = sMapMgr->GetZoneId(MapId, x, y, z);
+ uint32 zoneId = sMapMgr->GetZoneId(PHASEMASK_NORMAL, MapId, x, y, z);
if (!zoneId)
{
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 3d2e1ed4599..a8f1e9ad6c2 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -2184,7 +2184,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
else
{
WorldSafeLocsEntry const * graveyardLocation = sObjectMgr->GetClosestGraveyard(instanceEntrance->target_X, instanceEntrance->target_Y, instanceEntrance->target_Z, instanceEntrance->target_mapId, SendMsgTo->GetTeam());
- uint32 const zoneId = sMapMgr->GetZoneId(graveyardLocation->map_id, graveyardLocation->x, graveyardLocation->y, graveyardLocation->z);
+ uint32 const zoneId = sMapMgr->GetZoneId(PHASEMASK_NORMAL, graveyardLocation->map_id, graveyardLocation->x, graveyardLocation->y, graveyardLocation->z);
for (MemberSlot const& member : GetMemberSlots())
{
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index f8e38a775bc..9314fb82449 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -366,7 +366,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
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->GetMap()->IsUnderWater(plrMover->GetPhaseMask(), movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
}
/* process position-change */
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index e0378bfb7aa..bc23cc3ec5f 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2446,7 +2446,7 @@ float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, fl
LiquidData liquid_status;
- ZLiquidStatus res = GetLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status, collisionHeight);
+ ZLiquidStatus res = GetLiquidStatus(phasemask, x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status, collisionHeight);
switch (res)
{
case LIQUID_MAP_ABOVE_WATER:
@@ -2518,14 +2518,61 @@ float Map::GetMinHeight(float x, float y) const
static inline bool IsInWMOInterior(uint32 mogpFlags)
{
return (mogpFlags & 0x2000) != 0;
+}
+
+bool Map::GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
+{
+ float vmap_z = z;
+ float dynamic_z = z;
+ float check_z = z;
+ VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
+ uint32 vflags;
+ int32 vadtId;
+ int32 vrootId;
+ int32 vgroupId;
+ uint32 dflags;
+ int32 dadtId;
+ int32 drootId;
+ int32 dgroupId;
+
+ bool hasVmapAreaInfo = vmgr->getAreaInfo(GetId(), x, y, vmap_z, vflags, vadtId, vrootId, vgroupId);
+ bool hasDynamicAreaInfo = _dynamicTree.getAreaInfo(x, y, dynamic_z, phaseMask, dflags, dadtId, drootId, dgroupId);
+ auto useVmap = [&]() { check_z = vmap_z; flags = vflags; adtId = vadtId; rootId = vrootId; groupId = vgroupId; };
+ auto useDyn = [&]() { check_z = dynamic_z; flags = dflags; adtId = dadtId; rootId = drootId; groupId = dgroupId; };
+
+ if (hasVmapAreaInfo)
+ {
+ if (hasDynamicAreaInfo && dynamic_z > vmap_z)
+ useDyn();
+ else
+ useVmap();
+ }
+ else if (hasDynamicAreaInfo)
+ {
+ useDyn();
}
-uint32 Map::GetAreaId(float x, float y, float z) const
+ if (hasVmapAreaInfo || hasDynamicAreaInfo)
+ {
+ // check if there's terrain between player height and object height
+ if (GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y))
+ {
+ float mapHeight = gmap->getHeight(x, y);
+ // z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
+ if (z + 2.0f > mapHeight && mapHeight > check_z)
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+uint32 Map::GetAreaId(uint32 phaseMask, float x, float y, float z) const
{
uint32 mogpFlags;
int32 adtId, rootId, groupId;
float vmapZ = z;
- bool hasVmapArea = VMAP::VMapFactory::createOrGetVMapManager()->getAreaInfo(GetId(), x, y, vmapZ, mogpFlags, adtId, rootId, groupId);
+ bool hasVmapArea = GetAreaInfo(phaseMask, x, y, vmapZ, mogpFlags, adtId, rootId, groupId);
uint32 gridAreaId = 0;
float gridMapHeight = INVALID_HEIGHT;
@@ -2556,9 +2603,9 @@ uint32 Map::GetAreaId(float x, float y, float z) const
return areaId;
}
-uint32 Map::GetZoneId(float x, float y, float z) const
+uint32 Map::GetZoneId(uint32 phaseMask, float x, float y, float z) const
{
- uint32 areaId = GetAreaId(x, y, z);
+ uint32 areaId = GetAreaId(phaseMask, x, y, z);
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaId))
if (area->zone)
return area->zone;
@@ -2566,15 +2613,15 @@ 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(uint32 phaseMask, uint32& zoneid, uint32& areaid, float x, float y, float z) const
{
- areaid = zoneid = GetAreaId(x, y, z);
+ areaid = zoneid = GetAreaId(phaseMask, x, y, z);
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(areaid))
if (area->zone)
zoneid = area->zone;
}
-ZLiquidStatus Map::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data, float collisionHeight) const
+ZLiquidStatus Map::GetLiquidStatus(uint32 phaseMask, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data, float collisionHeight) const
{
ZLiquidStatus result = LIQUID_MAP_NO_WATER;
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
@@ -2603,7 +2650,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(phaseMask, x, y, z)))
{
uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType];
if (!overrideLiquid && area->zone)
@@ -2665,12 +2712,15 @@ ZLiquidStatus Map::GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidTyp
return result;
}
-void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType, float collisionHeight) const
+void Map::GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType, float collisionHeight) const
{
VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager();
VMAP::AreaAndLiquidData vmapData;
+ VMAP::AreaAndLiquidData dynData;
+ VMAP::AreaAndLiquidData* wmoData = nullptr;
GridMap* gmap = const_cast<Map*>(this)->GetGrid(x, y);
vmgr->getAreaAndLiquidData(GetId(), x, y, z, reqLiquidType, vmapData);
+ _dynamicTree.getAreaAndLiquidData(x, y, z, phaseMask, reqLiquidType, dynData);
uint32 gridAreaId = 0;
float gridMapHeight = INVALID_HEIGHT;
@@ -2680,7 +2730,6 @@ void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFul
gridMapHeight = gmap->getHeight(x, y);
}
- bool vmapLocation = false;
bool useGridLiquid = true;
// floor is the height we are closer to (but only if above)
@@ -2692,17 +2741,28 @@ void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFul
(G3D::fuzzyLt(z, gridMapHeight - GROUND_HEIGHT_TOLERANCE) || vmapData.floorZ > gridMapHeight))
{
data.floorZ = vmapData.floorZ;
- vmapLocation = true;
+ wmoData = &vmapData;
+ }
+ // NOTE: Objects will not detect a case when a wmo providing area/liquid despawns from under them
+ // but this is fine as these kind of objects are not meant to be spawned and despawned a lot
+ // example: Lich King platform
+ if (dynData.floorZ > VMAP_INVALID_HEIGHT &&
+ G3D::fuzzyGe(z, dynData.floorZ - GROUND_HEIGHT_TOLERANCE) &&
+ (G3D::fuzzyLt(z, gridMapHeight - GROUND_HEIGHT_TOLERANCE) || dynData.floorZ > gridMapHeight) &&
+ (G3D::fuzzyLt(z, vmapData.floorZ - GROUND_HEIGHT_TOLERANCE) || dynData.floorZ > vmapData.floorZ))
+ {
+ data.floorZ = dynData.floorZ;
+ wmoData = &dynData;
}
- if (vmapLocation)
+ if (wmoData)
{
- if (vmapData.areaInfo)
+ if (wmoData->areaInfo)
{
- data.areaInfo = boost::in_place(vmapData.areaInfo->adtId, vmapData.areaInfo->rootId, vmapData.areaInfo->groupId, vmapData.areaInfo->mogpFlags);
+ data.areaInfo = boost::in_place(wmoData->areaInfo->adtId, wmoData->areaInfo->rootId, wmoData->areaInfo->groupId, wmoData->areaInfo->mogpFlags);
// wmo found
- WMOAreaTableEntry const* wmoEntry = GetWMOAreaTableEntryByTripple(vmapData.areaInfo->rootId, vmapData.areaInfo->adtId, vmapData.areaInfo->groupId);
- data.outdoors = (vmapData.areaInfo->mogpFlags & 0x8) != 0;
+ WMOAreaTableEntry const* wmoEntry = GetWMOAreaTableEntryByTripple(wmoData->areaInfo->rootId, wmoData->areaInfo->adtId, wmoData->areaInfo->groupId);
+ data.outdoors = (wmoData->areaInfo->mogpFlags & 0x8) != 0;
if (wmoEntry)
{
data.areaId = wmoEntry->areaId;
@@ -2715,7 +2775,7 @@ void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFul
if (!data.areaId)
data.areaId = gridAreaId;
- useGridLiquid = !IsInWMOInterior(vmapData.areaInfo->mogpFlags);
+ useGridLiquid = !IsInWMOInterior(wmoData->areaInfo->mogpFlags);
}
}
else
@@ -2733,9 +2793,9 @@ void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFul
// liquid processing
data.liquidStatus = LIQUID_MAP_NO_WATER;
- if (vmapLocation && vmapData.liquidInfo && vmapData.liquidInfo->level > vmapData.floorZ)
+ if (wmoData && wmoData->liquidInfo && wmoData->liquidInfo->level > wmoData->floorZ)
{
- uint32 liquidType = vmapData.liquidInfo->type;
+ uint32 liquidType = wmoData->liquidInfo->type;
if (GetId() == 530 && liquidType == 2) // gotta love blizzard hacks
liquidType = 15;
@@ -2761,12 +2821,12 @@ void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFul
}
data.liquidInfo = boost::in_place();
- data.liquidInfo->level = vmapData.liquidInfo->level;
- data.liquidInfo->depth_level = vmapData.floorZ;
+ data.liquidInfo->level = wmoData->liquidInfo->level;
+ data.liquidInfo->depth_level = wmoData->floorZ;
data.liquidInfo->entry = liquidType;
data.liquidInfo->type_flags = 1 << liquidFlagType;
- float delta = vmapData.liquidInfo->level - z;
+ float delta = wmoData->liquidInfo->level - z;
if (delta > collisionHeight)
data.liquidStatus = LIQUID_MAP_UNDER_WATER;
else if (delta > 0.0f)
@@ -2781,7 +2841,7 @@ void Map::GetFullTerrainStatusForPosition(float x, float y, float z, PositionFul
{
LiquidData gridMapLiquid;
ZLiquidStatus gridMapStatus = gmap->GetLiquidStatus(x, y, z, reqLiquidType, &gridMapLiquid, collisionHeight);
- if (gridMapStatus != LIQUID_MAP_NO_WATER && (gridMapLiquid.level > vmapData.floorZ))
+ if (gridMapStatus != LIQUID_MAP_NO_WATER && (!wmoData || gridMapLiquid.level > wmoData->floorZ))
{
if (GetId() == 530 && gridMapLiquid.entry == 2)
gridMapLiquid.entry = 15;
@@ -2824,16 +2884,16 @@ bool Map::getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float
return result;
}
-bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const
+bool Map::IsInWater(uint32 phaseMask, 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(phaseMask, 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(uint32 phaseMask, 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(phaseMask, 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 5d5c61bb80b..a6a4e53bc50 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -396,19 +396,20 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
Map const* GetParent() const { return m_parentMap; }
- void GetFullTerrainStatusForPosition(float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType = MAP_ALL_LIQUIDS, float collisionHeight = 2.03128f) const; // DEFAULT_COLLISION_HEIGHT in Object.h
- ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr, float collisionHeight = 2.03128f) const; // DEFAULT_COLLISION_HEIGHT in Object.h
+ void GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, PositionFullTerrainStatus& data, uint8 reqLiquidType, float collisionHeight) const;
+ ZLiquidStatus GetLiquidStatus(uint32 phaseMask, float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = nullptr, float collisionHeight = 2.03128f) const; // DEFAULT_COLLISION_HEIGHT in Object.h
- uint32 GetAreaId(float x, float y, float z) const;
- uint32 GetAreaId(Position const& pos) const { return GetAreaId(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
- uint32 GetZoneId(float x, float y, float z) const;
- uint32 GetZoneId(Position const& pos) const { return GetZoneId(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, float x, float y, float z) const;
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, Position const& pos) const { GetZoneAndAreaId(zoneid, areaid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
+ bool GetAreaInfo(uint32 phaseMask, float x, float y, float z, uint32& mogpflags, int32& adtId, int32& rootId, int32& groupId) const;
+ uint32 GetAreaId(uint32 phaseMask, float x, float y, float z) const;
+ uint32 GetAreaId(uint32 phaseMask, Position const& pos) const { return GetAreaId(phaseMask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
+ uint32 GetZoneId(uint32 phaseMask, float x, float y, float z) const;
+ uint32 GetZoneId(uint32 phaseMask, Position const& pos) const { return GetZoneId(phaseMask, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
+ void GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, float x, float y, float z) const;
+ void GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, Position const& pos) const { GetZoneAndAreaId(phaseMask, zoneid, areaid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
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(uint32 phaseMask, float x, float y, float z, LiquidData* data = nullptr) const;
+ bool IsUnderWater(uint32 phaseMask, 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 9d3b1a1746b..2323e31ab9a 100644
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -38,27 +38,27 @@ 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(uint32 phaseMask, 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(phaseMask, x, y, z);
}
- uint32 GetAreaId(uint32 mapid, Position const& pos) const { return GetAreaId(mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
- uint32 GetAreaId(WorldLocation const& loc) const { return GetAreaId(loc.GetMapId(), loc); }
- uint32 GetZoneId(uint32 mapid, float x, float y, float z) const
+ uint32 GetAreaId(uint32 phaseMask, uint32 mapid, Position const& pos) const { return GetAreaId(phaseMask, mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
+ uint32 GetAreaId(uint32 phaseMask, WorldLocation const& loc) const { return GetAreaId(phaseMask, loc.GetMapId(), loc); }
+ uint32 GetZoneId(uint32 phaseMask, 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(phaseMask, x, y, z);
}
- uint32 GetZoneId(uint32 mapid, Position const& pos) const { return GetZoneId(mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
- uint32 GetZoneId(WorldLocation const& loc) const { return GetZoneId(loc.GetMapId(), loc); }
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) const
+ uint32 GetZoneId(uint32 phaseMask, uint32 mapid, Position const& pos) const { return GetZoneId(phaseMask, mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
+ uint32 GetZoneId(uint32 phaseMask, WorldLocation const& loc) const { return GetZoneId(phaseMask, loc.GetMapId(), loc); }
+ void GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, uint32 mapid, float x, float y, float z) const
{
Map const* m = const_cast<MapManager*>(this)->CreateBaseMap(mapid);
- m->GetZoneAndAreaId(zoneid, areaid, x, y, z);
+ m->GetZoneAndAreaId(phaseMask, zoneid, areaid, x, y, z);
}
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, uint32 mapid, Position const& pos) const { GetZoneAndAreaId(zoneid, areaid, mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
- void GetZoneAndAreaId(uint32& zoneid, uint32& areaid, WorldLocation const& loc) const { GetZoneAndAreaId(zoneid, areaid, loc.GetMapId(), loc); }
+ void GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, uint32 mapid, Position const& pos) const { GetZoneAndAreaId(phaseMask, zoneid, areaid, mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
+ void GetZoneAndAreaId(uint32 phaseMask, uint32& zoneid, uint32& areaid, WorldLocation const& loc) const { GetZoneAndAreaId(phaseMask, zoneid, areaid, loc.GetMapId(), loc); }
void Initialize(void);
void Update(uint32);
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 305c6b2bd67..35d518b752e 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -186,7 +186,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 = _source->GetBaseMap()->GetLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, nullptr, _source->GetCollisionHeight());
+ ZLiquidStatus status = _source->GetMap()->GetLiquidStatus(_source->GetPhaseMask(), _pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, nullptr, _source->GetCollisionHeight());
// One of the points is not in the water, cancel movement.
if (status == LIQUID_MAP_NO_WATER)
{
@@ -220,7 +220,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
bool buildShotrcut = false;
G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos;
- if (_source->GetBaseMap()->IsUnderWater(p.x, p.y, p.z))
+ if (_source->GetMap()->IsUnderWater(_source->GetPhaseMask(), p.x, p.y, p.z))
{
TC_LOG_DEBUG("maps.mmaps", "++ BuildPolyPath :: underWater case");
if (Unit const* _sourceUnit = _source->ToUnit())
@@ -698,7 +698,7 @@ void PathGenerator::UpdateFilter()
NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z)
{
LiquidData data;
- ZLiquidStatus liquidStatus = _source->GetBaseMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data, _source->GetCollisionHeight());
+ ZLiquidStatus liquidStatus = _source->GetMap()->GetLiquidStatus(_source->GetPhaseMask(), x, y, z, MAP_ALL_LIQUIDS, &data, _source->GetCollisionHeight());
if (liquidStatus == LIQUID_MAP_NO_WATER)
return NAV_GROUND;
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 857b9def33c..3b0d337f52a 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -5025,7 +5025,7 @@ void AuraEffect::HandlePreventResurrection(AuraApplication const* aurApp, uint8
if (apply)
aurApp->GetTarget()->RemoveByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_RELEASE_TIMER);
- else if (!aurApp->GetTarget()->GetBaseMap()->Instanceable())
+ else if (!aurApp->GetTarget()->GetMap()->Instanceable())
aurApp->GetTarget()->SetByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_RELEASE_TIMER);
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2675a8ae62c..4eb9b163c3a 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1322,7 +1322,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
float ground = m_caster->GetMapHeight(x, y, z);
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
LiquidData liquidData;
- if (m_caster->GetMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData, m_caster->GetCollisionHeight()))
+ if (m_caster->GetMap()->GetLiquidStatus(m_caster->GetPhaseMask(), x, y, z, MAP_ALL_LIQUIDS, &liquidData, m_caster->GetCollisionHeight()))
liquidLevel = liquidData.level;
if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index e3925b284f6..855389ae868 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -716,7 +716,7 @@ public:
uint32 respawnZoneId = 0;
if (SpawnData const* edata = data->ToSpawnData())
{
- respawnZoneId = map->GetZoneId(edata->spawnPoint);
+ respawnZoneId = map->GetZoneId(edata->phaseMask, edata->spawnPoint);
if (range)
{
if (!player->IsInDist(edata->spawnPoint, range))
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index f7fb8525475..2afbd4f367a 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -292,7 +292,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, object->GetCollisionHeight());
+ ZLiquidStatus status = map->GetLiquidStatus(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus, object->GetCollisionHeight());
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 0b4479513a5..2800c186f28 100644
--- a/src/server/scripts/Commands/cs_tele.cpp
+++ b/src/server/scripts/Commands/cs_tele.cpp
@@ -194,7 +194,7 @@ public:
CharacterDatabaseTransaction 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(PHASEMASK_NORMAL, tele->mapId, tele->position_x, tele->position_y, tele->position_z), target_guid, dummy);
}
return true;
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 3f0a4dfce5c..c83cd236629 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -211,7 +211,7 @@ class spell_spawn_blood_pool : public SpellScript
Unit* caster = GetCaster();
Position summonPos = caster->GetPosition();
LiquidData liquidStatus;
- if (caster->GetMap()->GetLiquidStatus(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus, caster->GetCollisionHeight()))
+ if (caster->GetMap()->GetLiquidStatus(caster->GetPhaseMask(), caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus, caster->GetCollisionHeight()))
summonPos.m_positionZ = liquidStatus.level;
dest.Relocate(summonPos);
}
diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h
index e2d828f37a7..5a5039b8312 100644
--- a/src/server/shared/DataStores/DBCStructure.h
+++ b/src/server/shared/DataStores/DBCStructure.h
@@ -579,24 +579,24 @@ struct CurrencyTypesEntry
struct DestructibleModelDataEntry
{
uint32 Id;
- //uint32 DamagedUnk1;
- //uint32 DamagedUnk2;
- uint32 DamagedDisplayId;
- //uint32 DamagedUnk3;
- //uint32 DestroyedUnk1;
- //uint32 DestroyedUnk2;
- uint32 DestroyedDisplayId;
- //uint32 DestroyedUnk3;
- //uint32 RebuildingUnk1;
- //uint32 RebuildingUnk2;
- uint32 RebuildingDisplayId;
- //uint32 RebuildingUnk3;
- //uint32 SmokeUnk1;
- //uint32 SmokeUnk2;
- uint32 SmokeDisplayId;
- //uint32 SmokeUnk3;
- //uint32 Unk4;
- //uint32 Unk5;
+ //uint32 State0ImpactEffectDoodadSet;
+ //uint32 State0AmbientDoodadSet;
+ uint32 State1Wmo;
+ //uint32 State1DestructionDoodadSet;
+ //uint32 State1ImpactEffectDoodadSet;
+ //uint32 State1AmbientDoodadSet;
+ uint32 State2Wmo;
+ //uint32 State2DestructionDoodadSet;
+ //uint32 State2ImpactEffectDoodadSet;
+ //uint32 State2AmbientDoodadSet;
+ uint32 State3Wmo;
+ //uint32 State3InitDoodadSet;
+ //uint32 State3AmbientDoodadSet;
+ //uint32 EjectDirection;
+ uint32 State0Wmo;
+ //uint32 DoNotHighlight;
+ //uint32 HealEffect;
+ //uint32 HealEffectSpeed;
};
struct DungeonEncounterEntry