diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 4ccbc89cb..192ba8e75 100644 Binary files a/.voidbot/state/aetheria.cc and b/.voidbot/state/aetheria.cc differ diff --git a/Assets/Scripts/UI/Menu/TradeMenu.cs b/Assets/Scripts/UI/Menu/TradeMenu.cs index 8e042e269..69e163748 100644 --- a/Assets/Scripts/UI/Menu/TradeMenu.cs +++ b/Assets/Scripts/UI/Menu/TradeMenu.cs @@ -316,7 +316,7 @@ public class TradeMenu : MonoBehaviour Output = x.output(i), SortKey = x.sortKey(i) }).ToArray(), - OnClick = () => Properties.Inspect(i.Item), + OnClick = () => Properties.Inspect(i.TypedItem), OnDoubleClick = () => { switch (i.Item) diff --git a/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs b/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs index 543d1667c..c2af52a33 100644 --- a/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs +++ b/Assets/Scripts/UI/Properties Panel/PropertiesPanel.cs @@ -454,8 +454,11 @@ public class PropertiesPanel : MonoBehaviour return; } - var typedItem = FindTypedPropertyItem(item); + AddTypedBehaviorProperties(FindTypedPropertyItem(item), statValueFunction); + } + private void AddTypedBehaviorProperties(AetheriaRuntimeCatalogItem typedItem, Func statValueFunction) + { var sheet = AddStatSheet(); foreach (var behavior in typedItem?.BehaviorPayloads ?? Array.Empty()) { @@ -716,45 +719,38 @@ public class PropertiesPanel : MonoBehaviour RefreshValues(); } - public void Inspect(ItemData data) + public void Inspect(AetheriaRuntimeCatalogItem item) { - AddProperty("Type", () => data.Name); - AddProperty(data.Description).Label.fontStyle = FontStyles.Normal; - if (data is EquippableItemData gearData) + Clear(); + if (item == null) { - AddProperty("Durability", () => ActionGameManager.RuntimePlayerSettings.Format(gearData.Durability)); - var sheet = AddStatSheet(); - foreach (var behavior in gearData.Behaviors) - { - if (behavior is StatModifierData statMod) - { - if(Math.Abs(statMod.Modifier.Min - statMod.Modifier.Max) < .001f) - sheet.AddStat($"{statMod.Stat.Target}:{statMod.Stat.Stat}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.RuntimePlayerSettings.Format(statMod.Modifier.Min)}"); - else - sheet.AddStat($"{statMod.Stat.Target}:{statMod.Stat.Stat}", () => $"{(statMod.Type == StatModifierType.Constant ? "+" : "x")}{ActionGameManager.RuntimePlayerSettings.Format(statMod.Modifier.Min)}-{ActionGameManager.RuntimePlayerSettings.Format(statMod.Modifier.Max)}"); - } - var type = behavior.GetType(); - if (type.GetCustomAttribute(typeof(RuntimeInspectable)) != null) - { - foreach (var field in type.GetFields().Where(f => f.GetCustomAttribute() != null)) - { - var fieldType = field.FieldType; - if (fieldType == typeof(float)) - sheet.AddStat(field.Name, () => $"{ActionGameManager.RuntimePlayerSettings.Format((float) field.GetValue(behavior))}"); - else if (fieldType == typeof(int)) - sheet.AddStat(field.Name, () => $"{(int) field.GetValue(behavior)}"); - else if (fieldType == typeof(PerformanceStat)) - { - var stat = (PerformanceStat) field.GetValue(behavior); - if(Math.Abs(stat.Min - stat.Max) < .001f) - sheet.AddStat(field.Name, () => $"{ActionGameManager.RuntimePlayerSettings.Format(stat.Min)}"); - else - sheet.AddStat(field.Name, () => $"{ActionGameManager.RuntimePlayerSettings.Format(stat.Min)}-{ActionGameManager.RuntimePlayerSettings.Format(stat.Max)}"); - } - } - } - } + RefreshValues(); + return; } + + Title.text = item.Name; + AddProperty(item.Description).Label.fontStyle = FontStyles.Normal; + + var sheet = AddStatSheet(); + var manufacturer = ActionGameManager.RuntimeCatalog?.GetManufacturer(item); + sheet.AddStat("Manufacturer", () => manufacturer?.Name ?? "GameCult"); + sheet.AddStat("Mass", () => ActionGameManager.RuntimePlayerSettings.Format((float)item.Mass)); + sheet.AddStat("Price", () => item.Price.ToString("N0")); + + if (!string.IsNullOrWhiteSpace(item.HardpointType)) + { + sheet.AddStat("Durability", () => ActionGameManager.RuntimePlayerSettings.Format((float)item.Durability)); + var thermalRange = GetThermalRange(item); + var heatCurve = AddCurveField(); + heatCurve.Show( + "Thermal Performance", + GetThermalPerformanceCurve(item), + t => ActionGameManager.RuntimePlayerSettings.FormatTemperature(lerp(thermalRange.minimum, thermalRange.maximum, t)), + true); + AddTypedBehaviorProperties(item, stat => stat.Min); + } + + RefreshValues(); } public void Inspect(object obj, bool inspectablesOnly = false, bool readWrite = false, bool topLevel = true) diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 0e329731e..e487696e8 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -220,8 +220,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. manufacturer, base mass, max durability, thermal bounds, and thermal performance curve keys for basic item presentation without hydrating legacy DTOs. Runtime behavior stat display and damage-range curves read typed - behavior payload fields by legacy payload key; the explicit `Inspect(ItemData)` - overload remains a legacy DTO inspection surface. Incomplete typed thermal + behavior payload fields by legacy payload key. The old explicit + `Inspect(ItemData)` DTO inspection overload is deleted; trade row clicks now + inspect the typed runtime catalog row directly. Incomplete typed thermal curve rows render a neutral fallback curve instead of hydrating legacy `EquippableItemData`. Inventory selection highlighting now uses typed item shape cells only for UI tint geometry; incomplete typed rows produce no @@ -731,9 +732,9 @@ First Aetheria surfaces to publish: thermal curve presentation onto typed catalog rows; incomplete typed rows use a neutral fallback curve instead of hydrating legacy thermal DTOs. - Done: move PropertiesPanel runtime behavior stat display and damage-range - curves onto typed behavior payload fields; only the explicit - `Inspect(ItemData)` projection inspector still reflects legacy behavior - DTOs. + curves onto typed behavior payload fields, and delete the explicit + `Inspect(ItemData)` projection inspector after moving trade row inspection + onto typed runtime catalog rows. - Done: remove the loot pickup presentation fallback to legacy `ItemData`; typed category/name rows now decide pickup visuals and scan labels, and missing typed rows render generic unknown gear pickup presentation.