fix in MMAP navigation when traveling to portal node
clang PCH / build (push) Canceled after 0s
GCC PCH / build (push) Canceled after 0s

This commit is contained in:
Nico committed 2026-10-16 22:28:22 +00:00
1 parent fe7b5e0f02
commit 6e17dedff2
2 files changed
+57 -3

No files matched your search

+56 -2
View File
@@ -125,10 +125,22 @@ bool ClientlessTravelMgr::AnalyzePath(
diagnostics.FinalDistance = diagnostics.DirectDistance; diagnostics.FinalDistance = diagnostics.DirectDistance;
uint32 const pathType = diagnostics.PathType; uint32 const pathType = diagnostics.PathType;
// VCORE_C814A_NAVIGATION_FIX: narrowly accept a short incomplete MMAP path
// only when its actual points reach the target without unsafe segments.
bool const shortEndReached =
diagnostics.Calculated &&
(pathType & uint32(PATHFIND_INCOMPLETE)) != 0 &&
(pathType & uint32(PATHFIND_NOPATH)) == 0 &&
diagnostics.PointCount >= 2 &&
diagnostics.DirectDistance <= 25.0f &&
diagnostics.PathLength <= 40.0f &&
diagnostics.FinalDistance <= 0.25f &&
diagnostics.MaxSegmentLength <= 6.0f &&
diagnostics.MaxZDelta <= 4.0f;
diagnostics.Complete = diagnostics.Complete =
diagnostics.Calculated && diagnostics.Calculated &&
(pathType & uint32(PATHFIND_NOPATH)) == 0 && (pathType & uint32(PATHFIND_NOPATH)) == 0 &&
(pathType & uint32(PATHFIND_INCOMPLETE)) == 0; ((pathType & uint32(PATHFIND_INCOMPLETE)) == 0 || shortEndReached);
auto addReason = [&](char const* reason) auto addReason = [&](char const* reason)
{ {
@@ -196,6 +208,19 @@ bool ClientlessTravelMgr::LaunchPath(Player* player, TravelRecord& record)
Position const& target = record.Status.Target; Position const& target = record.Status.Target;
// VCORE_C814A_NAVIGATION_FIX: an already reached node is not a failed spline.
if (Distance3D(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(),
target.GetPositionX(), target.GetPositionY(), target.GetPositionZ()) <= ARRIVAL_DISTANCE)
{
record.Status.State = ClientlessTravelState::Arrived;
record.Status.RemainingDistance = 0.0f;
record.Status.NoProgressMs = 0;
TC_LOG_INFO("server.adventurebot.navigation",
"NAV_ALREADY_ARRIVED guid=%u name='%s' map=%u",
player->GetGUID().GetCounter(), player->GetName().c_str(), player->GetMapId());
return true;
}
AnalyzePath(player, target, record.Status.Path); AnalyzePath(player, target, record.Status.Path);
ClientlessPathDiagnostics const& nav = record.Status.Path; ClientlessPathDiagnostics const& nav = record.Status.Path;
record.Status.NavSequence = _nextNavSequence++; record.Status.NavSequence = _nextNavSequence++;
@@ -245,9 +270,38 @@ bool ClientlessTravelMgr::LaunchPath(Player* player, TravelRecord& record)
auto const& points = path.GetPath(); auto const& points = path.GetPath();
uint32 const executionType = uint32(path.GetPathType()); uint32 const executionType = uint32(path.GetPathType());
// VCORE_C814A_NAVIGATION_FIX: confirm the execution path independently.
float executionLength = 0.0f;
float executionMaxSegment = 0.0f;
float executionMaxZ = 0.0f;
for (std::size_t i = 1; i < points.size(); ++i)
{
float const segment = Distance3D(points[i-1].x, points[i-1].y, points[i-1].z,
points[i].x, points[i].y, points[i].z);
executionLength += segment;
executionMaxSegment = std::max(executionMaxSegment, segment);
executionMaxZ = std::max(executionMaxZ, std::fabs(points[i].z - points[i-1].z));
}
float const executionFinalDistance = points.empty() ? nav.DirectDistance :
Distance3D(points.back().x, points.back().y, points.back().z,
target.GetPositionX(), target.GetPositionY(), target.GetPositionZ());
bool const executionShortEndReached =
(executionType & uint32(PATHFIND_INCOMPLETE)) != 0 &&
(executionType & uint32(PATHFIND_NOPATH)) == 0 &&
points.size() >= 2 &&
nav.DirectDistance <= 25.0f &&
executionLength <= 40.0f &&
executionFinalDistance <= 0.25f &&
executionMaxSegment <= 6.0f &&
executionMaxZ <= 4.0f;
if (executionShortEndReached)
TC_LOG_INFO("server.adventurebot.navigation",
"NAV_SHORT_INCOMPLETE_ACCEPT guid=%u name='%s' path=%.2f final=%.2f",
player->GetGUID().GetCounter(), player->GetName().c_str(),
executionLength, executionFinalDistance);
if (points.size() < 2 || if (points.size() < 2 ||
(executionType & uint32(PATHFIND_NOPATH)) != 0 || (executionType & uint32(PATHFIND_NOPATH)) != 0 ||
(executionType & uint32(PATHFIND_INCOMPLETE)) != 0) ((executionType & uint32(PATHFIND_INCOMPLETE)) != 0 && !executionShortEndReached))
{ {
record.Status.State = ClientlessTravelState::PathRejected; record.Status.State = ClientlessTravelState::PathRejected;
TC_LOG_WARN("server.adventurebot.navigation", TC_LOG_WARN("server.adventurebot.navigation",
@@ -12,7 +12,7 @@ log("Arthoran C8.13b bridge test loaded")
--}) --})
queue_action("travel_to_node", { queue_action("travel_to_node", {
node = "portal_at_2173_target", node = "lakeshire",
bridge_radius = 400, bridge_radius = 400,
bridge_path_max = 600 bridge_path_max = 600
}) })