diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 4481ec5dc..89a4bc489 100644 Binary files a/.voidbot/state/aetheria.cc and b/.voidbot/state/aetheria.cc differ diff --git a/Aetheria.State/README.md b/Aetheria.State/README.md index 25fe19524..caf391c09 100644 --- a/Aetheria.State/README.md +++ b/Aetheria.State/README.md @@ -83,10 +83,10 @@ legacy catalog group/table annotations; their remaining metadata is projection and inspection metadata for the typed runtime bridge. Item instances now carry `AetheriaRuntimeItemReference`, a typed item-key facade. `ItemInstance.ItemKey` is the identity surface, while `ItemId` is a -derived legacy-GUID compatibility projection for behavior config and broader -simulation paths. Cargo inventory indexes, consumable activation lookup, -action-bar consumable quantity/fill, transfer lookup, and trade owned counts -now use item keys. +derived legacy-GUID compatibility projection for broader simulation paths. +Cargo inventory indexes, consumable activation lookup, action-bar consumable +quantity/fill, transfer lookup, trade owned counts, weapon ammo references, and +item-use behavior references now use item keys. The old generic `RuntimeCatalogLink` abstraction, `ItemManager.GetData` hydration path, vague `ItemInstance.Data` identity field, and old `RuntimeItemReference.Projection` cache have been deleted; runtime item facts diff --git a/Assets/Scripts/ServerShared/AetheriaRuntimeItemReference.cs b/Assets/Scripts/ServerShared/AetheriaRuntimeItemReference.cs index b7df3cabd..df6c7d949 100644 --- a/Assets/Scripts/ServerShared/AetheriaRuntimeItemReference.cs +++ b/Assets/Scripts/ServerShared/AetheriaRuntimeItemReference.cs @@ -38,6 +38,11 @@ public class AetheriaRuntimeItemReference return legacyItemId == Guid.Empty ? "" : $"{LegacyItemDefinitionPrefix}{legacyItemId:D}"; } + public static Guid ToLegacyId(string itemKey) + { + return TryParseLegacyId(itemKey, out var itemId) ? itemId : Guid.Empty; + } + private static bool TryParseLegacyId(string itemKey, out Guid itemId) { itemId = Guid.Empty; diff --git a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs index 11409bc11..14c256e18 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ConstantWeapon.cs @@ -84,7 +84,7 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior OnStopFiring?.Invoke(); return false; } - if (_data.AmmoType != Guid.Empty) + if (!string.IsNullOrWhiteSpace(_data.AmmoItemKey)) { if (_reloading) { @@ -104,10 +104,10 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior if (_data.MagazineSize > 1 && _ammo > 0) _ammo--; else { - var cargo = Entity.FindItemInCargo(_data.AmmoType); + var cargo = Entity.FindItemInCargo(_data.AmmoItemKey); if (cargo != null) { - var item = cargo.GetFirstItem(_data.AmmoType); + var item = cargo.GetFirstItem(_data.AmmoItemKey); if (item is SimpleCommodity simpleCommodity) cargo.Remove(simpleCommodity, 1); diff --git a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs index 85921bae4..f36cc0032 100644 --- a/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/InstantWeapon.cs @@ -127,12 +127,12 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior } var hasAmmo = true; - if (_data.AmmoType != Guid.Empty) + if (!string.IsNullOrWhiteSpace(_data.AmmoItemKey)) { - var cargo = Entity.FindItemInCargo(_data.AmmoType); + var cargo = Entity.FindItemInCargo(_data.AmmoItemKey); if (cargo != null) { - var item = cargo.GetFirstItem(_data.AmmoType); + var item = cargo.GetFirstItem(_data.AmmoItemKey); if (item is SimpleCommodity simpleCommodity) cargo.Remove(simpleCommodity, 1); } diff --git a/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs b/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs index 949543508..d764f06e2 100644 --- a/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs +++ b/Assets/Scripts/ServerShared/Behaviors/ItemUsage.cs @@ -7,7 +7,8 @@ using System.Linq; [Inspectable, Order(-5)] public class ItemUsageConfig : RuntimeBehaviorConfig { - public Guid Item; + public string ItemKey; + public Guid Item => AetheriaRuntimeItemReference.ToLegacyId(ItemKey); public override Behavior CreateInstance(EquippedItem item) { @@ -36,10 +37,10 @@ public class ItemUsage : Behavior public override bool Execute(float dt) { - var cargo = Entity.FindItemInCargo(_data.Item); + var cargo = Entity.FindItemInCargo(_data.ItemKey); if (cargo == null) return false; - var item = cargo.GetFirstItem(_data.Item); + var item = cargo.GetFirstItem(_data.ItemKey); if (item is SimpleCommodity simpleCommodity) cargo.Remove(simpleCommodity, 1); if (item is CraftedItemInstance craftedItemInstance) diff --git a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs index c7250668a..1b41e2386 100644 --- a/Assets/Scripts/ServerShared/Behaviors/Weapon.cs +++ b/Assets/Scripts/ServerShared/Behaviors/Weapon.cs @@ -43,7 +43,8 @@ public abstract class WeaponConfig : RuntimeBehaviorConfig [InspectablePrefab] public PerformanceStat Visibility = new PerformanceStat(); - public Guid AmmoType; + public string AmmoItemKey; + public Guid AmmoType => AetheriaRuntimeItemReference.ToLegacyId(AmmoItemKey); [InspectablePrefab] public int MagazineSize; @@ -69,9 +70,10 @@ public abstract class Weapon : Behavior, IActivatedBehavior public abstract int Ammo { get; } public DamageType DamageType { get; } public string EffectPrefab { get; } + public string AmmoItemKey { get; } public Guid AmmoType { get; } public int MagazineSize { get; } - public bool UsesAmmo => AmmoType != Guid.Empty; + public bool UsesAmmo => !string.IsNullOrWhiteSpace(AmmoItemKey); public GuidedProjectileTargetMode GuidedProjectileTargeting { get; private set; } public bool HasGuidedProjectileProfile => GuidedProjectileTargeting != GuidedProjectileTargetMode.None; public float4[] GuidedProjectileGuidanceCurve { get; private set; } @@ -102,6 +104,7 @@ public abstract class Weapon : Behavior, IActivatedBehavior _data = data; DamageType = data.DamageType; EffectPrefab = data.EffectPrefab ?? ""; + AmmoItemKey = data.AmmoItemKey; AmmoType = data.AmmoType; MagazineSize = data.MagazineSize; InitializeGuidedProjectileProfile(data); @@ -112,6 +115,7 @@ public abstract class Weapon : Behavior, IActivatedBehavior _data = data; DamageType = data.DamageType; EffectPrefab = data.EffectPrefab ?? ""; + AmmoItemKey = data.AmmoItemKey; AmmoType = data.AmmoType; MagazineSize = data.MagazineSize; InitializeGuidedProjectileProfile(data); diff --git a/Assets/Scripts/ServerShared/ItemManager.cs b/Assets/Scripts/ServerShared/ItemManager.cs index 23c577840..41aa13052 100644 --- a/Assets/Scripts/ServerShared/ItemManager.cs +++ b/Assets/Scripts/ServerShared/ItemManager.cs @@ -185,7 +185,7 @@ public class ItemManager private static void ApplyItemUsageConfig(ItemUsageConfig config, BehaviorPayloadReader reader) { - config.Item = reader.Guid(1, config.Item); + config.ItemKey = reader.ItemKey(1, config.ItemKey); } private static void ApplyMiningToolConfig(MiningToolConfig config, BehaviorPayloadReader reader) @@ -303,7 +303,7 @@ public class ItemManager config.Energy = reader.PerformanceStat(9, config.Energy); config.Heat = reader.PerformanceStat(10, config.Heat); config.Visibility = reader.PerformanceStat(11, config.Visibility); - config.AmmoType = reader.Guid(12, config.AmmoType); + config.AmmoItemKey = reader.ItemKey(12, config.AmmoItemKey); config.MagazineSize = reader.Int(13, config.MagazineSize); config.ReloadTime = reader.Float(14, config.ReloadTime); config.Spread = reader.PerformanceStat(15, config.Spread); @@ -424,6 +424,13 @@ public class ItemManager : fallback; } + public string ItemKey(int key, string fallback = "") + { + return Guid(key) is var itemId && itemId != System.Guid.Empty + ? AetheriaRuntimeItemReference.FromLegacyId(itemId) + : fallback; + } + public T Enum(int key, T fallback) where T : struct { if (!_fields.TryGetValue(key, out var value)) diff --git a/Assets/Scripts/UI/HUD/SchematicDisplay.cs b/Assets/Scripts/UI/HUD/SchematicDisplay.cs index a2f207caa..f77e2d2fa 100644 --- a/Assets/Scripts/UI/HUD/SchematicDisplay.cs +++ b/Assets/Scripts/UI/HUD/SchematicDisplay.cs @@ -256,7 +256,7 @@ public class SchematicDisplay : MonoBehaviour if(x.Weapon.MagazineSize > 1) x.ListElement.AmmoLabel.text = x.Weapon.Ammo.ToString(); else - x.ListElement.AmmoLabel.text = _entity.CountItemsInCargo(x.Weapon.AmmoType).ToString(); + x.ListElement.AmmoLabel.text = _entity.CountItemsInCargo(x.Weapon.AmmoItemKey).ToString(); } } diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 69280230a..97bb73f2b 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -53,8 +53,8 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. while hosting the CultMesh state node. `Aetheria.State.ApplyPending` remains a bounded local operator applicator for both pending lanes. - Shared item domain state is still partly built around `AetheriaRuntimeItemReference`, - `ItemData`, `RuntimeBehaviorConfig`, derived GUID compatibility in behavior - config and broader simulation paths, and runtime catalog metadata. Dead + `ItemData`, `RuntimeBehaviorConfig`, derived GUID compatibility in broader + simulation paths, and runtime catalog metadata. Dead user-record and galaxy-map-layer catalog roots have been deleted, and surviving runtime DTOs no longer carry legacy catalog group/table annotations. Newtonsoft, JsonKnownTypes, RethinkDB, LiteNetLib client transport, and the broken @@ -624,7 +624,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. legacy-GUID compatibility projection. `EquippedCargoBay.ItemsOfType`, consumable activation, action-bar consumable fill/quantity display, item transfer lookup, and trade owned-count rows now use item keys rather than - GUID-owned cargo indexes; + GUID-owned cargo indexes. Weapon ammo and item-use behavior config item + references are also typed-key-first (`AmmoItemKey`/`ItemKey`), with + `AmmoType`/`Item` only derived GUID compatibility; there is no remaining `ItemInstance.Data` identity/backing field. The reader interface for this bridge is named `IRuntimeItemCatalogReader` and exposes only typed catalog row lookup. Behavior @@ -1203,9 +1205,10 @@ First Aetheria surfaces to publish: `Aetheria.Shared.Unity`; the remaining MessagePack reference is contained in the typed state package's `.cc` reader. - In progress: convert domain references from GUID/base-class patterns to - typed record refs. Item instances and cargo inventory indexes now carry - typed item keys; remaining behavior config and broader simulation paths - still derive legacy GUIDs until those structures move to typed keys. + typed record refs. Item instances, cargo inventory indexes, weapon ammo + references, and item-use behavior references now carry typed item keys; + remaining broader simulation paths still derive legacy GUIDs until those + structures move to typed keys. - Remove runtime dependency on `ItemData` DTOs as item instance owners. 5. Mesh host @@ -1327,6 +1330,10 @@ First Aetheria surfaces to publish: counts from derived `Guid ItemId` keys to typed `ItemKey` strings. GUID behavior-config fields still translate at the cargo boundary until behavior config construction moves to typed item references. + - Done: move weapon ammo and `ItemUsage` config references from GUID fields + to typed item-key fields. `AmmoType` and `Item` remain derived compatibility + properties, but runtime ammo consumption, item use, and HUD ammo counts use + `AmmoItemKey`/`ItemKey`. - Done: delete the dead `ItemManager.GetRuntimeItemProjection` bridge after loadout generation stopped hydrating selected typed rows into `EquippableItemData` merely to instantiate equipment.