Files
Yogstation/code/datums/emotes.dm
13spacemen 73ce93fa95 Vox Race (#21275)
* add dna blocks
isvox helper
species_vox define
sprite accessory global lists
vox emote support
species sprite system preliminary
species traits in prefs is a list instead of single trait
system for restricting equipping clothing from a species
vox pidgin language
vox sprite accessories
is_dimorphic species var for species without gender diff in body icon
vox species
icon render key only considers gender for dimorphic species
blend mode add support for coloring sprite accessories and hair
haircolor and facehaircolor species traits
vox bodyparts
vox organs
added to roundstart races
added some icons

* remove vox eyes option
add more vox info to dna procs
started renaming spines to tail markings
tail markings working

* vox hair icon gen in handle_hair proc
used facehaircolor trait

* add 2nd mutant color
allow blacklisting prefs from species
add vox custom named prefs
add system for multi-bodyzone sprite accessories
add vox body markings
add preliminary "icon variants" system for limbs with different sprites

* vox V blue blood type
add KFV, KFV dog fashion
paradise flag items
voxpox graffiti
vox plushie
vox skin
vox nitrogen tanks
items on fire can have a custom fire overlay
vox blood packs
highlander support for vox
vox breathing class
vox breath masks
vox meat
vox cortical stack (brain)
vox quill emote, vox scream is shriek
vox species perks
vox species info
vox scream sneeze cough sounds
on husk and on husk cure procs
vox organs dont decay
vox lungs breathe n2
vox tongue shrieks sometimes when speaking
added many icons like clothing

* lungs work properly
fixed breath alerts not working

* colortone proc grayscale arg
vox generates its own husk icon on the fly

* more husking improvements

* add husk color for dynamic husk icons
mutant bodyparts can be husked

* arg for drawing blood in husk image gen

* vox bodies replaced by skin tone
more work on limb icon variants, static sprite parts
vox tgui skin tone dropdown

* uncapitalized vox tail types

* update skin tone and tail procs

* added some vox specific underwear

* improved skin tone and limb variant code

* vox underwear pref icons

* sprite sheets system in icon code

* many sprites added

* changesource flags
icons for vox meat vox skin, change kfv recipe due to limbs not having icons and breaking recipe code

* done underwear and undershirts

* name procs

* hair, facial hair progress, renamed hair to quills

* all hair and facial hair in

* add n2 pref, big n2 tank, suicide messages, butt sprites, tail wont update skin tone unless vox is the original owner, survival box, cropped hair fix, removed useless species_fit var

* flag renames, add no vox allowed sign, default n2 tank is specialized

* vox heart sprite, lang sprite, some lore

* vox armalis scream added until armalis exist

* added bay vox clothes, disabled armalis scream for regular vox, added more sprites

* fix species specific icons, fix other sprites

* rearrange clothing, add scrap armor, crimson tail enabled

* all colored jumpsuits done

* renamed a ton of vox icon states

* more sprite work

* more sprite sheet stuff, if no species icon fall back to original icon

* color defines, code cleanup, commented out paradise race flags, get rid of pointless sprite sheets null

* attempted repairing chest
repaired crimson tail

* fixed crimson tails

* more sprite stuff

* less pointless sprite sheets definitions, singlelined sprite sheets definitions

* moved all undershirts to one file

* head sprite stuff

* fixed tail sprite errors
added all vox tails
fixed tail markings south dir and positions

* completed all heads

* all legs done

* completed all arms

* completed all chest sprites

* added classic vox sprite
added all skin tones/tails
slight change to vox eye static code

* vox organ and tail stuff

* hair gradient support, eyes static moved to species, order prefix for prefs, supplemental quill colors, tears sprite

* undid random newlines and spaces, brain uses alt brain name in some text, survival box replacement based on species, species can have multiple attack verbs

* added a ton of vox clothing sprites, species clothing defines, vox can choose jumpsuit style again, vox cream pie overlay

* moth species define, removed redundant survival box code, lazy fetch vox icon for tgui species menu, fixed eye icon errors, checks for vox tail type, icon render key considers static sprite parts, rewrote some limb icon code, add KFV inhands and head clothing sprites, ling space helmet and human head hat have separate sprites

* more code cleanup

* vox organs no longer ORGAN_ROBOTIC, changed some descs of organs

* mmi proper cortical stack sprite, made some references to "brain" consider alt brain name, added undecaying vox appendix, tweaked organ names and desc

* add vox bird traumas, vox hide to maint loot, vox plushie to crate and arcade and random plushie, vox hide export datum, added all flags to gift vendor,

* cold resist is back, removed burn and stun mods
fix paths
language tweak

* basic hair color and style changing support

* vox med jumpsuit crosses are blue

* correct vox skin tone colors in tgui, green renamed to lime, delete preview sprites, add mutation toxin, regen icons on changing species, add vox to heads of staff except captain

* species sprite support for chameleon item

* fixed vox prefs, telomeres traits check for noclone, add mask pref for vox, vox breath mask is non adjustable, fix vox heart icon state, fix vox appendix iconstate, fix sprite sheets, fix cortical stack name, vox not allowed to be hop

* sorted and renamed many icon states

* lizard robe correctly in uniforms, sprited new signaltech vox jumpsuit, robo satchel back sprite, renamed some icon states

* vox blood color defines, maint loot, traumas

* added artist, recovery, clerk uniforms by Falcon2346 from /vg/station

mesonhealth by me

maint loot, vox lang tweaks, limbgrower vox fixes, species box null list fix, undergarments species sprite fix

* vox shaped bloody mob overlays, more use of species defines, species sprites based on id instead of name, human footprint sprite considers species_id of legs, update_icons.dm more based on specific bodyparts

* new winterhood, labcoat, chem labcoat, atmos, engine, rsecurity, paramedic, robotics, chief engineer | vox sprites by falcon2346

* vox gene, cmo, green, tox, vir, robo labcoats done by me

* rebase errors fix

* added medical labcoat by falcon2346
brig phys labcoat and mining medic labcoat by me

* redid signaltech jumpsuit based on falcon's atmos tech jumpsuit

* vox gags support, remove unneeded sprite sheet code and fix oversights

* emp severity fix, null checks, fixed golem head/chest sprites, added missing vox hardsuits and new TG vox biosuits by paradise and me

* modularized some code

* suicide global list, list init optimizations

* reverse unnecessary file changes, whitespace, modularization

* added new cardborg head vox sprite, better vox magboots sprites, green glasses, mob can equip proc fix

* increased pref window height by 70px

* repath gas reagents, fix vox->ipc runtime, remove custom cough/sneeze code in favor of added tg versions

* misc minor edits

* removed var/is_husked from bodyparts
more checks before doing husk coloration

* modified eyes_missing sprites for vox to be similar to blue vox blood
added dark pixels (rgb edge + #080808) to vox eye sockets to prevent transparency weirdness such as seeing turfs through head sprite
commented some vars and procs, removed redundant parts_to_husk list
2024-06-18 06:21:54 -05:00

255 lines
8.4 KiB
Plaintext

#define EMOTE_VISIBLE 1
#define EMOTE_AUDIBLE 2
/datum/emote
/// What calls the emote.
var/key = ""
/// This will also call the emote.
var/key_third_person = ""
/// Message displayed when emote is used.
var/message = ""
/// Message displayed if the user is a mime.
var/message_mime = ""
/// Message displayed if the user is a grown alien.
var/message_alien = ""
/// Message displayed if the user is an alien larva.
var/message_larva = ""
/// Message displayed if the user is a robot.
var/message_robot = ""
/// Message displayed if the user is an AI.
var/message_AI = ""
/// Message displayed if the user is a monkey.
var/message_monkey = ""
/// Message to display if the user is an IPC
var/message_ipc = ""
/// Message to display if the user is a simple_animal or basic mob.
var/message_simple = ""
/// Message with %t at the end to allow adding params to the message, like for mobs doing an emote relatively to something else.
var/message_param = ""
/// Whether the emote is visible and/or audible bitflag
var/emote_type = EMOTE_VISIBLE
/// Checks if the mob can use its hands before performing the emote.
var/hands_use_check = FALSE
/// Will only work if the emote is EMOTE_AUDIBLE.
var/muzzle_ignore = FALSE
/// Types that are allowed to use that emote.
var/list/mob_type_allowed_typecache = /mob
/// Types that are NOT allowed to use that emote.
var/list/mob_type_blacklist_typecache
/// Types that can use this emote regardless of their state.
var/list/mob_type_ignore_stat_typecache
/// In which state can you use this emote? (Check stat.dm for a full list of them)
var/stat_allowed = CONSCIOUS
/// Sound to play when emote is called.
var/sound
/// Used for the honk borg emote.
var/vary = FALSE
/// Can only code call this event instead of the player.
var/only_forced_audio = FALSE
/// The cooldown between the uses of the emote.
var/cooldown = 0.8 SECONDS
/datum/emote/New()
if (ispath(mob_type_allowed_typecache))
switch (mob_type_allowed_typecache)
if (/mob)
mob_type_allowed_typecache = GLOB.typecache_mob
if (/mob/living)
mob_type_allowed_typecache = GLOB.typecache_living
else
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)
else
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)
mob_type_blacklist_typecache = typecacheof(mob_type_blacklist_typecache)
mob_type_ignore_stat_typecache = typecacheof(mob_type_ignore_stat_typecache)
/datum/emote/proc/run_emote(mob/user, params, type_override, intentional = FALSE)
. = TRUE
if(!can_run_emote(user, TRUE, intentional))
return FALSE
var/msg = select_message_type(user, intentional)
if(params && message_param)
msg = select_param(user, params)
msg = replace_pronoun(user, msg)
if(isliving(user))
var/mob/living/L = user
for(var/obj/item/implant/I in L.implants)
I.trigger(key, L)
if(!msg)
return
user.log_message(msg, LOG_EMOTE)
var/dchatmsg = "<b>[user]</b> [msg]"
var/tmp_sound = get_sound(user)
if(tmp_sound && should_play_sound(user, intentional) && (!only_forced_audio || !intentional))
playsound(user, tmp_sound, 50, vary)
for(var/mob/M in GLOB.dead_mob_list)
if(!M.client || isnewplayer(M))
continue
var/T = get_turf(user)
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null)))
M.show_message("[FOLLOW_LINK(M, user)] [dchatmsg]")
if(emote_type == EMOTE_AUDIBLE)
user.audible_message(msg, audible_message_flags = EMOTE_MESSAGE)
else
user.visible_message(msg, visible_message_flags = EMOTE_MESSAGE)
/// For handling emote cooldown, return true to allow the emote to happen
/datum/emote/proc/check_cooldown(mob/user, intentional, update=TRUE, is_keybind = FALSE)
if(!intentional)
return TRUE
var/cd = cooldown
if (is_keybind)
cd = 2 SECONDS // cooldown when used as a keybind
if(user.emotes_used && user.emotes_used[src] + cd > world.time)
return FALSE
if(!update)
return TRUE
if(!user.emotes_used)
user.emotes_used = list()
user.emotes_used[src] = world.time
return TRUE
/datum/emote/proc/get_sound(mob/living/user)
return sound //by default just return this var.
/datum/emote/proc/replace_pronoun(mob/user, message)
if(findtext(message, "their"))
message = replacetext(message, "their", user.p_their())
if(findtext(message, "them"))
message = replacetext(message, "them", user.p_them())
if(findtext(message, "%s"))
message = replacetext(message, "%s", user.p_s())
return message
/datum/emote/proc/select_message_type(mob/user, intentional)
. = message
if(!muzzle_ignore && user.is_muzzled() && emote_type == EMOTE_AUDIBLE)
return "makes a [pick("strong ", "weak ", "")]noise."
if(user.mind && user.mind.miming && message_mime)
. = message_mime
if(isalienadult(user) && message_alien)
. = message_alien
else if(islarva(user) && message_larva)
. = message_larva
else if(iscyborg(user) && message_robot)
. = message_robot
else if(isAI(user) && message_AI)
. = message_AI
else if(ismonkey(user) && message_monkey)
. = message_monkey
else if(isipc(user) && message_ipc)
. = message_ipc
else if(isvox(user) && message_vox)
. = message_vox
else if(isanimal(user) && message_simple)
. = message_simple
/datum/emote/proc/select_param(mob/user, params)
return replacetext(message_param, "%t", params)
/**
* Check to see if the user is allowed to run the emote.
*
* Arguments:
* * user - Person that is trying to send the emote.
* * status_check - Bool that says whether we should check their stat or not.
* * intentional - Bool that says whether the emote was forced (FALSE) or not (TRUE).
*
* Returns a bool about whether or not the user can run the emote.
*/
/datum/emote/proc/can_run_emote(mob/user, status_check = TRUE, intentional = FALSE)
if(!is_type_in_typecache(user, mob_type_allowed_typecache))
return FALSE
if(is_type_in_typecache(user, mob_type_blacklist_typecache))
return FALSE
if(status_check && !is_type_in_typecache(user, mob_type_ignore_stat_typecache))
if(user.stat > stat_allowed)
if(!intentional)
return FALSE
switch(user.stat)
if(SOFT_CRIT)
to_chat(user, span_notice("You cannot [key] while in a critical condition."))
if(UNCONSCIOUS)
to_chat(user, span_notice("You cannot [key] while unconscious."))
if(DEAD)
to_chat(user, span_notice("You cannot [key] while dead."))
return FALSE
if(hands_use_check && HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
if(!intentional)
return FALSE
to_chat(user, span_warning("You cannot use your hands to [key] right now!"))
return FALSE
if(HAS_TRAIT(user, TRAIT_EMOTEMUTE))
return FALSE
return TRUE
/**
* Check to see if the user should play a sound when performing the emote.
*
* Arguments:
* * user - Person that is doing the emote.
* * intentional - Bool that says whether the emote was forced (FALSE) or not (TRUE).
*
* Returns a bool about whether or not the user should play a sound when performing the emote.
*/
/datum/emote/proc/should_play_sound(mob/user, intentional = FALSE)
if(emote_type & EMOTE_AUDIBLE && !muzzle_ignore)
if(user.is_muzzled())
return FALSE
if(HAS_TRAIT(user, TRAIT_MUTE))
return FALSE
if(ishuman(user))
var/mob/living/carbon/human/loud_mouth = user
if(HAS_MIND_TRAIT(loud_mouth, TRAIT_MIMING)) // vow of silence prevents outloud noises
return FALSE
if(!loud_mouth.getorganslot(ORGAN_SLOT_TONGUE))
return FALSE
if(only_forced_audio && intentional)
return FALSE
return TRUE
/**
* Allows the intrepid coder to send a basic emote
* Takes text as input, sends it out to those who need to know after some light parsing
* If you need something more complex, make it into a datum emote
* Arguments:
* * text - The text to send out
*/
/mob/proc/manual_emote(text) //Just override the song and dance
. = TRUE
if(findtext(text, "their"))
text = replacetext(text, "their", p_their())
if(findtext(text, "them"))
text = replacetext(text, "them", p_them())
if(findtext(text, "%s"))
text = replacetext(text, "%s", p_s())
if(stat != CONSCIOUS)
return
if(!text)
CRASH("Someone passed nothing to manual_emote(), fix it")
log_message(text, LOG_EMOTE)
var/ghost_text = "<b>[src]</b> " + text //Sin I know
for(var/mob/M in GLOB.dead_mob_list)
if(!M.client || isnewplayer(M))
continue
var/T = get_turf(src)
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null)))
M.show_message("[FOLLOW_LINK(M, src)] [ghost_text]")
visible_message(text, visible_message_flags = EMOTE_MESSAGE)