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