diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 7bb1a46431a..9054d3a0670 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -262,4 +262,7 @@
// /obj/item/bodypart on_mob_life() retval flag
#define BODYPART_LIFE_UPDATE_HEALTH (1<<0)
+#define MAX_REVIVE_FIRE_DAMAGE 180
+#define MAX_REVIVE_BRUTE_DAMAGE 180
+
#define HUMAN_FIRE_STACK_ICON_NUM 3
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index cc68d238c71..b33b19ff877 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -210,7 +210,7 @@
H.set_cloned_appearance()
- H.suiciding = FALSE
+ H.set_suicide(FALSE)
attempting = FALSE
return TRUE
diff --git a/code/game/machinery/exp_cloner.dm b/code/game/machinery/exp_cloner.dm
index 2a222ed413b..683451945b0 100644
--- a/code/game/machinery/exp_cloner.dm
+++ b/code/game/machinery/exp_cloner.dm
@@ -67,7 +67,7 @@
H.set_cloned_appearance()
- H.suiciding = FALSE
+ H.set_suicide(FALSE)
attempting = FALSE
return TRUE
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 641a51030d6..e379d62d027 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -437,8 +437,18 @@
do_help(H, user)
/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H)
+ if(H.suiciding || H.has_trait(TRAIT_NOCLONE) || H.hellbound)
+ return
+ if((world.time - H.timeofdeath) > tlimit)
+ return
+ if((H.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (H.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
+ return
+ if(!H.getorgan(/obj/item/organ/heart))
+ return
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
- return (!H.suiciding && !(H.has_trait(TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
+ if(QDELETED(BR) || BR.damaged_brain || BR.suicided)
+ return
+ return TRUE
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(isliving(H.pulledby)) //CLEAR!
@@ -567,14 +577,19 @@
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile."
else if (!H.getorgan(/obj/item/organ/heart))
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing."
- else if(total_burn >= 180 || total_brute >= 180)
+ else if(total_burn >= MAX_REVIVE_FIRE_DAMAGE || total_brute >= MAX_REVIVE_BRUTE_DAMAGE)
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile."
else if(H.get_ghost())
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful."
else
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
- if(!BR || BR.damaged_brain)
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile."
+ if(BR)
+ if(BR.damaged_brain)
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain damaged beyond point of no return. Further attempts futile."
+ if(BR.suicided || BR.brainmob?.suiciding)
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No intelligence pattern can be detected in patient's brain. Further attempts futile."
+ else
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing. Further attempts futile."
if(failed)
user.visible_message(failed)
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 0e11522b6b3..b959f760b6d 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -254,7 +254,7 @@
to_chat(user, "The MMI indicates that their mind is currently inactive; it might change!")
return
- if(BM.stat == DEAD || (M.brain && M.brain.damaged_brain))
+ if(BM.stat == DEAD || BM.suiciding || (M.brain && (M.brain.damaged_brain || M.brain.suicided)))
to_chat(user, "Sticking a dead brain into the frame would sort of defeat the purpose!")
return
diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm
index 14f6f372031..24b9bd6811a 100644
--- a/code/modules/client/verbs/suicide.dm
+++ b/code/modules/client/verbs/suicide.dm
@@ -1,5 +1,29 @@
/mob/var/suiciding = 0
+/mob/proc/set_suicide(suicide_state)
+ suiciding = suicide_state
+
+/mob/living/carbon/set_suicide(suicide_state) //you thought that box trick was pretty clever, didn't you? well now hardmode is on, boyo.
+ . = ..()
+ var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
+ if(B)
+ B.suicided = suicide_state
+
+/mob/living/silicon/robot/set_suicide(suicide_state)
+ . = ..()
+ if(mmi)
+ if(mmi.brain)
+ mmi.brain.suicided = suicide_state
+ if(mmi.brainmob)
+ mmi.brainmob.suiciding = suicide_state
+
+/mob/living/carbon/human/virtual_reality/set_suicide(suicide_state)
+ return
+
+/mob/living/carbon/human/virtual_reality/canSuicide()
+ to_chat(src, "I'm sorry [first_name()], I'm afraid you can't do that.")
+ return
+
/mob/living/carbon/human/verb/suicide()
set hidden = 1
if(!canSuicide())
@@ -11,14 +35,14 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = TRUE
+ set_suicide(TRUE)
var/obj/item/held_item = get_active_held_item()
if(held_item)
var/damagetype = held_item.suicide_act(src)
if(damagetype)
if(damagetype & SHAME)
adjustStaminaLoss(200)
- suiciding = FALSE
+ set_suicide(FALSE)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "shameful_suicide", /datum/mood_event/shameful_suicide)
return
@@ -78,7 +102,7 @@
suicide_log()
adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
- death(0)
+ death(FALSE)
/mob/living/brain/verb/suicide()
set hidden = 1
@@ -88,13 +112,13 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = 1
+ set_suicide(TRUE)
visible_message("[src]'s brain is growing dull and lifeless. [p_they(TRUE)] look[p_s()] like [p_theyve()] lost the will to live.", \
"[src]'s brain is growing dull and lifeless. [p_they(TRUE)] look[p_s()] like [p_theyve()] lost the will to live.")
suicide_log()
- death(0)
+ death(FALSE)
/mob/living/carbon/monkey/verb/suicide()
set hidden = 1
@@ -104,14 +128,14 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = 1
+ set_suicide(TRUE)
visible_message("[src] is attempting to bite [p_their()] tongue. It looks like [p_theyre()] trying to commit suicide.", \
"[src] is attempting to bite [p_their()] tongue. It looks like [p_theyre()] trying to commit suicide.")
suicide_log()
adjustOxyLoss(max(200- getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
- death(0)
+ death(FALSE)
/mob/living/silicon/ai/verb/suicide()
set hidden = 1
@@ -121,7 +145,7 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = 1
+ set_suicide(TRUE)
visible_message("[src] is powering down. It looks like [p_theyre()] trying to commit suicide.", \
"[src] is powering down. It looks like [p_theyre()] trying to commit suicide.")
@@ -129,7 +153,7 @@
//put em at -175
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
- death(0)
+ death(FALSE)
/mob/living/silicon/robot/verb/suicide()
set hidden = 1
@@ -139,7 +163,7 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = 1
+ set_suicide(TRUE)
visible_message("[src] is powering down. It looks like [p_theyre()] trying to commit suicide.", \
"[src] is powering down. It looks like [p_theyre()] trying to commit suicide.")
@@ -147,7 +171,7 @@
//put em at -175
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
- death(0)
+ death(FALSE)
/mob/living/silicon/pai/verb/suicide()
set hidden = 1
@@ -159,7 +183,7 @@
suicide_log()
- death(0)
+ death(FALSE)
else
to_chat(src, "Aborting suicide attempt.")
@@ -171,7 +195,7 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = 1
+ set_suicide(TRUE)
visible_message("[src] is thrashing wildly! It looks like [p_theyre()] trying to commit suicide.", \
"[src] is thrashing wildly! It looks like [p_theyre()] trying to commit suicide.", \
"You hear thrashing.")
@@ -180,7 +204,7 @@
//put em at -175
adjustOxyLoss(max(200 - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
- death(0)
+ death(FALSE)
/mob/living/simple_animal/verb/suicide()
set hidden = 1
@@ -190,13 +214,13 @@
if(!canSuicide())
return
if(confirm == "Yes")
- suiciding = 1
+ set_suicide(TRUE)
visible_message("[src] begins to fall down. It looks like [p_theyve()] lost the will to live.", \
"[src] begins to fall down. It looks like [p_theyve()] lost the will to live.")
suicide_log()
- death(0)
+ death(FALSE)
/mob/living/proc/suicide_log()
log_game("[key_name(src)] committed suicide at [AREACOORD(src)] as [src.type].")
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index d03846d6523..ed9fd55a75e 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -90,7 +90,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
mind = body.mind //we don't transfer the mind but we keep a reference to it.
- suiciding = body.suiciding // Transfer whether they committed suicide.
+ set_suicide(body.suiciding) // Transfer whether they committed suicide.
if(ishuman(body))
var/mob/living/carbon/human/body_human = body
diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm
index bacdc4524bd..32fb61236aa 100644
--- a/code/modules/mob/living/brain/MMI.dm
+++ b/code/modules/mob/living/brain/MMI.dm
@@ -57,7 +57,7 @@
newbrain.brainmob = null
brainmob.forceMove(src)
brainmob.container = src
- if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death.
+ if(!newbrain.damaged_brain && !newbrain.suicided && !brainmob.suiciding) // the brain organ hasn't been beaten to death, nor was from a suicider.
brainmob.stat = CONSCIOUS //we manually revive the brain mob
GLOB.dead_mob_list -= brainmob
GLOB.alive_mob_list += brainmob
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index 7d1dc7d1d2c..35f45a49214 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -9,6 +9,7 @@
slot = ORGAN_SLOT_BRAIN
vital = TRUE
attack_verb = list("attacked", "slapped", "whacked")
+ var/suicided = FALSE
var/mob/living/brain/brainmob = null
var/damaged_brain = FALSE //whether the brain organ is damaged.
var/decoy_override = FALSE //I apologize to the security players, and myself, who abused this, but this is going to go.
@@ -70,6 +71,7 @@
brainmob.name = L.real_name
brainmob.real_name = L.real_name
brainmob.timeofhostdeath = L.timeofdeath
+ brainmob.suiciding = suicided
if(L.has_dna())
var/mob/living/carbon/C = L
if(!brainmob.stored_dna)
@@ -92,7 +94,9 @@
/obj/item/organ/brain/examine(mob/user)
..()
- if(brainmob)
+ if(suicided)
+ to_chat(user, "It's started turning slightly grey. They must not have been able to handle the stress of it all.")
+ else if(brainmob)
if(brainmob.client)
if(brainmob.health <= HEALTH_THRESHOLD_DEAD)
to_chat(user, "It's lifeless and severely damaged.")
diff --git a/code/modules/mob/living/brain/life.dm b/code/modules/mob/living/brain/life.dm
index 786bb0b55c3..6b3ec010b7b 100644
--- a/code/modules/mob/living/brain/life.dm
+++ b/code/modules/mob/living/brain/life.dm
@@ -20,7 +20,7 @@
else if(istype(loc, /obj/item/organ/brain))
BR = loc
if(BR)
- BR.damaged_brain = 1 //beaten to a pulp
+ BR.damaged_brain = TRUE //beaten to a pulp
/mob/living/brain/proc/handle_emp_damage()
if(emp_damage)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 3308f0fbbd4..5519c721637 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -436,7 +436,7 @@
if(stat == DEAD && can_be_revived()) //in some cases you can't revive (e.g. no brain)
GLOB.dead_mob_list -= src
GLOB.alive_mob_list += src
- suiciding = 0
+ set_suicide(FALSE)
stat = UNCONSCIOUS //the mob starts unconscious,
blind_eyes(1)
updatehealth() //then we check if the mob should wake up.
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 68c7ea02ae3..87007ae3fed 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -54,7 +54,7 @@
O.dna.struc_enzymes = R.set_se(O.dna.struc_enzymes, on=1)//we don't want to keep the race block inactive
if(suiciding)
- O.suiciding = suiciding
+ O.set_suicide(suiciding)
if(hellbound)
O.hellbound = hellbound
O.a_intent = INTENT_HARM
@@ -211,7 +211,7 @@
O.domutcheck()
if(suiciding)
- O.suiciding = suiciding
+ O.set_suicide(suiciding)
if(hellbound)
O.hellbound = hellbound
diff --git a/code/modules/research/nanites/nanite_programs/healing.dm b/code/modules/research/nanites/nanite_programs/healing.dm
index df32a5d127e..39dafdb0bc1 100644
--- a/code/modules/research/nanites/nanite_programs/healing.dm
+++ b/code/modules/research/nanites/nanite_programs/healing.dm
@@ -219,12 +219,12 @@
return FALSE
if((world.time - C.timeofdeath) > 1800) //too late
return FALSE
- if((C.getBruteLoss() > 180) || (C.getFireLoss() > 180) || !C.can_be_revived()) //too damaged
+ if((C.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (C.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE) || !C.can_be_revived()) //too damaged
return FALSE
if(!C.getorgan(/obj/item/organ/heart)) //what are we even shocking
return FALSE
var/obj/item/organ/brain/BR = C.getorgan(/obj/item/organ/brain)
- if(QDELETED(BR) || BR.damaged_brain)
+ if(QDELETED(BR) || BR.damaged_brain || BR.suicided)
return FALSE
if(C.get_ghost())
return FALSE