Merge branch 'master' into upstream-merge-10194

This commit is contained in:
Nadyr
2021-05-09 07:27:43 -04:00
committed by GitHub
336 changed files with 15110 additions and 13588 deletions

View File

@@ -0,0 +1,41 @@
var/list/_default_mob_emotes = list(
/decl/emote/visible,
/decl/emote/visible/scratch,
/decl/emote/visible/drool,
/decl/emote/visible/nod,
/decl/emote/visible/sway,
/decl/emote/visible/sulk,
/decl/emote/visible/twitch,
/decl/emote/visible/twitch_v,
/decl/emote/visible/dance,
/decl/emote/visible/roll,
/decl/emote/visible/shake,
/decl/emote/visible/jump,
/decl/emote/visible/shiver,
/decl/emote/visible/collapse,
/decl/emote/visible/spin,
/decl/emote/visible/sidestep,
/decl/emote/audible,
/decl/emote/audible/hiss,
/decl/emote/audible/whimper,
/decl/emote/audible/gasp,
/decl/emote/audible/scretch,
/decl/emote/audible/choke,
/decl/emote/audible/moan,
/decl/emote/audible/gnarl,
)
/mob
var/list/usable_emotes
/mob/proc/update_emotes(var/skip_sort)
usable_emotes = list()
for(var/emote in get_default_emotes())
var/decl/emote/emote_datum = decls_repository.get_decl(emote)
if(emote_datum.check_user(src))
usable_emotes[emote_datum.key] = emote_datum
if(!skip_sort)
usable_emotes = sortAssoc(usable_emotes)
/mob/proc/get_default_emotes()
return global._default_mob_emotes

View File

@@ -0,0 +1,11 @@
/datum/species
var/list/default_emotes = list()
/mob/living/carbon/update_emotes(var/skip_sort)
. = ..(skip_sort = TRUE)
if(species)
for(var/emote in species.default_emotes)
var/decl/emote/emote_datum = decls_repository.get_decl(emote)
if(emote_datum.check_user(src))
usable_emotes[emote_datum.key] = emote_datum
usable_emotes = sortAssoc(usable_emotes)

View File

@@ -0,0 +1,52 @@
/decl/emote/audible/cough
key = "cough"
emote_message_1p = "You cough!"
emote_message_1p_target = "You cough on TARGET!"
emote_message_3p = "coughs!"
emote_message_3p_target = "coughs on TARGET!"
emote_message_synthetic_1p_target = "You emit a robotic cough towards TARGET."
emote_message_synthetic_1p = "You emit a robotic cough."
emote_message_synthetic_3p_target = "emits a robotic cough towards TARGET."
emote_message_synthetic_3p = "emits a robotic cough."
emote_volume = 120
emote_volume_synthetic = 50
conscious = FALSE
emote_sound_synthetic = list(
FEMALE = list(
'sound/effects/mob_effects/f_machine_cougha.ogg',
'sound/effects/mob_effects/f_machine_coughb.ogg'
),
MALE = list(
'sound/effects/mob_effects/m_machine_cougha.ogg',
'sound/effects/mob_effects/m_machine_coughb.ogg',
'sound/effects/mob_effects/m_machine_coughc.ogg'
),
NEUTER = list(
'sound/effects/mob_effects/m_machine_cougha.ogg',
'sound/effects/mob_effects/m_machine_coughb.ogg',
'sound/effects/mob_effects/m_machine_coughc.ogg'
),
PLURAL = list(
'sound/effects/mob_effects/m_machine_cougha.ogg',
'sound/effects/mob_effects/m_machine_coughb.ogg',
'sound/effects/mob_effects/m_machine_coughc.ogg'
)
)
/decl/emote/audible/cough/get_emote_sound(var/atom/user)
if(ishuman(user) && !check_synthetic(user))
var/mob/living/carbon/human/H = user
if(H.get_gender() == FEMALE)
if(length(H.species.female_cough_sounds))
return list(
"sound" = H.species.female_cough_sounds,
"vol" = emote_volume
)
else
if(length(H.species.male_cough_sounds))
return list(
"sound" = H.species.male_cough_sounds,
"vol" = emote_volume
)
return ..()

View File

