Convert ItemSize to prototypes (#21481)

* item sizes are prototypes

* eek
This commit is contained in:
Nemanja
2023-11-06 02:20:50 -05:00
committed by GitHub
parent 38904904d0
commit 4729024d3e
20 changed files with 213 additions and 110 deletions

View File

@@ -1,4 +1,5 @@
using System.Numerics; using System.Numerics;
using Content.Client.Items.Systems;
using Content.Client.Message; using Content.Client.Message;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
@@ -23,6 +24,7 @@ namespace Content.Client.Storage.UI
private readonly IEntityManager _entityManager; private readonly IEntityManager _entityManager;
private readonly SharedStorageSystem _storage; private readonly SharedStorageSystem _storage;
private readonly ItemSystem _item;
private readonly RichTextLabel _information; private readonly RichTextLabel _information;
public readonly ContainerButton StorageContainerButton; public readonly ContainerButton StorageContainerButton;
@@ -34,6 +36,7 @@ namespace Content.Client.Storage.UI
{ {
_entityManager = entityManager; _entityManager = entityManager;
_storage = _entityManager.System<SharedStorageSystem>(); _storage = _entityManager.System<SharedStorageSystem>();
_item = _entityManager.System<ItemSystem>();
SetSize = new Vector2(240, 320); SetSize = new Vector2(240, 320);
Title = Loc.GetString("comp-storage-window-title"); Title = Loc.GetString("comp-storage-window-title");
RectClipContent = true; RectClipContent = true;
@@ -69,7 +72,7 @@ namespace Content.Client.Storage.UI
_information.SetMessage(Loc.GetString("comp-storage-window-weight", _information.SetMessage(Loc.GetString("comp-storage-window-weight",
("weight", 0), ("weight", 0),
("maxWeight", 0), ("maxWeight", 0),
("size", SharedItemSystem.GetItemSizeLocale(ItemSize.Normal)))); ("size", _item.GetItemSizeLocale(SharedStorageSystem.DefaultStorageMaxItemSize))));
vBox.AddChild(_information); vBox.AddChild(_information);
@@ -117,14 +120,14 @@ namespace Content.Client.Storage.UI
_information.SetMarkup(Loc.GetString("comp-storage-window-weight", _information.SetMarkup(Loc.GetString("comp-storage-window-weight",
("weight", _storage.GetCumulativeItemSizes(uid, uid.Comp)), ("weight", _storage.GetCumulativeItemSizes(uid, uid.Comp)),
("maxWeight", uid.Comp.MaxTotalWeight), ("maxWeight", uid.Comp.MaxTotalWeight),
("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp)))))); ("size", _item.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp))))));
} }
else else
{ {
_information.SetMarkup(Loc.GetString("comp-storage-window-slots", _information.SetMarkup(Loc.GetString("comp-storage-window-slots",
("itemCount", uid.Comp.Container.ContainedEntities.Count), ("itemCount", uid.Comp.Container.ContainedEntities.Count),
("maxCount", uid.Comp.MaxSlots), ("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, Align = Label.AlignMode.Right,
Text = item?.Size != null Text = item?.Size != null
? $"{SharedItemSystem.GetItemSizeWeight(item.Size)}" ? $"{_item.GetItemSizeWeight(item.Size)}"
: Loc.GetString("comp-storage-no-item-size") : Loc.GetString("comp-storage-no-item-size")
} }
} }

View File

@@ -26,6 +26,9 @@ namespace Content.IntegrationTests.Tests
var server = pair.Server; var server = pair.Server;
var protoManager = server.ResolveDependency<IPrototypeManager>(); var protoManager = server.ResolveDependency<IPrototypeManager>();
var entMan = server.ResolveDependency<IEntityManager>();
var itemSys = entMan.System<SharedItemSystem>();
await server.WaitAssertion(() => await server.WaitAssertion(() =>
{ {
@@ -37,7 +40,9 @@ namespace Content.IntegrationTests.Tests
!proto.TryGetComponent<ItemComponent>("Item", out var item)) !proto.TryGetComponent<ItemComponent>("Item", out var item))
continue; 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(); await pair.CleanReturnAsync();
@@ -77,10 +82,16 @@ namespace Content.IntegrationTests.Tests
await using var pair = await PoolManager.GetServerClient(); await using var pair = await PoolManager.GetServerClient();
var server = pair.Server; var server = pair.Server;
var entMan = server.ResolveDependency<IEntityManager>();
var protoMan = server.ResolveDependency<IPrototypeManager>(); var protoMan = server.ResolveDependency<IPrototypeManager>();
var compFact = server.ResolveDependency<IComponentFactory>(); var compFact = server.ResolveDependency<IComponentFactory>();
var id = compFact.GetComponentName(typeof(StorageFillComponent)); var id = compFact.GetComponentName(typeof(StorageFillComponent));
var itemSys = entMan.System<SharedItemSystem>();
var allSizes = protoMan.EnumeratePrototypes<ItemSizePrototype>().ToList();
allSizes.Sort();
Assert.Multiple(() => Assert.Multiple(() =>
{ {
foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server)) foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
@@ -97,14 +108,29 @@ namespace Content.IntegrationTests.Tests
proto.TryGetComponent<ItemComponent>("Item", out var item); proto.TryGetComponent<ItemComponent>("Item", out var item);
var fill = (StorageFillComponent) proto.Components[id].Component; var fill = (StorageFillComponent) proto.Components[id].Component;
var size = GetFillSize(fill, false, protoMan); var size = GetFillSize(fill, false, protoMan, itemSys);
var maxSize = storage.MaxItemSize ??
(item?.Size == null var maxSize = storage.MaxItemSize;
? SharedStorageSystem.DefaultStorageMaxItemSize if (storage.MaxItemSize == null)
: (ItemSize) Math.Max(0, (int) item.Size - 1)); {
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) 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."); $"{proto.ID} storage fill has too many items.");
} }
else else
@@ -123,14 +149,14 @@ namespace Content.IntegrationTests.Tests
if (!fillItem.TryGetComponent<ItemComponent>("Item", out var entryItem)) if (!fillItem.TryGetComponent<ItemComponent>("Item", out var entryItem))
continue; 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"); $"Entity {proto.ID} has storage-fill item, {entry.PrototypeId}, that is too large");
} }
} }
}); });
await pair.CleanReturnAsync(); await pair.CleanReturnAsync();
} }
[Test] [Test]
@@ -139,10 +165,13 @@ namespace Content.IntegrationTests.Tests
await using var pair = await PoolManager.GetServerClient(); await using var pair = await PoolManager.GetServerClient();
var server = pair.Server; var server = pair.Server;
var entMan = server.ResolveDependency<IEntityManager>();
var protoMan = server.ResolveDependency<IPrototypeManager>(); var protoMan = server.ResolveDependency<IPrototypeManager>();
var compFact = server.ResolveDependency<IComponentFactory>(); var compFact = server.ResolveDependency<IComponentFactory>();
var id = compFact.GetComponentName(typeof(StorageFillComponent)); var id = compFact.GetComponentName(typeof(StorageFillComponent));
var itemSys = entMan.System<SharedItemSystem>();
Assert.Multiple(() => Assert.Multiple(() =>
{ {
foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server)) foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
@@ -157,7 +186,7 @@ namespace Content.IntegrationTests.Tests
} }
var fill = (StorageFillComponent) proto.Components[id].Component; 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), Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity),
$"{proto.ID} storage fill is too large."); $"{proto.ID} storage fill is too large.");
} }
@@ -165,7 +194,7 @@ namespace Content.IntegrationTests.Tests
await pair.CleanReturnAsync(); 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) if (entry.PrototypeId == null)
return 0; return 0;
@@ -179,20 +208,21 @@ namespace Content.IntegrationTests.Tests
if (getCount) if (getCount)
return entry.Amount; return entry.Amount;
if (proto.TryGetComponent<ItemComponent>("Item", out var item)) 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}"); Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}");
return 0; 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 totalSize = 0;
var groups = new Dictionary<string, int>(); var groups = new Dictionary<string, int>();
foreach (var entry in fill.Contents) foreach (var entry in fill.Contents)
{ {
var size = GetEntrySize(entry, getCount, protoMan); var size = GetEntrySize(entry, getCount, protoMan, itemSystem);
if (entry.GroupId == null) if (entry.GroupId == null)
totalSize += size; totalSize += size;

View File

@@ -3,6 +3,7 @@ using Content.Shared.Containers.ItemSlots;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Toilet; using Content.Shared.Toilet;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
namespace Content.Server.Storage.Components namespace Content.Server.Storage.Components
{ {
@@ -19,7 +20,7 @@ namespace Content.Server.Storage.Components
/// Max item size that can be fitted into secret stash. /// Max item size that can be fitted into secret stash.
/// </summary> /// </summary>
[DataField("maxItemSize")] [DataField("maxItemSize")]
public ItemSize MaxItemSize = ItemSize.Small; public ProtoId<ItemSizePrototype> MaxItemSize = "Small";
/// <summary> /// <summary>
/// IC secret stash name. For example "the toilet cistern". /// IC secret stash name. For example "the toilet cistern".

View File

@@ -13,6 +13,7 @@ namespace Content.Server.Storage.EntitySystems
[Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedItemSystem _item = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -66,7 +67,7 @@ namespace Content.Server.Storage.EntitySystems
} }
// check if item is too big to fit into secret stash // 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", var msg = Loc.GetString("comp-secret-stash-action-hide-item-too-big",
("item", itemToHideUid), ("stash", GetSecretPartName(uid, component))); ("item", itemToHideUid), ("stash", GetSecretPartName(uid, component)));

View File

@@ -127,6 +127,7 @@ public sealed class StatValuesCommand : IConsoleCommand
private StatValuesEuiMessage GetItem() private StatValuesEuiMessage GetItem()
{ {
var values = new List<string[]>(); var values = new List<string[]>();
var itemSystem = _entManager.System<ItemSystem>();
var metaQuery = _entManager.GetEntityQuery<MetaDataComponent>(); var metaQuery = _entManager.GetEntityQuery<MetaDataComponent>();
var itemQuery = _entManager.GetEntityQuery<ItemComponent>(); var itemQuery = _entManager.GetEntityQuery<ItemComponent>();
var items = new HashSet<string>(1024); var items = new HashSet<string>(1024);
@@ -149,7 +150,7 @@ public sealed class StatValuesCommand : IConsoleCommand
values.Add(new[] values.Add(new[]
{ {
id, id,
$"{SharedItemSystem.GetItemSizeLocale(itemComp.Size)}", $"{itemSystem.GetItemSizeLocale(itemComp.Size)}",
}); });
} }

View File

@@ -98,7 +98,7 @@ public sealed class EnergySwordSystem : EntitySystem
{ {
if (TryComp(uid, out ItemComponent? item)) if (TryComp(uid, out ItemComponent? item))
{ {
_item.SetSize(uid, ItemSize.Small, item); _item.SetSize(uid, "Small", item);
} }
if (TryComp<DisarmMalusComponent>(uid, out var malus)) if (TryComp<DisarmMalusComponent>(uid, out var malus))
@@ -125,7 +125,7 @@ public sealed class EnergySwordSystem : EntitySystem
{ {
if (TryComp(uid, out ItemComponent? item)) if (TryComp(uid, out ItemComponent? item))
{ {
_item.SetSize(uid, ItemSize.Huge, item); _item.SetSize(uid, "Huge", item);
} }
if (comp.IsSharp) if (comp.IsSharp)

View File

@@ -14,6 +14,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
namespace Content.Shared.Inventory; namespace Content.Shared.Inventory;
@@ -23,12 +24,16 @@ public abstract partial class InventorySystem
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly SharedItemSystem _item = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly INetManager _netMan = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedTransformSystem _transform = default!;
[ValidatePrototypeId<ItemSizePrototype>]
private const string PocketableItemSize = "Small";
private void InitializeEquip() private void InitializeEquip()
{ {
//these events ensure that the client also gets its proper events raised when getting its containerstate updated //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)) if (slotDefinition.DependsOn != null && !TryGetSlotEntity(target, slotDefinition.DependsOn, out _, inventory))
return false; 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 if (clothing == null && !fittingInPocket
|| clothing != null && !clothing.Slots.HasFlag(slotDefinition.SlotFlags) && !fittingInPocket) || clothing != null && !clothing.Slots.HasFlag(slotDefinition.SlotFlags) && !fittingInPocket)
{ {

View File

@@ -1,5 +1,6 @@
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Item; namespace Content.Shared.Item;
@@ -15,7 +16,7 @@ public sealed partial class ItemComponent : Component
{ {
[DataField, ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
[Access(typeof(SharedItemSystem))] [Access(typeof(SharedItemSystem))]
public ItemSize Size = ItemSize.Small; public ProtoId<ItemSizePrototype> Size = "Small";
[Access(typeof(SharedItemSystem))] [Access(typeof(SharedItemSystem))]
[DataField] [DataField]
@@ -38,10 +39,10 @@ public sealed partial class ItemComponent : Component
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed class ItemComponentState : ComponentState public sealed class ItemComponentState : ComponentState
{ {
public ItemSize Size { get; } public ProtoId<ItemSizePrototype> Size { get; }
public string? HeldPrefix { get; } public string? HeldPrefix { get; }
public ItemComponentState(ItemSize size, string? heldPrefix) public ItemComponentState(ProtoId<ItemSizePrototype> size, string? heldPrefix)
{ {
Size = size; Size = size;
HeldPrefix = heldPrefix; HeldPrefix = heldPrefix;
@@ -64,40 +65,3 @@ public sealed class VisualsChangedEvent : EntityEventArgs
ContainerId = containerId; 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
}

View File

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

View File

@@ -1,6 +1,7 @@
using Content.Shared.Item; using Content.Shared.Item;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Server.Weapons.Melee.ItemToggle; namespace Content.Server.Weapons.Melee.ItemToggle;
@@ -21,11 +22,11 @@ public sealed partial class ItemToggleComponent : Component
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("offSize")] [DataField("offSize")]
public ItemSize OffSize = ItemSize.Small; public ProtoId<ItemSizePrototype> OffSize = "Small";
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("onSize")] [DataField("onSize")]
public ItemSize OnSize = ItemSize.Huge; public ProtoId<ItemSizePrototype> OnSize = "Huge";
} }
[ByRefEvent] [ByRefEvent]

View File

@@ -6,12 +6,14 @@ using Content.Shared.Examine;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Shared.Item; namespace Content.Shared.Item;
public abstract class SharedItemSystem : EntitySystem public abstract class SharedItemSystem : EntitySystem
{ {
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] protected readonly SharedContainerSystem Container = default!; [Dependency] protected readonly SharedContainerSystem Container = default!;
@@ -30,7 +32,7 @@ public abstract class SharedItemSystem : EntitySystem
#region Public API #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)) if (!Resolve(uid, ref component, false))
return; return;
@@ -128,6 +130,11 @@ public abstract class SharedItemSystem : EntitySystem
("size", GetItemSizeLocale(component.Size)))); ("size", GetItemSizeLocale(component.Size))));
} }
public ItemSizePrototype GetSizePrototype(ProtoId<ItemSizePrototype> id)
{
return _prototype.Index(id);
}
/// <summary> /// <summary>
/// Notifies any entity that is holding or wearing this item that they may need to update their sprite. /// Notifies any entity that is holding or wearing this item that they may need to update their sprite.
/// </summary> /// </summary>
@@ -140,14 +147,14 @@ public abstract class SharedItemSystem : EntitySystem
} }
[PublicAPI] [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] [PublicAPI]
public static int GetItemSizeWeight(ItemSize size) public int GetItemSizeWeight(ProtoId<ItemSizePrototype> size)
{ {
return (int) size; return GetSizePrototype(size).Weight;
} }
} }

View File

@@ -19,21 +19,23 @@ using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
namespace Content.Shared.Storage.EntitySystems; namespace Content.Shared.Storage.EntitySystems;
public abstract class SharedStorageSystem : EntitySystem public abstract class SharedStorageSystem : EntitySystem
{ {
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] protected readonly IRobustRandom Random = default!; [Dependency] protected readonly IRobustRandom Random = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly EntityLookupSystem _entityLookupSystem = default!; [Dependency] private readonly EntityLookupSystem _entityLookupSystem = default!;
[Dependency] protected readonly SharedEntityStorageSystem EntityStorage = default!; [Dependency] protected readonly SharedEntityStorageSystem EntityStorage = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly SharedItemSystem _item = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!; [Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!;
[Dependency] private readonly SharedInteractionSystem _sharedInteractionSystem = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] protected readonly SharedAudioSystem Audio = default!; [Dependency] protected readonly SharedAudioSystem Audio = default!;
@@ -46,7 +48,8 @@ public abstract class SharedStorageSystem : EntitySystem
private EntityQuery<StackComponent> _stackQuery; private EntityQuery<StackComponent> _stackQuery;
private EntityQuery<TransformComponent> _xformQuery; private EntityQuery<TransformComponent> _xformQuery;
public const ItemSize DefaultStorageMaxItemSize = ItemSize.Normal; [ValidatePrototypeId<ItemSizePrototype>]
public const string DefaultStorageMaxItemSize = "Normal";
/// <inheritdoc /> /// <inheritdoc />
public override void Initialize() 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 (!_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"; reason = "comp-storage-too-big";
return false; return false;
} }
if (TryComp<StorageComponent>(insertEnt, out var insertStorage) if (TryComp<StorageComponent>(insertEnt, out var insertStorage)
&& GetMaxItemSize((insertEnt, insertStorage)) >= GetMaxItemSize((uid, storageComp))) && _item.GetSizePrototype(GetMaxItemSize((insertEnt, insertStorage))) >= maxSize)
{ {
reason = "comp-storage-too-big"; reason = "comp-storage-too-big";
return false; return false;
@@ -495,7 +499,7 @@ public abstract class SharedStorageSystem : EntitySystem
return false; 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"; reason = "comp-storage-insufficient-capacity";
return false; return false;
@@ -643,7 +647,7 @@ public abstract class SharedStorageSystem : EntitySystem
/// <returns>true if inserted, false otherwise</returns> /// <returns>true if inserted, false otherwise</returns>
public bool PlayerInsertEntityInWorld(Entity<StorageComponent?> uid, EntityUid player, EntityUid toInsert) 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; return false;
if (!Insert(uid, toInsert, out _, user: player, uid.Comp)) 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)) if (!_itemQuery.TryGetComponent(item, out var itemComp))
continue; continue;
sum += SharedItemSystem.GetItemSizeWeight(itemComp.Size); sum += _item.GetItemSizeWeight(itemComp.Size);
} }
return sum; return sum;
} }
public ItemSize GetMaxItemSize(Entity<StorageComponent?> uid) public ProtoId<ItemSizePrototype> GetMaxItemSize(Entity<StorageComponent?> uid)
{ {
if (!Resolve(uid, ref uid.Comp)) if (!Resolve(uid, ref uid.Comp))
return DefaultStorageMaxItemSize; return DefaultStorageMaxItemSize;
@@ -723,12 +727,14 @@ public abstract class SharedStorageSystem : EntitySystem
if (!_itemQuery.TryGetComponent(uid, out var item)) if (!_itemQuery.TryGetComponent(uid, out var item))
return DefaultStorageMaxItemSize; return DefaultStorageMaxItemSize;
var size = _item.GetSizePrototype(item.Size);
// if there is no max item size specified, the value used // 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 // is one below the item size of the storage entity, clamped at ItemSize.Tiny
var sizes = Enum.GetValues<ItemSize>().ToList(); var sizes = _prototype.EnumeratePrototypes<ItemSizePrototype>().ToList();
var currentSizeIndex = sizes.IndexOf(item.Size); sizes.Sort();
return sizes[Math.Max(currentSizeIndex - 1, 0)]; var currentSizeIndex = sizes.IndexOf(size);
return sizes[Math.Max(currentSizeIndex - 1, 0)].ID;
} }
public FixedPoint2 GetStorageFillPercentage(Entity<StorageComponent?> uid) public FixedPoint2 GetStorageFillPercentage(Entity<StorageComponent?> uid)

