fix(Core/Collision): make spawned WMO gameobjects provide indoor/area info (#26790)

This commit is contained in:
Andrew
2026-07-25 17:16:58 -03:00
committed by GitHub
parent 9fe2eec585
commit db165fc26a
4 changed files with 9 additions and 6 deletions

View File

@@ -198,7 +198,8 @@ bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& MaxDist, bool Sto
bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationInfo& info, uint32 ph_mask) const
{
if (!(phasemask & ph_mask) || !owner->IsSpawned() || !IsMapObject())
// transports provide inaccurate area info while moving (e.g. Booty Bay - Ratchet boat, see #7335)
if (!(phasemask & ph_mask) || !owner->IsSpawned() || !IsMapObject() || owner->IsTransport())
return false;
if (!iBound.contains(point))
@@ -216,6 +217,8 @@ bool GameObjectModel::GetLocationInfo(G3D::Vector3 const& point, VMAP::LocationI
float world_Z = ((modelGround * iInvRot) * iScale + iPos).z;
if (info.ground_Z < world_Z)
{
info.rootId = groupInfo.rootId;
info.hitModel = groupInfo.hitModel;
info.ground_Z = world_Z;
return true;
}

View File

@@ -42,6 +42,7 @@ public:
virtual ~GameObjectModelOwnerBase() = default;
[[nodiscard]] virtual bool IsSpawned() const = 0;
[[nodiscard]] virtual bool IsTransport() const { return false; }
[[nodiscard]] virtual uint32 GetDisplayId() const = 0;
[[nodiscard]] virtual uint32 GetPhaseMask() const = 0;
[[nodiscard]] virtual G3D::Vector3 GetPosition() const = 0;

View File

@@ -2968,6 +2968,7 @@ public:
explicit GameObjectModelOwnerImpl(GameObject* owner) : _owner(owner) { }
bool IsSpawned() const override { return _owner->isSpawned(); }
bool IsTransport() const override { return _owner->IsTransport(); }
uint32 GetDisplayId() const override { return _owner->GetDisplayId(); }
uint32 GetPhaseMask() const override { return (_owner->GetGoState() == GO_STATE_READY || _owner->IsTransport()) ? _owner->GetPhaseMask() : 0; }
G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); }

View File

@@ -1389,15 +1389,15 @@ LiquidData const Map::GetLiquidData(uint32 phaseMask, float x, float y, float z,
return liquidData;
}
void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional<uint8> reqLiquidType)
void Map::GetFullTerrainStatusForPosition(uint32 phaseMask, float x, float y, float z, float collisionHeight, PositionFullTerrainStatus& data, Optional<uint8> reqLiquidType)
{
GridTerrainData* gmap = GetGridTerrainData(x, y);
VMAP::AreaAndLiquidData vmapData;
// VMAP::AreaAndLiquidData dynData;
VMAP::AreaAndLiquidData dynData;
VMAP::AreaAndLiquidData* wmoData = nullptr;
_mapCollisionData.GetStaticTree().GetAreaAndLiquidData(x, y, z, reqLiquidType, vmapData);
// _dynamicTree.GetAreaAndLiquidData(x, y, z, phaseMask, reqLiquidType, dynData);
_mapCollisionData.GetDynamicTree().GetAreaAndLiquidData(x, y, z, phaseMask, reqLiquidType, dynData);
uint32 gridAreaId = 0;
float gridMapHeight = INVALID_HEIGHT;
@@ -1424,7 +1424,6 @@ void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y
// 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))
@@ -1432,7 +1431,6 @@ void Map::GetFullTerrainStatusForPosition(uint32 /*phaseMask*/, float x, float y
data.floorZ = dynData.floorZ;
wmoData = &dynData;
}
*/
if (wmoData)
{