]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Convert ItemSize to prototypes (#21481)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Mon, 6 Nov 2023 07:20:50 +0000 (02:20 -0500)
committerGitHub <noreply@github.com>
Mon, 6 Nov 2023 07:20:50 +0000 (00:20 -0700)
* item sizes are prototypes

* eek

20 files changed:
Content.Client/Storage/UI/StorageWindow.cs
Content.IntegrationTests/Tests/StorageTest.cs
Content.Server/Storage/Components/SecretStashComponent.cs
Content.Server/Storage/EntitySystems/SecretStashSystem.cs
Content.Server/UserInterface/StatValuesCommand.cs
Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs
Content.Shared/Inventory/InventorySystem.Equip.cs
Content.Shared/Item/ItemComponent.cs
Content.Shared/Item/ItemSizePrototype.cs [new file with mode: 0644]
Content.Shared/Item/ItemToggleComponent.cs
Content.Shared/Item/SharedItemSystem.cs
Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs
Content.Shared/Storage/StorageComponent.cs
Resources/Prototypes/Catalog/Fills/Boxes/general.yml
Resources/Prototypes/Entities/Clothing/Shoes/specific.yml
Resources/Prototypes/Entities/Objects/Fun/candy_bucket.yml
Resources/Prototypes/Entities/Objects/Misc/candles.yml
Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml
Resources/Prototypes/Entities/Objects/Weapons/Melee/sledgehammer.yml
Resources/Prototypes/item_size.yml [new file with mode: 0644]

index fb3f7cd33fa8c8c6de1fabeac4632fbaae58a572..b096e8d472ed23c3446651974f51dc5a216c429b 100644 (file)
@@ -1,4 +1,5 @@
 using System.Numerics;
+using Content.Client.Items.Systems;
 using Content.Client.Message;
 using Robust.Client.Graphics;
 using Robust.Client.UserInterface.Controls;
@@ -23,6 +24,7 @@ namespace Content.Client.Storage.UI
         private readonly IEntityManager _entityManager;
 
         private readonly SharedStorageSystem _storage;
+        private readonly ItemSystem _item;
 
         private readonly RichTextLabel _information;
         public readonly ContainerButton StorageContainerButton;
@@ -34,6 +36,7 @@ namespace Content.Client.Storage.UI
         {
             _entityManager = entityManager;
             _storage = _entityManager.System<SharedStorageSystem>();
+            _item = _entityManager.System<ItemSystem>();
             SetSize = new Vector2(240, 320);
             Title = Loc.GetString("comp-storage-window-title");
             RectClipContent = true;
@@ -69,7 +72,7 @@ namespace Content.Client.Storage.UI
             _information.SetMessage(Loc.GetString("comp-storage-window-weight",
                 ("weight", 0),
                 ("maxWeight", 0),
-                ("size", SharedItemSystem.GetItemSizeLocale(ItemSize.Normal))));
+                ("size", _item.GetItemSizeLocale(SharedStorageSystem.DefaultStorageMaxItemSize))));
 
             vBox.AddChild(_information);
 
@@ -117,14 +120,14 @@ namespace Content.Client.Storage.UI
                 _information.SetMarkup(Loc.GetString("comp-storage-window-weight",
                     ("weight", _storage.GetCumulativeItemSizes(uid, uid.Comp)),
                     ("maxWeight", uid.Comp.MaxTotalWeight),
-                    ("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp))))));
+                    ("size", _item.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp))))));
             }
             else
             {
                 _information.SetMarkup(Loc.GetString("comp-storage-window-slots",
                     ("itemCount", uid.Comp.Container.ContainedEntities.Count),
                     ("maxCount", uid.Comp.MaxSlots),
-                    ("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp))))));
+                    ("size", _item.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp))))));
             }
         }
 
@@ -167,7 +170,7 @@ namespace Content.Client.Storage.UI
                         {
                             Align = Label.AlignMode.Right,
                             Text = item?.Size != null
-                                ? $"{SharedItemSystem.GetItemSizeWeight(item.Size)}"
+                                ? $"{_item.GetItemSizeWeight(item.Size)}"
                                 : Loc.GetString("comp-storage-no-item-size")
                         }
                     }
index e9781ef47a2856a841c43c083d2395916443c6b1..a5944f43949f2f4252b0f7c24484b9168598e9a1 100644 (file)
@@ -26,6 +26,9 @@ namespace Content.IntegrationTests.Tests
             var server = pair.Server;
 
             var protoManager = server.ResolveDependency<IPrototypeManager>();
