using System.Text.Json;
namespace XFEEDToolBox.Core.Outfitting;
/// <summary>Effective outfitting values calculated from a complete, observed loadout.</summary>
public sealed record EquipmentStatistics(
IReadOnlyDictionary<string,double> Ship,
IReadOnlyDictionary<string,IReadOnlyDictionary<string,double>> Modules)
{
public double? Value(string key)=>Ship.TryGetValue(key,out var value)?value:null;
}
public static partial class EdsyLinkCodec
{
public static EquipmentStatistics Statistics(ShipRefitDocument document)
{
// Never fill unknown core slots with EDSY's stock modules or apply an unsaved target.
if(new[]{"Armour","PowerPlant","MainEngines","FrameShiftDrive","LifeSupport","PowerDistributor","Radar","FuelTank"}
.Any(name=>document.Slots.FirstOrDefault(s=>s.Slot==name)?.Module is null))
throw new InvalidOperationException("等待完整装配,无法计算飞船属性。");
var actual=document with{Slots=document.Slots.Select(s=>s with{Target=null}).ToArray()};
var loadout=new{Ship=actual.ShipType,ShipName=actual.Name,ShipIdent=actual.Ident,Modules=actual.Slots.Select(JournalModule).ToArray()};
var changed=actual.Slots.Where(s=>s.Module!=s.Original).Select(s=>s.Slot).ToArray();
using var result=Invoke("xfeExport",JsonSerializer.Serialize(new{loadout,baselineHash=actual.EdsyHash,changed,statistics=true}));
var root=result.RootElement;
ThrowErrors(root);
static IReadOnlyDictionary<string,double> Values(JsonElement value)=>value.EnumerateObject()
.Where(p=>p.Value.ValueKind==JsonValueKind.Number&&p.Value.TryGetDouble(out var n)&&double.IsFinite(n))
.ToDictionary(p=>p.Name,p=>p.Value.GetDouble(),StringComparer.OrdinalIgnoreCase);
return new(Values(root.GetProperty("ship")),root.GetProperty("modules").EnumerateObject()
.ToDictionary(p=>p.Name,p=>Values(p.Value),StringComparer.OrdinalIgnoreCase));
}
}
using System.Text.Json;
namespace XFEEDToolBox.Core.Outfitting;
/// <summary>Effective outfitting values calculated from a complete, observed loadout.</summary>
public sealed record EquipmentStatistics(
IReadOnlyDictionary<string,double> Ship,
IReadOnlyDictionary<string,IReadOnlyDictionary<string,double>> Modules)
{
public double? Value(string key)=>Ship.TryGetValue(key,out var value)?value:null;
}
public static partial class EdsyLinkCodec
{
public static EquipmentStatistics Statistics(ShipRefitDocument document)
{
// Never fill unknown core slots with EDSY's stock modules or apply an unsaved target.
if(new[]{"Armour","PowerPlant","MainEngines","FrameShiftDrive","LifeSupport","PowerDistributor","Radar","FuelTank"}
.Any(name=>document.Slots.FirstOrDefault(s=>s.Slot==name)?.Module is null))
throw new InvalidOperationException("等待完整装配,无法计算飞船属性。");
var actual=document with{Slots=document.Slots.Select(s=>s with{Target=null}).ToArray()};
var loadout=new{Ship=actual.ShipType,ShipName=actual.Name,ShipIdent=actual.Ident,Modules=actual.Slots.Select(JournalModule).ToArray()};
var changed=actual.Slots.Where(s=>s.Module!=s.Original).Select(s=>s.Slot).ToArray();
using var result=Invoke("xfeExport",JsonSerializer.Serialize(new{loadout,baselineHash=actual.EdsyHash,changed,statistics=true}));
var root=result.RootElement;
ThrowErrors(root);
static IReadOnlyDictionary<string,double> Values(JsonElement value)=>value.EnumerateObject()
.Where(p=>p.Value.ValueKind==JsonValueKind.Number&&p.Value.TryGetDouble(out var n)&&double.IsFinite(n))
.ToDictionary(p=>p.Name,p=>p.Value.GetDouble(),StringComparer.OrdinalIgnoreCase);
return new(Values(root.GetProperty("ship")),root.GetProperty("modules").EnumerateObject()
.ToDictionary(p=>p.Name,p=>Values(p.Value),StringComparer.OrdinalIgnoreCase));
}
}