[TEST MERGE] Slot-based Storage (#21212)

This commit is contained in:
Nemanja
2023-10-25 18:53:38 -04:00
committed by GitHub
parent 6b04aaf964
commit 41795720da
234 changed files with 1052 additions and 1008 deletions

View File

@@ -1,16 +1,15 @@
using System.Numerics;
using Robust.Client.GameObjects;
using Content.Client.Message;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Shared.IdentityManagement;
using Content.Shared.Item;
using Content.Shared.Stacks;
using Content.Shared.Storage;
using Content.Shared.Storage.EntitySystems;
using Robust.Client.UserInterface;
using Robust.Shared.Containers;
using static Robust.Client.UserInterface.Controls.BoxContainer;
using Direction = Robust.Shared.Maths.Direction;
@@ -23,7 +22,9 @@ namespace Content.Client.Storage.UI
{
private readonly IEntityManager _entityManager;
private readonly Label _information;
private readonly SharedStorageSystem _storage;
private readonly RichTextLabel _information;
public readonly ContainerButton StorageContainerButton;
public readonly ListContainer EntityList;
private readonly StyleBoxFlat _hoveredBox = new() { BackgroundColor = Color.Black.WithAlpha(0.35f) };
@@ -32,6 +33,7 @@ namespace Content.Client.Storage.UI
public StorageWindow(IEntityManager entityManager)
{
_entityManager = entityManager;
_storage = _entityManager.System<SharedStorageSystem>();
SetSize = new Vector2(240, 320);
Title = Loc.GetString("comp-storage-window-title");
RectClipContent = true;
@@ -60,11 +62,14 @@ namespace Content.Client.Storage.UI
StorageContainerButton.AddChild(vBox);
_information = new Label
_information = new RichTextLabel
{
Text = Loc.GetString("comp-storage-window-volume", ("itemCount", 0), ("usedVolume", 0), ("maxVolume", 0)),
VerticalAlignment = VAlignment.Center
};
_information.SetMessage(Loc.GetString("comp-storage-window-volume",
("itemCount", 0),
("maxCount", 0),
("size", SharedItemSystem.GetItemSizeLocale(ItemSize.Normal))));
vBox.AddChild(_information);
@@ -101,15 +106,23 @@ namespace Content.Client.Storage.UI
EntityList.PopulateList(list);
// Sets information about entire storage container current capacity
if (component.StorageCapacityMax != 0)
SetStorageInformation((entity, component));
}
private void SetStorageInformation(Entity<StorageComponent> uid)
{
_information.Text = Loc.GetString("comp-storage-window-volume", ("itemCount", storedCount),
("usedVolume", component.StorageUsed), ("maxVolume", component.StorageCapacityMax));
if (uid.Comp.MaxSlots != uid.Comp.Container.ContainedEntities.Count
&& _storage.GetCumulativeItemSizes(uid, uid.Comp) == _storage.GetMaxTotalWeight((uid, uid.Comp)))
{
_information.SetMarkup(Loc.GetString("comp-storage-window-volume-full",
("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp))))));
}
else
{
_information.Text = Loc.GetString("comp-storage-window-volume-unlimited", ("itemCount", storedCount));
_information.SetMarkup(Loc.GetString("comp-storage-window-volume",
("itemCount", uid.Comp.Container.ContainedEntities.Count),
("maxCount", uid.Comp.MaxSlots),
("size", SharedItemSystem.GetItemSizeLocale(_storage.GetMaxItemSize((uid, uid.Comp))))));
}
}
@@ -122,10 +135,9 @@ namespace Content.Client.Storage.UI
|| !_entityManager.EntityExists(entity))
return;
_entityManager.TryGetComponent(entity, out ItemComponent? item);
_entityManager.TryGetComponent(entity, out StackComponent? stack);
_entityManager.TryGetComponent(entity, out ItemComponent? item);
var count = stack?.Count ?? 1;
var size = item?.Size;
var spriteView = new SpriteView
{
@@ -147,12 +159,14 @@ namespace Content.Client.Storage.UI
HorizontalExpand = true,
ClipText = true,
Text = _entityManager.GetComponent<MetaDataComponent>(Identity.Entity(entity, _entityManager)).EntityName +
(count > 1 ? $" x {count}" : string.Empty),
(count > 1 ? $" x {count}" : string.Empty)
},
new Label
{
Align = Label.AlignMode.Right,
Text = size.ToString() ?? Loc.GetString("comp-storage-no-item-size"),
Text = item?.Size != null
? SharedItemSystem.GetItemSizeLocale(item.Size)
: Loc.GetString("comp-storage-no-item-size")
}
}
});

View File

@@ -26,7 +26,7 @@ namespace Content.IntegrationTests.Tests
- type: Clothing
slots: [innerclothing]
- type: Item
size: 5
size: Tiny
- type: entity
name: IDCardDummy
@@ -36,7 +36,7 @@ namespace Content.IntegrationTests.Tests
slots:
- idcard
- type: Item
size: 5
size: Tiny
- type: IdCard
- type: entity
@@ -44,14 +44,14 @@ namespace Content.IntegrationTests.Tests
id: FlashlightDummy
components:
- type: Item
size: 5
size: Tiny
- type: entity
name: ToolboxDummy
id: ToolboxDummy
components:
- type: Item
size: 9999
size: Huge
";
[Test]
public async Task Test()

View File

@@ -1,39 +0,0 @@
using Content.Shared.Item;
using Content.Shared.Stacks;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests;
[TestFixture]
public sealed class StackTest
{
[Test]
public async Task StackCorrectItemSize()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var protoManager = server.ResolveDependency<IPrototypeManager>();
var compFact = server.ResolveDependency<IComponentFactory>();
Assert.Multiple(() =>
{
foreach (var entity in PoolManager.GetPrototypesWithComponent<StackComponent>(server))
{
if (!entity.TryGetComponent<StackComponent>(out var stackComponent, compFact) ||
!entity.TryGetComponent<ItemComponent>(out var itemComponent, compFact))
continue;
if (!protoManager.TryIndex<StackPrototype>(stackComponent.StackTypeId, out var stackProto) ||
stackProto.ItemSize == null)
continue;
var expectedSize = stackProto.ItemSize * stackComponent.Count;
Assert.That(itemComponent.Size, Is.EqualTo(expectedSize), $"Prototype id: {entity.ID} has an item size of {itemComponent.Size} but expected size of {expectedSize}.");
}
});
await pair.CleanReturnAsync();
}
}

View File

@@ -3,11 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using Content.Server.Storage.Components;
using Content.Shared.Item;
using Content.Shared.Prototypes;
using Content.Shared.Storage;
using Content.Shared.Storage.Components;
using Content.Shared.Storage.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.UnitTesting;
namespace Content.IntegrationTests.Tests
{
@@ -32,9 +33,11 @@ namespace Content.IntegrationTests.Tests
{
if (!proto.TryGetComponent<StorageComponent>("Storage", out var storage) ||
storage.Whitelist != null ||
!proto.TryGetComponent<ItemComponent>("Item", out var item)) continue;
storage.MaxItemSize == null ||
!proto.TryGetComponent<ItemComponent>("Item", out var item))
continue;
Assert.That(storage.StorageCapacityMax, Is.LessThanOrEqualTo(item.Size), $"Found storage arbitrage on {proto.ID}");
Assert.That(storage.MaxItemSize.Value, Is.LessThan(item.Size), $"Found storage arbitrage on {proto.ID}");
}
});
await pair.CleanReturnAsync();
@@ -82,31 +85,85 @@ namespace Content.IntegrationTests.Tests
{
foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
{
int capacity;
var isEntStorage = false;
if (proto.HasComponent<EntityStorageComponent>(compFact))
continue;
if (proto.TryGetComponent<StorageComponent>("Storage", out var storage))
if (!proto.TryGetComponent<StorageComponent>("Storage", out var storage))
{
capacity = storage.StorageCapacityMax;
Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!");
continue;
}
else if (proto.TryGetComponent<EntityStorageComponent>("EntityStorage", out var entStorage))
proto.TryGetComponent<ItemComponent>("Item", out var item);
var maxSize = storage.MaxItemSize ??
(item?.Size == null
? SharedStorageSystem.DefaultStorageMaxItemSize
: (ItemSize) Math.Max(0, (int) item.Size - 1));
var capacity = storage.MaxTotalWeight ??
storage.MaxSlots * SharedItemSystem.GetItemSizeWeight(storage.MaxItemSize ?? maxSize);
var fill = (StorageFillComponent) proto.Components[id].Component;
var size = GetFillSize(fill, false, protoMan);
Assert.That(size, Is.LessThanOrEqualTo(capacity), $"{proto.ID} storage fill is too large.");
Assert.That(GetFillSize(fill, true, protoMan), Is.LessThanOrEqualTo(storage.MaxSlots), $"{proto.ID} storage fill has too many items.");
foreach (var entry in fill.Contents)
{
capacity = entStorage.Capacity;
isEntStorage = true;
if (entry.PrototypeId == null)
continue;
if (!protoMan.TryIndex<EntityPrototype>(entry.PrototypeId, out var fillItem))
continue;
if (!fillItem.TryGetComponent<ItemComponent>("Item", out var entryItem))
continue;
Assert.That(entryItem.Size, Is.LessThanOrEqualTo(maxSize),
$"Entity {proto.ID} has storage-fill item, {entry.PrototypeId}, that is too large");
}
else
}
});
await pair.CleanReturnAsync();
}
[Test]
public async Task TestSufficientSpaceForEntityStorageFill()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var protoMan = server.ResolveDependency<IPrototypeManager>();
var compFact = server.ResolveDependency<IComponentFactory>();
var id = compFact.GetComponentName(typeof(StorageFillComponent));
Assert.Multiple(() =>
{
foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
{
if (proto.HasComponent<StorageComponent>(compFact))
continue;
if (!proto.TryGetComponent<EntityStorageComponent>("EntityStorage", out var entStorage))
{
Assert.Fail($"Entity {proto.ID} has storage-fill without a storage component!");
continue;
}
var fill = (StorageFillComponent) proto.Components[id].Component;
var size = GetFillSize(fill, isEntStorage);
Assert.That(size, Is.LessThanOrEqualTo(capacity), $"{proto.ID} storage fill is too large.");
var size = GetFillSize(fill, true, protoMan);
Assert.That(size, Is.LessThanOrEqualTo(entStorage.Capacity),
$"{proto.ID} storage fill is too large.");
}
});
await pair.CleanReturnAsync();
}
int GetEntrySize(EntitySpawnEntry entry, bool isEntStorage)
private int GetEntrySize(EntitySpawnEntry entry, bool getCount, IPrototypeManager protoMan)
{
if (entry.PrototypeId == null)
return 0;
@@ -117,23 +174,23 @@ namespace Content.IntegrationTests.Tests
return 0;
}
if (isEntStorage)
if (getCount)
return entry.Amount;
if (proto.TryGetComponent<ItemComponent>("Item", out var item))
return item.Size * entry.Amount;
return SharedItemSystem.GetItemSizeWeight(item.Size) * entry.Amount;
Assert.Fail($"Prototype is missing item comp: {entry.PrototypeId}");
return 0;
}
int GetFillSize(StorageFillComponent fill, bool isEntStorage)
private int GetFillSize(StorageFillComponent fill, bool getCount, IPrototypeManager protoMan)
{
var totalSize = 0;
var groups = new Dictionary<string, int>();
foreach (var entry in fill.Contents)
{
var size = GetEntrySize(entry, isEntStorage);
var size = GetEntrySize(entry, getCount, protoMan);
if (entry.GroupId == null)
totalSize += size;
@@ -143,8 +200,5 @@ namespace Content.IntegrationTests.Tests
return totalSize + groups.Values.Sum();
}
await pair.CleanReturnAsync();
}
}
}