@@ -0,0 +1,129 @@
/decl/emote/audible/awoo
key = "awoo"
emote_message_3p = "lets out an awoo."
emote_sound = 'sound/voice/awoo.ogg'
/decl/emote/audible/awoo2
key = "awoo2"
emote_message_3p = "lets out an awoo."
emote_sound = 'sound/voice/long_awoo.ogg'
/decl/emote/audible/growl
key = "growl"
emote_message_3p = "lets out a growl."
emote_sound = 'sound/voice/growl.ogg'
/decl/emote/audible/woof
key = "woof"
emote_message_3p = "lets out a woof."
emote_sound = 'sound/voice/woof.ogg'
/decl/emote/audible/woof2
key = "woof2"
emote_message_3p = "lets out a woof."
emote_sound = 'sound/voice/woof2.ogg'
/decl/emote/audible/nya
key = "nya"
emote_message_3p = "lets out a nya."
emote_sound = 'sound/voice/nya.ogg'
/decl/emote/audible/mrowl
key = "mrowl"
emote_message_3p = "mrowls."
emote_sound = 'sound/voice/mrow.ogg'
/decl/emote/audible/peep
key = "peep"
emote_message_3p = "peeps like a bird."
emote_sound = 'sound/voice/peep.ogg'
/decl/emote/audible/chirp
key = "chirp"
emote_message_3p = "chirps!"
emote_sound = 'sound/misc/nymphchirp.ogg'
/decl/emote/audible/hoot
key = "hoot"
emote_message_3p = "hoots!"
emote_sound = 'sound/voice/hoot.ogg'
/decl/emote/audible/weh
key = "weh"
emote_message_3p = "lets out a weh."
emote_sound = 'sound/voice/weh.ogg'
/decl/emote/audible/merp
key = "merp"
emote_message_3p = "lets out a merp."
emote_sound = 'sound/voice/merp.ogg'
/decl/emote/audible/myarp
key = "myarp"
emote_message_3p = "lets out a myarp."
emote_sound = 'sound/voice/myarp.ogg'
/decl/emote/audible/bark
key = "bark"
emote_message_3p = "lets out a bark."
emote_sound = 'sound/voice/bark2.ogg'
/decl/emote/audible/bork
key = "bork"
emote_message_3p = "lets out a bork."
emote_sound = 'sound/voice/bork.ogg'
/decl/emote/audible/mrow
emote_message_3p = "lets out a mrow."
emote_sound = 'sound/voice/mrow.ogg'
/decl/emote/audible/hypno
emote_message_3p = "lets out a mystifying tone."
emote_sound = 'sound/voice/hypno.ogg'
/decl/emote/audible/hiss
key = "hiss"
emote_message_3p = "lets out a hiss."
emote_sound = 'sound/voice/hiss.ogg'
/decl/emote/audible/rattle
key = "rattle"
emote_message_3p = "rattles!"
emote_sound = 'sound/voice/rattle.ogg'
/decl/emote/audible/squeak
key = "squeak"
emote_message_3p = "lets out a squeak."
emote_sound = 'sound/effects/mouse_squeak.ogg'
/decl/emote/audible/geck
key = "geck"
emote_message_3p = "geckers!"
emote_sound = 'sound/voice/geck.ogg'
/decl/emote/audible/baa
key = "baa"
emote_message_3p = "lets out a baa."
emote_sound = 'sound/voice/baa.ogg'
/decl/emote/audible/baa2
key = "baa2"
emote_message_3p = "bleats."
emote_sound = 'sound/voice/baa2.ogg'
/*
/decl/emote/audible/deathgasp2
key = "deathgasp2"
emote_message_3p = "[species.get_death_message()]"
m_type = 1
emote_sound = 'sound/voice/deathgasp2.ogg'
*/
/decl/emote/audible/mar
key = "mar"
emote_message_3p = "lets out a mar."
emote_sound = 'sound/voice/mar.ogg'
/decl/emote/audible/wurble
key = "wurble"
emote_message_3p = "lets out a wurble."
emote_sound = 'sound/voice/wurble.ogg'
/decl/emote/audible/snort
key = "snort"
emote_message_3p = "snorts!"
emote_sound = 'sound/voice/Snort.ogg'
/decl/emote/audible/meow
key = "meow"
emote_message_3p = "gently meows!"
emote_sound = 'sound/voice/Meow.ogg'
/decl/emote/audible/moo
key = "moo"
emote_message_3p = "takes a breath and lets out a moo."
emote_sound = 'sound/voice/Moo.ogg'
/decl/emote/audible/croak
key = "croak"
emote_message_3p = "rumbles their throat, puffs their cheeks and croaks."
emote_sound = 'sound/voice/Croak.ogg'
/decl/emote/audible/gao
key = "gao"
emote_message_3p = "lets out a gao."
emote_sound = 'sound/voice/gao.ogg'
/decl/emote/audible/cackle
key = "cackle"
emote_message_3p = "cackles hysterically!"
emote_sound = 'sound/voice/YeenCackle.ogg'

