From 96bed4ccef1cdd20351d2627186c8a7e72e1f315 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 21 Jun 2026 20:45:07 +0100 Subject: [PATCH] Share item stat ref parsing --- Aetheria.State.Verify/Program.cs | 5 ++- .../Tests/DaemonRuntimeDocumentTests.cs | 22 ++++++++++ Assets/Scripts/UI/Menu/InventoryMenu.cs | 41 +++---------------- .../AetheriaRuntimeDaemonItemStatQueries.cs | 35 ++++++++++++++++ 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/Aetheria.State.Verify/Program.cs b/Aetheria.State.Verify/Program.cs index 5214bdf2b..eb48fb966 100644 --- a/Aetheria.State.Verify/Program.cs +++ b/Aetheria.State.Verify/Program.cs @@ -4193,9 +4193,11 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root) } if (!source.Contains("ResolveInventorySurfaceStateRef", StringComparison.Ordinal) || - !source.Contains("TryReadItemStatRef(", StringComparison.Ordinal) || + !source.Contains("AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef(", StringComparison.Ordinal) || !source.Contains("AetheriaRuntimeDaemonItemStatQueries.ItemStatRef(", StringComparison.Ordinal) || !source.Contains("AetheriaRuntimeDaemonItemStatQueries.EvaluatePerformanceStat(", StringComparison.Ordinal) || + source.Contains("private static bool TryReadItemStatRef(", StringComparison.Ordinal) || + source.Contains("DecodeRefToken", StringComparison.Ordinal) || source.Contains("GameManager.ItemManager.GetTier", StringComparison.Ordinal) || source.Contains("GameManager.ItemManager.Evaluate", StringComparison.Ordinal) || actionGameManager.Contains("ObservedItemStat(", StringComparison.Ordinal) || @@ -4210,6 +4212,7 @@ static void RequireInventoryCargoItemDetailsUseEveSurface(string root) !surfaceDocument.Contains("public const string Value = \"valueRef\"", StringComparison.Ordinal) || !daemonItemStatQueries.Contains("public const string StateRefPrefix = \"aetheria.state/items\"", StringComparison.Ordinal) || !daemonItemStatQueries.Contains("public static string ItemStatRef(", StringComparison.Ordinal) || + !daemonItemStatQueries.Contains("public static bool TryReadItemStatRef(", StringComparison.Ordinal) || !daemonItemStatQueries.Contains("public string ValueRef =>", StringComparison.Ordinal) || !eveUnitySurfaceHost.Contains("Func stateRefResolver", StringComparison.Ordinal) || !eveUnitySurfaceHost.Contains("surface = ResolveStateRefs(surface, stateRefResolver)", StringComparison.Ordinal) || diff --git a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs index efeedc4e3..b0bb36caf 100644 --- a/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs +++ b/Assets/Scripts/Tests/DaemonRuntimeDocumentTests.cs @@ -1677,6 +1677,28 @@ public class DaemonRuntimeDocumentTests Assert.IsNull(envelope); } + [Test] + public void DaemonItemStatRefsRoundTripThroughSharedQueryHelper() + { + var stateRef = AetheriaRuntimeDaemonItemStatQueries.ItemStatRef( + "items/weapons/mining-laser", + "behavior/mining", + 2, + 7); + + Assert.IsTrue(AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef( + stateRef, + out var itemKey, + out var behaviorKind, + out var behaviorGroup, + out var fieldKey)); + + Assert.AreEqual("items/weapons/mining-laser", itemKey); + Assert.AreEqual("behavior/mining", behaviorKind); + Assert.AreEqual(2, behaviorGroup); + Assert.AreEqual(7, fieldKey); + } + [Test] public void DaemonOperationsMovesTargetSelectionIntoDaemonState() { diff --git a/Assets/Scripts/UI/Menu/InventoryMenu.cs b/Assets/Scripts/UI/Menu/InventoryMenu.cs index 832940236..cca23edf5 100644 --- a/Assets/Scripts/UI/Menu/InventoryMenu.cs +++ b/Assets/Scripts/UI/Menu/InventoryMenu.cs @@ -758,7 +758,12 @@ private string BuildEquippedItemTitle(EquippedItem item, AetheriaRuntimeCatalogI private bool TryResolveInventorySurfaceStateRef(string stateRef, out string value) { value = ""; - if (!TryReadItemStatRef(stateRef, out var itemKey, out var behaviorKind, out var behaviorGroup, out var fieldKey)) + if (!AetheriaRuntimeDaemonItemStatQueries.TryReadItemStatRef( + stateRef, + out var itemKey, + out var behaviorKind, + out var behaviorGroup, + out var fieldKey)) return false; var item = ResolveSelectedEquippableItem(itemKey); @@ -784,46 +789,12 @@ private string BuildEquippedItemTitle(EquippedItem item, AetheriaRuntimeCatalogI return ItemKeyMatches(cargo, itemKey) ? cargo : null; } - private static bool TryReadItemStatRef( - string stateRef, - out string itemKey, - out string behaviorKind, - out int behaviorGroup, - out int fieldKey) - { - itemKey = ""; - behaviorKind = ""; - behaviorGroup = -1; - fieldKey = -1; - - var parts = (stateRef ?? "").Split('/'); - if (parts.Length != 8 || - !string.Equals(parts[0], "aetheria.state", StringComparison.Ordinal) || - !string.Equals(parts[1], "items", StringComparison.Ordinal) || - !string.Equals(parts[3], "behaviors", StringComparison.Ordinal) || - !string.Equals(parts[6], "stats", StringComparison.Ordinal) || - !int.TryParse(parts[5], NumberStyles.Integer, CultureInfo.InvariantCulture, out behaviorGroup) || - !int.TryParse(parts[7], NumberStyles.Integer, CultureInfo.InvariantCulture, out fieldKey)) - { - return false; - } - - itemKey = DecodeRefToken(parts[2]); - behaviorKind = DecodeRefToken(parts[4]); - return !string.IsNullOrWhiteSpace(itemKey) && !string.IsNullOrWhiteSpace(behaviorKind); - } - private static bool ItemKeyMatches(EquippableItem item, string itemKey) { return item != null && string.Equals(item.ItemKey ?? "", itemKey ?? "", StringComparison.Ordinal); } - private static string DecodeRefToken(string token) - { - return (token ?? "").Replace("%2F", "/", StringComparison.Ordinal); - } - private static AetheriaRuntimeBehaviorValue ToRuntimeBehaviorValue(PerformanceStat stat) { return new AetheriaRuntimeBehaviorValue( diff --git a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonItemStatQueries.cs b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonItemStatQueries.cs index 4dd8c2adb..a3546f1f0 100644 --- a/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonItemStatQueries.cs +++ b/Packages/org.gamecult.aetheria.state/Runtime/AetheriaRuntimeDaemonItemStatQueries.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; #nullable enable @@ -50,6 +51,35 @@ namespace GameCult.Aetheria.State.Verse return $"{StateRefPrefix}/{Token(itemKey)}/behaviors/{Token(behaviorKind)}/{behaviorGroup}/stats/{fieldKey}"; } + public static bool TryReadItemStatRef( + string stateRef, + out string itemKey, + out string behaviorKind, + out int behaviorGroup, + out int fieldKey) + { + itemKey = ""; + behaviorKind = ""; + behaviorGroup = -1; + fieldKey = -1; + + var parts = (stateRef ?? "").Split('/'); + if (parts.Length != 8 || + !string.Equals(parts[0], "aetheria.state", StringComparison.Ordinal) || + !string.Equals(parts[1], "items", StringComparison.Ordinal) || + !string.Equals(parts[3], "behaviors", StringComparison.Ordinal) || + !string.Equals(parts[6], "stats", StringComparison.Ordinal) || + !int.TryParse(parts[5], NumberStyles.Integer, CultureInfo.InvariantCulture, out behaviorGroup) || + !int.TryParse(parts[7], NumberStyles.Integer, CultureInfo.InvariantCulture, out fieldKey)) + { + return false; + } + + itemKey = DecodeToken(parts[2]); + behaviorKind = DecodeToken(parts[4]); + return !string.IsNullOrWhiteSpace(itemKey) && !string.IsNullOrWhiteSpace(behaviorKind); + } + public static AetheriaRuntimeStatRecipePreviewState ConditionsFor( AetheriaRuntimeLoadoutItemCommit? item, double heat = 0, @@ -295,5 +325,10 @@ namespace GameCult.Aetheria.State.Verse ? "_" : value.Trim().Replace("/", "%2F"); } + + private static string DecodeToken(string value) + { + return (value ?? "").Replace("%2F", "/", StringComparison.Ordinal); + } } }