View File

@@ -187,7 +187,7 @@ namespace Content.Server.Chemistry.EntitySystems
}
// Ensure the number is valid.
if (message.Number == 0 || message.Number > storage.StorageCapacityMax - storage.StorageUsed)
if (message.Number == 0 || _storageSystem.HasSpace((chemMaster, storage)))
return;
// Ensure the amount is valid.
@@ -345,7 +345,7 @@ namespace Content.Server.Chemistry.EntitySystems
}
}
if (!TryComp(container, out StorageComponent? storage))
if (!TryComp(container, out StorageComponent? storage) || storage.Container == null)
return null;
var pills = storage.Container?.ContainedEntities.Select((Func<EntityUid, (string, FixedPoint2 quantity)>) (pill =>
@@ -358,7 +358,7 @@ namespace Content.Server.Chemistry.EntitySystems
if (pills == null)
return null;
return new ContainerInfo(name, storage.StorageUsed, storage.StorageCapacityMax)
return new ContainerInfo(name, storage.Container!.ContainedEntities.Count, storage.MaxSlots)
{
Entities = pills
};

View File

@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Inventory;
@@ -122,7 +123,7 @@ public sealed class FoodSystem : EntitySystem
return (false, false);
// Check for used storage on the food item
if (TryComp<StorageComponent>(food, out var storageState) && storageState.StorageUsed != 0)
if (TryComp<StorageComponent>(food, out var storageState) && storageState.Container.ContainedEntities.Any())
{
_popup.PopupEntity(Loc.GetString("food-has-used-storage", ("food", food)), user, user);
return (false, true);

View File

@@ -19,7 +19,7 @@ namespace Content.Server.Storage.Components
/// Max item size that can be fitted into secret stash.
/// </summary>
[DataField("maxItemSize")]
public int MaxItemSize = (int) ReferenceSizes.Pocket;
public ItemSize MaxItemSize = ItemSize.Small;
/// <summary>
/// IC secret stash name. For example "the toilet cistern".

View File

@@ -1,7 +1,6 @@
using Content.Shared.Rounding;
using Content.Shared.Storage;
using Content.Shared.Storage.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Containers;
namespace Content.Server.Storage.EntitySystems;
@@ -13,12 +12,12 @@ public sealed class StorageFillVisualizerSystem : EntitySystem
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StorageFillVisualizerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<StorageFillVisualizerComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<StorageFillVisualizerComponent, EntInsertedIntoContainerMessage>(OnInserted);
SubscribeLocalEvent<StorageFillVisualizerComponent, EntRemovedFromContainerMessage>(OnRemoved);
}
private void OnInit(EntityUid uid, StorageFillVisualizerComponent component, ComponentInit args)
private void OnStartup(EntityUid uid, StorageFillVisualizerComponent component, ComponentStartup args)
{
UpdateAppearance(uid, component: component);
}
@@ -42,7 +41,7 @@ public sealed class StorageFillVisualizerSystem : EntitySystem
if (component.MaxFillLevels < 1)
return;
var level = ContentHelpers.RoundToEqualLevels(storage.StorageUsed, storage.StorageCapacityMax, component.MaxFillLevels);
var level = ContentHelpers.RoundToEqualLevels(storage.Container.ContainedEntities.Count, storage.MaxSlots, component.MaxFillLevels);
_appearance.SetData(uid, StorageFillVisuals.FillLevel, level, appearance);
}
}

View File

@@ -98,7 +98,7 @@ public sealed class EnergySwordSystem : EntitySystem
{
if (TryComp(uid, out ItemComponent? item))
{
_item.SetSize(uid, 5, item);
_item.SetSize(uid, ItemSize.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, 9999, item);
_item.SetSize(uid, ItemSize.Huge, item);
}
if (comp.IsSharp)

View File

@@ -264,7 +264,7 @@ 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: <= (int) ReferenceSizes.Pocket };
var fittingInPocket = slotDefinition.SlotFlags.HasFlag(SlotFlags.POCKET) && item is { Size: <= ItemSize.Small };
if (clothing == null && !fittingInPocket
|| clothing != null && !clothing.Slots.HasFlag(slotDefinition.SlotFlags) && !fittingInPocket)
{

View File

@@ -13,18 +13,17 @@ namespace Content.Shared.Item;
[Access(typeof(SharedItemSystem))]
public sealed partial class ItemComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("size")]
[Access(typeof(SharedItemSystem), Other = AccessPermissions.ReadExecute)]
public int Size = 5;
[DataField, ViewVariables(VVAccess.ReadWrite)]
[Access(typeof(SharedItemSystem))]
public ItemSize Size = ItemSize.Small;
[Access(typeof(SharedItemSystem))]
[DataField("inhandVisuals")]
[DataField]
public Dictionary<HandLocation, List<PrototypeLayerData>> InhandVisuals = new();
[Access(typeof(SharedItemSystem))]
[ViewVariables(VVAccess.ReadWrite)]
[DataField("heldPrefix")]
[DataField]
public string? HeldPrefix;
/// <summary>
@@ -39,10 +38,10 @@ public sealed partial class ItemComponent : Component
[Serializable, NetSerializable]
public sealed class ItemComponentState : ComponentState
{
public int Size { get; }
public ItemSize Size { get; }
public string? HeldPrefix { get; }
public ItemComponentState(int size, string? heldPrefix)
public ItemComponentState(ItemSize size, string? heldPrefix)
{
Size = size;
HeldPrefix = heldPrefix;
@@ -66,6 +65,43 @@ public sealed class VisualsChangedEvent : EntityEventArgs
}
}
/// <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 = 3,
/// <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 = 4,
/// <summary>
/// Items that are too large to place inside of any kind of container.
/// </summary>
Huge = 5,
/// <summary>
/// Picture furry gf
/// </summary>
Ginormous = 6
}
/// <summary>
/// Reference sizes for common containers and items.
/// </summary>

View File

@@ -1,3 +1,4 @@
using Content.Shared.Item;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
@@ -20,11 +21,11 @@ public sealed partial class ItemToggleComponent : Component
[ViewVariables(VVAccess.ReadWrite)]
[DataField("offSize")]
public int OffSize = 1;
public ItemSize OffSize = ItemSize.Small;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("onSize")]
public int OnSize = 9999;
public ItemSize OnSize = ItemSize.Huge;
}
[ByRefEvent]

View File

@@ -1,23 +1,27 @@
using Content.Shared.CombatMode;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Stacks;
using Content.Shared.Verbs;
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] private readonly SharedCombatModeSystem _combatMode = default!;
[Dependency] protected readonly SharedContainerSystem Container = default!;
public const int ItemSizeWeightTiny = 1;
public const int ItemSizeWeightSmall = 2;
public const int ItemSizeWeightNormal = 4;
public const int ItemSizeWeightLarge = 8;
public const int ItemSizeWeightHuge = 16;
public const int ItemSizeWeightGinormous = 32;
public override void Initialize()
{
base.Initialize();
@@ -33,13 +37,13 @@ public abstract class SharedItemSystem : EntitySystem
#region Public API
public void SetSize(EntityUid uid, int size, ItemComponent? component = null)
public void SetSize(EntityUid uid, ItemSize size, ItemComponent? component = null)
{
if (!Resolve(uid, ref component, false))
return;
component.Size = size;
Dirty(component);
Dirty(uid, component);
}
public void SetHeldPrefix(EntityUid uid, string? heldPrefix, ItemComponent? component = null)
@@ -51,7 +55,7 @@ public abstract class SharedItemSystem : EntitySystem
return;
component.HeldPrefix = heldPrefix;
Dirty(component);
Dirty(uid, component);
VisualsChanged(uid);
}
@@ -67,7 +71,7 @@ public abstract class SharedItemSystem : EntitySystem
item.InhandVisuals = otherItem.InhandVisuals;
item.HeldPrefix = otherItem.HeldPrefix;
Dirty(item);
Dirty(uid, item);
VisualsChanged(uid);
}
@@ -83,14 +87,7 @@ public abstract class SharedItemSystem : EntitySystem
protected virtual void OnStackCountChanged(EntityUid uid, ItemComponent component, StackCountChangedEvent args)
{
if (!TryComp<StackComponent>(uid, out var stack))
return;
if (!_prototype.TryIndex<StackPrototype>(stack.StackTypeId, out var stackProto) ||
stackProto.ItemSize is not { } size)
return;
SetSize(uid, args.NewCount * size, component);
}
private void OnHandleState(EntityUid uid, ItemComponent component, ref ComponentHandleState args)
@@ -135,7 +132,7 @@ public abstract class SharedItemSystem : EntitySystem
private void OnExamine(EntityUid uid, ItemComponent component, ExaminedEvent args)
{
args.PushMarkup(Loc.GetString("item-component-on-examine-size",
("size", component.Size)));
("size", GetItemSizeLocale(component.Size))));
}
/// <summary>
@@ -148,4 +145,32 @@ public abstract class SharedItemSystem : EntitySystem
public virtual void VisualsChanged(EntityUid owner)
{
}
[PublicAPI]
public static string GetItemSizeLocale(ItemSize size)
{
return Robust.Shared.Localization.Loc.GetString($"item-component-size-{size.ToString()}");
}
[PublicAPI]
public static int GetItemSizeWeight(ItemSize size)
{
switch (size)
{
case ItemSize.Tiny:
return ItemSizeWeightTiny;
case ItemSize.Small:
return ItemSizeWeightSmall;
case ItemSize.Normal:
return ItemSizeWeightNormal;
case ItemSize.Large:
return ItemSizeWeightLarge;
case ItemSize.Huge:
return ItemSizeWeightHuge;
case ItemSize.Ginormous:
return ItemSizeWeightGinormous;
default:
throw new ArgumentOutOfRangeException(nameof(size), size, null);
}
}
}

