Initial import of BardFrontline
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
namespace BardFrontline.Core;
|
||||
|
||||
// One outstanding native request. Cooldown changes alone are insufficient for a cleanse: wait for acknowledgement.
|
||||
public sealed class RequestGate
|
||||
{
|
||||
public ActionDecision? Pending { get; private set; }
|
||||
private double sentAt;
|
||||
private ushort beforeSequence;
|
||||
private bool sequenceObserved;
|
||||
private ushort requestSequence;
|
||||
private readonly Dictionary<(Skill, ulong), double> failures = [];
|
||||
public string Reason { get; private set; } = "";
|
||||
|
||||
public void Submitted(ActionDecision decision, double now, ushort before, ushort after)
|
||||
{
|
||||
Pending = decision; sentAt = now; beforeSequence = before;
|
||||
sequenceObserved = after != before; requestSequence = after; Reason = "等待动作确认";
|
||||
}
|
||||
public bool Update(double now, ushort used, ushort handled, bool guardActive, bool cleansingStateChanged, bool ownedCastInProgress = false)
|
||||
{
|
||||
if (Pending == null) return false;
|
||||
if (!sequenceObserved && used != beforeSequence) { sequenceObserved = true; requestSequence = used; }
|
||||
var acknowledged = sequenceObserved && unchecked((short)(handled - requestSequence)) >= 0;
|
||||
var elapsed = now - sentAt;
|
||||
var release = Pending.Skill switch
|
||||
{
|
||||
Skill.Guard => guardActive || acknowledged && elapsed >= .5,
|
||||
Skill.Purify or Skill.WardensPaean => cleansingStateChanged || acknowledged && elapsed >= .5,
|
||||
_ => acknowledged && elapsed >= .1,
|
||||
};
|
||||
if (release) { Pending = null; Reason = ""; return false; }
|
||||
if (ownedCastInProgress) return true;
|
||||
if (elapsed < 2) return true;
|
||||
Fail(Pending, now, "动作确认超时,短暂退避"); Pending = null;
|
||||
return false;
|
||||
}
|
||||
public bool IsBlocked(Skill s, ulong id, double now) => failures.TryGetValue((s, id), out var until) && until > now;
|
||||
public void Fail(ActionDecision d, double now, string reason)
|
||||
{
|
||||
failures[(d.Skill, d.TargetId)] = now + .5; Reason = reason;
|
||||
foreach (var key in failures.Where(x => x.Value <= now).Select(x => x.Key).ToArray()) failures.Remove(key);
|
||||
}
|
||||
public void Reset() { Pending = null; failures.Clear(); Reason = ""; }
|
||||
}
|
||||
Reference in New Issue
Block a user