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