Use typed item keys in behavior item refs

This commit is contained in:
Meta Vens 2026-06-14 23:31:54 +01:00
commit 95bd76ee91
10 changed files with 48 additions and 24 deletions

Binary file not shown.

View file

@ -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<T>` abstraction, `ItemManager.GetData`
hydration path, vague `ItemInstance.Data` identity field, and old
`RuntimeItemReference.Projection` cache have been deleted; runtime item facts

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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)

View file

@ -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);

View file

@ -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<T>(int key, T fallback) where T : struct
{
if (!_fields.TryGetValue(key, out var value))

View file

@ -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();
}
}

View file

@ -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<T>` bridge
after loadout generation stopped hydrating selected typed rows into
`EquippableItemData` merely to instantiate equipment.