Files
Ghom 922bd0cb92 Refactor get_ear_protection() and soundbang_act() to be less bs (#93472)
so, the current `COMSIG_CARBON_SOUNDBANG` signal is kinda lame because:
1) it's relegated to carbon mobs
2) it means ear protection equipment actually has no effect when
`get_ear_protection` is called instead.
3) It's sent in more than one place in the code

So I replaced it with another signal, this one properly sent in
`get_ear_protection`, and therefore `soundbang_act` as well.

What's also lame is that the code for both `get_ear_protection` and
`soundbang_act` can be easily moved to the living type, and it wouldn't
make a huge impact aside causing simple mobs to be stunned very briefly
by flashbangs since they cannot be knocked down anyway. The less the
code is specific to a subtype, the easier it's to work with, the fewer
the paradigms etc.

Another lame thing is some of the code being kinda old. Also I wanted to
fix an issue with the shriek ling ability detailed in #93401. I wanted
to make the ability more consistent with how other sound-related
abilities work by making it use `soundbang_act`, but with an intensity
higher than any other feature so far, beside point-blank flashbangs
(holding on standing on one). I've also buffed the "ear protection"
offered by vacuums from 1 to 3, meaning nothing but point-blank
flashbangs will go through. Yes, this means shrieks are not good in a
vacuum because sound generally propagate in absence of molecules that
can transmit the vibration... at least IRL. The game's an approximation
anyway, but it's still inconsistent, like a fuckton of other things that
are even more outside of the scope of this PR. Well, at least it affects
simple/basic mobs too now.

## Why It's Good For The Game
This will fix #93401 and make some code less old and bad.

## Changelog

🆑
refactor: refactored code for ear/soundbang protection. Flashbangs and
other things can now affect simple/basic mobs as well, not just carbon
and occasionally silicons.
balance: Aliens are no longer impervious to soundbang_act. Still very
resistant to it due to their hardcoded ear protection
balance: How the resonant shriek changeling ability works is now
slightly more consistent with the ear/soundbang protection, meaning it
won't work well in a vacuum, but at least it works on simple mobs now.
fix: Everyone can now hear a changeling shriek, unless they're already
deafened or in a vacuum.
/🆑
2025-11-04 15:22:33 -05:00

114 lines
4.2 KiB
Plaintext

/mob/living/brain
var/obj/item/mmi/container = null
var/emp_damage = 0//Handles a type of MMI damage
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
stat = DEAD //we start dead by default
see_invisible = SEE_INVISIBLE_LIVING
speech_span = SPAN_ROBOT
/mob/living/brain/Initialize(mapload)
. = ..()
create_dna(src)
stored_dna.initialize_dna(random_human_blood_type())
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
OB.brainmob = src
forceMove(OB)
if(!container?.mecha && (!container || container.immobilize)) //Unless inside a mecha, brains are rather helpless.
add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), BRAIN_UNAIDED)
ADD_TRAIT(src, TRAIT_SILICON_EMOTES_ALLOWED, INNATE_TRAIT)
/mob/living/brain/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
var/obj/item/organ/brain/brain_loc = loc
if(brain_loc && isnull(new_turf) && brain_loc.owner) //we're actively being put inside a new body.
return ..(old_turf, get_turf(brain_loc.owner), same_z_layer, notify_contents)
return ..()
/mob/living/brain/proc/create_dna()
stored_dna = new /datum/dna/stored(src)
if(!stored_dna.species)
var/rando_race = pick(get_selectable_species())
stored_dna.species = new rando_race()
/mob/living/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
if(stat != DEAD)
death(TRUE)
if(mind) //You aren't allowed to return to brains that don't exist
mind.set_current(null)
ghostize() //Ghostize checks for key so nothing else is necessary.
container = null
QDEL_NULL(stored_dna)
return ..()
/// Override parent here because... the blind message doesn't really work given what's happen when a brain suicides. Can't hear a brain going grey. So, we omit the "blind" message.
/mob/living/brain/send_applicable_messages()
visible_message(span_danger(get_visible_suicide_message()), span_userdanger(get_visible_suicide_message()))
/mob/living/brain/get_visible_suicide_message()
return "[src]'s brain is growing dull and lifeless. [p_They()] look[p_s()] like [p_theyve()] lost the will to live."
/mob/living/brain/apply_suicide_damage(obj/item/suicide_tool, damage_type = NONE) // we don't really care about applying damage to the brain mob and is just needless work.
return FALSE
/mob/living/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
return FALSE
/mob/living/brain/blob_act(obj/structure/blob/B)
return
/mob/living/brain/get_eye_protection()//no eyes
return FLASH_PROTECTION_WELDER
/mob/living/brain/get_ear_protection(ignore_deafness = FALSE)
return ..() + EAR_PROTECTION_HEAVY
/mob/living/brain/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /atom/movable/screen/fullscreen/flash, length = 25)
return // no eyes, no flashing
/mob/living/brain/can_be_revived()
if(!container || health <= HEALTH_THRESHOLD_DEAD)
return FALSE
return TRUE
/mob/living/brain/fully_replace_character_name(oldname,newname)
..()
if(stored_dna)
stored_dna.real_name = real_name
/mob/living/brain/forceMove(atom/destination)
if(container)
return container.forceMove(destination)
else if (istype(loc, /obj/item/organ/brain))
var/obj/item/organ/brain/B = loc
B.forceMove(destination)
else if (istype(destination, /obj/item/organ/brain))
doMove(destination)
else if (istype(destination, /obj/item/mmi))
doMove(destination)
else
CRASH("Brainmob without a container [src] attempted to move to [destination].")
/mob/living/brain/update_mouse_pointer()
if (!client)
return
client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
if(!container)
return
if (container.mecha)
var/obj/vehicle/sealed/mecha/M = container.mecha
if(M.mouse_pointer)
client.mouse_pointer_icon = M.mouse_pointer
/mob/living/brain/proc/get_traumas()
. = list()
if(istype(loc, /obj/item/organ/brain))
var/obj/item/organ/brain/B = loc
. = B.traumas
/mob/living/brain/get_policy_keywords()
. = ..()
if(container)
. += "[container.type]"