feat(ui): port retail radar and compass
This commit is contained in:
parent
c4af181b92
commit
3cbe4b00a1
43 changed files with 2882 additions and 262 deletions
|
|
@ -51,7 +51,9 @@ public sealed record GameplaySettings(
|
|||
ShowTooltips: true,
|
||||
VividTargetingIndicator: false,
|
||||
SideBySideVitals: false,
|
||||
CoordinatesOnRadar: false,
|
||||
// Retail default character-options mask 0x50C4A54A includes
|
||||
// CoordinatesOnRadar (0x00400000).
|
||||
CoordinatesOnRadar: true,
|
||||
SpellDuration: true,
|
||||
AllowGive: true,
|
||||
ShowHelm: true,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ using AcDream.UI.Abstractions.Settings;
|
|||
|
||||
namespace AcDream.UI.Abstractions.Panels.Settings;
|
||||
|
||||
/// <summary>Per-character retained-window position in screen pixels.</summary>
|
||||
public readonly record struct UiWindowPosition(float X, float Y);
|
||||
|
||||
/// <summary>
|
||||
/// JSON-backed persistence for non-keybind settings (Display today; future
|
||||
/// tabs Audio / Gameplay / Chat / Character will be added to the same
|
||||
|
|
@ -290,6 +293,70 @@ public sealed class SettingsStore
|
|||
File.WriteAllText(_path, root.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
|
||||
}
|
||||
|
||||
/// <summary>Load a named retained-window position for one character.</summary>
|
||||
public UiWindowPosition? LoadWindowPosition(string toonKey, string windowName)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(toonKey);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(windowName);
|
||||
if (!File.Exists(_path)) return null;
|
||||
try
|
||||
{
|
||||
var root = JsonNode.Parse(File.ReadAllText(_path)) as JsonObject;
|
||||
var node = root?["windowPositions"]?[toonKey]?[windowName] as JsonObject;
|
||||
if (node is null) return null;
|
||||
float? x = node["x"]?.GetValue<float>();
|
||||
float? y = node["y"]?.GetValue<float>();
|
||||
return x is not null && y is not null ? new UiWindowPosition(x.Value, y.Value) : null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"settings: failed to load window position from {_path}: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save a named retained-window position under
|
||||
/// <c>windowPositions[toonKey][windowName]</c>, preserving all settings sections.
|
||||
/// </summary>
|
||||
public void SaveWindowPosition(string toonKey, string windowName, UiWindowPosition position)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(toonKey);
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(windowName);
|
||||
|
||||
var dir = Path.GetDirectoryName(_path);
|
||||
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
|
||||
|
||||
JsonObject root;
|
||||
if (File.Exists(_path))
|
||||
{
|
||||
try { root = JsonNode.Parse(File.ReadAllText(_path)) as JsonObject ?? new JsonObject(); }
|
||||
catch { root = new JsonObject(); }
|
||||
}
|
||||
else
|
||||
{
|
||||
root = new JsonObject();
|
||||
}
|
||||
|
||||
if (root["windowPositions"] is not JsonObject positions)
|
||||
{
|
||||
positions = new JsonObject();
|
||||
root["windowPositions"] = positions;
|
||||
}
|
||||
if (positions[toonKey] is not JsonObject toon)
|
||||
{
|
||||
toon = new JsonObject();
|
||||
positions[toonKey] = toon;
|
||||
}
|
||||
toon[windowName] = new JsonObject
|
||||
{
|
||||
["x"] = position.X,
|
||||
["y"] = position.Y,
|
||||
};
|
||||
root["version"] = CurrentSchemaVersion;
|
||||
File.WriteAllText(_path, root.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
|
||||
}
|
||||
|
||||
private static SortedDictionary<string, object> BuildChatObject(ChatSettings c)
|
||||
=> new(StringComparer.Ordinal)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue