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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using XFEEDToolBox.Core.Galaxy;
using XFEEDToolBox.Core.Localization;
namespace XFEEDToolBox.ViewModels;

public sealed record GalacticPlaceChoice(string Name)
{
    public string DisplayName=>ChineseNames.Translate(Name) is var n&&n!="未收录名称"?n:Name;
    public string OriginalName=>DisplayName==Name?"":Name;
}
public partial class ToolboxViewModel
{
    private readonly Dictionary<GalacticPlaceKind,IReadOnlyList<string>> placeChoices=[];
    private GalacticPlaces? placesClient;
    private GalacticPlaces PlacesClient=>placesClient??=new(galaxyHttp);
    private int placeSearchVersion;
    [ObservableProperty,NotifyPropertyChangedFor(nameof(PlacesNeedTrader)),NotifyPropertyChangedFor(nameof(PlacesNeedEngineer)),NotifyPropertyChangedFor(nameof(PlacesNeedItem)),NotifyPropertyChangedFor(nameof(PlacesNeedModule)),NotifyPropertyChangedFor(nameof(PlacesNeedGathering)),NotifyPropertyChangedFor(nameof(PlacesNeedGatheringMaterial)),NotifyPropertyChangedFor(nameof(PlacesAllowPadFilter))]
    public partial int GalaxyPlaceKindIndex {get;set;}
    public bool PlacesNeedTrader=>GalaxyPlaceKindIndex==0;
    public bool PlacesNeedEngineer=>GalaxyPlaceKindIndex==2;
    public bool PlacesNeedItem=>GalaxyPlaceKindIndex is >=3 and <=5;
    public bool PlacesNeedModule=>GalaxyPlaceKindIndex==4;
    public bool PlacesNeedGathering=>GalaxyPlaceKindIndex==6;
    public bool PlacesNeedGatheringMaterial=>PlacesNeedGathering&&GalaxyGatheringCategoryIndex!=2;
    public bool PlacesAllowPadFilter=>!PlacesNeedGathering&&GalaxyPlaceKindIndex!=2;
    [ObservableProperty,NotifyPropertyChangedFor(nameof(PlacesNeedGatheringMaterial)),NotifyPropertyChangedFor(nameof(GalaxyGatheringChoices)),NotifyPropertyChangedFor(nameof(GalaxyGatheringHint))]
    public partial int GalaxyGatheringCategoryIndex {get;set;}
    [ObservableProperty,NotifyPropertyChangedFor(nameof(GalaxyGatheringHint))] public partial GatheringMaterial? GalaxyGatheringMaterial {get;set;}=MaterialGathering.Choices(GatheringCategory.Manufactured).FirstOrDefault();
    public IReadOnlyList<GatheringMaterial> GalaxyGatheringChoices=>MaterialGathering.Choices((GatheringCategory)Math.Clamp(GalaxyGatheringCategoryIndex,0,2));
    public string GalaxyGatheringHint=>GalaxyGatheringCategoryIndex switch
    {
        0=>"G5 人造材料 · "+(GalaxyGatheringMaterial is {} m?MaterialGathering.Rule(m.Name).Description: "请选择材料")+";按星系势力与派系当前状态筛选最近候选,抵达后扫描高等级信号。",
        1=>"按所选材料筛选图中的脑树采集点,按当前位置距离排序;结果包含行星及起止地表坐标。",
        _=>"Jameson 坠毁点 · HIP 12099 1 B · 扫描数据信标;可在数据贸易商兑换其他数据。"
    };
    partial void OnGalaxyGatheringCategoryIndexChanged(int value)
    {
        GalaxyGatheringMaterial=GalaxyGatheringChoices.FirstOrDefault();InvalidateGatheringResults();
    }
    partial void OnGalaxyGatheringMaterialChanged(GatheringMaterial? value)=>InvalidateGatheringResults();
    private void InvalidateGatheringResults()
    {
        placeSearchVersion++;
        if(SearchGalacticPlacesCommand.IsRunning)SearchGalacticPlacesCommand.Cancel();
        GalaxyPlaces=[];GalaxyPlacesStatus="以当前位置查找材料采集点。";
    }
    [ObservableProperty] public partial int GalaxyTraderIndex {get;set;}
    [ObservableProperty] public partial int GalaxyModuleClassIndex {get;set;}
    [ObservableProperty] public partial string GalaxyModuleRating {get;set;}="全部";
    [ObservableProperty] public partial bool GalaxyPlaceLargePad {get;set;}
    [ObservableProperty] public partial string GalaxyPlaceQuery {get;set;}="";
    [ObservableProperty] public partial bool GalaxyPlacesBusy {get;set;}
    [ObservableProperty] public partial string GalaxyPlacesStatus {get;set;}="以当前位置查找;商品与装配库存以最新采集记录为准。";
    [ObservableProperty] public partial IReadOnlyList<GalacticPlace> GalaxyPlaces {get;set;}=[];
    [ObservableProperty] public partial EngineerLocation? GalaxyEngineer {get;set;}=EngineerDirectory.All.FirstOrDefault(e=>e.Name.StartsWith("Tod "));
    public IReadOnlyList<EngineerLocation> GalaxyEngineers=>EngineerDirectory.All;
    public IReadOnlyList<string> GalaxyModuleClasses {get;}=["全部","0","1","2","3","4","5","6","7","8"];
    public IReadOnlyList<string> GalaxyModuleRatings {get;}=["全部","A","B","C","D","E","F","G","H","I"];
    private void InvalidatePlaceResults()
    {
        placeSearchVersion++;if(SearchGalacticPlacesCommand.IsRunning)SearchGalacticPlacesCommand.Cancel();
        GalaxyPlaces=[];GalaxyPlacesStatus="以当前位置查找;商品与装配库存以最新采集记录为准。";
    }
    partial void OnGalaxyPlaceKindIndexChanged(int value){InvalidatePlaceResults();GalaxyPlaceQuery="";if(value==6)GalaxyPlacesStatus="选择材料类别和材料后查找采集点。";}
    partial void OnGalaxyTraderIndexChanged(int value)=>InvalidatePlaceResults();
    partial void OnGalaxyModuleClassIndexChanged(int value)=>InvalidatePlaceResults();
    partial void OnGalaxyModuleRatingChanged(string value)=>InvalidatePlaceResults();
    partial void OnGalaxyPlaceLargePadChanged(bool value)=>InvalidatePlaceResults();
    partial void OnGalaxyPlaceQueryChanged(string value)=>InvalidatePlaceResults();
    partial void OnGalaxyEngineerChanged(EngineerLocation? value)=>InvalidatePlaceResults();
    internal async Task<IReadOnlyList<GalacticPlaceChoice>> SuggestPlacesAsync(string query,CancellationToken token)
    {
        if(!PlacesNeedItem)return [];
        var kind=(GalacticPlaceKind)GalaxyPlaceKindIndex;
        if(!placeChoices.TryGetValue(kind,out var values))placeChoices[kind]=values=await PlacesClient.ChoicesAsync(kind,token);
        token.ThrowIfCancellationRequested();query=query.Trim();
        return values.Select(s=>new GalacticPlaceChoice(s)).Where(c=>c.Name.Contains(query,StringComparison.OrdinalIgnoreCase)||c.DisplayName.Contains(query,StringComparison.OrdinalIgnoreCase)).ToArray();
    }
    [RelayCommand] private async Task SearchGalacticPlacesAsync(CancellationToken cancellationToken=default)
    {
        using var stop=CancellationTokenSource.CreateLinkedTokenSource(lifetime.Token,cancellationToken);var token=stop.Token;var version=placeSearchVersion;GalaxyPlacesBusy=true;
        try
        {
            var origin=CurrentPlayer.Position??throw new InvalidOperationException("尚未读取当前星系坐标。");
            var kind=(GalacticPlaceKind)Math.Clamp(GalaxyPlaceKindIndex,0,6);
            IReadOnlyList<GalacticPlace> results;
            if(kind==GalacticPlaceKind.MaterialGathering)
            {
                var category=(GatheringCategory)Math.Clamp(GalaxyGatheringCategoryIndex,0,2);
                var material=GalaxyGatheringMaterial?.Name??"";GalaxyPlacesStatus="正在查找最近材料采集点…";
                results=category==GatheringCategory.Manufactured
                    ?await new MaterialGathering(galaxyHttp).SearchManufacturedAsync(material,origin,token)
                    :MaterialGathering.FixedPlaces(category,material,origin);
            }
            else if(kind==GalacticPlaceKind.Engineer)
            {
                var engineer=GalaxyEngineer??throw new InvalidOperationException("请先选择工程师。");
                results=[new(engineer.DisplayName,engineer.SystemName,engineer.Position,null,origin.DistanceTo(engineer.Position),engineer.BaseName+" · "+engineer.Body,"工程师驻地",engineer.Portrait)];
            }
            else
            {
                var value=kind==GalacticPlaceKind.MaterialTrader?new[]{"Raw","Manufactured","Encoded"}[Math.Clamp(GalaxyTraderIndex,0,2)]:GalaxyPlaceQuery;
                GalaxyPlacesStatus="正在查找最近地点…";
                results=await PlacesClient.SearchAsync(kind,value,origin,GalaxyModuleClassIndex==0?null:GalaxyModuleClassIndex-1,GalaxyModuleRating=="全部"?"":GalaxyModuleRating,GalaxyPlaceLargePad,token);
            }
            token.ThrowIfCancellationRequested();GalaxyPlaces=results;
            foreach(var result in results)galaxyCache[result.SystemName]=result.System;
            PublishGalaxy();
            GalaxyPlacesStatus=results.Count>0?$"找到 {results.Count} 个地点 · 按距离排序"+(kind is GalacticPlaceKind.Engineer or GalacticPlaceKind.MaterialGathering?"":" · Spansh 采集数据"):
                kind==GalacticPlaceKind.MaterialGathering?"未找到符合材料筛选条件的已上报星系。":"没有符合条件的已上报站点。";
            if(results.FirstOrDefault() is {} first)ShowGalacticPlace(first);
        }
        catch(OperationCanceledException){if(version==placeSearchVersion)GalaxyPlacesStatus="地点查找已取消。";}
        catch(Exception error){if(version==placeSearchVersion)GalaxyPlacesStatus="地点查找未完成:"+error.Message;}
        finally{GalaxyPlacesBusy=false;}
    }
    internal void ShowGalacticPlace(GalacticPlace place)
    {
        galaxyCache[place.SystemName]=place.System;GalaxySelection=place.System;GalaxyCentre=place.Position;PublishGalaxy();
    }
}