#define TONGUE_MAX_HEALTH 60 /obj/item/organ/tongue name = "tongue" desc = "A fleshy muscle mostly used for lying." icon_state = "tonguenormal" zone = BODY_ZONE_PRECISE_MOUTH slot = ORGAN_SLOT_TONGUE attack_verb = list("licked", "slobbered", "slapped", "frenched", "tongued") var/list/languages_possible var/say_mod = null var/taste_sensitivity = 15 // lower is more sensitive. maxHealth = TONGUE_MAX_HEALTH var/modifies_speech = FALSE var/static/list/languages_possible_base = typecacheof(list( /datum/language/common, /datum/language/draconic, /datum/language/codespeak, /datum/language/monkey, /datum/language/narsie, /datum/language/beachbum, /datum/language/ratvar, /datum/language/aphasia, /datum/language/slime, /datum/language/vampiric, /datum/language/dwarf, )) healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!! decay_factor = STANDARD_ORGAN_DECAY/2 /obj/item/organ/tongue/Initialize(mapload) . = ..() low_threshold_passed = "Your [name] feels a little sore." low_threshold_cleared = "Your [name] soreness has subsided." high_threshold_passed = "Your [name] is really starting to hurt." high_threshold_cleared = "The pain of your [name] has subsided a little." now_failing = "Your [name] feels like it's about to fall out!." now_fixed = "The excruciating pain of your [name] has subsided." languages_possible = languages_possible_base /obj/item/organ/tongue/proc/handle_speech(datum/source, list/speech_args) return /obj/item/organ/tongue/applyOrganDamage(d, maximum = maxHealth) . = ..() if (damage >= maxHealth) to_chat(owner, "Your tongue is singed beyond recognition, and disintegrates!") SSblackbox.record_feedback("tally", "fermi_chem", 1, "Tongues lost to Fermi") qdel(src) /obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE) ..() if(say_mod && M.dna && M.dna.species) M.dna.species.say_mod = say_mod if (modifies_speech) RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech) M.UnregisterSignal(M, COMSIG_MOB_SAY) /obj/item/organ/tongue/Remove(special = FALSE) if(!QDELETED(owner)) if(say_mod && owner.dna?.species) owner.dna.species.say_mod = initial(owner.dna.species.say_mod) UnregisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech) owner.RegisterSignal(owner, COMSIG_MOB_SAY, /mob/living/carbon/.proc/handle_tongueless_speech) return ..() /obj/item/organ/tongue/could_speak_language(language) return is_type_in_typecache(language, languages_possible) /obj/item/organ/tongue/lizard name = "forked tongue" desc = "A thin and long muscle typically found in reptilian races, apparently moonlights as a nose." icon_state = "tonguelizard" say_mod = "hisses" taste_sensitivity = 10 // combined nose + tongue, extra sensitive maxHealth = 40 //extra sensitivity means tongue is more susceptible to damage modifies_speech = TRUE /obj/item/organ/tongue/lizard/handle_speech(datum/source, list/speech_args) var/static/regex/lizard_hiss = new("s+", "g") var/static/regex/lizard_hiSS = new("S+", "g") var/message = speech_args[SPEECH_MESSAGE] if(message[1] != "*") message = lizard_hiss.Replace(message, "sss") message = lizard_hiSS.Replace(message, "SSS") speech_args[SPEECH_MESSAGE] = message /obj/item/organ/tongue/fly name = "proboscis" desc = "A freakish looking meat tube that apparently can take in liquids." icon_state = "tonguefly" say_mod = "buzzes" taste_sensitivity = 25 // you eat vomit, this is a mercy maxHealth = 80 //years of eatting trash has made your tongue strong modifies_speech = TRUE /obj/item/organ/tongue/fly/handle_speech(datum/source, list/speech_args) var/static/regex/fly_buzz = new("z+", "g") var/static/regex/fly_buZZ = new("Z+", "g") var/message = speech_args[SPEECH_MESSAGE] if(message[1] != "*") message = fly_buzz.Replace(message, "zzz") message = fly_buZZ.Replace(message, "ZZZ") speech_args[SPEECH_MESSAGE] = message /obj/item/organ/tongue/abductor name = "superlingual matrix" desc = "A mysterious structure that allows for instant communication between users. Pretty impressive until you need to eat something." icon_state = "tongueayylmao" say_mod = "gibbers" taste_sensitivity = 101 // ayys cannot taste anything. maxHealth = 120 //Ayys probe a lot modifies_speech = TRUE var/mothership /obj/item/organ/tongue/abductor/attack_self(mob/living/carbon/human/H) if(!istype(H)) return var/obj/item/organ/tongue/abductor/T = H.getorganslot(ORGAN_SLOT_TONGUE) if(!istype(T)) return if(T.mothership == mothership) to_chat(H, "[src] is already attuned to the same channel as your own.") return H.visible_message("[H] holds [src] in their hands, and concentrates for a moment.", "You attempt to modify the attunation of [src].") if(do_after(H, delay=15, target=src)) to_chat(H, "You attune [src] to your own channel.") mothership = T.mothership /obj/item/organ/tongue/abductor/examine(mob/M) . = ..() if(HAS_TRAIT(M, TRAIT_ABDUCTOR_TRAINING) || HAS_TRAIT(M.mind, TRAIT_ABDUCTOR_TRAINING) || isobserver(M)) if(!mothership) . += "It is not attuned to a specific mothership." else . += "It is attuned to [mothership]." /obj/item/organ/tongue/abductor/handle_speech(datum/source, list/speech_args) //Hacks var/message = speech_args[SPEECH_MESSAGE] var/mob/living/carbon/human/user = source var/rendered = "[user.name]: [message]" user.log_talk(message, LOG_SAY, tag="abductor") for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) var/obj/item/organ/tongue/T = H.getorganslot(ORGAN_SLOT_TONGUE) if(!T || T.type != type) continue if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor") var/datum/antagonist/abductor/A = user.mind.has_antag_datum(/datum/antagonist/abductor) if(!A || !(H.mind in A.team.members)) continue to_chat(H, rendered) for(var/mob/M in GLOB.dead_mob_list) var/link = FOLLOW_LINK(M, user) to_chat(M, "[link] [rendered]") speech_args[SPEECH_MESSAGE] = "" /obj/item/organ/tongue/zombie name = "rotting tongue" desc = "Between the decay and the fact that it's just lying there you doubt a tongue has ever seemed less sexy." icon_state = "tonguezombie" say_mod = "moans" taste_sensitivity = 32 maxHealth = 65 //Stop! It's already dead...! modifies_speech = TRUE /obj/item/organ/tongue/zombie/handle_speech(datum/source, list/speech_args) var/list/message_list = splittext(speech_args[SPEECH_MESSAGE], " ") var/maxchanges = max(round(message_list.len / 1.5), 2) for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--) var/insertpos = rand(1, message_list.len - 1) var/inserttext = message_list[insertpos] if(!(copytext(inserttext, -3) == "..."))//3 == length("...") message_list[insertpos] = inserttext + "..." if(prob(20) && message_list.len > 3) message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...") speech_args[SPEECH_MESSAGE] = jointext(message_list, " ") /obj/item/organ/tongue/alien name = "alien tongue" desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"." icon_state = "tonguexeno" say_mod = "hisses" taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED maxHealth = 500 //They've a little mouth for a tongue, so it's pretty rhobust modifies_speech = TRUE // not really, they just hiss var/static/list/languages_possible_alien = typecacheof(list( /datum/language/xenocommon, /datum/language/common, /datum/language/draconic, /datum/language/ratvar, /datum/language/monkey)) /obj/item/organ/tongue/alien/Initialize(mapload) . = ..() languages_possible = languages_possible_alien /obj/item/organ/tongue/alien/handle_speech(datum/source, list/speech_args) playsound(owner, "hiss", 25, 1, 1) /obj/item/organ/tongue/bone name = "bone \"tongue\"" desc = "Apparently skeletons alter the sounds they produce through oscillation of their teeth, hence their characteristic rattling." icon_state = "tonguebone" say_mod = "rattles" organ_flags = ORGAN_NO_SPOIL attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned") taste_sensitivity = 101 // skeletons cannot taste anything maxHealth = 75 //Take brute damage instead modifies_speech = TRUE var/chattering = FALSE var/phomeme_type = "sans" var/list/phomeme_types = list("sans", "papyrus") /obj/item/organ/tongue/bone/Initialize() . = ..() phomeme_type = pick(phomeme_types) /obj/item/organ/tongue/bone/applyOrganDamage(var/d, var/maximum = maxHealth) if(d < 0) return if(!owner) return var/target = owner.get_bodypart(BODY_ZONE_HEAD) owner.apply_damage(d, BURN, target) to_chat(owner, "You feel your skull burning! Oof, your bones!") return /obj/item/organ/tongue/bone/handle_speech(datum/source, list/speech_args) if (chattering) chatter(speech_args[SPEECH_MESSAGE], phomeme_type, source) switch(phomeme_type) if("sans") speech_args[SPEECH_SPANS] |= SPAN_SANS if("papyrus") speech_args[SPEECH_SPANS] |= SPAN_PAPYRUS /obj/item/organ/tongue/bone/plasmaman name = "plasma bone \"tongue\"" desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech." icon_state = "tongueplasma" modifies_speech = FALSE /obj/item/organ/tongue/robot name = "robotic voicebox" desc = "A voice synthesizer that can interface with organic lifeforms." status = ORGAN_ROBOTIC icon_state = "tonguerobot" say_mod = "states" attack_verb = list("beeped", "booped") modifies_speech = TRUE taste_sensitivity = 25 // not as good as an organic tongue maxHealth = 100 //RoboTongue! var/electronics_magic = TRUE /obj/item/organ/tongue/robot/could_speak_language(language) return ..() || electronics_magic /obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args) speech_args[SPEECH_SPANS] |= SPAN_ROBOT /obj/item/organ/tongue/fluffy name = "fluffy tongue" desc = "OwO what's this?" icon_state = "tonguefluffy" taste_sensitivity = 10 // extra sensitive and inquisitive uwu maxHealth = 35 //Sensitive tongue! modifies_speech = TRUE /obj/item/organ/tongue/fluffy/handle_speech(datum/source, list/speech_args) var/message = speech_args[SPEECH_MESSAGE] if(message[1] != "*") message = replacetext(message, "ne", "nye") message = replacetext(message, "nu", "nyu") message = replacetext(message, "na", "nya") message = replacetext(message, "no", "nyo") message = replacetext(message, "ove", "uv") message = replacetext(message, "l", "w") message = replacetext(message, "r", "w") message = lowertext(message) speech_args[SPEECH_MESSAGE] = message /obj/item/organ/tongue/cybernetic name = "cybernetic tongue" desc = "A state of the art robotic tongue that can detect the pH of anything drank." icon_state = "tonguecybernetic" taste_sensitivity = 10 maxHealth = 60 //It's robotic! organ_flags = ORGAN_SYNTHETIC /obj/item/organ/tongue/cybernetic/emp_act(severity) . = ..() if(. & EMP_PROTECT_SELF) return var/errormessage = list("Runtime in tongue.dm, line 39: Undefined operation \"zapzap ow my tongue\"", "afhsjifksahgjkaslfhashfjsak", "-1.#IND", "Graham's number", "inside you all along", "awaiting at least 1 approving review before merging this taste request") owner.say("The pH is appropriately [pick(errormessage)].", forced = "EMPed synthetic tongue") /obj/item/organ/tongue/cybernetic/handle_speech(datum/source, list/speech_args) speech_args[SPEECH_SPANS] |= SPAN_ROBOT /obj/item/organ/tongue/robot/ipc name = "positronic voicebox" say_mod = "beeps" desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms." electronics_magic = FALSE organ_flags = ORGAN_SYNTHETIC