< Summary

Information
Class: Trailblazer.Pathing.HybridRoutePlanner
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Hybrid/HybridRoutePlanner.cs
Line coverage
96%
Covered lines: 405
Uncovered lines: 14
Coverable lines: 419
Total lines: 711
Line coverage: 96.6%
Branch coverage
84%
Covered branches: 137
Total branches: 162
Branch coverage: 84.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Hybrid/HybridRoutePlanner.cs

#LineLine coverage
 1using FixedMathSharp;
 2using SwiftCollections;
 3using System;
 4using System.Diagnostics.CodeAnalysis;
 5
 6namespace Trailblazer.Pathing;
 7
 8internal static class HybridRoutePlanner
 9{
 10    public static bool TryPlan(HybridPathRequest request, [NotNullWhen(true)] out HybridRoutePlan? plan)
 11    {
 10312        plan = null;
 10313        if (request == null || !request.HasValidEndpoints)
 114            return false;
 15
 10216        if (TryPlanDirect(request, out HybridRoutePlan? directPlan))
 17        {
 2718            plan = directPlan;
 2719            return true;
 20        }
 21
 7522        HybridRoutePlan? singleTransitionPlan = GetBetterPlan(
 7523            TryPlanSingleTransitionLocally(request),
 7524            TryPlanSingleTransitionGlobal(request));
 7525        if (singleTransitionPlan != null)
 26        {
 3827            plan = singleTransitionPlan;
 3828            return true;
 29        }
 30
 3731        HybridRoutePlan? transitionPairPlan = GetBetterPlan(
 3732            TryPlanTransitionPairLocally(request),
 3733            TryPlanGlobalTransitionPairs(request));
 34
 3735        if (transitionPairPlan != null)
 36        {
 2937            plan = transitionPairPlan;
 2938            return true;
 39        }
 40
 841        HybridRoutePlan? climbTransitionChainPlan = GetBetterPlan(
 842            TryPlanChainedClimbTransitions(request, GetLocalDirectedClimbTransitions(request)),
 843            TryPlanChainedClimbTransitions(request, TraversalTransitionQuery.GetDirectedTransitions(TraversalTransitionT
 844        if (climbTransitionChainPlan != null)
 45        {
 346            plan = climbTransitionChainPlan;
 347            return true;
 48        }
 49
 550        return false;
 51    }
 52
 53    private static bool TryPlanDirect(HybridPathRequest request, [NotNullWhen(true)] out HybridRoutePlan? plan)
 54    {
 10255        plan = null;
 56
 10257        if (!TryCreateChartStep(
 10258            request.Origin,
 10259            request.TargetPosition,
 10260            request,
 10261            out HybridRouteStep? step,
 10262            out int chartCost))
 63        {
 7564            return false;
 65        }
 66
 2767        plan = new HybridRoutePlan(new[] { step! }, Array.Empty<TraversalTransition>(), chartCost);
 2768        return true;
 69    }
 70
 71    private static HybridRoutePlan? TryPlanSingleTransitionLocally(HybridPathRequest request)
 72    {
 7573        if (request.StartNode == null || request.EndNode == null)
 074            return null;
 75
 7576        HybridRoutePlan? bestPlan = null;
 7577        int startGridIndex = request.StartNode.GridIndex;
 7578        int endGridIndex = request.EndNode.GridIndex;
 79
 7580        if (TryPlanSingleTransition(
 7581            request,
 7582            TraversalTransitionQuery.GetDirectedTransitionsFromSourceGrid(
 7583                startGridIndex,
 7584                TraversalMedium.Solid,
 7585                TraversalMedium.Solid),
 7586            out HybridRoutePlan? startGridPlan))
 87        {
 3888            bestPlan = GetBetterPlan(bestPlan, startGridPlan);
 89        }
 90
 7591        if (startGridIndex != endGridIndex
 7592            && TryPlanSingleTransition(
 7593                request,
 7594                TraversalTransitionQuery.GetDirectedTransitionsToDestinationGrid(
 7595                    endGridIndex,
 7596                    TraversalMedium.Solid,
 7597                    TraversalMedium.Solid),
 7598                out HybridRoutePlan? endGridPlan))
 99        {
 1100            bestPlan = GetBetterPlan(bestPlan, endGridPlan);
 101        }
 102
 75103        return bestPlan;
 104    }
 105
 106    private static HybridRoutePlan? TryPlanSingleTransitionGlobal(HybridPathRequest request)
 107    {
 75108        return TryPlanSingleTransition(
 75109            request,
 75110            TraversalTransitionQuery.GetDirectedTransitions(
 75111                TraversalMedium.Solid,
 75112                TraversalMedium.Solid),
 75113            out HybridRoutePlan? plan)
 75114            ? plan
 75115            : null;
 116    }
 117
 118    private static bool TryPlanSingleTransition(
 119        HybridPathRequest request,
 120        TraversalTransition[] transitions,
 121        [NotNullWhen(true)] out HybridRoutePlan? plan)
 122    {
 151123        plan = null;
 151124        HybridRoutePlan? bestPlan = null;
 151125        if (transitions == null || transitions.Length == 0)
 68126            return false;
 127
 440128        for (int i = 0; i < transitions.Length; i++)
 129        {
 137130            TraversalTransition transition = transitions[i];
 137131            if (!TryCreateChartStep(
 137132                request.Origin,
 137133                transition.Source.Position,
 137134                request,
 137135                out HybridRouteStep? toTransitionStep,
 137136                out int toTransitionCost))
 137            {
 138                continue;
 139            }
 140
 95141            if (!TryCreateChartStep(
 95142                transition.Destination.Position,
 95143                request.TargetPosition,
 95144                request,
 95145                out HybridRouteStep? toTargetStep,
 95146                out int toTargetCost))
 147            {
 148                continue;
 149            }
 150
 77151            var candidate = new HybridRoutePlan(
 77152                new[]
 77153                {
 77154                    toTransitionStep!,
 77155                    HybridRouteStep.Waypoint(request.Context, transition.Destination.Position, transition.PathCostModifi
 77156                    toTargetStep!
 77157                },
 77158                new[] { transition },
 77159                toTransitionCost + transition.PathCostModifier + toTargetCost);
 160
 77161            bestPlan = GetBetterPlan(bestPlan, candidate);
 162        }
 163
 83164        plan = bestPlan;
 83165        return plan != null;
 166    }
 167
 168    private static HybridRoutePlan? TryPlanTransitionPairLocally(HybridPathRequest request)
 169    {
 37170        if (request.StartNode == null || request.EndNode == null)
 0171            return null;
 172
 37173        HybridRoutePlan? bestPlan = null;
 174
 37175        HybridRoutePlan? gasPlan = TryPlanTransitionPairForMedium(
 37176            request,
 37177            TraversalMedium.Gas,
 37178            TraversalTransitionQuery.GetDirectedTransitionsFromSourceGrid(
 37179                request.StartNode.GridIndex,
 37180                TraversalMedium.Solid,
 37181                TraversalMedium.Gas),
 37182            TraversalTransitionQuery.GetDirectedTransitionsToDestinationGrid(
 37183                request.EndNode.GridIndex,
 37184                TraversalMedium.Gas,
 37185                TraversalMedium.Solid));
 37186        bestPlan = GetBetterPlan(bestPlan, gasPlan);
 187
 37188        HybridRoutePlan? liquidPlan = TryPlanTransitionPairForMedium(
 37189            request,
 37190            TraversalMedium.Liquid,
 37191            TraversalTransitionQuery.GetDirectedTransitionsFromSourceGrid(
 37192                request.StartNode.GridIndex,
 37193                TraversalMedium.Solid,
 37194                TraversalMedium.Liquid),
 37195            TraversalTransitionQuery.GetDirectedTransitionsToDestinationGrid(
 37196                request.EndNode.GridIndex,
 37197                TraversalMedium.Liquid,
 37198                TraversalMedium.Solid));
 37199        bestPlan = GetBetterPlan(bestPlan, liquidPlan);
 200
 37201        return bestPlan;
 202    }
 203
 204    private static HybridRoutePlan? TryPlanGlobalTransitionPairs(HybridPathRequest request)
 205    {
 37206        HybridRoutePlan? bestPlan = null;
 207
 37208        bestPlan = GetBetterPlan(
 37209            bestPlan,
 37210            TryPlanTransitionPairForMedium(
 37211                request,
 37212                TraversalMedium.Gas,
 37213                TraversalTransitionQuery.GetDirectedTransitions(
 37214                    TraversalMedium.Solid,
 37215                    TraversalMedium.Gas),
 37216                TraversalTransitionQuery.GetDirectedTransitions(
 37217                    TraversalMedium.Gas,
 37218                    TraversalMedium.Solid)));
 219
 37220        bestPlan = GetBetterPlan(
 37221            bestPlan,
 37222            TryPlanTransitionPairForMedium(
 37223                request,
 37224                TraversalMedium.Liquid,
 37225                TraversalTransitionQuery.GetDirectedTransitions(
 37226                    TraversalMedium.Solid,
 37227                    TraversalMedium.Liquid),
 37228                TraversalTransitionQuery.GetDirectedTransitions(
 37229                    TraversalMedium.Liquid,
 37230                    TraversalMedium.Solid)));
 231
 37232        return bestPlan;
 233    }
 234
 235    private static HybridRoutePlan? TryPlanTransitionPairForMedium(
 236        HybridPathRequest request,
 237        TraversalMedium volumeMedium,
 238        TraversalTransition[] entries,
 239        TraversalTransition[] exits)
 240    {
 148241        return TryPlanTransitionPair(request, volumeMedium, entries, exits, out HybridRoutePlan? plan)
 148242            ? plan
 148243            : null;
 244    }
 245
 246    private static bool TryPlanTransitionPair(
 247        HybridPathRequest request,
 248        TraversalMedium volumeMedium,
 249        TraversalTransition[] entries,
 250        TraversalTransition[] exits,
 251        [NotNullWhen(true)] out HybridRoutePlan? plan)
 252    {
 148253        plan = null;
 148254        HybridRoutePlan? bestPlan = null;
 148255        if (entries == null
 148256            || exits == null
 148257            || entries.Length == 0
 148258            || exits.Length == 0)
 259        {
 88260            return false;
 261        }
 262
 240263        for (int i = 0; i < entries.Length; i++)
 264        {
 60265            TraversalTransition entry = entries[i];
 60266            if (!TryCreateChartStep(
 60267                request.Origin,
 60268                entry.Source.Position,
 60269                request,
 60270                out HybridRouteStep? toEntryStep,
 60271                out int toEntryCost))
 272            {
 273                continue;
 274            }
 275
 240276            for (int j = 0; j < exits.Length; j++)
 277            {
 60278                TraversalTransition exit = exits[j];
 60279                if (!TryCreateVolumeStep(
 60280                    entry.Destination.Position,
 60281                    exit.Source.Position,
 60282                    request,
 60283                    volumeMedium,
 60284                    out HybridRouteStep? volumeStep,
 60285                    out int volumeCost))
 286                {
 287                    continue;
 288                }
 289
 60290                if (!TryCreateChartStep(
 60291                    exit.Destination.Position,
 60292                    request.TargetPosition,
 60293                    request,
 60294                    out HybridRouteStep? toTargetStep,
 60295                    out int toTargetCost))
 296                {
 297                    continue;
 298                }
 299
 60300                var candidate = new HybridRoutePlan(
 60301                    new[]
 60302                    {
 60303                        toEntryStep!,
 60304                        HybridRouteStep.Waypoint(request.Context, entry.Destination.Position, entry.PathCostModifier),
 60305                        volumeStep!,
 60306                        HybridRouteStep.Waypoint(request.Context, exit.Destination.Position, exit.PathCostModifier),
 60307                        toTargetStep!
 60308                    },
 60309                    new[] { entry, exit },
 60310                    toEntryCost + entry.PathCostModifier + volumeCost + exit.PathCostModifier + toTargetCost);
 311
 60312                bestPlan = GetBetterPlan(bestPlan, candidate);
 313            }
 314        }
 315
 60316        plan = bestPlan;
 60317        return plan != null;
 318    }
 319
 320    private static bool TryCreateChartStep(
 321        Vector3d origin,
 322        Vector3d destination,
 323        HybridPathRequest request,
 324        [NotNullWhen(true)] out HybridRouteStep? step,
 325        out int pathCost)
 326    {
 790327        if (request.ChartRequestKind == HybridChartRequestKind.FlowField)
 328        {
 189329            return TryCreateFlowFieldStep(
 189330                origin,
 189331                destination,
 189332                request,
 189333                out step,
 189334                out pathCost);
 335        }
 336
 601337        return TryCreateAStarStep(
 601338            origin,
 601339            destination,
 601340            request,
 601341            out step,
 601342            out pathCost);
 343    }
 344
 345    private static bool TryCreateAStarStep(
 346        Vector3d origin,
 347        Vector3d destination,
 348        HybridPathRequest request,
 349        [NotNullWhen(true)] out HybridRouteStep? step,
 350        out int pathCost)
 351    {
 602352        step = null;
 602353        pathCost = 0;
 354
 602355        AStarPathRequest? chartRequest = AStarPathRequest.Create(
 602356            request.Context,
 602357            origin,
 602358            destination,
 602359            request.UnitSize,
 602360            request.Heuristic,
 602361            request.AllowUnwalkableEndpoints);
 602362        if (chartRequest == null)
 1363            return false;
 364
 601365        chartRequest.MaxClimbHeight = request.MaxClimbHeight;
 366
 601367        if (chartRequest.HasZeroDisplacement)
 368        {
 245369            step = HybridRouteStep.Waypoint(request.Context, destination);
 245370            return true;
 371        }
 372
 356373        AStarSurveyResult surveyResult = request.Context.Pathing.State.GuideState.AStarSurveyor.FindPath(chartRequest);
 356374        if (!surveyResult.HasPath)
 272375            return false;
 376
 84377        pathCost = surveyResult.Waypoints[^1].PathCost;
 84378        step = HybridRouteStep.Segment(chartRequest, chartKeys: surveyResult.ChartsUtilized);
 84379        return true;
 380    }
 381
 382    private static bool TryCreateFlowFieldStep(
 383        Vector3d origin,
 384        Vector3d destination,
 385        HybridPathRequest request,
 386        [NotNullWhen(true)] out HybridRouteStep? step,
 387        out int pathCost)
 388    {
 190389        step = null;
 190390        pathCost = 0;
 391
 190392        FlowFieldPathRequest? chartRequest = FlowFieldPathRequest.Create(
 190393            request.Context,
 190394            origin,
 190395            destination,
 190396            request.UnitSize,
 190397            request.AllowUnwalkableEndpoints);
 190398        if (chartRequest == null)
 1399            return false;
 400
 189401        chartRequest.MaxClimbHeight = request.MaxClimbHeight;
 189402        chartRequest.ExtraFloodRange = request.ExtraFloodRange;
 403
 189404        if (chartRequest.HasZeroDisplacement)
 405        {
 21406            step = HybridRouteStep.Waypoint(request.Context, destination);
 21407            return true;
 408        }
 409
 168410        FlowFieldSurveyResult surveyResult = request.Context.Pathing.State.GuideState.FlowFieldSurveyor.FindPath(chartRe
 168411        if (!surveyResult.HasPath
 168412            || surveyResult.Fields == null
 168413            || chartRequest.StartNode == null
 168414            || !surveyResult.Fields.TryGetValue(chartRequest.StartNode.WorldIndex, out FlowField startField))
 415        {
 115416            return false;
 417        }
 418
 53419        pathCost = startField.PathCost;
 53420        step = HybridRouteStep.Segment(chartRequest, chartKeys: surveyResult.ChartsUtilized);
 53421        return true;
 422    }
 423
 424    private static bool TryCreateVolumeStep(
 425        Vector3d origin,
 426        Vector3d destination,
 427        HybridPathRequest request,
 428        TraversalMedium medium,
 429        [NotNullWhen(true)] out HybridRouteStep? step,
 430        out int pathCost)
 431    {
 63432        step = null;
 63433        pathCost = 0;
 434
 63435        VolumePathRequest? volumeRequest = VolumePathRequest.Create(
 63436            request.Context,
 63437            origin,
 63438            destination,
 63439            request.UnitSize,
 63440            request.Heuristic,
 63441            request.AllowUnwalkableEndpoints,
 63442            medium);
 63443        if (volumeRequest == null)
 1444            return false;
 445
 62446        if (volumeRequest.HasZeroDisplacement)
 447        {
 1448            step = HybridRouteStep.Waypoint(request.Context, destination);
 1449            return true;
 450        }
 451
 61452        VolumeSurveyResult surveyResult = request.Context.Pathing.State.GuideState.VolumeSurveyor.FindPath(volumeRequest
 61453        if (!surveyResult.HasPath)
 1454            return false;
 455
 60456        pathCost = surveyResult.Waypoints![^1].PathCost;
 60457        step = HybridRouteStep.Segment(volumeRequest, chartKeys: surveyResult.ChartsUtilized);
 60458        return true;
 459    }
 460
 461    private static HybridRoutePlan? GetBetterPlan(HybridRoutePlan? current, HybridRoutePlan? candidate)
 462    {
 444463        if (candidate == null)
 138464            return current;
 465
 306466        if (current == null || candidate.TotalPathCost < current.TotalPathCost)
 235467            return candidate;
 468
 71469        return current;
 470    }
 471
 472    private static HybridRoutePlan? TryPlanChainedClimbTransitions(
 473        HybridPathRequest request,
 474        TraversalTransition[] transitions)
 475    {
 16476        if (transitions == null || transitions.Length == 0)
 10477            return null;
 478
 6479        int[] bestCosts = new int[transitions.Length];
 6480        int[] previousIndices = new int[transitions.Length];
 6481        HybridRouteStep?[] entrySteps = new HybridRouteStep?[transitions.Length];
 6482        HybridRouteStep?[] bridgeSteps = new HybridRouteStep?[transitions.Length];
 6483        bool[] visited = new bool[transitions.Length];
 484
 132485        for (int i = 0; i < transitions.Length; i++)
 486        {
 60487            bestCosts[i] = int.MaxValue;
 60488            previousIndices[i] = -1;
 489
 60490            if (!TryCreateChartStep(
 60491                request.Origin,
 60492                transitions[i].Source.Position,
 60493                request,
 60494                out HybridRouteStep? entryStep,
 60495                out int entryCost))
 496            {
 497                continue;
 498            }
 499
 18500            entrySteps[i] = entryStep;
 18501            bestCosts[i] = entryCost + transitions[i].PathCostModifier;
 502        }
 503
 6504        int bestEndIndex = -1;
 6505        HybridRouteStep? bestExitStep = null;
 6506        int bestTotalCost = int.MaxValue;
 507
 60508        while (true)
 509        {
 66510            int currentIndex = GetCheapestUnvisitedTransition(bestCosts, visited);
 66511            if (currentIndex < 0)
 512                break;
 513
 60514            visited[currentIndex] = true;
 60515            TraversalTransition currentTransition = transitions[currentIndex];
 60516            int currentCost = bestCosts[currentIndex];
 517
 60518            if (TryCreateChartStep(
 60519                currentTransition.Destination.Position,
 60520                request.TargetPosition,
 60521                request,
 60522                out HybridRouteStep? exitStep,
 60523                out int exitCost))
 524            {
 6525                int totalCost = currentCost + exitCost;
 6526                if (totalCost < bestTotalCost)
 527                {
 6528                    bestTotalCost = totalCost;
 6529                    bestEndIndex = currentIndex;
 6530                    bestExitStep = exitStep;
 531                }
 532            }
 533
 1320534            for (int nextIndex = 0; nextIndex < transitions.Length; nextIndex++)
 535            {
 600536                if (visited[nextIndex])
 537                    continue;
 538
 270539                HybridRouteStep? bridgeStep = null;
 270540                int bridgeCost = 0;
 270541                if (transitions[nextIndex].Source.Position != currentTransition.Destination.Position
 270542                    && !TryCreateChartStep(
 270543                        currentTransition.Destination.Position,
 270544                        transitions[nextIndex].Source.Position,
 270545                        request,
 270546                        out bridgeStep,
 270547                        out bridgeCost))
 548                {
 549                    continue;
 550                }
 551
 114552                int candidateCost = currentCost + bridgeCost + transitions[nextIndex].PathCostModifier;
 114553                if (candidateCost >= bestCosts[nextIndex])
 554                    continue;
 555
 74556                bestCosts[nextIndex] = candidateCost;
 74557                previousIndices[nextIndex] = currentIndex;
 74558                bridgeSteps[nextIndex] = bridgeStep;
 559            }
 560        }
 561
 6562        if (bestEndIndex < 0 || bestExitStep == null)
 0563            return null;
 564
 6565        return BuildChainedClimbPlan(
 6566            request.Context,
 6567            transitions,
 6568            previousIndices,
 6569            entrySteps,
 6570            bridgeSteps,
 6571            bestEndIndex,
 6572            bestExitStep,
 6573            bestTotalCost);
 574    }
 575
 576    private static TraversalTransition[] GetLocalDirectedClimbTransitions(HybridPathRequest request)
 577    {
 8578        if (request?.StartNode == null || request.EndNode == null)
 0579            return Array.Empty<TraversalTransition>();
 580
 8581        int startGridIndex = request.StartNode.GridIndex;
 8582        int endGridIndex = request.EndNode.GridIndex;
 8583        SwiftList<TraversalTransition> climbTransitions = new();
 8584        SwiftHashSet<string> seenTransitionIds = new();
 585
 8586        AddTransitions(
 8587            climbTransitions,
 8588            seenTransitionIds,
 8589            TraversalTransitionQuery.GetDirectedTransitionsFromSourceGrid(
 8590                startGridIndex,
 8591                TraversalTransitionType.Climb));
 592
 8593        TraversalTransition[] destinationTransitions = FilterTransitionsByType(
 8594            TraversalTransitionQuery.GetDirectedTransitionsToDestinationGrid(endGridIndex),
 8595            TraversalTransitionType.Climb);
 8596        AddTransitions(climbTransitions, seenTransitionIds, destinationTransitions);
 597
 8598        if (startGridIndex != endGridIndex)
 599        {
 0600            AddTransitions(
 0601                climbTransitions,
 0602                seenTransitionIds,
 0603                TraversalTransitionQuery.GetDirectedTransitionsFromSourceGrid(
 0604                    endGridIndex,
 0605                    TraversalTransitionType.Climb));
 606
 0607            TraversalTransition[] originDestinationTransitions = FilterTransitionsByType(
 0608                TraversalTransitionQuery.GetDirectedTransitionsToDestinationGrid(startGridIndex),
 0609                TraversalTransitionType.Climb);
 0610            AddTransitions(climbTransitions, seenTransitionIds, originDestinationTransitions);
 611        }
 612
 8613        return climbTransitions.Count == 0
 8614            ? Array.Empty<TraversalTransition>()
 8615            : climbTransitions.ToArray();
 616    }
 617
 618    private static TraversalTransition[] FilterTransitionsByType(
 619        TraversalTransition[] transitions,
 620        TraversalTransitionType type)
 621    {
 8622        if (transitions == null || transitions.Length == 0)
 5623            return Array.Empty<TraversalTransition>();
 624
 3625        SwiftList<TraversalTransition> climbTransitions = new();
 66626        for (int i = 0; i < transitions.Length; i++)
 627        {
 30628            if (transitions[i].Type == type)
 30629                climbTransitions.Add(transitions[i]);
 630        }
 631
 3632        return climbTransitions.Count == 0
 3633            ? Array.Empty<TraversalTransition>()
 3634            : climbTransitions.ToArray();
 635    }
 636
 637    private static void AddTransitions(
 638        SwiftList<TraversalTransition> destination,
 639        SwiftHashSet<string> seenTransitionIds,
 640        TraversalTransition[] source)
 641    {
 16642        if (source == null || source.Length == 0)
 10643            return;
 644
 132645        for (int i = 0; i < source.Length; i++)
 646        {
 60647            TraversalTransition transition = source[i];
 60648            if (seenTransitionIds.Add(transition.Id))
 30649                destination.Add(transition);
 650        }
 6651    }
 652
 653    private static int GetCheapestUnvisitedTransition(int[] bestCosts, bool[] visited)
 654    {
 66655        int bestIndex = -1;
 66656        int bestCost = int.MaxValue;
 1452657        for (int i = 0; i < bestCosts.Length; i++)
 658        {
 660659            if (visited[i] || bestCosts[i] >= bestCost)
 660                continue;
 661
 66662            bestCost = bestCosts[i];
 66663            bestIndex = i;
 664        }
 665
 66666        return bestIndex;
 667    }
 668
 669    private static HybridRoutePlan BuildChainedClimbPlan(
 670        TrailblazerWorldContext context,
 671        TraversalTransition[] transitions,
 672        int[] previousIndices,
 673        HybridRouteStep?[] entrySteps,
 674        HybridRouteStep?[] bridgeSteps,
 675        int endIndex,
 676        HybridRouteStep exitStep,
 677        int totalCost)
 678    {
 6679        SwiftList<int> reversedTransitionIndices = new();
 60680        for (int index = endIndex; index >= 0; index = previousIndices[index])
 24681            reversedTransitionIndices.Add(index);
 682
 6683        int transitionCount = reversedTransitionIndices.Count;
 6684        var orderedTransitions = new TraversalTransition[transitionCount];
 6685        var steps = new SwiftList<HybridRouteStep>();
 686
 6687        int startTransitionIndex = reversedTransitionIndices[transitionCount - 1];
 6688        steps.Add(entrySteps[startTransitionIndex]!);
 689
 6690        int orderedIndex = 0;
 60691        for (int i = transitionCount - 1; i >= 0; i--)
 692        {
 24693            int transitionIndex = reversedTransitionIndices[i];
 24694            TraversalTransition transition = transitions[transitionIndex];
 24695            orderedTransitions[orderedIndex] = transition;
 696
 24697            if (orderedIndex > 0 && bridgeSteps[transitionIndex] != null)
 2698                steps.Add(bridgeSteps[transitionIndex]!);
 699
 24700            steps.Add(HybridRouteStep.Waypoint(
 24701                context,
 24702                transition.Destination.Position,
 24703                transition.PathCostModifier));
 24704            orderedIndex++;
 705        }
 706
 6707        steps.Add(exitStep);
 6708        return new HybridRoutePlan(steps.ToArray(), orderedTransitions, totalCost);
 709    }
 710
 711}

Methods/Properties

TryPlan(Trailblazer.Pathing.HybridPathRequest,Trailblazer.Pathing.HybridRoutePlan&)
TryPlanDirect(Trailblazer.Pathing.HybridPathRequest,Trailblazer.Pathing.HybridRoutePlan&)
TryPlanSingleTransitionLocally(Trailblazer.Pathing.HybridPathRequest)
TryPlanSingleTransitionGlobal(Trailblazer.Pathing.HybridPathRequest)
TryPlanSingleTransition(Trailblazer.Pathing.HybridPathRequest,Trailblazer.Pathing.TraversalTransition[],Trailblazer.Pathing.HybridRoutePlan&)
TryPlanTransitionPairLocally(Trailblazer.Pathing.HybridPathRequest)
TryPlanGlobalTransitionPairs(Trailblazer.Pathing.HybridPathRequest)
TryPlanTransitionPairForMedium(Trailblazer.Pathing.HybridPathRequest,Trailblazer.TraversalMedium,Trailblazer.Pathing.TraversalTransition[],Trailblazer.Pathing.TraversalTransition[])
TryPlanTransitionPair(Trailblazer.Pathing.HybridPathRequest,Trailblazer.TraversalMedium,Trailblazer.Pathing.TraversalTransition[],Trailblazer.Pathing.TraversalTransition[],Trailblazer.Pathing.HybridRoutePlan&)
TryCreateChartStep(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Trailblazer.Pathing.HybridPathRequest,Trailblazer.Pathing.HybridRouteStep&,System.Int32&)
TryCreateAStarStep(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Trailblazer.Pathing.HybridPathRequest,Trailblazer.Pathing.HybridRouteStep&,System.Int32&)
TryCreateFlowFieldStep(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Trailblazer.Pathing.HybridPathRequest,Trailblazer.Pathing.HybridRouteStep&,System.Int32&)
TryCreateVolumeStep(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Trailblazer.Pathing.HybridPathRequest,Trailblazer.TraversalMedium,Trailblazer.Pathing.HybridRouteStep&,System.Int32&)
GetBetterPlan(Trailblazer.Pathing.HybridRoutePlan,Trailblazer.Pathing.HybridRoutePlan)
TryPlanChainedClimbTransitions(Trailblazer.Pathing.HybridPathRequest,Trailblazer.Pathing.TraversalTransition[])
GetLocalDirectedClimbTransitions(Trailblazer.Pathing.HybridPathRequest)
FilterTransitionsByType(Trailblazer.Pathing.TraversalTransition[],Trailblazer.Pathing.TraversalTransitionType)
AddTransitions(SwiftCollections.SwiftList`1<Trailblazer.Pathing.TraversalTransition>,SwiftCollections.SwiftHashSet`1<System.String>,Trailblazer.Pathing.TraversalTransition[])
GetCheapestUnvisitedTransition(System.Int32[],System.Boolean[])
BuildChainedClimbPlan(Trailblazer.TrailblazerWorldContext,Trailblazer.Pathing.TraversalTransition[],System.Int32[],Trailblazer.Pathing.HybridRouteStep[],Trailblazer.Pathing.HybridRouteStep[],System.Int32,Trailblazer.Pathing.HybridRouteStep,System.Int32)