diff --git a/Content.Server/Explosion/Components/OnTrigger/SmokeOnTriggerComponent.cs b/Content.Server/Explosion/Components/OnTrigger/SmokeOnTriggerComponent.cs
new file mode 100644
index 0000000000..d71e93495a
--- /dev/null
+++ b/Content.Server/Explosion/Components/OnTrigger/SmokeOnTriggerComponent.cs
@@ -0,0 +1,41 @@
+using Content.Server.Explosion.EntitySystems;
+using Content.Shared.Chemistry.Components;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Explosion.Components;
+
+///
+/// Creates a smoke cloud when triggered, with an optional solution to include in it.
+/// No sound is played incase a grenade is stealthy, use if you want a sound.
+///
+[RegisterComponent, Access(typeof(SmokeOnTriggerSystem))]
+public sealed partial class SmokeOnTriggerComponent : Component
+{
+ ///
+ /// How long the smoke stays for, after it has spread.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float Duration = 10;
+
+ ///
+ /// How much the smoke will spread.
+ ///
+ [DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
+ public int SpreadAmount;
+
+ ///
+ /// Smoke entity to spawn.
+ /// Defaults to smoke but you can use foam if you want.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public ProtoId SmokePrototype = "Smoke";
+
+ ///
+ /// Solution to add to each smoke cloud.
+ ///
+ ///
+ /// When using repeating trigger this essentially gets multiplied so dont do anything crazy like omnizine or lexorin.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public Solution Solution = new();
+}
diff --git a/Content.Server/Explosion/EntitySystems/SmokeOnTriggerSystem.cs b/Content.Server/Explosion/EntitySystems/SmokeOnTriggerSystem.cs
new file mode 100644
index 0000000000..3ddb411d40
--- /dev/null
+++ b/Content.Server/Explosion/EntitySystems/SmokeOnTriggerSystem.cs
@@ -0,0 +1,46 @@
+using Content.Server.Explosion.Components;
+using Content.Server.Fluids.EntitySystems;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Coordinates.Helpers;
+using Content.Shared.Maps;
+using Robust.Shared.Map;
+
+namespace Content.Server.Explosion.EntitySystems;
+
+///
+/// Handles creating smoke when is triggered.
+///
+public sealed class SmokeOnTriggerSystem : EntitySystem
+{
+ [Dependency] private readonly IMapManager _mapMan = default!;
+ [Dependency] private readonly SmokeSystem _smoke = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnTrigger);
+ }
+
+ private void OnTrigger(EntityUid uid, SmokeOnTriggerComponent comp, TriggerEvent args)
+ {
+ var xform = Transform(uid);
+ if (!_mapMan.TryFindGridAt(xform.MapPosition, out _, out var grid) ||
+ !grid.TryGetTileRef(xform.Coordinates, out var tileRef) ||
+ tileRef.Tile.IsSpace())
+ {
+ return;
+ }
+
+ var coords = grid.MapToGrid(xform.MapPosition);
+ var ent = Spawn(comp.SmokePrototype, coords.SnapToGrid());
+ if (!TryComp(ent, out var smoke))
+ {
+ Logger.Error($"Smoke prototype {comp.SmokePrototype} was missing SmokeComponent");
+ Del(ent);
+ return;
+ }
+
+ _smoke.StartSmoke(ent, comp.Solution, comp.Duration, comp.SpreadAmount, smoke);
+ }
+}
diff --git a/Resources/Locale/en-US/reagents/meta/narcotics.ftl b/Resources/Locale/en-US/reagents/meta/narcotics.ftl
index 7e5e41037e..7eed44835c 100644
--- a/Resources/Locale/en-US/reagents/meta/narcotics.ftl
+++ b/Resources/Locale/en-US/reagents/meta/narcotics.ftl
@@ -36,3 +36,6 @@ reagent-desc-mute-toxin = A thick chemical that coats the vocal cords, making th
reagent-name-norepinephric-acid = norepinephric acid
reagent-desc-norepinephric-acid = A smooth chemical that blocks the optical receptors, rendering the user blind during metabolization.
+
+reagent-name-tear-gas = tear gas
+reagent-desc-tear-gas = A chemical that causes severe irritation and crying, commonly used in riot control.
diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl
index 9725024c9c..a016d791d7 100644
--- a/Resources/Locale/en-US/store/uplink-catalog.ftl
+++ b/Resources/Locale/en-US/store/uplink-catalog.ftl
@@ -33,6 +33,9 @@ uplink-explosive-grenade-desc = A simplistic grenade with a three-and-a-half-sec
uplink-flash-grenade-name = Flashbang
uplink-flash-grenade-desc = A standard-issue flashbang, capable of blinding and slowing down anyone without proper protection. This, of course, includes you; make sure you're properly equipped before using it.
+uplink-smoke-grenade-name = Smoke Grenade
+uplink-smoke-grenade-desc = A grenade that releases a huge cloud of smoke, perfect for killing someone in the shadows or making a sneaky getaway.
+
uplink-mini-bomb-name = Minibomb
uplink-mini-bomb-desc = A low-yield, high-impact precision sabotage explosive with a five-second long fuse. Perfect for quickly destroying a machine, dead body, or whatever else needs to go.
diff --git a/Resources/Prototypes/Catalog/Fills/Items/belt.yml b/Resources/Prototypes/Catalog/Fills/Items/belt.yml
index ec683b8523..8f66c870fc 100644
--- a/Resources/Prototypes/Catalog/Fills/Items/belt.yml
+++ b/Resources/Prototypes/Catalog/Fills/Items/belt.yml
@@ -49,7 +49,7 @@
- type: StorageFill
contents:
- id: GrenadeFlashBang
- - id: GrenadeFlashBang
+ - id: TearGasGrenade
- id: Stunbaton
- id: Handcuffs
- id: Handcuffs
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml
index cd319c3b42..75f0cad84b 100644
--- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml
+++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml
@@ -3,6 +3,7 @@
startingInventory:
Handcuffs: 8
GrenadeFlashBang: 4
+ TearGasGrenade: 4
ClusterBangFull: 2
GrenadeStinger: 4
Flash: 5
diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml
index dc668fd6a2..de4789ae79 100644
--- a/Resources/Prototypes/Catalog/uplink_catalog.yml
+++ b/Resources/Prototypes/Catalog/uplink_catalog.yml
@@ -138,6 +138,16 @@
categories:
- UplinkExplosives
+- type: listing
+ id: UplinkSmokeGrenade
+ name: uplink-smoke-grenade-name
+ description: uplink-smoke-grenade-desc
+ productEntity: SmokeGrenade
+ cost:
+ Telecrystal: 1
+ categories:
+ - UplinkExplosives
+
- type: listing
id: UplinkSyndieMiniBomb
name: uplink-mini-bomb-name
diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml
index 79b726a6a9..d0ff683cdc 100644
--- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml
+++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml
@@ -175,6 +175,7 @@
components:
- Stunbaton
- FlashOnTrigger
+ - SmokeOnTrigger
- Flash
- Handcuff
- RangedMagazine
@@ -189,6 +190,10 @@
whitelist:
components:
- Stunbaton
+ tear_gas_grenade:
+ whitelist:
+ components:
+ - SmokeOnTrigger
sprite: Clothing/Belt/belt_overlay.rsi
- type: Appearance
@@ -373,6 +378,7 @@
components:
- Stunbaton
- FlashOnTrigger
+ - SmokeOnTrigger
- Flash
- Handcuff
- type: ItemMapper
@@ -385,6 +391,10 @@
whitelist:
components:
- Stunbaton
+ tear_gas_grenade:
+ whitelist:
+ components:
+ - SmokeOnTrigger
sprite: Clothing/Belt/belt_overlay.rsi
- type: Appearance
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml
index 7f5124a5eb..a3727351ec 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml
@@ -345,3 +345,34 @@
- type: TimerTriggerVisuals
primingSound:
path: /Audio/Effects/hallelujah.ogg
+
+- type: entity
+ parent: GrenadeBase
+ id: SmokeGrenade
+ name: smoke grenade
+ description: A tactical grenade that releases a large, long-lasting cloud of smoke when used.
+ components:
+ - type: Sprite
+ sprite: Objects/Weapons/Grenades/smoke.rsi
+ - type: SmokeOnTrigger
+ duration: 30
+ spreadAmount: 50
+ - type: SoundOnTrigger
+ sound: /Audio/Effects/smoke.ogg
+ - type: DeleteOnTrigger
+
+- type: entity
+ parent: SmokeGrenade
+ id: TearGasGrenade
+ name: tear gas grenade
+ description: A riot control tear gas grenade. Causes irritation, pain and makes you cry your eyes out.
+ components:
+ - type: Sprite
+ sprite: Objects/Weapons/Grenades/tear_gas.rsi
+ - type: SmokeOnTrigger
+ duration: 10
+ spreadAmount: 30
+ solution:
+ reagents:
+ - ReagentId: TearGas
+ Quantity: 50
diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml
index 2678f4cd71..d05cc29ab0 100644
--- a/Resources/Prototypes/Reagents/narcotics.yml
+++ b/Resources/Prototypes/Reagents/narcotics.yml
@@ -350,3 +350,49 @@
conditions:
- !type:ReagentThreshold
min: 20
+
+- type: reagent
+ id: TearGas
+ name: reagent-name-tear-gas
+ group: Narcotics
+ desc: reagent-desc-tear-gas
+ physicalDesc: reagent-physical-desc-milky
+ flavor: salty
+ color: "#96a8b5"
+ boilingPoint: 255.0
+ meltingPoint: 36.0
+ metabolisms:
+ Narcotic:
+ effects:
+ - !type:PopupMessage
+ type: Local
+ probability: 0.08
+ messages:
+ - generic-reagent-effect-burning-eyes
+ - generic-reagent-effect-burning-eyes-a-bit
+ - generic-reagent-effect-tearing-up
+ - norepinephricacid-effect-eyelids
+ - norepinephricacid-effect-eyes-itch
+ - norepinephricacid-effect-vision-fade
+ - norepinephricacid-effect-vision-fail
+ - !type:PopupMessage
+ type: Local
+ visualType: MediumCaution
+ probability: 0.03
+ messages:
+ - norepinephricacid-effect-eye-disconnect
+ - norepinephricacid-effect-eye-pain
+ - norepinephricacid-effect-darkness
+ - norepinephricacid-effect-blindness
+ conditions:
+ - !type:ReagentThreshold
+ min: 15
+ - !type:Emote
+ emote: Scream
+ probability: 0.08
+ - !type:GenericStatusEffect
+ key: TemporaryBlindness
+ component: TemporaryBlindness
+ conditions:
+ - !type:ReagentThreshold
+ min: 20
diff --git a/Resources/Textures/Clothing/Belt/belt_overlay.rsi/meta.json b/Resources/Textures/Clothing/Belt/belt_overlay.rsi/meta.json
index b8464e4243..18b282d9df 100644
--- a/Resources/Textures/Clothing/Belt/belt_overlay.rsi/meta.json
+++ b/Resources/Textures/Clothing/Belt/belt_overlay.rsi/meta.json
@@ -97,6 +97,9 @@
{
"name": "stunbaton"
},
+ {
+ "name": "tear_gas_grenade"
+ },
{
"name": "wrench"
},
diff --git a/Resources/Textures/Clothing/Belt/belt_overlay.rsi/tear_gas_grenade.png b/Resources/Textures/Clothing/Belt/belt_overlay.rsi/tear_gas_grenade.png
new file mode 100644
index 0000000000..3558e00f41
Binary files /dev/null and b/Resources/Textures/Clothing/Belt/belt_overlay.rsi/tear_gas_grenade.png differ
diff --git a/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/icon.png b/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/icon.png
new file mode 100644
index 0000000000..c6365e6404
Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/meta.json b/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/meta.json
new file mode 100644
index 0000000000..525248ce94
--- /dev/null
+++ b/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/meta.json
@@ -0,0 +1,17 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/blob/524270a5bcc1e0ea844b98c5a204986cec9721ac/icons/obj/weapons/grenade.dmi",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "primed"
+ }
+ ]
+}
diff --git a/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/primed.png b/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/primed.png
new file mode 100644
index 0000000000..ef7ca55e19
Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/smoke.rsi/primed.png differ
diff --git a/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/icon.png b/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/icon.png
new file mode 100644
index 0000000000..e3980eaf10
Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/meta.json b/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/meta.json
new file mode 100644
index 0000000000..60b919588c
--- /dev/null
+++ b/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/meta.json
@@ -0,0 +1,17 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/blob/524270a5bcc1e0ea844b98c5a204986cec9721ac/icons/obj/weapons/grenade.dmi and modified by deltanedas (github)",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "primed"
+ }
+ ]
+}
diff --git a/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/primed.png b/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/primed.png
new file mode 100644
index 0000000000..ca49e02fe3
Binary files /dev/null and b/Resources/Textures/Objects/Weapons/Grenades/tear_gas.rsi/primed.png differ