diff options
author | Shauren <shauren.trinity@gmail.com> | 2018-03-28 22:01:22 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-06-27 20:23:30 +0200 |
commit | 0468c70dfe91794ad272594323dd7feb611d0a93 (patch) | |
tree | bb623c775fe215e4c0867fb2efa4bda0b360f7ec /src | |
parent | 54c701cf0db81c0062e8c5020e07db18984d0ffa (diff) |
Core/Maps: Implemented getting area id from gameobject spawns
Yes, you can now spawn LK platform anywhere and it will treat you as inside Icecrown Citadel
(cherry picked from commit 42f9deb21ec68e169f7ed1c8cf14092f144b22da)
Diffstat (limited to 'src')
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 |