diff --git a/.voidbot/state/aetheria.cc b/.voidbot/state/aetheria.cc index 192ba8e75..5d4200132 100644 Binary files a/.voidbot/state/aetheria.cc and b/.voidbot/state/aetheria.cc differ diff --git a/Assets/Scripts/ServerShared/ItemManager.cs b/Assets/Scripts/ServerShared/ItemManager.cs index a945db109..d75eb6bbe 100644 --- a/Assets/Scripts/ServerShared/ItemManager.cs +++ b/Assets/Scripts/ServerShared/ItemManager.cs @@ -89,11 +89,6 @@ public class ItemManager return shape; } - public RuntimeItemReference CreateReference(ItemData item) - { - return new RuntimeItemReference(item); - } - public RuntimeItemReference CreateReference(Guid itemId) { return new RuntimeItemReference(itemId); @@ -221,57 +216,74 @@ public class ItemManager }; } - public SimpleCommodity CreateInstance(SimpleCommodityData item, int count) + public SimpleCommodity CreateSimpleCommodityInstance(AetheriaRuntimeCatalogItem item, int count) { - if (item != null) + var itemId = GetLegacyGuid(item); + if (itemId != Guid.Empty) { - var newItem = new SimpleCommodity + return new SimpleCommodity { - Data = CreateReference(item), + Data = CreateReference(itemId), Quantity = count }; - //ItemData.Add(newItem); - return newItem; } - - _logger("Attempted to create Simple Commodity instance using missing or incorrect item id"); + + _logger("Attempted to create simple commodity instance using missing typed item data"); return null; } public ItemInstance Instantiate(ItemInstance item) { - var data = GetData(item); - if(data is CraftedItemData c) + var typedItem = GetRuntimeItem(item); + if (typedItem == null) { - var i = CreateInstance(c); - i.Rotation = item.Rotation; - return i; + _logger($"Attempted to instantiate missing item id {item?.Data?.ItemId}"); + return null; } - if (item is SimpleCommodity s) + + ItemInstance instance = item switch { - var i = CreateInstance(data as SimpleCommodityData, s.Quantity); - i.Rotation = item.Rotation; - return i; - } - return null; + SimpleCommodity simple => CreateSimpleCommodityInstance(typedItem, simple.Quantity), + CraftedItemInstance => CreateCraftedInstance(typedItem), + _ => null + }; + + if (instance != null) + instance.Rotation = item.Rotation; + + return instance; } - public CraftedItemInstance CreateInstance(CraftedItemData item, float quality) + public CraftedItemInstance CreateCraftedInstance(AetheriaRuntimeCatalogItem item, float quality) { - if (item is EquippableItemData equippableItemData) + if (IsEquippable(item)) + return CreateEquippableInstance(item, quality); + + var itemId = GetLegacyGuid(item); + if (itemId == Guid.Empty) { - return new EquippableItem + throw new NullReferenceException("Attempted to create crafted item instance using missing typed item data!"); + } + + if (string.Equals(item.Category, nameof(ConsumableItemData), StringComparison.Ordinal)) + { + return new ConsumableItem { - Data = CreateReference(item), Quality = quality, Durability = GetInitialDurability(equippableItemData) + Data = CreateReference(itemId), + Quality = quality }; } - var newCommodity = new CompoundCommodity + return new CompoundCommodity { - Data = CreateReference(item), + Data = CreateReference(itemId), Quality = quality }; - return newCommodity; + } + + public CraftedItemInstance CreateCraftedInstance(AetheriaRuntimeCatalogItem item) + { + return CreateCraftedInstance(item, SelectCraftedQuality()); } public EquippableItem CreateEquippableInstance(AetheriaRuntimeCatalogItem item, float quality) @@ -295,23 +307,6 @@ public class ItemManager return CreateEquippableInstance(item, SelectCraftedQuality()); } - private float GetInitialDurability(EquippableItemData item) - { - var typedItem = GetRuntimeItem(item.ID); - return typedItem?.Durability > 0 ? (float)typedItem.Durability : item.Durability; - } - - public CraftedItemInstance CreateInstance(CraftedItemData item) - { - if (item == null) - { - throw new NullReferenceException("Attempted to create crafted item instance using missing or incorrect item data!"); - return null; - } - - return CreateInstance(item, SelectCraftedQuality()); - } - private float SelectCraftedQuality() { var quality = Random.NextFloat(); @@ -332,6 +327,12 @@ public class ItemManager : Guid.Empty; } + private static bool IsEquippable(AetheriaRuntimeCatalogItem item) + { + return !string.IsNullOrWhiteSpace(item?.HardpointType) || + string.Equals(item?.Category, nameof(HullData), StringComparison.Ordinal); + } + public (RarityTier tier, int upgrades) GetTier(CraftedItemInstance item) { var tier = GameplaySettings.Tiers[0]; diff --git a/docs/aetheria-perfect-machine-map.md b/docs/aetheria-perfect-machine-map.md index 764d51ebb..527e03540 100644 --- a/docs/aetheria-perfect-machine-map.md +++ b/docs/aetheria-perfect-machine-map.md @@ -233,9 +233,9 @@ legacy catalog cache, and legacy UI paths should be migration-only or deleted. max durability only, with current runtime durability as the generic denominator for incomplete typed rows. `ItemManager.Evaluate` also uses typed runtime item max durability and item names when evaluating unequipped - performance stats. `ItemManager.CreateInstance(CraftedItemData, float)` - initializes new equippable runtime durability from the typed runtime item row; - `EquippableItemData.Durability` is only an incomplete-row fallback. + performance stats. `ItemManager` typed item instantiation primitives create + simple commodities, crafted items, and equippable items from runtime catalog + rows; old DTO-based item creation is gone from blueprint cloning. `EquippedItem` also takes conductivity, max durability, thermal bounds, and thermal performance curve keys from the typed runtime item row for heat conduction, durability performance, thermal performance, and wear scaling. @@ -768,6 +768,10 @@ First Aetheria surfaces to publish: - Done: move runtime blueprint price aggregation and conductivity restore geometry onto typed runtime item price and hull shape rows; legacy `ItemData.Price` and `HullData.Shape` no longer own those blueprint paths. + - Done: move runtime blueprint item cloning off `ItemData` hydration and onto + typed runtime item rows; `ItemManager.Instantiate` now clones simple + commodities, crafted items, consumables, and equippables from + `AetheriaRuntimeCatalogItem` identity and facets. - Done: move final `Entity.ItemFits`, `TryFindSpace`, `TryEquip`, and `TryUnequip` gear occupancy/mass deltas onto typed catalog rows for item shape, hull shape/interior, hardpoint masks, cargo/docking category, and