forked from aly/qstbak
241 lines
5.2 KiB
C#
241 lines
5.2 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace LLib.Movement.Unstuck;
|
|
|
|
public sealed class RecoveryLadder
|
|
{
|
|
private readonly IRecoveryRung[] _rungs;
|
|
|
|
private readonly long[] _lastRunMs;
|
|
|
|
private readonly bool[] _hasRun;
|
|
|
|
private readonly List<string> _rungsFired;
|
|
|
|
private bool _hasRunAny;
|
|
|
|
private long _lastRunAnyMs;
|
|
|
|
private long _firstStallMs;
|
|
|
|
private long _lastStallMs;
|
|
|
|
public int Attempts { get; private set; }
|
|
|
|
public bool IsExhausted { get; private set; }
|
|
|
|
private int Cap
|
|
{
|
|
get
|
|
{
|
|
RecoveryMode mode = _003Coptions_003EP.Mode;
|
|
int num = ((mode == RecoveryMode.Aggressive) ? (-304547260) : (-304547257));
|
|
int result = default(int);
|
|
while (true)
|
|
{
|
|
int num2 = num;
|
|
int num3 = -304547258;
|
|
int num4 = num2;
|
|
switch ((num4 | num3) - (num4 & num3))
|
|
{
|
|
case 4:
|
|
result = _003Coptions_003EP.PassiveCap;
|
|
num = -304547258;
|
|
break;
|
|
case 1:
|
|
num = ((mode == RecoveryMode.Passive) ? (-304547262) : (-304547264));
|
|
break;
|
|
case 6:
|
|
num = -304547261;
|
|
break;
|
|
case 2:
|
|
result = _003Coptions_003EP.AggressiveCap;
|
|
num = -304547258;
|
|
break;
|
|
case 5:
|
|
result = _003Coptions_003EP.ConservativeCap;
|
|
num = -304547258;
|
|
break;
|
|
case 3:
|
|
num = -304547257;
|
|
break;
|
|
case 0:
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public RecoveryLadder(RecoveryLadderOptions options, IReadOnlyList<IRecoveryRung> rungs)
|
|
{
|
|
_003Coptions_003EP = options;
|
|
_rungs = rungs.ToArray();
|
|
_lastRunMs = new long[rungs.Count];
|
|
_hasRun = new bool[rungs.Count];
|
|
_rungsFired = new List<string>();
|
|
base._002Ector();
|
|
}
|
|
|
|
public RecoveryDecision OnStall(long nowMs)
|
|
{
|
|
int num = ((!IsExhausted) ? 1754338781 : 1754338772);
|
|
IRecoveryRung recoveryRung = default(IRecoveryRung);
|
|
int num7 = default(int);
|
|
while (true)
|
|
{
|
|
int num2 = num;
|
|
int num3 = 1754338771;
|
|
int num4 = num2;
|
|
int num5 = num4 + num3;
|
|
int num6 = num4 & num3;
|
|
switch (num5 - (num6 + num6))
|
|
{
|
|
case 9:
|
|
{
|
|
long num8 = _lastRunAnyMs;
|
|
long num9 = nowMs;
|
|
num = ((~(~num9 + num8) >= _003Coptions_003EP.GlobalCooldownMs) ? 1754338774 : 1754338768);
|
|
break;
|
|
}
|
|
case 0:
|
|
num = ((!_hasRunAny) ? 1754338774 : 1754338778);
|
|
break;
|
|
case 14:
|
|
num = ((Attempts < Cap) ? 1754338771 : 1754338783);
|
|
break;
|
|
case 16:
|
|
num = ((!recoveryRung.CanRun(Attempts + 1, nowMs)) ? 1754338773 : 1754338782);
|
|
break;
|
|
case 10:
|
|
recoveryRung = _rungs[num7];
|
|
num = ((!_hasRun[num7]) ? 1754338755 : 1754338776);
|
|
break;
|
|
case 4:
|
|
num = 1754338772;
|
|
break;
|
|
case 13:
|
|
Consume(nowMs);
|
|
_rungsFired.Add(recoveryRung.Name);
|
|
_hasRun[num7] = true;
|
|
_lastRunMs[num7] = nowMs;
|
|
_hasRunAny = true;
|
|
_lastRunAnyMs = nowMs;
|
|
return new RecoveryDecision(RecoveryDecisionKind.Run, recoveryRung, null);
|
|
case 6:
|
|
{
|
|
int num10 = num7;
|
|
num3 = 1;
|
|
num4 = num10;
|
|
int num11 = num4 ^ num3;
|
|
int num12 = num4 & num3;
|
|
num7 = num11 + (num12 + num12);
|
|
num = 1754338769;
|
|
break;
|
|
}
|
|
case 12:
|
|
IsExhausted = true;
|
|
return new RecoveryDecision(RecoveryDecisionKind.Exhausted, null, new RecoveryExhaustion(Attempts, _rungsFired.ToArray(), _firstStallMs, _lastStallMs));
|
|
case 1:
|
|
Consume(nowMs);
|
|
return new RecoveryDecision(RecoveryDecisionKind.Observe, null, null);
|
|
case 5:
|
|
num = ((_003Coptions_003EP.Mode != RecoveryMode.Passive) ? 1754338779 : 1754338770);
|
|
break;
|
|
case 11:
|
|
{
|
|
long num8 = _lastRunMs[num7];
|
|
long num9 = nowMs;
|
|
num = ((~(~num9 + num8) < recoveryRung.CooldownMs) ? 1754338773 : 1754338755);
|
|
break;
|
|
}
|
|
case 3:
|
|
return new RecoveryDecision(RecoveryDecisionKind.None, null, null);
|
|
case 2:
|
|
num = ((num7 < _rungs.Length) ? 1754338777 : 1754338780);
|
|
break;
|
|
case 15:
|
|
return new RecoveryDecision(RecoveryDecisionKind.None, null, null);
|
|
case 7:
|
|
return new RecoveryDecision(RecoveryDecisionKind.None, null, null);
|
|
case 8:
|
|
num7 = 0;
|
|
num = 1754338769;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
Attempts = 0;
|
|
IsExhausted = false;
|
|
_rungsFired.Clear();
|
|
_hasRunAny = false;
|
|
int num = 0;
|
|
int num2 = -478483629;
|
|
while (true)
|
|
{
|
|
int num3 = num2;
|
|
int num4 = -478483631;
|
|
int num5 = num3;
|
|
int num6 = num5 + num4;
|
|
int num7 = num5 & num4;
|
|
switch (num6 - (num7 + num7))
|
|
{
|
|
case 0:
|
|
return;
|
|
case 2:
|
|
num2 = ((num < _hasRun.Length) ? (-478483632) : (-478483631));
|
|
break;
|
|
case 1:
|
|
{
|
|
_hasRun[num] = false;
|
|
int num8 = num;
|
|
num4 = 1;
|
|
num5 = num8;
|
|
int num9 = num5 ^ num4;
|
|
int num10 = num5 & num4;
|
|
num = num9 + (num10 + num10);
|
|
num2 = -478483629;
|
|
break;
|
|
}
|
|
case 3:
|
|
num2 = -478483629;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Consume(long nowMs)
|
|
{
|
|
int num = ((Attempts != 0) ? 1659706856 : 1659706857);
|
|
while (true)
|
|
{
|
|
int num2 = num;
|
|
int num3 = 1659706856;
|
|
int num4 = num2;
|
|
int num5 = num4 + num3;
|
|
int num6 = num4 & num3;
|
|
switch (num5 - (num6 + num6))
|
|
{
|
|
case 2:
|
|
num = 1659706857;
|
|
break;
|
|
case 1:
|
|
_firstStallMs = nowMs;
|
|
num = 1659706856;
|
|
break;
|
|
case 0:
|
|
{
|
|
int attempts = Attempts;
|
|
num3 = 1;
|
|
num4 = attempts;
|
|
Attempts = (num4 | num3) + (num4 & num3);
|
|
_lastStallMs = nowMs;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|