diff --git a/Content.Shared/Item/SharedItemSystem.cs b/Content.Shared/Item/SharedItemSystem.cs index a1db9fa82c..05bb47076a 100644 --- a/Content.Shared/Item/SharedItemSystem.cs +++ b/Content.Shared/Item/SharedItemSystem.cs @@ -16,9 +16,14 @@ public abstract partial class SharedItemSystem : EntitySystem [Dependency] private SharedHandsSystem _handsSystem = default!; [Dependency] protected SharedContainerSystem Container = default!; + private readonly List _sortedSizes = []; + public override void Initialize() { base.Initialize(); + + ProtoMan.PrototypesReloaded += OnPrototypesReloaded; + SubscribeLocalEvent>(AddPickupVerb); SubscribeLocalEvent(OnHandInteract); SubscribeLocalEvent(OnItemAutoState); @@ -26,6 +31,26 @@ public abstract partial class SharedItemSystem : EntitySystem SubscribeLocalEvent(OnExamine); SubscribeLocalEvent(OnItemToggle); + + UpdatePrototypeCache(); + } + + public override void Shutdown() + { + ProtoMan.PrototypesReloaded -= OnPrototypesReloaded; + } + + public void OnPrototypesReloaded(PrototypesReloadedEventArgs args) + { + if (args.WasModified()) + UpdatePrototypeCache(); + } + + private void UpdatePrototypeCache() + { + _sortedSizes.Clear(); + _sortedSizes.AddRange(ProtoMan.EnumeratePrototypes()); + _sortedSizes.Sort(); } private void OnItemAutoState(EntityUid uid, ItemComponent component, ref AfterAutoHandleStateEvent args) @@ -148,6 +173,58 @@ public abstract partial class SharedItemSystem : EntitySystem return ProtoMan.Index(id); } + /// + /// Returns the prototype of the smallest size + /// + [PublicAPI] + public ItemSizePrototype GetSmallestSize() + { + return _sortedSizes[0]; + } + + /// + /// Returns the prototype of the largest size + /// + [PublicAPI] + public ItemSizePrototype GetLargestSize() + { + return _sortedSizes[^1]; + } + + /// + /// Returns a size prototype that is "one" smaller than the size prototype given + /// + /// null if the size is the smallest + [PublicAPI] + public ItemSizePrototype? GetSizeSmaller(ProtoId size) + { + var index = _sortedSizes.FindIndex(sizePrototype => sizePrototype.ID == size); + if (index == -1) + { + Log.Error($"Size prototype: {size} not found in _sortedSizes"); + return null; + } + + return index > 0 ? _sortedSizes[index - 1] : null; + } + + /// + /// Returns a size prototype that is "one" bigger than the size prototype given + /// + /// null if the size is the largest + [PublicAPI] + public ItemSizePrototype? GetSizeBigger(ProtoId size) + { + var index = _sortedSizes.FindIndex(sizePrototype => sizePrototype.ID == size); + if (index == -1) + { + Log.Error($"Size prototype: {size} not found in _sortedSizes"); + return null; + } + + return index < _sortedSizes.Count - 1 ? _sortedSizes[index + 1] : null; + } + /// /// Notifies any entity that is holding or wearing this item that they may need to update their sprite. /// diff --git a/Content.Shared/Storage/Components/SecretStashComponent.cs b/Content.Shared/Storage/Components/SecretStashComponent.cs index 54350952a8..5f8b0ed052 100644 --- a/Content.Shared/Storage/Components/SecretStashComponent.cs +++ b/Content.Shared/Storage/Components/SecretStashComponent.cs @@ -24,9 +24,10 @@ namespace Content.Shared.Storage.Components { /// /// Max item size that can be inserted into secret stash. + /// If null, uses one size smaller than the stash's size. /// - [DataField("maxItemSize")] - public ProtoId MaxItemSize = "Small"; + [DataField] + public ProtoId? MaxItemSize; /// /// Entity blacklist for secret stashes. diff --git a/Content.Shared/Storage/EntitySystems/SecretStashSystem.cs b/Content.Shared/Storage/EntitySystems/SecretStashSystem.cs index 0cc59f343e..4e2e5c8742 100644 --- a/Content.Shared/Storage/EntitySystems/SecretStashSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SecretStashSystem.cs @@ -17,6 +17,7 @@ using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using Robust.Shared.Map; +using Robust.Shared.Prototypes; namespace Content.Shared.Storage.EntitySystems; @@ -107,8 +108,26 @@ public sealed partial class SecretStashSystem : EntitySystem return false; } - // check if item is too big to fit into secret stash or is in the blacklist - if (_item.GetSizePrototype(itemComp.Size) > _item.GetSizePrototype(entity.Comp.MaxItemSize) || + // Check if item is too big to fit into secret stash or is in the blacklist. + ProtoId maxItemSize; + if (entity.Comp.MaxItemSize != null) + { + maxItemSize = entity.Comp.MaxItemSize.Value; + } + else if (TryComp(entity, out var stashItem)) + { + var smallerSize = _item.GetSizeSmaller(stashItem.Size); + if (smallerSize == null) + return false; + + maxItemSize = smallerSize.ID; + } + else + { + return false; + } + + if (_item.GetSizePrototype(itemComp.Size) > _item.GetSizePrototype(maxItemSize) || _whitelistSystem.IsWhitelistPass(entity.Comp.Blacklist, itemToHideUid)) { var msg = Loc.GetString("comp-secret-stash-action-hide-item-too-big", diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs index 85f72b876f..83c54626b9 100644 --- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs @@ -100,9 +100,6 @@ public abstract partial class SharedStorageSystem : EntitySystem private readonly List _entList = new(); private readonly HashSet _entSet = new(); - private readonly List _sortedSizes = new(); - private FrozenDictionary _nextSmallest = FrozenDictionary.Empty; - private const string QuickInsertUseDelayID = "quickInsert"; private const string OpenUiUseDelayID = "storage"; @@ -168,8 +165,6 @@ public abstract partial class SharedStorageSystem : EntitySystem .Register(); Subs.CVar(_cfg, CCVars.NestedStorage, OnNestedStorageCvar, true); - - UpdatePrototypeCache(); } private void OnItemSizeChanged(ref ItemSizeChangedEvent ev) @@ -242,30 +237,7 @@ public abstract partial class SharedStorageSystem : EntitySystem private void OnPrototypesReloaded(PrototypesReloadedEventArgs args) { - // TODO: This should update all entities in storage as well. - if (args.ByType.ContainsKey(typeof(ItemSizePrototype)) - || (args.Removed?.ContainsKey(typeof(ItemSizePrototype)) ?? false)) - { - UpdatePrototypeCache(); - } - } - - private void UpdatePrototypeCache() - { - _defaultStorageMaxItemSize = ProtoMan.Index(DefaultStorageMaxItemSize); - _sortedSizes.Clear(); - _sortedSizes.AddRange(ProtoMan.EnumeratePrototypes()); - _sortedSizes.Sort(); - - var nextSmallest = new KeyValuePair[_sortedSizes.Count]; - for (var i = 0; i < _sortedSizes.Count; i++) - { - var k = _sortedSizes[i].ID; - var v = _sortedSizes[Math.Max(i - 1, 0)]; - nextSmallest[i] = new(k, v); - } - - _nextSmallest = nextSmallest.ToFrozenDictionary(); + // TODO: This should update all entities in storage. } private void OnComponentInit(EntityUid uid, StorageComponent storageComp, ComponentInit args) @@ -1827,7 +1799,7 @@ public abstract partial class SharedStorageSystem : EntitySystem // if there is no max item size specified, the value used // is one below the item size of the storage entity. - return _nextSmallest[item.Size]; + return ItemSystem.GetSizeSmaller(item.Size) ?? ItemSystem.GetSmallestSize(); } /// diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml index f2317dcf58..fc968d40d3 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/cake.yml @@ -3,7 +3,7 @@ - type: entity parent: [SolutionNormal, FoodInjectableBase] - id: FoodCakeBase + id: FoodCakeBaseNoSecretStash abstract: true components: - type: FlavorProfile @@ -25,22 +25,14 @@ - type: Tag tags: - Cake - - type: SecretStash - maxItemSize: "Normal" - secretStashName: secret-stash-cake - damageEatenItemInside: - types: - Slash: 7.5 - - type: ToolOpenable - openToolQualityNeeded: Slicing - closeToolQualityNeeded: Slicing - verbOnly: true - - type: ContainerContainer - containers: - stash: !type:ContainerSlot {} - type: entity - parent: [SolutionVeryTiny, FoodCakeBase] + abstract: true + parent: [FoodCakeBaseNoSecretStash, BaseStashCake] + id: FoodCakeBase + +- type: entity + parent: [SolutionVeryTiny, FoodCakeBaseNoSecretStash] # no secret stash since it's tiny! id: FoodCakeSliceBase abstract: true description: Just a slice of cake, it is enough for everyone. diff --git a/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml b/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml index 562fb469a4..2745af5a59 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Plushies/plushies.yml @@ -4,7 +4,7 @@ - type: entity abstract: true - parent: [SolutionFood, SolutionSmall, BaseItem, BaseStash] + parent: [SolutionFood, SolutionSmall, BaseItem] id: BasePlushie components: - type: EmitSoundOnUse @@ -50,7 +50,39 @@ - ClothMade - type: entity - parent: BasePlushie + abstract: true + parent: [BasePlushie, BaseStashPlushie] + id: BasePlushieGinormous + components: + - type: Item + size: Ginormous + +- type: entity + abstract: true + parent: [BasePlushie, BaseStashPlushie] + id: BasePlushieNormal + components: + - type: Item + size: Normal + +- type: entity + abstract: true + parent: [BasePlushie, BaseStashPlushie] + id: BasePlushieSmall + components: + - type: Item + size: Small + +- type: entity + abstract: true + parent: BasePlushie # too smoll to fit secret stash + id: BasePlushieTiny + components: + - type: Item + size: Tiny + +- type: entity + parent: BasePlushieGinormous id: PlushieThrongler name: throngler plushie description: A stuffed toy to remind cargo techs of what they can no longer have. @@ -62,7 +94,6 @@ wideAnimationRotation: -135 attackRate: 10 - type: Item - size: Ginormous shape: - 0,0,3,3 - 1,4,2,6 @@ -73,7 +104,7 @@ CottonBurger: ThronglerPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieGhost name: ghost soft toy description: The start of your personal GHOST GANG! @@ -82,7 +113,6 @@ sprite: Mobs/Ghosts/ghost_human.rsi state: icon noRot: true - - type: Item - type: Physics fixedRotation: true bodyType: Dynamic @@ -137,7 +167,7 @@ CottonBurger: RevenantPlushie - type: entity - parent: BasePlushie + parent: BasePlushieNormal id: PlushieBee name: bee plushie description: A cute toy that resembles an even cuter programmer. You'd have to be a monster to grind this up. @@ -146,7 +176,6 @@ sprite: Objects/Fun/Plushies/bee.rsi state: icon - type: Item - size: Normal sprite: Objects/Fun/Plushies/bee.rsi - type: Extractable grindableSolutionName: food @@ -167,7 +196,7 @@ CottonBurger: BeePlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieHampter name: hampter plushie description: A cute stuffed toy that resembles a hamster. Its face looks squished. @@ -229,7 +258,7 @@ shader: unshaded - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieNuke name: nukie plushie description: A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious. @@ -251,7 +280,7 @@ CottonBurger: NukiePlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieRouny name: rouny plushie description: Rouny. @@ -273,7 +302,7 @@ CottonBurger: RounyPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieLamp name: lamp plushie description: A light emitting friend! @@ -290,7 +319,7 @@ CottonBurger: LampPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieArachind name: arachnid plushie description: An adorable stuffed toy that resembles an arachnid. It feels silky.. @@ -323,7 +352,7 @@ CottonBurger: ArachnidPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieLizard #Weh! name: lizard plushie description: An adorable stuffed toy that resembles a lizardperson. Made by CentComm as a token initiative to combat speciesism in work environments. "Welcome your new colleagues as you do this plush, with open arms!" @@ -384,7 +413,7 @@ Quantity: 10 - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieExperiment #Arf! name: experiment plushie description: A plushie of a canid of sorts. It yearns to be detonated on a landmine. @@ -568,7 +597,7 @@ CottonBurger: InversedLizardPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieDiona # TODO Better way of doing the flowering visuals. Probably make it an "AppearanceChangeEntityEffect" on reactive? name: diona plushie description: An adorable stuffed toy that resembles a diona. Love water and cuddles. Do not wet! @@ -645,7 +674,7 @@ CottonBurger: DionaPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieSharkBlue name: blue shark soft toy description: Big and safe to have by your side if you want to discover the world below the surface of the ocean. @@ -723,7 +752,7 @@ - ClothMade - type: entity - parent: BasePlushie + parent: BasePlushieNormal id: PlushieRatvar name: ratvar plushie description: A large stuffed doll of the elder god Ratvar. @@ -732,7 +761,6 @@ sprite: Objects/Fun/Plushies/ratvar.rsi state: icon - type: Item - size: Normal sprite: Objects/Fun/Plushies/ratvar.rsi - type: MultiHandedItem - type: Clothing @@ -745,7 +773,7 @@ CottonBurger: RatvarPlushie - type: entity - parent: BasePlushie + parent: BasePlushieNormal id: PlushieNar name: nar'sie plushie description: A large stuffed doll of the elder goddess Nar'Sie. @@ -754,7 +782,6 @@ sprite: Objects/Fun/Plushies/narsie.rsi state: icon - type: Item - size: Normal sprite: Objects/Fun/Plushies/narsie.rsi - type: MultiHandedItem - type: Clothing @@ -767,7 +794,7 @@ CottonBurger: NarPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieCarp name: carp plushie description: An adorable stuffed toy that resembles the monstrous space carp. @@ -875,7 +902,7 @@ - PlushieCarpHolo - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieSlime name: slime plushie description: An adorable stuffed toy that resembles a slime. It's basically a hacky sack. @@ -908,7 +935,7 @@ CottonBurger: SlimePlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieSnake name: snake plushie description: An adorable stuffed toy that resembles a snake. @@ -946,7 +973,7 @@ CottonBurger: SnakePlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: ToyMouse name: mouse toy description: A colorful toy mouse! @@ -980,7 +1007,7 @@ CottonBurger: MousePlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieVox name: vox plushie description: SKREEEEEEEEEEEE! @@ -1019,7 +1046,7 @@ CottonBurger: VoxPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieAtmosian name: atmosian plushie description: An adorable stuffed toy that resembles a brave atmosian. Unfortunately, he won't fix those depressurizations for you. @@ -1041,7 +1068,7 @@ CottonBurger: AtmosianPlushie - type: entity - parent: BasePlushie + parent: BasePlushieNormal id: PlushieXeno name: xeno plushie description: An adorable stuffed toy that resembles a scary xenomorf. You're lucky it's just a toy. @@ -1049,8 +1076,6 @@ - type: Sprite sprite: Objects/Fun/Plushies/xeno.rsi state: icon - - type: Item - size: Normal - type: EmitSoundOnUse sound: &PlushieXenoSound path: /Audio/Weapons/Xeno/alien_spitacid.ogg @@ -1082,7 +1107,7 @@ CottonBurger: XenoPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushiePenguin name: penguin plushie description: I use arch btw! @@ -1100,7 +1125,7 @@ CottonBurger: PenguinPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieHuman name: human plushie description: This is a felt plush of a human. All craftsmanship is of the lowest quality. The human is naked. The human is crying. The human is screaming. @@ -1147,7 +1172,7 @@ CottonBurger: HumanPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieMoth name: moth plushie description: Cute and fluffy moth plushie. Enjoy, bz! @@ -1180,7 +1205,7 @@ CottonBurger: MothPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieSheep name: sheep plushie description: A soft, wooly, stuffed sheep. 100% cotton. @@ -1256,7 +1281,7 @@ soundHit: *PlushieSpaceSheepSound - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: PlushieVulp name: vulpkanin plushie description: An adorable stuffed toy that resembles a vulpkanin. Yip! Yap! @@ -1297,7 +1322,7 @@ CottonBurger: PlushieVulp - type: entity - parent: BasePlushie + parent: BasePlushieTiny id: ToyIan name: ian toy description: Unable to eat, but just as fluffy as the real guy! @@ -1314,8 +1339,6 @@ head: - state: equipped-HELMET offset: "0, 0.06" - - type: Item - size: Tiny - type: EmitSoundOnUse sound: &SoundIan path: /Audio/Items/Toys/ian.ogg @@ -1336,7 +1359,7 @@ CottonBurger: IanPlushie - type: entity - parent: BasePlushie + parent: BasePlushieSmall id: ToyAmongPequeno name: among pequeño description: Sus! diff --git a/Resources/Prototypes/Entities/Objects/Fun/sound_maker.yml b/Resources/Prototypes/Entities/Objects/Fun/sound_maker.yml index f0f1e3d1f8..8110dafb45 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/sound_maker.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/sound_maker.yml @@ -261,7 +261,7 @@ - type: entity abstract: true - parent: [BaseItem, BaseStash] + parent: BaseItem id: BaseRubberToy components: - type: Tag @@ -317,7 +317,7 @@ - ToyRubberDuck - type: entity - parent: BaseRubberToy + parent: [BaseRubberToy, BaseStashPlushie] id: RubberChicken name: rubber chicken description: A stress inducing parody of nature's most delectable avian. diff --git a/Resources/Prototypes/Entities/Objects/base_item.yml b/Resources/Prototypes/Entities/Objects/base_item.yml index 11eea7faf7..c4ad726d25 100644 --- a/Resources/Prototypes/Entities/Objects/base_item.yml +++ b/Resources/Prototypes/Entities/Objects/base_item.yml @@ -217,13 +217,9 @@ abstract: true id: BaseStash components: - - type: Speech - speechVerb: Default # for pais (In the secret stash) - type: SecretStash - secretStashName: secret-stash-plushie blacklist: components: - - SecretStash # Prevents being able to insert plushies inside each other (infinite plush)! - NukeDisk # Because a core mechanic of nukies should not be "where in this bag is the fucking disk" tags: - QuantumSpinInverter # It will cause issues with the grinder... @@ -231,7 +227,31 @@ - type: ToolOpenable openToolQualityNeeded: Slicing closeToolQualityNeeded: Slicing # Should probably be stitching or something if that gets added - name: secret-stash-plushie - type: ContainerContainer containers: stash: !type:ContainerSlot {} + +- type: entity + abstract: true + parent: BaseStash + id: BaseStashPlushie + components: + - type: Speech + speechVerb: Default # for pais (In the secret stash) + - type: SecretStash + secretStashName: secret-stash-plushie + - type: ToolOpenable + name: secret-stash-plushie + +- type: entity + abstract: true + parent: BaseStash + id: BaseStashCake + components: + - type: SecretStash + secretStashName: secret-stash-cake + damageEatenItemInside: + types: + Slash: 7.5 + - type: ToolOpenable + verbOnly: true diff --git a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml index 45701055ef..15f110e3c9 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml @@ -84,6 +84,7 @@ - type: Appearance - type: SecretStash secretStashName: secret-stash-toilet + maxItemSize: Small - type: ToolOpenable openToolQualityNeeded: Prying closeToolQualityNeeded: Prying