The effects of flashbangs become less severe the further away you are from the flashbang when it detonates. (#92294)

## About The Pull Request

<img width="691" height="207" alt="flashbang agony zone"
src="https://github.com/user-attachments/assets/a4cc5fdb-19dc-4849-8c4a-2db1ac0fe212"
/>

In this handy chart, you can now see the impact of the flashbang based
on location.

**Dead Center:** While our Powergaming RD for Testing Pruposes is immune
to this, being on this tile when the flashbang goes off still hard stuns
you for a really long time even if you have ear protection. The bang
doesn't do anything in a vacuum.

**Pointblank:** This works as it does live, going through protections.
Though the bang doesn't work in a vacuum.

**Sweetspot:** This works as it does live, stunning and knocking you
down, but not if you're protected from the flash and the bang. This is
currently set to 3 tiles.

**Stagger Zone:** If you're vulnerable to the bang, you are staggered
and drop your items, rather than stunned and knocked down. If you're
vulnerable to the flash, you are dizzied and drop your items, rather
than stunned and knocked down.

**Safe Zone:** Basically this is outside of the flashbang's effective
range. The effective range is the same as live (7 tiles).

## Why It's Good For The Game

Flashbangs are a pretty easy room wide attack that acts as a one of our
more extreme gear checks. You either are entirely safe from this, or you
probably are going to eat shit to something just tossed into your line
of sight. Either you need to be able to disappear from the room
immediately, or the flashbang gets you.

Without nullifying the room attacking effect too severely, as well as
the mass disarming capabilities of the flashbang, this at least helps
provide some ways to counteract flashbangs without absolutely needing to
have the protections. You can play around the stagger and dizziness more
easily than you can the stuns.

The vacuum stuff is mostly because being hit by a flashbang's bang in a
vacuum is a bit absurd. The flash still works, however.

## Changelog
🆑
balance: The effects of flashbangs become less severe the further away
you are from the flashbang.
balance: The bang effect of flashbangs cannot affect you in a vacuum.
The flash still functions in a vacuum.
/🆑

---------

Co-authored-by: Aki Ito <11748095+ExcessiveUseOfCobblestone@users.noreply.github.com>
This commit is contained in:
necromanceranne
2025-08-14 22:33:08 +10:00
committed by GitHub
parent a27d91c5b9
commit 77375b66eb
2 changed files with 60 additions and 30 deletions
+40 -11
View File
@@ -5,7 +5,12 @@
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
possible_fuse_time = list("3", "4", "5")
var/flashbang_range = 7 //how many tiles away the mob will be stunned.
//how many tiles away the mob will be affected by the flashbang.
var/flashbang_range = 7
//The devision for the sweetspot culations. if set to 1, the sweetspot is ostensibly the flashbang range.
var/sweetspot_divider = 3
//The light emitted by this flashbang to indicate the sweetspot.
var/flashbang_light = LIGHT_COLOR_INTENSE_RED
/obj/item/grenade/flashbang/apply_grenade_fantasy_bonuses(quality)
flashbang_range = modify_fantasy_variable("flashbang_range", flashbang_range, quality)
@@ -13,6 +18,14 @@
/obj/item/grenade/flashbang/remove_grenade_fantasy_bonuses(quality)
flashbang_range = reset_fantasy_variable("flashbang_range", flashbang_range)
/obj/item/grenade/flashbang/arm_grenade(mob/user, delayoverride, msg = TRUE, volume = 60)
. = ..()
if(!.)
return
var/sweetspot_range = clamp(CEILING(flashbang_range/sweetspot_divider, 1), 0, flashbang_range)
set_light(sweetspot_range, sweetspot_range, flashbang_light)
/obj/item/grenade/flashbang/detonate(mob/living/lanced_by)
. = ..()
if(!.)
@@ -34,22 +47,38 @@
return
living_mob.show_message(span_warning("BANG"), MSG_AUDIBLE)
var/distance = max(0, get_dist(get_turf(src), turf))
var/sweetspot_range = clamp(CEILING(flashbang_range/sweetspot_divider, 1), 0, flashbang_range)
//Flash
if(living_mob.flash_act(affect_silicon = 1))
living_mob.Paralyze(max(20/max(1, distance), 5))
living_mob.Knockdown(max(200/max(1, distance), 60))
var/attempt_flash = living_mob.flash_act(affect_silicon = 1)
if(attempt_flash == FLASH_COMPLETED)
if(distance <= sweetspot_range || issilicon(living_mob))
living_mob.Paralyze(max(20/max(1, distance), 5))
living_mob.Knockdown(max(200/max(1, distance), 60))
else
living_mob.adjust_dizzy_up_to(max(200/max(1, distance), 5), 20 SECONDS)
living_mob.dropItemToGround(living_mob.get_active_held_item())
living_mob.dropItemToGround(living_mob.get_inactive_held_item())
//Bang
if(!distance || loc == living_mob || loc == living_mob.loc)
living_mob.Paralyze(20)
living_mob.Knockdown(200)
living_mob.soundbang_act(1, 200, 10, 15)
else
if(distance <= 1) // Adds more stun as to not prime n' pull (#45381)
living_mob.Paralyze(5)
living_mob.Knockdown(30)
living_mob.soundbang_act(2, 20 SECONDS, 10, 15)
return
if(distance <= 1) // Adds more stun as to not prime n' pull (#45381)
living_mob.soundbang_act(2, 3 SECONDS, 5)
return
if(distance <= sweetspot_range)
living_mob.soundbang_act(1, max(200 / max(1, distance), 60), rand(0, 5))
return
if(!living_mob.soundbang_act(1, 0, rand(0, 2)))
return
living_mob.adjust_staggered_up_to(max(200/max(1, distance), 5), 10 SECONDS)
living_mob.dropItemToGround(living_mob.get_active_held_item())
living_mob.dropItemToGround(living_mob.get_inactive_held_item())
/obj/item/grenade/stingbang
name = "stingbang"
@@ -508,28 +508,29 @@
var/ear_safety = get_ear_protection()
var/obj/item/organ/ears/ears = get_organ_slot(ORGAN_SLOT_EARS)
var/effect_amount = intensity - ear_safety
if(effect_amount > 0)
if(stun_pwr)
Paralyze((stun_pwr*effect_amount)*0.1)
Knockdown(stun_pwr*effect_amount)
if(effect_amount <= 0)
return FALSE
if(ears && (deafen_pwr || damage_pwr))
var/ear_damage = damage_pwr * effect_amount
var/deaf = deafen_pwr * effect_amount
ears.adjustEarDamage(ear_damage,deaf)
if(stun_pwr)
Paralyze((stun_pwr*effect_amount)*0.1)
Knockdown(stun_pwr*effect_amount)
if(ears.damage >= 15)
to_chat(src, span_warning("Your ears start to ring badly!"))
if(prob(ears.damage - 5))
to_chat(src, span_userdanger("You can't hear anything!"))
// Makes you deaf, enough that you need a proper source of healing, it won't self heal
// you need earmuffs, inacusiate, or replacement
ears.set_organ_damage(ears.maxHealth)
else if(ears.damage >= 5)
to_chat(src, span_warning("Your ears start to ring!"))
SEND_SOUND(src, sound('sound/items/weapons/flash_ring.ogg',0,1,0,250))
return effect_amount //how soundbanged we are
if(ears && (deafen_pwr || damage_pwr))
var/ear_damage = damage_pwr * effect_amount
var/deaf = deafen_pwr * effect_amount
ears.adjustEarDamage(ear_damage,deaf)
. = effect_amount //how soundbanged we are
SEND_SOUND(src, sound('sound/items/weapons/flash_ring.ogg',0,1,0,250))
if(ears.damage < 5)
return
if(ears.damage >= 15 && prob(ears.damage - 5))
to_chat(src, span_userdanger("You can't hear anything!"))
// Makes you deaf, enough that you need a proper source of healing, it won't self heal
// you need earmuffs, inacusiate, or replacement
ears.set_organ_damage(ears.maxHealth)
to_chat(src, span_warning("Your ears start to ring[ears.damage >= 15 ? " badly!":"!"]"))
/mob/living/carbon/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
if(damage_type != BRUTE && damage_type != BURN)