diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs
index d06f8b1658..2459d1d29e 100644
--- a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs
+++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs
@@ -2,7 +2,6 @@ using System.Numerics;
using Content.Client.Items;
using Content.Client.Weapons.Ranged.Components;
using Content.Shared.Camera;
-using Content.Shared.Input;
using Content.Shared.Spawners.Components;
using Content.Shared.Weapons.Ranged;
using Content.Shared.Weapons.Ranged.Components;
diff --git a/Content.Server/Explosion/Components/TriggerWhenEmptyComponent.cs b/Content.Server/Explosion/Components/TriggerWhenEmptyComponent.cs
new file mode 100644
index 0000000000..71edd42646
--- /dev/null
+++ b/Content.Server/Explosion/Components/TriggerWhenEmptyComponent.cs
@@ -0,0 +1,9 @@
+namespace Content.Server.Explosion.Components;
+
+///
+/// Triggers a gun when attempting to shoot while it's empty
+///
+[RegisterComponent]
+public sealed class TriggerWhenEmptyComponent : Component
+{
+}
diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs
index eb2d3b6a0d..ee47c016e5 100644
--- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs
+++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs
@@ -22,7 +22,7 @@ using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
-using Robust.Shared.Player;
+using Content.Shared.Weapons.Ranged.Events;
namespace Content.Server.Explosion.EntitySystems
{
@@ -77,6 +77,7 @@ namespace Content.Server.Explosion.EntitySystems
SubscribeLocalEvent(OnImplantTrigger);
SubscribeLocalEvent(OnStepTriggered);
SubscribeLocalEvent(OnSlipTriggered);
+ SubscribeLocalEvent(OnEmptyTriggered);
SubscribeLocalEvent(OnSpawnTrigger);
SubscribeLocalEvent(HandleDeleteTrigger);
@@ -186,6 +187,11 @@ namespace Content.Server.Explosion.EntitySystems
Trigger(uid, args.Slipped);
}
+ private void OnEmptyTriggered(EntityUid uid, TriggerWhenEmptyComponent component, ref OnEmptyGunShotEvent args)
+ {
+ Trigger(uid, args.EmptyGun);
+ }
+
public bool Trigger(EntityUid trigger, EntityUid? user = null)
{
var triggerEvent = new TriggerEvent(trigger, user);
diff --git a/Content.Shared/Weapons/Ranged/Events/OnEmptyGunShotEvent.cs b/Content.Shared/Weapons/Ranged/Events/OnEmptyGunShotEvent.cs
new file mode 100644
index 0000000000..efae42952b
--- /dev/null
+++ b/Content.Shared/Weapons/Ranged/Events/OnEmptyGunShotEvent.cs
@@ -0,0 +1,7 @@
+namespace Content.Shared.Weapons.Ranged.Events;
+
+///
+/// Raised directed on the gun when trying to fire it while it's out of ammo
+///
+[ByRefEvent]
+public record struct OnEmptyGunShotEvent(EntityUid EmptyGun);
diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs
index 29913cd73d..296c260a28 100644
--- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs
+++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs
@@ -130,15 +130,14 @@ public abstract partial class SharedGunSystem
private void OnBallisticVerb(EntityUid uid, BallisticAmmoProviderComponent component, GetVerbsEvent args)
{
- if (!args.CanAccess || !args.CanInteract || args.Hands == null)
+ if (!args.CanAccess || !args.CanInteract || args.Hands == null || !component.Cycleable)
return;
- if (component.Cycleable == true)
- args.Verbs.Add(new Verb()
- {
- Text = Loc.GetString("gun-ballistic-cycle"),
- Disabled = GetBallisticShots(component) == 0,
- Act = () => ManualCycle(uid, component, Transform(uid).MapPosition, args.User),
- });
+ args.Verbs.Add(new Verb()
+ {
+ Text = Loc.GetString("gun-ballistic-cycle"),
+ Disabled = GetBallisticShots(component) == 0,
+ Act = () => ManualCycle(uid, component, Transform(uid).MapPosition, args.User),
+ });
}
private void OnBallisticExamine(EntityUid uid, BallisticAmmoProviderComponent component, ExaminedEvent args)
@@ -151,6 +150,9 @@ public abstract partial class SharedGunSystem
private void ManualCycle(EntityUid uid, BallisticAmmoProviderComponent component, MapCoordinates coordinates, EntityUid? user = null, GunComponent? gunComp = null)
{
+ if (!component.Cycleable)
+ return;
+
// Reset shotting for cycling
if (Resolve(uid, ref gunComp, false) &&
gunComp is { FireRate: > 0f } &&
diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
index 68b64d43dc..8866fcf55a 100644
--- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
+++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
@@ -7,7 +7,6 @@ using Content.Shared.Damage;
using Content.Shared.Examine;
using Content.Shared.Gravity;
using Content.Shared.Hands.Components;
-using Content.Shared.Interaction.Events;
using Content.Shared.Popups;
using Content.Shared.Projectiles;
using Content.Shared.Tag;
@@ -304,6 +303,10 @@ public abstract partial class SharedGunSystem : EntitySystem
if (ev.Ammo.Count <= 0)
{
+ // triggers effects on the gun if it's empty
+ var emptyGunShotEvent = new OnEmptyGunShotEvent();
+ RaiseLocalEvent(gunUid, ref emptyGunShotEvent);
+
// Play empty gun sounds if relevant
// If they're firing an existing clip then don't play anything.
if (shots > 0)
diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl
index 1fc1462b70..1812097dda 100644
--- a/Resources/Locale/en-US/store/uplink-catalog.ftl
+++ b/Resources/Locale/en-US/store/uplink-catalog.ftl
@@ -212,7 +212,7 @@ uplink-proximity-mine-name = Proximity Mine
uplink-proximity-mine-desc = A mine disguised as a wet floor sign.
uplink-disposable-turret-name = Disposable Ballistic Turret
-uplink-disposable-turret-desc = Looks and functions like a normal electrical toolbox. Upon hitting the toolbox it will transform into a ballistic turret, theoretically shooting at anyone except members of the syndicate.
+uplink-disposable-turret-desc = Looks and functions like a normal electrical toolbox. Upon hitting the toolbox it will transform into a ballistic turret, theoretically shooting at anyone except members of the syndicate. Can be turned back into a toolbox using a screwdriver and repaired using a wrench.
# Armor
uplink-chameleon-name = Chameleon Kit
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml
index c620fb6956..9bdee06750 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml
@@ -143,14 +143,7 @@
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- - !type:PlaySoundBehavior
- sound:
- path: /Audio/Effects/metalbreak.ogg
- - !type:SpawnEntitiesBehavior
- spawn:
- WeaponTurretSyndicateBroken:
- min: 1
- max: 1
+ - !type:TriggerBehavior
- type: Gun
fireRate: 2
selectedMode: FullAuto
@@ -168,6 +161,14 @@
- type: Repairable
qualityNeeded: "Anchoring"
doAfterDelay: 3
+ - type: TriggerWhenEmpty
+ - type: ExplodeOnTrigger
+ - type: Explosive
+ explosionType: Default
+ maxIntensity: 10
+ intensitySlope: 1.5
+ totalIntensity: 30
+ canCreateVacuum: false
- type: entity
parent: BaseWeaponTurret