diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs
index bbac7acd12..5f8ab0ecb6 100644
--- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs
+++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs
@@ -10,6 +10,7 @@ using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Effects;
+using Content.Shared.FixedPoint;
using Content.Shared.Interaction.Components;
using Content.Shared.Projectiles;
using Content.Shared.Weapons.Melee;
@@ -132,6 +133,27 @@ public sealed partial class GunSystem : SharedGunSystem
case CartridgeAmmoComponent cartridge:
if (!cartridge.Spent)
{
+ if (gun.CompatibleAmmo != null &&
+ !gun.CompatibleAmmo.Exists(ammoAllowed => ammoAllowed.Equals(cartridge.Prototype))
+ && user != null)
+ {
+ if (gun.DamageOnWrongAmmo != null)
+ Damageable.TryChangeDamage(user, gun.DamageOnWrongAmmo, origin: user);
+ _stun.TryParalyze(user.Value, TimeSpan.FromSeconds(3f), true);
+
+ Audio.PlayPvs(new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/bang.ogg"), gunUid);
+
+ PopupSystem.PopupEntity(Loc.GetString("gun-component-wrong-ammo"), user.Value);
+ _adminLogger.Add(LogType.EntityDelete, LogImpact.Medium, $"Shot wrong ammo by {ToPrettyString(user.Value)} deleted {ToPrettyString(gunUid)}");
+ userImpulse = false;
+
+ SetCartridgeSpent(ent!.Value, cartridge, true);
+ MuzzleFlash(gunUid, cartridge, user);
+ Del(gunUid);
+ if (cartridge.DeleteOnSpawn)
+ Del(ent.Value);
+ return;
+ }
if (cartridge.Count > 1)
{
var angles = LinearSpread(mapAngle - cartridge.Spread / 2,
diff --git a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs
index fb52870df8..350dd85d69 100644
--- a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs
+++ b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs
@@ -1,7 +1,11 @@
+using Content.Shared.Damage;
+using Content.Shared.Tag;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
+using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Weapons.Ranged.Components;
@@ -110,6 +114,18 @@ public partial class GunComponent : Component
[ViewVariables(VVAccess.ReadWrite), DataField("resetOnHandSelected")]
public bool ResetOnHandSelected = true;
+ ///
+ /// Type of ammo the gun can work with
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("compatibleAmmo")]
+ public List>? CompatibleAmmo;
+
+ ///
+ /// Damage the gun deals when used with wrong ammo
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("damageOnWrongAmmo")]
+ public DamageSpecifier? DamageOnWrongAmmo = null;
+
///
/// How fast the projectile moves.
///
diff --git a/Resources/Locale/en-US/weapons/ranged/gun.ftl b/Resources/Locale/en-US/weapons/ranged/gun.ftl
index fe60f3eed1..3fbf5f77e7 100644
--- a/Resources/Locale/en-US/weapons/ranged/gun.ftl
+++ b/Resources/Locale/en-US/weapons/ranged/gun.ftl
@@ -6,6 +6,7 @@ gun-selected-mode = Selected {$mode}
gun-disabled = You can't use guns!
gun-clumsy = The gun blows up in your face!
gun-set-fire-mode = Set to {$mode}
+gun-component-wrong-ammo = Wrong ammo!
# SelectiveFire
gun-SemiAuto = semi-auto
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml
index 21780fefb6..92a88111f5 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/shotgun.yml
@@ -148,4 +148,4 @@
spread: 45 #deadly if you can get up close... otherwise, good luck doing any kind of real damage
proto: PelletShotgunImprovised
- type: SpentAmmoVisuals
- state: "improvised"
\ No newline at end of file
+ state: "improvised"
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml
index 887295b4b1..5f19ac03d0 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml
@@ -75,7 +75,7 @@
id: PelletShotgunImprovised
name: improvised pellet
noSpawn: true
- parent: BaseBullet
+ parent: BaseBullet
components:
- type: Sprite
sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi
@@ -135,6 +135,9 @@
- ItemMask
restitution: 0.3
friction: 0.2
+ - type: Tag
+ tags:
+ - PelletShotgunFlare
- type: Sprite
sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi
state: buckshot-flare
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml
index cfcc0a01cd..810a36105b 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/flare_gun.yml
@@ -17,8 +17,13 @@
selectedMode: SemiAuto
availableModes:
- SemiAuto
+ compatibleAmmo:
+ - PelletShotgunFlare
soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/flaregun.ogg
+ damageOnWrongAmmo:
+ types:
+ Blunt: 6.0
- type: BallisticAmmoProvider
whitelist:
tags:
diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml
index dfdaa85789..4546c4ac48 100644
--- a/Resources/Prototypes/tags.yml
+++ b/Resources/Prototypes/tags.yml
@@ -930,6 +930,9 @@
- type: Tag
id: ShellShotgun
+- type: Tag
+ id: PelletShotgunFlare
+
- type: Tag
id: Shiv