using System; using System.Numerics; namespace LLib.Movement.Unstuck; public sealed class StallDetector(StallDetectorOptions options) { private bool _hasAnchor; private long _anchorMs; private Vector3 _anchorPosition; private DriveMode _anchorMode; private bool _anchorUsesProgress; private float _referenceBestDistance; private float _bestDistance; private long _lastDrivenMs; private long _cooldownUntilMs; public StallVerdict? Observe(in StallSample sample) { int num = (sample.Driving ? 860999294 : 860999280); bool flag = default(bool); while (true) { int num2 = num; int num3 = 860999289; int num4 = num2; int num5; switch ((num4 | num3) - (num4 & num3)) { case 8: num5 = (sample.DistanceToTarget.HasValue ? 1 : 0); goto IL_0163; case 4: num = ((sample.TimestampMs - _lastDrivenMs > options.ContinuityGapMs) ? 860999295 : 860999282); break; case 1: return ObserveProgress(in sample); case 11: num = ((sample.Mode != _anchorMode) ? 860999295 : 860999289); break; case 10: return ObserveDisplacement(in sample); case 7: num = ((sample.Mode == DriveMode.Ground) ? 860999292 : 860999281); break; case 2: num = 860999280; break; case 6: Anchor(in sample, flag); return null; case 9: return null; case 0: num = ((flag == _anchorUsesProgress) ? 860999290 : 860999295); break; case 5: num5 = 0; goto IL_0163; case 3: { _lastDrivenMs = sample.TimestampMs; num = (flag ? 860999288 : 860999283); break; } IL_0163: flag = (byte)num5 != 0; num = ((!_hasAnchor) ? 860999295 : 860999293); break; } } } public void Reset() { _hasAnchor = false; _cooldownUntilMs = 0L; } private StallVerdict? ObserveProgress(in StallSample sample) { float value = sample.DistanceToTarget.Value; int num = ((!(value < _bestDistance)) ? 755996687 : 755996681); long num7 = default(long); float num8 = default(float); while (true) { int num2 = num; int num3 = 755996685; int num4 = num2; int num5 = num4 + num3; int num6 = num4 & num3; switch (num5 - (num6 + num6)) { case 0: num = 755996681; break; case 3: return null; case 6: return Trip(in sample, num7, num8); case 2: num8 = _referenceBestDistance - _bestDistance; num = ((!(num8 >= options.ProgressImprovementThreshold)) ? 755996684 : 755996680); break; case 5: _referenceBestDistance = _bestDistance; _anchorMs = sample.TimestampMs; _anchorPosition = sample.Position; return null; case 1: num7 = sample.TimestampMs - _anchorMs; num = ((num7 < options.ProgressWindowMs) ? 755996686 : 755996683); break; case 4: _bestDistance = value; num = 755996687; break; } } } private StallVerdict? ObserveDisplacement(in StallSample sample) { int num = ((sample.Mode == DriveMode.Ground) ? 508532326 : 508532323); long num9 = default(long); float num8 = default(float); while (true) { int num2 = num; int num3 = 508532327; int num4 = num2; int num5 = num4 + num3; int num6 = num4 & num3; float num7; switch (num5 - (num6 + num6)) { case 2: num9 = sample.TimestampMs - _anchorMs; num = ((num9 < options.GroundWindowMs) ? 508532324 : 508532322); break; case 5: return Trip(in sample, num9, num8); case 1: num7 = DistanceXZ(_anchorPosition, sample.Position); goto IL_00ae; case 3: return null; case 0: num = 508532323; break; case 4: num7 = Vector3.Distance(_anchorPosition, sample.Position); goto IL_00ae; case 6: { _anchorMs = sample.TimestampMs; _anchorPosition = sample.Position; return null; } IL_00ae: num8 = num7; num = ((!(num8 >= options.GroundDistanceThreshold)) ? 508532325 : 508532321); break; } } } private StallVerdict? Trip(in StallSample sample, long elapsedMs, float measured) { bool num = sample.TimestampMs < _cooldownUntilMs; Anchor(in sample, _anchorUsesProgress); int num2 = ((!num) ? (-1156731677) : (-1156731680)); while (true) { int num3 = num2; int num4 = -1156731679; int num5 = num3; int num6 = num5 + num4; int num7 = num5 & num4; switch (num6 - (num7 + num7)) { case 2: _cooldownUntilMs = sample.TimestampMs + options.CooldownMs; return new StallVerdict(elapsedMs, measured, sample.Mode); case 1: return null; case 0: goto IL_0092; } continue; IL_0092: num2 = -1156731680; } } private void Anchor(in StallSample sample, bool usesProgress) { _hasAnchor = true; _anchorMs = sample.TimestampMs; _anchorPosition = sample.Position; _anchorMode = sample.Mode; _anchorUsesProgress = usesProgress; _lastDrivenMs = sample.TimestampMs; _referenceBestDistance = (_bestDistance = sample.DistanceToTarget.GetValueOrDefault()); } private static float DistanceXZ(Vector3 a, Vector3 b) { float num = a.X - b.X; float num2 = a.Z - b.Z; return _206A_202D_200C_206C_206C_206B_202D_202E_206B_200B_200B_206F_206F_202B_200D_200F_206A_202C_200C_202A_202D_202C_200B_206F_206F_200F_206F_206B_206E_200D_202C_200C_200D_206F_202A_202D_202D_200B_200D_202C_202E(num * num + num2 * num2); } static float _206A_202D_200C_206C_206C_206B_202D_202E_206B_200B_200B_206F_206F_202B_200D_200F_206A_202C_200C_202A_202D_202C_200B_206F_206F_200F_206F_206B_206E_200D_202C_200C_200D_206F_202A_202D_202D_200B_200D_202C_202E(float P_0) { return MathF.Sqrt(P_0); } }