View File

@@ -5,6 +5,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Storage namespace Content.Shared.Storage
@@ -34,7 +35,7 @@ namespace Content.Shared.Storage
/// </summary> /// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
[Access(typeof(SharedStorageSystem))] [Access(typeof(SharedStorageSystem))]
public ItemSize? MaxItemSize; public ProtoId<ItemSizePrototype>? MaxItemSize;
/// <summary> /// <summary>
/// The max number of entities that can be inserted into this storage. /// The max number of entities that can be inserted into this storage.

View File

@@ -414,8 +414,6 @@
parent: BoxCardboard parent: BoxCardboard
id: BoxCandle id: BoxCandle
components: components:
- type: Item
size: 30
- type: Sprite - type: Sprite
layers: layers:
- state: box - state: box
@@ -440,8 +438,6 @@
parent: BoxCardboard parent: BoxCardboard
id: BoxCandleSmall id: BoxCandleSmall
components: components:
- type: Item
size: 30
- type: Sprite - type: Sprite
layers: layers:
- state: box - state: box

View File

@@ -202,7 +202,6 @@
- state: equipped-FEET - state: equipped-FEET
offset: "0, -0.04" offset: "0, -0.04"
- type: Item - type: Item
size: 10
sprite: Clothing/Shoes/Specific/skates.rsi sprite: Clothing/Shoes/Specific/skates.rsi
- type: ClothingSpeedModifier - type: ClothingSpeedModifier
walkModifier: 1.3 walkModifier: 1.3

