< Summary

Information
Class: Trailblazer.Navigation.Steering.PathRequestRecord
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Navigation/Steering/Serialization/PathRequestRecord.cs
Line coverage
98%
Covered lines: 155
Uncovered lines: 3
Coverable lines: 158
Total lines: 277
Line coverage: 98.1%
Branch coverage
89%
Covered branches: 59
Total branches: 66
Branch coverage: 89.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
Capture(...)100%1212100%
TryCreateRequest(...)81.81%2222100%
TryCreateGuide(...)100%1414100%
Reset()100%11100%
RecordData(...)100%11100%
RestoreWaypointIndex(...)83.33%6683.33%
RestoreWaypointIndex(...)83.33%6683.33%
RestoreWaypointIndex(...)83.33%6683.33%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Navigation/Steering/Serialization/PathRequestRecord.cs

#LineLine coverage
 1using Chronicler;
 2using FixedMathSharp;
 3using System;
 4using Trailblazer.Pathing;
 5
 6namespace Trailblazer.Navigation.Steering;
 7
 8internal enum PathRequestRecordKind
 9{
 10    None,
 11    AStar,
 12    FlowField,
 13    Volume,
 14    Hybrid
 15}
 16
 17/// <summary>
 18/// Stores a serializable path-request shape and rebuilds it on load.
 19/// </summary>
 20internal sealed class PathRequestRecord : IRecordable
 21{
 22    private const int NoWaypointIndex = -1;
 23
 24    public PathRequestRecordKind Kind;
 25
 26    public Vector3d Origin;
 27
 28    public Vector3d TargetPosition;
 29
 10130    public Fixed64 UnitSize = Fixed64.One;
 31
 32    public bool AllowUnwalkableEndpoints;
 33
 34    public bool AllowTraversalTransitions;
 35
 36    public int MaxPathSearchRange;
 37
 10138    public Fixed64 MaxClimbHeight = Fixed64.One;
 39
 40    public HeuristicMethod AStarHeuristic = HeuristicMethod.Manhattan;
 41
 10142    public int FlowFieldExtraFloodRange = FlowFieldPathRequest.DefaultExtraFloodRange;
 43
 10144    public TraversalMedium Medium = TraversalMedium.Gas;
 45
 46    public bool HasGuide;
 47
 10148    public int WaypointIndex = NoWaypointIndex;
 49
 50    public void Capture(IPathRequest? request, IGuide? guide)
 51    {
 5552        Reset();
 5553        if (request == null)
 1454            return;
 55
 4156        Origin = request.Origin;
 4157        TargetPosition = request.TargetPosition;
 4158        UnitSize = request.UnitSize;
 4159        AllowUnwalkableEndpoints = request.AllowUnwalkableEndpoints;
 4160        MaxPathSearchRange = request.MaxPathSearchRange;
 4161        HasGuide = guide != null;
 62
 63        switch (request)
 64        {
 65            case AStarPathRequest aStar:
 1966                Kind = PathRequestRecordKind.AStar;
 1967                AllowTraversalTransitions = aStar.AllowTraversalTransitions;
 1968                AStarHeuristic = aStar.Heuristic;
 1969                MaxClimbHeight = aStar.MaxClimbHeight;
 1970                break;
 71
 72            case FlowFieldPathRequest flowField:
 573                Kind = PathRequestRecordKind.FlowField;
 574                AllowTraversalTransitions = flowField.AllowTraversalTransitions;
 575                MaxClimbHeight = flowField.MaxClimbHeight;
 576                FlowFieldExtraFloodRange = flowField.ExtraFloodRange;
 577                break;
 78
 79            case VolumePathRequest volume:
 1480                Kind = PathRequestRecordKind.Volume;
 1481                AStarHeuristic = volume.Heuristic;
 1482                Medium = volume.Medium;
 1483                break;
 84
 85            case HybridPathRequest hybrid:
 286                Kind = PathRequestRecordKind.Hybrid;
 287                AStarHeuristic = hybrid.Heuristic;
 288                MaxClimbHeight = hybrid.MaxClimbHeight;
 289                break;
 90
 91            default:
 192                throw new NotSupportedException(
 193                    $"Unable to record steering path request type '{request.GetType().Name}'.");
 94        }
 95
 4096        if (guide is IWaypointGuide waypointGuide)
 1397            WaypointIndex = waypointGuide.CurrentWaypointIndex;
 4098    }
 99
 100    public bool TryCreateRequest(TrailblazerWorldContext context, out IPathRequest? request)
 101    {
 57102        request = null;
 57103        PathRequestContextResolver.ThrowIfUnusable(context);
 104
 57105        switch (Kind)
 106        {
 107            case PathRequestRecordKind.None:
 13108                return true;
 109
 110            case PathRequestRecordKind.AStar:
 20111                AStarPathRequest? aStar = AStarPathRequest.Create(
 20112                    context,
 20113                    Origin,
 20114                    TargetPosition,
 20115                    UnitSize,
 20116                    AStarHeuristic,
 20117                    AllowUnwalkableEndpoints,
 20118                    AllowTraversalTransitions);
 20119                if (aStar == null)
 4120                    return false;
 121
 16122                aStar.MaxClimbHeight = MaxClimbHeight;
 16123                if (MaxPathSearchRange > 0)
 16124                    aStar.MaxPathSearchRange = MaxPathSearchRange;
 125
 16126                request = aStar;
 16127                return true;
 128
 129            case PathRequestRecordKind.FlowField:
 5130                FlowFieldPathRequest? flowField = FlowFieldPathRequest.Create(
 5131                    context,
 5132                    Origin,
 5133                    TargetPosition,
 5134                    UnitSize,
 5135                    AllowUnwalkableEndpoints,
 5136                    AllowTraversalTransitions);
 5137                if (flowField == null)
 1138                    return false;
 139
 4140                flowField.MaxClimbHeight = MaxClimbHeight;
 4141                flowField.ExtraFloodRange = FlowFieldExtraFloodRange;
 4142                if (MaxPathSearchRange > 0)
 4143                    flowField.MaxPathSearchRange = MaxPathSearchRange;
 144
 4145                request = flowField;
 4146                return true;
 147
 148            case PathRequestRecordKind.Volume:
 15149                VolumePathRequest? volume = VolumePathRequest.Create(
 15150                    context,
 15151                    Origin,
 15152                    TargetPosition,
 15153                    UnitSize,
 15154                    AStarHeuristic,
 15155                    AllowUnwalkableEndpoints,
 15156                    Medium);
 15157                if (volume == null)
 1158                    return false;
 159
 14160                if (MaxPathSearchRange > 0)
 14161                    volume.MaxPathSearchRange = MaxPathSearchRange;
 162
 14163                request = volume;
 14164                return true;
 165
 166            case PathRequestRecordKind.Hybrid:
 3167                HybridPathRequest? hybrid = HybridPathRequest.Create(
 3168                    context,
 3169                    Origin,
 3170                    TargetPosition,
 3171                    UnitSize,
 3172                    AStarHeuristic,
 3173                    MaxClimbHeight,
 3174                    AllowUnwalkableEndpoints);
 3175                if (hybrid == null)
 1176                    return false;
 177
 2178                if (MaxPathSearchRange > 0)
 2179                    hybrid.MaxPathSearchRange = MaxPathSearchRange;
 180
 2181                request = hybrid;
 2182                return true;
 183
 184            default:
 1185                return false;
 186        }
 187    }
 188
 189    public bool TryCreateGuide(IPathRequest? request, out IGuide? guide)
 190    {
 17191        guide = null;
 17192        if (!HasGuide || request == null)
 1193            return false;
 194
 16195        if (!request.Context.Guides.RequestGuide(request, out guide) || guide == null)
 2196            return false;
 197
 14198        if (guide is AStarGuide aStarGuide)
 4199            RestoreWaypointIndex(aStarGuide);
 10200        else if (guide is VolumeGuide volumeGuide)
 5201            RestoreWaypointIndex(volumeGuide);
 5202        else if (guide is HybridGuide hybridGuide)
 1203            RestoreWaypointIndex(hybridGuide);
 204
 14205        return true;
 206    }
 207
 208    public void Reset()
 209    {
 59210        Kind = PathRequestRecordKind.None;
 59211        Origin = Vector3d.Zero;
 59212        TargetPosition = Vector3d.Zero;
 59213        UnitSize = Fixed64.One;
 59214        AllowUnwalkableEndpoints = false;
 59215        AllowTraversalTransitions = false;
 59216        MaxPathSearchRange = 0;
 59217        MaxClimbHeight = Fixed64.One;
 59218        AStarHeuristic = HeuristicMethod.Manhattan;
 59219        FlowFieldExtraFloodRange = FlowFieldPathRequest.DefaultExtraFloodRange;
 59220        Medium = TraversalMedium.Gas;
 59221        HasGuide = false;
 59222        WaypointIndex = NoWaypointIndex;
 59223    }
 224
 225    public void RecordData(IChronicler chronicler)
 226    {
 90227        RecordValues.Look(chronicler, ref Kind, "Kind", PathRequestRecordKind.None);
 90228        RecordValues.Look(chronicler, ref Origin, "Origin", Vector3d.Zero);
 90229        RecordValues.Look(chronicler, ref TargetPosition, "TargetPosition", Vector3d.Zero);
 90230        RecordValues.Look(chronicler, ref UnitSize, "UnitSize", Fixed64.One);
 90231        RecordValues.Look(chronicler, ref AllowUnwalkableEndpoints, "AllowUnwalkableEndpoints", false);
 90232        RecordValues.Look(chronicler, ref AllowTraversalTransitions, "AllowTraversalTransitions", false);
 90233        RecordValues.Look(chronicler, ref MaxPathSearchRange, "MaxPathSearchRange", 0);
 90234        RecordValues.Look(chronicler, ref MaxClimbHeight, "MaxClimbHeight", Fixed64.One);
 90235        RecordValues.Look(chronicler, ref AStarHeuristic, "AStarHeuristic", HeuristicMethod.Manhattan);
 90236        RecordValues.Look(chronicler, ref FlowFieldExtraFloodRange, "FlowFieldExtraFloodRange", FlowFieldPathRequest.Def
 90237        RecordValues.Look(chronicler, ref Medium, "Medium", TraversalMedium.Gas);
 90238        RecordValues.Look(chronicler, ref HasGuide, "HasGuide", false);
 90239        RecordValues.Look(chronicler, ref WaypointIndex, "WaypointIndex", NoWaypointIndex);
 90240    }
 241
 242    private void RestoreWaypointIndex(AStarGuide guide)
 243    {
 4244        if (WaypointIndex <= 0)
 0245            return;
 246
 12247        while (guide.CurrentWaypointIndex < WaypointIndex
 12248            && guide.TryGetWaypointAt(guide.CurrentWaypointIndex + 1, out _))
 249        {
 8250            guide.AdvanceWaypoint();
 251        }
 4252    }
 253
 254    private void RestoreWaypointIndex(VolumeGuide guide)
 255    {
 5256        if (WaypointIndex <= 0)
 0257            return;
 258
 12259        while (guide.CurrentWaypointIndex < WaypointIndex
 12260            && guide.TryGetWaypointAt(guide.CurrentWaypointIndex + 1, out _))
 261        {
 7262            guide.AdvanceWaypoint();
 263        }
 5264    }
 265
 266    private void RestoreWaypointIndex(HybridGuide guide)
 267    {
 1268        if (WaypointIndex <= 0)
 0269            return;
 270
 2271        while (guide.CurrentWaypointIndex < WaypointIndex
 2272            && guide.TryGetWaypointAt(guide.CurrentWaypointIndex + 1, out _))
 273        {
 1274            guide.AdvanceWaypoint();
 275        }
 1276    }
 277}