mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-17 21:50:50 -04:00
Revert "Core/Entities: Reduce the probability of units dropping under the map (#21322)"
This reverts commit 9e0faace9a.
This commit is contained in:
@@ -3262,103 +3262,13 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
// Only call this function when you already checked for collision with vmap/gameobject.
|
||||
// You should check for collision again after this one has been called.
|
||||
// excludeCollisionHeight should only be true if you had collision, it wont add it to raycasts for dest position.
|
||||
float WorldObject::SelectBestZForDestination(float x, float y, float z, bool excludeCollisionHeight) const
|
||||
{
|
||||
if (Unit const* unit = ToUnit())
|
||||
{
|
||||
float const ground = GetFloorZ();
|
||||
bool const isInAir = (G3D::fuzzyGt(unit->GetPositionZ(), ground + GROUND_HEIGHT_TOLERANCE) || G3D::fuzzyLt(unit->GetPositionZ(), ground - GROUND_HEIGHT_TOLERANCE));
|
||||
if (isInAir)
|
||||
{
|
||||
// creatures never get MOVEMENTFLAG_FLYING, check it additionally for them
|
||||
if (Creature const* creature = ToCreature())
|
||||
if (creature->CanFly())
|
||||
return z;
|
||||
|
||||
if (unit->IsFlying())
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
float myX, myY, myZ;
|
||||
GetPosition(myX, myY, myZ);
|
||||
|
||||
float const myCollisionHeight = GetCollisionHeight();
|
||||
float const destCollisionHeight = excludeCollisionHeight ? 0.0f : myCollisionHeight;
|
||||
|
||||
float const myGridHeight = GetMap()->GetGridMapHeight(myX, myY);
|
||||
float const myVmapFloor = std::max(GetMap()->GetVMapFloor(myX, myY, myZ, 150.0f, myCollisionHeight),
|
||||
GetMap()->GetGameObjectFloor(GetPhaseMask(), myX, myY, myZ, 150.0f, myCollisionHeight));
|
||||
|
||||
// which of these 3 do I want ?
|
||||
float const destGridHeight = GetMap()->GetGridMapHeight(x, y);
|
||||
float const destCeil = GetMap()->GetCeil(GetPhaseMask(), x, y, z, 150.0f, destCollisionHeight);
|
||||
float const destVmapFloor = std::max(GetMap()->GetVMapFloor(x, y, z, 150.0f, destCollisionHeight),
|
||||
GetMap()->GetGameObjectFloor(GetPhaseMask(), x, y, z, 150.0f, destCollisionHeight));
|
||||
|
||||
bool const hasVmapFloor = myVmapFloor > INVALID_HEIGHT;
|
||||
bool const hasDestGridHeight = destGridHeight > INVALID_HEIGHT;
|
||||
bool const hasDestVmapCeil = destCeil < VMAP_INVALID_CEIL && destCeil != destVmapFloor;
|
||||
bool const hasDestVmapFloor = destVmapFloor > INVALID_HEIGHT;
|
||||
bool const destBetweenVmaps = hasDestVmapCeil && hasDestVmapFloor;
|
||||
bool const noVmap = !hasDestVmapFloor && !hasDestVmapCeil;
|
||||
|
||||
// It is possible that while moving, our feet are slightly moving under the ground. Jumping / reconnecting fixes this issue but we don't want to rely on that.
|
||||
myZ += myCollisionHeight;
|
||||
bool const isOnVmap = hasVmapFloor &&
|
||||
((myZ < myGridHeight && std::fabs(myVmapFloor - myZ) < std::fabs(myGridHeight - myZ)) ||
|
||||
(myZ > myGridHeight && myVmapFloor > myGridHeight));
|
||||
|
||||
bool const hasToFollowGridHeight = hasDestGridHeight && (noVmap ||
|
||||
(z > destGridHeight && destGridHeight > destVmapFloor) ||
|
||||
(z < destGridHeight && hasDestVmapFloor && !hasDestVmapCeil) ||
|
||||
(z < destGridHeight && !hasDestVmapFloor) ||
|
||||
(destBetweenVmaps && !isOnVmap && destGridHeight > destVmapFloor && destGridHeight < destCeil));
|
||||
|
||||
float result = INVALID_HEIGHT;
|
||||
if (hasToFollowGridHeight)
|
||||
{
|
||||
result = destGridHeight;
|
||||
if (hasDestVmapFloor)
|
||||
if (std::fabs(destVmapFloor - destGridHeight) < myCollisionHeight)
|
||||
result = std::max(destVmapFloor, destGridHeight);
|
||||
|
||||
if (hasDestVmapCeil)
|
||||
if (std::fabs(destCeil - destGridHeight) < myCollisionHeight)
|
||||
result = std::max(destCeil, destGridHeight);
|
||||
}
|
||||
else if (hasDestVmapFloor)
|
||||
result = destVmapFloor;
|
||||
else if (hasDestVmapCeil)
|
||||
result = destCeil;
|
||||
|
||||
if (Unit const* unit = ToUnit())
|
||||
if (!unit->CanSwim())
|
||||
return result;
|
||||
|
||||
LiquidData liquidData;
|
||||
ZLiquidStatus const liquidStatus = GetMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData, destCollisionHeight);
|
||||
switch (liquidStatus)
|
||||
{
|
||||
case LIQUID_MAP_ABOVE_WATER:
|
||||
return std::max<float>(liquidData.level, result);
|
||||
case LIQUID_MAP_IN_WATER:
|
||||
case LIQUID_MAP_UNDER_WATER:
|
||||
return std::max<float>(z, result);
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float angle)
|
||||
{
|
||||
angle += GetOrientation();
|
||||
float destx = pos.m_positionX + dist * std::cos(angle);
|
||||
float desty = pos.m_positionY + dist * std::sin(angle);
|
||||
float destz = pos.m_positionZ;
|
||||
float destx, desty, destz;
|
||||
destx = pos.m_positionX + dist * std::cos(angle);
|
||||
desty = pos.m_positionY + dist * std::sin(angle);
|
||||
destz = pos.m_positionZ;
|
||||
|
||||
// Prevent invalid coordinates here, position is unchanged
|
||||
if (!Trinity::IsValidMapCoord(destx, desty))
|
||||
@@ -3367,72 +3277,52 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
return;
|
||||
}
|
||||
|
||||
bool const col = ComputeCollisionPosition(pos, { destx, desty, destz }, destx, desty, destz);
|
||||
UpdateAllowedPositionZ(destx, desty, destz);
|
||||
bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ, destx, desty, destz, destx, desty, destz, -0.5f);
|
||||
|
||||
// collision occured
|
||||
if (col)
|
||||
{
|
||||
// move back a bit
|
||||
destx -= CONTACT_DISTANCE * std::cos(angle);
|
||||
desty -= CONTACT_DISTANCE * std::sin(angle);
|
||||
dist = std::sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty));
|
||||
|
||||
destz = SelectBestZForDestination(destx, desty, destz, col);
|
||||
|
||||
float const step = dist / 10.0f;
|
||||
// do not allow too big z changes
|
||||
for (uint8 j = 0; j < 10 && std::fabs(pos.m_positionZ - destz) > 6.0f; ++j)
|
||||
{
|
||||
destx -= step * std::cos(angle);
|
||||
desty -= step * std::sin(angle);
|
||||
// There should not be any collision between our position and destx, desty, pos.m_positionZ at this point.
|
||||
// Use pos.m_positionZ here because destz was not good.
|
||||
destz = SelectBestZForDestination(destx, desty, pos.m_positionZ, col);
|
||||
}
|
||||
|
||||
Trinity::NormalizeMapCoord(destx);
|
||||
Trinity::NormalizeMapCoord(desty);
|
||||
// We might want to loop until there is no more collision with a better z position. (And/or until a fixed #attemps have been made).
|
||||
ComputeCollisionPosition(pos, { destx, desty, destz }, destx, desty, destz);
|
||||
pos.Relocate(destx, desty, destz);
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
// check dynamic collision
|
||||
col = GetMap()->getObjectHitPos(GetPhaseMask(), pos.m_positionX, pos.m_positionY, pos.m_positionZ, destx, desty, destz, destx, desty, destz, -0.5f);
|
||||
|
||||
bool WorldObject::ComputeCollisionPosition(Position const& startPosition, Position const& endPosition, float& x, float& y, float& z) const
|
||||
// Collided with a gameobject
|
||||
if (col)
|
||||
{
|
||||
destx -= CONTACT_DISTANCE * std::cos(angle);
|
||||
desty -= CONTACT_DISTANCE * std::sin(angle);
|
||||
dist = std::sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty));
|
||||
}
|
||||
|
||||
float step = dist / 10.0f;
|
||||
|
||||
for (uint8 j = 0; j < 10; ++j)
|
||||
{
|
||||
Position vmapCollisionPos;
|
||||
bool const vmapCollision = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), startPosition.m_positionX, startPosition.m_positionY, startPosition.m_positionZ + GetCollisionHeight(), endPosition.m_positionX, endPosition.m_positionY, endPosition.m_positionZ + GetCollisionHeight(), vmapCollisionPos.m_positionX, vmapCollisionPos.m_positionY, vmapCollisionPos.m_positionZ, -CONTACT_DISTANCE * 2.0f);
|
||||
Position gameObjectCollisionPos;
|
||||
bool const gameObjectCollision = GetMap()->getObjectHitPos(GetPhaseMask(), startPosition.m_positionX, startPosition.m_positionY, startPosition.m_positionZ + GetCollisionHeight(), endPosition.m_positionX, endPosition.m_positionY, endPosition.m_positionZ + GetCollisionHeight(), gameObjectCollisionPos.m_positionX, gameObjectCollisionPos.m_positionY, gameObjectCollisionPos.m_positionZ, -CONTACT_DISTANCE * 2.0f);
|
||||
|
||||
// Both collision occures, check which one is closest to start.
|
||||
if (vmapCollision && gameObjectCollision)
|
||||
// do not allow too big z changes
|
||||
if (std::fabs(pos.m_positionZ - destz) > 6.0f)
|
||||
{
|
||||
if (startPosition.GetExactDist(vmapCollision) < startPosition.GetExactDist(gameObjectCollisionPos))
|
||||
{
|
||||
x = vmapCollisionPos.m_positionX;
|
||||
y = vmapCollisionPos.m_positionY;
|
||||
z = vmapCollisionPos.m_positionZ;
|
||||
return true;
|
||||
destx -= step * std::cos(angle);
|
||||
desty -= step * std::sin(angle);
|
||||
UpdateAllowedPositionZ(destx, desty, destz);
|
||||
}
|
||||
|
||||
x = gameObjectCollisionPos.m_positionX;
|
||||
y = gameObjectCollisionPos.m_positionY;
|
||||
z = gameObjectCollisionPos.m_positionZ;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vmapCollision)
|
||||
// we have correct destz now
|
||||
else
|
||||
{
|
||||
x = vmapCollisionPos.m_positionX;
|
||||
y = vmapCollisionPos.m_positionY;
|
||||
z = vmapCollisionPos.m_positionZ;
|
||||
return true;
|
||||
pos.Relocate(destx, desty, destz);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (gameObjectCollision)
|
||||
{
|
||||
x = gameObjectCollisionPos.m_positionX;
|
||||
y = gameObjectCollisionPos.m_positionY;
|
||||
z = gameObjectCollisionPos.m_positionZ;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
Trinity::NormalizeMapCoord(pos.m_positionX);
|
||||
Trinity::NormalizeMapCoord(pos.m_positionY);
|
||||
UpdateAllowedPositionZ(destx, desty, pos.m_positionZ);
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
@@ -3625,7 +3515,10 @@ float WorldObject::GetMapWaterOrGroundLevel(float x, float y, float z, float* gr
|
||||
|
||||
float WorldObject::GetMapHeight(float x, float y, float z, bool vmap/* = true*/, float distanceToSearch/* = DEFAULT_HEIGHT_SEARCH*/) const
|
||||
{
|
||||
return GetMap()->GetHeight(GetPhaseMask(), x, y, z, vmap, distanceToSearch, GetCollisionHeight());
|
||||
if (z != MAX_HEIGHT)
|
||||
z += GetCollisionHeight();
|
||||
|
||||
return GetMap()->GetHeight(GetPhaseMask(), x, y, z, vmap, distanceToSearch);
|
||||
}
|
||||
|
||||
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>&, uint32, float) const;
|
||||
|
||||
Reference in New Issue
Block a user