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