View File

@@ -13,7 +13,7 @@
threshold: 1 threshold: 1
- type: Item - type: Item
heldPrefix: empty heldPrefix: empty
size: 20 size: Normal
- type: Appearance - type: Appearance
- type: GenericVisualizer - type: GenericVisualizer
visuals: visuals:

View File

@@ -11,7 +11,7 @@
- state: candle-big - state: candle-big
color: "#decb8e" color: "#decb8e"
- type: Item - type: Item
size: 2 size: Small
- type: Appearance - type: Appearance
- type: Reactive - type: Reactive
groups: groups:
@@ -155,7 +155,7 @@
id: CandleSmall id: CandleSmall
components: components:
- type: Item - type: Item
size: 1 size: Tiny
- type: Sprite - type: Sprite
layers: layers:
- state: candle-small - state: candle-small

View File

@@ -178,7 +178,7 @@
wizardball6: "" wizardball6: ""
- type: Appearance - type: Appearance
- type: Item - type: Item
size: 150 size: Normal
- type: Tag - type: Tag
tags: tags:
- ArtifactFragment - ArtifactFragment
@@ -202,5 +202,3 @@
components: components:
- type: Stack - type: Stack
count: 1 count: 1
- type: Item
size: 5

View File

@@ -19,4 +19,4 @@
Blunt: 10 Blunt: 10
Structural: 60 Structural: 60
- type: Item - type: Item
size: 80 size: Large

View File

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