aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/Object/Object.cpp38
1 files changed, 36 insertions, 2 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index eef0e51392c..69effaa016e 100755
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2692,8 +2692,42 @@ void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float &x, float
void WorldObject::MovePosition(Position &pos, float dist, float angle)
{
angle += m_orientation;
- pos.m_positionX += dist * cos(angle);
- pos.m_positionY += dist * sin(angle);
+ float destx, desty, destz, ground, floor;
+ destx = pos.m_positionX + dist * cos(angle);
+ desty = pos.m_positionY + dist * sin(angle);
+
+ // Prevent invalid coordinates here, position is unchanged
+ if (!Trinity::IsValidMapCoord(destx, desty))
+ {
+ sLog->outCrash("WorldObject::MovePosition invalid coordinates X: %f and Y: %f were passed!", destx, desty);
+ return;
+ }
+
+ ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
+ floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
+ destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
+
+ float step = dist/10.0f;
+
+ for (uint8 j = 0; j < 10; ++j)
+ {
+ // do not allow too big z changes
+ if (fabs(pos.m_positionZ - destz) > 6)
+ {
+ destx -= step * cos(angle);
+ desty -= step * sin(angle);
+ ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
+ floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
+ destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
+ }
+ // we have correct destz now
+ else
+ {
+ pos.Relocate(destx, desty, destz);
+ break;
+ }
+ }
+
Trinity::NormalizeMapCoord(pos.m_positionX);
Trinity::NormalizeMapCoord(pos.m_positionY);
UpdateGroundPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ);