< Summary

Information
Class: Trailblazer.Navigation.Motor.ClimbLocomotion
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Navigation/Motor/Locomotion/ClimbLocomotion.cs
Line coverage
98%
Covered lines: 81
Uncovered lines: 1
Coverable lines: 82
Total lines: 247
Line coverage: 98.7%
Branch coverage
75%
Covered branches: 9
Total branches: 12
Branch coverage: 75%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor()100%11100%
get_IsEnabled()100%11100%
set_IsEnabled(...)50%22100%
ApplyClimbSnapshot(...)100%44100%
CreateActiveMantleState()50%22100%
RecordData(...)75%4497.91%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Navigation/Motor/Locomotion/ClimbLocomotion.cs

#LineLine coverage
 1using Chronicler;
 2using FixedMathSharp;
 3using Trailblazer.Support;
 4
 5namespace Trailblazer.Navigation.Motor;
 6
 7/// <summary>
 8/// Stores climb locomotion configuration and runtime attachment state.
 9/// </summary>
 10public class ClimbLocomotion : ILocomotion
 11{
 12    /// <summary>
 13    /// Default maximum speed while climbing.
 14    /// </summary>
 115    public static readonly Fixed64 DefaultMaxClimbSpeed = Fixed64.One;
 16
 17    /// <summary>
 18    /// Default maximum acceleration while climbing.
 19    /// </summary>
 120    public static readonly Fixed64 DefaultMaxClimbAcceleration = (Fixed64)8;
 21
 22    /// <summary>
 23    /// Default gravity compensation applied while attached to a climb affordance.
 24    /// </summary>
 125    public static readonly Fixed64 DefaultGravityCompensationWhileClimbing = Fixed64.One;
 26
 27    /// <summary>
 28    /// Default positional tolerance used when validating attachment continuity without a stable affordance id.
 29    /// </summary>
 130    public static readonly Fixed64 DefaultClimbStartTolerance = Fixed64.Half;
 31
 79032    private bool _isEnabled = true;
 33
 34    /// <inheritdoc cref="ILocomotion.IsEnabled"/>
 35    public bool IsEnabled
 36    {
 420537        get => _isEnabled;
 38        set
 39        {
 140            _isEnabled = value;
 141            if (!_isEnabled)
 142                this.ClearTransientState();
 143        }
 44    }
 45
 46    /// <summary>
 47    /// Determines whether this locomotion may engage with climb affordances.
 48    /// </summary>
 79049    public bool CanClimb = true;
 50
 51    /// <summary>
 52    /// Maximum climb speed while attached.
 53    /// </summary>
 79054    public Fixed64 MaxClimbSpeed = DefaultMaxClimbSpeed;
 55
 56    /// <summary>
 57    /// Maximum acceleration while attached.
 58    /// </summary>
 79059    public Fixed64 MaxClimbAcceleration = DefaultMaxClimbAcceleration;
 60
 61    /// <summary>
 62    /// Amount of gravity canceled while actively climbing.
 63    /// </summary>
 79064    public Fixed64 GravityCompensationWhileClimbing = DefaultGravityCompensationWhileClimbing;
 65
 66    /// <summary>
 67    /// Positional tolerance used for initial attach and attachment continuity checks.
 68    /// </summary>
 79069    public Fixed64 ClimbStartTolerance = DefaultClimbStartTolerance;
 70
 71    /// <summary>
 72    /// Whether lateral traverse across a climb surface is allowed.
 73    /// </summary>
 79074    public bool AllowLateralTraverse = true;
 75
 76    /// <summary>
 77    /// Whether active mantle should query an optional host validator each frame.
 78    /// </summary>
 79    public bool ValidateActiveMantleWithHost;
 80
 81    /// <summary>
 82    /// Optional host-owned resolver that supplies deterministic climb affordance snapshots.
 83    /// </summary>
 84    public IClimbAffordanceResolver? ClimbResolver;
 85
 86    /// <summary>
 87    /// Whether active climb movement is currently attached to an affordance.
 88    /// </summary>
 89    [Transient]
 90    public bool IsClimbing { get; set; }
 91
 92    /// <summary>
 93    /// Whether the locomotion is currently in a mantle/top-out phase.
 94    /// </summary>
 95    [Transient]
 96    public bool IsMantling { get; set; }
 97
 98    /// <summary>
 99    /// Kind of affordance currently attached, when active.
 100    /// </summary>
 101    [Transient]
 102    public ClimbAffordanceKind ActiveClimbKind { get; set; }
 103
 104    /// <summary>
 105    /// Stable host affordance identity when available.
 106    /// </summary>
 107    [Transient]
 108    public int? AttachmentId { get; set; }
 109
 110    /// <summary>
 111    /// Stored attachment point for the current climb interaction.
 112    /// </summary>
 113    [Transient]
 114    public Vector3d AttachmentPoint { get; set; }
 115
 116    /// <summary>
 117    /// Stored attachment surface normal for the current climb interaction.
 118    /// </summary>
 119    [Transient]
 120    public Vector3d AttachedSurfaceNormal { get; set; }
 121
 122    /// <summary>
 123    /// Stored climb up direction for the current climb interaction.
 124    /// </summary>
 125    [Transient]
 126    public Vector3d AttachedUpDirection { get; set; }
 127
 128    /// <summary>
 129    /// Whether lateral movement is allowed for the active frame snapshot.
 130    /// </summary>
 131    [Transient]
 132    public bool ActiveAllowLateralTraverse { get; set; }
 133
 134    /// <summary>
 135    /// Whether descent is allowed for the active frame snapshot.
 136    /// </summary>
 137    [Transient]
 138    public bool ActiveAllowDescent { get; set; }
 139
 140    /// <summary>
 141    /// Whether detaching via jump is allowed for the active frame snapshot.
 142    /// </summary>
 143    [Transient]
 144    public bool ActiveAllowDetachJump { get; set; }
 145
 146    /// <summary>
 147    /// Whether mantling is allowed for the active frame snapshot.
 148    /// </summary>
 149    [Transient]
 150    public bool ActiveAllowMantle { get; set; }
 151
 152    /// <summary>
 153    /// Current mantle target when a ledge affordance supplies one.
 154    /// </summary>
 155    [Transient]
 156    public Vector3d? MantleTargetPosition { get; set; }
 157
 158    /// <summary>
 159    /// Applies a climb affordance snapshot to update the active attachment state for the current frame.
 160    /// </summary>
 161    /// <param name="snapshot"></param>
 162    public void ApplyClimbSnapshot(ClimbAffordanceSnapshot snapshot)
 163    {
 38164        ActiveClimbKind = snapshot.Kind;
 38165        AttachmentId = snapshot.AffordanceId;
 38166        AttachmentPoint = snapshot.AttachmentPoint;
 38167        AttachedSurfaceNormal = snapshot.SurfaceNormal;
 38168        AttachedUpDirection = snapshot.UpDirection;
 38169        ActiveAllowLateralTraverse = snapshot.AllowLateralTraverse && AllowLateralTraverse;
 38170        ActiveAllowDescent = snapshot.AllowDescent;
 38171        ActiveAllowDetachJump = snapshot.AllowDetachJump;
 38172        ActiveAllowMantle = snapshot.AllowMantle && snapshot.MantleTargetPosition.HasValue;
 38173        MantleTargetPosition = snapshot.MantleTargetPosition;
 38174    }
 175
 176    /// <summary>
 177    /// Creates a readonly snapshot for optional active mantle validation.
 178    /// </summary>
 179    public ActiveMantleState CreateActiveMantleState()
 180    {
 4181        return new ActiveMantleState(
 4182            ActiveClimbKind,
 4183            AttachmentId,
 4184            AttachmentPoint,
 4185            AttachedSurfaceNormal,
 4186            AttachedUpDirection,
 4187            MantleTargetPosition ?? AttachmentPoint);
 188    }
 189
 190    /// <inheritdoc />
 191    public void RecordData(IChronicler chronicler)
 192    {
 104193        RecordValues.Look(chronicler, ref _isEnabled, "IsEnabled", true);
 104194        RecordValues.Look(chronicler, ref CanClimb, "CanClimb", true);
 104195        RecordValues.Look(chronicler, ref MaxClimbSpeed, "MaxClimbSpeed", DefaultMaxClimbSpeed);
 104196        RecordValues.Look(chronicler, ref MaxClimbAcceleration, "MaxClimbAcceleration", DefaultMaxClimbAcceleration);
 104197        RecordValues.Look(chronicler, ref GravityCompensationWhileClimbing, "GravityCompensationWhileClimbing", DefaultG
 104198        RecordValues.Look(chronicler, ref ClimbStartTolerance, "ClimbStartTolerance", DefaultClimbStartTolerance);
 104199        RecordValues.Look(chronicler, ref AllowLateralTraverse, "AllowLateralTraverse", true);
 104200        RecordValues.Look(chronicler, ref ValidateActiveMantleWithHost, "ValidateActiveMantleWithHost", false);
 201
 104202        bool isClimbing = IsClimbing;
 104203        bool isMantling = IsMantling;
 104204        ClimbAffordanceKind activeClimbKind = ActiveClimbKind;
 104205        int? attachmentId = AttachmentId;
 104206        Vector3d attachmentPoint = AttachmentPoint;
 104207        Vector3d attachedSurfaceNormal = AttachedSurfaceNormal;
 104208        Vector3d attachedUpDirection = AttachedUpDirection;
 104209        bool activeAllowLateralTraverse = ActiveAllowLateralTraverse;
 104210        bool activeAllowDescent = ActiveAllowDescent;
 104211        bool activeAllowDetachJump = ActiveAllowDetachJump;
 104212        bool activeAllowMantle = ActiveAllowMantle;
 104213        Vector3d? mantleTargetPosition = MantleTargetPosition;
 214
 104215        RecordValues.Look(chronicler, ref isClimbing, "IsClimbing", false);
 104216        RecordValues.Look(chronicler, ref isMantling, "IsMantling", false);
 104217        RecordValues.Look(chronicler, ref activeClimbKind, "ActiveClimbKind", ClimbAffordanceKind.None);
 104218        RecordValues.Look(chronicler, ref attachmentId, "AttachmentId", null);
 104219        RecordValues.Look(chronicler, ref attachmentPoint, "AttachmentPoint", Vector3d.Zero);
 104220        RecordValues.Look(chronicler, ref attachedSurfaceNormal, "AttachedSurfaceNormal", Vector3d.Zero);
 104221        RecordValues.Look(chronicler, ref attachedUpDirection, "AttachedUpDirection", Vector3d.Zero);
 104222        RecordValues.Look(chronicler, ref activeAllowLateralTraverse, "ActiveAllowLateralTraverse", false);
 104223        RecordValues.Look(chronicler, ref activeAllowDescent, "ActiveAllowDescent", true);
 104224        RecordValues.Look(chronicler, ref activeAllowDetachJump, "ActiveAllowDetachJump", true);
 104225        RecordValues.Look(chronicler, ref activeAllowMantle, "ActiveAllowMantle", false);
 104226        RecordValues.Look(chronicler, ref mantleTargetPosition, "MantleTargetPosition", null);
 227
 104228        if (chronicler.Mode == SerializationMode.Loading)
 229        {
 52230            IsClimbing = isClimbing;
 52231            IsMantling = isMantling;
 52232            ActiveClimbKind = activeClimbKind;
 52233            AttachmentId = attachmentId;
 52234            AttachmentPoint = attachmentPoint;
 52235            AttachedSurfaceNormal = attachedSurfaceNormal;
 52236            AttachedUpDirection = attachedUpDirection;
 52237            ActiveAllowLateralTraverse = activeAllowLateralTraverse;
 52238            ActiveAllowDescent = activeAllowDescent;
 52239            ActiveAllowDetachJump = activeAllowDetachJump;
 52240            ActiveAllowMantle = activeAllowMantle;
 52241            MantleTargetPosition = mantleTargetPosition;
 242
 52243            if (!_isEnabled)
 0244                this.ClearTransientState();
 245        }
 104246    }
 247}