fiexed virtuel entry nodes so they will be considered equal to all other Nodes
This commit is contained in:
1 parent
ae2a4a0f08
commit
2bcffa5131
4 files changed
+80
-32
No files matched your search
@@ -551,14 +551,9 @@ bool ClientlessActionExecutorMgr::StartTravelToNode(
|
||||
record.TaxiSourceNodeId = 0;
|
||||
record.TaxiDestinationNodeId = 0;
|
||||
std::string error;
|
||||
if (sClientlessTravelGraphMgr->PlanRoute(
|
||||
player, destinationNode, startRadius, record.Route, error,
|
||||
&record.FailedEdgeDatabaseIds))
|
||||
{
|
||||
record.RouteComplete = true;
|
||||
record.AdaptiveReachedNode = destinationNode;
|
||||
}
|
||||
else if (!sClientlessTravelGraphMgr->PlanAdaptiveRoute(
|
||||
// VCORE_VIRTUAL_EDGE_V11_PORTAL_APPROACH: adaptive planning is primary.
|
||||
// This considers MMAP-reachable ordinary and virtual ground entry points together.
|
||||
if (!sClientlessTravelGraphMgr->PlanAdaptiveRoute(
|
||||
player, destinationNode, startRadius, record.LocalBridgeRadius,
|
||||
record.Route, record.RouteComplete, record.AdaptiveReachedNode, error,
|
||||
&record.FailedEdgeDatabaseIds, &record.FailedBridgeKeys))
|
||||
@@ -1279,7 +1274,11 @@ bool ClientlessActionExecutorMgr::StartRouteStep(
|
||||
Position destination;
|
||||
destination.Relocate(step.X, step.Y, step.Z, step.O);
|
||||
|
||||
if (!sClientlessTravelMgr->StartTravel(player, destination, true))
|
||||
bool const portalSourceApproach =
|
||||
step.NodeKey.rfind("portal_at_", 0) == 0 &&
|
||||
step.NodeKey.find("_source") != std::string::npos;
|
||||
if (!sClientlessTravelMgr->StartTravel(player, destination, !portalSourceApproach,
|
||||
portalSourceApproach))
|
||||
{
|
||||
record.Status.State = ClientlessActionExecutionState::Failed;
|
||||
record.Status.Detail = "travel start failed for route node " + step.NodeKey;
|
||||
@@ -1466,6 +1465,18 @@ bool ClientlessActionExecutorMgr::RecoverTravel(
|
||||
|
||||
if (failedEdgeDatabaseId)
|
||||
record.FailedEdgeDatabaseIds.insert(failedEdgeDatabaseId);
|
||||
// A failed initial local approach must not be tried five times at the same spot.
|
||||
if (!failedEdgeDatabaseId && record.RouteStep == 0 && !record.Route.empty() &&
|
||||
reason.rfind("route-local-", 0) == 0)
|
||||
{
|
||||
std::string const& badStart = record.Route.front().NodeKey;
|
||||
if (badStart != "virtual_ground_entry")
|
||||
{
|
||||
record.FailedBridgeKeys.insert("start:" + badStart);
|
||||
TC_LOG_WARN("server.adventurebot.navigation",
|
||||
"START_NODE_BLOCK node='%s' reason='%s'", badStart.c_str(), reason.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool const bridgeFailure = reason.rfind("local-bridge-", 0) == 0;
|
||||
|
||||
@@ -1561,24 +1572,11 @@ bool ClientlessActionExecutorMgr::RecoverTravel(
|
||||
}
|
||||
else if (record.Status.ActionName == "travel_to_node")
|
||||
{
|
||||
planned = sClientlessTravelGraphMgr->PlanRoute(
|
||||
player,
|
||||
record.PlannedDestinationNode,
|
||||
radius,
|
||||
record.Route,
|
||||
error,
|
||||
&record.FailedEdgeDatabaseIds);
|
||||
|
||||
if (planned)
|
||||
{
|
||||
record.RouteComplete = true;
|
||||
record.AdaptiveReachedNode = record.PlannedDestinationNode;
|
||||
}
|
||||
else
|
||||
planned = sClientlessTravelGraphMgr->PlanAdaptiveRoute(
|
||||
player, record.PlannedDestinationNode, radius, record.LocalBridgeRadius,
|
||||
record.Route, record.RouteComplete, record.AdaptiveReachedNode, error,
|
||||
&record.FailedEdgeDatabaseIds, &record.FailedBridgeKeys);
|
||||
// VCORE_VIRTUAL_EDGE_V11_PORTAL_APPROACH: adaptive recovery only.
|
||||
planned = sClientlessTravelGraphMgr->PlanAdaptiveRoute(
|
||||
player, record.PlannedDestinationNode, radius, record.LocalBridgeRadius,
|
||||
record.Route, record.RouteComplete, record.AdaptiveReachedNode, error,
|
||||
&record.FailedEdgeDatabaseIds, &record.FailedBridgeKeys);
|
||||
|
||||
if (planned)
|
||||
TC_LOG_WARN("server.adventurebot.navigation",
|
||||
|
||||
@@ -470,6 +470,25 @@ bool ClientlessTravelGraphMgr::PlanAdaptiveRoute(
|
||||
if (localDistance > startRadius)
|
||||
continue;
|
||||
|
||||
// VCORE_VIRTUAL_EDGE_V11_PORTAL_APPROACH: never seed an unreachable node.
|
||||
if (blockedBridgeKeys && blockedBridgeKeys->count("start:" + node.Key))
|
||||
continue;
|
||||
if (localDistance > 1.5f)
|
||||
{
|
||||
Position entryTarget;
|
||||
entryTarget.Relocate(node.X, node.Y, node.Z, node.O);
|
||||
ClientlessPathDiagnostics entryNav;
|
||||
sClientlessTravelMgr->AnalyzePath(const_cast<Player*>(player), entryTarget, entryNav);
|
||||
if (!entryNav.Calculated || !entryNav.Complete || entryNav.FinalDistance > 1.5f ||
|
||||
entryNav.MaxSegmentLength > 8.0f || entryNav.MaxZDelta > 5.0f ||
|
||||
entryNav.PathLength > 500.0f)
|
||||
{
|
||||
TC_LOG_INFO("server.adventurebot.navigation",
|
||||
"START_NODE_REJECT node='%s' distance=%.2f reason='%s'",
|
||||
node.Key.c_str(), localDistance, entryNav.Reason.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
State state{ node.Key, false };
|
||||
std::string const key = stateKey(state);
|
||||
auto found = distance.find(key);
|
||||
@@ -575,6 +594,8 @@ bool ClientlessTravelGraphMgr::PlanAdaptiveRoute(
|
||||
|
||||
State state{ candidate.Edge.ToNode, false };
|
||||
std::string key = stateKey(state);
|
||||
if (blockedBridgeKeys && blockedBridgeKeys->count("start:" + candidate.Edge.ToNode))
|
||||
continue;
|
||||
float remainingFraction = candidate.Edge.Reverse
|
||||
? float(candidate.Index) / float(candidate.Count - 1)
|
||||
: float(candidate.Count - candidate.Index - 1) / float(candidate.Count - 1);
|
||||
@@ -591,7 +612,7 @@ bool ClientlessTravelGraphMgr::PlanAdaptiveRoute(
|
||||
open.push({ newCost, state });
|
||||
++accepted;
|
||||
}
|
||||
if (accepted)
|
||||
if (validated)
|
||||
TC_LOG_INFO("server.adventurebot.navigation",
|
||||
"VIRTUAL_EDGE_CANDIDATES map=%u tested=%u accepted=%u",
|
||||
player->GetMapId(), validated, accepted);
|
||||
|
||||
@@ -242,7 +242,16 @@ bool ClientlessTravelMgr::LaunchPath(Player* player, TravelRecord& record)
|
||||
nav.MaxZDelta, nav.FinalDistance, record.Status.RepathCount,
|
||||
nav.Reason.c_str());
|
||||
|
||||
if (!nav.Calculated || !nav.Complete || nav.PointCount < 2 || nav.FinalDistance > MAX_PATH_FINAL_ERROR)
|
||||
// VCORE_VIRTUAL_EDGE_V11_PORTAL_APPROACH: execute only a validated partial
|
||||
// MMAP corridor. Never turn this exception on for normal ground navigation.
|
||||
bool const portalPartial = record.PortalApproach && nav.Calculated &&
|
||||
(nav.PathType & uint32(PATHFIND_INCOMPLETE)) != 0 &&
|
||||
(nav.PathType & uint32(PATHFIND_NOPATH)) == 0 &&
|
||||
nav.PointCount >= 2 && nav.FinalDistance <= 6.0f &&
|
||||
nav.PathLength <= 100.0f && nav.MaxSegmentLength <= 6.0f &&
|
||||
nav.MaxZDelta <= 4.0f;
|
||||
if (!nav.Calculated || (!nav.Complete && !portalPartial) || nav.PointCount < 2 ||
|
||||
(nav.FinalDistance > MAX_PATH_FINAL_ERROR && !portalPartial))
|
||||
{
|
||||
record.Status.State = ClientlessTravelState::PathRejected;
|
||||
record.Status.NoProgressMs = 0;
|
||||
@@ -299,9 +308,15 @@ bool ClientlessTravelMgr::LaunchPath(Player* player, TravelRecord& record)
|
||||
"NAV_SHORT_INCOMPLETE_ACCEPT guid=%u name='%s' path=%.2f final=%.2f",
|
||||
player->GetGUID().GetCounter(), player->GetName().c_str(),
|
||||
executionLength, executionFinalDistance);
|
||||
bool const portalExecutionPartial = record.PortalApproach && portalPartial &&
|
||||
(executionType & uint32(PATHFIND_INCOMPLETE)) != 0 &&
|
||||
(executionType & uint32(PATHFIND_NOPATH)) == 0 &&
|
||||
points.size() >= 2 && executionFinalDistance <= 6.0f &&
|
||||
executionLength <= 100.0f && executionMaxSegment <= 6.0f && executionMaxZ <= 4.0f;
|
||||
if (points.size() < 2 ||
|
||||
(executionType & uint32(PATHFIND_NOPATH)) != 0 ||
|
||||
((executionType & uint32(PATHFIND_INCOMPLETE)) != 0 && !executionShortEndReached))
|
||||
((executionType & uint32(PATHFIND_INCOMPLETE)) != 0 &&
|
||||
!executionShortEndReached && !portalExecutionPartial))
|
||||
{
|
||||
record.Status.State = ClientlessTravelState::PathRejected;
|
||||
TC_LOG_WARN("server.adventurebot.navigation",
|
||||
@@ -312,6 +327,17 @@ bool ClientlessTravelMgr::LaunchPath(Player* player, TravelRecord& record)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (portalExecutionPartial)
|
||||
{
|
||||
// Mark local traversal arrived at the actual MMAP endpoint only;
|
||||
// the portal executor still checks IsInAreaTriggerRadius and actual map transition.
|
||||
Position endpoint;
|
||||
endpoint.Relocate(points.back().x, points.back().y, points.back().z, player->GetOrientation());
|
||||
record.Status.Target = endpoint;
|
||||
TC_LOG_INFO("server.adventurebot.navigation",
|
||||
"NAV_PORTAL_PARTIAL_APPROACH guid=%u remainingToTrigger=%.2f path=%.2f",
|
||||
player->GetGUID().GetCounter(), executionFinalDistance, executionLength);
|
||||
}
|
||||
std::vector<Position> spline;
|
||||
spline.reserve(points.size() + 1);
|
||||
|
||||
@@ -406,7 +432,7 @@ bool ClientlessTravelMgr::LaunchPath(Player* player, TravelRecord& record)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClientlessTravelMgr::StartTravel(Player* player, Position const& target, bool allowGroundMount)
|
||||
bool ClientlessTravelMgr::StartTravel(Player* player, Position const& target, bool allowGroundMount, bool portalApproach)
|
||||
{
|
||||
if (!player || !player->IsInWorld())
|
||||
return false;
|
||||
@@ -419,6 +445,7 @@ bool ClientlessTravelMgr::StartTravel(Player* player, Position const& target, bo
|
||||
record.Status.MapId = player->GetMapId();
|
||||
record.Status.Target = target;
|
||||
record.AllowGroundMount = allowGroundMount;
|
||||
record.PortalApproach = portalApproach;
|
||||
|
||||
LaunchPath(player, record);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class TC_GAME_API ClientlessTravelMgr
|
||||
public:
|
||||
static ClientlessTravelMgr* instance();
|
||||
|
||||
bool StartTravel(Player* player, Position const& target, bool allowGroundMount = false);
|
||||
bool StartTravel(Player* player, Position const& target, bool allowGroundMount = false, bool portalApproach = false);
|
||||
bool AnalyzePath(Player* player, Position const& target, ClientlessPathDiagnostics& diagnostics) const;
|
||||
void CancelTravel(uint32 characterGuid);
|
||||
ClientlessTravelStatus const* GetStatus(uint32 characterGuid) const;
|
||||
@@ -76,6 +76,8 @@ private:
|
||||
uint32 CheckTimerMs = 0;
|
||||
std::vector<Position> ActiveSpline;
|
||||
bool AllowGroundMount = false;
|
||||
// VCORE_VIRTUAL_EDGE_V11_PORTAL_APPROACH: only actual portal source steps.
|
||||
bool PortalApproach = false;
|
||||
};
|
||||
|
||||
bool LaunchPath(Player* player, TravelRecord& record);
|
||||
|
||||
Reference in new issue
Block a user