diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 6bdf29b8697..0cebc3cf07f 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -343,5 +343,20 @@
//Wabbacjack staff projectiles
#define WABBAJACK (1<<6)
+// Reasons a defibrilation might fail
+#define DEFIB_FAIL_SUICIDE (1<<1)
+#define DEFIB_FAIL_HELLBOUND (1<<2)
+#define DEFIB_FAIL_HUSK (1<<3)
+#define DEFIB_FAIL_TISSUE_DAMAGE (1<<4)
+#define DEFIB_FAIL_FAILING_HEART (1<<5)
+#define DEFIB_FAIL_NO_HEART (1<<6)
+#define DEFIB_FAIL_FAILING_BRAIN (1<<7)
+#define DEFIB_FAIL_NO_BRAIN (1<<8)
+#define DEFIB_FAIL_NO_INTELLIGENCE (1<<9)
+
+// Bit mask of possible return values by can_defib that would result in a revivable patient
+// `| 1` is added to account for can_defib() returning TRUE, meaning there's no issues
+#define DEFIB_REVIVABLE_STATES (DEFIB_FAIL_NO_HEART | DEFIB_FAIL_FAILING_HEART | DEFIB_FAIL_HUSK | DEFIB_FAIL_TISSUE_DAMAGE | DEFIB_FAIL_FAILING_BRAIN | 1)
+
#define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return;
#define INTERACTING_WITH(X, Y) (Y in X.do_afters)
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index f06e636e360..cee57e388dd 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -189,7 +189,7 @@
if(HAS_TRAIT(src, TRAIT_XENO_HOST))
holder.icon_state = "hudxeno"
else if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH)))
- if(key || get_ghost(FALSE, TRUE))
+ if((key || get_ghost(FALSE, TRUE)) && (can_defib() & DEFIB_REVIVABLE_STATES))
holder.icon_state = "huddefib"
else
holder.icon_state = "huddead"
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index d59b8e644fc..aaf08c2bbff 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -444,7 +444,7 @@
do_harm(H, user)
return
- if(H.can_defib())
+ if(H.can_defib() != TRUE)
H.notify_ghost_cloning("Your heart is being defibrillated!")
H.grab_ghost() // Shove them back in their body.
@@ -545,8 +545,6 @@
if(do_after(user, 30, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("[user] places [src] on [H]'s chest.", "You place [src] on [H]'s chest.")
playsound(src, 'sound/machines/defib_charge.ogg', 75, FALSE)
- var/total_burn = 0
- var/total_brute = 0
var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
if(do_after(user, 20, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
for(var/obj/item/carried_item in H.contents)
@@ -561,35 +559,36 @@
H.visible_message("[H]'s body convulses a bit.")
playsound(src, "bodyfall", 50, TRUE)
playsound(src, 'sound/machines/defib_zap.ogg', 75, TRUE, -1)
- total_brute = H.getBruteLoss()
- total_burn = H.getFireLoss()
shock_touching(30, H)
- var/failed
- if (H.suiciding)
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile."
- else if (H.hellbound)
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile."
- else if (!heart)
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing."
- else if (heart.organ_flags & ORGAN_FAILING)
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart too damaged, replace or repair and try again."
- else if(total_burn >= MAX_REVIVE_FIRE_DAMAGE || total_brute >= MAX_REVIVE_BRUTE_DAMAGE || HAS_TRAIT(H, TRAIT_HUSK))
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Tissue damage too severe, repair and try again."
- else
- var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
- if(BR)
- if(BR.organ_flags & ORGAN_FAILING)
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is too damaged, repair and try again. "
- 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."
+ var/defib_result = H.can_defib()
+ var/fail_reason
- if(failed)
- user.visible_message(failed)
+ switch (defib_result)
+ if (DEFIB_FAIL_SUICIDE)
+ fail_reason = "Recovery of patient impossible. Further attempts futile."
+ if (DEFIB_FAIL_HELLBOUND)
+ fail_reason = "Patient's soul appears to be on another plane of existence. Further attempts futile."
+ if (DEFIB_FAIL_NO_HEART)
+ fail_reason = "Patient's heart is missing."
+ if (DEFIB_FAIL_FAILING_HEART, DEFIB_FAIL_HUSK)
+ fail_reason = "Patient's heart too damaged, replace or repair and try again."
+ if (DEFIB_FAIL_TISSUE_DAMAGE)
+ fail_reason = "Tissue damage too severe, repair and try again."
+ if (DEFIB_FAIL_FAILING_BRAIN)
+ fail_reason = "Patient's brain is too damaged, repair and try again."
+ if (DEFIB_FAIL_NO_INTELLIGENCE)
+ fail_reason = "No intelligence pattern can be detected in patient's brain. Further attempts futile."
+ if (DEFIB_FAIL_NO_BRAIN)
+ fail_reason = "Patient's brain is missing. Further attempts futile."
+
+ if(fail_reason)
+ user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - [fail_reason]")
playsound(src, 'sound/machines/defib_failed.ogg', 50, FALSE)
else
+ var/total_brute = H.getBruteLoss()
+ var/total_burn = H.getFireLoss()
+
//If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit
if (H.health > HALFWAYCRITDEATH)
H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index df4e83d4ec4..66ff1fe52c2 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -841,16 +841,40 @@
return 0
/mob/living/carbon/proc/can_defib()
+ if (suiciding)
+ return DEFIB_FAIL_SUICIDE
+
+ if (hellbound)
+ return DEFIB_FAIL_HELLBOUND
+
+ if (HAS_TRAIT(src, TRAIT_HUSK))
+ return DEFIB_FAIL_HUSK
+
+ if ((getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
+ return DEFIB_FAIL_TISSUE_DAMAGE
+
var/obj/item/organ/heart = getorgan(/obj/item/organ/heart)
- if(suiciding || hellbound || HAS_TRAIT(src, TRAIT_HUSK))
- return
- if((getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
- return
- if(!heart || (heart.organ_flags & ORGAN_FAILING))
- return
+
+ if (!heart)
+ return DEFIB_FAIL_NO_HEART
+
+ if (heart.organ_flags & ORGAN_FAILING)
+ return DEFIB_FAIL_FAILING_HEART
+
var/obj/item/organ/brain/BR = getorgan(/obj/item/organ/brain)
- if(QDELETED(BR) || (BR.organ_flags & ORGAN_FAILING) || BR.suicided)
- return
+
+ if (QDELETED(BR))
+ return DEFIB_FAIL_NO_BRAIN
+
+ if (BR.organ_flags & ORGAN_FAILING)
+ return DEFIB_FAIL_FAILING_BRAIN
+
+ if (!BR.brainmob)
+ return DEFIB_FAIL_NO_INTELLIGENCE
+
+ if (BR.suicided || BR.brainmob.suiciding)
+ return DEFIB_FAIL_SUICIDE
+
return TRUE
/mob/living/carbon/harvest(mob/living/user)
diff --git a/code/modules/research/nanites/nanite_programs/healing.dm b/code/modules/research/nanites/nanite_programs/healing.dm
index 706a048be49..3f401d52108 100644
--- a/code/modules/research/nanites/nanite_programs/healing.dm
+++ b/code/modules/research/nanites/nanite_programs/healing.dm
@@ -225,7 +225,7 @@
var/mob/living/carbon/C = host_mob
if(C.get_ghost())
return FALSE
- return C.can_defib()
+ return C.can_defib() == TRUE
/datum/nanite_program/defib/proc/zap()
var/mob/living/carbon/C = host_mob