mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
feat(Core/RPG): Port cmangos 8-angle LOS+navmesh-snap to MoveWorldObjectTo
This commit is contained in:
parent
0ba9908007
commit
4f193cb0cb
@ -488,32 +488,61 @@ bool NewRpgBaseAction::MoveWorldObjectTo(ObjectGuid guid, float distance)
|
|||||||
if (!object)
|
if (!object)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float x = object->GetPositionX();
|
Map* map = bot->GetMap();
|
||||||
float y = object->GetPositionY();
|
if (!map)
|
||||||
float z = object->GetPositionZ();
|
return false;
|
||||||
float angle = 0.f;
|
|
||||||
|
|
||||||
if (!object->ToUnit() || !object->ToUnit()->isMoving())
|
// 8-angle deterministic iteration around the target. For each angle,
|
||||||
angle = object->GetAngle(bot) + (M_PI * irand(-25, 25) / 100.0); // Closest 45 degrees towards the target
|
// validate the candidate against the navmesh with a strict ground-only
|
||||||
else
|
// filter (NAV_GROUND, exclude STEEP/WATER/MAGMA/SLIME). Reject if no
|
||||||
angle = object->GetOrientation() +
|
// valid poly within 5y XY+Z or if the snap drifts the Z by >10y.
|
||||||
(M_PI * irand(-25, 25) / 100.0); // 45 degrees infront of target (leading it's movement)
|
// First angle that passes both LOS and navmesh-snap wins.
|
||||||
|
dtNavMeshQuery const* navMeshQuery =
|
||||||
|
map->GetMapCollisionData().GetMMapData().GetNavMeshQuery();
|
||||||
|
float const baseAngle = object->GetAngle(bot);
|
||||||
|
|
||||||
// Bias toward the full radius so the bot stops next to the object,
|
for (float step = 0.0f; step < 2.0f * static_cast<float>(M_PI);
|
||||||
// not on top of it. Uniform rnd would put dest anywhere in [0, distance].
|
step += static_cast<float>(M_PI) / 4.0f)
|
||||||
float rnd = 0.85f + 0.15f * rand_norm();
|
|
||||||
x += cos(angle) * distance * rnd;
|
|
||||||
y += sin(angle) * distance * rnd;
|
|
||||||
if (!object->GetMap()->CheckCollisionAndGetValidCoords(object, object->GetPositionX(), object->GetPositionY(),
|
|
||||||
object->GetPositionZ(), x, y, z))
|
|
||||||
{
|
{
|
||||||
x = object->GetPositionX();
|
float const angle = baseAngle + step;
|
||||||
y = object->GetPositionY();
|
float x = object->GetPositionX() + std::cos(angle) * distance;
|
||||||
z = object->GetPositionZ();
|
float y = object->GetPositionY() + std::sin(angle) * distance;
|
||||||
|
float z = object->GetPositionZ();
|
||||||
|
|
||||||
|
// LOS check at eye height.
|
||||||
|
if (!bot->IsWithinLOS(x, y, z + bot->GetCollisionHeight()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Strict navmesh-snap validation (cmangos ClosestCorrectPoint port).
|
||||||
|
if (navMeshQuery)
|
||||||
|
{
|
||||||
|
dtQueryFilter filter;
|
||||||
|
filter.setIncludeFlags(NAV_GROUND);
|
||||||
|
filter.setExcludeFlags(NAV_GROUND_STEEP | NAV_WATER | NAV_MAGMA | NAV_SLIME);
|
||||||
|
|
||||||
|
float const point[VERTEX_SIZE] = { y, z, x };
|
||||||
|
float const extents[VERTEX_SIZE] = { 5.0f, 5.0f, 5.0f };
|
||||||
|
float closest[VERTEX_SIZE] = { 0.0f, 0.0f, 0.0f };
|
||||||
|
dtPolyRef polyRef = INVALID_POLYREF;
|
||||||
|
|
||||||
|
if (!dtStatusSucceed(navMeshQuery->findNearestPoly(
|
||||||
|
point, extents, &filter, &polyRef, closest)) ||
|
||||||
|
polyRef == INVALID_POLYREF)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float const snappedZ = closest[1];
|
||||||
|
if (std::fabs(snappedZ - z) > 10.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
x = closest[2];
|
||||||
|
y = closest[0];
|
||||||
|
z = snappedZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MoveFarTo(WorldPosition(object->GetMapId(), x, y, z));
|
||||||
}
|
}
|
||||||
// Route through MoveFarTo so every approach gets the full probe
|
|
||||||
// + travel-node fallback (and a precise debug label).
|
return false;
|
||||||
return MoveFarTo(WorldPosition(object->GetMapId(), x, y, z));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NewRpgBaseAction::MoveRandomNear(float moveStep, MovementPriority priority, WorldObject* center)
|
bool NewRpgBaseAction::MoveRandomNear(float moveStep, MovementPriority priority, WorldObject* center)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user