diff --git a/code/datums/emotes.dm b/code/datums/emotes.dm
index 5bb5c0d4157b..b5625e060064 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -23,6 +23,7 @@
var/sound //Sound to play when emote is called
var/vary = FALSE //used for the honk borg emote
var/only_forced_audio = FALSE //can only code call this event instead of the player.
+ var/cooldown = 0.4 SECONDS
/datum/emote/New()
if (ispath(mob_type_allowed_typecache))
@@ -75,6 +76,19 @@
else
user.visible_message(msg)
+/// For handling emote cooldown, return true to allow the emote to happen
+/datum/emote/proc/check_cooldown(mob/user, intentional, update=TRUE)
+ if(!intentional)
+ return TRUE
+ if(user.emotes_used && user.emotes_used[src] + cooldown > world.time)
+ return FALSE
+ if(!update)
+ return TRUE
+ if(!user.emotes_used)
+ user.emotes_used = list()
+ user.emotes_used[src] = world.time
+ return TRUE
+
/datum/emote/proc/get_sound(mob/living/user)
return sound //by default just return this var.
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index b3a4398f14f6..dd0535ed6fb5 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -13,12 +13,18 @@
if(!length(key_emotes))
if(intentional)
to_chat(src, "'[act]' emote does not exist. Say *help for a list.")
- return
+ return FALSE
+ var/silenced = FALSE
for(var/datum/emote/P in key_emotes)
+ if(!P.check_cooldown(src, intentional))
+ silenced = TRUE
+ continue
if(P.run_emote(src, param, m_type, intentional))
- return
- if(intentional)
+ return TRUE
+ if(intentional && !silenced)
to_chat(src, "Unusable emote '[act]'. Say *help for a list.")
+ return FALSE
+
/datum/emote/flip
key = "flip"
@@ -26,6 +32,7 @@
restraint_check = TRUE
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer)
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
+ cooldown = 0 SECONDS
/datum/emote/flip/run_emote(mob/user, params , type_override, intentional)
. = ..()
@@ -38,6 +45,7 @@
restraint_check = TRUE
mob_type_allowed_typecache = list(/mob/living, /mob/dead/observer)
mob_type_ignore_stat_typecache = list(/mob/dead/observer)
+ cooldown = 0 SECONDS
/datum/emote/spin/run_emote(mob/user, params , type_override, intentional)
. = ..()
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 74f33179be40..b51505450d31 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -80,6 +80,7 @@
message_monkey = "lets out a faint chimper as it collapses and stops moving..."
message_simple = "stops moving..."
stat_allowed = UNCONSCIOUS
+ cooldown = 3.4 SECONDS
/datum/emote/living/deathgasp/run_emote(mob/user, params, type_override, intentional)
var/mob/living/simple_animal/S = user
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 9c1bf784ccbd..5726f2484178 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -106,3 +106,5 @@
var/registered_z
var/memory_amt = 0
+
+ var/list/emotes_used /// Used for tracking last uses of emotes for cooldown purposes