Files
fulpstation/code/modules/mob/living/emote.dm
MrPerson f7eb2c905b Unicode awareness Part 2 -- copytext() (#48512)
* Unicode support Part 2 -- copytext()

This is the transition of all copytext() calls to be unicode aware and also some nearby calls in the same functions. Most things are just replacing copytext() with copytext_char() as a terrible character limiter but a few others were slightly more involved.

I replaced a ton of
````
var/something = sanitize(input())
something = copytext(something, 1, MAX_MESSAGE_LEN)
````

with a single stripped_input() call. stripped_input() already calls html_encode(), trim(), and some other sanitization so there shouldn't be any major issues there.

This is still VERY rough btw; DNA is a mess, the status displays are complete ass, there's a copytext() in code\datums\shuttles.dm that I'm not sure what to do with, and I didn't touch anything in the tools folder. I haven't tested this much at all yet, I only got it to compile earlier this morning. There's also likely to be weird bugs until I get around to fixing length(), findtext(), and the rest of the string procs.

* Makes the code functional

* Assume color hex strings are always # followed by ascii.
Properly encodes and decodes the stuff in mob_helpers.dm which fixes some issues there.

* Removes ninjaspeak since it's unused
2020-01-18 13:07:22 +13:00

529 lines
14 KiB
Plaintext

/* EMOTE DATUMS */
/datum/emote/living
mob_type_allowed_typecache = /mob/living
mob_type_blacklist_typecache = list(/mob/living/simple_animal/slime, /mob/living/brain)
/datum/emote/living/blush
key = "blush"
key_third_person = "blushes"
message = "blushes."
/datum/emote/living/bow
key = "bow"
key_third_person = "bows"
message = "bows."
message_param = "bows to %t."
restraint_check = TRUE
/datum/emote/living/burp
key = "burp"
key_third_person = "burps"
message = "burps."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/choke
key = "choke"
key_third_person = "chokes"
message = "chokes!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/cross
key = "cross"
key_third_person = "crosses"
message = "crosses their arms."
restraint_check = TRUE
/datum/emote/living/chuckle
key = "chuckle"
key_third_person = "chuckles"
message = "chuckles."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/collapse
key = "collapse"
key_third_person = "collapses"
message = "collapses!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/collapse/run_emote(mob/user, params, type_override, intentional)
. = ..()
if(. && isliving(user))
var/mob/living/L = user
L.Unconscious(40)
/datum/emote/living/cough
key = "cough"
key_third_person = "coughs"
message = "coughs!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/cough/can_run_emote(mob/user, status_check = TRUE , intentional)
. = ..()
if(HAS_TRAIT(user, TRAIT_SOOTHED_THROAT))
return FALSE
/datum/emote/living/dance
key = "dance"
key_third_person = "dances"
message = "dances around happily."
restraint_check = TRUE
/datum/emote/living/deathgasp
key = "deathgasp"
key_third_person = "deathgasps"
message = "seizes up and falls limp, their eyes dead and lifeless..."
message_robot = "shudders violently for a moment before falling still, its eyes slowly darkening."
message_AI = "screeches, its screen flickering as its systems slowly halt."
message_alien = "lets out a waning guttural screech, and collapses onto the floor..."
message_larva = "lets out a sickly hiss of air and falls limply to the floor..."
message_monkey = "lets out a faint chimper as it collapses and stops moving..."
message_simple = "stops moving..."
cooldown = (15 SECONDS)
stat_allowed = UNCONSCIOUS
/datum/emote/living/deathgasp/run_emote(mob/user, params, type_override, intentional)
var/mob/living/simple_animal/S = user
if(istype(S) && S.deathmessage)
message_simple = S.deathmessage
. = ..()
message_simple = initial(message_simple)
if(. && user.deathsound)
if(isliving(user))
var/mob/living/L = user
if(!L.can_speak_vocal() || L.oxyloss >= 50)
return //stop the sound if oxyloss too high/cant speak
playsound(user, user.deathsound, 200, TRUE, TRUE)
/datum/emote/living/drool
key = "drool"
key_third_person = "drools"
message = "drools."
/datum/emote/living/faint
key = "faint"
key_third_person = "faints"
message = "faints."
/datum/emote/living/faint/run_emote(mob/user, params, type_override, intentional)
. = ..()
if(. && isliving(user))
var/mob/living/L = user
L.SetSleeping(200)
/datum/emote/living/flap
key = "flap"
key_third_person = "flaps"
message = "flaps their wings."
restraint_check = TRUE
var/wing_time = 20
/datum/emote/living/flap/run_emote(mob/user, params, type_override, intentional)
. = ..()
if(. && ishuman(user))
var/mob/living/carbon/human/H = user
var/open = FALSE
if(H.dna.features["wings"] != "None")
if("wingsopen" in H.dna.species.mutant_bodyparts)
open = TRUE
H.CloseWings()
else
H.OpenWings()
addtimer(CALLBACK(H, open ? /mob/living/carbon/human.proc/OpenWings : /mob/living/carbon/human.proc/CloseWings), wing_time)
/datum/emote/living/flap/aflap
key = "aflap"
key_third_person = "aflaps"
message = "flaps their wings ANGRILY!"
restraint_check = TRUE
wing_time = 10
/datum/emote/living/frown
key = "frown"
key_third_person = "frowns"
message = "frowns."
/datum/emote/living/gag
key = "gag"
key_third_person = "gags"
message = "gags."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/gasp
key = "gasp"
key_third_person = "gasps"
message = "gasps!"
emote_type = EMOTE_AUDIBLE
stat_allowed = UNCONSCIOUS
/datum/emote/living/giggle
key = "giggle"
key_third_person = "giggles"
message = "giggles."
message_mime = "giggles silently!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/glare
key = "glare"
key_third_person = "glares"
message = "glares."
message_param = "glares at %t."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/grin
key = "grin"
key_third_person = "grins"
message = "grins."
/datum/emote/living/groan
key = "groan"
key_third_person = "groans"
message = "groans!"
message_mime = "appears to groan!"
/datum/emote/living/grimace
key = "grimace"
key_third_person = "grimaces"
message = "grimaces."
/datum/emote/living/jump
key = "jump"
key_third_person = "jumps"
message = "jumps!"
restraint_check = TRUE
/datum/emote/living/kiss
key = "kiss"
key_third_person = "kisses"
message = "blows a kiss."
message_param = "blows a kiss to %t."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/laugh
key = "laugh"
key_third_person = "laughs"
message = "laughs."
message_mime = "laughs silently!"
emote_type = EMOTE_AUDIBLE
vary = TRUE
/datum/emote/living/laugh/can_run_emote(mob/living/user, status_check = TRUE , intentional)
. = ..()
if(. && iscarbon(user))
var/mob/living/carbon/C = user
return !C.silent
/datum/emote/living/laugh/get_sound(mob/living/user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna.species.id == "human" && (!H.mind || !H.mind.miming))
if(user.gender == FEMALE)
return 'sound/voice/human/womanlaugh.ogg'
else
return pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg')
/datum/emote/living/look
key = "look"
key_third_person = "looks"
message = "looks."
message_param = "looks at %t."
/datum/emote/living/nod
key = "nod"
key_third_person = "nods"
message = "nods."
message_param = "nods at %t."
/datum/emote/living/point
key = "point"
key_third_person = "points"
message = "points."
message_param = "points at %t."
restraint_check = TRUE
/datum/emote/living/point/run_emote(mob/user, params, type_override, intentional)
message_param = initial(message_param) // reset
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.get_num_arms() == 0)
if(H.get_num_legs() != 0)
message_param = "tries to point at %t with a leg, <span class='userdanger'>falling down</span> in the process!"
H.Paralyze(20)
else
message_param = "<span class='userdanger'>bumps [user.p_their()] head on the ground</span> trying to motion towards %t."
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
..()
/datum/emote/living/pout
key = "pout"
key_third_person = "pouts"
message = "pouts."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/scream
key = "scream"
key_third_person = "screams"
message = "screams."
message_mime = "acts out a scream!"
emote_type = EMOTE_AUDIBLE
mob_type_blacklist_typecache = list(/mob/living/carbon/human) //Humans get specialized scream.
/datum/emote/living/scream/select_message_type(mob/user, intentional)
. = ..()
if(!intentional && isanimal(user))
return "makes a loud and pained whimper."
/datum/emote/living/scowl
key = "scowl"
key_third_person = "scowls"
message = "scowls."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/shake
key = "shake"
key_third_person = "shakes"
message = "shakes their head."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/shiver
key = "shiver"
key_third_person = "shiver"
message = "shivers."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/sigh
key = "sigh"
key_third_person = "sighs"
message = "sighs."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/sit
key = "sit"
key_third_person = "sits"
message = "sits down."
/datum/emote/living/smile
key = "smile"
key_third_person = "smiles"
message = "smiles."
/datum/emote/living/sneeze
key = "sneeze"
key_third_person = "sneezes"
message = "sneezes."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/smug
key = "smug"
key_third_person = "smugs"
message = "grins smugly."
/datum/emote/living/sniff
key = "sniff"
key_third_person = "sniffs"
message = "sniffs."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/snore
key = "snore"
key_third_person = "snores"
message = "snores."
message_mime = "sleeps soundly."
emote_type = EMOTE_AUDIBLE
stat_allowed = UNCONSCIOUS
/datum/emote/living/stare
key = "stare"
key_third_person = "stares"
message = "stares."
message_param = "stares at %t."
/datum/emote/living/strech
key = "stretch"
key_third_person = "stretches"
message = "stretches their arms."
/datum/emote/living/sulk
key = "sulk"
key_third_person = "sulks"
message = "sulks down sadly."
/datum/emote/living/surrender
key = "surrender"
key_third_person = "surrenders"
message = "puts their hands on their head and falls to the ground, they surrender!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/surrender/run_emote(mob/user, params, type_override, intentional)
. = ..()
if(. && isliving(user))
var/mob/living/L = user
L.Paralyze(200)
/datum/emote/living/sway
key = "sway"
key_third_person = "sways"
message = "sways around dizzily."
/datum/emote/living/tremble
key = "tremble"
key_third_person = "trembles"
message = "trembles in fear!"
/datum/emote/living/twitch
key = "twitch"
key_third_person = "twitches"
message = "twitches violently."
/datum/emote/living/twitch_s
key = "twitch_s"
message = "twitches."
/datum/emote/living/wave
key = "wave"
key_third_person = "waves"
message = "waves."
/datum/emote/living/whimper
key = "whimper"
key_third_person = "whimpers"
message = "whimpers."
message_mime = "appears hurt."
/datum/emote/living/wsmile
key = "wsmile"
key_third_person = "wsmiles"
message = "smiles weakly."
/datum/emote/living/yawn
key = "yawn"
key_third_person = "yawns"
message = "yawns."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/custom
key = "me"
key_third_person = "custom"
message = null
/datum/emote/living/custom/can_run_emote(mob/user, status_check, intentional)
. = ..() && intentional
/datum/emote/living/custom/proc/check_invalid(mob/user, input)
var/static/regex/stop_bad_mime = regex(@"says|exclaims|yells|asks")
if(stop_bad_mime.Find(input, 1, 1))
to_chat(user, "<span class='danger'>Invalid emote.</span>")
return TRUE
return FALSE
/datum/emote/living/custom/run_emote(mob/user, params, type_override = null, intentional = FALSE)
if(!can_run_emote(user, TRUE, intentional))
return FALSE
if(is_banned_from(user.ckey, "Emote"))
to_chat(user, "<span class='boldwarning'>You cannot send custom emotes (banned).</span>")
return FALSE
else if(QDELETED(user))
return FALSE
else if(user.client && user.client.prefs.muted & MUTE_IC)
to_chat(user, "<span class='boldwarning'>You cannot send IC messages (muted).</span>")
return FALSE
else if(!params)
var/custom_emote = copytext(sanitize(input("Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN)
if(custom_emote && !check_invalid(user, custom_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
if("Visible")
emote_type = EMOTE_VISIBLE
if("Hearable")
emote_type = EMOTE_AUDIBLE
else
alert("Unable to use this emote, must be either hearable or visible.")
return
message = custom_emote
else
message = params
if(type_override)
emote_type = type_override
. = ..()
message = null
emote_type = EMOTE_VISIBLE
/datum/emote/living/custom/replace_pronoun(mob/user, message)
return message
/datum/emote/living/help
key = "help"
/datum/emote/living/help/run_emote(mob/user, params, type_override, intentional)
var/list/keys = list()
var/list/message = list("Available emotes, you can use them with say \"*emote\": ")
for(var/key in GLOB.emote_list)
for(var/datum/emote/P in GLOB.emote_list[key])
if(P.key in keys)
continue
if(P.can_run_emote(user, status_check = FALSE , intentional = TRUE))
keys += P.key
keys = sortList(keys)
for(var/emote in keys)
if(LAZYLEN(message) > 1)
message += ", [emote]"
else
message += "[emote]"
message += "."
message = jointext(message, "")
to_chat(user, message)
/datum/emote/beep
key = "beep"
key_third_person = "beeps"
message = "beeps."
message_param = "beeps at %t."
sound = 'sound/machines/twobeep.ogg'
mob_type_allowed_typecache = list(/mob/living/brain, /mob/living/silicon)
/datum/emote/living/circle
key = "circle"
key_third_person = "circles"
restraint_check = TRUE
/datum/emote/living/circle/run_emote(mob/user, params, type_override, intentional)
. = ..()
var/obj/item/circlegame/N = new(user)
if(user.put_in_hands(N))
to_chat(user, "<span class='notice'>You make a circle with your hand.</span>")
else
qdel(N)
to_chat(user, "<span class='warning'>You don't have any free hands to make a circle with.</span>")
/datum/emote/living/slap
key = "slap"
key_third_person = "slaps"
restraint_check = TRUE
/datum/emote/living/slap/run_emote(mob/user, params, type_override, intentional)
. = ..()
if(!.)
return
var/obj/item/slapper/N = new(user)
if(user.put_in_hands(N))
to_chat(user, "<span class='notice'>You ready your slapping hand.</span>")
else
to_chat(user, "<span class='warning'>You're incapable of slapping in your current state.</span>")
/datum/emote/inhale
key = "inhale"
key_third_person = "inhales"
message = "breathes in."
/datum/emote/exhale
key = "exhale"
key_third_person = "exhales"
message = "breathes out."