+            var entMan = server.ResolveDependency<IEntityManager>();
+
+            var itemSys = entMan.System<SharedItemSystem>();
 
             await server.WaitAssertion(() =>
             {
@@ -37,7 +40,9 @@ namespace Content.IntegrationTests.Tests
                         !proto.TryGetComponent<ItemComponent>("Item", out var item))
                         continue;
 
-                    Assert.That(storage.MaxItemSize.Value, Is.LessThanOrEqualTo(item.Size), $"Found storage arbitrage on {proto.ID}");
+                    Assert.That(itemSys.GetSizePrototype(storage.MaxItemSize.Value).Weight,
+                        Is.LessThanOrEqualTo(itemSys.GetSizePrototype(item.Size).Weight),
+                        $"Found storage arbitrage on {proto.ID}");
                 }
             });
             await pair.CleanReturnAsync();
@@ -77,10 +82,16 @@ namespace Content.IntegrationTests.Tests
             await using var pair = await PoolManager.GetServerClient();
             var server = pair.Server;
 
+            var entMan = server.ResolveDependency<IEntityManager>();
             var protoMan = server.ResolveDependency<IPrototypeManager>();
             var compFact = server.ResolveDependency<IComponentFactory>();
             var id = compFact.GetComponentName(typeof(StorageFillComponent));
 
+            var itemSys = entMan.System<SharedItemSystem>();
+
+            var allSizes = protoMan.EnumeratePrototypes<ItemSizePrototype>().ToList();
+            allSizes.Sort();
+
             Assert.Multiple(() =>
             {
                 foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
@@ -97,14 +108,29 @@ namespace Content.IntegrationTests.Tests
                     proto.TryGetComponent<ItemComponent>("Item", out var item);
 
                     var fill = (StorageFillComponent) proto.Components[id].Component;
-                    var size = GetFillSize(fill, false, protoMan);
-                    var maxSize = storage.MaxItemSize ??
-                                  (item?.Size == null
-                                      ? SharedStorageSystem.DefaultStorageMaxItemSize
-                                      : (ItemSize) Math.Max(0, (int) item.Size - 1));
+                    var size = GetFillSize(fill, false, protoMan, itemSys);
+
+                    var maxSize = storage.MaxItemSize;
+                    if (storage.MaxItemSize == null)
+                    {
+                        if (item?.Size == null)
+                        {
+                            maxSize = SharedStorageSystem.DefaultStorageMaxItemSize;
+                        }
+                        else
+                        {
+                            var curIndex = allSizes.IndexOf(protoMan.Index(item.Size));
+                            var index = Math.Max(0, curIndex - 1);
+                            maxSize = allSizes[index].ID;
+                        }
+                    }
+
+                    if (maxSize == null)
+                        continue;
+
                     if (storage.MaxSlots != null)
                     {
-                        Assert.That(GetFillSize(fill, true, protoMan), Is.LessThanOrEqualTo(storage.MaxSlots),
+                        Assert.That(GetFillSize(fill, true, protoMan, itemSys), Is.LessThanOrEqualTo(storage.MaxSlots),
                             $"{proto.ID} storage fill has too many items.");
                     }
                     else
@@ -123,14 +149,14 @@ namespace Content.IntegrationTests.Tests
                         if (!fillItem.TryGetComponent<ItemComponent>("Item", out var entryItem))
                             continue;
 
-                        Assert.That(entryItem.Size, Is.LessThanOrEqualTo(maxSize),
+                        Assert.That(protoMan.Index(entryItem.Size).Weight,
+                            Is.LessThanOrEqualTo(protoMan.Index(maxSize.Value).Weight),
                             $"Entity {proto.ID} has storage-fill item, {entry.PrototypeId}, that is too large");
                     }
                 }
             });
 
             await pair.CleanReturnAsync();
-
         }
 
         [Test]
@@ -139,10 +165,13 @@ namespace Content.IntegrationTests.Tests
             await using var pair = await PoolManager.GetServerClient();
             var server = pair.Server;
 
+            var entMan = server.ResolveDependency<IEntityManager>();
             var protoMan = server.ResolveDependency<IPrototypeManager>();
             var compFact = server.ResolveDependency<IComponentFactory>();
             var id = compFact.GetComponentName(typeof(StorageFillComponent));
 
