From cd16f6baf198cbd05f74bb6b693078a78e04727f Mon Sep 17 00:00:00 2001 From: bash Date: Fri, 10 Apr 2026 12:47:49 +0200 Subject: [PATCH] z-axe clamping to prevent clipping throught the map --- src/Ai/Base/Actions/MovementActions.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Ai/Base/Actions/MovementActions.cpp b/src/Ai/Base/Actions/MovementActions.cpp index 4f4a110a3..85855f60d 100644 --- a/src/Ai/Base/Actions/MovementActions.cpp +++ b/src/Ai/Base/Actions/MovementActions.cpp @@ -101,6 +101,11 @@ bool MovementAction::MoveNear(WorldObject* target, float distance, MovementPrior float x = target->GetPositionX() + cos(angle) * distance; float y = target->GetPositionY() + sin(angle) * distance; float z = target->GetPositionZ(); + // Clamp Z to the terrain under the offset point so we don't + // hand PointMovementGenerator a Z that matches the target's + // floor but not the sampled (x,y) — avoids straight-line + // fallbacks through geometry. + bot->UpdateAllowedPositionZ(x, y, z); if (!bot->IsWithinLOS(x, y, z)) continue; @@ -250,7 +255,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, // bot->CastStop(); // botAI->InterruptSpell(); // } - DoMovePoint(bot, x, y, z, generatePath, backwards); + DoMovePoint(bot, x, y, modifiedZ, generatePath, backwards); float delay = 1000.0f * MoveDelay(distance, backwards); if (lessDelay) { @@ -258,7 +263,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle, } delay = std::max(.0f, delay); delay = std::min((float)sPlayerbotAIConfig.maxWaitForMove, delay); - AI_VALUE(LastMovement&, "last movement").Set(mapId, x, y, z, bot->GetOrientation(), delay, priority); + AI_VALUE(LastMovement&, "last movement") + .Set(mapId, x, y, modifiedZ, bot->GetOrientation(), delay, priority); return true; } } @@ -778,15 +784,17 @@ bool MovementAction::MoveTo(WorldObject* target, float distance, MovementPriorit float dx = cos(angle) * needToGo + bx; float dy = sin(angle) * needToGo + by; - float dz; // = std::max(bz, tz); // calc accurate z position to avoid stuck + // Start from a seed Z between bot and target, then clamp to the + // terrain under (dx,dy). Linear interpolation alone ignores hills + // between the two units and fed PointMovementGenerator a Z that + // could be well above/below ground, triggering straight-line + // fallbacks through walls. + float dz; if (distanceToTarget > CONTACT_DISTANCE) - { dz = bz + (tz - bz) * (needToGo / distanceToTarget); - } else - { dz = tz; - } + bot->UpdateAllowedPositionZ(dx, dy, dz); return MoveTo(target->GetMapId(), dx, dy, dz, false, false, false, false, priority); }