diff --git a/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs b/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs index 127882e780..0fb661aaaa 100644 --- a/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/BallisticAmmoProviderComponent.cs @@ -45,4 +45,10 @@ public sealed class BallisticAmmoProviderComponent : Component /// [ViewVariables(VVAccess.ReadWrite), DataField("cycled")] public bool Cycled = true; + + /// + /// Is it okay for this entity to directly transfer its valid ammunition into another provider? + /// + [ViewVariables(VVAccess.ReadWrite), DataField("mayTransfer")] + public bool MayTransfer = false; } diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs index b6493f42d2..dcaaec58ab 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs @@ -26,6 +26,7 @@ public abstract partial class SharedGunSystem SubscribeLocalEvent(OnBallisticExamine); SubscribeLocalEvent>(OnBallisticVerb); SubscribeLocalEvent(OnBallisticInteractUsing); + SubscribeLocalEvent(OnBallisticAfterInteract); SubscribeLocalEvent(OnBallisticUse); } @@ -50,6 +51,81 @@ public abstract partial class SharedGunSystem Dirty(component); } + private void OnBallisticAfterInteract(EntityUid uid, BallisticAmmoProviderComponent component, AfterInteractEvent args) + { + if (args.Handled || + !component.MayTransfer || + !Timing.IsFirstTimePredicted || + args.Target == null || + args.Used == args.Target || + Deleted(args.Target) || + !TryComp(args.Target, out BallisticAmmoProviderComponent? targetComponent) || + targetComponent.Whitelist == null) + { + return; + } + + args.Handled = true; + + if (targetComponent.Entities.Count + targetComponent.UnspawnedCount == targetComponent.Capacity) + { + Popup( + Loc.GetString("gun-ballistic-transfer-target-full", + ("entity", args.Target)), + args.Target, + args.User); + return; + } + + if (component.Entities.Count + component.UnspawnedCount == 0) + { + Popup( + Loc.GetString("gun-ballistic-transfer-empty", + ("entity", args.Used)), + args.Used, + args.User); + return; + } + + void SimulateInsertAmmo(EntityUid ammo, EntityUid ammoProvider, EntityCoordinates coordinates) + { + var evInsert = new InteractUsingEvent(args.User, ammo, ammoProvider, coordinates); + RaiseLocalEvent(ammoProvider, evInsert); + } + + List ammo = new(); + var evTakeAmmo = new TakeAmmoEvent(1, ammo, Transform(args.Used).Coordinates, args.User); + RaiseLocalEvent(args.Used, evTakeAmmo); + + foreach (var shot in ammo) + { + if (shot is not AmmoComponent cast) + continue; + + if (!targetComponent.Whitelist.IsValid(cast.Owner)) + { + Popup( + Loc.GetString("gun-ballistic-transfer-invalid", + ("ammoEntity", cast.Owner), + ("targetEntity", args.Target.Value)), + args.Used, + args.User); + + // TODO: For better or worse, this will play a sound, but it's the + // more future-proof thing to do than copying the same code + // that OnBallisticInteractUsing has, sans sound. + SimulateInsertAmmo(cast.Owner, args.Used, Transform(args.Used).Coordinates); + } + else + { + SimulateInsertAmmo(cast.Owner, args.Target.Value, Transform(args.Target.Value).Coordinates); + } + + if (cast.Owner.IsClientSide()) + Del(cast.Owner); + } + } + private void OnBallisticVerb(EntityUid uid, BallisticAmmoProviderComponent component, GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || args.Hands == null) return; diff --git a/Resources/Locale/en-US/weapons/ranged/gun.ftl b/Resources/Locale/en-US/weapons/ranged/gun.ftl index 2dd840e25d..b1e75acf0c 100644 --- a/Resources/Locale/en-US/weapons/ranged/gun.ftl +++ b/Resources/Locale/en-US/weapons/ranged/gun.ftl @@ -15,6 +15,9 @@ gun-FullAuto = full-auto gun-ballistic-cycle = Cycle gun-ballistic-cycled = Cycled gun-ballistic-cycled-empty = Cycled (empty) +gun-ballistic-transfer-invalid = {CAPITALIZE(THE($ammoEntity))} won't fit inside {THE($targetEntity)}! +gun-ballistic-transfer-empty = {CAPITALIZE(THE($entity))} is empty. +gun-ballistic-transfer-target-full = {CAPITALIZE(THE($entity))} is already fully loaded. # CartridgeAmmo gun-cartridge-spent = It is [color=red]spent[/color]. @@ -32,4 +35,4 @@ gun-revolver-full = Revolver full gun-revolver-insert = Inserted gun-revolver-spin = Spin revolver gun-revolver-spun = Spun -gun-speedloader-empty = Speedloader empty \ No newline at end of file +gun-speedloader-empty = Speedloader empty diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimaterial.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimaterial.yml index ce891be9a9..a9661ba943 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimaterial.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/antimaterial.yml @@ -4,6 +4,7 @@ name: ammunition box (.60 anti-material) components: - type: BallisticAmmoProvider + mayTransfer: true capacity: 30 proto: CartridgeAntiMaterial - type: Sprite diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml index fc59ad9279..4fff28544c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/caseless_rifle.yml @@ -5,6 +5,7 @@ name: ammunition box (.25 caseless) components: - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeCaselessRifle diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml index d2581f4dde..ee2376172c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml @@ -5,6 +5,7 @@ name: ammunition box (.30 rifle) components: - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeLightRifle diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml index 6aa7e976b8..5581c7aba0 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/magnum.yml @@ -4,6 +4,7 @@ id: BaseMagazineBoxMagnum components: - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeMagnum diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml index 0a9829871d..bcba37d0c7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/pistol.yml @@ -5,6 +5,7 @@ name: ammunition box (.35 auto) components: - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgePistol diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml index dcaf9d4142..52c0abe583 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/rifle.yml @@ -4,6 +4,7 @@ id: BaseMagazineBoxRifle components: - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeRifle diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/toy.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/toy.yml index 2ae06a84be..762352b173 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/toy.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/toy.yml @@ -5,6 +5,7 @@ name: foamdart box components: - type: BallisticAmmoProvider + mayTransfer: true capacity: 30 - type: Sprite netsync: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml index b66bff9f2c..ad92333983 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/caseless_rifle.yml @@ -8,6 +8,7 @@ tags: - MagazineCaselessRifle - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeCaselessRifle diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml index dc05298c84..f9ef981bf0 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/heavy_rifle.yml @@ -10,6 +10,7 @@ - type: Item size: 10 - type: BallisticAmmoProvider + mayTransfer: true capacity: 100 - type: ContainerContainer containers: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml index 11c5d26b69..a200c6bfc3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/light_rifle.yml @@ -9,6 +9,7 @@ tags: - MagazineLightRifle - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeLightRifle diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml index 3d33e09173..e01de5879a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/magnum.yml @@ -8,6 +8,7 @@ tags: - MagazineMagnum - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeMagnum @@ -41,6 +42,7 @@ tags: - MagazineMagnumSubMachineGun - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeMagnum diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml index 003200b72d..f43c13f21b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/pistol.yml @@ -8,6 +8,7 @@ tags: - MagazinePistol - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgePistol @@ -41,6 +42,7 @@ tags: - MagazinePistolHighCapacity - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgePistol @@ -74,6 +76,7 @@ tags: - MagazinePistolSubMachineGun - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgePistol @@ -106,6 +109,7 @@ tags: - MagazinePistolSubMachineGunTopMounted - type: BallisticAmmoProvider + mayTransfer: true proto: CartridgePistol whitelist: tags: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml index f81296055d..f476a6db55 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/rifle.yml @@ -11,6 +11,7 @@ - type: Item size: 5 - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - CartridgeRifle diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml index ee20abb7ed..62d206acc5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Magazines/shotgun.yml @@ -8,6 +8,7 @@ tags: - MagazineShotgun - type: BallisticAmmoProvider + mayTransfer: true whitelist: tags: - ShellShotgun