diff --git a/Content.Shared/Interaction/Components/SmartEquipPickupStorageComponent.cs b/Content.Shared/Interaction/Components/SmartEquipPickupStorageComponent.cs new file mode 100644 index 0000000000000..c3511b6a8c488 --- /dev/null +++ b/Content.Shared/Interaction/Components/SmartEquipPickupStorageComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Interaction.Components; + +/// +/// Marks entity for
+/// Trying to smart equip this item will result in picking it up instead of taking something from +///
+[RegisterComponent, NetworkedComponent] +public sealed partial class SmartEquipPickupStorageComponent : Component; diff --git a/Content.Shared/Interaction/SmartEquipSystem.cs b/Content.Shared/Interaction/SmartEquipSystem.cs index 7529d8701d5d8..a90dece9d97b5 100644 --- a/Content.Shared/Interaction/SmartEquipSystem.cs +++ b/Content.Shared/Interaction/SmartEquipSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Input; +using Content.Shared.Interaction.Components; using Content.Shared.Inventory; using Content.Shared.Popups; using Content.Shared.Stacks; @@ -32,6 +33,7 @@ public sealed class SmartEquipSystem : EntitySystem /// public override void Initialize() { + CommandBinds.Builder .Bind(ContentKeyFunctions.SmartEquipBackpack, InputCmdHandler.FromDelegate(HandleSmartEquipBackpack, handle: false, outsidePrediction: false)) .Bind(ContentKeyFunctions.SmartEquipBelt, InputCmdHandler.FromDelegate(HandleSmartEquipBelt, handle: false, outsidePrediction: false)) @@ -113,7 +115,9 @@ private void HandleSmartEquip(ICommonSession? session, string equipmentSlot) // - without hand item: fail // 2) has an item, and that item is a storage item // - with hand item: try to put it in storage - // - without hand item: try to take the last stored item and put it in our hands + // - without hand item: + // - if item has SmartEquipPickupStorageComponent - try to pick up it + // - try to take the last stored item and put it in our hands // 3) has an item, and that item is an item slots holder // - with hand item: get the highest priority item slot with a valid whitelist and try to insert it // - without hand item: get the highest priority item slot with an item and try to eject it @@ -145,6 +149,14 @@ private void HandleSmartEquip(ICommonSession? session, string equipmentSlot) } // case 2 (storage item): + if (HasComp(slotItem) && handItem == null + && _inventory.CanUnequip(uid, equipmentSlot, out var _)) + { + if (_inventory.TryUnequip(uid, equipmentSlot, inventory: inventory, predicted: true, checkDoafter: true) + && _hands.TryPickup(uid, slotItem, handsComp: hands)) + return; + } + if (TryComp(slotItem, out var storage)) { switch (handItem) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml index edb3d40803545..99c1b046a101a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml @@ -30,6 +30,7 @@ soundGunshot: collection: BulletMiss soundEmpty: null + - type: SmartEquipPickupStorage - type: ItemSlots slots: projectiles: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml index cbed4c7760f54..7e11bbe55174c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/HMGs/hmgs.yml @@ -24,6 +24,7 @@ path: /Audio/Weapons/Guns/Empty/lmg_empty.ogg - type: StaticPrice price: 500 + - type: SmartEquipPickupStorage # No chamber because HMG may want its own - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml index 80d71669a7e8f..47c7f3a8f36e0 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml @@ -38,6 +38,7 @@ soundRack: path: /Audio/Weapons/Guns/Cock/lmg_cock.ogg - type: AmmoCounter + - type: SmartEquipPickupStorage - type: ItemSlots slots: gun_magazine: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 7a2b44e61529c..ff62ef7835f2f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -15,6 +15,7 @@ size: Ginormous - type: StaticPrice price: 500 + - type: SmartEquipPickupStorage - type: ContainerContainer containers: ballistic-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml index ec3fa31297307..5a72927893b72 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml @@ -37,6 +37,7 @@ - type: ChamberMagazineAmmoProvider soundRack: path: /Audio/Weapons/Guns/Cock/pistol_cock.ogg + - type: SmartEquipPickupStorage - type: ItemSlots slots: gun_magazine: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml index 1ea835a2cd495..0dadab0de983a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Revolvers/revolvers.yml @@ -32,6 +32,7 @@ path: /Audio/Weapons/Guns/Gunshots/revolver.ogg - type: UseDelay delay: 0.66 + - type: SmartEquipPickupStorage - type: ContainerContainer containers: revolver-ammo: !type:Container diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml index 6e5580e8a2139..70bcfc1e28944 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml @@ -28,6 +28,7 @@ - type: ChamberMagazineAmmoProvider soundRack: path: /Audio/Weapons/Guns/Cock/sf_rifle_cock.ogg + - type: SmartEquipPickupStorage - type: ItemSlots slots: gun_magazine: @@ -199,7 +200,7 @@ name: XL8 description: |- The Experimental Lecter 8 - An unreasonably expensive military grade assault rifle with integrated optic. + An unreasonably expensive military grade assault rifle with integrated optic. Uses .20 rifle ammo. components: - type: Sprite @@ -219,7 +220,7 @@ - Burst - SemiAuto - FullAuto - + - type: entity name: Estoc DMR parent: [BaseWeaponRifle, BaseSyndicateContraband] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index 2ecaaec89ebd9..622c1604e01a1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -34,6 +34,7 @@ - type: ChamberMagazineAmmoProvider soundRack: path: /Audio/Weapons/Guns/Cock/smg_cock.ogg + - type: SmartEquipPickupStorage - type: ItemSlots slots: gun_magazine: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml index 0a23a51a4fe4b..85534f8c22c95 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml @@ -37,6 +37,7 @@ proto: ShellShotgun soundInsert: path: /Audio/Weapons/Guns/MagIn/shotgun_insert.ogg + - type: SmartEquipPickupStorage - type: ContainerContainer containers: ballistic-ammo: !type:Container