diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index d7d857f0f46..bcfbdc8e37c 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -446,4 +446,7 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define SLIME_FRIENDSHIP_STOPCHASE 4 //Min friendship to order it to stop chasing someone (their target)
#define SLIME_FRIENDSHIP_STOPCHASE_NOANGRY 6 //Min friendship to order it to stop chasing someone (their target) without it losing friendship
#define SLIME_FRIENDSHIP_STAY 3 //Min friendship to order it to stay
-#define SLIME_FRIENDSHIP_ATTACK 8 //Min friendship to order it to attack
\ No newline at end of file
+#define SLIME_FRIENDSHIP_ATTACK 8 //Min friendship to order it to attack
+
+#define DEADCHAT_DEATHRATTLE "deathrattle"
+#define DEADCHAT_REGULAR "regular-deadchat"
diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm
index 207c01db0dc..12d5e376201 100644
--- a/code/__DEFINES/preferences.dm
+++ b/code/__DEFINES/preferences.dm
@@ -12,8 +12,9 @@
#define SOUND_PRAYERS 512
#define ANNOUNCE_LOGIN 1024
#define SOUND_ANNOUNCEMENTS 2048
+#define DISABLE_DEATHRATTLE 4096
-#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS)
+#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS|DISABLE_DEATHRATTLE)
//Chat toggles
#define CHAT_OOC 1
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 41c5a80fe81..3cbe887a2b7 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -327,3 +327,31 @@ Proc for attack log creation, because really why not
var/mob/living/carbon/human/H = A
if(H.dna && istype(H.dna.species, species_datum))
. = TRUE
+
+
+/proc/deadchat_broadcast(message, mob/follow_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR)
+ for(var/mob/M in player_list)
+ var/datum/preferences/prefs
+ if(M.client && M.client.prefs)
+ prefs = M.client.prefs
+ else
+ prefs = new
+
+ var/adminoverride = 0
+ if(M.client && M.client.holder && (prefs.chat_toggles & CHAT_DEAD))
+ adminoverride = 1
+ if(istype(M, /mob/new_player) && !adminoverride)
+ continue
+ if(M.stat != DEAD && !adminoverride)
+ continue
+ if(speaker_key && speaker_key in prefs.ignoring)
+ continue
+ if(message_type == DEADCHAT_DEATHRATTLE)
+ if(prefs.toggles & DISABLE_DEATHRATTLE)
+ continue
+
+ if(istype(M, /mob/dead/observer) && follow_target)
+ var/link = FOLLOW_LINK(M, follow_target)
+ M << "[link] [message]"
+ else
+ M << "[message]"
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index bf3071d1dda..edcfcb3a2a0 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -54,6 +54,17 @@
usr << "You will [(prefs.chat_toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from nearby radios or speakers"
feedback_add_details("admin_verb","THR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/verb/toggle_deathrattle()
+ set name = "Toggle Deathrattle"
+ set category = "Preferences"
+ set desc = "Toggle recieving a message in deadchat when sentient mobs \
+ die."
+ prefs.toggles ^= DISABLE_DEATHRATTLE
+ usr << "You will \
+ [(prefs.toggles & DISABLE_DEATHRATTLE) ? "no longer" : "now"] get \
+ messages when a sentient mob dies."
+ feedback_add_details("admin_verb", "TDR") // If you are copy-pasting this, maybe you should spend some time reading the comments.
+
/client/proc/toggleadminhelpsound()
set name = "Hear/Silence Adminhelps"
set category = "Preferences"
@@ -332,4 +343,4 @@ var/global/list/ghost_orbits = list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
prefs.toggles ^= SOUND_ANNOUNCEMENTS
src << "You will now [(prefs.toggles & SOUND_ANNOUNCEMENTS) ? "hear announcement sounds" : "no longer hear announcements"]."
prefs.save_preferences()
- feedback_add_details("admin_verb","TAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
\ No newline at end of file
+ feedback_add_details("admin_verb","TAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index e4c1500e632..df0181f844f 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -44,6 +44,13 @@
unset_machine()
timeofdeath = world.time
tod = worldtime2text()
+ if(mind && mind.name && mind.active)
+ var/area/A = get_area(loc)
+ var/rendered = "\
+ [mind.name] has died at [A.name]\
+ ."
+ deadchat_broadcast(rendered, follow_target = src,
+ message_type=DEADCHAT_DEATHRATTLE)
if(mind)
mind.store_memory("Time of death: [tod]", 0)
living_mob_list -= src
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 3c7f50028fe..3d1c57bbe2d 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -51,21 +51,7 @@
message = src.say_quote(message, get_spans())
var/rendered = "DEAD: [name][alt_name] [message]"
- for(var/mob/M in player_list)
- var/adminoverride = 0
- if(M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))
- adminoverride = 1
- if(istype(M, /mob/new_player) && !adminoverride)
- continue
- if(M.stat != DEAD && !adminoverride)
- continue
- if(K && M.client && K in M.client.prefs.ignoring)
- continue
- if(istype(M, /mob/dead/observer))
- var/link = FOLLOW_LINK(M, src)
- M << "[link] [rendered]"
- else
- M << "[rendered]"
+ deadchat_broadcast(rendered, follow_target = src, speaker_key = K)
/mob/proc/emote(var/act)
return