using XFEEDToolBox.Core.Models;
namespace XFEEDToolBox.Core.Execution;
public enum AutomaticTradeMode { Regular, CommunityGoal }
public sealed record AutomaticTradeConfiguration
{
public int Schema{get;init;}=1;
public Station Source{get;init;}=new();
public Station Destination{get;init;}=new();
public string WorkingDirectory{get;init;}="";
public int EmptyValidationVisits{get;init;}=0;
public int CargoCapacity{get;init;}=0;
public AutomaticTradeMode Mode{get;init;}=AutomaticTradeMode.Regular;
public ulong? CommunityGoalId{get;init;}
public string[] Commodities{get;init;}=[];
public bool ReturnTrade{get;init;}=true;
public bool AutoSelectSource{get;init;}=true;
public PlannerRequest? SourcePlanning{get;init;}
public bool SourceCenterFollowsPlayer{get;init;}=true;
public bool UsesDynamicSources=>Mode==AutomaticTradeMode.CommunityGoal&&AutoSelectSource;
public decimal ReserveCredits{get;init;}
public decimal? InvestmentCredits{get;init;}
public bool RequireSupercruiseOvercharge{get;init;}=true;
// Retained for existing configuration files; escape alignment is no longer the default policy.
public bool RequireInterdictionEscape{get;init;}
public bool ExitOnInterdiction{get;init;}=true;
public bool ValidateMenuReentry{get;init;}=false;
public string? ConfirmedCommunityGoalJourney{get;init;}
public decimal PurchaseReserve(decimal credits,decimal shipRebuy,decimal serviceBudget)
{
if(credits<0||shipRebuy<0||serviceBudget<0)throw new ArgumentOutOfRangeException(nameof(credits),"Actual wallet and operating budgets cannot be negative.");
var minimum=Math.Max(ReserveCredits,shipRebuy);
return Math.Max(minimum,InvestmentCredits is {} cap?credits-cap:minimum)+serviceBudget;
}
public void Validate()
{
if(!RequireSupercruiseOvercharge||!ExitOnInterdiction)
throw new InvalidDataException("自动跑商需要启用SCO温度燃油控制与被拦截立即大退保护。");
if(ConfirmedCommunityGoalJourney is not null&&!Path.IsPathFullyQualified(ConfirmedCommunityGoalJourney))
throw new InvalidDataException("已确认CG旅程必须使用完整路径。");
if(Schema!=1||!Enum.IsDefined(Mode)||Source.MarketId<=0||Destination.MarketId<=0||Source.MarketId==Destination.MarketId
||string.IsNullOrWhiteSpace(Source.Name)||string.IsNullOrWhiteSpace(Source.SystemName)||string.IsNullOrWhiteSpace(Destination.Name)||string.IsNullOrWhiteSpace(Destination.SystemName)
||!Path.IsPathFullyQualified(WorkingDirectory)||EmptyValidationVisits is <0 or >10||CargoCapacity<0||ReserveCredits<0||InvestmentCredits is <=0)
throw new InvalidDataException("请选择不同的起点和终点,并提供有效的运行记录目录及保留资金。");
}
}
using XFEEDToolBox.Core.Models;
namespace XFEEDToolBox.Core.Execution;
public enum AutomaticTradeMode { Regular, CommunityGoal }
public sealed record AutomaticTradeConfiguration
{
public int Schema{get;init;}=1;
public Station Source{get;init;}=new();
public Station Destination{get;init;}=new();
public string WorkingDirectory{get;init;}="";
public int EmptyValidationVisits{get;init;}=0;
public int CargoCapacity{get;init;}=0;
public AutomaticTradeMode Mode{get;init;}=AutomaticTradeMode.Regular;
public ulong? CommunityGoalId{get;init;}
public string[] Commodities{get;init;}=[];
public bool ReturnTrade{get;init;}=true;
public bool AutoSelectSource{get;init;}=true;
public PlannerRequest? SourcePlanning{get;init;}
public bool SourceCenterFollowsPlayer{get;init;}=true;
public bool UsesDynamicSources=>Mode==AutomaticTradeMode.CommunityGoal&&AutoSelectSource;
public decimal ReserveCredits{get;init;}
public decimal? InvestmentCredits{get;init;}
public bool RequireSupercruiseOvercharge{get;init;}=true;
// Retained for existing configuration files; escape alignment is no longer the default policy.
public bool RequireInterdictionEscape{get;init;}
public bool ExitOnInterdiction{get;init;}=true;
public bool ValidateMenuReentry{get;init;}=false;
public string? ConfirmedCommunityGoalJourney{get;init;}
public decimal PurchaseReserve(decimal credits,decimal shipRebuy,decimal serviceBudget)
{
if(credits<0||shipRebuy<0||serviceBudget<0)throw new ArgumentOutOfRangeException(nameof(credits),"Actual wallet and operating budgets cannot be negative.");
var minimum=Math.Max(ReserveCredits,shipRebuy);
return Math.Max(minimum,InvestmentCredits is {} cap?credits-cap:minimum)+serviceBudget;
}
public void Validate()
{
if(!RequireSupercruiseOvercharge||!ExitOnInterdiction)
throw new InvalidDataException("自动跑商需要启用SCO温度燃油控制与被拦截立即大退保护。");
if(ConfirmedCommunityGoalJourney is not null&&!Path.IsPathFullyQualified(ConfirmedCommunityGoalJourney))
throw new InvalidDataException("已确认CG旅程必须使用完整路径。");
if(Schema!=1||!Enum.IsDefined(Mode)||Source.MarketId<=0||Destination.MarketId<=0||Source.MarketId==Destination.MarketId
||string.IsNullOrWhiteSpace(Source.Name)||string.IsNullOrWhiteSpace(Source.SystemName)||string.IsNullOrWhiteSpace(Destination.Name)||string.IsNullOrWhiteSpace(Destination.SystemName)
||!Path.IsPathFullyQualified(WorkingDirectory)||EmptyValidationVisits is <0 or >10||CargoCapacity<0||ReserveCredits<0||InvestmentCredits is <=0)
throw new InvalidDataException("请选择不同的起点和终点,并提供有效的运行记录目录及保留资金。");
}
}