XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
namespace XFEEDToolBox.Core.Navigation;

public sealed record CruiseOverchargeGateFrame
{
    public bool IdentityVerified{get;init;}
    public bool GeometryVerified{get;init;}
    public bool TargetVerified{get;init;}
    public bool InSupercruise{get;init;}
    public bool AssistEnabled{get;init;}
    public bool CollisionCourse{get;init;}
    public bool Emergency{get;init;}
    public bool NativeCanEngage{get;init;}
    public int RawFsdState{get;init;}
    public int OverchargeState{get;init;}=-1;
    public ulong ObservedAt{get;init;}
    public double Hull{get;init;}=double.NaN;
    public double Heat{get;init;}=double.NaN;
    public double HeatRise{get;init;}=double.NaN;
    public ScoThermalInput? ThermalInput{get;init;}
    public double MainFuel{get;init;}=double.NaN;
    public double FuelCapacity{get;init;}=double.NaN;
    public double FuelRateUpper{get;init;}=double.NaN;
    public double RequiredFuelReserve{get;init;}=double.NaN;
    public double Distance{get;init;}=double.NaN;
    public double Speed{get;init;}=double.NaN;
    public double AimErrorDegrees{get;init;}=double.NaN;
    public bool CruiseParametersVerified{get;init;}
    public double CruiseApproachSeconds{get;init;}=double.NaN;
    public ulong ShipEntity{get;init;}
    public ulong ReferenceWorld{get;init;}
    public int TargetKey{get;init;}=-1;
    public ScoExitApproachDecision? ExitApproach{get;init;}
}

/// <summary>Additional per-update SCO interlock, evaluated inside the original owning thread.</summary>
public static class CruiseOverchargeNativeGuard
{
    public static string? Refusal(CruiseOverchargeGateFrame value,ulong now,ulong deadline)
    {
        if(!value.IdentityVerified||!value.TargetVerified)return "identity-or-target";
        if(value.ObservedAt>now||now-value.ObservedAt>200||deadline<=now||deadline-now>250)return "expired";
        if(!value.InSupercruise||value.RawFsdState!=2||value.OverchargeState is <0 or >2)return "flight-state";
        if(!value.GeometryVerified||value.CollisionCourse||value.AssistEnabled)return "geometry-or-assist";
        if(value.Emergency||!double.IsFinite(value.Hull)||value.Hull is <=0 or >1)return "health";
        if(!value.NativeCanEngage)return "native-refusal";
        var active=value.OverchargeState is 1 or 2;
        if(!double.IsFinite(value.Distance)||!double.IsFinite(value.Speed)||value.Speed<0||!double.IsFinite(value.AimErrorDegrees)
            ||(value.ExitApproach?.RequiresStop(value.Distance,value.Speed,active,value.CruiseParametersVerified,value.CruiseApproachSeconds,
                value.ShipEntity,value.ReferenceWorld,value.TargetKey,now)
                ??ScoApproachEnvelope.RequiresStop(value.Distance,value.Speed,active,value.CruiseParametersVerified,value.CruiseApproachSeconds))
            ||value.AimErrorDegrees<0||value.AimErrorDegrees>(active?6:3))return "approach-or-alignment";
        if(!double.IsFinite(value.Heat)||value.Heat<0||value.Heat>=100)return "heat";
        if(value.ThermalInput is not {} thermal)return "thermal-model";
        var forecast=ScoThermalPredictor.Predict(thermal with{HeatPercent=value.Heat,LeaseRemainingSeconds=(deadline-now)/1000d});
        if(!forecast.Known)return "thermal-model";
        if(forecast.ShouldStop)return "heat";
        if(!double.IsFinite(value.MainFuel)||!double.IsFinite(value.FuelCapacity)||value.FuelCapacity<=0||value.MainFuel<0||value.MainFuel>value.FuelCapacity+.001
            ||!double.IsFinite(value.RequiredFuelReserve)||value.RequiredFuelReserve<=0||value.RequiredFuelReserve>=value.FuelCapacity
            ||!double.IsFinite(value.FuelRateUpper)||value.FuelRateUpper<=0
            ||value.MainFuel-value.RequiredFuelReserve-value.FuelRateUpper*2-Math.Max(.25,value.FuelCapacity*.01)<=0)return "fuel";
        return null;
    }
}