diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 32af0998702..25c712354ce 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -1,3 +1,18 @@
+#define EMOTE_COOLDOWN 50 //Time in deciseconds that the cooldown lasts
+
+//Emote Cooldown System (it's so simple!)
+/mob/proc/handle_emote_CD()
+ if(emote_cd == 2) return 1 // Cooldown emotes were disabled by an admin, prevent use
+ if(src.emote_cd == 1) return 1 // Already on CD, prevent use
+
+ src.emote_cd = 1 // Starting cooldown
+ spawn(EMOTE_COOLDOWN)
+ if(emote_cd == 2) return 1 // Don't reset if cooldown emotes were disabled by an admin during the cooldown
+ src.emote_cd = 0 // Cooldown complete, ready for more!
+
+ return 0 // Proceed with emote
+//--FalseIncarnate
+
// All mobs should have custom emote, really..
/mob/proc/custom_emote(var/m_type=1,var/message = null)
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 65c9d41c478..b2cf5cea48f 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -20,69 +20,100 @@
if(src.stat == 2.0 && (act != "deathgasp"))
return
+
+ //Emote Cooldown System (it's so simple!)
+ // proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
+ var/on_CD = 0
+ switch(act)
+ //Cooldown-inducing emotes
+ if("ping","buzz","beep")
+ if (species.name == "Machine") //Only Machines can beep, ping, and buzz
+ on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
+ else //Everyone else fails, skip the emote attempt
+ return
+ if("squish")
+ if(species.name == "Slime People") //Only Slime People can squish
+ on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
+ else //Everyone else fails, skip the emote attempt
+ return
+ if("scream", "fart", "flip")
+ 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(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")
- if (species.name == "Machine")
- var/M = null
- if(param)
- for (var/mob/A in view(null, null))
- if (param == A.name)
- M = A
- break
- if(!M)
- param = null
+ 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 = "[src] pings at [param]."
- else
- message = "[src] pings."
- playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
- m_type = 1
+ if (param)
+ message = "[src] pings at [param]."
else
- if (!species.name == "Machine")
- return
+ message = "[src] pings."
+ playsound(src.loc, 'sound/machines/ping.ogg', 50, 0)
+ m_type = 1
if("buzz")
- if (species.name == "Machine")
- var/M = null
- if(param)
- for (var/mob/A in view(null, null))
- if (param == A.name)
- M = A
- break
- if(!M)
- param = null
+ 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 = "[src] buzzes at [param]."
- else
- message = "[src] buzzes."
- playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
- m_type = 1
+ if (param)
+ message = "[src] buzzes at [param]."
else
- if (!species.name == "Machine")
- return
+ message = "[src] buzzes."
+ playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
+ m_type = 1
if("beep")
- if(species.name == "Machine")
- var/M = null
- if(param)
- for (var/mob/A in view(null, null))
- if (param == A.name)
- M = A
- break
- if(!M)
- param = null
+ 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 = "[src] beeps at [param]."
- else
- message = "[src] beeps."
- playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
- m_type = 1
+ if (param)
+ message = "[src] beeps at [param]."
else
- if (!species.name == "Machine")
- return
+ message = "[src] beeps."
+ playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0)
+ m_type = 1
+
+ if("squish")
+ 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 = "[src] squishes at [param]."
+ else
+ message = "[src] squishes."
+ playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
+ m_type = 1
if("wag")
if(species.bodyflags & TAIL_WAGGING)
diff --git a/code/modules/mob/living/carbon/monkey/emote.dm b/code/modules/mob/living/carbon/monkey/emote.dm
index 706029df8c9..0f19e93c326 100644
--- a/code/modules/mob/living/carbon/monkey/emote.dm
+++ b/code/modules/mob/living/carbon/monkey/emote.dm
@@ -11,6 +11,26 @@
var/muzzled = is_muzzled()
+ //Emote Cooldown System (it's so simple!)
+ // proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
+ var/on_CD = 0
+ switch(act)
+ //Cooldown-inducing emotes
+ if("chirp")
+ if(istype(src,/mob/living/carbon/monkey/diona)) //Only Diona Nymphs can chirp
+ on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
+ else //Everyone else fails, skip the emote attempt
+ return
+ if("flip")
+ on_CD = handle_emote_CD()
+ //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(on_CD == 1) // Check if we need to suppress the emote attempt.
+ return // Suppress emote, you're still cooling off.
+ //--FalseIncarnate
+
switch(act)
if ("me")
if(silent)
@@ -32,10 +52,9 @@
return custom_emote(m_type, message)
if ("chirp")
- if(istype(src,/mob/living/carbon/monkey/diona))
- message = "The [src.name] chirps!"
- playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
- m_type = 2
+ message = "The [src.name] chirps!"
+ playsound(src.loc, 'sound/misc/nymphchirp.ogg', 50, 0)
+ m_type = 2
if("sign")
if (!src.restrained())
message = text("The monkey signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
diff --git a/code/modules/mob/living/carbon/monkey/say.dm b/code/modules/mob/living/carbon/monkey/say.dm
new file mode 100644
index 00000000000..9a629c358fc
--- /dev/null
+++ b/code/modules/mob/living/carbon/monkey/say.dm
@@ -0,0 +1,28 @@
+/mob/living/carbon/monkey/say(var/message)
+ var/verb = "says"
+ var/message_range = world.view
+
+ if(client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "\red You cannot speak in IC (Muted)."
+ return
+
+ message = trim_strip_html_properly(message)
+
+ if(stat == 2)
+ return say_dead(message)
+
+ if(copytext(message,1,2) == "*")
+ return emote(copytext(message,2))
+
+ var/datum/language/speaking = parse_language(message)
+
+ if(speaking)
+ message = copytext(message, 2+length(speaking.key))
+
+ message = trim(message)
+
+ if(!message || stat)
+ return
+
+ ..(message, speaking, verb, null, null, message_range, null)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm
index 6bf18971ba6..8efab8a0f57 100644
--- a/code/modules/mob/living/silicon/robot/emote.dm
+++ b/code/modules/mob/living/silicon/robot/emote.dm
@@ -8,6 +8,21 @@
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!)
+ // proc/handle_emote_CD() located in [code\modules\mob\emote.dm]
+ var/on_CD = 0
+ switch(act)
+ //Cooldown-inducing emotes
+ if("ping","buzz","beep","law") //halt is exempt because it's used to stop criminal scum
+ 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(on_CD == 1) // Check if we need to suppress the emote attempt.
+ return // Suppress emote, you're still cooling off.
+ //--FalseIncarnate
+
switch(act)
if ("me")
if (src.client)
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index b91583758af..7aa2f58efca 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -138,6 +138,8 @@
var/coughedtime = null
+ var/emote_cd = 0 // Used to supress emote spamming. 1 if on CD, 2 if disabled by admin (manually set), else 0
+
var/inertia_dir = 0
var/music_lastplayed = "null"
diff --git a/paradise.dme b/paradise.dme
index c7692b54575..40cb30de985 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1301,6 +1301,7 @@
#include "code\modules\mob\living\carbon\monkey\login.dm"
#include "code\modules\mob\living\carbon\monkey\monkey.dm"
#include "code\modules\mob\living\carbon\monkey\powers.dm"
+#include "code\modules\mob\living\carbon\monkey\say.dm"
#include "code\modules\mob\living\carbon\monkey\update_icons.dm"
#include "code\modules\mob\living\silicon\death.dm"
#include "code\modules\mob\living\silicon\login.dm"
diff --git a/sound/effects/slime_squish.ogg b/sound/effects/slime_squish.ogg
new file mode 100644
index 00000000000..60e118e217b
Binary files /dev/null and b/sound/effects/slime_squish.ogg differ