mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-12 16:44:43 +01:00
341 lines
14 KiB
Plaintext
341 lines
14 KiB
Plaintext
/obj/item/organ/ears
|
|
name = "ears"
|
|
icon_state = "ears"
|
|
desc = "There are three parts to the ear. Inner, middle and outer. Only one of these parts should be normally visible."
|
|
zone = BODY_ZONE_HEAD
|
|
slot = ORGAN_SLOT_EARS
|
|
gender = PLURAL
|
|
|
|
healing_factor = STANDARD_ORGAN_HEALING
|
|
decay_factor = STANDARD_ORGAN_DECAY
|
|
|
|
low_threshold_passed = span_info("Your ears begin to resonate with an internal ring sometimes.")
|
|
now_failing = span_warning("You are unable to hear at all!")
|
|
now_fixed = span_info("Noise slowly begins filling your ears once more.")
|
|
low_threshold_cleared = span_info("The ringing in your ears has died down.")
|
|
visual = FALSE
|
|
|
|
/// temporary deafness, measured in seconds. While > 0, the person is unable to hear anything.
|
|
var/temporary_deafness = 0
|
|
|
|
// `damage` in this case measures long term damage to the ears, if too high,
|
|
// the person will not have either `deaf` or `ear_damage` decrease
|
|
// without external aid (earmuffs, drugs)
|
|
|
|
/// Resistance against loud noises
|
|
var/bang_protect = EAR_PROTECTION_NONE
|
|
/// Multiplier for both long term and short term ear damage
|
|
var/damage_multiplier = 1
|
|
|
|
/obj/item/organ/ears/on_life(seconds_per_tick)
|
|
// only inform when things got worse, needs to happen before we heal
|
|
if((damage > low_threshold && prev_damage < low_threshold) || (damage > high_threshold && prev_damage < high_threshold))
|
|
to_chat(owner, span_warning("The ringing in your ears grows louder, blocking out any external noises for a moment."))
|
|
|
|
. = ..()
|
|
// if we have non-damage related deafness like mutations, quirks or clothing (earmuffs), don't bother processing here.
|
|
// Ear healing from earmuffs or chems happen elsewhere
|
|
if(HAS_TRAIT_NOT_FROM(owner, TRAIT_DEAF, EAR_DAMAGE))
|
|
return
|
|
// no healing if failing
|
|
if(organ_flags & ORGAN_FAILING)
|
|
return
|
|
adjust_temporary_deafness(-seconds_per_tick SECONDS)
|
|
if((damage > low_threshold) && SPT_PROB(damage / 60, seconds_per_tick))
|
|
adjust_temporary_deafness(4 SECONDS)
|
|
SEND_SOUND(owner, sound('sound/items/weapons/flash_ring.ogg'))
|
|
|
|
/obj/item/organ/ears/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags)
|
|
. = ..()
|
|
if(temporary_deafness)
|
|
on_deafened()
|
|
REMOVE_TRAIT(organ_owner, TRAIT_DEAF, NO_EARS)
|
|
|
|
/obj/item/organ/ears/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags)
|
|
. = ..()
|
|
if(temporary_deafness)
|
|
on_undeafened(organ_owner)
|
|
// Do not apply with special flag, even if it would ultimately be redundant by new ears being hot-swapped in.
|
|
// This is so we don't trip signal_addtrait when hot-swapping ears, which could cause inappropriate behavior like nuking sound effects.
|
|
if(!special)
|
|
ADD_TRAIT(organ_owner, TRAIT_DEAF, NO_EARS)
|
|
|
|
/obj/item/organ/ears/get_status_appendix(advanced, add_tooltips)
|
|
if(owner.stat == DEAD || !HAS_TRAIT(owner, TRAIT_DEAF))
|
|
return
|
|
if(advanced)
|
|
if(HAS_TRAIT_FROM(owner, TRAIT_DEAF, QUIRK_TRAIT))
|
|
return conditional_tooltip("Subject is permanently deaf.", "Irreparable under normal circumstances.", add_tooltips)
|
|
if(HAS_TRAIT_FROM(owner, TRAIT_DEAF, GENETIC_MUTATION))
|
|
return conditional_tooltip("Subject is genetically deaf.", "Use medication such as [/datum/reagent/medicine/mutadone::name].", add_tooltips)
|
|
if((organ_flags & ORGAN_FAILING) || HAS_TRAIT_FROM(owner, TRAIT_DEAF, EAR_DAMAGE))
|
|
return conditional_tooltip("Subject is [(organ_flags & ORGAN_FAILING) ? "permanently": "temporarily"] deaf from ear damage.", "Repair surgically, use medication such as [/datum/reagent/medicine/inacusiate::name], or protect ears with earmuffs.", add_tooltips)
|
|
return "Subject is deaf."
|
|
|
|
/obj/item/organ/ears/show_on_condensed_scans()
|
|
// Always show if we have an appendix
|
|
return ..() || (owner.stat != DEAD && HAS_TRAIT(owner, TRAIT_DEAF))
|
|
|
|
///Adjust the temporary deafness of the person, up or down
|
|
/obj/item/organ/ears/proc/adjust_temporary_deafness(amount)
|
|
// organ failure makes us permanently deafened. Also, doesn't do anything if not in someone or during godmode
|
|
if(amount > 0 && owner && HAS_TRAIT(owner, TRAIT_GODMODE))
|
|
return
|
|
|
|
temporary_deafness = max(temporary_deafness + amount * damage_multiplier, 0)
|
|
|
|
if(!owner)
|
|
return
|
|
|
|
if(temporary_deafness && !HAS_TRAIT_FROM(owner, TRAIT_DEAF, EAR_DAMAGE))
|
|
on_deafened()
|
|
else if(!temporary_deafness && HAS_TRAIT_FROM(owner, TRAIT_DEAF, EAR_DAMAGE))
|
|
on_undeafened()
|
|
|
|
///Called when temporary deafness begins
|
|
/obj/item/organ/ears/proc/on_deafened()
|
|
RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(adjust_speech))
|
|
ADD_TRAIT(owner, TRAIT_DEAF, EAR_DAMAGE)
|
|
|
|
///Called when temporary deafness reaches zero. Has to have an 'organ_owner' arg, because by the time it's called on 'on_mob_remove', owner is already null
|
|
/obj/item/organ/ears/proc/on_undeafened(mob/living/organ_owner = owner)
|
|
REMOVE_TRAIT(organ_owner, TRAIT_DEAF, EAR_DAMAGE)
|
|
UnregisterSignal(organ_owner, COMSIG_MOB_SAY)
|
|
|
|
/obj/item/organ/ears/on_begin_failure()
|
|
add_organ_trait(TRAIT_DEAF)
|
|
|
|
/obj/item/organ/ears/on_failure_recovery()
|
|
remove_organ_trait(TRAIT_DEAF)
|
|
|
|
/// Being deafened by loud noises makes you shout
|
|
/obj/item/organ/ears/proc/adjust_speech(datum/source, list/speech_args)
|
|
SIGNAL_HANDLER
|
|
|
|
if(HAS_TRAIT_NOT_FROM(owner, TRAIT_DEAF, EAR_DAMAGE) || HAS_TRAIT(owner, TRAIT_SIGN_LANG))
|
|
return
|
|
|
|
var/message = speech_args[SPEECH_MESSAGE]
|
|
// Replace only end-of-sentence punctuation with exclamation marks (hence the empty space)
|
|
// We don't wanna mess with things like ellipses
|
|
message = replacetext(message, ". ", "! ")
|
|
message = replacetext(message, "? ", "?! ")
|
|
// Special case for the last character
|
|
switch(copytext_char(message, -1))
|
|
if(".")
|
|
if(copytext_char(message, -2) != "..") // Once again ignoring ellipses, let people trail off
|
|
message = copytext_char(message, 1, -1) + "!"
|
|
if("?")
|
|
message = copytext_char(message, 1, -1) + "?!"
|
|
if("!")
|
|
pass()
|
|
else
|
|
message += "!"
|
|
|
|
speech_args[SPEECH_MESSAGE] = message
|
|
return COMPONENT_UPPERCASE_SPEECH
|
|
|
|
/obj/item/organ/ears/feel_for_damage(self_aware)
|
|
// Ear damage has audible effects, so we don't really need to "feel" it when self-examining
|
|
return ""
|
|
|
|
/obj/item/organ/ears/invincible
|
|
damage_multiplier = 0
|
|
|
|
/obj/item/organ/ears/cat
|
|
name = "cat ears"
|
|
icon = 'icons/obj/clothing/head/costume.dmi'
|
|
worn_icon = 'icons/mob/clothing/head/costume.dmi'
|
|
icon_state = "kitty"
|
|
visual = TRUE
|
|
damage_multiplier = 2
|
|
|
|
restyle_flags = EXTERNAL_RESTYLE_FLESH
|
|
|
|
//dna_block = /datum/dna_block/feature/accessory/ears // BUBBER EDIT REMOVAL - Customization - We have our own system to handle DNA.
|
|
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/cat_ears
|
|
|
|
/// Bodypart overlay for the horrible cat ears
|
|
/datum/bodypart_overlay/mutant/cat_ears
|
|
layers = EXTERNAL_FRONT | EXTERNAL_BEHIND
|
|
color_source = ORGAN_COLOR_HAIR
|
|
feature_key = FEATURE_EARS
|
|
dyable = TRUE
|
|
|
|
/// Layer upon which we add the inner ears overlay
|
|
var/inner_layer = EXTERNAL_FRONT
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE)
|
|
return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEHAIR)
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/get_image(image_layer, obj/item/bodypart/limb)
|
|
var/mutable_appearance/base_ears = ..()
|
|
base_ears.color = (dye_color || draw_color)
|
|
|
|
// Only add inner ears on the inner layer
|
|
if(image_layer != bitflag_to_layer(inner_layer))
|
|
return base_ears
|
|
|
|
// Construct image of inner ears, apply to base ears as an overlay
|
|
feature_key += "inner"
|
|
var/mutable_appearance/inner_ears = ..()
|
|
feature_key = initial(feature_key)
|
|
var/mutable_appearance/ear_holder = mutable_appearance(layer = image_layer)
|
|
ear_holder.overlays += base_ears
|
|
ear_holder.overlays += inner_ears
|
|
return ear_holder
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/color_image(image/overlay, layer, obj/item/bodypart/limb)
|
|
return // We color base ears manually above in get_image
|
|
|
|
/obj/item/organ/ears/cat/cybernetic
|
|
name = "basic cybernetic cat ears"
|
|
icon = 'icons/obj/medical/organs/organs.dmi'
|
|
icon_state = "ears-c-cat"
|
|
desc = "A basic cybernetic organ designed to mimic the operation of ears."
|
|
damage_multiplier = 2.4
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/cat_ears/cybernetic
|
|
sprite_accessory_override = /datum/sprite_accessory/ears/cat/cybernetic
|
|
organ_flags = ORGAN_ROBOTIC
|
|
failing_desc = "seems to be broken."
|
|
|
|
/obj/item/organ/ears/cat/cybernetic/upgraded
|
|
name = "cybernetic cat ears"
|
|
icon_state = "ears-c-cat-u"
|
|
desc = "A cybernetic cat ear, still less durable than human ears."
|
|
damage_multiplier = 1.5
|
|
|
|
/obj/item/organ/ears/cat/cybernetic/volume
|
|
name = "volume-adjusting cybernetic cat ears"
|
|
icon_state = "ears-c-cat-u2"
|
|
desc = "Advanced cybernetic cat ears capable of dampening loud noises to protect their user."
|
|
damage_multiplier = 1
|
|
bang_protect = 1
|
|
|
|
/obj/item/organ/ears/cat/cybernetic/whisper
|
|
name = "whisper-sensiive cybernetic cat ears"
|
|
icon_state = "ears-c-cat-green"
|
|
desc = "Allows the user to more easily hear whispers. The user becomes extremely vulnerable to loud noises, however."
|
|
damage_multiplier = 3 // 4 would be excessive
|
|
organ_traits = list(TRAIT_GOOD_HEARING)
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/cat_ears/cybernetic/green
|
|
|
|
/obj/item/organ/ears/cat/cybernetic/xray
|
|
name = "wall-penetrating cybernetic cat ears"
|
|
icon_state = "ears-c-cat-blue"
|
|
desc = "Through the power of modern feline engineering, allows the user to hear speech through walls. The user becomes extremely vulnerable to loud noises, however."
|
|
damage_multiplier = 3 // As above, 4 would be excessive
|
|
organ_traits = list(TRAIT_XRAY_HEARING)
|
|
bodypart_overlay = /datum/bodypart_overlay/mutant/cat_ears/cybernetic/blue
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/cybernetic
|
|
color_source = null
|
|
dyable = FALSE
|
|
/// Color of the inner ear
|
|
var/inner_color = "#F0004A"
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/cybernetic/get_image(image_layer, obj/item/bodypart/limb)
|
|
if (image_layer != bitflag_to_layer(inner_layer))
|
|
return ..()
|
|
var/mutable_appearance/ear_holder = ..()
|
|
var/mutable_appearance/inner = ear_holder.overlays[2]
|
|
inner.color = inner_color
|
|
return ear_holder
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/cybernetic/get_overlay(layer, obj/item/bodypart/limb)
|
|
if (layer != inner_layer)
|
|
return ..()
|
|
var/list/all_images = ..()
|
|
//var/mutable_appearance/ear_holder = all_images[1] //BUBBER EDIT REMOVAL: Ear overlays in skyrat code is different. Check /datum/bodypart_overlay/mutant/proc/get_images()
|
|
var/mutable_appearance/inner = all_images[2] //BUBBER EDIT CHANGE: ORIGINAL: var/mutable_appearance/inner = ear_holder.overlays[2]
|
|
inner.color = inner_color // BUBBER EDIT ADDITION: We don't call get_image, we call get_singular_image(). This works fine here though.
|
|
all_images += emissive_appearance(inner.icon, inner.icon_state, limb, layer = inner.layer, alpha = inner.alpha * 0.75)
|
|
return all_images
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/cybernetic/green
|
|
inner_color = "#00D844"
|
|
|
|
/datum/bodypart_overlay/mutant/cat_ears/cybernetic/blue
|
|
inner_color = "#0079EA"
|
|
|
|
/obj/item/organ/ears/ghost
|
|
name = "ghost ears"
|
|
desc = "All the more to hear you... though it can't hear through walls."
|
|
icon_state = "ears-ghost"
|
|
movement_type = PHASING
|
|
organ_flags = parent_type::organ_flags | ORGAN_GHOST
|
|
|
|
/obj/item/organ/ears/penguin
|
|
name = "penguin ears"
|
|
desc = "The source of a penguin's happy feet."
|
|
|
|
/obj/item/organ/ears/penguin/on_mob_insert(mob/living/carbon/human/ear_owner)
|
|
. = ..()
|
|
to_chat(ear_owner, span_notice("You suddenly feel like you've lost your balance."))
|
|
ear_owner.AddElementTrait(TRAIT_WADDLING, ORGAN_TRAIT, /datum/element/waddling)
|
|
|
|
/obj/item/organ/ears/penguin/on_mob_remove(mob/living/carbon/human/ear_owner)
|
|
. = ..()
|
|
to_chat(ear_owner, span_notice("Your sense of balance comes back to you."))
|
|
REMOVE_TRAIT(ear_owner, TRAIT_WADDLING, ORGAN_TRAIT)
|
|
|
|
/obj/item/organ/ears/cybernetic
|
|
name = "basic cybernetic ears"
|
|
icon_state = "ears-c"
|
|
desc = "A basic cybernetic organ designed to mimic the operation of ears."
|
|
damage_multiplier = 1.2
|
|
organ_flags = ORGAN_ROBOTIC
|
|
failing_desc = "seems to be broken."
|
|
|
|
/obj/item/organ/ears/cybernetic/upgraded
|
|
name = "cybernetic ears"
|
|
icon_state = "ears-c-u"
|
|
desc = "A cybernetic ear, surpassing the performance of organic ears."
|
|
damage_multiplier = 0.75
|
|
|
|
/obj/item/organ/ears/cybernetic/whisper
|
|
name = "whisper-sensitive cybernetic ears"
|
|
icon_state = "ears-c-u"
|
|
desc = "Allows the user to more easily hear whispers. The user becomes extra vulnerable to loud noises, however."
|
|
// Same sensitivity as felinid ears
|
|
damage_multiplier = 2
|
|
// The original idea was to use signals to do this not traits. Unfortunately, the star effect used for whispers applies before any relevant signals
|
|
// This seems like the least invasive solution
|
|
organ_traits = list(TRAIT_GOOD_HEARING)
|
|
|
|
/obj/item/organ/ears/cybernetic/volume
|
|
name = "volume-adjusting cybernetic ears"
|
|
icon_state = "ears-c-u"
|
|
desc = "Advanced cybernetic ears capable of dampening loud noises to protect their user."
|
|
bang_protect = EAR_PROTECTION_NORMAL
|
|
damage_multiplier = 0.5
|
|
|
|
/obj/item/organ/ears/cybernetic/volume
|
|
name = "volume-adjusting cybernetic ears"
|
|
icon_state = "ears-c-u"
|
|
desc = "Advanced cybernetic ears capable of dampening loud noises to protect their user."
|
|
bang_protect = 1
|
|
damage_multiplier = 0.5
|
|
|
|
// "X-ray ears" that let you hear through walls
|
|
/obj/item/organ/ears/cybernetic/xray
|
|
name = "wall-penetrating cybernetic ears"
|
|
icon_state = "ears-c-u"
|
|
desc = "Through the power of modern engineering, allows the user to hear speech through walls. The user becomes extra vulnerable to loud noises, however."
|
|
// Same sensitivity as felinid ears
|
|
damage_multiplier = 2
|
|
organ_traits = list(TRAIT_XRAY_HEARING)
|
|
|
|
/obj/item/organ/ears/cybernetic/emp_act(severity)
|
|
. = ..()
|
|
if(. & EMP_PROTECT_SELF)
|
|
return
|
|
apply_organ_damage(20 / severity)
|
|
|
|
/obj/item/organ/ears/pod
|
|
name = "pod ears"
|
|
desc = "Strangest salad you've ever seen."
|
|
foodtype_flags = PODPERSON_ORGAN_FOODTYPES
|
|
color = COLOR_LIME
|