View File

@@ -1,10 +1,7 @@
using Content.Server.Storage.Components;
using Content.Shared.Hands;
using Content.Shared.Inventory;
using Content.Shared.Stacks;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Shared.Storage.EntitySystems;
@@ -56,7 +53,7 @@ public sealed class MagnetPickupSystem : EntitySystem
comp.NextScan += ScanDelay;
// No space
if (storage.StorageUsed >= storage.StorageCapacityMax)
if (!_storage.HasSpace((uid, storage)))
continue;
if (!_inventory.TryGetContainingSlot(uid, out var slotDef))

View File

@@ -4,7 +4,6 @@ using Content.Shared.CombatMode;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Destructible;
using Content.Shared.DoAfter;
using Content.Shared.Hands;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Implants.Components;
@@ -46,6 +45,8 @@ public abstract class SharedStorageSystem : EntitySystem
private EntityQuery<StackComponent> _stackQuery;
private EntityQuery<TransformComponent> _xformQuery;
public const ItemSize DefaultStorageMaxItemSize = ItemSize.Normal;
/// <inheritdoc />
public override void Initialize()
{
@@ -89,6 +90,7 @@ public abstract class SharedStorageSystem : EntitySystem
{
// TODO: I had this.
// We can get states being applied before the container is ready.
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (component.Container == default)
return;
@@ -229,7 +231,7 @@ public abstract class SharedStorageSystem : EntitySystem
return;
}
if (TryComp<TransformComponent>(uid, out var transformOwner) && TryComp<TransformComponent>(target, out var transformEnt))
if (_xformQuery.TryGetComponent(uid, out var transformOwner) && TryComp<TransformComponent>(target, out var transformEnt))
{
var parent = transformOwner.ParentUid;
@@ -239,7 +241,7 @@ public abstract class SharedStorageSystem : EntitySystem
_transform
);
if (PlayerInsertEntityInWorld(uid, args.User, target, storageComp))
if (PlayerInsertEntityInWorld((uid, storageComp), args.User, target))
{
RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(GetNetEntity(uid),
new List<NetEntity> { GetNetEntity(target) },
@@ -285,7 +287,7 @@ public abstract class SharedStorageSystem : EntitySystem
var angle = targetXform.LocalRotation;
if (PlayerInsertEntityInWorld(uid, args.Args.User, entity, component))
if (PlayerInsertEntityInWorld((uid, component), args.Args.User, entity))
{
successfullyInserted.Add(entity);
successfullyInsertedPositions.Add(position);
@@ -322,7 +324,7 @@ public abstract class SharedStorageSystem : EntitySystem
/// </summary>
private void OnInteractWithItem(EntityUid uid, StorageComponent storageComp, StorageInteractWithItemEvent args)
{
if (args.Session.AttachedEntity is not EntityUid player)
if (args.Session.AttachedEntity is not { } player)
return;
var entity = GetEntity(args.InteractedItemUID);
@@ -396,27 +398,10 @@ public abstract class SharedStorageSystem : EntitySystem
public void RecalculateStorageUsed(EntityUid uid, StorageComponent storageComp)
{
storageComp.StorageUsed = 0;
foreach (var entity in storageComp.Container.ContainedEntities)
{
if (!_itemQuery.TryGetComponent(entity, out var itemComp))
continue;
var size = itemComp.Size;
storageComp.StorageUsed += size;
}
_appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.StorageUsed);
_appearance.SetData(uid, StorageVisuals.Capacity, storageComp.StorageCapacityMax);
}
public int GetAvailableSpace(EntityUid uid, StorageComponent? component = null)
{
if (!Resolve(uid, ref component))
return 0;
return component.StorageCapacityMax - component.StorageUsed;
// it might make more sense to use the weights instead of the slots.
// I'm not sure.
_appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.Container.ContainedEntities.Count);
_appearance.SetData(uid, StorageVisuals.Capacity, storageComp.MaxSlots);
}
/// <summary>
@@ -449,17 +434,20 @@ public abstract class SharedStorageSystem : EntitySystem
/// Verifies if an entity can be stored and if it fits
/// </summary>
/// <param name="uid">The entity to check</param>
/// <param name="insertEnt"></param>
/// <param name="reason">If returning false, the reason displayed to the player</param>
/// <param name="storageComp"></param>
/// <param name="item"></param>
/// <returns>true if it can be inserted, false otherwise</returns>
public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null)
public bool CanInsert(EntityUid uid, EntityUid insertEnt, out string? reason, StorageComponent? storageComp = null, ItemComponent? item = null)
{
if (!Resolve(uid, ref storageComp))
if (!Resolve(uid, ref storageComp) || !Resolve(insertEnt, ref item))
{
reason = null;
return false;
}
if (TryComp(insertEnt, out TransformComponent? transformComp) && transformComp.Anchored)
if (Transform(insertEnt).Anchored)
{
reason = "comp-storage-anchored-failure";
return false;
@@ -477,15 +465,19 @@ public abstract class SharedStorageSystem : EntitySystem
return false;
}
if (TryComp(insertEnt, out StorageComponent? storage) &&
storage.StorageCapacityMax >= storageComp.StorageCapacityMax)
if (item.Size > GetMaxItemSize((uid, storageComp)))
{
reason = "comp-storage-too-big";
return false;
}
if (storageComp.Container.ContainedEntities.Count >= storageComp.MaxSlots)
{
reason = "comp-storage-insufficient-capacity";
return false;
}
if (TryComp(insertEnt, out ItemComponent? itemComp) &&
itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed)
if (SharedItemSystem.GetItemSizeWeight(item.Size) + GetCumulativeItemSizes(uid, storageComp) > GetMaxTotalWeight((uid, storageComp)))
{
reason = "comp-storage-insufficient-capacity";
return false;
@@ -542,8 +534,7 @@ public abstract class SharedStorageSystem : EntitySystem
if (insertStack.Count > 0)
{
// Try to insert it as a new stack.
if (TryComp(insertEnt, out ItemComponent? itemComp) &&
itemComp.Size > storageComp.StorageCapacityMax - storageComp.StorageUsed ||
if (!CanInsert(uid, insertEnt, out _, storageComp) ||
!storageComp.Container.Insert(insertEnt))
{
// If we also didn't do any stack fills above then just end
@@ -568,7 +559,9 @@ public abstract class SharedStorageSystem : EntitySystem
/// <summary>
/// Inserts an entity into storage from the player's active hand
/// </summary>
/// <param name="uid"></param>
/// <param name="player">The player to insert an entity from</param>
/// <param name="storageComp"></param>
/// <returns>true if inserted, false otherwise</returns>
public bool PlayerInsertHeldEntity(EntityUid uid, EntityUid player, StorageComponent? storageComp = null)
{
@@ -589,21 +582,23 @@ public abstract class SharedStorageSystem : EntitySystem
return false;
}
return PlayerInsertEntityInWorld(uid, player, toInsert.Value, storageComp);
return PlayerInsertEntityInWorld((uid, storageComp), player, toInsert.Value);
}
/// <summary>
/// Inserts an Entity (<paramref name="toInsert"/>) in the world into storage, informing <paramref name="player"/> if it fails.
/// <paramref name="toInsert"/> is *NOT* held, see <see cref="PlayerInsertHeldEntity(Robust.Shared.GameObjects.EntityUid)"/>.
/// <paramref name="toInsert"/> is *NOT* held, see <see cref="PlayerInsertHeldEntity(EntityUid,EntityUid,StorageComponent)"/>.
/// </summary>
/// <param name="uid"></param>
/// <param name="player">The player to insert an entity with</param>
/// <param name="toInsert"></param>
/// <returns>true if inserted, false otherwise</returns>
public bool PlayerInsertEntityInWorld(EntityUid uid, EntityUid player, EntityUid toInsert, StorageComponent? storageComp = null)
public bool PlayerInsertEntityInWorld(Entity<StorageComponent?> uid, EntityUid player, EntityUid toInsert)
{
if (!Resolve(uid, ref storageComp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid))
if (!Resolve(uid, ref uid.Comp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid))
return false;
if (!Insert(uid, toInsert, out _, user: player, storageComp))
if (!Insert(uid, toInsert, out _, user: player, uid.Comp))
{
_popupSystem.PopupClient(Loc.GetString("comp-storage-cant-insert"), uid, player);
return false;
@@ -611,6 +606,65 @@ public abstract class SharedStorageSystem : EntitySystem
return true;
}
/// <summary>
/// Returns true if there is enough space to theoretically fit another item.
/// </summary>
public bool HasSpace(Entity<StorageComponent?> uid)
{
if (!Resolve(uid, ref uid.Comp))
return false;
return uid.Comp.Container.ContainedEntities.Count < uid.Comp.MaxSlots &&
GetCumulativeItemSizes(uid, uid.Comp) < GetMaxTotalWeight(uid);
}
/// <summary>
/// Returns the sum of all the ItemSizes of the items inside of a storage.
/// </summary>
public int GetCumulativeItemSizes(EntityUid uid, StorageComponent? component = null)
{
if (!Resolve(uid, ref component))
return 0;
var sum = 0;
foreach (var item in component.Container.ContainedEntities)
{
if (!_itemQuery.TryGetComponent(item, out var itemComp))
continue;
sum += SharedItemSystem.GetItemSizeWeight(itemComp.Size);
}
return sum;
}
public ItemSize GetMaxItemSize(Entity<StorageComponent?> uid)
{
if (!Resolve(uid, ref uid.Comp))
return DefaultStorageMaxItemSize;
// If we specify a max item size, use that
if (uid.Comp.MaxItemSize != null)
return uid.Comp.MaxItemSize.Value;
if (!_itemQuery.TryGetComponent(uid, out var item))
return DefaultStorageMaxItemSize;
// 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
return (ItemSize) Math.Max((int) item.Size - 1, 1);
}
public int GetMaxTotalWeight(Entity<StorageComponent?> uid)
{
if (!Resolve(uid, ref uid.Comp))
return 0;
if (uid.Comp.MaxTotalWeight != null)
return uid.Comp.MaxTotalWeight.Value;
return uid.Comp.MaxSlots * SharedItemSystem.GetItemSizeWeight(GetMaxItemSize(uid));
}
/// <summary>
/// Plays a clientside pickup animation for the specified uid.
/// </summary>

View File

@@ -1,3 +1,5 @@
using Content.Shared.Item;
using Content.Shared.Storage.EntitySystems;
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
@@ -20,6 +22,25 @@ namespace Content.Shared.Storage
[ViewVariables]
public Container Container = default!;
/// <summary>
/// The max number of entities that can be inserted into this storage.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public int MaxSlots = 7;
/// <summary>
/// The maximum size item that can be inserted into this storage,
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
[Access(typeof(SharedStorageSystem))]
public ItemSize? MaxItemSize;
/// <summary>
/// A limit for the cumulative ItemSizes that can be inserted in this storage.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public int? MaxTotalWeight;
// TODO: Make area insert its own component.
[DataField("quickInsert")]
public bool QuickInsert; // Can insert storables by "attacking" them with the storage entity
@@ -45,18 +66,6 @@ namespace Content.Shared.Storage
[DataField("blacklist")]
public EntityWhitelist? Blacklist;
/// <summary>
/// How much storage is currently being used by contained entities.
/// </summary>
[ViewVariables, DataField("storageUsed"), AutoNetworkedField]
public int StorageUsed;
/// <summary>
/// Maximum capacity for storage.
/// </summary>
[DataField("capacity"), AutoNetworkedField]
public int StorageCapacityMax = 10000;
/// <summary>
/// Sound played whenever an entity is inserted into storage.
/// </summary>

View File

@@ -1,9 +1,10 @@
comp-storage-no-item-size = N/A
comp-storage-cant-insert = Can't insert.
comp-storage-insufficient-capacity = Insufficient capacity.
comp-storage-too-big = Too big!
comp-storage-insufficient-capacity = No room!
comp-storage-invalid-container = This doesn't go in there!
comp-storage-anchored-failure = Can't insert an anchored item.
comp-storage-cant-drop = You can't let go of { THE($entity) }!
comp-storage-window-title = Storage Item
comp-storage-window-volume = Items: { $itemCount }, Stored: { $usedVolume }/{ $maxVolume }
comp-storage-window-volume-unlimited = Items: { $itemCount }
comp-storage-window-volume = Items: { $itemCount }/{ $maxCount }, Max Size: {$size}
comp-storage-window-volume-full = [color=orange][bold]FULL[/bold][/color], Max Size: {$size}

View File

@@ -7,3 +7,10 @@ pick-up-verb-get-data-text = Pick Up
pick-up-verb-get-data-text-inventory = Put in hand
item-component-on-examine-size = Size: {$size}
item-component-size-Tiny = tiny
item-component-size-Small = small
item-component-size-Normal = normal
item-component-size-Large = large
item-component-size-Huge = huge
item-component-size-Ginormous = bulky

View File

@@ -874,36 +874,6 @@ entities:
pos: -0.5,0.5
parent: 325
type: Transform
- proto: ClothingBeltSyndieHolster
entities:
- uid: 317
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- canCollide: False
type: Physics
- proto: ClothingHandsGlovesCombat
entities:
- uid: 316
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- canCollide: False
type: Physics
- proto: ClothingMaskGasSyndicate
entities:
- uid: 318
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- canCollide: False
type: Physics
- proto: ComputerIFFSyndicate
entities:
- uid: 40
@@ -926,16 +896,6 @@ entities:
ents:
- 245
type: ContainerContainer
- proto: Crowbar
entities:
- uid: 313
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- canCollide: False
type: Physics
- proto: CyberPen
entities:
- uid: 77
@@ -1672,16 +1632,6 @@ entities:
pos: -2.5,-3.5
parent: 325
type: Transform
- proto: Multitool
entities:
- uid: 314
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- canCollide: False
type: Physics
- proto: NitrogenTankFilled
entities:
- uid: 105
@@ -1880,20 +1830,6 @@ entities:
type: Transform
- canCollide: False
type: Physics
- proto: Screwdriver
entities:
- uid: 310
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- selected:
enum.DamageStateVisualLayers.Base:
screwdriver: '#1861D5FF'
type: RandomSprite
- canCollide: False
type: Physics
- proto: SheetGlass1
entities:
- uid: 244
@@ -2382,21 +2318,6 @@ entities:
- pos: 1.5699697,-0.44908836
parent: 325
type: Transform
- containers:
storagebase: !type:Container
showEnts: False
occludes: True
ents:
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
type: ContainerContainer
- canCollide: False
type: Physics
- proto: ToyFigurineNukie
@@ -2656,16 +2577,6 @@ entities:
- pos: -2.5,2.5
parent: 325
type: Transform
- proto: Welder
entities:
- uid: 312
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- canCollide: False
type: Physics
- proto: WindoorSecure
entities:
- uid: 166
@@ -2687,30 +2598,6 @@ entities:
ents:
- 346
type: ContainerContainer
- proto: Wirecutter
entities:
- uid: 315
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- selected:
enum.DamageStateVisualLayers.Base:
cutters: '#D58C18FF'
type: RandomSprite
- canCollide: False
type: Physics
- proto: Wrench
entities:
- uid: 311
components:
- flags: InContainer
type: MetaData
- parent: 177
type: Transform
- canCollide: False
type: Physics
- proto: YellowOxygenTankFilled
entities:
- uid: 167

View File

@@ -102471,8 +102471,6 @@ entities:
type: Transform
- count: 15
type: Stack
- size: 15
type: Item
- proto: SheetPlasma
entities:
- uid: 12944
@@ -102564,8 +102562,6 @@ entities:
type: Transform
- count: 20
type: Stack
- size: 20
type: Item
- proto: Shovel
entities:
- uid: 12955

View File

@@ -78331,8 +78331,6 @@ entities:
type: Transform
- count: 15
type: Stack
- size: 30
type: Item
- proto: StoolBar
entities:
- uid: 921

View File

@@ -291,8 +291,7 @@
- id: RegenerativeMesh
- id: RCD
- id: RCDAmmo
- id: RCDAmmo
- id: RCDAmmo
amount: 2
- id: CableMVStack
- id: CableHVStack

View File

@@ -198,6 +198,9 @@
name: syndicate pyjama duffel bag
description: Contains 3 pairs of syndicate pyjamas and 3 plushies for the ultimate sleepover.
components:
- type: Storage
maxSlots: 16
maxTotalWeight: 44
- type: StorageFill
contents:
- id: ClothingUniformJumpsuitPyjamaSyndicateRed
@@ -231,6 +234,8 @@
id: ClothingBackpackChameleonFill
suffix: Fill, Chameleon
components:
- type: Storage
maxSlots: 9
- type: StorageFill
contents:
- id: ClothingUniformJumpsuitChameleon

View File

@@ -278,7 +278,7 @@
containers:
ballistic-ammo: !type:Container
- type: Item
size: 30
size: Normal
- type: Sprite
sprite: Objects/Storage/boxes.rsi

View File

@@ -37,7 +37,8 @@
- state: box
- state: light
- type: Storage
capacity: 60
maxSlots: 12
maxTotalWeight: 24
whitelist:
components:
- LightBulb
@@ -60,7 +61,8 @@
- state: box
- state: lighttube
- type: Storage
capacity: 60
maxSlots: 12
maxTotalWeight: 24
whitelist:
components:
- LightBulb
@@ -85,7 +87,8 @@
- state: box
- state: lightmixed
- type: Storage
capacity: 60
maxSlots: 12
maxTotalWeight: 24
whitelist:
components:
- LightBulb
@@ -108,7 +111,6 @@
- state: box
- state: pda
- type: Storage
capacity: 60
whitelist:
components:
- Pda
@@ -128,7 +130,6 @@
- state: box
- state: pda
- type: Storage
capacity: 60
whitelist:
components:
- IdCard
@@ -148,7 +149,6 @@
- state: box
- state: headset
- type: Storage
capacity: 60
whitelist:
components:
- Headset
@@ -192,7 +192,6 @@
description: A special box for sensitive people.
components:
- type: Storage
capacity: 30
- type: Sprite
layers:
- state: box_hug
@@ -234,6 +233,12 @@
id: BoxPerformer
description: Happy Hatsune Miku Day!
components:
- type: Storage
maxItemSize: Normal
whitelist:
components:
- Clothing
- Food
- type: StorageFill
contents:
- id: ClothingShoesBootsPerformer
@@ -267,7 +272,7 @@
- id: TrashBag
amount: 6
- type: Storage
capacity: 800
maxItemSize: Normal
whitelist:
tags:
- TrashBag
@@ -294,7 +299,6 @@
- state: box
- state: encryptokey
- type: Storage
capacity: 30
whitelist:
components:
- EncryptionKey
@@ -386,13 +390,12 @@
description: Two syndicate encryption keys for the price of one. Miniaturized for ease of use.
components:
- type: Item
size: 15
size: Normal
- type: StorageFill
contents:
- id: EncryptionKeySyndie
amount: 2
- type: Storage
capacity: 15
- type: entity
name: deathrattle implant box
@@ -401,7 +404,7 @@
description: Six deathrattle implants and handheld GPS devices for the whole squad.
components:
- type: Item
size: 60
size: Normal
- type: StorageFill
contents:
- id: DeathRattleImplanter
@@ -409,7 +412,8 @@
- id: HandheldGPSBasic
amount: 6
- type: Storage
capacity: 60
maxSlots: 12
maxTotalWeight: 24
- type: Sprite
layers:
- state: box
@@ -434,19 +438,20 @@
description: This box filled with colorful darts.
components:
- type: Item
size: 40
size: Normal
- type: StorageFill
contents:
- id: Dart
amount: 5
amount: 3
- id: DartBlue
amount: 5
amount: 3
- id: DartPurple
amount: 5
amount: 3
- id: DartYellow
amount: 5
amount: 3
- type: Storage
capacity: 40
maxSlots: 12
maxTotalWeight: 24
- type: Sprite
layers:
- state: box

View File

@@ -93,10 +93,13 @@
parent: BoxCardboard
id: BoxMouthSwab
components:
- type: Storage
maxSlots: 10
maxTotalWeight: 20
- type: StorageFill
contents:
- id: DiseaseSwab
amount: 30
amount: 10
- type: Sprite
layers:
- state: box

View File

@@ -49,6 +49,12 @@
id: BoxZiptie
description: A box full of zipties.
components:
- type: Storage
maxSlots: 10
maxTotalWeight: 20
whitelist:
components:
- Handcuff
- type: StorageFill
contents:
- id: Zipties
@@ -64,6 +70,9 @@
id: BoxForensicPad
description: A box of forensic pads.
components:
- type: Storage
maxSlots: 10
maxTotalWeight: 20
- type: StorageFill
contents:
- id: ForensicPad

View File

@@ -302,7 +302,7 @@
- id: TargetDarts
amount: 1
- id: BoxDarts
amount: 1
amount: 2
- id: BoxDarts
amount: 1
prob: 0.05

View File

@@ -89,14 +89,11 @@
- type: StorageFill
contents:
- id: Brutepack
amount: 1
- id: Ointment
amount: 1
- id: Bloodpack
amount: 1
- id: Gauze
- id: EmergencyMedipen #You never know what people are going to latejoin into
amount: 6
amount: 3
- type: entity
id: ClothingBeltPlantFilled
@@ -124,6 +121,10 @@
name: grenadier chest rig
suffix: Filled
components:
- type: Item
size: Large
- type: Storage
maxSlots: 8
- type: StorageFill
contents:
- id: ExGrenade

View File

@@ -15,6 +15,10 @@
parent: BriefcaseSyndie
suffix: SniperBundle
components:
- type: Item
size: Huge
- type: Storage
maxItemSize: Large
- type: StorageFill
contents:
- id: WeaponSniperHristov

View File

@@ -12,8 +12,7 @@
- id: Ointment
amount: 2
- id: Gauze
- id: PillTricordrazine
amount: 5
- id: PillCanisterTricordrazine
# see https://github.com/tgstation/blob/master/code/game/objects/items/storage/firstaid.dm for example contents
- type: entity
@@ -28,10 +27,8 @@
- id: Ointment
amount: 2
- id: SyringeSigynate
- id: PillKelotane
amount: 5
- id: PillDermaline
amount: 5
- id: PillCanisterKelotane
- id: PillCanisterDermaline
- type: entity
id: MedkitBruteFilled
@@ -45,10 +42,8 @@
- id: Gauze
- id: Bloodpack
- id: SyringeTranexamicAcid
- id: PillIron
amount: 5
- id: PillBicaridine
amount: 5
- id: PillCanisterIron
- id: PillCanisterBicaridine
- type: entity
id: MedkitToxinFilled
@@ -60,10 +55,8 @@
- id: SyringeIpecac
- id: SyringeEthylredoxrazine
- id: AntiPoisonMedipen
- id: PillDylovene
amount: 5
- id: PillCharcoal
amount: 3
- id: PillCanisterDylovene
- id: PillCanisterCharcoal
- type: entity
id: MedkitOxygenFilled
@@ -76,8 +69,7 @@
- id: EmergencyOxygenTankFilled
- id: EmergencyMedipen
- id: SyringeInaprovaline
- id: PillDexalin
amount: 7
- id: PillCanisterDexalin
- type: entity
id: MedkitRadiationFilled
@@ -92,8 +84,7 @@
amount: 1
- id: EmergencyMedipen
amount: 1
- id: PillHyronalin
amount: 5
- id: PillCanisterHyronalin
- type: entity
id: MedkitAdvancedFilled
@@ -120,11 +111,9 @@
- id: MedicatedSuture
- id: RegenerativeMesh
- id: SyringeEphedrine
- id: SyringeSaline
- id: BruteAutoInjector
- id: BurnAutoInjector
- id: EmergencyMedipen
- id: Bloodpack
- type: entity
id: StimkitFilled

View File

@@ -8,13 +8,14 @@
sprite: Clothing/Back/Backpacks/backpack.rsi
state: icon
- type: Item
size: 9999
size: Huge
- type: Clothing
quickEquip: false
slots:
- back
- type: Storage
capacity: 100
maxSlots: 7
maxTotalWeight: 28
- type: ContainerContainer
containers:
storagebase: !type:Container
@@ -196,7 +197,8 @@
- type: Sprite
sprite: Clothing/Back/Backpacks/ertleader.rsi
- type: Storage
capacity: 250
maxSlots: 10
maxTotalWeight: 40
- type: entity
parent: ClothingBackpackERTLeader
@@ -259,8 +261,12 @@
shader: unshaded
- type: Clothing
equippedPrefix: holding
- type: Item
size: Ginormous
- type: Storage
capacity: 9999
maxSlots: 14
maxItemSize: Large
maxTotalWeight: 56 #14 normal-sized items.
- type: entity
parent: ClothingBackpackClown

View File

@@ -7,7 +7,8 @@
- type: Sprite
sprite: Clothing/Back/Duffels/duffel.rsi
- type: Storage
capacity: 120
maxSlots: 10
maxTotalWeight: 40
- type: ClothingSpeedModifier
walkModifier: 1
sprintModifier: 0.9
@@ -162,8 +163,6 @@
components:
- type: Sprite
sprite: Clothing/Back/Duffels/syndicate.rsi
- type: Storage
capacity: 131
- type: entity
parent: ClothingBackpackDuffelSyndicate
@@ -228,7 +227,11 @@
- state: icon
- state: icon-unlit
shader: unshaded
- type: Item
size: Ginormous
- type: Storage
capacity: 9999
maxSlots: 14
maxItemSize: Large
maxTotalWeight: 56 #14 normal-sized items.
- type: ClothingSpeedModifier
sprintModifier: 1 # makes its stats identical to other variants of bag of holding

View File

@@ -167,5 +167,9 @@
- state: icon
- state: icon-unlit
shader: unshaded
- type: Item
size: Ginormous
- type: Storage
capacity: 9999
maxSlots: 14
maxItemSize: Large
maxTotalWeight: 56 #14 normal-sized items.

View File

@@ -33,7 +33,7 @@
sprite: Clothing/Back/Backpacks/waterbackpack.rsi
state: icon
- type: Item
size: 200
size: Huge
- type: Clothing
slots: BACK
sprite: Clothing/Back/Backpacks/waterbackpack.rsi

View File

@@ -6,7 +6,7 @@
- type: Sprite
state: icon
- type: Item
size: 50
size: Normal
- type: Clothing
slots: [belt]
quickEquip: false
@@ -22,7 +22,10 @@
id: ClothingBeltStorageBase
components:
- type: Storage
capacity: 40
maxSlots: 7
maxItemSize: Normal
- type: Item
size: Large
- type: ContainerContainer
containers:
storagebase: !type:Container

View File

@@ -11,7 +11,7 @@
- type: Clothing
sprite: Clothing/Belt/utility.rsi
- type: Storage
capacity: 45
maxItemSize: Normal
# TODO: Fill this out more.
whitelist:
tags:
@@ -83,7 +83,6 @@
- type: Clothing
sprite: Clothing/Belt/ce.rsi
- type: Storage
capacity: 105
# TODO: Fill this out more.
whitelist:
tags:
@@ -238,7 +237,6 @@
- type: Clothing
sprite: Clothing/Belt/medical.rsi
- type: Storage
capacity: 60
whitelist:
tags:
- Wrench
@@ -393,7 +391,7 @@
- type: Clothing
sprite: Clothing/Belt/sheath.rsi
- type: Storage
capacity: 15
maxSlots: 1
whitelist:
tags:
- CaptainSabre
@@ -418,9 +416,8 @@
- type: Clothing
sprite: Clothing/Belt/bandolier.rsi
- type: Item
size: 60
size: Large
- type: Storage
capacity: 60
whitelist:
tags:
- ShellShotgun
@@ -451,7 +448,7 @@
- type: Clothing
sprite: Clothing/Belt/holster.rsi
- type: Storage
capacity: 20
maxSlots: 3
- type: entity
parent: ClothingBeltStorageBase
@@ -464,9 +461,8 @@
- type: Clothing
sprite: Clothing/Belt/syndieholster.rsi
- type: Item
size: 60
size: Large
- type: Storage
capacity: 60
whitelist:
components:
- Gun
@@ -528,9 +524,7 @@
- type: Clothing
sprite: Clothing/Belt/militarywebbingmed.rsi
- type: Item
size: 70
- type: Storage
capacity: 70
size: Large
- type: entity
parent: ClothingBeltBase
@@ -559,7 +553,7 @@
- type: Clothing
sprite: Clothing/Belt/wand.rsi
- type: Storage
capacity: 120
maxSlots: 8
whitelist:
tags:
- WizardWand

View File

@@ -12,7 +12,8 @@
visible: false
- type: Clothing
- type: Storage
capacity: 150
maxSlots: 15
maxItemSize: Small
whitelist:
tags:
- Arrow

View File

@@ -9,7 +9,8 @@
- type: Clothing
sprite: Clothing/Belt/waistbag_leather.rsi
- type: Storage
capacity: 20
maxSlots: 5
maxItemSize: Small
#Colorization on worn items doesn't work. If this ever gets fixed, you can duplicate this entry and change the color on the sprite to add color variants.
#- type: entity

View File

@@ -17,6 +17,8 @@
keySlots: 4
- type: Sprite
state: icon
- type: Item
size: Small
- type: Clothing
slots:
- ears

View File

@@ -7,3 +7,5 @@
state: icon
- type: Clothing
slots: [eyes]
- type: Item
size: Small

View File

@@ -9,6 +9,8 @@
slots: [gloves]
- type: Food
requiresSpecialDigestion: true
- type: Item
size: Small
- type: SolutionContainerManager
solutions:
food:

View File

@@ -8,6 +8,8 @@
- HEAD
- type: Sprite
state: icon
- type: Item
size: Small
- type: Food
requiresSpecialDigestion: true
- type: SolutionContainerManager
@@ -117,7 +119,7 @@
name: base space helmet
components:
- type: Item
size: 10
size: Small
- type: PressureProtection
highPressureMultiplier: 0.6
lowPressureMultiplier: 1000

View File

@@ -197,7 +197,7 @@
- type: Clothing
sprite: Clothing/Head/Hats/chefhat.rsi
- type: Storage
capacity: 5
maxSlots: 1
- type: UserInterface
interfaces:
- key: enum.StorageUiKey.Key
@@ -751,10 +751,10 @@
offset: "0, 0.12"
sprite: Clothing/Head/Hats/magician.rsi
- type: Item
size: 10
size: Small
sprite: Clothing/Head/Hats/magician.rsi
- type: Storage
capacity: 10
maxSlots: 1
- type: UserInterface
interfaces:
- key: enum.StorageUiKey.Key

View File

@@ -5,6 +5,8 @@
components:
- type: Sprite
state: icon
- type: Item
size: Small
- type: Clothing
slots: [mask]

View File

@@ -4,7 +4,7 @@
id: ClothingNeckBase
components:
- type: Item
size: 10
size: Small
- type: Clothing
quickEquip: true
slots:

View File

@@ -6,7 +6,7 @@
description: be nothing do crime
components:
- type: Item
size: 1
size: Tiny
- type: entity
parent: ClothingNeckPinBase

View File

@@ -15,7 +15,7 @@
id: ClothingOuterBaseLarge
components:
- type: Item
size: 80
size: Normal
- type: Clothing
slots:
- outerClothing
@@ -29,9 +29,9 @@
id: ClothingOuterStorageBase
components:
- type: Item
size: 10
size: Normal
- type: Storage
capacity: 10
maxSlots: 3
- type: ContainerContainer
containers:
storagebase: !type:Container
@@ -72,7 +72,7 @@
walkModifier: 0.4
sprintModifier: 0.6
- type: Item
size: 121
size: Large
- type: Armor
modifiers:
coefficients:
@@ -107,7 +107,7 @@
walkModifier: 0.8
sprintModifier: 0.8
- type: Item
size: 80
size: Normal
- type: entity
parent: ClothingOuterBase
@@ -130,7 +130,7 @@
id: ClothingOuterBaseMedium
components:
- type: Item
size: 30
size: Normal
- type: Clothing
slots:
- outerClothing

View File

@@ -350,7 +350,7 @@
walkModifier: 0.75
sprintModifier: 0.75
- type: Item
size: 50
size: Normal
- type: Tag
tags:
- WhitelistChameleon

View File

@@ -176,7 +176,7 @@
- type: Sprite
sprite: Clothing/OuterClothing/Suits/iansuit.rsi
- type: Item
size: 30
size: Normal
- type: Clothing
sprite: Clothing/OuterClothing/Suits/iansuit.rsi
- type: ToggleableClothing
@@ -197,7 +197,7 @@
- type: Sprite
sprite: Clothing/OuterClothing/Suits/carpsuit.rsi
- type: Item
size: 30
size: Normal
- type: Clothing
sprite: Clothing/OuterClothing/Suits/carpsuit.rsi
- type: ToggleableClothing

View File

@@ -11,7 +11,7 @@
- type: TemperatureProtection
coefficient: 0.1
- type: Item
size: 10
size: Small
- type: Armor
modifiers:
coefficients:

View File

@@ -8,6 +8,8 @@
- FEET
- type: Sprite
state: icon
- type: Item
size: Normal
- type: Food
requiresSpecialDigestion: true
- type: SolutionContainerManager
@@ -39,7 +41,7 @@
id: ClothingShoesStorageBase
components:
- type: Storage
capacity: 10
maxSlots: 1
- type: ContainerContainer
containers:
storagebase: !type:Container

View File

@@ -181,7 +181,7 @@
- state: equipped-FEET
offset: "0, -0.02"
- type: Item
size: 10
size: Small
sprite: Clothing/Shoes/Specific/large_clown.rsi
- type: ClothingSpeedModifier
walkModifier: 0.85

View File

@@ -3,6 +3,8 @@
parent: BaseItem
id: Clothing
components:
- type: Item
size: Normal
- type: Sprite
- type: Tag
tags:

View File

@@ -101,7 +101,7 @@
types:
Blunt: 20000
- type: Item
size: 1
size: Tiny
sprite: Objects/Weapons/Melee/debug.rsi
- type: entity

View File

@@ -959,7 +959,7 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: mouse-0
- type: Item
size: 5
size: Tiny
- type: Clothing
quickEquip: false
sprite: Mobs/Animals/mouse.rsi
@@ -1424,7 +1424,7 @@
groups:
Brute: 5
- type: Item
size: 80
size: Normal
- type: OnUseTimerTrigger
delay: 10
beepSound:
@@ -2329,7 +2329,7 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: hamster-0
- type: Item
size: 5
size: Tiny
- type: Physics
- type: Fixtures
fixtures:

View File

@@ -172,7 +172,9 @@
graph: SupplyBot
node: bot
- type: Storage
capacity: 250
maxSlots: 15
maxItemSize: Large
maxTotalWeight: 60
- type: UserInterface
interfaces:
- key: enum.StorageUiKey.Key

View File

@@ -370,9 +370,9 @@
map: ["6pack6"]
visible: false
- type: Item
size: 6
size: Normal
- type: Storage
capacity: 30
maxSlots: 6
whitelist:
tags:
- Cola

View File

@@ -28,7 +28,7 @@
abstract: true
components:
- type: Item
size: 1
size: Tiny
- type: FlavorProfile
flavors:
- bread

View File

@@ -21,7 +21,7 @@
- ReagentId: Vitamin
Quantity: 5
- type: Item
size: 25
size: Normal
- type: entity
parent: FoodCakeBase
@@ -43,7 +43,7 @@
- ReagentId: Vitamin
Quantity: 1
- type: Item
size: 5
size: Tiny
# Custom Cake Example
@@ -574,7 +574,7 @@
- type: Food
transferAmount: 12
- type: Item
size: 40
size: Normal
- type: PointLight
color: "#FFFF00"
radius: 2

View File

@@ -16,7 +16,7 @@
- ReagentId: Nutriment
Quantity: 3
- type: Item
size: 1
size: Tiny
- type: Tag
tags:
- DonkPocket

View File

@@ -21,7 +21,7 @@
Quantity: 3
- type: Item
sprite: Objects/Consumable/Food/Baked/donut.rsi
size: 1
size: Tiny
# Tastes like donut.
# The sprinkles are now an overlay, so you can put them on any donut! If we really

View File

@@ -16,7 +16,7 @@
- ReagentId: Nutriment
Quantity: 5
- type: Item
size: 1
size: Tiny
# Muffins/Buns

View File

@@ -24,7 +24,7 @@
- type: SliceableFood
count: 8
- type: Item
size: 8
size: Normal
- type: Tag
tags:
- Pizza
@@ -53,7 +53,7 @@
- ReagentId: Vitamin
Quantity: 0.8
- type: Item
size: 1
size: Tiny
- type: Tag
tags:
- Pizza

View File

@@ -38,13 +38,14 @@
map: ["pink-box6"]
visible: false
- type: Storage
capacity: 6
maxSlots: 6
maxTotalWeight: 12
whitelist:
tags:
- Donut
- type: Item
sprite: Objects/Consumable/Food/Baked/donut.rsi
size: 6
size: Small
heldPrefix: box
- type: StorageFill
contents:
@@ -118,13 +119,13 @@
map: ["box12"]
visible: false
- type: Storage
capacity: 12
maxSlots: 12
whitelist:
tags:
- Egg
- type: Item
sprite: Objects/Consumable/Food/egg.rsi
size: 12
size: Small
- type: StorageFill
contents:
- id: FoodEgg
@@ -175,6 +176,9 @@
id: EggBoxBroken
suffix: Broken
components:
- type: Storage
maxSlots: 12
maxItemSize: Small
- type: StorageFill
contents:
- id: Eggshells
@@ -206,7 +210,8 @@
map: ["enum.StorageVisualLayers.Door"]
# TODO make these entitystorage again + placeablesurface after entity storage ECS gets merged.
- type: Storage
capacity: 8
maxSlots: 1
maxItemSize: Normal
whitelist:
tags:
- Pizza
@@ -296,10 +301,10 @@
map: ["box6"]
visible: false
- type: Storage
capacity: 6
maxSlots: 6
- type: Item
sprite: Objects/Consumable/Food/Baked/nuggets.rsi
size: 6
size: Small
heldPrefix: box
- type: StorageFill
contents:
@@ -333,10 +338,10 @@
whitelist:
tags:
- DonkPocket
capacity: 6
maxSlots: 6
- type: Item
sprite: Objects/Consumable/Food/Baked/donkpocket.rsi
size: 6
size: Small
- type: StorageFill
contents:
- id: FoodDonkpocket
@@ -458,8 +463,6 @@
- type: Item
sprite: Objects/Storage/Happyhonk/clown.rsi
heldPrefix: box
- type: Storage
capacity: 30
- type: Tag
tags:
- Trash
@@ -583,10 +586,8 @@
suffix: Toy Unsafe, Snacks
name: syndicate snack box
components:
- type: Item
size: 64
- type: Storage
capacity: 64 # need more room for goodies
maxSlots: 9
- type: StorageFill
contents:
# toy

View File

@@ -37,7 +37,7 @@
- type: Item
sprite: Objects/Consumable/Food/snacks.rsi
heldPrefix: packet
size: 3
size: Tiny
- type: DamageOnLand
damage:
types:
@@ -63,7 +63,7 @@
- type: Item
sprite: Objects/Consumable/Food/snacks.rsi
heldPrefix: packet
size: 3
size: Tiny
- type: PhysicalComposition
materialComposition:
Steel: 100

View File

@@ -16,7 +16,7 @@
sprite: Objects/Consumable/Food/egg.rsi
- type: Item
sprite: Objects/Consumable/Food/egg.rsi
size: 1
size: Tiny
- type: SolutionContainerManager
solutions:
food:
@@ -69,7 +69,7 @@
sprite: Objects/Consumable/Food/egg.rsi
state: eggshells
- type: Item
size: 1
size: Tiny
- type: SolutionContainerManager
solutions:
food:

View File

@@ -24,7 +24,7 @@
- ReagentId: Fat
Quantity: 5
- type: Item
size: 5
size: Tiny
- type: Fixtures
fixtures:
fix1:

View File

@@ -136,7 +136,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/nettle.rsi
- type: Item
size: 10
size: Small
sprite: Objects/Specific/Hydroponics/nettle.rsi
- type: MeleeWeapon
damage:
@@ -166,7 +166,7 @@
- type: Sprite
sprite: Objects/Specific/Hydroponics/death_nettle.rsi
- type: Item
size: 10
size: Small
sprite: Objects/Specific/Hydroponics/death_nettle.rsi
- type: MeleeWeapon
damage:
@@ -836,7 +836,7 @@
sprite: Objects/Specific/Hydroponics/corn.rsi
state: cob
- type: Item
size: 1
size: Tiny
- type: Tag
tags:
- Trash
@@ -1365,7 +1365,7 @@
description: Round green object that you can slice and eat.
components:
- type: Item
size: 10
size: Small
- type: FlavorProfile
flavors:
- watermelon
@@ -1427,7 +1427,7 @@
description: Juicy green and red slice.
components:
- type: Item
size: 2
size: Tiny
- type: FlavorProfile
flavors:
- watermelon

View File

@@ -17,7 +17,7 @@
- ReagentId: Nutriment
Quantity: 8
- type: Item
size: 5
size: Small
# Kebabs

View File

@@ -21,7 +21,7 @@
- type: Item
sprite: Objects/Consumable/Food/snacks.rsi
heldPrefix: packet
size: 3
size: Tiny
# Snacks
# "Snacks" means food in a packet. Down the line this stuff can have multiple
@@ -101,7 +101,7 @@
state: chocolatebar
- type: Item
heldPrefix: chocolatebar
size: 3
size: Tiny
- type: Tag
tags:
- FoodSnack
@@ -346,7 +346,7 @@
- type: Item
sprite: Objects/Consumable/Food/snacks.rsi
heldPrefix: packet
size: 1
size: Tiny
- type: Food
trash: FoodCookieFortune
@@ -357,7 +357,7 @@
description: A carefully synthesized brick designed to contain the highest ratio of nutriment to volume. Tastes like shit.
components:
- type: Item
size: 10
size: Small
- type: Tag
tags:
- FoodSnack
@@ -381,7 +381,7 @@
flavors:
- nutribrick
- type: Item
size: 10
size: Small
- type: Sprite
state: nutribrick-open
- type: Food

View File

@@ -10,11 +10,9 @@
- state: closed
- state: open
map: ["openLayer"]
- type: Storage
capacity: 36
- type: Item
sprite: Objects/Consumable/Smokeables/Cigarettes/Cartons/green.rsi
size: 36
size: Normal
- type: StorageFill
contents:
- id: CigPackGreen

View File

@@ -17,7 +17,7 @@
slots: [ mask ]
equippedPrefix: unlit
- type: Item
size: 1
size: Tiny
- type: Construction
graph: smokeableCigarette
node: cigarette
@@ -41,7 +41,7 @@
slots: [ mask ]
equippedPrefix: unlit
- type: Item
size: 1
size: Tiny
- type: Construction
graph: smokeableCigarette
node: cigarette

View File

@@ -17,7 +17,7 @@
slots: [ mask ]
equippedPrefix: unlit
- type: Item
size: 1
size: Tiny
- type: Construction
graph: smokeableJoint
node: joint
@@ -48,7 +48,7 @@
slots: [ mask ]
equippedPrefix: unlit
- type: Item
size: 1
size: Tiny
- type: Construction
graph: smokeableBlunt
node: blunt

View File

@@ -43,9 +43,9 @@
Steel: 50
- type: SpaceGarbage
- type: Storage
capacity: 5
maxSlots: 5
- type: Item
size: 5
size: Small
- type: StorageFill
contents:
- id: Cigarette
@@ -108,9 +108,10 @@
Steel: 50
- type: SpaceGarbage
- type: Storage
capacity: 10
maxSlots: 10
maxTotalWeight: 20
- type: Item
size: 10
size: Small
- type: StorageFill
contents:
- id: CigaretteRandom

View File

@@ -9,7 +9,7 @@
tags:
- RollingPaper
- CigFilter
capacity: 20
maxSlots: 20
- type: StorageFill
contents:
- id: PaperRolling
@@ -31,7 +31,6 @@
tags:
- RollingPaper
- CigFilter
capacity: 32
- type: StorageFill
contents:
- id: PaperRolling
@@ -54,7 +53,7 @@
state: cigpaper
- type: Item
sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi
size: 5
size: Tiny
- type: Tag
tags:
- RollingPaper
@@ -68,8 +67,6 @@
components:
- type: Stack
count: 1
- type: Item
size: 1
- type: entity
id: CigaretteFilter
@@ -86,7 +83,7 @@
state: cigfilter
- type: Item
sprite: Objects/Consumable/Smokeables/Cigarettes/paper.rsi
size: 10
size: Tiny
- type: Tag
tags:
- CigFilter
@@ -99,5 +96,3 @@
components:
- type: Stack
count: 1
- type: Item
size: 2

View File

@@ -35,10 +35,10 @@
map: ["cigar8"]
visible: false
- type: Storage
capacity: 8
maxSlots: 8
- type: Item
sprite: Objects/Consumable/Smokeables/Cigars/case.rsi
size: 8
size: Small
- type: StorageFill
contents:
- id: Cigar

View File

@@ -19,7 +19,7 @@
slots: [ mask ]
equippedPrefix: unlit
- type: Item
size: 1
size: Tiny
- type: entity
id: CigarSpent
@@ -49,7 +49,7 @@
slots: [ mask ]
equippedPrefix: unlit
- type: Item
size: 1
size: Tiny
- type: entity
id: CigarGoldSpent

View File

@@ -12,7 +12,7 @@
slots: [ mask ]
equippedPrefix: unlit
- type: Item
size: 3
size: Tiny
sprite: Objects/Consumable/Smokeables/Pipes/pipe.rsi
- type: Appearance
- type: BurnStateVisuals

View File

@@ -9,6 +9,6 @@
layers:
- state: icon
- type: Item
size: 1001
size: Huge
- type: StaticPrice
price: 0

View File

@@ -15,9 +15,7 @@
suffix: Empty
components:
- type: Item
size: 30
- type: Storage
capacity: 30
size: Normal
- type: entity
id: PresentRandomUnsafe

View File

@@ -17,7 +17,7 @@
sprite: Objects/Devices/timer.rsi
state: timer
- type: Item
size: 5
size: Small
- type: PayloadTrigger
components:
- type: OnUseTimerTrigger

View File

@@ -8,7 +8,7 @@
sprite: Objects/Misc/module.rsi
state: abductor_mod
- type: Item
size: 10
size: Small
- type: Tag
tags:
- WeaponPistolCHIMPUpgradeKit

View File

@@ -8,7 +8,7 @@
sprite: Objects/Devices/forensic_scanner.rsi
state: forensicnew
- type: Item
size: 5
size: Small
- type: Clothing
sprite: Objects/Devices/forensic_scanner.rsi
quickEquip: false

View File

@@ -37,7 +37,7 @@
components:
- IdCard
- type: Item
size: 10
size: Tiny
- type: ContainerContainer
containers:
PDA-id: !type:ContainerSlot {}

View File

@@ -16,7 +16,7 @@
- key: enum.InstrumentUiKey.Key
type: InstrumentBoundUserInterface
- type: Item
size: 24
size: Normal
- type: StaticPrice
price: 200

View File

@@ -14,7 +14,7 @@
sprite: Objects/Fun/Instruments/trumpet.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/trumpet.rsi
- type: Tag
tags:
@@ -32,7 +32,7 @@
sprite: Objects/Fun/Instruments/trombone.rsi
state: icon
- type: Item
size: 48
size: Normal
sprite: Objects/Fun/Instruments/trombone.rsi
- type: Tag
tags:
@@ -50,7 +50,7 @@
sprite: Objects/Fun/Instruments/frenchhorn.rsi
state: icon
- type: Item
size: 48
size: Normal
sprite: Objects/Fun/Instruments/frenchhorn.rsi
- type: Tag
tags:
@@ -69,7 +69,7 @@
sprite: Objects/Fun/Instruments/euphonium.rsi
state: icon
- type: Item
size: 48
size: Normal
sprite: Objects/Fun/Instruments/euphonium.rsi
- type: Tag
tags:

View File

@@ -10,7 +10,7 @@
- type: Instrument
program: 121
- type: Item
size: 10
size: Small
- type: entity
parent: BaseHandheldInstrument
@@ -24,7 +24,7 @@
- type: Instrument
program: 122
- type: Item
size: 10
size: Small
- type: entity
parent: BaseHandheldInstrument
@@ -38,7 +38,7 @@
- type: Instrument
program: 123
- type: Item
size: 5
size: Tiny
- type: entity
parent: BaseHandheldInstrument
@@ -55,7 +55,7 @@
- type: Instrument
program: 124
- type: Item
size: 10
size: Small
- type: Prayable
sentMessage: prayer-popup-notify-centcom-sent
notifiactionPrefix: prayer-chat-notify-centcom
@@ -74,7 +74,7 @@
- type: Instrument
program: 125
- type: Item
size: 10
size: Small
- type: entity
parent: BaseHandheldInstrument
@@ -88,7 +88,7 @@
- type: Instrument
program: 126
- type: Item
size: 5
size: Tiny
- type: entity
parent: BaseHandheldInstrument
@@ -102,7 +102,7 @@
sprite: Objects/Fun/Instruments/gunpet.rsi
state: icon
- type: Item
size: 15
size: Normal
sprite: Objects/Fun/Instruments/gunpet.rsi
- type: Tag
tags:
@@ -125,7 +125,7 @@
- BrassInstrument #Go figure.
- type: Item
sprite: Objects/Fun/Instruments/bike_horn.rsi
size: 10
size: Small
- type: Clothing
sprite: Objects/Fun/Instruments/bike_horn.rsi
slots: [Belt]

View File

@@ -9,7 +9,7 @@
sprite: Objects/Fun/Instruments/glockenspiel.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/glockenspiel.rsi
- type: Tag
tags:
@@ -58,7 +58,7 @@
sprite: Objects/Fun/Instruments/microphone.rsi
state: icon
- type: Item
size: 10
size: Small
sprite: Objects/Fun/Instruments/microphone.rsi
- type: entity
@@ -76,7 +76,7 @@
sprite: Objects/Fun/Instruments/h_synthesizer.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/h_synthesizer.rsi
- type: Tag
tags:
@@ -135,5 +135,5 @@
sprite: Objects/Fun/Instruments/h_synthesizer.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/h_synthesizer.rsi

View File

@@ -15,7 +15,7 @@
sprite: Objects/Fun/Instruments/eguitar.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/eguitar.rsi
- type: Clothing
quickEquip: false
@@ -44,7 +44,7 @@
sprite: Objects/Fun/Instruments/bassguitar.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/bassguitar.rsi
- type: Clothing
quickEquip: false
@@ -72,7 +72,7 @@
sprite: Objects/Fun/Instruments/rockguitar.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/rockguitar.rsi
- type: Clothing
quickEquip: false
@@ -115,7 +115,7 @@
- StringInstrument
- type: Item
sprite: Objects/Fun/Instruments/guitar.rsi
size: 24
size: Normal
- type: Clothing
quickEquip: false
slots:
@@ -178,7 +178,7 @@
sprite: Objects/Fun/Instruments/banjo.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/banjo.rsi
- type: Tag
tags:
@@ -200,7 +200,7 @@
sprite: Objects/Fun/Instruments/violin.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/violin.rsi
- type: Tag
tags:
@@ -218,7 +218,7 @@
sprite: Objects/Fun/Instruments/viola.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/viola.rsi
- type: Tag
tags:
@@ -236,7 +236,7 @@
sprite: Objects/Fun/Instruments/cello.rsi
state: icon
- type: Item
size: 48
size: Normal
sprite: Objects/Fun/Instruments/cello.rsi
- type: Tag
tags:

View File

@@ -16,7 +16,7 @@
sprite: Objects/Fun/Instruments/saxophone.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/saxophone.rsi
- type: Tag
tags:
@@ -45,7 +45,7 @@
sprite: Objects/Fun/Instruments/accordion.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/accordion.rsi
- type: Tag
tags:
@@ -62,7 +62,7 @@
sprite: Objects/Fun/Instruments/harmonica.rsi
state: icon
- type: Item
size: 10
size: Small
sprite: Objects/Fun/Instruments/harmonica.rsi
- type: Tag
tags:
@@ -80,7 +80,7 @@
sprite: Objects/Fun/Instruments/clarinet.rsi
state: icon
- type: Item
size: 20
size: Normal
sprite: Objects/Fun/Instruments/clarinet.rsi
- type: Tag
tags:
@@ -98,7 +98,7 @@
sprite: Objects/Fun/Instruments/flute.rsi
state: icon
- type: Item
size: 20
size: Normal
sprite: Objects/Fun/Instruments/flute.rsi
- type: Tag
tags:
@@ -116,7 +116,7 @@
sprite: Objects/Fun/Instruments/recorder.rsi
state: icon
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/Instruments/recorder.rsi
- type: Tag
tags:
@@ -134,7 +134,7 @@
sprite: Objects/Fun/Instruments/panflute.rsi
state: icon
- type: Item
size: 15
size: Normal
sprite: Objects/Fun/Instruments/panflute.rsi
- type: Tag
tags:
@@ -153,7 +153,7 @@
sprite: Objects/Fun/Instruments/ocarina.rsi
state: icon
- type: Item
size: 15
size: Normal
sprite: Objects/Fun/Instruments/ocarina.rsi
- type: Tag
tags:
@@ -171,7 +171,7 @@
sprite: Objects/Fun/Instruments/bagpipes.rsi
state: icon
- type: Item
size: 48
size: Normal
sprite: Objects/Fun/Instruments/bagpipes.rsi
- type: Tag
tags:

View File

@@ -9,7 +9,7 @@
state: icon
- type: Item
sprite: Objects/Fun/bikehorn.rsi
size: 5
size: Tiny
- type: Clothing
sprite: Objects/Fun/bikehorn.rsi
slots: [Belt]
@@ -58,7 +58,7 @@
state: icon
- type: Item
sprite: Objects/Fun/cluwnehorn.rsi
size: 5
size: Tiny
- type: Clothing
sprite: Objects/Fun/cluwnehorn.rsi
slots: [Belt]
@@ -100,7 +100,7 @@
state: icon
- type: Item
sprite: Objects/Fun/goldbikehorn.rsi
size: 5
size: Tiny
- type: Clothing
sprite: Objects/Fun/goldbikehorn.rsi
slots: [Belt]
@@ -119,7 +119,7 @@
state: icon
- type: Item
sprite: Objects/Fun/bananiumhorn.rsi
size: 5
size: Tiny
- type: Clothing
sprite: Objects/Fun/bananiumhorn.rsi
slots: [Belt]

View File

@@ -9,7 +9,7 @@
sprite: Objects/Fun/crayons.rsi
- type: Item
sprite: Objects/Fun/crayons.rsi
size: 1
size: Tiny
- type: Tag
tags:
- Write
@@ -235,10 +235,11 @@
sprite: Objects/Fun/crayons.rsi
state: box
- type: Storage
capacity: 7
maxSlots: 7
maxTotalWeight: 7
- type: Item
sprite: Objects/Fun/crayons.rsi
size: 7
size: Small
heldPrefix: box
- type: StorageFill
contents:

View File

@@ -40,7 +40,7 @@
types:
Piercing: 4
- type: Item
size: 2
size: Tiny
sprite: Objects/Fun/Darts/dart_red.rsi
- type: ItemCooldown
- type: SolutionContainerManager

View File

@@ -13,7 +13,7 @@
tags:
- Dice
- type: Item
size: 2
size: Tiny
- type: entity
parent: BaseDice

View File

@@ -17,8 +17,8 @@
sprite: Objects/Fun/dice.rsi
state: dicebag
- type: Item
size: Small
- type: Storage
capacity: 18
whitelist:
tags:
- Dice
@@ -32,4 +32,5 @@
sprite: Objects/Fun/dice.rsi
state: magicdicebag
- type: Storage
capacity: 30
maxSlots: 14
maxTotalWeight: 28

View File

@@ -14,7 +14,7 @@
- type: DoAfter
- type: VentriloquistPuppet
- type: Item
size: 30
size: Normal
- type: Muted
- type: TypingIndicator
proto: robot

View File

@@ -554,7 +554,7 @@
components:
- type: Sprite
- type: Item
size: 24
size: Normal
- type: entity
parent: FoamWeaponBase
@@ -566,7 +566,7 @@
sprite: Objects/Fun/toys.rsi
state: foamcrossbow
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/toys.rsi
heldPrefix: foamcrossbow
- type: Gun
@@ -672,7 +672,7 @@
types:
Blunt: 0
- type: Item
size: 20
size: Small
sprite: Objects/Fun/toys.rsi
heldPrefix: foamblade
- type: ItemCooldown
@@ -692,7 +692,7 @@
sound:
path: /Audio/Effects/Footsteps/bounce.ogg
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/toys.rsi
heldPrefix: bask
- type: TileFrictionModifier
@@ -708,7 +708,7 @@
sprite: Objects/Fun/toys.rsi
state: football
- type: Item
size: 12
size: Small
sprite: Objects/Fun/toys.rsi
heldPrefix: footb
@@ -725,7 +725,7 @@
sound:
path: /Audio/Effects/Footsteps/bounce.ogg
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/toys.rsi
heldPrefix: beachb
- type: TileFrictionModifier
@@ -741,7 +741,7 @@
sprite: Objects/Fun/toys.rsi
state: synb
- type: Item
size: 24
size: Small
sprite: Objects/Fun/toys.rsi
heldPrefix: synb
- type: Damageable
@@ -760,7 +760,7 @@
sprite: Objects/Fun/toys.rsi
state: corgib
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/toys.rsi
heldPrefix: corgib
- type: Damageable
@@ -785,7 +785,7 @@
intensity: 2000
falloffPower: 2.6
- type: Item
size: 12
size: Small
sprite: Objects/Fun/toys.rsi
heldPrefix: singularitytoy
@@ -803,7 +803,7 @@
radius: 2
color: "#00CCFF"
- type: Item
size: 24
size: Normal
sprite: Objects/Fun/toys.rsi
heldPrefix: orb
- type: TileFrictionModifier
@@ -828,7 +828,7 @@
shader: unshaded
map: [ "blade" ]
- type: Item
size: 5
size: Small
sprite: Objects/Weapons/Melee/e_sword.rsi
- type: UseDelay
delay: 1.0
@@ -892,7 +892,7 @@
types:
Blunt: 0
- type: Item
size: 15
size: Normal
sprite: Objects/Weapons/Melee/cutlass.rsi
- type: entity
@@ -934,7 +934,7 @@
- type: StaminaDamageOnHit
damage: 8
- type: Item
size: 5
size: Small
sprite: Objects/Fun/rubber_hammer.rsi
- type: Appearance
- type: DisarmMalus

View File

@@ -9,7 +9,7 @@
sprite: Objects/Materials/Sheets/glass.rsi
- type: Item
sprite: Objects/Materials/Sheets/glass.rsi
size: 30
size: Normal
- type: StaticPrice
price: 0
- type: Tag
@@ -83,8 +83,6 @@
- type: Stack
stackType: Glass
count: 10
- type: Item
size: 10
- type: entity
parent: SheetGlass
@@ -96,16 +94,12 @@
- type: Stack
stackType: Glass
count: 1
- type: Item
size: 1
- type: entity
parent: SheetGlass
id: SheetGlassLingering0
suffix: Lingering, 0
components:
- type: Item
size: 0
- type: Stack
lingering: true
count: 0
@@ -174,8 +168,6 @@
- type: Stack
stackType: ReinforcedGlass
count: 1
- type: Item
size: 1
- type: entity
parent: SheetGlassBase
@@ -201,7 +193,6 @@
map: ["base"]
- type: Item
heldPrefix: pglass
size: 30
- type: Construction
graph: Glass
node: SheetPGlass
@@ -239,8 +230,6 @@
- type: Stack
stackType: PlasmaGlass
count: 1
- type: Item
size: 1
- type: entity
parent: SheetPGlass
@@ -281,8 +270,6 @@
- type: Stack
stackType: ReinforcedPlasmaGlass
count: 1
- type: Item
size: 1
- type: entity
parent: SheetGlassBase
@@ -345,8 +332,6 @@
- type: Stack
stackType: UraniumGlass
count: 1
- type: Item
size: 1
- type: entity
parent: SheetUGlass
@@ -386,5 +371,3 @@
- type: Stack
stackType: ReinforcedUraniumGlass
count: 1
- type: Item
size: 1

View File

@@ -8,7 +8,7 @@
sprite: Objects/Materials/Sheets/metal.rsi
- type: Item
sprite: Objects/Materials/Sheets/metal.rsi
size: 30
size: Normal
- type: StaticPrice
price: 0
- type: Tag
@@ -75,8 +75,6 @@
name: steel
suffix: 10
components:
- type: Item
size: 10
- type: Sprite
state: steel
- type: Stack
@@ -89,8 +87,6 @@
name: steel
suffix: Single
components:
- type: Item
size: 1
- type: Sprite
state: steel
- type: Stack
@@ -102,8 +98,6 @@
id: SheetSteelLingering0
suffix: Lingering, 0
components:
- type: Item
size: 0
- type: Stack
lingering: true
count: 0
@@ -145,8 +139,6 @@
- type: Stack
stackType: Plasteel
count: 10
- type: Item
size: 10
- type: entity
parent: SheetPlasteel
@@ -159,5 +151,3 @@
- type: Stack
stackType: Plasteel
count: 1
- type: Item
size: 1

Some files were not shown because too many files have changed in this diff Show More