using XFEEDToolBox.Core.Localization;
namespace XFEEDToolBox.Core.Navigation;
[Flags]
public enum SystemLocationCategory { None=0,Star=1,Asteroid=2,Planet=4,LandablePlanet=8,Settlement=16,Station=32,Carrier=64,PointOfInterest=128,Signal=256,Other=512,All=1023 }
public sealed record SystemLocation(int Key,ulong WorldAddress,string Name,string SecondaryName,int NativeKind,SystemLocationCategory Category,
long? MarketId,Vector3d? Position,double? DistanceMetres,bool Selected,string Identity)
{
public uint? NativeStarType{get;init;}
public string DisplayName=>GameNavigationNames.Location(Name,KindText);
public string DisplaySecondaryName=>GameNavigationNames.Location(SecondaryName,"");
public string KindText=>Category switch{SystemLocationCategory.Star=>"恒星",SystemLocationCategory.Asteroid=>"小行星带",SystemLocationCategory.Planet=>"行星与卫星",
SystemLocationCategory.LandablePlanet=>"可登陆的行星与卫星",SystemLocationCategory.Settlement=>"据点",SystemLocationCategory.Station=>"站点",SystemLocationCategory.Carrier=>"航母",
SystemLocationCategory.PointOfInterest=>"兴趣点",SystemLocationCategory.Signal=>"信号源",_=>"其他地点"};
public string DistanceText=>DistanceMetres is not {} distance?"距离待确认":distance<1000?$"{distance:F0} m":distance<299792458?$"{distance/1000:N1} km":$"{distance/299792458:N2} ls";
}
public sealed record CurrentSystemSnapshot(long SystemAddress,string SystemName,ulong EntityId,long Sequence,DateTimeOffset ObservedAt,IReadOnlyList<SystemLocation> Locations)
{
public bool DisplayOnly{get;init;}
public Vector3d? PlayerPosition{get;init;}
public ulong PlayerReferenceWorld{get;init;}
public Vector3d? PlayerForward{get;init;}
public IReadOnlyList<SystemOrbit> Orbits{get;init;}=[];
}
public sealed record SystemLocationFilter(SystemLocationCategory Categories=SystemLocationCategory.None,string Search="")
{
public SystemLocationCategory EffectiveCategories=>Categories==SystemLocationCategory.None?SystemLocationCategory.All:Categories;
public IReadOnlyList<SystemLocation> Apply(CurrentSystemSnapshot snapshot)
=>snapshot.Locations.Where(x=>(x.Category&EffectiveCategories)!=0&&(string.IsNullOrWhiteSpace(Search)||x.Name.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)
||x.SecondaryName.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)||x.DisplayName.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)
||x.DisplaySecondaryName.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)))
.OrderBy(x=>x.DistanceMetres??double.MaxValue).ThenBy(x=>x.Name,StringComparer.OrdinalIgnoreCase).ThenBy(x=>x.Key).ToArray();
}
public interface ICurrentSystemLocationSource
{
Task<CurrentSystemSnapshot> ReadLocationsAsync(CancellationToken token=default);
}
using XFEEDToolBox.Core.Localization;
namespace XFEEDToolBox.Core.Navigation;
[Flags]
public enum SystemLocationCategory { None=0,Star=1,Asteroid=2,Planet=4,LandablePlanet=8,Settlement=16,Station=32,Carrier=64,PointOfInterest=128,Signal=256,Other=512,All=1023 }
public sealed record SystemLocation(int Key,ulong WorldAddress,string Name,string SecondaryName,int NativeKind,SystemLocationCategory Category,
long? MarketId,Vector3d? Position,double? DistanceMetres,bool Selected,string Identity)
{
public uint? NativeStarType{get;init;}
public string DisplayName=>GameNavigationNames.Location(Name,KindText);
public string DisplaySecondaryName=>GameNavigationNames.Location(SecondaryName,"");
public string KindText=>Category switch{SystemLocationCategory.Star=>"恒星",SystemLocationCategory.Asteroid=>"小行星带",SystemLocationCategory.Planet=>"行星与卫星",
SystemLocationCategory.LandablePlanet=>"可登陆的行星与卫星",SystemLocationCategory.Settlement=>"据点",SystemLocationCategory.Station=>"站点",SystemLocationCategory.Carrier=>"航母",
SystemLocationCategory.PointOfInterest=>"兴趣点",SystemLocationCategory.Signal=>"信号源",_=>"其他地点"};
public string DistanceText=>DistanceMetres is not {} distance?"距离待确认":distance<1000?$"{distance:F0} m":distance<299792458?$"{distance/1000:N1} km":$"{distance/299792458:N2} ls";
}
public sealed record CurrentSystemSnapshot(long SystemAddress,string SystemName,ulong EntityId,long Sequence,DateTimeOffset ObservedAt,IReadOnlyList<SystemLocation> Locations)
{
public bool DisplayOnly{get;init;}
public Vector3d? PlayerPosition{get;init;}
public ulong PlayerReferenceWorld{get;init;}
public Vector3d? PlayerForward{get;init;}
public IReadOnlyList<SystemOrbit> Orbits{get;init;}=[];
}
public sealed record SystemLocationFilter(SystemLocationCategory Categories=SystemLocationCategory.None,string Search="")
{
public SystemLocationCategory EffectiveCategories=>Categories==SystemLocationCategory.None?SystemLocationCategory.All:Categories;
public IReadOnlyList<SystemLocation> Apply(CurrentSystemSnapshot snapshot)
=>snapshot.Locations.Where(x=>(x.Category&EffectiveCategories)!=0&&(string.IsNullOrWhiteSpace(Search)||x.Name.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)
||x.SecondaryName.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)||x.DisplayName.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)
||x.DisplaySecondaryName.Contains(Search.Trim(),StringComparison.OrdinalIgnoreCase)))
.OrderBy(x=>x.DistanceMetres??double.MaxValue).ThenBy(x=>x.Name,StringComparer.OrdinalIgnoreCase).ThenBy(x=>x.Key).ToArray();
}
public interface ICurrentSystemLocationSource
{
Task<CurrentSystemSnapshot> ReadLocationsAsync(CancellationToken token=default);
}