227 lines
5.4 KiB
C#
227 lines
5.4 KiB
C#
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);
|
|
}
|
|
}
|