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

XFEWarframe

【WinUI】基于Warframe游戏本体的公开服务器以及安装器

公开
关注 0 Fork 0 Star 0
UTF-8
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Newtonsoft.Json.Linq;

namespace XFEWarframe.Desktop.Editing;

public partial class RivenStatRow : ObservableObject
{
    private readonly Action<RivenStatRow> remove;
    public RivenStatRow(IReadOnlyList<RivenStatOption> tags, Action<RivenStatRow> remove)
    {
        this.remove = remove;
        Tags = tags.Select(x => new RivenStatOption(x.Key, x.Label, x.ColorKey)).ToArray();
        SelectedTag = Tags.FirstOrDefault();
    }
    public IReadOnlyList<RivenStatOption> Tags { get; }
    public IReadOnlyList<string> Modes { get; } = ["品质(9000–11000)", "实际数值"];
    [ObservableProperty, NotifyPropertyChangedFor(nameof(Tone))] public partial RivenStatOption? SelectedTag { get; set; }
    [ObservableProperty, NotifyPropertyChangedFor(nameof(Tone))] public partial bool Negative { get; set; }
    [ObservableProperty] public partial int ModeIndex { get; set; }
    [ObservableProperty] public partial double Value { get; set; } = 10000;
    [ObservableProperty] public partial string Result { get; set; } = "";
    [ObservableProperty] public partial string Quality { get; set; } = "";
    public string Tone => Negative ? "negative" : SelectedTag?.ColorKey ?? "";
    private double? displayedValue, rollValue;
    partial void OnModeIndexChanged(int value)
    {
        if ((value == 1 ? displayedValue : rollValue) is double converted) Value = converted;
    }
    partial void OnSelectedTagChanged(RivenStatOption? value)
    {
        if (ModeIndex == 1 && value?.DisplayValue is double converted) Value = converted;
    }
    public void ResetResult()
    {
        Result = Quality = "";
        // Keep the last calculated numeric choices while the user types a new selection.
        foreach (var option in Tags) { option.DisplayText = option.Label; option.Tone = Negative ? "negative" : option.ColorKey; }
    }
    public void ApplyResult(JToken result)
    {
        Result = result.Value<string>("text") ?? $"{result.Value<double>("displayValue"):+0.##;-0.##;0} {SelectedTag?.Label}";
        displayedValue = result.Value<double>("displayValue"); rollValue = result.Value<double>("roll");
        Quality = $"{result.Value<string>("grade")} · {UiText.Translate("品质")} {result.Value<double>("roll"):0.##}";
        foreach (var data in result["options"] ?? new JArray())
            if (Tags.FirstOrDefault(x => x.Key == data.Value<string>("key")) is { } option)
            { option.DisplayText = data.Value<string>("text") ?? option.Label; option.DisplayValue = data.Value<double?>("displayValue"); option.Tone = Negative ? "negative" : option.ColorKey; }
    }
    private JObject? original;
    private double originalValue;
    public void Retain(JObject row) { original = (JObject)row.DeepClone(); originalValue = Value; }
    public object Request() => new { tag = SelectedTag?.Key ?? "", negative = Negative, mode = ModeIndex == 1 ? "stat" : "roll", value = Value,
        originalRow = original, encodedValue = ModeIndex == 0 && Value == originalValue && SelectedTag?.Key == original?.Value<string>("Tag") ? original?.Value<long?>("Value") : null };
    [RelayCommand] private void Remove() => remove(this);
}

public partial class RivenStatOption(string key, string label, string colorKey) : ObservableObject
{
    public string Key { get; } = key;
    public string Label { get; } = label;
    public string ColorKey { get; } = colorKey;
    public override string ToString() => Label;
    public double? DisplayValue { get; set; }
    [ObservableProperty] public partial string DisplayText { get; set; } = label;
    [ObservableProperty] public partial string Tone { get; set; } = colorKey;
    public static RivenStatOption FromJson(JToken value) => new(value.Value<string>("key")!, value.Value<string>("label")!, value.Value<string>("color") ?? "");
}