+            var itemSys = entMan.System<SharedItemSystem>();
+
             Assert.Multiple(() =>
             {
                 foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
@@ -157,7 +186,7 @@ namespace Content.IntegrationTests.Tests
                     }
 
                     var fill = (StorageFillComponent) proto.Components[id].Component;
-                    var size = GetFillSize(fill, true, protoMan);
+                    var size = GetFillSize(fill, true, protoMan, itemSys);
                     Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity),
                         $"{proto.ID} storage fill is too large.");
                 }
@@ -165,7 +194,7 @@ namespace Content.IntegrationTests.Tests
             await pair.CleanReturnAsync();
         }
 
-        private int GetEntrySize(EntitySpawnEntry entry, bool getCount, IPrototypeManager protoMan)
+        private int GetEntrySize(EntitySpawnEntry entry, bool getCount, IPrototypeManager protoMan, SharedItemSystem itemSystem)
         {
             if (entry.PrototypeId == null)
                 return 0;
@@ -179,20 +208,21 @@ namespace Content.IntegrationTests.Tests
             if (getCount)
                 return entry.Amount;
 
+
             if (proto.TryGetComponent<ItemComponent>("Item", out var item))
-                return SharedItemSystem.GetItemSizeWeight(item.Size) * entry.Amount;
+                return itemSystem.GetItemSizeWeight(item.Size) * entry.Amount;
 
             Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}");
             return 0;
         }
 
