refactor(Core/Travel): Drop TravelPlan struct; GetFullPath returns TravelPath

This commit is contained in:
bash 2026-05-30 22:56:48 +02:00
parent 7d507a6922
commit f7df64e4c2
5 changed files with 20 additions and 76 deletions

View File

@ -3069,11 +3069,7 @@ TravelPath MovementAction::ResolveMovePath(WorldPosition const& startPos,
if (needsLongPath && !sTravelNodeMap.getNodes().empty() && !bot->InBattleground())
{
// Wrap the legacy TravelPlan-populating call; the steps field on
// TravelPlan IS a TravelPath, so extract it directly.
TravelPlan tmp;
if (sTravelNodeMap.GetFullPath(tmp, startPos, bot->GetZoneId(), endPos, bot))
out = tmp.steps;
out = sTravelNodeMap.GetFullPath(startPos, bot->GetZoneId(), endPos, bot);
}
else
{

View File

@ -77,7 +77,6 @@ void NewRpgInfo::Reset()
{
data = Idle{};
startT = getMSTime();
ClearTravel();
}
NewRpgStatus NewRpgInfo::GetStatus()

View File

@ -78,11 +78,6 @@ struct NewRpgInfo
uint32 startT{0}; // start timestamp of the current status
// Travel Node System
TravelPlan travelPlan;
bool HasActiveTravelPlan() const { return travelPlan.IsActive(); }
void ClearTravel() { travelPlan.Reset(); }
using RpgData = std::variant<
Idle,
GoGrind,

View File

@ -1512,23 +1512,10 @@ TravelNodeRoute TravelNodeMap::FindRouteNearestNodes(WorldPosition startPos, Wor
return TravelNodeRoute();
}
bool TravelNodeMap::GetFullPath(TravelPlan& plan,
WorldPosition botPos, uint32 botZoneId,
TravelPath TravelNodeMap::GetFullPath(WorldPosition botPos, uint32 botZoneId,
WorldPosition destination, Unit* bot)
{
// Capture previous pathToStart from the about-to-be-reset plan so we
// can try cropPathTo to reuse it across the per-tick re-resolve.
std::vector<WorldPosition> prevPathToStart;
for (auto const& pt : plan.steps.GetPathRef())
{
if (pt.type == PathNodeType::NODE_PREPATH)
prevPathToStart.push_back(pt.point);
else
break; // PREPATH is always at the head
}
plan.Reset();
plan.destination = destination;
TravelPath path;
// mmap-probe first: if a 40-step probe makes meaningful progress,
// prefer it over the graph. Loosened from "reaches within spellDistance"
@ -1556,10 +1543,10 @@ bool TravelNodeMap::GetFullPath(TravelPlan& plan,
if (closeEnough || meaningfulProgress)
{
plan.steps.addPoint(botPos, PathNodeType::NODE_PREPATH);
path.addPoint(botPos, PathNodeType::NODE_PREPATH);
for (size_t i = 1; i < probe.size(); ++i)
plan.steps.addPoint(probe[i], PathNodeType::NODE_PATH);
return true;
path.addPoint(probe[i], PathNodeType::NODE_PATH);
return path;
}
}
}
@ -1595,7 +1582,7 @@ bool TravelNodeMap::GetFullPath(TravelPlan& plan,
std::vector<TravelNode*> endCandidates = pickKNearest(destination, destZone);
if (startCandidates.empty() || endCandidates.empty())
return false;
return path; // empty
TravelNode* startNode = nullptr;
TravelNode* endNode = nullptr;
@ -1621,24 +1608,14 @@ bool TravelNodeMap::GetFullPath(TravelPlan& plan,
}
if (route.isEmpty() || !startNode || !endNode)
return false;
return path; // empty
WorldPosition startNodePos = *startNode->getPosition();
WorldPosition endNodePos = *endNode->getPosition();
// pathToStart: mmap-path from bot to the first node. Try cropping
// the previous pathToStart first (cmangos parity) — if it still
// reaches the chosen startNode within reactDistance we avoid a full
// re-probe. Falls back to fresh getPathTo if crop fails or invalid.
// pathToStart: fresh mmap-path from bot to the first node.
std::vector<WorldPosition> pathToStart;
if (!prevPathToStart.empty())
{
std::vector<WorldPosition> cropped = prevPathToStart;
bool ok = startNodePos.cropPathTo(cropped, sPlayerbotAIConfig.reactDistance);
if (ok && cropped.size() >= 2)
pathToStart = cropped;
}
if (pathToStart.empty() && bot && botPos.GetMapId() == startNodePos.GetMapId())
if (bot && botPos.GetMapId() == startNodePos.GetMapId())
{
std::vector<WorldPosition> probe = botPos.getPathTo(startNodePos, bot);
if (probe.size() >= 2)
@ -1663,9 +1640,9 @@ bool TravelNodeMap::GetFullPath(TravelPlan& plan,
if (pathToEnd.empty())
pathToEnd = {destination};
plan.steps = route.BuildPath(pathToStart, pathToEnd, nullptr);
path = route.BuildPath(pathToStart, pathToEnd, nullptr);
return !plan.steps.empty();
return path;
}
bool TravelNodeMap::cropUselessNode(TravelNode* startNode)

View File

@ -68,7 +68,9 @@
//
// GetFullPath finds nearest nodes (zone-indexed), runs A* to get a node route, then
// BuildPath assembles a flat TravelPath with typed waypoints (walk, portal, transport, flight).
// ExecuteTravelPlan iterates the path by stepIdx, dispatching on each point's PathNodeType.
// MoveFarTo re-resolves a fresh TravelPath each tick; UpcommingSpecialMovement cuts
// to the head segment when special; HandleSpecialMovement dispatches the matching
// action (portal interact, area-trigger marker, transport board, flight taxi).
// Cross-map travel is handled naturally by portal/transport edges in the A* graph.
//
// If setup cannot resolve (no node, no route, no flight), the bot teleports directly to the destination
@ -585,34 +587,6 @@ public:
uint32 currentGold = 0;
};
struct TravelPlan
{
WorldPosition destination;
// Flat waypoint path built upfront by GetFullPath:
TravelPath steps;
uint32 stepIdx{0};
// Spline scratch (used by executor):
std::vector<G3D::Vector3> walkPoints;
uint32 expectedDuration{0}; // used to derive the lastMove delay
// Taxi scratch:
std::vector<uint32> route;
bool IsActive() const { return !steps.empty(); }
void Reset()
{
destination = WorldPosition();
steps.clear();
stepIdx = 0;
walkPoints.clear();
expectedDuration = 0;
route.clear();
}
};
// The container of all nodes.
class TravelNodeMap
{
@ -742,8 +716,11 @@ public:
// empty static vector for unknown zones.
std::vector<TravelNode*> const& GetNodesInZone(uint32 zoneId) const;
bool GetFullPath(TravelPlan& plan, WorldPosition botPos,
uint32 botZoneId, WorldPosition destination, Unit* bot = nullptr);
// Resolve a full TravelPath from botPos to destination. Returns an
// empty TravelPath if no graph route + mmap stitch is reachable;
// the caller is then expected to fall back to a single-point path.
TravelPath GetFullPath(WorldPosition botPos, uint32 botZoneId,
WorldPosition destination, Unit* bot = nullptr);
// Resolve A* route between two world positions (returns node vector)
std::vector<TravelNode*> ResolveRoute(WorldPosition startPos,