mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-21 03:55:05 +01:00
Datumized Emotes (#17544)
* Add raw tg emote datums * Some more initial implementation * First (big) commit * More reworks, most emotes seem to work but cooldowns are weird * Add the remaining emote species * Add simple mobs * Update defines, add more comments * Remove unnecessary intentional calls * Fix some bugs, add more functionality - Silicon mobs/bots can't use all the living emotes - Sound volume can now be specified for emotes - Added a define for emotes to not go thru runechat - Reorganized some emotes - Some human emotes that need breath will gasp - IPCs can beep boop - Restore power warn for robits - Sneezing and coughing have sound effects * Fixes emote species separation not working in *help * Reorganize emotes based on what's available on paradise * mouthful mode * Update implants to use emote signals * Update species whitelist to use a typecache * Cleanups * More small changes - Remove old extraneous typecache - Reconfigure drask emotes - Make all mime emotes visible (since they're silent) * Remove old emote functions * Update emote sounds, volume * Rework more emotes into EMOTE_VISIBLE * *rumble* * More slight testing and cleanup - Drop audio emote cooldown from 10 to 5 seconds - Change clapping behaivor slightly, putting it into run_emote - Update some emote flags here and there - Fix up johnny, though remind me why this one exists? * Fix indentation, missing typecast * fix some returns * More review * Rename emote files * Add'l review * Even more emote fixes! - Move defines out into an emote define file - Integrate audio and general emote cooldowns - change some 1 and 2 into visible/audible - Try to fix monkey screech * Add ability for admins to mute users' emotes. * Rename cooldowns, add general mob emote cooldown. * Fix flip not always geting the right message * Add some emote target handling, docs * Fix admin rights, indentation * Update emote.dm set default mode to ANY * General implant fixes - The way implant triggers are handled is now improved, with separate checks for death and emotes instead of just checking deathgasp. - Implants can choose to be triggered for the first death or for every death. - Voice of God play dead now activates sad trombone read: voice of god can now no longer lowtiergod nukies * Bunch of other changes and bugfixes - Adds number flag for behavior - Reworks how muzzling/vocalizing emotes works - Breaks out sound effects - Drops cooldown to 1.5s * Fix people being able to snore/nightmare while awake. * Bump paralysis on living emotes * First review pass * Clean up implants (while we're here) and fix compile errors * in living error * More outstanding review fixes * use more isx() checks * Add pre-emote signal, try_run_emote() * Prevent silicons from playing their deathgasp multiple times * Add emote postfix behavior for adding parameters to non-message params. Also adds a signal to intercept emote actions. * Fix linter complaints * Remove new player checks on GLOB.dead_mob_list * Fix species emotes not being distinguished, remove weird legacy code * monkey ball * better docs == better code * Fix audio cooldown, silicon emotes * Fix ghost emotes (don't worry they're staying) * Restore spin to 2 seconds * oh johnny boy * Make fainting last two seconds instead of .2 seconds * Remove extra highfive message * Tick friendly emotes * Fix up friendly emotes, ghost emotes * Add some emote message safeguards, prevent flip from showing twice * Fix ghost vision message format * Fix hands_use_check on non-carbon mobs * Bring emotes in line with say re. oxyloss * Add option for death implants to not trigger on gib * Try adding some unit testing * Include emote unit tests * More attempts at unit testing * More attempts at unit testing? * forget it this is fine * Housekeeping * Little bit more * Remove extra bolding from ghostsight emotes * More sanity checks, fix snore * Remove stack trace when unintentional emote fails * Update code/modules/mob/living/silicon/silicon_emote.dm oops Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> * More implant cleanups * Oh I missed this * Silence wagging, more review fixes * Oops 2 * ensure everything can swear * High-five fixes and status effect stuff - Adds new on_timeout() function that gets triggered when a status effect expires - Fixes up passing arguments to status effects - Ensures high-five explosions don't kill the wizards * More review stuff - Add a stat to text to make things easier - Make it harder to delete emotes - BIG DANGER - pose can no longer be set while unconscious * Remove extra high five logic, godmode changes * forgor * Fix gasp not working * Update docs for good measure * Some review and custom emote fixes * Fixes death alarms being broken * Better handle stat_allowed, more review comments. * ..() conventions * This is why unit tests are nice * Remove drone snowflake emote stuff * Linting * No more flipping on the ground * Snap doesn't require hands free * Does it make complete sense? no, but it's Fun * Apply suggestions from code review Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> * Fix revenant messages, power warning * epic webedit fail, laugh at this user Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
This commit is contained in:
@@ -141,6 +141,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_PRAY]'><font color='[check_mute(M.client.ckey, MUTE_PRAY) ? "red" : "#6685f5"]'>PRAY</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ADMINHELP]'><font color='[check_mute(M.client.ckey, MUTE_ADMINHELP) ? "red" : "#6685f5"]'>ADMINHELP</font></a> |
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_DEADCHAT]'><font color='[check_mute(M.client.ckey, MUTE_DEADCHAT) ?" red" : "#6685f5"]'>DEADCHAT</font></a>]
|
||||
<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_EMOTE]'><font color='[check_mute(M.client.ckey, MUTE_EMOTE) ?" red" : "#6685f5"]'>EMOTE</font></a>]
|
||||
(<A href='?_src_=holder;mute=[M.UID()];mute_type=[MUTE_ALL]'><font color='[check_mute(M.client.ckey, MUTE_ALL) ? "red" : "#6685f5"]'>toggle all</font></a>)
|
||||
"}
|
||||
|
||||
|
||||
@@ -222,13 +222,22 @@
|
||||
var/mute_string
|
||||
|
||||
switch(mute_type)
|
||||
if(MUTE_IC) mute_string = "IC (say and emote)"
|
||||
if(MUTE_OOC) mute_string = "OOC"
|
||||
if(MUTE_PRAY) mute_string = "pray"
|
||||
if(MUTE_ADMINHELP) mute_string = "adminhelp, admin PM and ASAY"
|
||||
if(MUTE_DEADCHAT) mute_string = "deadchat and DSAY"
|
||||
if(MUTE_ALL) mute_string = "everything"
|
||||
else return
|
||||
if(MUTE_IC)
|
||||
mute_string = "IC (say and emote)"
|
||||
if(MUTE_OOC)
|
||||
mute_string = "OOC"
|
||||
if(MUTE_PRAY)
|
||||
mute_string = "pray"
|
||||
if(MUTE_ADMINHELP)
|
||||
mute_string = "adminhelp, admin PM and ASAY"
|
||||
if(MUTE_DEADCHAT)
|
||||
mute_string = "deadchat and DSAY"
|
||||
if(MUTE_EMOTE)
|
||||
mute_string = "emote"
|
||||
if(MUTE_ALL)
|
||||
mute_string = "everything"
|
||||
else
|
||||
return
|
||||
|
||||
if(automute)
|
||||
muteunmute = "auto-muted"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
name = "exile implant"
|
||||
desc = "Prevents you from returning from away missions"
|
||||
origin_tech = "materials=2;biotech=3;magnets=2;bluespace=3"
|
||||
activated = 0
|
||||
activated = IMPLANT_ACTIVATED_PASSIVE
|
||||
|
||||
/obj/item/implant/exile/get_data()
|
||||
var/dat = {"<b>Implant Specifications:</b><BR>
|
||||
|
||||
@@ -43,8 +43,7 @@
|
||||
nightmare()
|
||||
if(ishuman(src))
|
||||
if(prob(10))
|
||||
custom_emote(1,"writhes in [p_their()] sleep.")
|
||||
dir = pick(GLOB.cardinal)
|
||||
emote("nightmare")
|
||||
|
||||
/mob/living/carbon/proc/experience_dream(dream_image, isNightmare)
|
||||
dreaming--
|
||||
|
||||
@@ -6,28 +6,6 @@
|
||||
|
||||
return say_dead(message)
|
||||
|
||||
|
||||
/mob/dead/observer/emote(act, type, message, force)
|
||||
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
if(act != "me")
|
||||
return
|
||||
|
||||
log_ghostemote(message, src)
|
||||
|
||||
if(src.client)
|
||||
if(check_mute(client.ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot emote in deadchat (muted).</span>")
|
||||
return
|
||||
|
||||
if(src.client.handle_spam_prevention(message, MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
. = src.emote_dead(message)
|
||||
|
||||
/mob/dead/observer/handle_track(message, verb = "says", mob/speaker = null, speaker_name, atom/follow_target, hard_to_hear)
|
||||
return "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
|
||||
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
#define EMOTE_COOLDOWN 20 //Time in deciseconds that the cooldown lasts
|
||||
|
||||
//Emote Cooldown System (it's so simple!)
|
||||
/mob/proc/handle_emote_CD(cooldown = EMOTE_COOLDOWN)
|
||||
if(emote_cd == 3) //Spam those emotes
|
||||
return FALSE
|
||||
if(emote_cd == 2) // Cooldown emotes were disabled by an admin, prevent use
|
||||
return TRUE
|
||||
if(emote_cd == 1) // Already on CD, prevent use
|
||||
return TRUE
|
||||
|
||||
emote_cd = TRUE // Starting cooldown
|
||||
spawn(cooldown)
|
||||
if(emote_cd == 2)
|
||||
return // Don't reset if cooldown emotes were disabled by an admin during the cooldown
|
||||
emote_cd = FALSE // Cooldown complete, ready for more!
|
||||
return FALSE // Proceed with emote
|
||||
|
||||
//--FalseIncarnate
|
||||
|
||||
/mob/proc/handle_emote_param(target, not_self, vicinity, return_mob) //Only returns not null if the target param is valid.
|
||||
var/view_vicinity = vicinity ? vicinity : null //not_self means we'll only return if target is valid and not us
|
||||
if(target) //vicinity is the distance passed to the view proc.
|
||||
for(var/mob/A in view(view_vicinity, null)) //if set, return_mob will cause this proc to return the mob instead of just its name if the target is valid.
|
||||
if(target == A.name && (!not_self || (not_self && target != name)))
|
||||
if(return_mob)
|
||||
return A
|
||||
else
|
||||
return target
|
||||
|
||||
// All mobs should have custom emote, really..
|
||||
/mob/proc/custom_emote(m_type=EMOTE_VISUAL, message = null)
|
||||
if(stat || !use_me && usr == src)
|
||||
if(usr)
|
||||
to_chat(usr, "You are unable to emote.")
|
||||
return
|
||||
var/muzzled = is_muzzled()
|
||||
if(muzzled)
|
||||
var/obj/item/clothing/mask/muzzle/M = wear_mask
|
||||
if(m_type == EMOTE_SOUND && M.mute >= MUZZLE_MUTE_MUFFLE)
|
||||
return //Not all muzzles block sound
|
||||
if(m_type == EMOTE_SOUND && !can_speak())
|
||||
return
|
||||
|
||||
var/input
|
||||
if(!message)
|
||||
input = sanitize(copytext(input(src,"Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN))
|
||||
else
|
||||
input = message
|
||||
if(input)
|
||||
message = "<B>[src]</B> [input]"
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
if(message)
|
||||
log_emote(message, src)
|
||||
if(isliving(src)) //isliving because these are defined on the mob/living level not mob
|
||||
var/mob/living/L = src
|
||||
L.say_log += "EMOTE: [input]" //say log too so it is easier on admins instead of having to merge the two with timestamps etc
|
||||
L.emote_log += input //emote only log if an admin wants to search just for emotes they don't have to sift through the say
|
||||
create_log(EMOTE_LOG, input) // TODO after #13047: Include the channel
|
||||
// Hearing gasp and such every five seconds is not good emotes were not global for a reason.
|
||||
// Maybe some people are okay with that.
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(findtext(message, " snores.")) //Because we have so many sleeping people.
|
||||
break
|
||||
|
||||
if(isobserver(M) && M.get_preference(PREFTOGGLE_CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
// Type 1 (Visual) emotes are sent to anyone in view of the item
|
||||
if(m_type & EMOTE_VISUAL)
|
||||
var/runechat_text = input
|
||||
if(length(input) > 100)
|
||||
runechat_text = "[copytext(input, 1, 101)]..."
|
||||
var/list/can_see = get_mobs_in_view(1,src) //Allows silicon & mmi mobs carried around to see the emotes of the person carrying them around.
|
||||
can_see |= viewers(src,null)
|
||||
for(var/mob/O in can_see)
|
||||
|
||||
if(O.status_flags & PASSEMOTES)
|
||||
|
||||
for(var/obj/item/holder/H in O.contents)
|
||||
H.show_message(message, m_type)
|
||||
|
||||
for(var/mob/living/M in O.contents)
|
||||
M.show_message(message, m_type)
|
||||
|
||||
O.show_message(message, m_type)
|
||||
if(O.client?.prefs.toggles2 & PREFTOGGLE_2_RUNECHAT)
|
||||
O.create_chat_message(src, runechat_text, symbol = RUNECHAT_SYMBOL_EMOTE)
|
||||
|
||||
// Type 2 (Audible) emotes are sent to anyone in hear range
|
||||
// of the *LOCATION* -- this is important for pAIs to be heard
|
||||
else if(m_type & EMOTE_SOUND)
|
||||
for(var/mob/O in get_mobs_in_view(7,src))
|
||||
|
||||
if(O.status_flags & PASSEMOTES)
|
||||
|
||||
for(var/obj/item/holder/H in O.contents)
|
||||
H.show_message(message, m_type)
|
||||
|
||||
for(var/mob/living/M in O.contents)
|
||||
M.show_message(message, m_type)
|
||||
|
||||
O.show_message(message, m_type)
|
||||
|
||||
/mob/proc/emote_dead(message)
|
||||
if(check_mute(client.ckey, MUTE_DEADCHAT))
|
||||
to_chat(src, "<span class='warning'>You cannot send deadchat emotes (muted).</span>")
|
||||
return
|
||||
|
||||
if(!(client.prefs.toggles & PREFTOGGLE_CHAT_DEAD))
|
||||
to_chat(src, "<span class='warning'>You have deadchat muted.</span>")
|
||||
return
|
||||
|
||||
if(!src.client.holder)
|
||||
if(!GLOB.dsay_enabled)
|
||||
to_chat(src, "<span class='warning'>Deadchat is globally muted</span>")
|
||||
return
|
||||
|
||||
|
||||
var/input
|
||||
if(!message)
|
||||
input = sanitize(copytext(input(src, "Choose an emote to display.") as text|null, 1, MAX_MESSAGE_LEN))
|
||||
else
|
||||
input = message
|
||||
|
||||
if(input)
|
||||
message = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <b>[src]</b> [message]</span>"
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
if(message)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(check_rights(R_ADMIN|R_MOD, 0, M) && M.get_preference(PREFTOGGLE_CHAT_DEAD)) // Show the emote to admins/mods
|
||||
to_chat(M, message)
|
||||
|
||||
else if(M.stat == DEAD && M.get_preference(PREFTOGGLE_CHAT_DEAD)) // Show the emote to regular ghosts with deadchat toggled on
|
||||
M.show_message(message, 2)
|
||||
@@ -1,141 +0,0 @@
|
||||
/mob/living/carbon/alien/humanoid/emote(act, m_type = 1, message = null, force)
|
||||
var/param = null
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
// if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
// act = copytext(act,1,length(act)) //seriously who the fuck wrote this
|
||||
var/muzzled = is_muzzled()
|
||||
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
|
||||
//cooldown system handled by /code/modules/mob/emotes.dm
|
||||
switch(act)
|
||||
if("roar")
|
||||
on_CD = handle_emote_CD()
|
||||
if("deathgasp")
|
||||
on_CD = handle_emote_CD()
|
||||
if("hiss")
|
||||
on_CD = handle_emote_CD()
|
||||
if("gnarl")
|
||||
on_CD = handle_emote_CD()
|
||||
if("flip")
|
||||
on_CD = handle_emote_CD()
|
||||
|
||||
if(!force && on_CD == 1)
|
||||
return
|
||||
|
||||
switch(act)
|
||||
|
||||
|
||||
|
||||
if("sign")
|
||||
if(!restrained())
|
||||
var/num = null
|
||||
if(text2num(param))
|
||||
num = "the number [text2num(param)]"
|
||||
if(num)
|
||||
message = "<B>\The [src]</B> signs [num]."
|
||||
m_type = 1
|
||||
if("burp")
|
||||
if(!muzzled)
|
||||
message = "<B>\The [src]</B> burps."
|
||||
m_type = 2
|
||||
if("deathgasp")
|
||||
message = "<B>\The [src]</B> lets out a waning guttural screech, green blood bubbling from its maw..."
|
||||
m_type = 2
|
||||
if("scratch")
|
||||
if(!restrained())
|
||||
message = "<B>\The [src]</B> scratches."
|
||||
m_type = 1
|
||||
if("whimper")
|
||||
if(!muzzled)
|
||||
message = "<B>\The [src]</B> whimpers."
|
||||
m_type = 2
|
||||
if("roar")
|
||||
if(!muzzled)
|
||||
message = "<B>\The [src]</B> roars."
|
||||
m_type = 2
|
||||
if("hiss")
|
||||
if(!muzzled)
|
||||
message = "<B>\The [src]</B> hisses."
|
||||
m_type = 2
|
||||
if("tail")
|
||||
message = "<B>\The [src]</B> waves its tail."
|
||||
m_type = 1
|
||||
if("gasp")
|
||||
message = "<B>\The [src]</B> gasps."
|
||||
m_type = 2
|
||||
if("shiver")
|
||||
message = "<B>\The [src]</B> shivers."
|
||||
m_type = 2
|
||||
if("drool")
|
||||
message = "<B>\The [src]</B> drools."
|
||||
m_type = 1
|
||||
if("scretch")
|
||||
if(!muzzled)
|
||||
message = "<B>\The [src]</B> scretches."
|
||||
m_type = 2
|
||||
if("choke")
|
||||
message = "<B>\The [src]</B> chokes."
|
||||
m_type = 2
|
||||
if("moan")
|
||||
message = "<B>\The [src]</B> moans!"
|
||||
m_type = 2
|
||||
if("nod")
|
||||
message = "<B>\The [src]</B> nods its head."
|
||||
m_type = 1
|
||||
if("sit")
|
||||
message = "<B>\The [src]</B> sits down."
|
||||
m_type = 1
|
||||
if("sway")
|
||||
message = "<B>\The [src]</B> sways around dizzily."
|
||||
m_type = 1
|
||||
if("sulk")
|
||||
message = "<B>\The [src]</B> sulks down sadly."
|
||||
m_type = 1
|
||||
if("twitch")
|
||||
message = "<B>\The [src]</B> twitches violently."
|
||||
m_type = 1
|
||||
if("dance")
|
||||
if(!restrained())
|
||||
message = "<B>\The [src]</B> dances around happily."
|
||||
m_type = 1
|
||||
if("roll")
|
||||
if(!restrained())
|
||||
message = "<B>\The [src]</B> rolls."
|
||||
m_type = 1
|
||||
if("shake")
|
||||
message = "<B>\The [src]</B> shakes its head."
|
||||
m_type = 1
|
||||
if("gnarl")
|
||||
if(!muzzled)
|
||||
message = "<B>\The [src]</B> gnarls and shows its teeth.."
|
||||
m_type = 2
|
||||
if("jump")
|
||||
message = "<B>\The [src]</B> jumps!"
|
||||
m_type = 1
|
||||
if("collapse")
|
||||
Paralyse(4 SECONDS)
|
||||
message = "<B>\The [src]</B> collapses!"
|
||||
m_type = 2
|
||||
if("flip")
|
||||
m_type = 1
|
||||
message = "<B>\The [src]</B> does a flip!"
|
||||
SpinAnimation(5,1)
|
||||
if("help")
|
||||
to_chat(src, "burp, flip, deathgasp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper")
|
||||
|
||||
if(!stat)
|
||||
if(act == "roar")
|
||||
playsound(src.loc, 'sound/voice/hiss5.ogg', 50, 1, 1)
|
||||
if(act == "deathgasp")
|
||||
playsound(src.loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
|
||||
if(act == "hiss")
|
||||
playsound(src.loc, 'sound/voice/hiss1.ogg', 30, 1, 1)
|
||||
if(act == "gnarl")
|
||||
playsound(src.loc, 'sound/voice/hiss4.ogg', 30, 1, 1)
|
||||
..()
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Emotes usable by humanoid xenomorphs.
|
||||
*/
|
||||
/datum/emote/living/carbon/alien/humanoid
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/alien/humanoid)
|
||||
|
||||
/datum/emote/living/carbon/alien/humanoid/roar
|
||||
key = "roar"
|
||||
key_third_person = "roars"
|
||||
message = "roars!"
|
||||
message_param = "roars at %t!"
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
sound = "sound/voice/hiss5.ogg"
|
||||
volume = 80
|
||||
|
||||
/datum/emote/living/carbon/alien/humanoid/hiss
|
||||
key = "hiss"
|
||||
key_third_person = "hisses"
|
||||
message = "hisses!"
|
||||
message_param = "hisses at %t!"
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
sound = "sound/voice/hiss1.ogg"
|
||||
volume = 30
|
||||
|
||||
/datum/emote/living/carbon/alien/humanoid/gnarl
|
||||
key = "gnarl"
|
||||
key_third_person = "gnarls"
|
||||
message = "gnarls and shows its teeth."
|
||||
message_param = "gnarls and flashes its teeth at %t."
|
||||
sound = "sound/voice/hiss4.ogg"
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
volume = 30
|
||||
@@ -1,126 +0,0 @@
|
||||
/mob/living/carbon/alien/larva/emote(act, m_type = 1, message = null, force)
|
||||
var/param = null
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
var/muzzled = is_muzzled()
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
if("me")
|
||||
if(HAS_TRAIT(src, TRAIT_MUTE))
|
||||
return
|
||||
if(src.client)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='warning'>You cannot send IC messages (muted).</span>")
|
||||
return
|
||||
if(src.client.handle_spam_prevention(message, MUTE_IC))
|
||||
return
|
||||
if(stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if("custom")
|
||||
return custom_emote(m_type, message)
|
||||
if("sign")
|
||||
if(!src.restrained())
|
||||
message = text("<B>The alien</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
|
||||
m_type = 1
|
||||
if("burp")
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> burps."
|
||||
m_type = 2
|
||||
if("scratch")
|
||||
if(!src.restrained())
|
||||
message = "<B>[src]</B> scratches."
|
||||
m_type = 1
|
||||
if("whimper")
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> whimpers."
|
||||
m_type = 2
|
||||
// if("roar")
|
||||
// if(!muzzled)
|
||||
// message = "<B>[src]</B> roars." Commenting out since larva shouldn't roar /N
|
||||
// m_type = 2
|
||||
if("tail")
|
||||
message = "<B>[src]</B> waves its tail."
|
||||
m_type = 1
|
||||
if("gasp")
|
||||
message = "<B>[src]</B> gasps."
|
||||
m_type = 2
|
||||
if("shiver")
|
||||
message = "<B>[src]</B> shivers."
|
||||
m_type = 2
|
||||
if("drool")
|
||||
message = "<B>[src]</B> drools."
|
||||
m_type = 1
|
||||
if("scretch")
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> scretches."
|
||||
m_type = 2
|
||||
if("choke")
|
||||
message = "<B>[src]</B> chokes."
|
||||
m_type = 2
|
||||
if("moan")
|
||||
message = "<B>[src]</B> moans!"
|
||||
m_type = 2
|
||||
if("nod")
|
||||
message = "<B>[src]</B> nods its head."
|
||||
m_type = 1
|
||||
// if("sit")
|
||||
// message = "<B>[src]</B> sits down." //Larvan can't sit down, /N
|
||||
// m_type = 1
|
||||
if("sway")
|
||||
message = "<B>[src]</B> sways around dizzily."
|
||||
m_type = 1
|
||||
if("sulk")
|
||||
message = "<B>[src]</B> sulks down sadly."
|
||||
m_type = 1
|
||||
if("twitch")
|
||||
message = "<B>[src]</B> twitches violently."
|
||||
m_type = 1
|
||||
if("dance")
|
||||
if(!src.restrained())
|
||||
message = "<B>[src]</B> dances around happily."
|
||||
m_type = 1
|
||||
if("roll")
|
||||
if(!src.restrained())
|
||||
message = "<B>[src]</B> rolls."
|
||||
m_type = 1
|
||||
if("shake")
|
||||
message = "<B>[src]</B> shakes its head."
|
||||
m_type = 1
|
||||
if("gnarl")
|
||||
if(!muzzled)
|
||||
message = "<B>[src]</B> gnarls and shows its teeth.."
|
||||
m_type = 2
|
||||
if("jump")
|
||||
message = "<B>[src]</B> jumps!"
|
||||
m_type = 1
|
||||
if("hiss_")
|
||||
message = "<B>[src]</B> hisses softly."
|
||||
m_type = 1
|
||||
if("collapse")
|
||||
Paralyse(4 SECONDS)
|
||||
message = text("<B>[]</B> collapses!", src)
|
||||
m_type = 2
|
||||
if("help")
|
||||
to_chat(src, "burp, choke, collapse, dance, drool, gasp, shiver, gnarl, jump, moan, nod, roll, scratch,\nscretch, shake, sign-#, sulk, sway, tail, twitch, whimper")
|
||||
else
|
||||
to_chat(src, text("Invalid Emote: []", act))
|
||||
if((message && src.stat == 0))
|
||||
log_emote(message, src)
|
||||
if(m_type & 1)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
//Foreach goto(703)
|
||||
else
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message(message, m_type)
|
||||
//Foreach goto(746)
|
||||
return
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Emotes usable by brains, but only while they're in MMIs.
|
||||
*/
|
||||
/datum/emote/living/carbon/brain
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/brain)
|
||||
mob_type_blacklist_typecache = null
|
||||
/// The message that will be displayed to themselves, since brains can't really see their own emotes
|
||||
var/self_message
|
||||
|
||||
/datum/emote/living/carbon/brain/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
if(self_message)
|
||||
to_chat(user, self_message)
|
||||
|
||||
/datum/emote/living/carbon/brain/can_run_emote(mob/user, status_check, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/brain/B = user
|
||||
|
||||
if(!(B.container && istype(B.container, /obj/item/mmi))) // No MMI, no emotes
|
||||
return FALSE
|
||||
|
||||
// So, brains can't really see their own emotes so we'll probably just want to send an extra message
|
||||
|
||||
/datum/emote/living/carbon/brain/alarm
|
||||
key = "alarm"
|
||||
key_third_person = "alarms"
|
||||
message = "sounds an alarm."
|
||||
self_message = "You sound an alarm."
|
||||
|
||||
/datum/emote/living/carbon/brain/alert
|
||||
key = "alert"
|
||||
key_third_person = "alerts"
|
||||
message = "lets out a distressed noise."
|
||||
self_message = "You let out a distressed noise."
|
||||
|
||||
/datum/emote/living/carbon/brain/notice
|
||||
key = "notice"
|
||||
message = "plays a loud tone."
|
||||
self_message = "You play a loud tone."
|
||||
|
||||
/datum/emote/living/carbon/brain/flash
|
||||
key = "flash"
|
||||
message = "starts flashing its lights quickly!"
|
||||
|
||||
/datum/emote/living/carbon/brain/whistle
|
||||
key = "whistle"
|
||||
key_third_person = "whistles"
|
||||
message = "whistles."
|
||||
self_message = "You whistle."
|
||||
|
||||
/datum/emote/living/carbon/brain/beep
|
||||
key = "beep"
|
||||
key_third_person = "beeps"
|
||||
message = "beeps."
|
||||
self_message = "You beep."
|
||||
|
||||
/datum/emote/living/carbon/brain/boop
|
||||
key = "boop"
|
||||
key_third_person = "boops"
|
||||
message = "boops."
|
||||
self_message = "You boop."
|
||||
@@ -1,51 +0,0 @@
|
||||
/mob/living/carbon/brain/emote(act,m_type = 1, message = null, force)
|
||||
if(!(container && istype(container, /obj/item/mmi)))//No MMI, no emotes
|
||||
return
|
||||
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
if(src.stat == DEAD)
|
||||
return
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
|
||||
if("alarm")
|
||||
to_chat(src, "You sound an alarm.")
|
||||
message = "<B>\The [src]</B> sounds an alarm."
|
||||
m_type = 2
|
||||
if("alert")
|
||||
to_chat(src, "You let out a distressed noise.")
|
||||
message = "<B>\The [src]</B> lets out a distressed noise."
|
||||
m_type = 2
|
||||
if("notice")
|
||||
to_chat(src, "You play a loud tone.")
|
||||
message = "<B>\The [src]</B> plays a loud tone."
|
||||
m_type = 2
|
||||
if("flash")
|
||||
message = "The lights on <B>\the [src]</B> flash quickly."
|
||||
m_type = 1
|
||||
if("blink")
|
||||
message = "<B>\The [src]</B> blinks."
|
||||
m_type = 1
|
||||
if("whistle")
|
||||
to_chat(src, "You whistle.")
|
||||
message = "<B>\The [src]</B> whistles."
|
||||
m_type = 2
|
||||
if("beep")
|
||||
to_chat(src, "You beep.")
|
||||
message = "<B>\The [src]</B> beeps."
|
||||
m_type = 2
|
||||
if("boop")
|
||||
to_chat(src, "You boop.")
|
||||
message = "<B>\The [src]</B> boops."
|
||||
m_type = 2
|
||||
if("help")
|
||||
to_chat(src, "alarm, alert, notice, flash,blink, whistle, beep, boop")
|
||||
|
||||
if(message && !stat)
|
||||
..()
|
||||
@@ -0,0 +1,190 @@
|
||||
/datum/emote/living/carbon
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon)
|
||||
mob_type_blacklist_typecache = list(/mob/living/carbon/brain)
|
||||
|
||||
/datum/emote/living/carbon/blink
|
||||
key = "blink"
|
||||
key_third_person = "blinks"
|
||||
message = "blinks."
|
||||
|
||||
/datum/emote/living/carbon/blink_r
|
||||
key = "blink_r"
|
||||
message = "blinks rapidly."
|
||||
|
||||
/datum/emote/living/carbon/clap
|
||||
key = "clap"
|
||||
key_third_person = "claps"
|
||||
message = "claps."
|
||||
message_mime = "claps silently."
|
||||
message_param = "claps at %t."
|
||||
emote_type = EMOTE_SOUND
|
||||
vary = TRUE
|
||||
|
||||
/datum/emote/living/carbon/clap/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.bodyparts_by_name[BODY_ZONE_L_ARM] || !H.bodyparts_by_name[BODY_ZONE_R_ARM])
|
||||
if(!H.bodyparts_by_name[BODY_ZONE_L_ARM] && !H.bodyparts_by_name[BODY_ZONE_R_ARM])
|
||||
// no arms...
|
||||
to_chat(user, "<span class='warning'>You need arms to be able to clap.</span>")
|
||||
else
|
||||
// well, we've got at least one
|
||||
user.visible_message("[user] makes the sound of one hand clapping.")
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/clap/get_sound(mob/living/user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H?.mind.miming)
|
||||
return pick(
|
||||
'sound/misc/clap1.ogg',
|
||||
'sound/misc/clap2.ogg',
|
||||
'sound/misc/clap3.ogg',
|
||||
'sound/misc/clap4.ogg')
|
||||
|
||||
/datum/emote/living/carbon/cross
|
||||
key = "cross"
|
||||
key_third_person = "crosses"
|
||||
message = "crosses their arms."
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/chuckle
|
||||
key = "chuckle"
|
||||
key_third_person = "chuckles"
|
||||
message = "chuckles."
|
||||
message_mime = "appears to chuckle."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
muzzled_noises = list("joyful", "upbeat")
|
||||
|
||||
/datum/emote/living/carbon/cough
|
||||
key = "cough"
|
||||
key_third_person = "coughs"
|
||||
message = "coughs!"
|
||||
message_mime = "appears to cough!"
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
vary = TRUE
|
||||
age_based = TRUE
|
||||
volume = 120
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/carbon/cough/get_sound(mob/living/user)
|
||||
. = ..()
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.gender == FEMALE)
|
||||
if(H.dna.species.female_cough_sounds)
|
||||
return pick(H.dna.species.female_cough_sounds)
|
||||
else
|
||||
if(H.dna.species.male_cough_sounds)
|
||||
return pick(H.dna.species.male_cough_sounds)
|
||||
|
||||
/datum/emote/living/carbon/moan
|
||||
key = "moan"
|
||||
key_third_person = "moans"
|
||||
message = "moans!"
|
||||
message_mime = "appears to moan!"
|
||||
muzzled_noises = list("pained")
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/carbon/giggle
|
||||
key = "giggle"
|
||||
key_third_person = "giggles"
|
||||
message = "giggles."
|
||||
message_mime = "giggles silently!"
|
||||
muzzled_noises = list("bubbly")
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/carbon/gurgle
|
||||
key = "gurgle"
|
||||
key_third_person = "gurgles"
|
||||
message = "makes an uncomfortable gurgle."
|
||||
muzzled_noises = list("unpleasant", "guttural")
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/carbon/inhale
|
||||
key = "inhale"
|
||||
key_third_person = "inhales"
|
||||
message = "breathes in."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
muzzled_noises = list("breathy")
|
||||
|
||||
/datum/emote/living/carbon/inhale/sharp
|
||||
key = "inhale_s"
|
||||
key_third_person = "inhales sharply!"
|
||||
message = "takes a deep breath!"
|
||||
|
||||
/datum/emote/living/carbon/kiss
|
||||
key = "kiss"
|
||||
key_third_person = "kisses"
|
||||
message = "blows a kiss."
|
||||
message_param = "blows a kiss at %t!"
|
||||
muzzled_noises = list("smooching")
|
||||
|
||||
/datum/emote/living/carbon/wave
|
||||
key = "wave"
|
||||
key_third_person = "waves"
|
||||
message = "waves."
|
||||
message_param = "waves at %t."
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/yawn
|
||||
key = "yawn"
|
||||
key_third_person = "yawns"
|
||||
message = "yawns."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
muzzled_noises = list("tired", "lazy", "sleepy")
|
||||
|
||||
/datum/emote/living/carbon/exhale
|
||||
key = "exhale"
|
||||
key_third_person = "exhales"
|
||||
message = "breathes out."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/carbon/laugh
|
||||
key = "laugh"
|
||||
key_third_person = "laughs"
|
||||
message = "laughs."
|
||||
message_mime = "laughs silently!"
|
||||
message_param = "laughs at %t."
|
||||
muzzled_noises = list("happy", "joyful")
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/carbon/scowl
|
||||
key = "scowl"
|
||||
key_third_person = "scowls"
|
||||
message = "scowls."
|
||||
|
||||
/datum/emote/living/groan
|
||||
key = "groan"
|
||||
key_third_person = "groans"
|
||||
message = "groans!"
|
||||
message_mime = "appears to groan!"
|
||||
message_param = "groans at %t."
|
||||
muzzled_noises = list("pained")
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/carbon/sign
|
||||
key = "sign"
|
||||
key_third_person = "signs"
|
||||
message = "signs."
|
||||
message_param = "signs the number %t."
|
||||
param_desc = "number(0-10)"
|
||||
// Humans get their own proc since they have fingers
|
||||
mob_type_blacklist_typecache = list(/mob/living/carbon/human)
|
||||
hands_use_check = TRUE
|
||||
target_behavior = EMOTE_TARGET_BHVR_NUM
|
||||
|
||||
/datum/emote/living/carbon/faint
|
||||
key = "faint"
|
||||
key_third_person = "faints"
|
||||
message = "faints."
|
||||
|
||||
/datum/emote/living/carbon/faint/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(. && isliving(user))
|
||||
var/mob/living/L = user
|
||||
L.SetSleeping(2 SECONDS)
|
||||
@@ -86,8 +86,6 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/death(gibbed)
|
||||
if(can_die() && !gibbed && deathgasp_on_death)
|
||||
emote("deathgasp", force = TRUE) //let the world KNOW WE ARE DEAD
|
||||
|
||||
// Only execute the below if we successfully died
|
||||
. = ..(gibbed)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2015,3 +2015,21 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
to_chat(usr, "[src] does not have any stored infomation!")
|
||||
else
|
||||
to_chat(usr, "OOC Metadata is not supported by this server!")
|
||||
|
||||
/mob/living/carbon/human/verb/pose()
|
||||
set name = "Set Pose"
|
||||
set desc = "Sets a description which will be shown when someone examines you."
|
||||
set category = "IC"
|
||||
|
||||
// no metagaming
|
||||
if(stat)
|
||||
return
|
||||
|
||||
pose = sanitize(copytext(input(usr, "This is [src]. [p_they(TRUE)] [p_are()]...", "Pose", null) as text, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
/mob/living/carbon/human/verb/set_flavor()
|
||||
set name = "Set Flavour Text"
|
||||
set desc = "Sets an extended description of your character's features."
|
||||
set category = "IC"
|
||||
|
||||
update_flavor_text()
|
||||
|
||||
@@ -0,0 +1,686 @@
|
||||
/datum/emote/living/carbon/human
|
||||
/// Custom messages that should be applied based on species
|
||||
/// Should be an associative list of species name: message
|
||||
var/species_custom_messages = list()
|
||||
/// Custom messages applied to mimes of a particular species
|
||||
var/species_custom_mime_messages = list()
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/human)
|
||||
|
||||
/datum/emote/living/carbon/human/select_message_type(mob/user, msg, intentional)
|
||||
. = ..()
|
||||
|
||||
var/mob/living/carbon/human/human_user = user
|
||||
|
||||
if(!species_custom_messages || (human_user.mind?.miming && !species_custom_mime_messages))
|
||||
return .
|
||||
|
||||
var/custom_message
|
||||
if(user.mind?.miming)
|
||||
custom_message = species_custom_mime_messages[human_user.dna.species?.name]
|
||||
else
|
||||
custom_message = species_custom_messages[human_user.dna.species?.name]
|
||||
|
||||
if(custom_message)
|
||||
return custom_message
|
||||
|
||||
/datum/emote/living/carbon/human/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if((emote_type & EMOTE_MOUTH) && !H.mind?.miming)
|
||||
if(H.getOxyLoss() > 10 || H.AmountLoseBreath() >= 8 SECONDS) // no screaming if you don't have enough breath to scream
|
||||
H.emote("gasp")
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/human/airguitar
|
||||
key = "airguitar"
|
||||
message = "is strumming the air and headbanging like a safari chimp."
|
||||
emote_type = EMOTE_VISIBLE
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/cry
|
||||
key = "cry"
|
||||
key_third_person = "cries"
|
||||
message = "cries."
|
||||
muzzled_noises = list("weak", "pathetic", "sad")
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/carbon/human/dap
|
||||
key = "dap"
|
||||
key_third_person = "daps"
|
||||
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
|
||||
message_param = "give daps to %t."
|
||||
emote_target_type = EMOTE_TARGET_MOB
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/eyebrow
|
||||
key = "eyebrow"
|
||||
message = "raises an eyebrow."
|
||||
message_param = "raises an eyebrow at %t."
|
||||
|
||||
/datum/emote/living/carbon/human/grumble
|
||||
key = "grumble"
|
||||
key_third_person = "grumbles"
|
||||
message = "grumbles!"
|
||||
message_mime = "seems to grumble!"
|
||||
message_postfix = "at %t!"
|
||||
muzzled_noises = list("bothered")
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/carbon/human/hug
|
||||
key = "hug"
|
||||
key_third_person = "hugs"
|
||||
message = "hugs themselves."
|
||||
message_param = "hugs %t."
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/mumble
|
||||
key = "mumble"
|
||||
key_third_person = "mumbles"
|
||||
message = "mumbles!"
|
||||
message_mime = "seems to be speaking sweet nothings!"
|
||||
message_postfix = "at %t!"
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/carbon/human/nod
|
||||
key = "nod"
|
||||
key_third_person = "nods"
|
||||
message = "nods their head."
|
||||
message_param = "nods their head at %t."
|
||||
|
||||
/datum/emote/living/carbon/human/scream
|
||||
key = "scream"
|
||||
key_third_person = "screams"
|
||||
message = "screams!"
|
||||
message_mime = "acts out a scream!"
|
||||
message_postfix = "at %t!"
|
||||
muzzled_noises = list("very loud")
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
only_forced_audio = FALSE
|
||||
vary = TRUE
|
||||
age_based = TRUE
|
||||
cooldown = 5 SECONDS
|
||||
mob_type_blacklist_typecache = list(
|
||||
/mob/living/carbon/human/monkey, // screech instead
|
||||
/mob/living/silicon // Robot sounds
|
||||
)
|
||||
|
||||
/datum/emote/living/carbon/human/scream/select_message_type(mob/user, msg, intentional)
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.dna.species?.scream_verb)
|
||||
if(H.mind?.miming)
|
||||
return "[H.dna.species?.scream_verb] silently!"
|
||||
else
|
||||
return "[H.dna.species?.scream_verb]!"
|
||||
|
||||
/datum/emote/living/carbon/human/scream/get_sound(mob/living/user)
|
||||
var/mob/living/carbon/human/human = user
|
||||
if(human.mind?.miming || !istype(human))
|
||||
return
|
||||
if(human.gender == FEMALE)
|
||||
return human.dna.species.female_scream_sound
|
||||
else
|
||||
return human.dna.species.male_scream_sound
|
||||
|
||||
/datum/emote/living/carbon/human/gasp
|
||||
key = "gasp"
|
||||
key_third_person = "gasps"
|
||||
message = "gasps!"
|
||||
message_mime = "appears to be gasping!"
|
||||
emote_type = EMOTE_SOUND // Don't make this one a mouth emote since we don't want it to be caught by nobreath
|
||||
age_based = TRUE
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
volume = 100
|
||||
|
||||
/datum/emote/living/carbon/human/gasp/get_sound(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.is_muzzled())
|
||||
// If you're muzzled you're not making noise
|
||||
return
|
||||
|
||||
if(H.health > 0)
|
||||
return H.dna.species.gasp_sound
|
||||
|
||||
if(H.gender == FEMALE)
|
||||
return pick(H.dna.species.female_dying_gasp_sounds)
|
||||
else
|
||||
return pick(H.dna.species.male_dying_gasp_sounds)
|
||||
|
||||
/datum/emote/living/carbon/human/shake
|
||||
key = "shake"
|
||||
key_third_person = "shakes"
|
||||
message = "shakes their head."
|
||||
message_param = "shakes their head at %t."
|
||||
|
||||
/datum/emote/living/carbon/human/pale
|
||||
key = "pale"
|
||||
message = "goes pale for a second."
|
||||
|
||||
/datum/emote/living/carbon/human/raise
|
||||
key = "raise"
|
||||
key_third_person = "raises"
|
||||
message = "raises a hand."
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/salute
|
||||
key = "salute"
|
||||
key_third_person = "salutes"
|
||||
message = "salutes."
|
||||
message_param = "salutes to %t."
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/shrug
|
||||
key = "shrug"
|
||||
key_third_person = "shrugs"
|
||||
message = "shrugs."
|
||||
|
||||
/datum/emote/living/carbon/human/sniff
|
||||
key = "sniff"
|
||||
key_third_person = "sniff"
|
||||
message = "sniffs."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/carbon/human/johnny
|
||||
key = "johnny"
|
||||
message = "takes a drag from a cigarette and blows their own name out in smoke."
|
||||
message_param = "dummy" // Gets handled in select_param
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
target_behavior = EMOTE_TARGET_BHVR_DEFAULT_TO_BASE
|
||||
emote_target_type = EMOTE_TARGET_MOB
|
||||
|
||||
/datum/emote/living/carbon/human/johnny/select_param(mob/user, params)
|
||||
if(!params)
|
||||
return message
|
||||
var/mob/target = find_target(user, params, EMOTE_TARGET_MOB)
|
||||
if(!target)
|
||||
return message
|
||||
var/msg = message
|
||||
if(user.mind?.miming)
|
||||
msg = "takes a drag from a cigarette and blows \"[target.name]\" out in smoke."
|
||||
else
|
||||
msg = "says, \"[target.name], please. They had a family.\" [user] takes a drag from a cigarette and blows [user.p_their()] name out in smoke."
|
||||
return msg
|
||||
|
||||
/datum/emote/living/carbon/human/johnny/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!istype(H.wear_mask, /obj/item/clothing/mask/cigarette))
|
||||
to_chat(user, "<span class='warning'>You can't be that cool without a cigarette between your lips.</span>")
|
||||
return TRUE
|
||||
|
||||
var/obj/item/clothing/mask/cigarette/cig = H.wear_mask
|
||||
|
||||
if(!cig.lit)
|
||||
to_chat(user, "<span class='warning'>You have to light that [cig] first, cool cat.</span>")
|
||||
return TRUE
|
||||
|
||||
if(H.getOxyLoss() > 30)
|
||||
user.visible_message(
|
||||
"<span class='warning'>[user] gasps for air and swallows their cigarette!</span>",
|
||||
"<span class='warning'>You gasp for air and accidentally swallow your [cig]!</span>"
|
||||
)
|
||||
if(cig.lit)
|
||||
to_chat(user, "<span class='userdanger'>The lit [cig] burns on the way down!")
|
||||
user.unEquip(cig)
|
||||
qdel(cig)
|
||||
H.adjustFireLoss(5)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/human/sneeze
|
||||
key = "sneeze"
|
||||
key_third_person = "sneezes"
|
||||
message = "sneezes."
|
||||
muzzled_noises = list("strange", "sharp")
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
volume = 70
|
||||
|
||||
/datum/emote/living/carbon/human/sneeze/get_sound(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.gender == FEMALE)
|
||||
return H.dna.species.female_sneeze_sound
|
||||
else
|
||||
return H.dna.species.male_sneeze_sound
|
||||
|
||||
/datum/emote/living/carbon/human/slap
|
||||
key = "slap"
|
||||
key_third_person = "slaps"
|
||||
hands_use_check = TRUE
|
||||
cooldown = 3 SECONDS // to prevent endless table slamming
|
||||
|
||||
/datum/emote/living/carbon/human/slap/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
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
|
||||
qdel(N)
|
||||
to_chat(user, "<span class='warning'>You're incapable of slapping in your current state.</span>")
|
||||
|
||||
/datum/emote/living/carbon/human/wink
|
||||
key = "wink"
|
||||
key_third_person = "winks"
|
||||
message = "winks."
|
||||
|
||||
/datum/emote/living/carbon/human/highfive
|
||||
key = "highfive"
|
||||
key_third_person = "highfives"
|
||||
message = "requests a highfive."
|
||||
hands_use_check = TRUE
|
||||
cooldown = 3 SECONDS
|
||||
|
||||
/datum/emote/living/carbon/human/highfive/can_run_emote(mob/user, status_check, intentional)
|
||||
. = ..()
|
||||
var/mob/living/carbon/user_carbon = user
|
||||
if(user_carbon.restrained())
|
||||
return FALSE
|
||||
|
||||
/datum/emote/living/carbon/human/highfive/proc/wiz_cleanup(mob/user, mob/highfived)
|
||||
user.status_flags &= ~GODMODE
|
||||
highfived.status_flags &= ~GODMODE
|
||||
|
||||
/datum/emote/living/carbon/human/highfive/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/carbon/user_carbon = user
|
||||
if(user_carbon.has_status_effect(STATUS_EFFECT_HIGHFIVE))
|
||||
user.visible_message("[user.name] shakes [user.p_their()] hand around slightly, impatiently waiting for someone to high-five them.")
|
||||
return TRUE
|
||||
user_carbon.apply_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
for(var/mob/living/L in orange(1))
|
||||
if(L.has_status_effect(STATUS_EFFECT_HIGHFIVE) && L != user)
|
||||
if(iswizard(user) && iswizard(L))
|
||||
user.visible_message("<span class='biggerdanger'><b>[user.name]</b> and <b>[L.name]</b> high-five EPICALLY!</span>")
|
||||
user_carbon.status_flags |= GODMODE
|
||||
L.status_flags |= GODMODE
|
||||
explosion(get_turf(user), 5, 2, 1, 3)
|
||||
// explosions have a spawn so this makes sure that we don't get gibbed
|
||||
addtimer(CALLBACK(src, .proc/wiz_cleanup, user_carbon, L), 1)
|
||||
user_carbon.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
L.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
return TRUE
|
||||
user.visible_message("<b>[user.name]</b> and <b>[L.name]</b> high-five!")
|
||||
playsound(user, 'sound/effects/snap.ogg', 50)
|
||||
user_carbon.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
L.remove_status_effect(STATUS_EFFECT_HIGHFIVE)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/human/handshake
|
||||
key = "handshake"
|
||||
message = "holds out their hand."
|
||||
hands_use_check = TRUE
|
||||
emote_target_type = EMOTE_TARGET_MOB
|
||||
target_behavior = EMOTE_TARGET_BHVR_DEFAULT_TO_BASE
|
||||
|
||||
/datum/emote/living/carbon/human/handshake/act_on_target(mob/user, target)
|
||||
. = ..()
|
||||
if(!target)
|
||||
user.visible_message(
|
||||
"[user] seems to shake hands with empty space.",
|
||||
"You shake the air's hand."
|
||||
)
|
||||
return EMOTE_ACT_STOP_EXECUTION
|
||||
|
||||
if(!user.Adjacent(target) || !ishuman(target))
|
||||
message_param = "extends a hand towards %t."
|
||||
return TRUE
|
||||
|
||||
var/mob/living/carbon/human/human_target = target
|
||||
|
||||
if(human_target.canmove && !human_target.r_hand && !human_target.restrained())
|
||||
message_param = "shakes hands with %t."
|
||||
else
|
||||
message_param = "holds out [user.p_their()] hand to %t."
|
||||
|
||||
/datum/emote/living/carbon/human/handshake/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/target
|
||||
for(var/mob/living/A in oview(5, user))
|
||||
if(params == A.name)
|
||||
target = A
|
||||
|
||||
if(!target)
|
||||
user.visible_message(
|
||||
"[user] seems to shake hands with empty space.",
|
||||
"You shake the air's hand."
|
||||
)
|
||||
return TRUE
|
||||
|
||||
if(target.canmove && !target.r_hand && !target.restrained())
|
||||
message_param = "shakes hands with %t."
|
||||
else
|
||||
message_param = "holds out [user.p_their()] hand to %t."
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/human/snap
|
||||
key = "snap"
|
||||
key_third_person = "snaps"
|
||||
message = "snaps their fingers."
|
||||
message_param = "snaps their fingers at %t."
|
||||
sound = "sound/effects/fingersnap.ogg"
|
||||
emote_type = EMOTE_SOUND
|
||||
|
||||
/datum/emote/living/carbon/human/snap/run_emote(mob/user, params, type_override, intentional)
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/external/LH = H.get_organ("l_hand")
|
||||
var/obj/item/organ/external/RH = H.get_organ("r_hand")
|
||||
var/left_hand_good = FALSE
|
||||
var/right_hand_good = FALSE
|
||||
if(LH && !(LH.status & ORGAN_SPLINTED) && !(LH.status & ORGAN_BROKEN))
|
||||
left_hand_good = TRUE
|
||||
if(RH && !(RH.status & ORGAN_SPLINTED) && !(RH.status & ORGAN_BROKEN))
|
||||
right_hand_good = TRUE
|
||||
|
||||
if(!left_hand_good && !right_hand_good)
|
||||
to_chat(user, "You need at least one hand in good working order to snap your fingers.")
|
||||
return TRUE
|
||||
|
||||
if(prob(5))
|
||||
user.visible_message("<span class='danger'><b>[user]</b> snaps [p_their()] fingers right off!</span>")
|
||||
playsound(user.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/human/fart
|
||||
key = "fart"
|
||||
key_third_person = "farts"
|
||||
message = "farts."
|
||||
message_param = "farts in %t's general direction."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/carbon/human/fart/run_emote(mob/user, params, type_override, intentional)
|
||||
var/farted_on_something = FALSE
|
||||
for(var/atom/A in get_turf(user))
|
||||
farted_on_something = A.fart_act(user) || farted_on_something
|
||||
if(!farted_on_something)
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/carbon/sign/signal
|
||||
key = "signal"
|
||||
key_third_person = "signals"
|
||||
message_param = "raises %t fingers."
|
||||
param_desc = "number(0-10)"
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/human)
|
||||
hands_use_check = TRUE
|
||||
|
||||
|
||||
/////////
|
||||
// Species-specific emotes
|
||||
|
||||
/datum/emote/living/carbon/human/wag
|
||||
key = "wag"
|
||||
key_third_person = "wags"
|
||||
message = "starts wagging their tail."
|
||||
emote_type = EMOTE_VISIBLE | EMOTE_FORCE_NO_RUNECHAT
|
||||
species_type_whitelist_typecache = list(
|
||||
/datum/species/unathi,
|
||||
/datum/species/vulpkanin,
|
||||
/datum/species/tajaran,
|
||||
/datum/species/vox
|
||||
)
|
||||
|
||||
/datum/emote/living/carbon/human/proc/can_wag(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!(H.dna.species.bodyflags & TAIL_WAGGING))
|
||||
return FALSE
|
||||
var/obscured = H.wear_suit && (H.wear_suit.flags_inv & HIDETAIL)
|
||||
if(!istype(H))
|
||||
return FALSE
|
||||
if(istype(H.body_accessory, /datum/body_accessory/tail))
|
||||
if(!H.body_accessory.try_restrictions(user))
|
||||
return FALSE
|
||||
|
||||
if(H.dna.species.bodyflags & TAIL_WAGGING && obscured)
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/wag/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.start_tail_wagging()
|
||||
|
||||
|
||||
/datum/emote/living/carbon/human/wag/can_run_emote(mob/user, status_check = TRUE, intentional)
|
||||
if(!..())
|
||||
return FALSE
|
||||
|
||||
if(!can_wag(user))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/wag/stop
|
||||
key = "swag" // B)
|
||||
key_third_person = "swags"
|
||||
message = "stops wagging their tail."
|
||||
|
||||
/datum/emote/living/carbon/human/wag/stop/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.stop_tail_wagging()
|
||||
|
||||
///Snowflake emotes only for le epic chimp
|
||||
/datum/emote/living/carbon/human/monkey
|
||||
species_type_whitelist_typecache = list(/datum/species/monkey)
|
||||
|
||||
|
||||
// Note: subtype of human scream, not monkey, so we need the overrides.
|
||||
/datum/emote/living/carbon/human/scream/screech
|
||||
key = "screech"
|
||||
key_third_person = "screeches"
|
||||
message = "screeches!"
|
||||
message_param = "screeches at %t!"
|
||||
vary = FALSE
|
||||
mob_type_blacklist_typecache = list()
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/human/monkey)
|
||||
species_type_whitelist_typecache = list(/datum/species/monkey)
|
||||
|
||||
/datum/emote/living/carbon/human/scream/screech/roar
|
||||
key = "roar"
|
||||
key_third_person = "roars"
|
||||
message = "roars!"
|
||||
message_param = "roars at %t!"
|
||||
|
||||
/datum/emote/living/carbon/human/monkey/gnarl
|
||||
key = "gnarl"
|
||||
key_third_person = "gnarls"
|
||||
message = "gnarls and shows their teeth!"
|
||||
message_param = "gnarls and shows their teeth at %t."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/carbon/human/monkey/roll
|
||||
key = "roll"
|
||||
key_third_person = "rolls"
|
||||
message = "rolls."
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/monkey/roll/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(.)
|
||||
user.SpinAnimation(10, 1)
|
||||
|
||||
/datum/emote/living/carbon/human/monkey/scratch
|
||||
key = "scratch"
|
||||
key_third_person = "scratches"
|
||||
message = "scratches."
|
||||
hands_use_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/monkey/tail
|
||||
key = "tail"
|
||||
message = "waves their tail."
|
||||
|
||||
///////
|
||||
// More specific human species emotes
|
||||
|
||||
/datum/emote/living/carbon/human/flap
|
||||
key = "flap"
|
||||
key_third_person = "flaps"
|
||||
message = "flaps their wings."
|
||||
species_type_whitelist_typecache = list(/datum/species/moth)
|
||||
|
||||
/datum/emote/living/carbon/human/flap/angry
|
||||
key = "aflap"
|
||||
key_third_person = "aflaps"
|
||||
message = "flaps their wings ANGRILY!"
|
||||
|
||||
/datum/emote/living/carbon/human/flutter
|
||||
key = "flutter"
|
||||
key_third_person = "flutters"
|
||||
message = "flutters their wings."
|
||||
species_type_whitelist_typecache = list(/datum/species/moth)
|
||||
|
||||
/datum/emote/living/carbon/human/quill
|
||||
key = "quill"
|
||||
key_third_person = "quills"
|
||||
message = "rustles their quills."
|
||||
message_param = "rustles their quills at %t."
|
||||
emote_type = EMOTE_SOUND
|
||||
age_based = TRUE
|
||||
// Credit to sound-ideas (freesfx.co.uk) for the sound.
|
||||
sound = "sound/effects/voxrustle.ogg"
|
||||
species_type_whitelist_typecache = list(/datum/species/vox)
|
||||
|
||||
/datum/emote/living/carbon/human/warble
|
||||
key = "warble"
|
||||
key_third_person = "warbles"
|
||||
message = "warbles."
|
||||
message_param = "warbles at %t."
|
||||
emote_type = EMOTE_SOUND
|
||||
age_based = TRUE
|
||||
// Copyright CC BY 3.0 alienistcog (freesound.org) for the sound.
|
||||
sound = "sound/effects/warble.ogg"
|
||||
species_type_whitelist_typecache = list(/datum/species/skrell)
|
||||
|
||||
/datum/emote/living/carbon/human/clack
|
||||
key = "clack"
|
||||
key_third_person = "clacks"
|
||||
message = "clacks their mandibles."
|
||||
message_param = "clacks their mandibles at %t."
|
||||
species_type_whitelist_typecache = list(/datum/species/kidan)
|
||||
emote_type = EMOTE_SOUND
|
||||
audio_cooldown = 3 SECONDS
|
||||
age_based = TRUE
|
||||
// Credit to DrMinky (freesound.org) for the sound.
|
||||
sound = "sound/effects/Kidanclack.ogg"
|
||||
|
||||
/datum/emote/living/carbon/human/clack/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
mineral_scan_pulse(get_turf(src), range = world.view)
|
||||
|
||||
/datum/emote/living/carbon/human/clack/click
|
||||
key = "click"
|
||||
key_third_person = "clicks"
|
||||
message = "clicks their mandibles."
|
||||
message_param = "clicks their mandibles at %t."
|
||||
// Credit to DrMinky (freesound.org) for the sound.
|
||||
sound = "sound/effects/Kidanclack2.ogg"
|
||||
|
||||
/datum/emote/living/carbon/human/drask_talk
|
||||
species_type_whitelist_typecache = list(/datum/species/drask)
|
||||
emote_type = EMOTE_SOUND
|
||||
age_based = TRUE
|
||||
sound = "sound/voice/drasktalk.ogg"
|
||||
|
||||
/datum/emote/living/carbon/human/drask_talk/drone
|
||||
key = "drone"
|
||||
key_third_person = "drones"
|
||||
message = "drones."
|
||||
message_param = "drones at %t."
|
||||
|
||||
/datum/emote/living/carbon/human/drask_talk/hum
|
||||
key = "hum"
|
||||
key_third_person = "hums"
|
||||
message = "hums."
|
||||
message_param = "hums at %t."
|
||||
|
||||
/datum/emote/living/carbon/human/drask_talk/rumble
|
||||
key = "rumble"
|
||||
key_third_person = "rumbles"
|
||||
message = "rumbles."
|
||||
message_param = "rumbles at %t."
|
||||
|
||||
/datum/emote/living/carbon/human/hiss
|
||||
key = "hiss"
|
||||
key_third_person = "hisses"
|
||||
message = "hisses."
|
||||
message_param = "hisses at %t."
|
||||
species_type_whitelist_typecache = list(/datum/species/unathi)
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
age_based = TRUE
|
||||
// Credit to Jamius (freesound.org) for the sound.
|
||||
sound = "sound/effects/unathihiss.ogg"
|
||||
muzzled_noises = list("weak hissing")
|
||||
|
||||
/datum/emote/living/carbon/human/creak
|
||||
key = "creak"
|
||||
key_third_person = "creaks"
|
||||
message = "creaks."
|
||||
message_param = "creaks at %t."
|
||||
emote_type = EMOTE_SOUND
|
||||
age_based = TRUE
|
||||
species_type_whitelist_typecache = list(/datum/species/diona)
|
||||
sound = "sound/voice/dionatalk1.ogg"
|
||||
|
||||
/datum/emote/living/carbon/human/squish
|
||||
key = "squish"
|
||||
key_third_person = "squishes"
|
||||
message = "squishes."
|
||||
message_param = "squishes at %t."
|
||||
emote_type = EMOTE_SOUND
|
||||
age_based = TRUE
|
||||
// Credit to DrMinky (freesound.org) for the sound.
|
||||
sound = "sound/effects/slime_squish.ogg"
|
||||
|
||||
/datum/emote/living/carbon/human/squish/can_run_emote(mob/user, status_check, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
if(isslimeperson(src)) //Only Slime People can squish
|
||||
return TRUE
|
||||
else
|
||||
var/mob/living/carbon/human/H = user
|
||||
for(var/obj/item/organ/external/L in H.bodyparts) // if your limbs are squishy you can squish too!
|
||||
if(istype(L.dna.species, /datum/species/slime))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/emote/living/carbon/human/howl
|
||||
key = "howl"
|
||||
key_third_person = "howls"
|
||||
message = "howls."
|
||||
message_mime = "acts out a howl."
|
||||
message_param = "howls at %t."
|
||||
species_type_whitelist_typecache = list(/datum/species/vulpkanin)
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
age_based = TRUE
|
||||
sound = "sound/goonstation/voice/howl.ogg"
|
||||
muzzled_noises = list("very loud")
|
||||
volume = 100
|
||||
cooldown = 10 SECONDS
|
||||
|
||||
/datum/emote/living/carbon/human/growl
|
||||
key = "growl"
|
||||
key_third_person = "growls"
|
||||
message = "growls."
|
||||
message_mime = "growls silently."
|
||||
message_param = "growls at %t."
|
||||
species_type_whitelist_typecache = list(/datum/species/vulpkanin)
|
||||
sound = "growls" // what the fuck why is this just top level
|
||||
volume = 80
|
||||
muzzled_noises = list("annoyed")
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/carbon/human/rattle
|
||||
key = "rattle"
|
||||
key_third_person = "rattles"
|
||||
message = "rattles their bones."
|
||||
message_param = "rattles their bones at %t."
|
||||
species_type_whitelist_typecache = list(/datum/species/skeleton, /datum/species/plasmaman)
|
||||
@@ -67,7 +67,7 @@
|
||||
if(!(lying || resting))
|
||||
if(!HAS_TRAIT(src, TRAIT_NOPAIN))
|
||||
emote("scream")
|
||||
custom_emote(1, "collapses!")
|
||||
emote("collapses")
|
||||
Weaken(10 SECONDS) //can't emote while weakened, apparently.
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
continue
|
||||
|
||||
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
|
||||
custom_emote(1, "[HAS_TRAIT(src, TRAIT_NOPAIN) ? "" : emote_scream ]drops what [p_they()] [p_were()] holding in [p_their()] [E.name]!")
|
||||
custom_emote(EMOTE_VISIBLE, "[HAS_TRAIT(src, TRAIT_NOPAIN) ? "" : emote_scream ]drops what [p_they()] [p_were()] holding in [p_their()] [E.name]!")
|
||||
|
||||
else if(E.is_malfunctioning())
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
if(!unEquip(r_hand))
|
||||
continue
|
||||
|
||||
custom_emote(1, "drops what [p_they()] [p_were()] holding, [p_their()] [E.name] malfunctioning!")
|
||||
custom_emote(EMOTE_VISIBLE, "drops what [p_they()] [p_were()] holding, [p_their()] [E.name] malfunctioning!")
|
||||
|
||||
do_sparks(5, 0, src)
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
SetLoseBreath(0)
|
||||
|
||||
if(!gibbed && deathgasp_on_death)
|
||||
emote("deathgasp", force = TRUE)
|
||||
emote("deathgasp")
|
||||
|
||||
if(mind && suiciding)
|
||||
mind.suicided = TRUE
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
/mob/living/attack_animal(mob/living/simple_animal/M)
|
||||
M.face_atom(src)
|
||||
if((M.a_intent == INTENT_HELP && M.ckey) || M.melee_damage_upper == 0)
|
||||
M.custom_emote(1, "[M.friendly] [src].")
|
||||
M.custom_emote(EMOTE_VISIBLE, "[M.friendly] [src].")
|
||||
return FALSE
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='warning'>You don't want to hurt anyone!</span>")
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
/datum/emote/living
|
||||
mob_type_allowed_typecache = /mob/living
|
||||
mob_type_blacklist_typecache = list(
|
||||
/mob/living/carbon/brain, // nice try
|
||||
/mob/living/captive_brain,
|
||||
/mob/living/silicon,
|
||||
/mob/living/simple_animal/bot
|
||||
)
|
||||
message_postfix = "at %t."
|
||||
|
||||
/datum/emote/living/should_play_sound(mob/user, intentional)
|
||||
. = ..()
|
||||
if(user.mind?.miming)
|
||||
return FALSE // shh
|
||||
return .
|
||||
|
||||
/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."
|
||||
message_postfix = "to %t."
|
||||
|
||||
/datum/emote/living/burp
|
||||
key = "burp"
|
||||
key_third_person = "burps"
|
||||
message = "burps."
|
||||
message_mime = "opens their mouth rather obnoxiously."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
muzzled_noises = list("peculiar")
|
||||
|
||||
/datum/emote/living/choke
|
||||
key = "choke"
|
||||
key_third_person = "chokes"
|
||||
message = "chokes!"
|
||||
message_mime = "clutches their throat desperately!"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
muzzled_noises = list("gagging", "strong")
|
||||
|
||||
/datum/emote/living/collapse
|
||||
key = "collapse"
|
||||
key_third_person = "collapses"
|
||||
message = "collapses!"
|
||||
emote_type = EMOTE_VISIBLE
|
||||
|
||||
/datum/emote/living/collapse/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(. && isliving(user))
|
||||
var/mob/living/L = user
|
||||
L.Paralyse(4 SECONDS)
|
||||
|
||||
/datum/emote/living/dance
|
||||
key = "dance"
|
||||
key_third_person = "dances"
|
||||
message = "dances around happily."
|
||||
|
||||
/datum/emote/living/jump
|
||||
key = "jump"
|
||||
key_third_person = "jumps"
|
||||
message = "jumps!"
|
||||
|
||||
/datum/emote/living/deathgasp
|
||||
key = "deathgasp"
|
||||
key_third_person = "deathgasps"
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE // make sure deathgasp gets runechatted regardless
|
||||
age_based = TRUE
|
||||
cooldown = 10 SECONDS
|
||||
volume = 40
|
||||
unintentional_stat_allowed = DEAD
|
||||
message = "seizes up and falls limp, their eyes dead and lifeless..."
|
||||
message_alien = "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, green blood bubbling from its maw..."
|
||||
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..."
|
||||
|
||||
mob_type_blacklist_typecache = list(
|
||||
/mob/living/carbon/brain,
|
||||
/mob/living/captive_brain
|
||||
)
|
||||
|
||||
/datum/emote/living/deathgasp/get_sound(mob/living/user)
|
||||
. = ..()
|
||||
|
||||
if(isanimal(user))
|
||||
var/mob/living/simple_animal/S = user
|
||||
if(S.deathmessage)
|
||||
message_simple = S.deathmessage
|
||||
return S.death_sound
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.dna.species)
|
||||
message = H.dna.species.death_message
|
||||
return pick(H.dna.species.death_sounds)
|
||||
|
||||
if(isalien(user))
|
||||
var/mob/living/carbon/alien/A = user
|
||||
message_alien = A.death_message
|
||||
return A.death_sound
|
||||
|
||||
if(issilicon(user))
|
||||
var/mob/living/silicon/SI = user
|
||||
return SI.death_sound
|
||||
|
||||
/datum/emote/living/drool
|
||||
key = "drool"
|
||||
key_third_person = "drools"
|
||||
message = "drools."
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/quiver
|
||||
key = "quiver"
|
||||
key_third_person = "quivers"
|
||||
message = "quivers."
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/frown
|
||||
key = "frown"
|
||||
key_third_person = "frowns"
|
||||
message = "frowns."
|
||||
message_param = "frowns at %t."
|
||||
|
||||
/datum/emote/living/gag
|
||||
key = "gag"
|
||||
key_third_person = "gags"
|
||||
message = "gags."
|
||||
message_mime = "appears to gag."
|
||||
message_param = "gags at %t."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/glare
|
||||
key = "glare"
|
||||
key_third_person = "glares"
|
||||
message = "glares."
|
||||
message_param = "glares at %t."
|
||||
|
||||
/datum/emote/living/grin
|
||||
key = "grin"
|
||||
key_third_person = "grins"
|
||||
message = "grins."
|
||||
|
||||
/datum/emote/living/grimace
|
||||
key = "grimace"
|
||||
key_third_person = "grimaces"
|
||||
message = "grimaces."
|
||||
|
||||
/datum/emote/living/look
|
||||
key = "look"
|
||||
key_third_person = "looks"
|
||||
message = "looks."
|
||||
message_param = "looks at %t."
|
||||
|
||||
/datum/emote/living/bshake
|
||||
key = "bshake"
|
||||
key_third_person = "bshakes"
|
||||
message = "shakes."
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/shudder
|
||||
key = "shudder"
|
||||
key_third_person = "shudders"
|
||||
message = "shudders."
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/point
|
||||
key = "point"
|
||||
key_third_person = "points"
|
||||
message = "points."
|
||||
message_param = "points at %t."
|
||||
hands_use_check = TRUE
|
||||
target_behavior = EMOTE_TARGET_BHVR_USE_PARAMS_ANYWAY
|
||||
emote_target_type = EMOTE_TARGET_ANY
|
||||
|
||||
/datum/emote/living/point/act_on_target(mob/user, target)
|
||||
if(!target)
|
||||
return
|
||||
|
||||
user.pointed(target)
|
||||
|
||||
/datum/emote/living/point/run_emote(mob/user, params, type_override, intentional)
|
||||
// again, /tg/ has some flavor when pointing (like if you only have one leg) that applies debuffs
|
||||
// but it's so common that seems unnecessary for here
|
||||
message_param = initial(message_param) // reset
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.has_left_hand() && !H.has_right_hand())
|
||||
if(H.get_num_legs() != 0)
|
||||
message_param = "tries to point at %t with a leg."
|
||||
else
|
||||
// nugget
|
||||
message_param = "<span class='userdanger>bumps [user.p_their()] head on the ground</span> trying to motion towards %t."
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/emote/living/pout
|
||||
key = "pout"
|
||||
key_third_person = "pouts"
|
||||
message = "pouts."
|
||||
|
||||
/datum/emote/living/scream
|
||||
key = "scream"
|
||||
key_third_person = "screams"
|
||||
message = "screams!"
|
||||
message_mime = "acts out a scream!"
|
||||
message_simple = "whimpers."
|
||||
message_alien = "roars!"
|
||||
emote_type = EMOTE_SOUND | EMOTE_MOUTH
|
||||
mob_type_blacklist_typecache = list(
|
||||
// Humans and silicons get specialized scream.
|
||||
/mob/living/carbon/human,
|
||||
/mob/living/silicon
|
||||
)
|
||||
volume = 80
|
||||
|
||||
/datum/emote/living/scream/get_sound(mob/living/user)
|
||||
. = ..()
|
||||
if(isalien(user))
|
||||
return "sound/voice/hiss5.ogg"
|
||||
|
||||
/datum/emote/living/shake
|
||||
key = "shake"
|
||||
key_third_person = "shakes"
|
||||
message = "shakes their head."
|
||||
|
||||
/datum/emote/living/shiver
|
||||
key = "shiver"
|
||||
key_third_person = "shiver"
|
||||
message = "shivers."
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/sigh
|
||||
key = "sigh"
|
||||
key_third_person = "sighs"
|
||||
message = "sighs."
|
||||
message_mime = "appears to sigh."
|
||||
muzzled_noises = list("weak")
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
/datum/emote/living/sigh/happy
|
||||
key = "hsigh"
|
||||
key_third_person = "hsighs"
|
||||
message = "sighs contentedly."
|
||||
message_mime = "appears to sigh contentedly"
|
||||
muzzled_noises = list("chill", "relaxed")
|
||||
|
||||
/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."
|
||||
message_param = "smiles at %t."
|
||||
|
||||
/datum/emote/living/smug
|
||||
key = "smug"
|
||||
key_third_person = "smugs"
|
||||
message = "grins smugly."
|
||||
message_param = "grins smugly at %t."
|
||||
|
||||
/datum/emote/living/sniff
|
||||
key = "sniff"
|
||||
key_third_person = "sniffs"
|
||||
message = "sniffs."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/snore
|
||||
key = "snore"
|
||||
key_third_person = "snores"
|
||||
message = "snores."
|
||||
message_mime = "sleeps soundly."
|
||||
message_simple = "stirs in their sleep."
|
||||
message_robot = "dreams of electric sheep..."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
// lock it so these emotes can only be used while unconscious
|
||||
stat_allowed = UNCONSCIOUS
|
||||
max_stat_allowed = UNCONSCIOUS
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
max_unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/nightmare
|
||||
key = "nightmare"
|
||||
message = "writhes in their sleep."
|
||||
emote_type = EMOTE_VISIBLE
|
||||
stat_allowed = UNCONSCIOUS
|
||||
max_stat_allowed = UNCONSCIOUS
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
max_unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/nightmare/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
user.dir = pick(GLOB.cardinal)
|
||||
|
||||
/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."
|
||||
message_robot = "tests their actuators."
|
||||
|
||||
/datum/emote/living/sulk
|
||||
key = "sulk"
|
||||
key_third_person = "sulks"
|
||||
message = "sulks down sadly."
|
||||
|
||||
/datum/emote/living/sway
|
||||
key = "sway"
|
||||
key_third_person = "sways"
|
||||
message = "sways around dizzily."
|
||||
|
||||
/datum/emote/living/swear
|
||||
key = "swear"
|
||||
key_third_person = "swears"
|
||||
message = "says a swear word!"
|
||||
message_param = "says a swear word at %t!"
|
||||
message_mime = "makes a rude gesture!"
|
||||
message_simple = "makes an angry noise!"
|
||||
message_robot = "makes a particularly offensive series of beeps!"
|
||||
message_postfix = "at %t!"
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
|
||||
mob_type_blacklist_typecache = list(
|
||||
/mob/living/carbon/brain,
|
||||
/mob/living/captive_brain
|
||||
)
|
||||
|
||||
/datum/emote/living/tilt
|
||||
key = "tilt"
|
||||
key_third_person = "tilts"
|
||||
message = "tilts their head to the side."
|
||||
|
||||
/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."
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/twitch_s
|
||||
key = "twitch_s"
|
||||
message = "twitches."
|
||||
unintentional_stat_allowed = UNCONSCIOUS
|
||||
|
||||
/datum/emote/living/whimper
|
||||
key = "whimper"
|
||||
key_third_person = "whimpers"
|
||||
message = "whimpers."
|
||||
message_mime = "appears hurt."
|
||||
emote_type = EMOTE_AUDIBLE | EMOTE_MOUTH
|
||||
muzzled_noises = list("weak", "pathetic")
|
||||
|
||||
/datum/emote/living/wsmile
|
||||
key = "wsmile"
|
||||
key_third_person = "wsmiles"
|
||||
message = "smiles weakly."
|
||||
|
||||
/datum/emote/living/custom
|
||||
key = "me"
|
||||
key_third_person = "custom"
|
||||
message = null
|
||||
mob_type_blacklist_typecache = list(
|
||||
/mob/living/carbon/brain, // nice try
|
||||
/mob/living/captive_brain
|
||||
)
|
||||
|
||||
// Custom emotes should be able to be forced out regardless of context.
|
||||
// It falls on the caller to determine whether or not it should actually be called.
|
||||
unintentional_stat_allowed = DEAD
|
||||
|
||||
/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)
|
||||
var/custom_emote
|
||||
var/custom_emote_type
|
||||
|
||||
if(QDELETED(user))
|
||||
return FALSE
|
||||
else if(check_mute(user?.client?.ckey, MUTE_IC))
|
||||
to_chat(user, "<span class='boldwarning'>You cannot send IC messages (muted).</span>")
|
||||
return FALSE
|
||||
else if(!params)
|
||||
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")
|
||||
custom_emote_type = EMOTE_VISIBLE
|
||||
if("Hearable")
|
||||
custom_emote_type = EMOTE_AUDIBLE
|
||||
else
|
||||
to_chat(user,"<span class='warning'>Unable to use this emote, must be either hearable or visible.</span>")
|
||||
return
|
||||
else
|
||||
custom_emote = params
|
||||
if(type_override)
|
||||
custom_emote_type = type_override
|
||||
|
||||
message = custom_emote
|
||||
emote_type = custom_emote_type
|
||||
. = ..()
|
||||
message = initial(message)
|
||||
emote_type = initial(emote_type)
|
||||
|
||||
/datum/emote/living/custom/replace_pronoun(mob/user, message)
|
||||
// Trust the user said what they mean
|
||||
return message
|
||||
|
||||
@@ -125,7 +125,7 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
var/message_mode = parse_message_mode(message, "headset")
|
||||
|
||||
if(copytext(message, 1, 2) == "*")
|
||||
return emote(copytext(message, 2))
|
||||
return emote(copytext(message, 2), intentional = TRUE)
|
||||
|
||||
//parse the radio code and consume it
|
||||
if(message_mode)
|
||||
@@ -295,44 +295,6 @@ GLOBAL_LIST_EMPTY(channel_to_radio_key)
|
||||
/mob/living/proc/GetVoice()
|
||||
return name
|
||||
|
||||
/mob/living/emote(act, type, message, force) //emote code is terrible, this is so that anything that isn't already snowflaked to shit can call the parent and handle emoting sanely
|
||||
if(client)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='danger'>You cannot speak in IC (Muted).</span>")
|
||||
return
|
||||
|
||||
if(stat)
|
||||
return 0
|
||||
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(act && type && message) //parent call
|
||||
log_emote(message, src)
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
|
||||
if(isnewplayer(M))
|
||||
continue
|
||||
|
||||
if(isobserver(M) && M.get_preference(PREFTOGGLE_CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
|
||||
M.show_message(message)
|
||||
|
||||
switch(type)
|
||||
if(1) //Visible
|
||||
visible_message(message)
|
||||
return 1
|
||||
if(2) //Audible
|
||||
audible_message(message)
|
||||
return 1
|
||||
|
||||
else //everything else failed, emote is probably invalid
|
||||
if(act == "help")
|
||||
return //except help, because help is handled individually
|
||||
to_chat(src, "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>")
|
||||
|
||||
/mob/living/whisper(message as text)
|
||||
message = trim_strip_html_properly(message)
|
||||
|
||||
|
||||
@@ -45,6 +45,6 @@
|
||||
|
||||
/mob/living/silicon/death(gibbed)
|
||||
. = ..()
|
||||
if(!gibbed)
|
||||
if(. && !gibbed)
|
||||
if(death_sound)
|
||||
playsound(get_turf(src), death_sound, 200, 1)
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/mob/living/silicon/emote(act, m_type=1, message = null, force)
|
||||
var/param = null
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
//Emote Cooldown System (it's so simple!)
|
||||
//handle_emote_CD() located in [code\modules\mob\emote.dm]
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
//Cooldown-inducing emotes
|
||||
if("scream", "screams")
|
||||
on_CD = handle_emote_CD(50) //longer cooldown
|
||||
if("ping","pings","buzz","buzzs","buzzes","beep","beeps","yes","no", "buzz2")
|
||||
//halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT.
|
||||
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
|
||||
//Everything else, including typos of the above emotes
|
||||
else
|
||||
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
|
||||
|
||||
if(!force && on_CD == 1) // Check if we need to suppress the emote attempt.
|
||||
return // Suppress emote, you're still cooling off.
|
||||
//--FalseIncarnate
|
||||
|
||||
switch(act)
|
||||
if("ping","pings")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> pings[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("buzz","buzzs","buzzes")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> buzzes[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("beep","beeps")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> beeps[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("yes")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> emits an affirmative blip[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("no")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> emits a negative blip[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("scream", "screams")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> screams[M ? " at [M]" : ""]!"
|
||||
playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0)
|
||||
m_type = 2
|
||||
|
||||
if("buzz2")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> emits an irritated buzzing sound[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
|
||||
if("help")
|
||||
to_chat(src, "yes, no, beep, ping, buzz, scream, buzz2")
|
||||
|
||||
..()
|
||||
@@ -49,9 +49,6 @@
|
||||
|
||||
/mob/living/silicon/robot/death(gibbed)
|
||||
if(can_die())
|
||||
if(!gibbed && deathgasp_on_death)
|
||||
emote("deathgasp", force = TRUE)
|
||||
|
||||
if(module)
|
||||
module.handle_death(src, gibbed)
|
||||
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/mob/living/silicon/robot/drone/say(message)
|
||||
if(copytext(message, 1, 2) == "*")
|
||||
return emote(copytext(message, 2))
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/drone/whisper_say(list/message_pieces)
|
||||
say(multilingual_to_message(message_pieces)) //drones do not get to whisper, only speak normally
|
||||
return 1
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/mob/living/silicon/robot/emote(act, m_type=1, message = null, force)
|
||||
var/param = null
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
//Emote Cooldown System (it's so simple!)
|
||||
//handle_emote_CD() located in [code\modules\mob\emote.dm]
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
//Cooldown-inducing emotes
|
||||
if("law","flip","flips","halt") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT.
|
||||
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
|
||||
if("spin","spins")
|
||||
on_CD = handle_emote_CD(5 SECONDS)
|
||||
//Everything else, including typos of the above emotes
|
||||
else
|
||||
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
|
||||
|
||||
if(!force && on_CD == 1) // Check if we need to suppress the emote attempt.
|
||||
return // Suppress emote, you're still cooling off.
|
||||
//--FalseIncarnate
|
||||
|
||||
switch(act)
|
||||
|
||||
if("salute","salutes")
|
||||
if(!src.buckled)
|
||||
var/M = null
|
||||
if(param)
|
||||
for(var/mob/A in view(null, null))
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if(param)
|
||||
message = "<B>[src]</B> salutes to [param]."
|
||||
else
|
||||
message = "<B>[src]</b> salutes."
|
||||
m_type = 1
|
||||
if("bow","bows")
|
||||
if(!src.buckled)
|
||||
var/M = null
|
||||
if(param)
|
||||
for(var/mob/A in view(null, null))
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if(param)
|
||||
message = "<B>[src]</B> bows to [param]."
|
||||
else
|
||||
message = "<B>[src]</B> bows."
|
||||
m_type = 1
|
||||
|
||||
if("clap","claps")
|
||||
if(!src.restrained())
|
||||
message = "<B>[src]</B> claps."
|
||||
m_type = 2
|
||||
if("flap","flaps")
|
||||
if(!src.restrained())
|
||||
message = "<B>[src]</B> flaps its wings."
|
||||
m_type = 2
|
||||
|
||||
if("aflap","aflaps")
|
||||
if(!src.restrained())
|
||||
message = "<B>[src]</B> flaps its wings ANGRILY!"
|
||||
m_type = 2
|
||||
|
||||
if("twitch")
|
||||
message = "<B>[src]</B> twitches violently."
|
||||
m_type = 1
|
||||
|
||||
if("twitch_s","twitches")
|
||||
message = "<B>[src]</B> twitches."
|
||||
m_type = 1
|
||||
|
||||
if("nod","nods")
|
||||
message = "<B>[src]</B> nods."
|
||||
m_type = 1
|
||||
|
||||
if("deathgasp")
|
||||
message = "<B>[src]</B> shudders violently for a moment, then becomes motionless, its eyes slowly darkening."
|
||||
m_type = 1
|
||||
|
||||
if("glare","glares")
|
||||
var/M = null
|
||||
if(param)
|
||||
for(var/mob/A in view(null, null))
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if(param)
|
||||
message = "<B>[src]</B> glares at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> glares."
|
||||
|
||||
if("stare","stares")
|
||||
var/M = null
|
||||
if(param)
|
||||
for(var/mob/A in view(null, null))
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if(param)
|
||||
message = "<B>[src]</B> stares at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> stares."
|
||||
|
||||
if("look","looks")
|
||||
var/M = null
|
||||
if(param)
|
||||
for(var/mob/A in view(null, null))
|
||||
if(param == A.name)
|
||||
M = A
|
||||
break
|
||||
|
||||
if(!M)
|
||||
param = null
|
||||
|
||||
if(param)
|
||||
message = "<B>[src]</B> looks at [param]."
|
||||
else
|
||||
message = "<B>[src]</B> looks."
|
||||
m_type = 1
|
||||
|
||||
|
||||
if("law")
|
||||
if(istype(module,/obj/item/robot_module/security))
|
||||
message = "<B>[src]</B> shows its legal authorization barcode."
|
||||
|
||||
playsound(src.loc, 'sound/voice/biamthelaw.ogg', 50, 0)
|
||||
m_type = 2
|
||||
else
|
||||
to_chat(src, "You are not THE LAW, pal.")
|
||||
|
||||
if("halt")
|
||||
if(istype(module,/obj/item/robot_module/security))
|
||||
message = "<B>[src]</B>'s speakers skreech, \"Halt! Security!\"."
|
||||
|
||||
playsound(src.loc, 'sound/voice/halt.ogg', 50, 0)
|
||||
m_type = 2
|
||||
else
|
||||
to_chat(src, "You are not security.")
|
||||
|
||||
if("flip","flips")
|
||||
m_type = 1
|
||||
message = "<B>[src]</B> does a flip!"
|
||||
src.SpinAnimation(5,1)
|
||||
|
||||
if("spin","spins")
|
||||
spin(20, 1)
|
||||
message = "<B>[src]</B> spins!"
|
||||
|
||||
if("help")
|
||||
to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitches, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look,\n law, halt, flip, spin")
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/silicon/robot/verb/powerwarn()
|
||||
set category = "Robot Commands"
|
||||
set name = "Power Warning"
|
||||
|
||||
if(handle_emote_CD(50))
|
||||
return
|
||||
|
||||
if(!is_component_functioning("power cell") || !cell || !cell.charge)
|
||||
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
|
||||
"You announce you are operating in low power mode.")
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You can only use this emote when you're out of charge.</span>")
|
||||
@@ -1528,3 +1528,19 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
|
||||
|
||||
/mob/living/silicon/robot/can_see_reagents()
|
||||
return see_reagents
|
||||
|
||||
/mob/living/silicon/robot/verb/powerwarn()
|
||||
set category = "Robot Commands"
|
||||
set name = "Power Warning"
|
||||
|
||||
|
||||
|
||||
if(!is_component_functioning("power cell") || !cell || !cell.charge)
|
||||
if(!start_audio_emote_cooldown(10 SECONDS))
|
||||
to_chat(src, "<span class='warning'>The low-power capacitor for your speaker system is still recharging, please try again later.</span>")
|
||||
return
|
||||
visible_message("<span class='warning'>The power warning light on <span class='name'>[src]</span> flashes urgently.</span>",\
|
||||
"<span class='warning'>You announce you are operating in low power mode.</span>")
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>You can only use this emote when you're out of charge.</span>")
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
to_chat(src, "<i><span class='game say'>Holopad action relayed, <span class='name'>[real_name]</span> <span class='message'>[message]</span></span></i>")
|
||||
|
||||
for(var/mob/M in viewers(T.loc))
|
||||
M.show_message(rendered, 2)
|
||||
M.show_message(rendered, EMOTE_VISIBLE)
|
||||
|
||||
log_emote("(HPAD) [message]", src)
|
||||
else //This shouldn't occur, but better safe then sorry.
|
||||
@@ -107,10 +107,10 @@
|
||||
return
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/emote(act, type, message, force)
|
||||
/mob/living/silicon/ai/emote(act, type, message, intentional = TRUE, force_silence = FALSE)
|
||||
var/obj/machinery/hologram/holopad/T = current
|
||||
if(istype(T) && T.masters[src])//Is the AI using a holopad?
|
||||
src.holopad_emote(message)
|
||||
holopad_emote(message)
|
||||
else //Emote normally, then.
|
||||
..()
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/datum/emote/living/silicon
|
||||
// Humans are allowed for the sake of IPCs
|
||||
mob_type_allowed_typecache = list(/mob/living/silicon, /mob/living/simple_animal/bot, /mob/living/carbon/human)
|
||||
mob_type_blacklist_typecache = list()
|
||||
|
||||
/datum/emote/living/silicon/can_run_emote(mob/user, status_check, intentional)
|
||||
. = ..()
|
||||
// Let IPCs (and people with robo-heads) make beep-boop noises
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/external/head/head = H.get_organ(BODY_ZONE_HEAD)
|
||||
if(head && !head.is_robotic())
|
||||
return FALSE
|
||||
|
||||
/datum/emote/living/silicon/scream
|
||||
key = "scream"
|
||||
key_third_person = "screams"
|
||||
message = "screams!"
|
||||
message_param = "screams at %t!"
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
vary = TRUE
|
||||
sound = "sound/goonstation/voice/robot_scream.ogg"
|
||||
volume = 80
|
||||
|
||||
/datum/emote/living/silicon/ping
|
||||
key = "ping"
|
||||
key_third_person = "pings"
|
||||
message = "pings."
|
||||
message_param = "pings at %t."
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
sound = "sound/machines/ping.ogg"
|
||||
|
||||
/datum/emote/living/silicon/buzz
|
||||
key = "buzz"
|
||||
key_third_person = "buzzes"
|
||||
message = "buzzes."
|
||||
message_param = "buzzes at %t."
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
sound = "sound/machines/buzz-sigh.ogg"
|
||||
|
||||
/datum/emote/living/silicon/buzz2
|
||||
key = "buzz2"
|
||||
message = "emits an irritated buzzing sound."
|
||||
message_param = "emits an irritated buzzing sound at %t."
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
sound = "sound/machines/buzz-two.ogg"
|
||||
|
||||
/datum/emote/living/silicon/beep
|
||||
key = "beep"
|
||||
key_third_person = "beeps"
|
||||
message = "beeps."
|
||||
message_param = "beeps at %t."
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
sound = "sound/machines/twobeep.ogg"
|
||||
|
||||
/datum/emote/living/silicon/yes
|
||||
key = "yes"
|
||||
message = "emits an affirmative blip."
|
||||
message_param = "emits an affirmative blip at %t."
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
sound = "sound/machines/synth_yes.ogg"
|
||||
|
||||
/datum/emote/living/silicon/no
|
||||
key = "no"
|
||||
message = "emits a negative blip."
|
||||
message_param = "emits a negative blip at %t."
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
sound = "sound/machines/synth_no.ogg"
|
||||
|
||||
/datum/emote/living/silicon/law
|
||||
key = "law"
|
||||
message = "shows its legal authorization barcode."
|
||||
message_param = "shows %t its legal authorization barcode."
|
||||
emote_type = EMOTE_SOUND | EMOTE_AUDIBLE
|
||||
sound = "sound/voice/biamthelaw.ogg"
|
||||
|
||||
/datum/emote/living/silicon/law/can_run_emote(mob/user, status_check, intentional)
|
||||
. = ..()
|
||||
var/mob/living/silicon/robot/bot = user
|
||||
if(!istype(bot) || !istype(bot.module, /obj/item/robot_module/security))
|
||||
return FALSE
|
||||
|
||||
/datum/emote/living/silicon/halt
|
||||
key = "halt"
|
||||
message = "screeches \"HALT! SECURITY!\" from its speakers."
|
||||
message_param = "instructs %t to HALT."
|
||||
emote_type = EMOTE_SOUND
|
||||
sound = "sound/voice/halt.ogg"
|
||||
|
||||
/datum/emote/living/silicon/halt/can_run_emote(mob/user, status_check, intentional)
|
||||
. = ..()
|
||||
var/mob/living/silicon/robot/bot = user
|
||||
if(!istype(bot) || !istype(bot.module, /obj/item/robot_module/security))
|
||||
return FALSE
|
||||
@@ -1,4 +1,5 @@
|
||||
//Defines for bots are now found in code\__DEFINES\bots.dm
|
||||
// Emotes for bots are shared with silicon, and are found at code/modules/mob/living/silicon/emotes.dm
|
||||
|
||||
// AI (i.e. game AI, not the AI player) controlled bots
|
||||
/mob/living/simple_animal/bot
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/mob/living/simple_animal/bot/emote(act, m_type = 1, message = null, force)
|
||||
var/param = null
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
//Emote Cooldown System (it's so simple!)
|
||||
//handle_emote_CD() located in [code\modules\mob\emote.dm]
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
//Cooldown-inducing emotes
|
||||
if("scream", "screams")
|
||||
on_CD = handle_emote_CD(50) //longer cooldown
|
||||
if("ping","buzz","beep","yes","no") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT.
|
||||
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
|
||||
//Everything else, including typos of the above emotes
|
||||
else
|
||||
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
|
||||
|
||||
if(!force && on_CD == 1) // Check if we need to suppress the emote attempt.
|
||||
return // Suppress emote, you're still cooling off.
|
||||
//--FalseIncarnate
|
||||
|
||||
switch(act)
|
||||
if("ping")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> pings[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("buzz")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> buzzes[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("beep")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> beeps[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("yes")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> emits an affirmative blip[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("no")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> emits an negative blip[M ? " at [M]" : ""]."
|
||||
playsound(src.loc, 'sound/machines/synth_no.ogg', 50, 0)
|
||||
m_type = 2
|
||||
|
||||
if("scream", "screams")
|
||||
var/M = handle_emote_param(param)
|
||||
|
||||
message = "<B>[src]</B> screams[M ? " at [M]" : ""]!"
|
||||
playsound(src.loc, 'sound/goonstation/voice/robot_scream.ogg', 80, 0)
|
||||
m_type = 2
|
||||
|
||||
if("help")
|
||||
to_chat(src, "scream(s), yes, no, beep, buzz, ping")
|
||||
..()
|
||||
@@ -11,7 +11,6 @@
|
||||
speak_emote = list("purrs", "meows")
|
||||
emote_hear = list("meows", "mews")
|
||||
emote_see = list("shakes its head", "shivers")
|
||||
var/meow_sound = 'sound/creatures/cat_meow.ogg' //Used in emote.
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
see_in_dark = 6
|
||||
@@ -104,26 +103,26 @@
|
||||
/mob/living/simple_animal/pet/cat/handle_automated_action()
|
||||
if(!stat && !buckled)
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("stretches out for a belly rub.", "wags its tail.", "lies down."))
|
||||
StartResting()
|
||||
else if(prob(1))
|
||||
custom_emote(1, pick("sits down.", "crouches on its hind legs.", "looks alert."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("sits down.", "crouches on its hind legs.", "looks alert."))
|
||||
icon_state = "[icon_living]_sit"
|
||||
collar_type = "[initial(collar_type)]_sit"
|
||||
resting = TRUE
|
||||
update_canmove()
|
||||
else if(prob(1))
|
||||
if(resting)
|
||||
custom_emote(1, pick("gets up and meows.", "walks around.", "stops resting."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("gets up and meows.", "walks around.", "stops resting."))
|
||||
StopResting()
|
||||
else
|
||||
custom_emote(1, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat."))
|
||||
|
||||
//MICE!
|
||||
if(eats_mice && isturf(loc) && !incapacitated())
|
||||
for(var/mob/living/simple_animal/mouse/M in view(1, src))
|
||||
if(!M.stat && Adjacent(M))
|
||||
custom_emote(1, "splats \the [M]!")
|
||||
custom_emote(EMOTE_VISIBLE, "splats \the [M]!")
|
||||
M.death()
|
||||
M.splat()
|
||||
movement_target = null
|
||||
@@ -131,7 +130,7 @@
|
||||
break
|
||||
for(var/obj/item/toy/cattoy/T in view(1, src))
|
||||
if(T.cooldown < (world.time - 400))
|
||||
custom_emote(1, "bats \the [T] around with its paw!")
|
||||
custom_emote(EMOTE_VISIBLE, "bats \the [T] around with its paw!")
|
||||
T.cooldown = world.time
|
||||
|
||||
/mob/living/simple_animal/pet/cat/handle_automated_movement()
|
||||
@@ -155,41 +154,6 @@
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
|
||||
/mob/living/simple_animal/pet/cat/emote(act, m_type = 1, message = null, force)
|
||||
if(stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
if("meow")
|
||||
on_CD = handle_emote_CD()
|
||||
if("hiss")
|
||||
on_CD = handle_emote_CD()
|
||||
if("purr")
|
||||
on_CD = handle_emote_CD()
|
||||
else
|
||||
on_CD = 0
|
||||
|
||||
if(!force && on_CD == 1)
|
||||
return
|
||||
|
||||
switch(act)
|
||||
if("meow")
|
||||
message = "<B>[src]</B> [pick(emote_hear)]!"
|
||||
m_type = 2 //audible
|
||||
playsound(src, meow_sound, 50, 0.75)
|
||||
if("hiss")
|
||||
message = "<B>[src]</B> hisses!"
|
||||
m_type = 2
|
||||
if("purr")
|
||||
message = "<B>[src]</B> purrs."
|
||||
m_type = 2
|
||||
if("help")
|
||||
to_chat(src, "scream, meow, hiss, purr")
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/cat/Proc
|
||||
name = "Proc"
|
||||
gender = MALE
|
||||
@@ -215,7 +179,6 @@
|
||||
icon_living = "Syndicat"
|
||||
icon_dead = "Syndicat_dead"
|
||||
icon_resting = "Syndicat_rest"
|
||||
meow_sound = null //Need robo-meow.
|
||||
gender = FEMALE
|
||||
faction = list("syndicate")
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
melee_damage_upper = 8
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
var/chirp_sound = 'sound/creatures/nymphchirp.ogg' //used in emote
|
||||
|
||||
speed = 0
|
||||
stop_automated_movement = 0
|
||||
@@ -277,31 +276,6 @@
|
||||
to_chat(src, "<span class='warning'>You don't have any hands!</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/diona/emote(act, m_type = 1, message = null, force)
|
||||
if(stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
if("chirp")
|
||||
on_CD = handle_emote_CD()
|
||||
else
|
||||
on_CD = 0
|
||||
|
||||
if(!force && on_CD == 1)
|
||||
return
|
||||
|
||||
switch(act) //IMPORTANT: Emotes MUST NOT CONFLICT anywhere along the chain.
|
||||
if("chirp")
|
||||
message = "<B>\The [src]</B> chirps!"
|
||||
m_type = 2 //audible
|
||||
playsound(src, chirp_sound, 40, 1, 1)
|
||||
if("help")
|
||||
to_chat(src, "scream, chirp")
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/diona/npc_safe(mob/user)
|
||||
if(!jobban_isbanned(user, ROLE_NYMPH))
|
||||
return TRUE
|
||||
|
||||
@@ -43,40 +43,6 @@
|
||||
return
|
||||
playsound(src, yelp_sound, 75, TRUE)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/emote(act, m_type = 1, message = null, force)
|
||||
if(incapacitated())
|
||||
return
|
||||
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
if("bark")
|
||||
on_CD = handle_emote_CD()
|
||||
if("yelp")
|
||||
on_CD = handle_emote_CD()
|
||||
else
|
||||
on_CD = 0
|
||||
|
||||
if(!force && on_CD == 1)
|
||||
return
|
||||
|
||||
switch(act)
|
||||
if("bark")
|
||||
message = "<B>[src]</B> [pick(src.speak_emote)]!"
|
||||
m_type = 2 //audible
|
||||
playsound(src, pick(src.bark_sound), 50, TRUE)
|
||||
if("yelp")
|
||||
message = "<B>[src]</B> yelps!"
|
||||
m_type = 2 //audible
|
||||
playsound(src, yelp_sound, 75, TRUE)
|
||||
if("growl")
|
||||
message = "<B>[src]</B> growls!"
|
||||
m_type = 2 //audible
|
||||
if("help")
|
||||
to_chat(src, "scream, bark, growl")
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
switch(M.a_intent)
|
||||
@@ -90,10 +56,10 @@
|
||||
if(change > 0)
|
||||
if(M && stat != DEAD) // Added check to see if this mob (the corgi) is dead to fix issue 2454
|
||||
new /obj/effect/temp_visual/heart(loc)
|
||||
custom_emote(1, "yaps happily!")
|
||||
custom_emote(EMOTE_VISIBLE, "yaps happily!")
|
||||
else
|
||||
if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case)
|
||||
custom_emote(1, "growls!")
|
||||
emote("growl")
|
||||
|
||||
//Corgis and pugs are now under one dog subtype
|
||||
|
||||
@@ -564,7 +530,7 @@
|
||||
if(isturf(movement_target.loc))
|
||||
movement_target.attack_animal(src) // Eat the thing
|
||||
else if(prob(30) && ishuman(movement_target.loc)) // mean hooman has stolen it
|
||||
custom_emote(EMOTE_VISUAL, "stares at [movement_target.loc]'s [movement_target] with a sad puppy-face.")
|
||||
custom_emote(EMOTE_VISIBLE, "stares at [movement_target.loc]'s [movement_target] with a sad puppy-face.")
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/corgi
|
||||
name = "Corgi meat"
|
||||
@@ -669,7 +635,7 @@
|
||||
. = ..()
|
||||
if(!resting && !buckled)
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("dances around.","chases her tail."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("dances around.","chases her tail."))
|
||||
spin(20, 1)
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/exoticcorgi
|
||||
@@ -765,7 +731,7 @@
|
||||
. = ..()
|
||||
if(!resting && !buckled)
|
||||
if(prob(1))
|
||||
custom_emote(1, pick("chases its tail."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("chases its tail."))
|
||||
spawn(0)
|
||||
for(var/i in list(1, 2, 4, 8, 4, 2, 1, 2, 4, 8, 4, 2, 1, 2, 4, 8, 4, 2))
|
||||
dir = i
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/datum/emote/living/simple_animal
|
||||
mob_type_allowed_typecache = list(/mob/living/simple_animal)
|
||||
|
||||
/datum/emote/living/simple_animal/diona_chirp
|
||||
key = "chirp"
|
||||
key_third_person = "chirps"
|
||||
message = "chirps!"
|
||||
sound = "sound/creatures/nymphchirp.ogg"
|
||||
emote_type = EMOTE_SOUND
|
||||
mob_type_allowed_typecache = list(/mob/living/simple_animal/diona)
|
||||
|
||||
// Dog emotes
|
||||
|
||||
/datum/emote/living/simple_animal/pet/dog
|
||||
mob_type_allowed_typecache = list(/mob/living/simple_animal/pet/dog)
|
||||
|
||||
/datum/emote/living/simple_animal/pet/dog/bark
|
||||
key = "bark"
|
||||
key_third_person = "barks"
|
||||
message = "barks."
|
||||
message_param = "barks at %t."
|
||||
emote_type = EMOTE_SOUND
|
||||
|
||||
/datum/emote/living/simple_animal/pet/dog/bark/get_sound(mob/living/user)
|
||||
. = ..()
|
||||
|
||||
var/mob/living/simple_animal/pet/dog/D = user
|
||||
message = pick(D.speak_emote)
|
||||
return pick(D.bark_sound)
|
||||
|
||||
/datum/emote/living/simple_animal/pet/dog/yelp
|
||||
key = "yelp"
|
||||
key_third_person = "yelps"
|
||||
message = "yelps!"
|
||||
message_param = "yelps at %t!"
|
||||
emote_type = EMOTE_SOUND
|
||||
|
||||
/datum/emote/living/simple_animal/pet/dog/yelp/get_sound(mob/living/user)
|
||||
var/mob/living/simple_animal/pet/dog/D = user
|
||||
return D.yelp_sound
|
||||
|
||||
/datum/emote/living/simple_animal/pet/dog/growl
|
||||
key = "growl"
|
||||
key_third_person = "growls"
|
||||
message = "growls!"
|
||||
message_param = "growls at %t!"
|
||||
emote_type = EMOTE_SOUND
|
||||
sound = "growl"
|
||||
|
||||
// Mouse
|
||||
|
||||
/datum/emote/living/simple_animal/mouse
|
||||
mob_type_allowed_typecache = list(/mob/living/simple_animal/mouse)
|
||||
|
||||
/datum/emote/living/simple_animal/mouse/squeak
|
||||
key = "squeak"
|
||||
key_third_person = "squeaks"
|
||||
message = "squeaks!"
|
||||
message_param = "squeaks at %t!"
|
||||
emote_type = EMOTE_SOUND
|
||||
|
||||
/datum/emote/living/simple_animal/mouse/squeak/get_sound(mob/living/user)
|
||||
var/mob/living/simple_animal/mouse/M = user
|
||||
return M.squeak_sound
|
||||
|
||||
// cat
|
||||
|
||||
/datum/emote/living/simple_animal/pet/cat
|
||||
mob_type_allowed_typecache = list(/mob/living/simple_animal/pet/cat)
|
||||
|
||||
/datum/emote/living/simple_animal/pet/cat/meow
|
||||
key = "meow"
|
||||
key_third_person = "meows"
|
||||
message = "meows."
|
||||
message_param = "meows at %t."
|
||||
sound = "sound/creatures/cat_meow.ogg"
|
||||
emote_type = EMOTE_SOUND
|
||||
|
||||
/datum/emote/living/simple_animal/pet/cat/meow/run_emote(mob/user, params, type_override, intentional)
|
||||
var/mob/living/simple_animal/pet/cat/C = user
|
||||
message = pick(C.emote_hear)
|
||||
. = ..()
|
||||
|
||||
/datum/emote/living/simple_animal/pet/cat/hiss
|
||||
key = "hiss"
|
||||
key_third_person = "hisses"
|
||||
message = "hisses!"
|
||||
message_param = "hisses at %t!"
|
||||
|
||||
/datum/emote/living/simple_animal/pet/cat/purr
|
||||
key = "purr"
|
||||
key_third_person = "purrs"
|
||||
message = "purrs."
|
||||
@@ -67,7 +67,7 @@
|
||||
if(prob(1))
|
||||
StopResting()
|
||||
else if(prob(5))
|
||||
custom_emote(2, "snuffles")
|
||||
custom_emote(EMOTE_AUDIBLE, "snuffles")
|
||||
else if(prob(0.5))
|
||||
StartResting()
|
||||
|
||||
@@ -119,31 +119,6 @@
|
||||
if(client)
|
||||
client.time_died_as_mouse = world.time
|
||||
|
||||
/mob/living/simple_animal/mouse/emote(act, m_type = 1, message = null, force)
|
||||
if(stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
var/on_CD = 0
|
||||
act = lowertext(act)
|
||||
switch(act)
|
||||
if("squeak") //Mouse time
|
||||
on_CD = handle_emote_CD()
|
||||
else
|
||||
on_CD = 0
|
||||
|
||||
if(!force && on_CD == 1)
|
||||
return
|
||||
|
||||
switch(act)
|
||||
if("squeak")
|
||||
message = "<B>\The [src]</B> [pick(emote_hear)]!"
|
||||
m_type = 2 //audible
|
||||
playsound(src, squeak_sound, 40, 1)
|
||||
if("help")
|
||||
to_chat(src, "scream, squeak")
|
||||
|
||||
..()
|
||||
|
||||
/*
|
||||
* Mouse types
|
||||
*/
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
return
|
||||
if(resting)
|
||||
if(!wants_to_rest())
|
||||
custom_emote(1, "growls, and gets up.")
|
||||
custom_emote(EMOTE_VISIBLE, "growls, and gets up.")
|
||||
playsound(get_turf(src), 'sound/hallucinations/growl2.ogg', 50, 1)
|
||||
StopResting()
|
||||
else if(wants_to_rest())
|
||||
custom_emote(1, "lays down, and starts to lick their wounds.")
|
||||
custom_emote(EMOTE_VISIBLE, "lays down, and starts to lick their wounds.")
|
||||
StartResting()
|
||||
|
||||
/mob/living/simple_animal/hostile/hellhound/examine(mob/user)
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
/mob/living/simple_animal/hostile/proc/Aggro()
|
||||
vision_range = aggro_vision_range
|
||||
if(target && emote_taunt.len && prob(taunt_chance))
|
||||
emote("me", 1, "[pick(emote_taunt)] at [target].")
|
||||
custom_emote(EMOTE_VISIBLE, "[pick(emote_taunt)] at [target].")
|
||||
taunt_chance = max(taunt_chance-7,2)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LoseAggro()
|
||||
|
||||
@@ -394,7 +394,7 @@ Difficulty: Medium
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/visible_message()
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/visible_message(message, self_message, blind_message)
|
||||
if(swooping & SWOOP_INVULNERABLE) //to suppress attack messages without overriding every single proc that could send a message saying we got hit
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
/mob/living/simple_animal/parrot/death(gibbed)
|
||||
if(can_die())
|
||||
if(held_item)
|
||||
custom_emote(EMOTE_VISUAL, "lets go of [held_item]!")
|
||||
custom_emote(EMOTE_VISIBLE, "lets go of [held_item]!")
|
||||
drop_held_item()
|
||||
walk(src, 0)
|
||||
return ..()
|
||||
@@ -247,7 +247,7 @@
|
||||
parrot_state |= PARROT_ATTACK
|
||||
else
|
||||
if(held_item)
|
||||
custom_emote(EMOTE_VISUAL, "lets go of [held_item]!")
|
||||
custom_emote(EMOTE_VISIBLE, "lets go of [held_item]!")
|
||||
|
||||
parrot_state |= PARROT_FLEE //Otherwise, fly like a bat out of hell!
|
||||
drop_held_item(FALSE)
|
||||
@@ -347,7 +347,7 @@
|
||||
//Search for item to steal
|
||||
parrot_interest = search_for_perch_and_item()
|
||||
if(parrot_interest)
|
||||
custom_emote(EMOTE_VISUAL, "looks in [parrot_interest]'s direction and takes flight.")
|
||||
custom_emote(EMOTE_VISIBLE, "looks in [parrot_interest]'s direction and takes flight.")
|
||||
parrot_state = PARROT_SWOOP|PARROT_STEAL
|
||||
icon_state = "parrot_fly"
|
||||
return
|
||||
@@ -371,7 +371,7 @@
|
||||
parrot_interest = AM
|
||||
parrot_state = PARROT_SWOOP|PARROT_STEAL
|
||||
face_atom(AM)
|
||||
custom_emote(EMOTE_VISUAL, "turns and flies towards [parrot_interest].")
|
||||
custom_emote(EMOTE_VISIBLE, "turns and flies towards [parrot_interest].")
|
||||
return
|
||||
else //Else it's a perch
|
||||
parrot_perch = AM
|
||||
@@ -493,10 +493,10 @@
|
||||
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
|
||||
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, MELEE), sharp = TRUE)
|
||||
custom_emote(EMOTE_VISUAL, pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("pecks [H]'s [affecting].", "cuts [H]'s [affecting] with its talons."))
|
||||
else
|
||||
L.adjustBruteLoss(damage)
|
||||
custom_emote(EMOTE_VISUAL, pick("pecks at [L].", "claws [L]."))
|
||||
custom_emote(EMOTE_VISIBLE, pick("pecks at [L].", "claws [L]."))
|
||||
return
|
||||
//Otherwise, fly towards the mob!
|
||||
else
|
||||
|
||||
@@ -229,23 +229,23 @@
|
||||
else
|
||||
randomValue -= speak.len
|
||||
if(emote_see && randomValue <= emote_see.len)
|
||||
custom_emote(1, pick(emote_see))
|
||||
custom_emote(EMOTE_VISIBLE, pick(emote_see))
|
||||
else
|
||||
custom_emote(2, pick(emote_hear))
|
||||
custom_emote(EMOTE_AUDIBLE, pick(emote_hear))
|
||||
else
|
||||
say(pick(speak))
|
||||
else
|
||||
if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
||||
custom_emote(1, pick(emote_see))
|
||||
custom_emote(EMOTE_VISIBLE, pick(emote_see))
|
||||
if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len))
|
||||
custom_emote(2, pick(emote_hear))
|
||||
custom_emote(EMOTE_AUDIBLE, pick(emote_hear))
|
||||
if((emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
||||
var/length = emote_hear.len + emote_see.len
|
||||
var/pick = rand(1,length)
|
||||
if(pick <= emote_see.len)
|
||||
custom_emote(1, pick(emote_see))
|
||||
custom_emote(EMOTE_VISIBLE, pick(emote_see))
|
||||
else
|
||||
custom_emote(2,pick(emote_hear))
|
||||
custom_emote(EMOTE_AUDIBLE, pick(emote_hear))
|
||||
|
||||
|
||||
/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment)
|
||||
@@ -316,20 +316,6 @@
|
||||
pcollar.forceMove(drop_location())
|
||||
pcollar = null
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/emote(act, m_type = 1, message = null, force)
|
||||
if(stat)
|
||||
return
|
||||
act = lowertext(act)
|
||||
switch(act) //IMPORTANT: Emotes MUST NOT CONFLICT anywhere along the chain.
|
||||
if("scream")
|
||||
message = "<B>\The [src]</B> whimpers."
|
||||
m_type = 2
|
||||
if("help")
|
||||
to_chat(src, "scream")
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/say_quote(message)
|
||||
var/verb = "says"
|
||||
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/mob/living/simple_animal/slime/emote(act, m_type = 1, message = null, force)
|
||||
if(stat)
|
||||
return
|
||||
|
||||
if(findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
//param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_'
|
||||
act = copytext(act,1,length(act))
|
||||
|
||||
act = lowertext(act)
|
||||
|
||||
var/regenerate_icons
|
||||
|
||||
switch(act) //Alphabetical please
|
||||
if("me")
|
||||
if(HAS_TRAIT(src, TRAIT_MUTE))
|
||||
return
|
||||
if(src.client)
|
||||
if(check_mute(client.ckey, MUTE_IC))
|
||||
to_chat(src, "<span class='warning'>You cannot send IC messages (muted).</span>")
|
||||
return
|
||||
if(src.client.handle_spam_prevention(message, MUTE_IC))
|
||||
return
|
||||
if(stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
return custom_emote(m_type, message)
|
||||
if("bounce")
|
||||
message = "<B>[src]</B> bounces in place."
|
||||
m_type = 1
|
||||
|
||||
if("custom")
|
||||
return custom_emote(m_type, message)
|
||||
|
||||
if("jiggle")
|
||||
message = "<B>[src]</B> jiggles!"
|
||||
m_type = 1
|
||||
|
||||
if("light")
|
||||
message = "<B>[src]</B> lights up for a bit, then stops."
|
||||
m_type = 1
|
||||
|
||||
if("moan")
|
||||
message = "<B>[src]</B> moans."
|
||||
m_type = 2
|
||||
|
||||
if("shiver")
|
||||
message = "<B>[src]</B> shivers."
|
||||
m_type = 2
|
||||
|
||||
if("sway")
|
||||
message = "<B>[src]</B> sways around dizzily."
|
||||
m_type = 1
|
||||
|
||||
if("twitch")
|
||||
message = "<B>[src]</B> twitches."
|
||||
m_type = 1
|
||||
|
||||
if("vibrate")
|
||||
message = "<B>[src]</B> vibrates!"
|
||||
m_type = 1
|
||||
|
||||
if("noface") //mfw I have no face
|
||||
mood = null
|
||||
regenerate_icons = 1
|
||||
|
||||
if("smile")
|
||||
mood = "mischevous"
|
||||
regenerate_icons = 1
|
||||
|
||||
if(":3")
|
||||
mood = ":33"
|
||||
regenerate_icons = 1
|
||||
|
||||
if("pout")
|
||||
mood = "pout"
|
||||
regenerate_icons = 1
|
||||
|
||||
if("frown")
|
||||
mood = "sad"
|
||||
regenerate_icons = 1
|
||||
|
||||
if("scowl")
|
||||
mood = "angry"
|
||||
regenerate_icons = 1
|
||||
|
||||
if("help") //This is an exception
|
||||
to_chat(src, "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate. \n\nYou may also change your face with: \n\nsmile, :3, pout, frown, scowl, noface")
|
||||
|
||||
else
|
||||
to_chat(src, "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>")
|
||||
if((message && stat == CONSCIOUS))
|
||||
if(client)
|
||||
log_emote("[name]/[key] : [message]", src)
|
||||
if(m_type & 1)
|
||||
visible_message(message)
|
||||
else
|
||||
loc.audible_message(message)
|
||||
|
||||
if(regenerate_icons)
|
||||
regenerate_icons()
|
||||
@@ -0,0 +1,66 @@
|
||||
/// Sentinel value; passing this as mood sets mood to null.
|
||||
#define MOOD_RESET "reset"
|
||||
|
||||
/datum/emote/living/simple_animal/slime
|
||||
mob_type_allowed_typecache = list(/mob/living/simple_animal/slime)
|
||||
/// Apply mood of the emote. Set this to MOOD_RESET to cause the emote to reset the mood back to default.
|
||||
var/mood
|
||||
|
||||
/datum/emote/living/simple_animal/slime/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
if(mood)
|
||||
var/mob/living/simple_animal/slime/S = user
|
||||
if(mood == MOOD_RESET)
|
||||
S.mood = null
|
||||
else
|
||||
S.mood = mood
|
||||
|
||||
/datum/emote/living/simple_animal/slime/bounce
|
||||
key = "bounce"
|
||||
key_third_person = "bounces"
|
||||
message = "bounces in place."
|
||||
|
||||
/datum/emote/living/simple_animal/slime/jiggle
|
||||
key = "jiggle"
|
||||
key_third_person = "jiggles"
|
||||
message = "jiggles!"
|
||||
|
||||
/datum/emote/living/simple_animal/slime/light
|
||||
key = "light"
|
||||
key_third_person = "lights"
|
||||
message = "lights up for a bit, then stops."
|
||||
|
||||
/datum/emote/living/simple_animal/slime/vibrate
|
||||
key = "vibrate"
|
||||
key_third_person = "vibrates"
|
||||
message = "vibrates!"
|
||||
|
||||
/datum/emote/living/simple_animal/slime/noface
|
||||
// mfw no face
|
||||
key = "noface"
|
||||
mood = MOOD_RESET
|
||||
|
||||
/datum/emote/living/simple_animal/slime/smile
|
||||
key = "smile"
|
||||
mood = "mischevous"
|
||||
|
||||
/datum/emote/living/simple_animal/slime/colon_three
|
||||
key = ":3"
|
||||
mood = ":33"
|
||||
|
||||
/datum/emote/living/simple_animal/slime/pout
|
||||
key = "pout"
|
||||
mood = "pout"
|
||||
|
||||
/datum/emote/living/simple_animal/slime/sad
|
||||
key = "frown"
|
||||
mood = "sad"
|
||||
|
||||
/datum/emote/living/simple_animal/slime/scowl
|
||||
key = "scowl"
|
||||
mood = "angry"
|
||||
|
||||
#undef MOOD_RESET
|
||||
+13
-13
@@ -70,26 +70,26 @@
|
||||
t+= "<span class='notice'>N2O: [environment.sleeping_agent] \n</span>"
|
||||
t+= "<span class='notice'>Agent B: [environment.agent_b] \n</span>"
|
||||
|
||||
usr.show_message(t, 1)
|
||||
usr.show_message(t, EMOTE_VISIBLE)
|
||||
|
||||
/mob/proc/show_message(msg, type, alt, alt_type)//Message, type of message (1 or 2), alternative message, alt message type (1 or 2)
|
||||
|
||||
if(!client) return
|
||||
|
||||
if(type)
|
||||
if(type & 1 && !has_vision(information_only=TRUE))//Vision related
|
||||
if(type & EMOTE_VISIBLE && !has_vision(information_only=TRUE))//Vision related
|
||||
if(!(alt))
|
||||
return
|
||||
else
|
||||
msg = alt
|
||||
type = alt_type
|
||||
if(type & EMOTE_AUDIBLE && !can_hear())//Hearing related
|
||||
if(!( alt ))
|
||||
return
|
||||
else
|
||||
msg = alt
|
||||
type = alt_type
|
||||
if(type & 2 && !can_hear())//Hearing related
|
||||
if(!( alt ))
|
||||
return
|
||||
else
|
||||
msg = alt
|
||||
type = alt_type
|
||||
if(type & 1 && !has_vision(information_only=TRUE))
|
||||
if(type & EMOTE_VISIBLE && !has_vision(information_only=TRUE))
|
||||
return
|
||||
// Added voice muffling for Issue 41.
|
||||
if(stat == UNCONSCIOUS)
|
||||
@@ -111,7 +111,7 @@
|
||||
var/msg = message
|
||||
if(self_message && M == src)
|
||||
msg = self_message
|
||||
M.show_message(msg, 1, blind_message, 2)
|
||||
M.show_message(msg, EMOTE_VISIBLE, blind_message, EMOTE_AUDIBLE)
|
||||
|
||||
// Show a message to all mobs in sight of this atom
|
||||
// Use for objects performing visible actions
|
||||
@@ -121,7 +121,7 @@
|
||||
for(var/mob/M in get_mobs_in_view(7, src))
|
||||
if(!M.client)
|
||||
continue
|
||||
M.show_message(message, 1, blind_message, 2)
|
||||
M.show_message(message, EMOTE_VISIBLE, blind_message, EMOTE_AUDIBLE)
|
||||
|
||||
// Show a message to all mobs in earshot of this one
|
||||
// This would be for audible actions by the src mob
|
||||
@@ -135,7 +135,7 @@
|
||||
range = hearing_distance
|
||||
var/msg = message
|
||||
for(var/mob/M in get_mobs_in_view(range, src))
|
||||
M.show_message(msg, 2, deaf_message, 1)
|
||||
M.show_message(msg, EMOTE_AUDIBLE, deaf_message, EMOTE_VISIBLE)
|
||||
|
||||
// based on say code
|
||||
var/omsg = replacetext(message, "<B>[src]</B> ", "")
|
||||
@@ -161,7 +161,7 @@
|
||||
if(hearing_distance)
|
||||
range = hearing_distance
|
||||
for(var/mob/M in get_mobs_in_view(range, src))
|
||||
M.show_message(message, 2, deaf_message, 1)
|
||||
M.show_message(message, EMOTE_AUDIBLE, deaf_message, EMOTE_VISIBLE)
|
||||
|
||||
/mob/proc/findname(msg)
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
var/list/languages = list() // For speaking/listening.
|
||||
var/list/abilities = list() // For species-derived or admin-given powers.
|
||||
var/list/speak_emote = list("says") // Verbs used when speaking. Defaults to 'say' if speak_emote is null.
|
||||
var/emote_type = 1 // Define emote default type, 1 for seen emotes, 2 for heard emotes
|
||||
var/emote_type = EMOTE_VISIBLE // Define emote default type, 1 for seen emotes, 2 for heard emotes
|
||||
var/name_archive //For admin things like possession
|
||||
|
||||
var/timeofdeath = 0 //Living
|
||||
@@ -98,7 +98,17 @@
|
||||
|
||||
var/in_throw_mode = 0
|
||||
|
||||
var/emote_cd = 0 // Used to supress emote spamming. 1 if on CD, 2 if disabled by admin (manually set), else 0
|
||||
// See /datum/emote
|
||||
|
||||
/// Cooldown on audio effects from emotes.
|
||||
var/audio_emote_cd_status = EMOTE_READY
|
||||
|
||||
/// Override for cooldowns on non-audio emotes. Should be a number in deciseconds.
|
||||
var/emote_cooldown_override = null
|
||||
|
||||
/// Tracks last uses of emotes for cooldown purposes
|
||||
var/list/emotes_used
|
||||
var/list/emotes_on_cooldown
|
||||
|
||||
var/job = null //Living
|
||||
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
|
||||
// The datum in use is defined in code/datums/emotes.dm
|
||||
|
||||
/**
|
||||
* Send an emote.
|
||||
*
|
||||
* * emote_key: Key of the emote being triggered
|
||||
* * m_type: Type of the emote, like EMOTE_AUDIBLE. If this is not null, the default type of the emote will be overridden.
|
||||
* * message: Custom parameter for the emote. This should be used if you want to pass something like a target programmatically.
|
||||
* * intentional: Whether or not the emote was deliberately triggered by the mob. If true, it's forced, which skips some checks when calling the emote.
|
||||
* * force_silence: If true, unusable/nonexistent emotes will not notify the user.
|
||||
*/
|
||||
/mob/proc/emote(emote_key, type_override = null, message = null, intentional = FALSE, force_silence = FALSE)
|
||||
emote_key = lowertext(emote_key)
|
||||
var/param = message
|
||||
var/custom_param_offset = findtext(emote_key, EMOTE_PARAM_SEPARATOR, 1, null)
|
||||
if(custom_param_offset)
|
||||
param = copytext(emote_key, custom_param_offset + length(emote_key[custom_param_offset]))
|
||||
emote_key = copytext(emote_key, 1, custom_param_offset)
|
||||
|
||||
var/list/key_emotes = GLOB.emote_list[emote_key]
|
||||
|
||||
if(!length(key_emotes))
|
||||
if(intentional && !force_silence)
|
||||
to_chat(src, "<span class='notice'>'[emote_key]' emote does not exist. Say *help for a list.</span>")
|
||||
else if(!intentional)
|
||||
CRASH("Emote with key [emote_key] was attempted to be called, though doesn't exist!")
|
||||
return FALSE
|
||||
var/silenced = FALSE
|
||||
for(var/datum/emote/P in key_emotes)
|
||||
if(!P.check_cooldown(src, intentional))
|
||||
// if an emote's on cooldown, don't spam them with messages of not being able to use it
|
||||
silenced = TRUE
|
||||
continue
|
||||
if(P.try_run_emote(src, param, type_override, intentional))
|
||||
return TRUE
|
||||
if(intentional && !silenced && !force_silence)
|
||||
to_chat(src, "<span class='notice'>Unusable emote '[emote_key]'. Say *help for a list.</span>")
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Perform a custom emote.
|
||||
*
|
||||
* * m_type: Type of message to send.
|
||||
* * message: Content of the message. If none is provided, the user will be prompted to choose the input.
|
||||
* * intentional: Whether or not the user intendeded to perform the emote.
|
||||
*/
|
||||
/mob/proc/custom_emote(m_type = EMOTE_VISIBLE, message = null, intentional = FALSE)
|
||||
var/input = ""
|
||||
if(!message && !client)
|
||||
CRASH("An empty custom emote was called from a client-less mob.")
|
||||
else if (!message)
|
||||
input = sanitize(copytext(input(src,"Choose an emote to display.") as text|null, 1, MAX_MESSAGE_LEN))
|
||||
else
|
||||
input = message
|
||||
|
||||
emote("me", m_type, input, intentional)
|
||||
|
||||
/**
|
||||
* Get a list of all emote keys usable by the current mob.
|
||||
*
|
||||
* * intentional_use: Whether or not to check based on if the action was intentional.
|
||||
*/
|
||||
/mob/proc/usable_emote_keys(intentional_use = TRUE)
|
||||
var/list/all_keys = list()
|
||||
for(var/key in GLOB.emote_list)
|
||||
for(var/datum/emote/P in GLOB.emote_list[key])
|
||||
if(P.key in all_keys)
|
||||
continue
|
||||
if(P.can_run_emote(src, status_check = FALSE, intentional = null))
|
||||
all_keys += P.key
|
||||
if(P.key_third_person)
|
||||
all_keys += P.key_third_person
|
||||
|
||||
return all_keys
|
||||
|
||||
/datum/emote/help
|
||||
key = "help"
|
||||
mob_type_ignore_stat_typecache = list(/mob/dead/observer, /mob/living/silicon/ai)
|
||||
|
||||
/datum/emote/help/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
var/list/base_keys = list()
|
||||
var/list/all_keys = list()
|
||||
var/list/species_emotes = list()
|
||||
var/list/message = list("Available emotes, you can use them with say \"*emote\": ")
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
for(var/key in GLOB.emote_list)
|
||||
for(var/datum/emote/P in GLOB.emote_list[key])
|
||||
var/full_key = P.key
|
||||
if(P.key in all_keys)
|
||||
continue
|
||||
if(P.can_run_emote(user, status_check = FALSE, intentional = TRUE))
|
||||
if(P.message_param && P.param_desc)
|
||||
// Add our parameter description, like flap-user
|
||||
full_key = P.key + "\[[EMOTE_PARAM_SEPARATOR][P.param_desc]\]"
|
||||
if(istype(H) && P.species_type_whitelist_typecache && H.dna && is_type_in_typecache(H.dna.species, P.species_type_whitelist_typecache))
|
||||
species_emotes += full_key
|
||||
else
|
||||
base_keys += full_key
|
||||
all_keys += P.key
|
||||
|
||||
base_keys = sortList(base_keys)
|
||||
message += base_keys.Join(", ")
|
||||
message += "."
|
||||
message = message.Join("")
|
||||
if(length(species_emotes) > 0)
|
||||
species_emotes = sortList(species_emotes)
|
||||
message += "\n<u>[user?.dna?.species.name] specific emotes</u> :- "
|
||||
message += species_emotes.Join(", ")
|
||||
message += "."
|
||||
to_chat(user, message)
|
||||
|
||||
/datum/emote/flip
|
||||
key = "flip"
|
||||
key_third_person = "flips"
|
||||
message = "does a flip!"
|
||||
hands_use_check = TRUE
|
||||
emote_type = EMOTE_VISIBLE | EMOTE_FORCE_NO_RUNECHAT // don't need an emote to see that
|
||||
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer) // okay but what if we allowed ghosts to flip as well
|
||||
mob_type_blacklist_typecache = list(/mob/living/carbon/brain, /mob/camera, /mob/living/silicon/ai)
|
||||
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
|
||||
|
||||
/datum/emote/flip/run_emote(mob/user, params, type_override, intentional)
|
||||
|
||||
if(isobserver(user))
|
||||
user.SpinAnimation(5, 1)
|
||||
return TRUE
|
||||
|
||||
var/mob/living/L = user
|
||||
|
||||
if(user.lying || (istype(L) && L.IsWeakened()))
|
||||
message = "flops and flails around on the floor."
|
||||
return ..()
|
||||
else if(params)
|
||||
message_param = "flips in %t's general direction."
|
||||
else if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H.get_active_hand(), /obj/item/grab))
|
||||
var/obj/item/grab/G = H.get_active_hand()
|
||||
if(G && G.affecting)
|
||||
if(H.buckled || G.affecting.buckled)
|
||||
to_chat(user, "<span class='warning'>[G.affecting] is buckled, you can't flip around [G.affecting.p_them()]!</span>")
|
||||
return TRUE
|
||||
var/turf/oldloc = user.loc
|
||||
var/turf/newloc = G.affecting.loc
|
||||
if(isturf(oldloc) && isturf(newloc))
|
||||
user.SpinAnimation(5, 1)
|
||||
user.glide_for(0.6 SECONDS) // This and the glide_for below are purely arbitrary. Pick something that looks aesthetically pleasing.
|
||||
user.forceMove(newloc)
|
||||
G.glide_for(0.6 SECONDS)
|
||||
G.affecting.forceMove(oldloc)
|
||||
message = "flips over [G.affecting]!"
|
||||
return ..()
|
||||
|
||||
user.SpinAnimation(5, 1)
|
||||
|
||||
if(prob(5) && ishuman(user))
|
||||
message = "attempts a flip and crashes to the floor!"
|
||||
sleep(0.3 SECONDS)
|
||||
if(istype(L))
|
||||
L.Weaken(4 SECONDS)
|
||||
return ..()
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/emote/spin
|
||||
key = "spin"
|
||||
key_third_person = "spins"
|
||||
hands_use_check = TRUE
|
||||
emote_type = EMOTE_VISIBLE | EMOTE_FORCE_NO_RUNECHAT
|
||||
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer)
|
||||
mob_type_blacklist_typecache = list(/mob/living/carbon/brain, /mob/camera, /mob/living/silicon/ai)
|
||||
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
|
||||
cooldown = 2 SECONDS // how long the spin takes, any faster and mobs can spin
|
||||
|
||||
/datum/emote/spin/run_emote(mob/user, params, type_override, intentional)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
|
||||
if(prob(95) || isobserver(user) || !ishuman(user))
|
||||
user.spin(20, 1)
|
||||
return TRUE
|
||||
|
||||
user.spin(32, 1)
|
||||
to_chat(user, "<span class='warning'>You spin too much!</span>")
|
||||
var/mob/living/L = user
|
||||
if(istype(L))
|
||||
L.Dizzy(24 SECONDS)
|
||||
L.Confused(24 SECONDS)
|
||||
@@ -744,3 +744,48 @@ GLOBAL_LIST_INIT(intents, list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM
|
||||
message_admins("[src.ckey] just got booted back to lobby with no jobs enabled, but antag rolling enabled. Likely antag rolling abuse.")
|
||||
return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Helper proc to determine if a mob can use emotes that make sound or not.
|
||||
*/
|
||||
/mob/proc/can_use_audio_emote()
|
||||
switch(audio_emote_cd_status)
|
||||
if(EMOTE_INFINITE) // Spam those emotes
|
||||
return TRUE
|
||||
if(EMOTE_ADMIN_BLOCKED) // Cooldown emotes were disabled by an admin, prevent use
|
||||
return FALSE
|
||||
if(EMOTE_ON_COOLDOWN) // Already on CD, prevent use
|
||||
return FALSE
|
||||
if(EMOTE_READY)
|
||||
return TRUE
|
||||
|
||||
CRASH("Invalid emote type")
|
||||
|
||||
/**
|
||||
* # Start the cooldown for an emote that plays audio.
|
||||
*
|
||||
* * cooldown: The amount of time that should be waited before any other audio emote can fire.
|
||||
*/
|
||||
/mob/proc/start_audio_emote_cooldown(cooldown = AUDIO_EMOTE_COOLDOWN)
|
||||
if(!can_use_audio_emote())
|
||||
return FALSE
|
||||
|
||||
if(audio_emote_cd_status == EMOTE_READY)
|
||||
audio_emote_cd_status = EMOTE_ON_COOLDOWN // Starting cooldown
|
||||
addtimer(CALLBACK(src, .proc/on_audio_emote_cooldown_end), cooldown)
|
||||
return TRUE // proceed with emote
|
||||
|
||||
|
||||
/mob/proc/on_audio_emote_cooldown_end()
|
||||
if(audio_emote_cd_status == EMOTE_ON_COOLDOWN)
|
||||
// only reset emotes that probably weren't set by an admin
|
||||
audio_emote_cd_status = EMOTE_READY
|
||||
|
||||
/proc/stat_to_text(stat)
|
||||
switch(stat)
|
||||
if(CONSCIOUS)
|
||||
return "conscious"
|
||||
if(UNCONSCIOUS)
|
||||
return "unconscious"
|
||||
if(DEAD)
|
||||
return "dead"
|
||||
|
||||
+12
-8
@@ -2,6 +2,8 @@
|
||||
#define ILLEGAL_CHARACTERS_LIST list("<" = "", ">" = "", \
|
||||
"\[" = "", "]" = "", "{" = "", "}" = "")
|
||||
|
||||
#define USABLE_DEAD_EMOTES list("*flip", "*spin")
|
||||
|
||||
/mob/proc/say()
|
||||
return
|
||||
|
||||
@@ -39,9 +41,9 @@
|
||||
|
||||
set_typing_indicator(FALSE, TRUE)
|
||||
if(use_me)
|
||||
custom_emote(usr.emote_type, message)
|
||||
custom_emote(usr.emote_type, message, intentional = TRUE)
|
||||
else
|
||||
usr.emote(message)
|
||||
usr.emote(message, intentional = TRUE)
|
||||
|
||||
|
||||
/mob/proc/say_dead(message)
|
||||
@@ -62,6 +64,13 @@
|
||||
if(client.handle_spam_prevention(message, MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
|
||||
if(message in USABLE_DEAD_EMOTES)
|
||||
emote(copytext(message, 2), intentional = TRUE)
|
||||
log_emote(message, src)
|
||||
create_log(DEADCHAT_LOG, message)
|
||||
return
|
||||
|
||||
say_dead_direct("[pick("complains", "moans", "whines", "laments", "blubbers", "salts")], <span class='message'>\"[message]\"</span>", src)
|
||||
create_log(DEADCHAT_LOG, message)
|
||||
log_ghostsay(message, src)
|
||||
@@ -110,12 +119,6 @@
|
||||
verb = "asks"
|
||||
return verb
|
||||
|
||||
|
||||
/mob/proc/emote(act, type, message, force)
|
||||
if(act == "me")
|
||||
return custom_emote(type, message)
|
||||
|
||||
|
||||
/mob/proc/get_ear()
|
||||
// returns an atom representing a location on the map from which this
|
||||
// mob can hear things
|
||||
@@ -220,4 +223,5 @@
|
||||
. += S.message + " "
|
||||
. = trim_right(.)
|
||||
|
||||
#undef USABLE_DEAD_EMOTES
|
||||
#undef ILLEGAL_CHARACTERS_LIST
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
if(blood_volume)
|
||||
blood_volume = max(blood_volume - amt, 0)
|
||||
if(prob(10 * amt)) // +5% chance per internal bleeding site that we'll cough up blood on a given tick.
|
||||
custom_emote(1, "coughs up blood!")
|
||||
custom_emote(EMOTE_VISIBLE, "coughs up blood!")
|
||||
add_splatter_floor(loc, 1)
|
||||
return 1
|
||||
else if(amt >= 1 && prob(5 * amt)) // +2.5% chance per internal bleeding site that we'll cough up blood on a given tick. Must be bleeding internally in more than one place to have a chance at this.
|
||||
|
||||
@@ -77,10 +77,10 @@
|
||||
|
||||
if(is_bruised())
|
||||
if(prob(2) && !(NO_BLOOD in owner.dna.species.species_traits))
|
||||
owner.custom_emote(1, "coughs up blood!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "coughs up blood!")
|
||||
owner.bleed(1)
|
||||
if(prob(4))
|
||||
owner.custom_emote(1, "gasps for air!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "gasps for air!")
|
||||
owner.AdjustLoseBreath(10 SECONDS)
|
||||
|
||||
/obj/item/organ/internal/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
I.receive_damage(brute * 0.5)
|
||||
brute -= brute * 0.5
|
||||
|
||||
if(status & ORGAN_BROKEN && prob(40) && brute)
|
||||
if(status & ORGAN_BROKEN && prob(40) && brute && !owner.stat)
|
||||
owner.emote("scream") //getting hit on broken hand hurts
|
||||
if(status & ORGAN_SPLINTED && prob((brute + burn)*4)) //taking damage to splinted limbs removes the splints
|
||||
status &= ~ORGAN_SPLINTED
|
||||
@@ -627,7 +627,7 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
)
|
||||
to_chat(owner, "<span class='userdanger'>Something feels like it shattered in your [name]!</span>")
|
||||
playsound(owner, "bonebreak", 150, 1)
|
||||
if(!HAS_TRAIT(owner, TRAIT_NOPAIN))
|
||||
if(!HAS_TRAIT(owner, TRAIT_NOPAIN) && !owner.stat)
|
||||
owner.emote("scream")
|
||||
|
||||
status |= ORGAN_BROKEN
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
if(hand && owner.canUnEquip(hand))
|
||||
owner.unEquip(hand)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] malfunctions, dropping what it was holding!</span>")
|
||||
owner.custom_emote(1, "drops what [owner.p_they()] [owner.p_were()] holding, [owner.p_their()] [name] malfunctioning!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "drops what [owner.p_they()] [owner.p_were()] holding, [owner.p_their()] [name] malfunctioning!")
|
||||
|
||||
/obj/item/organ/external/arm/right
|
||||
limb_name = "r_arm"
|
||||
@@ -92,10 +92,10 @@
|
||||
return
|
||||
if(owner.AmountWeakened())
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] malfunctions, preventing you from getting back up!</span>")
|
||||
owner.custom_emote(1, "is unable to get back up, [owner.p_their()] [name] malfunctioning!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "is unable to get back up, [owner.p_their()] [name] malfunctioning!")
|
||||
else
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] malfunctions, dropping you to the ground!</span>")
|
||||
owner.custom_emote(1, "drops to the ground, [owner.p_their()] [name] malfunctioning!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "drops to the ground, [owner.p_their()] [name] malfunctioning!")
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.AdjustWeakened(8 SECONDS)
|
||||
@@ -130,10 +130,10 @@
|
||||
return
|
||||
if(owner.AmountWeakened())
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] malfunctions, preventing you from getting back up!</span>")
|
||||
owner.custom_emote(1, "is unable to get back up, [owner.p_their()] [name] malfunctioning!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "is unable to get back up, [owner.p_their()] [name] malfunctioning!")
|
||||
else
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] malfunctions, dropping you to the ground!</span>")
|
||||
owner.custom_emote(1, "drops to the ground, [owner.p_their()] [name] malfunctioning!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "drops to the ground, [owner.p_their()] [name] malfunctioning!")
|
||||
switch(severity)
|
||||
if(1)
|
||||
owner.AdjustWeakened(8 SECONDS)
|
||||
@@ -173,7 +173,7 @@
|
||||
if(hand && owner.canUnEquip(hand))
|
||||
owner.unEquip(hand)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] malfunctions, dropping what it was holding!</span>")
|
||||
owner.custom_emote(1, "drops what [owner.p_they()] [owner.p_were()] holding, [owner.p_their()] [name] malfunctioning!")
|
||||
owner.custom_emote(EMOTE_VISIBLE, "drops what [owner.p_they()] [owner.p_were()] holding, [owner.p_their()] [name] malfunctioning!")
|
||||
|
||||
/obj/item/organ/external/hand/remove()
|
||||
if(owner)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "component_tests.dm"
|
||||
#include "config_sanity.dm"
|
||||
#include "crafting_lists.dm"
|
||||
#include "emotes.dm"
|
||||
#include "log_format.dm"
|
||||
#include "map_templates.dm"
|
||||
#include "purchase_reference_test.dm"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
/datum/unit_test/emote/Run()
|
||||
// be aware that some of these values (like message, message_param) are subject to being set at runtime.
|
||||
for(var/emote_type in subtypesof(/datum/emote))
|
||||
var/datum/emote/cur_emote = new emote_type()
|
||||
if(cur_emote.message_param && !cur_emote.param_desc)
|
||||
Fail("emote [cur_emote] was given a message parameter without a description.")
|
||||
|
||||
// Sanity checks, these emotes probably won't appear to a user but we should make sure they're cleaned up.
|
||||
if(!cur_emote.key)
|
||||
if(cur_emote.message || cur_emote.message_param)
|
||||
Fail("emote [cur_emote] is missing a key but has a message defined.")
|
||||
if(cur_emote.key_third_person)
|
||||
Fail("emote [cur_emote] has a third-person key defined, but no first-person key. Either first person, both, or neither should be defined.")
|
||||
|
||||
// These are ones that might appear to a user, and so could use some special handling.
|
||||
else
|
||||
if(isnull(cur_emote.emote_type))
|
||||
Fail("emote [cur_emote] has a null target type.")
|
||||
|
||||
if(isnum(cur_emote.max_stat_allowed) && cur_emote.max_stat_allowed < cur_emote.stat_allowed)
|
||||
Fail("emote [cur_emote]'s max_stat_allowed is greater than its stat_allowed, and would be unusable.")
|
||||
|
||||
if(isnum(cur_emote.max_unintentional_stat_allowed) && cur_emote.max_unintentional_stat_allowed < cur_emote.unintentional_stat_allowed)
|
||||
Fail("emote [cur_emote]'s max_unintentional_stat_allowed is greater than its unintentional_stat_allowed, and would be unusable.")
|
||||
|
||||
|
||||
/datum/unit_test/emote/proc/has_punctuation(datum/emote/E, msg)
|
||||
return E.remove_ending_punctuation(msg) == msg
|
||||
Reference in New Issue
Block a user