-        private int GetFillSize(StorageFillComponent fill, bool getCount, IPrototypeManager protoMan)
+        private int GetFillSize(StorageFillComponent fill, bool getCount, IPrototypeManager protoMan, SharedItemSystem itemSystem)
         {
             var totalSize = 0;
             var groups = new Dictionary<string, int>();
             foreach (var entry in fill.Contents)
             {
-                var size = GetEntrySize(entry, getCount, protoMan);
+                var size = GetEntrySize(entry, getCount, protoMan, itemSystem);
 
                 if (entry.GroupId == null)
                     totalSize += size;
index 6c7095617c2ec22730b9479643a5cf6c6a29da3b..a63cb074ad2264d9cea55233729d3c3bb67348bd 100644 (file)
@@ -3,6 +3,7 @@ using Content.Shared.Containers.ItemSlots;
 using Content.Shared.Item;
 using Content.Shared.Toilet;
 using Robust.Shared.Containers;
+using Robust.Shared.Prototypes;
 
 namespace Content.Server.Storage.Components
 {
@@ -19,7 +20,7 @@ namespace Content.Server.Storage.Components
         ///     Max item size that can be fitted into secret stash.
         /// </summary>
         [DataField("maxItemSize")]
-        public ItemSize MaxItemSize = ItemSize.Small;
+        public ProtoId<ItemSizePrototype> MaxItemSize = "Small";
 
         /// <summary>
         ///     IC secret stash name. For example "the toilet cistern".
index 81e8bd431ef97b2a1117eb16f0d92f9cdd750ebc..49be0a2f880f15be58da55a49359f0434102b4f7 100644 (file)
@@ -13,6 +13,7 @@ namespace Content.Server.Storage.EntitySystems
         [Dependency] private readonly PopupSystem _popupSystem = default!;
         [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
         [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+        [Dependency] private readonly SharedItemSystem _item = default!;
 
         public override void Initialize()
         {
@@ -66,7 +67,7 @@ namespace Content.Server.Storage.EntitySystems
             }
 
             // check if item is too big to fit into secret stash
-            if (item.Size > component.MaxItemSize)
+            if (_item.GetSizePrototype(item.Size) > _item.GetSizePrototype(component.MaxItemSize))
             {
                 var msg = Loc.GetString("comp-secret-stash-action-hide-item-too-big",
                     ("item", itemToHideUid), ("stash", GetSecretPartName(uid, component)));
index 3021233a1c9a95db41f3a843c60007ff6bcaabe6..9ec38753d404f07025b341a184a08fdfc5d87bec 100644 (file)
@@ -127,6 +127,7 @@ public sealed class StatValuesCommand : IConsoleCommand
     private StatValuesEuiMessage GetItem()
     {
         var values = new List<string[]>();
+        var itemSystem = _entManager.System<ItemSystem>();
         var metaQuery = _entManager.GetEntityQuery<MetaDataComponent>();
         var itemQuery = _entManager.GetEntityQuery<ItemComponent>();
         var items = new HashSet<string>(1024);
@@ -149,7 +150,7 @@ public sealed class StatValuesCommand : IConsoleCommand
             values.Add(new[]
             {
                 id,
-                $"{SharedItemSystem.GetItemSizeLocale(itemComp.Size)}",
+                $"{itemSystem.GetItemSizeLocale(itemComp.Size)}",
             });
         }
 
index 80316d64f9ae47b0a51ef71b82538839c04bacf1..c943aeb7f0cedc8f96695d8f790d4b27ac608c0e 100644 (file)
@@ -98,7 +98,7 @@ public sealed class EnergySwordSystem : EntitySystem
     {
         if (TryComp(uid, out ItemComponent? item))
         {
-            _item.SetSize(uid, ItemSize.Small, item);
+            _item.SetSize(uid, "Small", item);
         }
 
         if (TryComp<DisarmMalusComponent>(uid, out var malus))
@@ -125,7 +125,7 @@ public sealed class EnergySwordSystem : EntitySystem
     {
         if (TryComp(uid, out ItemComponent? item))
         {
-            _item.SetSize(uid, ItemSize.Huge, item);
+            _item.SetSize(uid, "Huge", item);
         }
 
         if (comp.IsSharp)
index 23c0fbd0a2d29ade27b942c399d9208882f4ecba..7b6ccaf0d485deed6f1f3bb1096fa428bf907205 100644 (file)
@@ -14,6 +14,7 @@ using Robust.Shared.Audio;
 using Robust.Shared.Containers;
 using Robust.Shared.Network;
 using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Timing;
 
 namespace Content.Shared.Inventory;
@@ -23,12 +24,16 @@ public abstract partial class InventorySystem
     [Dependency] private readonly SharedPopupSystem _popup = default!;
     [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
     [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+    [Dependency] private readonly SharedItemSystem _item = default!;
     [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
     [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
     [Dependency] private readonly IGameTiming _gameTiming = default!;
     [Dependency] private readonly INetManager _netMan = default!;
     [Dependency] private readonly SharedTransformSystem _transform = default!;
 
+    [ValidatePrototypeId<ItemSizePrototype>]
+    private const string PocketableItemSize = "Small";
+
     private void InitializeEquip()
     {
         //these events ensure that the client also gets its proper events raised when getting its containerstate updated
@@ -264,7 +269,9 @@ public abstract partial class InventorySystem
         if (slotDefinition.DependsOn != null && !TryGetSlotEntity(target, slotDefinition.DependsOn, out _, inventory))
             return false;
 
-        var fittingInPocket = slotDefinition.SlotFlags.HasFlag(SlotFlags.POCKET) && item is { Size: <= ItemSize.Small };
+        var fittingInPocket = slotDefinition.SlotFlags.HasFlag(SlotFlags.POCKET) &&
+                              item != null &&
+                              _item.GetSizePrototype(item.Size) <= _item.GetSizePrototype(PocketableItemSize);
         if (clothing == null && !fittingInPocket
             || clothing != null && !clothing.Slots.HasFlag(slotDefinition.SlotFlags) && !fittingInPocket)
         {
index 2c667b778a2ab2dabc76ad827d5d0ac93627fe6f..ef4d4513207b4ea4e987a7f71d7826c996ee99a9 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Shared.Hands.Components;
 using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization;
 
 namespace Content.Shared.Item;
@@ -15,7 +16,7 @@ public sealed partial class ItemComponent : Component
 {
     [DataField, ViewVariables(VVAccess.ReadWrite)]
     [Access(typeof(SharedItemSystem))]
-    public ItemSize Size = ItemSize.Small;
+    public ProtoId<ItemSizePrototype> Size = "Small";
 
     [Access(typeof(SharedItemSystem))]
     [DataField]
@@ -38,10 +39,10 @@ public sealed partial class ItemComponent : Component
 [Serializable, NetSerializable]
 public sealed class ItemComponentState : ComponentState
 {
-    public ItemSize Size { get; }
+    public ProtoId<ItemSizePrototype> Size { get; }
     public string? HeldPrefix { get; }
 
-    public ItemComponentState(ItemSize size, string? heldPrefix)
+    public ItemComponentState(ProtoId<ItemSizePrototype> size, string? heldPrefix)
     {
         Size = size;
         HeldPrefix = heldPrefix;
@@ -64,40 +65,3 @@ public sealed class VisualsChangedEvent : EntityEventArgs
         ContainerId = containerId;
     }
 }
-
-/// <summary>
-/// Abstracted sizes for items.
-/// Used to determine what can fit into inventories.
-/// </summary>
-public enum ItemSize
-{
-    /// <summary>
-    /// Items that can be held completely in one's hand.
-    /// </summary>
-    Tiny = 1,
-
-    /// <summary>
-    /// Items that can fit inside of a standard pocket.
-    /// </summary>
-    Small = 2,
-
-    /// <summary>
-    /// Items that can fit inside of a standard bag.
-    /// </summary>
-    Normal = 4,
-
-    /// <summary>
-    /// Items that are too large to fit inside of standard bags, but can worn in exterior slots or placed in custom containers.
-    /// </summary>
-    Large = 8,
-
-    /// <summary>
-    /// Items that are too large to place inside of any kind of container.
-    /// </summary>
-    Huge = 16,
-
-    /// <summary>
-    /// Picture furry gf
-    /// </summary>
-    Ginormous = 32
-}
diff --git a/Content.Shared/Item/ItemSizePrototype.cs b/Content.Shared/Item/ItemSizePrototype.cs
new file mode 100644 (file)
index 0000000..e498809
--- /dev/null
@@ -0,0 +1,53 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Item;
+
+/// <summary>
+/// This is a prototype for a category of an item's size.
+/// </summary>
+[Prototype("itemSize")]
+public sealed partial class ItemSizePrototype : IPrototype, IComparable<ItemSizePrototype>
+{
+    /// <inheritdoc/>
+    [IdDataField]
+    public string ID { get; } = default!;
+
+    /// <summary>
+    /// The amount of space in a bag an item of this size takes.
+    /// </summary>
+    [DataField]
+    public readonly int Weight = 1;
+
+    /// <summary>
+    /// A player-facing name used to describe this size.
+    /// </summary>
+    [DataField]
+    public readonly LocId Name;
+
+    public int CompareTo(ItemSizePrototype? other)
+    {
+        if (other is not { } otherItemSize)
+            return 0;
+        return Weight.CompareTo(otherItemSize.Weight);
+    }
+
+    public static bool operator <(ItemSizePrototype a, ItemSizePrototype b)
+    {
+        return a.Weight < b.Weight;
+    }
+
+    public static bool operator >(ItemSizePrototype a, ItemSizePrototype b)
+    {
+        return a.Weight > b.Weight;
+    }
+
+    public static bool operator <=(ItemSizePrototype a, ItemSizePrototype b)
+    {
+        return a.Weight <= b.Weight;
+    }
+
+    public static bool operator >=(ItemSizePrototype a, ItemSizePrototype b)
+    {
+        return a.Weight >= b.Weight;
+    }
+}
index 250306f8c72fce8569396557561bc5d58b60670d..eb25f259aea1a91fa6718ae617e67dd4f01383a6 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Shared.Item;
 using Robust.Shared.Audio;
 using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
 
 namespace Content.Server.Weapons.Melee.ItemToggle;
 
@@ -21,11 +22,11 @@ public sealed partial class ItemToggleComponent : Component
 
     [ViewVariables(VVAccess.ReadWrite)]
     [DataField("offSize")]
-    public ItemSize OffSize = ItemSize.Small;
+    public ProtoId<ItemSizePrototype> OffSize = "Small";
 
     [ViewVariables(VVAccess.ReadWrite)]
     [DataField("onSize")]
-    public ItemSize OnSize = ItemSize.Huge;
+    public ProtoId<ItemSizePrototype> OnSize = "Huge";
 }
 
 [ByRefEvent]
index 4317a2307f40ac490fec9236960cf72eb3652a9d..ee4dc1e45f71fdcb62f76b644a51b02eb2c6f6f2 100644 (file)
@@ -6,12 +6,14 @@ using Content.Shared.Examine;
 using JetBrains.Annotations;
 using Robust.Shared.Containers;
 using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Utility;
 
 namespace Content.Shared.Item;
 
 public abstract class SharedItemSystem : EntitySystem
 {
+    [Dependency] private readonly IPrototypeManager _prototype = default!;
     [Dependency] private   readonly SharedHandsSystem _handsSystem = default!;
     [Dependency] protected readonly SharedContainerSystem Container = default!;
 
@@ -30,7 +32,7 @@ public abstract class SharedItemSystem : EntitySystem
 
     #region Public API
 
-    public void SetSize(EntityUid uid, ItemSize size, ItemComponent? component = null)
+    public void SetSize(EntityUid uid, ProtoId<ItemSizePrototype> size, ItemComponent? component = null)
     {
         if (!Resolve(uid, ref component, false))
             return;
@@ -128,6 +130,11 @@ public abstract class SharedItemSystem : EntitySystem
             ("size", GetItemSizeLocale(component.Size))));
     }
 
+    public ItemSizePrototype GetSizePrototype(ProtoId<ItemSizePrototype> id)
+    {
+        return _prototype.Index(id);
+    }
+
     /// <summary>
     ///     Notifies any entity that is holding or wearing this item that they may need to update their sprite.
     /// </summary>
@@ -140,14 +147,14 @@ public abstract class SharedItemSystem : EntitySystem
     }
 
     [PublicAPI]
-    public static string GetItemSizeLocale(ItemSize size)
+    public string GetItemSizeLocale(ProtoId<ItemSizePrototype> size)
     {
-        return Robust.Shared.Localization.Loc.GetString($"item-component-size-{size.ToString()}");
+        return Loc.GetString(GetSizePrototype(size).Name);
     }
 
     [PublicAPI]
-    public static int GetItemSizeWeight(ItemSize size)
+    public int GetItemSizeWeight(ProtoId<ItemSizePrototype> size)
     {
-        return (int) size;
+        return GetSizePrototype(size).Weight;
     }
 }
index 91405883987911582adf541df3cb21cdb1eb8bfc..63f5ba39a54a407aba9b8b0207ae3fa40a173554 100644 (file)
@@ -19,21 +19,23 @@ using Content.Shared.Timing;
 using Content.Shared.Verbs;
 using Robust.Shared.Containers;
 using Robust.Shared.Map;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 
 namespace Content.Shared.Storage.EntitySystems;
 
 public abstract class SharedStorageSystem : EntitySystem
 {
+    [Dependency] private readonly IPrototypeManager _prototype = default!;
     [Dependency] protected readonly IRobustRandom Random = default!;
     [Dependency] private   readonly SharedContainerSystem _containerSystem = default!;
     [Dependency] private   readonly SharedDoAfterSystem _doAfterSystem = default!;
     [Dependency] private   readonly EntityLookupSystem _entityLookupSystem = default!;
     [Dependency] protected readonly SharedEntityStorageSystem EntityStorage = default!;
     [Dependency] private   readonly SharedInteractionSystem _interactionSystem = default!;
+    [Dependency] private readonly SharedItemSystem _item = default!;
     [Dependency] private   readonly SharedPopupSystem _popupSystem = default!;
     [Dependency] private   readonly SharedHandsSystem _sharedHandsSystem = default!;
-    [Dependency] private   readonly SharedInteractionSystem _sharedInteractionSystem = default!;
     [Dependency] private   readonly ActionBlockerSystem _actionBlockerSystem = default!;
     [Dependency] private   readonly SharedAppearanceSystem _appearance = default!;
     [Dependency] protected readonly SharedAudioSystem Audio = default!;
@@ -46,7 +48,8 @@ public abstract class SharedStorageSystem : EntitySystem
     private EntityQuery<StackComponent> _stackQuery;
     private EntityQuery<TransformComponent> _xformQuery;
 
-    public const ItemSize DefaultStorageMaxItemSize = ItemSize.Normal;
+    [ValidatePrototypeId<ItemSizePrototype>]
+    public const string DefaultStorageMaxItemSize = "Normal";
 
     /// <inheritdoc />
     public override void Initialize()
@@ -474,14 +477,15 @@ public abstract class SharedStorageSystem : EntitySystem
 
         if (!_stackQuery.TryGetComponent(insertEnt, out var stack) || !HasSpaceInStacks(uid, stack.StackTypeId))
         {
-            if (item.Size > GetMaxItemSize((uid, storageComp)))
+            var maxSize = _item.GetSizePrototype(GetMaxItemSize((uid, storageComp)));
+            if (_item.GetSizePrototype(item.Size) > maxSize)
             {
                 reason = "comp-storage-too-big";
                 return false;
             }
 
             if (TryComp<StorageComponent>(insertEnt, out var insertStorage)
-                && GetMaxItemSize((insertEnt, insertStorage)) >= GetMaxItemSize((uid, storageComp)))
+                && _item.GetSizePrototype(GetMaxItemSize((insertEnt, insertStorage))) >= maxSize)
             {
                 reason = "comp-storage-too-big";
                 return false;
@@ -495,7 +499,7 @@ public abstract class SharedStorageSystem : EntitySystem
                     return false;
                 }
             }
-            else if (SharedItemSystem.GetItemSizeWeight(item.Size) + GetCumulativeItemSizes(uid, storageComp) > storageComp.MaxTotalWeight)
+            else if (_item.GetItemSizeWeight(item.Size) + GetCumulativeItemSizes(uid, storageComp) > storageComp.MaxTotalWeight)
             {
                 reason = "comp-storage-insufficient-capacity";
                 return false;
@@ -643,7 +647,7 @@ public abstract class SharedStorageSystem : EntitySystem
     /// <returns>true if inserted, false otherwise</returns>
     public bool PlayerInsertEntityInWorld(Entity<StorageComponent?> uid, EntityUid player, EntityUid toInsert)
     {
-        if (!Resolve(uid, ref uid.Comp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid))
+        if (!Resolve(uid, ref uid.Comp) || !_interactionSystem.InRangeUnobstructed(player, uid))
             return false;
 
         if (!Insert(uid, toInsert, out _, user: player, uid.Comp))
@@ -706,13 +710,13 @@ public abstract class SharedStorageSystem : EntitySystem
         {
             if (!_itemQuery.TryGetComponent(item, out var itemComp))
                 continue;
-            sum += SharedItemSystem.GetItemSizeWeight(itemComp.Size);
+            sum += _item.GetItemSizeWeight(itemComp.Size);
         }
 
         return sum;
     }
 
-    public ItemSize GetMaxItemSize(Entity<StorageComponent?> uid)
+    public ProtoId<ItemSizePrototype> GetMaxItemSize(Entity<StorageComponent?> uid)
     {
         if (!Resolve(uid, ref uid.Comp))
             return DefaultStorageMaxItemSize;
@@ -723,12 +727,14 @@ public abstract class SharedStorageSystem : EntitySystem
 
         if (!_itemQuery.TryGetComponent(uid, out var item))
             return DefaultStorageMaxItemSize;
+        var size = _item.GetSizePrototype(item.Size);
 
         // if there is no max item size specified, the value used
         // is one below the item size of the storage entity, clamped at ItemSize.Tiny
-        var sizes = Enum.GetValues<ItemSize>().ToList();
-        var currentSizeIndex = sizes.IndexOf(item.Size);
-        return sizes[Math.Max(currentSizeIndex - 1, 0)];
+        var sizes = _prototype.EnumeratePrototypes<ItemSizePrototype>().ToList();
+        sizes.Sort();
+        var currentSizeIndex = sizes.IndexOf(size);
+        return sizes[Math.Max(currentSizeIndex - 1, 0)].ID;
     }
 
     public FixedPoint2 GetStorageFillPercentage(Entity<StorageComponent?> uid)
index 2c05cb4eed6fd8d4580db06594379080f891a961..56aa07d6498b554d7f4024aa13c834246d2749b7 100644 (file)
@@ -5,6 +5,7 @@ using Robust.Shared.Audio;
 using Robust.Shared.Containers;
 using Robust.Shared.GameStates;
 using Robust.Shared.Map;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization;
 
 namespace Content.Shared.Storage
@@ -34,7 +35,7 @@ namespace Content.Shared.Storage
         /// </summary>
         [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
         [Access(typeof(SharedStorageSystem))]
-        public ItemSize? MaxItemSize;
+        public ProtoId<ItemSizePrototype>? MaxItemSize;
 
         /// <summary>
         /// The max number of entities that can be inserted into this storage.
index 5daaf8d74818aa65d03fc41f1239cef52851e46c..ae5f01301d5236e8244f1a11c1509c3721f7b2a0 100644 (file)
   parent: BoxCardboard
   id: BoxCandle
   components:
-  - type: Item
-    size: 30
   - type: Sprite
     layers:
       - state: box
         amount: 3
       - id: CandlePurple
         amount: 3
-        
+
 - type: entity
   name: small candle box
   parent: BoxCardboard
   id: BoxCandleSmall
   components:
-  - type: Item
-    size: 30
   - type: Sprite
     layers:
       - state: box
index 5223ab926b105dd627c2155906048b59ee4af70f..ea8e3b17f1c9bf1e63b32358ce7910e0d3d941fe 100644 (file)
       - state: equipped-FEET
         offset: "0, -0.04"
   - type: Item
-    size: 10
     sprite: Clothing/Shoes/Specific/skates.rsi
   - type: ClothingSpeedModifier
     walkModifier: 1.3
index 5bdf80f6455d760f10ecc236ac6447a057b1326f..d78def0c94d6df902b09f93918b3c22ce00a24e5 100644 (file)
@@ -13,7 +13,7 @@
     threshold: 1
   - type: Item
     heldPrefix: empty
-    size: 20
+    size: Normal
   - type: Appearance
   - type: GenericVisualizer
     visuals:
index d86b20caf616febf8c2e4c385da0be5025ef76df..bef37e5fd087b2429004b6ddc5c5981639c0ee83 100644 (file)
         - state: candle-big
           color: "#decb8e"
     - type: Item
-      size: 2
+      size: Small
     - type: Appearance
     - type: Reactive
       groups:
         Flammable: [ Touch ]
         Extinguish: [ Touch ]
     - type: ExtinguishOnInteract
-      extinguishAttemptSound: 
+      extinguishAttemptSound:
         path: /Audio/Items/candle_blowing.ogg
         params:
           variation: 0.05
@@ -28,9 +28,9 @@
       fireSpread: false
       canResistFire: false
       alwaysCombustible: true
-      canExtinguish: true 
+      canExtinguish: true
       firestacksOnIgnite: 3.0
-      firestackFade: -0.01 
+      firestackFade: -0.01
       damage:
         types:
           Heat: 0.1
@@ -56,7 +56,7 @@
         behaviors:
         - !type:DoActsBehavior
           acts: [ "Destruction" ]
-          
+
 - type: entity
   name: red candle
   parent: Candle
   - type: Sprite
     layers:
       - state: candle-big
-        color: "#5d997e"  
+        color: "#5d997e"
   - type: Item
     inhandVisuals:
       left:
         color: "#984aa1"
 
 
-- type: entity 
+- type: entity
   name: small candle
   parent: Candle
   id: CandleSmall
   components:
     - type: Item
-      size: 1
+      size: Tiny
     - type: Sprite
       layers:
         - state: candle-small
   - type: Sprite
     layers:
       - state: candle-small
-        color: "#5d997e"  
+        color: "#5d997e"
   - type: Item
     inhandVisuals:
       left:
 
 #Purely decorative candles for mappers. Do not have any functionality.
 
-- type: entity 
-  name: magic candle 
+- type: entity
+  name: magic candle
   description: It's either magic or high tech, but this candle never goes out. On the other hand, its flame is quite cold.
   parent: BaseItem
   suffix: Decorative
   - type: Sprite
     layers:
       - state: candle-big
-        color: "#5d997e" 
+        color: "#5d997e"
       - state: fire-big
         shader: unshaded
   - type: Item
         color: "#1b1724"
       right:
       - state: inhand-right
-        color: "#1b1724"    
+        color: "#1b1724"
 
 - type: entity
   name: small magic green candle
       - state: candle-small
         color: "#5d997e"
       - state: fire-small
-        shader: unshaded        
+        shader: unshaded
   - type: Item
     inhandVisuals:
       left:
         color: "#5d997e"
       right:
       - state: inhand-right
-        color: "#5d997e"  
+        color: "#5d997e"
 
 - type: entity
   name: small magic purple candle
         color: "#984aa1"
       right:
       - state: inhand-right
-        color: "#984aa1"  
+        color: "#984aa1"
index 9e988bb977b1b1cadfeefbc5028693d8ba45d293..2de09112c12f574398e91113ac270264fb3365db 100644 (file)
         wizardball6: ""
   - type: Appearance
   - type: Item
-    size: 150
+    size: Normal
   - type: Tag
     tags:
     - ArtifactFragment
   components:
   - type: Stack
     count: 1
-  - type: Item
-    size: 5
index 8a3754c035f56db469c822d5d51bbdb563153980..3a0eb0ab2c0bd97272df7af5ac09a22dfa32db95 100644 (file)
@@ -19,4 +19,4 @@
         Blunt: 10
         Structural: 60
   - type: Item
-    size: 80
+    size: Large
diff --git a/Resources/Prototypes/item_size.yml b/Resources/Prototypes/item_size.yml
new file mode 100644 (file)
index 0000000..47d1fe3
--- /dev/null
@@ -0,0 +1,35 @@
+# Items that can be held completely in one's hand.
+- type: itemSize
+  id: Tiny
+  weight: 1
+  name: item-component-size-Tiny
+
+# Items that can fit inside of a standard pocket.
+- type: itemSize
+  id: Small
+  weight: 2
+  name: item-component-size-Small
+
+# Items that can fit inside of a standard bag.
+- type: itemSize
+  id: Normal
+  weight: 4
+  name: item-component-size-Normal
+
+# Items that are too large to fit inside of standard bags, but can worn in exterior slots or placed in custom containers.
+- type: itemSize
+  id: Large
+  weight: 8
+  name: item-component-size-Large
+
+# Items that are too large to place inside of any kind of container.
+- type: itemSize
+  id: Huge
+  weight: 16
+  name: item-component-size-Huge
+
+# Picture furry gf
+- type: itemSize
+  id: Ginormous
+  weight: 32
+  name: item-component-size-Ginormous