StorageComponent.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. using Content.Shared.Item;
  2. using Content.Shared.Storage.EntitySystems;
  3. using Content.Shared.Whitelist;
  4. using Robust.Shared.Audio;
  5. using Robust.Shared.Containers;
  6. using Robust.Shared.GameStates;
  7. using Robust.Shared.Map;
  8. using Robust.Shared.Prototypes;
  9. using Robust.Shared.Serialization;
  10. namespace Content.Shared.Storage
  11. {
  12. /// <summary>
  13. /// Handles generic storage with window, such as backpacks.
  14. /// </summary>
  15. [RegisterComponent, NetworkedComponent]
  16. public sealed partial class StorageComponent : Component
  17. {
  18. public static string ContainerId = "storagebase";
  19. [ViewVariables]
  20. public Container Container = default!;
  21. /// <summary>
  22. /// A dictionary storing each entity to its position within the storage grid.
  23. /// </summary>
  24. [DataField, ViewVariables(VVAccess.ReadWrite)]
  25. public Dictionary<EntityUid, ItemStorageLocation> StoredItems = new();
  26. /// <summary>
  27. /// A dictionary storing each saved item to its location in the grid.
  28. /// When trying to quick insert an item, if there is an empty location with the same name it will be placed there.
  29. /// Multiple items with the same name can be saved, they will be checked individually.
  30. /// </summary>
  31. [DataField]
  32. public Dictionary<string, List<ItemStorageLocation>> SavedLocations = new();
  33. /// <summary>
  34. /// A list of boxes that comprise a combined grid that determines the location that items can be stored.
  35. /// </summary>
  36. [DataField, ViewVariables(VVAccess.ReadWrite)]
  37. public List<Box2i> Grid = new();
  38. /// <summary>
  39. /// The maximum size item that can be inserted into this storage,
  40. /// </summary>
  41. [DataField, ViewVariables(VVAccess.ReadWrite)]
  42. [Access(typeof(SharedStorageSystem))]
  43. public ProtoId<ItemSizePrototype>? MaxItemSize;
  44. // TODO: Make area insert its own component.
  45. [DataField]
  46. public bool QuickInsert; // Can insert storables by clicking them with the storage entity
  47. /// <summary>
  48. /// Minimum delay between quick/area insert actions.
  49. /// </summary>
  50. /// <remarks>Used to prevent autoclickers spamming server with individual pickup actions.</remarks>
  51. public TimeSpan QuickInsertCooldown = TimeSpan.FromSeconds(0.5);
  52. /// <summary>
  53. /// Minimum delay between UI open actions.
  54. /// <remarks>Used to spamming opening sounds.</remarks>
  55. /// </summary>
  56. [DataField]
  57. public TimeSpan OpenUiCooldown = TimeSpan.Zero;
  58. /// <summary>
  59. /// Can insert stuff by clicking the storage entity with it.
  60. /// </summary>
  61. [DataField]
  62. public bool ClickInsert = true;
  63. /// <summary>
  64. /// Open the storage window when pressing E.
  65. /// When false you can still open the inventory using verbs.
  66. /// </summary>
  67. [DataField]
  68. public bool OpenOnActivate = true;
  69. /// <summary>
  70. /// How many entities area pickup can pickup at once.
  71. /// </summary>
  72. public const int AreaPickupLimit = 10;
  73. [DataField]
  74. public bool AreaInsert; // Clicking with the storage entity causes it to insert all nearby storables after a delay
  75. [DataField]
  76. public int AreaInsertRadius = 1;
  77. /// <summary>
  78. /// Whitelist for entities that can go into the storage.
  79. /// </summary>
  80. [DataField]
  81. public EntityWhitelist? Whitelist;
  82. /// <summary>
  83. /// Blacklist for entities that can go into storage.
  84. /// </summary>
  85. [DataField]
  86. public EntityWhitelist? Blacklist;
  87. /// <summary>
  88. /// Sound played whenever an entity is inserted into storage.
  89. /// </summary>
  90. [DataField]
  91. public SoundSpecifier? StorageInsertSound = new SoundCollectionSpecifier("storageRustle");
  92. /// <summary>
  93. /// Sound played whenever an entity is removed from storage.
  94. /// </summary>
  95. [DataField]
  96. public SoundSpecifier? StorageRemoveSound;
  97. /// <summary>
  98. /// Sound played whenever the storage window is opened.
  99. /// </summary>
  100. [DataField]
  101. public SoundSpecifier? StorageOpenSound = new SoundCollectionSpecifier("storageRustle");
  102. /// <summary>
  103. /// Sound played whenever the storage window is closed.
  104. /// </summary>
  105. [DataField]
  106. public SoundSpecifier? StorageCloseSound;
  107. /// <summary>
  108. /// If not null, ensures that all inserted items are of the same orientation
  109. /// Horizontal - items are stored laying down
  110. /// Vertical - items are stored standing up
  111. /// </summary>
  112. [DataField, ViewVariables(VVAccess.ReadWrite)]
  113. public StorageDefaultOrientation? DefaultStorageOrientation;
  114. /// <summary>
  115. /// If true, sets StackVisuals.Hide to true when the container is closed
  116. /// Used in cases where there are sprites that are shown when the container is open but not
  117. /// when it is closed
  118. /// </summary>
  119. [DataField]
  120. public bool HideStackVisualsWhenClosed = true;
  121. [Serializable, NetSerializable]
  122. public enum StorageUiKey : byte
  123. {
  124. Key,
  125. }
  126. /// <summary>
  127. /// Allow or disallow showing the "open/close storage" verb.
  128. /// This is desired on items that we don't want to be accessed by the player directly.
  129. /// </summary>
  130. [DataField]
  131. public bool ShowVerb = true;
  132. }
  133. [Serializable, NetSerializable]
  134. public sealed class OpenNestedStorageEvent : EntityEventArgs
  135. {
  136. public readonly NetEntity InteractedItemUid;
  137. public readonly NetEntity StorageUid;
  138. public OpenNestedStorageEvent(NetEntity interactedItemUid, NetEntity storageUid)
  139. {
  140. InteractedItemUid = interactedItemUid;
  141. StorageUid = storageUid;
  142. }
  143. }
  144. [Serializable, NetSerializable]
  145. public sealed class StorageInteractWithItemEvent : EntityEventArgs
  146. {
  147. public readonly NetEntity InteractedItemUid;
  148. public readonly NetEntity StorageUid;
  149. public StorageInteractWithItemEvent(NetEntity interactedItemUid, NetEntity storageUid)
  150. {
  151. InteractedItemUid = interactedItemUid;
  152. StorageUid = storageUid;
  153. }
  154. }
  155. [Serializable, NetSerializable]
  156. public sealed class StorageSetItemLocationEvent : EntityEventArgs
  157. {
  158. public readonly NetEntity ItemEnt;
  159. public readonly NetEntity StorageEnt;
  160. public readonly ItemStorageLocation Location;
  161. public StorageSetItemLocationEvent(NetEntity itemEnt, NetEntity storageEnt, ItemStorageLocation location)
  162. {
  163. ItemEnt = itemEnt;
  164. StorageEnt = storageEnt;
  165. Location = location;
  166. }
  167. }
  168. [Serializable, NetSerializable]
  169. public sealed class StorageTransferItemEvent : EntityEventArgs
  170. {
  171. public readonly NetEntity ItemEnt;
  172. /// <summary>
  173. /// Target storage to receive the transfer.
  174. /// </summary>
  175. public readonly NetEntity StorageEnt;
  176. public readonly ItemStorageLocation Location;
  177. public StorageTransferItemEvent(NetEntity itemEnt, NetEntity storageEnt, ItemStorageLocation location)
  178. {
  179. ItemEnt = itemEnt;
  180. StorageEnt = storageEnt;
  181. Location = location;
  182. }
  183. }
  184. [Serializable, NetSerializable]
  185. public sealed class StorageInsertItemIntoLocationEvent : EntityEventArgs
  186. {
  187. public readonly NetEntity ItemEnt;
  188. public readonly NetEntity StorageEnt;
  189. public readonly ItemStorageLocation Location;
  190. public StorageInsertItemIntoLocationEvent(NetEntity itemEnt, NetEntity storageEnt, ItemStorageLocation location)
  191. {
  192. ItemEnt = itemEnt;
  193. StorageEnt = storageEnt;
  194. Location = location;
  195. }
  196. }
  197. [Serializable, NetSerializable]
  198. public sealed class StorageSaveItemLocationEvent : EntityEventArgs
  199. {
  200. public readonly NetEntity Item;
  201. public readonly NetEntity Storage;
  202. public StorageSaveItemLocationEvent(NetEntity item, NetEntity storage)
  203. {
  204. Item = item;
  205. Storage = storage;
  206. }
  207. }
  208. /// <summary>
  209. /// Network event for displaying an animation of entities flying into a storage entity
  210. /// </summary>
  211. [Serializable, NetSerializable]
  212. public sealed class AnimateInsertingEntitiesEvent : EntityEventArgs
  213. {
  214. public readonly NetEntity Storage;
  215. public readonly List<NetEntity> StoredEntities;
  216. public readonly List<NetCoordinates> EntityPositions;
  217. public readonly List<Angle> EntityAngles;
  218. public AnimateInsertingEntitiesEvent(NetEntity storage, List<NetEntity> storedEntities, List<NetCoordinates> entityPositions, List<Angle> entityAngles)
  219. {
  220. Storage = storage;
  221. StoredEntities = storedEntities;
  222. EntityPositions = entityPositions;
  223. EntityAngles = entityAngles;
  224. }
  225. }
  226. [ByRefEvent]
  227. public record struct StorageInteractAttemptEvent(bool Silent, bool Cancelled = false);
  228. [ByRefEvent]
  229. public record struct StorageInteractUsingAttemptEvent(bool Cancelled = false);
  230. [NetSerializable]
  231. [Serializable]
  232. public enum StorageVisuals : byte
  233. {
  234. Open,
  235. HasContents,
  236. StorageUsed,
  237. Capacity
  238. }
  239. [Serializable, NetSerializable]
  240. public enum StorageDefaultOrientation : byte
  241. {
  242. Horizontal,
  243. Vertical
  244. }
  245. }