Convert ItemSize to prototypes (#21481)
* item sizes are prototypes * eek
This commit is contained in:
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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".
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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)}",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
53
Content.Shared/Item/ItemSizePrototype.cs
Normal file
53
Content.Shared/Item/ItemSizePrototype.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -414,8 +414,6 @@
|
||||
parent: BoxCardboard
|
||||
id: BoxCandle
|
||||
components:
|
||||
- type: Item
|
||||
size: 30
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: box
|
||||
@@ -434,14 +432,12 @@
|
||||
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
|
||||
|
||||
@@ -202,7 +202,6 @@
|
||||
- state: equipped-FEET
|
||||
offset: "0, -0.04"
|
||||
- type: Item
|
||||
size: 10
|
||||
sprite: Clothing/Shoes/Specific/skates.rsi
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 1.3
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
threshold: 1
|
||||
- type: Item
|
||||
heldPrefix: empty
|
||||
size: 20
|
||||
size: Normal
|
||||
- type: Appearance
|
||||
- type: GenericVisualizer
|
||||
visuals:
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
- 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
|
||||
@@ -120,7 +120,7 @@
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: candle-big
|
||||
color: "#5d997e"
|
||||
color: "#5d997e"
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
@@ -149,13 +149,13 @@
|
||||
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
|
||||
@@ -236,7 +236,7 @@
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: candle-small
|
||||
color: "#5d997e"
|
||||
color: "#5d997e"
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
@@ -266,8 +266,8 @@
|
||||
|
||||
#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
|
||||
@@ -354,7 +354,7 @@
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: candle-big
|
||||
color: "#5d997e"
|
||||
color: "#5d997e"
|
||||
- state: fire-big
|
||||
shader: unshaded
|
||||
- type: Item
|
||||
@@ -444,7 +444,7 @@
|
||||
color: "#1b1724"
|
||||
right:
|
||||
- state: inhand-right
|
||||
color: "#1b1724"
|
||||
color: "#1b1724"
|
||||
|
||||
- type: entity
|
||||
name: small magic green candle
|
||||
@@ -456,7 +456,7 @@
|
||||
- state: candle-small
|
||||
color: "#5d997e"
|
||||
- state: fire-small
|
||||
shader: unshaded
|
||||
shader: unshaded
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
@@ -464,7 +464,7 @@
|
||||
color: "#5d997e"
|
||||
right:
|
||||
- state: inhand-right
|
||||
color: "#5d997e"
|
||||
color: "#5d997e"
|
||||
|
||||
- type: entity
|
||||
name: small magic purple candle
|
||||
@@ -484,4 +484,4 @@
|
||||
color: "#984aa1"
|
||||
right:
|
||||
- state: inhand-right
|
||||
color: "#984aa1"
|
||||
color: "#984aa1"
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
wizardball6: ""
|
||||
- type: Appearance
|
||||
- type: Item
|
||||
size: 150
|
||||
size: Normal
|
||||
- type: Tag
|
||||
tags:
|
||||
- ArtifactFragment
|
||||
@@ -202,5 +202,3 @@
|
||||
components:
|
||||
- type: Stack
|
||||
count: 1
|
||||
- type: Item
|
||||
size: 5
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
Blunt: 10
|
||||
Structural: 60
|
||||
- type: Item
|
||||
size: 80
|
||||
size: Large
|
||||
|
||||
35
Resources/Prototypes/item_size.yml
Normal file
35
Resources/Prototypes/item_size.yml
Normal 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
|
||||
Reference in New Issue
Block a user