View File

@@ -0,0 +1,16 @@
/decl/emote/audible/scream
key = "scream"
emote_message_1p = "You scream!"
emote_message_3p = "screams!"
/decl/emote/audible/scream/get_emote_message_1p(var/atom/user, var/atom/target, var/extra_params)
if(ishuman(user))
var/mob/living/carbon/human/H = user
return "You [H.species.scream_verb_1p]!"
. = ..()
/decl/emote/audible/cough/get_emote_message_3p(var/atom/user, var/atom/target, var/extra_params)
if(ishuman(user))
var/mob/living/carbon/human/H = user
return "[H.species.scream_verb_3p]!"
. = ..()

View File

@@ -0,0 +1,24 @@
/decl/emote/audible/slap
key = "slap"
emote_message_1p_target = "You slap TARGET across the face. Ouch!"
emote_message_1p = "You slap yourself across the face!"
emote_message_3p_target = "slaps TARGET across the face. Ouch!"
emote_message_3p = "slaps USER_SELF across the face!"
emote_sound = 'sound/effects/snap.ogg'
check_restraints = TRUE
check_range = 1
/decl/emote/audible/slap/New()
..()
emote_message_1p_target = SPAN_DANGER(emote_message_1p_target)
emote_message_1p = SPAN_DANGER(emote_message_1p)
emote_message_3p_target = SPAN_DANGER(emote_message_3p_target)
emote_message_3p = SPAN_DANGER(emote_message_3p)
/decl/emote/audible/slap/do_extra(var/atom/user, var/atom/target)
. = ..()
if(ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/clothing/mask/smokable/mask = H.wear_mask
if(istype(mask) && H.unEquip(mask))
mask.forceMove(get_turf(H))

View File

@@ -0,0 +1,29 @@
/decl/emote/audible/sneeze
key = "sneeze"
emote_message_1p = "You sneeze."
emote_message_3p = "sneezes."
emote_sound_synthetic = list(
FEMALE = 'sound/effects/mob_effects/machine_sneeze.ogg',
MALE = 'sound/effects/mob_effects/f_machine_sneeze.ogg',
NEUTER = 'sound/effects/mob_effects/f_machine_sneeze.ogg',
PLURAL = 'sound/effects/mob_effects/f_machine_sneeze.ogg'
)
emote_message_synthetic_1p = "You emit a robotic sneeze."
emote_message_synthetic_1p_target = "You emit a robotic sneeze towards TARGET."
emote_message_synthetic_3p = "emits a robotic sneeze."
emote_message_synthetic_3p_target = "emits a robotic sneeze towards TARGET."
/decl/emote/audible/sneeze/get_emote_sound(var/atom/user)
if(ishuman(user) && !check_synthetic(user))
var/mob/living/carbon/human/H = user
if(H.get_gender() == FEMALE)
return list(
"sound" = H.species.female_sneeze_sound,
"vol" = emote_volume
)
else
return list(
"sound" = H.species.male_sneeze_sound,
"vol" = emote_volume
)
return ..()

View File

@@ -0,0 +1,36 @@
/decl/emote/audible/whistle
key = "whistle"
emote_message_1p = "You whistle a tune."
emote_message_3p = "whistles a tune."
emote_sound = 'sound/voice/longwhistle.ogg'
emote_message_muffled = "makes a light spitting noise, a poor attempt at a whistle."
emote_sound_synthetic = 'sound/voice/longwhistle_robot.ogg'
emote_message_synthetic_1p = "You whistle a robotic tune."
emote_message_synthetic_3p = "whistles a robotic tune."
/decl/emote/audible/whistle/quiet
key = "qwhistle"
emote_message_1p = "You whistle quietly."
emote_message_3p = "whistles quietly."
emote_sound = 'sound/voice/shortwhistle.ogg'
emote_message_synthetic_1p = "You whistle robotically."
emote_message_synthetic_3p = "whistles robotically."
emote_sound_synthetic = 'sound/voice/shortwhistle_robot.ogg'
/decl/emote/audible/whistle/wolf
key = "wwhistle"
emote_message_1p = "You whistle inappropriately."
emote_message_3p = "whistles inappropriately."
emote_sound = 'sound/voice/wolfwhistle.ogg'
emote_message_synthetic_1p = "You beep inappropriately."
emote_message_synthetic_3p = "beeps inappropriately."
emote_sound_synthetic = 'sound/voice/wolfwhistle_robot.ogg'
/decl/emote/audible/whistle/summon
key = "swhistle"
emote_message_1p = "You whistle a tune."
emote_message_3p = "whistles a tune."
emote_sound = 'sound/voice/summon_whistle.ogg'
emote_message_synthetic_1p = "You whistle a robotic tune."
emote_message_synthetic_3p = "whistles a robotic tune."
emote_sound_synthetic = 'sound/voice/summon_whistle_robot.ogg'

View File

@@ -0,0 +1,40 @@
/decl/emote/exertion/biological
key = "esweat"
emote_range = 4
emote_message_1p = "You are sweating heavily."
emote_message_3p = "is sweating heavily."
/decl/emote/exertion/biological/check_user(mob/living/user)
if(istype(user) && !user.isSynthetic())
return ..()
return FALSE
/decl/emote/exertion/biological/breath
key = "ebreath"
emote_message_1p = "You feel out of breath."
emote_message_3p = "looks out of breath."
/decl/emote/exertion/biological/pant
key = "epant"
emote_range = 3
message_type = AUDIBLE_MESSAGE
emote_message_1p = "You pant to catch your breath."
emote_message_3p = "pants for air."
emote_message_impaired = "You can see USER breathing heavily."
/decl/emote/exertion/synthetic
key = "ewhine"
emote_range = 3
message_type = AUDIBLE_MESSAGE
emote_message_1p = "You overstress your actuators."
emote_message_3p = "USER's actuators whine with strain."
/decl/emote/exertion/synthetic/check_user(mob/living/user)
if(istype(user) && user.isSynthetic())
return ..()
return FALSE
/decl/emote/exertion/synthetic/creak
key = "ecreak"
emote_message_1p = "Your chassis stress indicators spike."
emote_message_3p = "USER's joints creak with stress."

View File

@@ -0,0 +1,33 @@
// Not specifically /human type because those won't allow FBPs to use them
/decl/emote/helper/vwag
key = "vwag"
emote_message_3p = ""
/decl/emote/helper/vwag/check_user(mob/living/carbon/human/user)
if(!istype(user) || (!user.tail_style || !user.tail_style.ani_state))
return FALSE
return ..()
/decl/emote/helper/vwag/do_emote(var/mob/living/carbon/human/user, var/extra_params)
if(user.toggle_tail(message = 1))
return ..()
/decl/emote/helper/vwag/get_emote_message_3p(var/mob/living/carbon/human/user, var/atom/target, var/extra_params)
return "[user.wagging ? "starts" : "stops"] wagging USER_THEIR tail."
/decl/emote/helper/vflap
key = "vflap"
emote_message_3p = ""
/decl/emote/helper/vflap/check_user(mob/living/carbon/human/user)
if(!istype(user) || (!user.wing_style || !user.wing_style.ani_state))
return FALSE
return ..()
/decl/emote/helper/vflap/do_emote(var/mob/living/carbon/human/user, var/extra_params)
if(user.toggle_wing(message = 1))
return ..()
/decl/emote/helper/vflap/get_emote_message_3p(var/mob/living/carbon/human/user, var/atom/target, var/extra_params)
return "[user.flapping ? "starts" : "stops"] flapping USER_THEIR wings."

View File

@@ -0,0 +1,62 @@
/decl/emote/human
key = "vomit"
/decl/emote/human/check_user(var/mob/living/carbon/human/user)
return (istype(user))//VOREStation Edit - What does a mouth have to do with wagging?? && user.check_has_mouth() && !user.isSynthetic())
/decl/emote/human/do_emote(var/mob/living/carbon/human/user)
user.vomit()
/decl/emote/human/deathgasp
key = "deathgasp"
/decl/emote/human/deathgasp/do_emote(mob/living/carbon/human/user)
if(istype(user) && user.species.get_death_message(user) == DEATHGASP_NO_MESSAGE)
to_chat(user, SPAN_WARNING("Your species has no deathgasp."))
return
. = ..()
/decl/emote/human/deathgasp/get_emote_message_3p(var/mob/living/carbon/human/user)
return "USER [user.species.get_death_message(user)]"
/decl/emote/human/swish
key = "swish"
/decl/emote/human/swish/do_emote(var/mob/living/carbon/human/user)
user.animate_tail_once()
/decl/emote/human/wag
key = "wag"
/decl/emote/human/wag/do_emote(var/mob/living/carbon/human/user)
user.animate_tail_start()
/decl/emote/human/sway
key = "sway"
/decl/emote/human/sway/do_emote(var/mob/living/carbon/human/user)
user.animate_tail_start()
/decl/emote/human/qwag
key = "qwag"
/decl/emote/human/qwag/do_emote(var/mob/living/carbon/human/user)
user.animate_tail_fast()
/decl/emote/human/fastsway
key = "fastsway"
/decl/emote/human/fastsway/do_emote(var/mob/living/carbon/human/user)
user.animate_tail_fast()
/decl/emote/human/swag
key = "swag"
/decl/emote/human/swag/do_emote(var/mob/living/carbon/human/user)
user.animate_tail_stop()
/decl/emote/human/stopsway
key = "stopsway"
/decl/emote/human/stopsway/do_emote(var/mob/living/carbon/human/user)
user.animate_tail_stop()

View File

@@ -0,0 +1,32 @@
/decl/emote/slime
key = "nomood"
var/mood
/decl/emote/slime/do_extra(var/mob/living/simple_mob/slime/user)
. = ..()
if(istype(user))
user.mood = mood
user.update_icon()
/decl/emote/slime/check_user(var/atom/user)
return isslime(user)
/decl/emote/slime/pout
key = "pout"
mood = "pout"
/decl/emote/slime/sad
key = "sad"
mood = "sad"
/decl/emote/slime/angry
key = "angry"
mood = "angry"
/decl/emote/slime/frown
key = "frown"
mood = "mischevous"
/decl/emote/slime/smile
key = "smile"
mood = ":3"

View File

@@ -0,0 +1,76 @@
/decl/emote/visible/spin
key = "spin"
check_restraints = TRUE
emote_message_3p = "spins!"
/decl/emote/visible/spin/do_extra(mob/user)
if(istype(user))
user.spin(20, 1)
/decl/emote/visible/sidestep
key = "sidestep"
check_restraints = TRUE
emote_message_3p = "steps rhythmically and moves side to side."
/decl/emote/visible/sidestep/do_extra(mob/user)
if(istype(user))
animate(user, pixel_x = 5, time = 5)
sleep(3)
animate(user, pixel_x = -5, time = 5)
animate(pixel_x = user.default_pixel_x, pixel_y = user.default_pixel_x, time = 2)
/decl/emote/visible/flip
key = "flip"
emote_message_1p = "You do a flip!"
emote_message_3p = "does a flip!"
emote_sound = 'sound/effects/bodyfall4.ogg'
/decl/emote/visible/flip/do_extra(mob/user)
. = ..()
if(istype(user))
user.SpinAnimation(7,1)
/decl/emote/visible/floorspin
key = "floorspin"
emote_message_1p = "You spin around on the floor!"
emote_message_3p = "spins around on the floor!"
var/static/list/spin_dirs = list(
NORTH,
SOUTH,
EAST,
WEST,
EAST,
SOUTH,
NORTH,
SOUTH,
EAST,
WEST,
EAST,
SOUTH,
NORTH,
SOUTH,
EAST,
WEST,
EAST,
SOUTH
)
/decl/emote/visible/floorspin/proc/spin_dir(var/mob/user)
set waitfor = FALSE
for(var/i in spin_dirs)
user.set_dir(i)
sleep(1)
if(QDELETED(user))
return
/decl/emote/visible/floorspin/proc/spin_anim(var/mob/user)
set waitfor = FALSE
sleep(1)
if(!QDELETED(user))
user.SpinAnimation(10,1)
/decl/emote/visible/floorspin/do_extra(mob/user)
. = ..()
if(istype(user))
spin_dir(user)
spin_anim(user)

View File

@@ -0,0 +1,10 @@
/decl/emote/visible/vomit
key = "vomit"
/decl/emote/visible/vomit/do_emote(var/atom/user, var/extra_params)
if(isliving(user))
var/mob/living/M = user
if(!M.isSynthetic())
M.vomit()
return
to_chat(src, SPAN_WARNING("You are unable to vomit."))

View File

@@ -0,0 +1,7 @@
/decl/emote/visible/mlem
key = "mlem"
emote_message_3p = "mlems USER_THEIR tongue up over USER_THEIR nose. Mlem."
/decl/emote/visible/blep
key = "blep"
emote_message_3p = "bleps USER_THEIR tongue out. Blep."

View File

@@ -0,0 +1,181 @@
// Note about emote messages:
// - USER / TARGET will be replaced with the relevant name, in bold.
// - USER_THEM / TARGET_THEM / USER_THEIR / TARGET_THEIR will be replaced with a
// gender-appropriate version of the same.
// - Impaired messages do not do any substitutions.
/decl/emote
var/key // Command to use emote ie. '*[key]'
var/emote_message_1p // First person message ('You do a flip!')
var/emote_message_3p // Third person message ('Urist McBackflip does a flip!')
var/emote_message_synthetic_1p // First person message for robits.
var/emote_message_synthetic_3p // Third person message for robits.
var/emote_message_impaired // Deaf/blind message ('You hear someone flipping out.', 'You see someone opening and closing their mouth')
var/emote_message_1p_target // 'You do a flip at Urist McTarget!'
var/emote_message_3p_target // 'Urist McShitter does a flip at Urist McTarget!'
var/emote_message_synthetic_1p_target // First person targeted message for robits.
var/emote_message_synthetic_3p_target // Third person targeted message for robits.
var/emote_message_radio // A message to send over the radio if one picks up this emote.
var/emote_message_radio_synthetic // As above, but for synthetics.
var/emote_message_muffled // A message to show if the emote is audible and the user is muzzled.
var/list/emote_sound // A sound for the emote to play.
// Can either be a single sound, a list of sounds to pick from, or an
// associative array of gender to single sounds/a list of sounds.
var/list/emote_sound_synthetic // As above, but used when check_synthetic() is true.
var/emote_volume = 50 // Volume of sound to play.
var/emote_volume_synthetic = 50 // As above, but used when check_synthetic() is true.
var/message_type = VISIBLE_MESSAGE // Audible/visual flag
var/check_restraints // Can this emote be used while restrained?
var/check_range // falsy, or a range outside which the emote will not work
var/conscious = TRUE // Do we need to be awake to emote this?
var/emote_range = 0 // If >0, restricts emote visibility to viewers within range.
/decl/emote/proc/get_emote_message_1p(var/atom/user, var/atom/target, var/extra_params)
if(target)
if(emote_message_synthetic_1p_target && check_synthetic(user))
return emote_message_synthetic_1p_target
return emote_message_1p_target
if(emote_message_synthetic_1p && check_synthetic(user))
return emote_message_synthetic_1p
return emote_message_1p
/decl/emote/proc/get_emote_message_3p(var/atom/user, var/atom/target, var/extra_params)
if(target)
if(emote_message_synthetic_3p_target && check_synthetic(user))
return emote_message_synthetic_3p_target
return emote_message_3p_target
if(emote_message_synthetic_3p && check_synthetic(user))
return emote_message_synthetic_3p
return emote_message_3p
/decl/emote/proc/get_emote_sound(var/atom/user)
if(check_synthetic(user) && emote_sound_synthetic)
return list(
"sound" = emote_sound_synthetic,
"vol" = emote_volume_synthetic
)
if(emote_sound)
return list(
"sound" = emote_sound,
"vol" = emote_volume
)
/decl/emote/proc/do_emote(var/atom/user, var/extra_params)
if(ismob(user) && check_restraints)
var/mob/M = user
if(M.restrained())
to_chat(user, SPAN_WARNING("You are restrained and cannot do that."))
return
var/atom/target
if(can_target() && extra_params)
extra_params = lowertext(extra_params)
for(var/atom/thing in view(user))
if(extra_params == lowertext(thing.name))
target = thing
break
if(target && target != user && check_range)
if (get_dist(user, target) > check_range)
to_chat(user, SPAN_WARNING("\The [target] is too far away."))
return
var/use_1p = get_emote_message_1p(user, target, extra_params)
if(use_1p)
if(target)
use_1p = replace_target_tokens(use_1p, target)
use_1p = "<span class='emote'>[capitalize(replace_user_tokens(use_1p, user))]</span>"
var/use_3p = get_emote_message_3p(user, target, extra_params)
if(use_3p)
if(target)
use_3p = replace_target_tokens(use_3p, target)
use_3p = "<span class='emote'><b>\The [user]</b> [replace_user_tokens(use_3p, user)]</span>"
var/use_radio = get_radio_message(user)
if(use_radio)
if(target)
use_radio = replace_target_tokens(use_radio, target)
use_radio = replace_user_tokens(use_radio, user)
var/use_range = emote_range
if (!use_range)
use_range = world.view
if(ismob(user))
var/mob/M = user
if(message_type == AUDIBLE_MESSAGE)
if(isliving(user))
var/mob/living/L = user
if(L.silent)
M.visible_message(message = "[user] opens their mouth silently!", self_message = "You cannot say anything!", blind_message = emote_message_impaired)
return
else
M.audible_message(message = use_3p, self_message = use_1p, deaf_message = emote_message_impaired, hearing_distance = use_range, radio_message = use_radio)
else
M.visible_message(message = use_3p, self_message = use_1p, blind_message = emote_message_impaired, range = use_range)
do_extra(user, target)
do_sound(user)
/decl/emote/proc/replace_target_tokens(var/msg, var/atom/target)
. = msg
if(istype(target))
var/datum/gender/target_gender = gender_datums[target.get_visible_gender()]
. = replacetext(., "TARGET_THEM", target_gender.him)
. = replacetext(., "TARGET_THEIR", target_gender.his)
. = replacetext(., "TARGET_SELF", target_gender.himself)
. = replacetext(., "TARGET", "<b>\the [target]</b>")
/decl/emote/proc/replace_user_tokens(var/msg, var/atom/user)
. = msg
if(istype(user))
var/datum/gender/user_gender = gender_datums[user.get_visible_gender()]
. = replacetext(., "USER_THEM", user_gender.him)
. = replacetext(., "USER_THEIR", user_gender.his)
. = replacetext(., "USER_SELF", user_gender.himself)
. = replacetext(., "USER", "<b>\the [user]</b>")
/decl/emote/proc/get_radio_message(var/atom/user)
if(emote_message_radio_synthetic && check_synthetic(user))
return emote_message_radio_synthetic
return emote_message_radio
/decl/emote/proc/do_extra(var/atom/user, var/atom/target)
return
/decl/emote/proc/do_sound(var/atom/user)
var/list/use_sound = get_emote_sound(user)
if(!islist(use_sound) || length(use_sound) < 2)
return
var/sound_to_play = use_sound["sound"]
if(!sound_to_play)
return
if(islist(sound_to_play))
if(sound_to_play[user.gender])
sound_to_play = sound_to_play[user.gender]
if(islist(sound_to_play) && length(sound_to_play))
sound_to_play = pick(sound_to_play)
if(sound_to_play)
playsound(user.loc, sound_to_play, use_sound["vol"], 0, preference = /datum/client_preference/emote_noises) //VOREStation Add - Preference
/decl/emote/proc/check_user(var/atom/user)
return TRUE
/decl/emote/proc/can_target()
return (emote_message_1p_target || emote_message_3p_target)
/decl/emote/dd_SortValue()
return key
/decl/emote/proc/check_synthetic(var/mob/living/user)
. = istype(user) && user.isSynthetic()
if(!. && ishuman(user) && message_type == AUDIBLE_MESSAGE)
var/mob/living/carbon/human/H = user
if(H.should_have_organ(O_LUNGS))
var/obj/item/organ/internal/lungs/L = H.internal_organs_by_name[O_LUNGS]
if(L && L.robotic == 2) //Hard-coded to 2, incase we add lifelike robotic lungs
. = TRUE

View File

@@ -0,0 +1,183 @@
/mob/proc/can_emote(var/emote_type)
return (stat == CONSCIOUS)
/mob/living/can_emote(var/emote_type)
return (..() && !(silent && emote_type == AUDIBLE_MESSAGE))
/mob/proc/emote(var/act, var/m_type, var/message)
set waitfor = FALSE
// s-s-snowflake
if(src.stat == DEAD && act != "deathgasp")
return
if(usr == src) //client-called emote
if (client && (client.prefs.muted & MUTE_IC))
to_chat(src, "<span class='warning'>You cannot send IC messages (muted).</span>")
return
if(act == "help")
to_chat(src,"<b>Usable emotes:</b> [english_list(usable_emotes)].")
return
if(!can_emote(m_type))
to_chat(src, SPAN_WARNING("You cannot currently [m_type == AUDIBLE_MESSAGE ? "audibly" : "visually"] emote!"))
return
if(act == "me")
return custom_emote(m_type, message)
if(act == "custom")
if(!message)
message = sanitize_or_reflect(input(src,"Choose an emote to display.") as text|null, src) //VOREStation Edit - Reflect too long messages, within reason
if(!message)
return
if (!m_type)
if(alert(src, "Is this an audible emote?", "Emote", "Yes", "No") == "No")
m_type = VISIBLE_MESSAGE
else
m_type = AUDIBLE_MESSAGE
return custom_emote(m_type, message)
var/splitpoint = findtext(act, " ")
if(splitpoint > 0)
var/tempstr = act
act = copytext(tempstr,1,splitpoint)
message = copytext(tempstr,splitpoint+1,0)
//VOREStation Add - NIF soulcatcher shortcuts
if(act == "nsay")
return nsay(message)
if(act == "nme")
return nme(message)
//VOREStation Add End
var/decl/emote/use_emote = usable_emotes[act]
if(!use_emote)
to_chat(src, SPAN_WARNING("Unknown emote '[act]'. Type <b>say *help</b> for a list of usable emotes."))
return
if(m_type != use_emote.message_type && use_emote.conscious && stat != CONSCIOUS)
return
if(use_emote.message_type == AUDIBLE_MESSAGE && is_muzzled())
audible_message("<b>\The [src]</b> [use_emote.emote_message_muffled || "makes a muffled sound."]")
return
else
use_emote.do_emote(src, message)
for (var/obj/item/weapon/implant/I in src)
if (I.implanted)
I.trigger(act, src)
/mob/proc/format_emote(var/emoter = null, var/message = null)
var/pretext
var/subtext
var/nametext
var/end_char
var/start_char
var/name_anchor
if(!message || !emoter)
return
message = html_decode(message)
name_anchor = findtext(message, "*")
if(name_anchor > 0) // User supplied emote with visible_emote token (default ^)
pretext = copytext(message, 1, name_anchor)
subtext = copytext(message, name_anchor + 1, length(message) + 1)
else
// No token. Just the emote as usual.
subtext = message
// Oh shit, we got this far! Let's see... did the user attempt to use more than one token?
if(findtext(subtext, "*"))
// abort abort!
to_chat(emoter, SPAN_WARNING("You may use only one \"["*"]\" symbol in your emote."))
return
if(pretext)
// Add a space at the end if we didn't already supply one.
end_char = copytext(pretext, length(pretext), length(pretext) + 1)
if(end_char != " ")
pretext += " "
// Grab the last character of the emote message.
end_char = copytext(subtext, length(subtext), length(subtext) + 1)
if(!(end_char in list(".", "?", "!", "\"", "-", "~"))) // gotta include ~ for all you fucking weebs
// No punctuation supplied. Tack a period on the end.
subtext += "."
// Add a space to the subtext, unless it begins with an apostrophe or comma.
if(subtext != ".")
// First, let's get rid of any existing space, to account for sloppy emoters ("X, ^ , Y")
subtext = trim_left(subtext)
start_char = copytext(subtext, 1, 2)
if(start_char != "," && start_char != "'")
subtext = " " + subtext
pretext = capitalize(html_encode(pretext))
nametext = html_encode(nametext)
subtext = html_encode(subtext)
// Store the player's name in a nice bold, naturalement
nametext = "<B>[emoter]</B>"
return pretext + nametext + subtext
/mob/proc/custom_emote(var/m_type = VISIBLE_MESSAGE, var/message, var/range = world.view)
if((usr && stat) || (!use_me && usr == src))
to_chat(src, "You are unable to emote.")
return
var/input
if(!message)
input = sanitize(input(src,"Choose an emote to display.") as text|null)
else
input = message
if(input)
message = format_emote(src, message)
else
return
if(input)
log_emote(message,src) //Log before we add junk
message = "<span class='emote'><B>[src]</B> [input]</span>"
else
return
if(message)
message = encode_html_emphasis(message)
// Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
var/turf/T = get_turf(src)
if(!T) return
var/list/in_range = get_mobs_and_objs_in_view_fast(T,range,2,remote_ghosts = client ? TRUE : FALSE)
var/list/m_viewers = in_range["mobs"]
var/list/o_viewers = in_range["objs"]
for(var/mob in m_viewers)
var/mob/M = mob
spawn(0) // It's possible that it could be deleted in the meantime, or that it runtimes.
if(M)
if(isobserver(M))
message = "<span class='emote'><B>[src]</B> ([ghost_follow_link(src, M)]) [input]</span>"
M.show_message(message, m_type)
for(var/obj in o_viewers)
var/obj/O = obj
spawn(0)
if(O)
O.see_emote(src, message, m_type)
// Specific mob type exceptions below.
/mob/living/silicon/ai/emote(var/act, var/type, var/message)
var/obj/machinery/hologram/holopad/T = src.holo
if(T && T.masters[src]) //Is the AI using a holopad?
src.holopad_emote(message)
else //Emote normally, then.
..()