diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm
index ffcb2eae1d7..88cc3971347 100644
--- a/code/__defines/mobs.dm
+++ b/code/__defines/mobs.dm
@@ -304,6 +304,11 @@
#define FLASH_PROTECTION_MODERATE 1
#define FLASH_PROTECTION_MAJOR 2
+#define EAR_PROTECTION_REDUCED -1
+#define EAR_PROTECTION_NONE 0
+#define EAR_PROTECTION_MODERATE 1
+#define EAR_PROTECTION_MAJOR 2
+
#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6)
#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3)
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index 105c7be2970..6fc5e6b9bdc 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -342,7 +342,7 @@
var/list/victims = list()
for(var/mob/living/carbon/human/T in hearers(4, src) - src)
- if(T.get_hearing_protection())
+ if(T.get_hearing_protection() >= EAR_PROTECTION_MAJOR)
continue
if(!vampire_can_affect_target(T, 0))
continue
diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm
index 8132a15a6b0..bce085a6c1c 100644
--- a/code/game/machinery/jukebox.dm
+++ b/code/game/machinery/jukebox.dm
@@ -90,7 +90,7 @@ datum/track/New(var/title_name, var/audio)
for(var/mob/living/carbon/M in ohearers(6, src))
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.get_hearing_protection())
+ if(H.get_hearing_protection() >= EAR_PROTECTION_MAJOR)
continue
M.sleeping = 0
M.stuttering += 20
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 0437c70b7b2..3b832cde59b 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -92,6 +92,11 @@
if(!L || !user || !clumsy_check(user) || !cooldown())
return
+ if(L == user)
+ if(user.a_intent == I_HURT)
+ attack_self(user)
+ return
+
L.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])")
user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [L.name] ([L.ckey])")
msg_admin_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [L.name] ([L.ckey]) (JMP)",ckey=key_name(user),ckey_target=key_name(L))
@@ -118,17 +123,14 @@
else
user.visible_message(SPAN_NOTICE("[user] fails to blind [L] with \the [src]."))
-/obj/item/device/flash/attack_hand(mob/living/carbon/user)
- if(!user || loc != user || user.a_intent != I_HURT)
- return ..()
-
- attack_self(user)
-
/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
// AOE flash
if(!user || !clumsy_check(user)|| !cooldown())
return
+ if(user.a_intent != I_HURT)
+ return
+
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(broken)
diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm
index 32827cbdf5a..bc78df7a4e4 100644
--- a/code/game/objects/items/weapons/grenades/flashbang.dm
+++ b/code/game/objects/items/weapons/grenades/flashbang.dm
@@ -27,10 +27,13 @@
if(M.flash_act(ignore_inherent = TRUE))
M.Weaken(10)
- // 1 - 9x/70 gives us an intensity of 100% at zero,
- // 87% at one turf, all the way to 10% at 7 tiles
- var/bang_intensity = 1 - (9 * get_dist(T,M) / 70)
- M.soundbang_act(bang_intensity, 3, 10, 15)
+ // 1 - 9x/70 gives us 100% at zero, 87% at 1 turf, all the way to 10% at 7
+ var/bang_intensity = 1 - (9 * get_dist(T, M) / 70)
+ M.noise_act(intensity = EAR_PROTECTION_MAJOR, damage_pwr = 10 * bang_intensity, deafen_pwr = 15 * (1 - bang_intensity))
+
+ if(M.get_hearing_sensitivity()) // we only stun if they've got sensitive ears
+ // checking for protection is handled by noise_act
+ M.noise_act(intensity = EAR_PROTECTION_MAJOR, stun_pwr = 2)
M.disable_cloaking_device()
M.update_icon()
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 9693452f89b..c7c9a11aeef 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -163,7 +163,7 @@
return ..()
/mob/living/carbon/human/playsound_get_environment(pressure_factor = 1.0)
- if(get_hearing_protection())
+ if(get_hearing_protection() >= EAR_PROTECTION_MAJOR)
return PADDED_CELL
return ..()
@@ -171,9 +171,7 @@
return 1
/mob/living/carbon/human/check_sound_equipment_volume()
- if(get_hearing_protection())
- return 0.6
- return 1
+ return 1 - (get_hearing_protection() * 0.2)
/mob/proc/playsound_to(turf/source_turf, sound/original_sound, use_random_freq, modify_environment = TRUE, use_pressure = TRUE, required_preferences = 0, required_asfx_toggles = 0)
var/sound/S = copy_sound(original_sound)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index a307f29f9f4..f282a175c5a 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -821,14 +821,14 @@
if (!ignore_inherent && species.inherent_eye_protection)
. = max(species.inherent_eye_protection, flash_protection)
else
- . = flash_protection
+ return flash_protection
- if(!flash_protection && HAS_TRAIT(src, TRAIT_ORIGIN_LIGHT_SENSITIVE))
- return species.inherent_eye_protection ? species.inherent_eye_protection - 1 : FLASH_PROTECTION_REDUCED
+ if(HAS_TRAIT(src, TRAIT_ORIGIN_LIGHT_SENSITIVE))
+ return max(. - 1, FLASH_PROTECTION_REDUCED)
/mob/living/carbon/human/flash_act(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, ignore_inherent = FALSE, type = /obj/screen/fullscreen/flash, length = 2.5 SECONDS)
if(..())
- var/obj/item/organ/E = get_eyes()
+ var/obj/item/organ/E = get_eyes(no_synthetic = !affect_silicon)
if(istype(E))
return E.flash_act(intensity, override_blindness_check, affect_silicon, ignore_inherent, type, length)
else if(intensity == get_flash_protection(ignore_inherent))
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index e55eb447e48..0bda54a4e0e 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -303,18 +303,18 @@
return species.icon_y_offset
/mob/living/carbon/human/get_hearing_protection()
- return (l_ear?.item_flags & SOUNDPROTECTION) || (r_ear?.item_flags & SOUNDPROTECTION) || (head?.item_flags & SOUNDPROTECTION)
+ . = EAR_PROTECTION_NONE
-/mob/living/carbon/human/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
- // First, increase intensity for sensitive hearing
- intensity *= (1 + 0.25 * get_hearing_sensitivity())
- if(!intensity || get_hearing_protection())
- return FALSE
+ if ((l_ear?.item_flags & SOUNDPROTECTION) || (r_ear?.item_flags & SOUNDPROTECTION) || (head?.item_flags & SOUNDPROTECTION))
+ return EAR_PROTECTION_MAJOR
- if(istype(head, /obj/item/clothing/head/helmet))
- intensity -= 0.5
- if(HAS_FLAG(mutations, HULK))
- intensity -= 0.5
+ if(istype(head, /obj/item/clothing/head/helmet) || HAS_FLAG(mutations, HULK))
+ . = EAR_PROTECTION_MODERATE
+
+ return max(EAR_PROTECTION_REDUCED, . - (get_hearing_sensitivity() / 2))
+
+/mob/living/carbon/human/noise_act(intensity = EAR_PROTECTION_MODERATE, stun_pwr = 0, damage_pwr = 0, deafen_pwr = 0)
+ intensity -= get_hearing_protection()
if(intensity <= 0)
return FALSE
@@ -325,7 +325,7 @@
if(deafen_pwr || damage_pwr)
var/ear_damage = damage_pwr * intensity
var/deaf = deafen_pwr * intensity
- adjustEarDamage(ear_damage, deaf, TRUE)
+ adjustEarDamage(rand(1, ear_damage), deaf, TRUE)
sound_to(src, sound('sound/weapons/flash_ring.ogg',0,1,0,100))
return intensity
@@ -374,7 +374,7 @@
return TRUE
return FALSE
-/mob/living/carbon/human/proc/get_hearing_sensitivity()
+/mob/living/carbon/human/get_hearing_sensitivity()
return species.hearing_sensitivity
/mob/living/carbon/human/proc/is_listening()
diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm
index 24350af0cb5..a8a43dbb7ad 100644
--- a/code/modules/mob/living/carbon/human/human_powers.dm
+++ b/code/modules/mob/living/carbon/human/human_powers.dm
@@ -632,7 +632,7 @@ mob/living/carbon/human/proc/change_monitor()
visible_message("\The [src] shrieks!")
playsound(src.loc, 'sound/species/revenant/grue_screech.ogg', 100, 1)
for (var/mob/living/carbon/human/T in hearers(4, src) - src)
- if(T.get_hearing_protection())
+ if(T.get_hearing_protection() >= EAR_PROTECTION_MAJOR)
continue
if (T.get_hearing_sensitivity() == HEARING_VERY_SENSITIVE)
earpain(2, TRUE, 1)
@@ -829,7 +829,7 @@ mob/living/carbon/human/proc/change_monitor()
var/list/victims = list()
for (var/mob/living/carbon/human/T in hearers(4, src) - src)
- if(T.get_hearing_protection())
+ if(T.get_hearing_protection() >= EAR_PROTECTION_MAJOR)
continue
if (T.get_hearing_sensitivity() == HEARING_VERY_SENSITIVE)
earpain(3, TRUE, 1)
@@ -837,7 +837,7 @@ mob/living/carbon/human/proc/change_monitor()
earpain(2, TRUE, 2)
for (var/mob/living/carbon/human/T in hearers(2, src) - src)
- if(T.get_hearing_protection())
+ if(T.get_hearing_protection() >= EAR_PROTECTION_MAJOR)
continue
to_chat(T, SPAN_DANGER("You hear an ear piercing shriek and feel your senses go dull!"))
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index fbc49c37698..960ba115549 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -1412,9 +1412,13 @@
if(ear_deaf <= 1 && (sdisabilities & DEAF) && has_hearing_aid())
setEarDamage(-1, max(ear_deaf-1, 0))
- if(get_hearing_protection()) // resting your ears make them heal faster
+ var/ear_safety = get_hearing_protection()
+
+ if(ear_safety >= EAR_PROTECTION_MAJOR) // resting your ears make them heal faster
adjustEarDamage(-0.15, 0)
setEarDamage(-1)
+ else if(ear_safety > EAR_PROTECTION_NONE)
+ adjustEarDamage(-0.10, 0)
else if(ear_damage < HEARING_DAMAGE_SLOW_HEAL) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
adjustEarDamage(-0.05, 0)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 2c80c31a31c..85f76a2207e 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -56,6 +56,9 @@
/mob/living/proc/get_hearing_protection()
return FALSE
+/mob/living/proc/get_hearing_sensitivity()
+ return FALSE
+
/mob/living/proc/aura_check(var/type)
if(!auras)
return TRUE
@@ -122,8 +125,9 @@
addtimer(CALLBACK(src, /mob/proc/clear_fullscreen, "flash", length), length)
return TRUE
-/// Called when the mob receives a loud bang
-/mob/living/proc/soundbang_act()
+/// Called when the mob hears a very loud noise!
+/// Intensity can be an EAR_PROTECTION_X define or an arbitrary/computed value between -1 and 2 (or more if you're insane)
+/mob/living/proc/noise_act(intensity = EAR_PROTECTION_MODERATE, stun_pwr = 0, damage_pwr = 0, deafen_pwr = 0)
return FALSE
/mob/living/proc/get_attack_victim(obj/item/I, mob/living/user, var/target_zone)
diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm
index b555ddfcac9..fdc4be3731d 100644
--- a/code/modules/organs/internal/eyes.dm
+++ b/code/modules/organs/internal/eyes.dm
@@ -47,15 +47,19 @@
if(burnthrough <= 0)
return
- if(burnthrough == 1)
- to_chat(owner, SPAN_WARNING("Your eyes sting a little."))
- take_damage(rand(1, 3), TRUE)
- else if(burnthrough == 2)
- to_chat(owner, SPAN_WARNING("Your eyes burn!"))
+ var/eye_name = (BP_IS_ROBOTIC(src) && robotic_name) ? robotic_name : "eyes"
+
+ if(burnthrough <= 1)
+ to_chat(owner, SPAN_WARNING("Your [eye_name] sting a little."))
+ owner.eye_blurry = max(owner.eye_blurry, 6)
+ take_damage(1, TRUE)
+ else if(burnthrough <= 2)
+ to_chat(owner, SPAN_WARNING("Your [eye_name] burn!"))
+ owner.eye_blurry = max(owner.eye_blurry, rand(6, 12))
+ take_damage(rand(2, 3), TRUE)
+ else if(burnthrough > 2)
+ to_chat(owner, SPAN_DANGER("[FONT_HUGE("Your [eye_name] burn from the intense light of the flash!")]"))
take_damage(rand(3, 5), TRUE)
- else if(burnthrough >= 3)
- to_chat(owner, SPAN_DANGER("[FONT_HUGE("Your eyes burn from the intense light of the flash!")]"))
- take_damage(rand(5, 9), TRUE)
owner.eye_blurry += rand(12, 20)
if(is_bruised() && !is_broken() && !(owner.disabilities & NEARSIGHTED))
diff --git a/html/changelogs/johnwildkins-flashfix.yml b/html/changelogs/johnwildkins-flashfix.yml
new file mode 100644
index 00000000000..e719e53159a
--- /dev/null
+++ b/html/changelogs/johnwildkins-flashfix.yml
@@ -0,0 +1,9 @@
+author: JohnWildkins
+
+delete-after: True
+
+changes:
+ - tweak: "The sound component of flashbangs no longer stuns unless you have sensitive and unprotected hearing."
+ - tweak: "Eye damage from flashes has been significantly reduced."
+ - bugfix: "You can no longer use a flash that isn't in your hand to AOE flash."
+ - backend: "soundbang_act renamed to noise_act; ear protection now uses defines for preset values like flash/eye protection"