From 6481a50506f12ab7fd567945c439230f233f775f Mon Sep 17 00:00:00 2001
From: SabreML <57483089+SabreML@users.noreply.github.com>
Date: Sun, 2 May 2021 15:42:56 +0100
Subject: [PATCH] 'Do Not Revive' verb for Ghosts (#15934)
* DNR
* Review things
Bound to be something I missed, but testing all seems to work fine.
* Aliven't
---
code/game/data_huds.dm | 9 +++++-
code/game/objects/items/devices/scanners.dm | 29 +++++++++++++------
code/game/objects/items/weapons/defib.dm | 13 +++++----
code/modules/mob/dead/observer/observer.dm | 24 +++++++++++++++
code/modules/mob/living/carbon/carbon.dm | 2 +-
.../reagents/chemistry/reagents/medicine.dm | 5 ++++
6 files changed, 66 insertions(+), 16 deletions(-)
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index 3692f725361..284b130f803 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -181,11 +181,18 @@
var/dead = stat == DEAD || HAS_TRAIT(src, TRAIT_FAKEDEATH)
// To the right of health bar
if(dead)
- var/revivable = timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT)
+ var/mob/dead/observer/ghost = get_ghost(TRUE)
+ var/revivable
+ if(ghost && !ghost.can_reenter_corpse) // DNR or AntagHUD
+ revivable = FALSE
+ else if(timeofdeath && (round(world.time - timeofdeath) < DEFIB_TIME_LIMIT))
+ revivable = TRUE
+
if(revivable)
holder.icon_state = "hudflatline"
else
holder.icon_state = "huddead"
+
else if(HAS_TRAIT(src, TRAIT_XENO_HOST))
holder.icon_state = "hudxeno"
else if(B && B.controlling)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 2bb6125b5ed..761943f9bcf 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -100,9 +100,9 @@ REAGENT SCANNER
/obj/item/healthanalyzer/attack(mob/living/M, mob/living/user)
if((HAS_TRAIT(user, TRAIT_CLUMSY) || user.getBrainLoss() >= 60) && prob(50))
user.visible_message("[user] analyzes the floor's vitals!", "You stupidly try to analyze the floor's vitals!")
- to_chat(user, "Analyzing results for The floor:\n\tOverall status: Healthy")
- to_chat(user, "Key: Suffocation/Toxin/Burn/Brute")
- to_chat(user, "\tDamage specifics: 0-0-0-0")
+ to_chat(user, "Analyzing results for The floor:\n\tOverall status: Healthy")
+ to_chat(user, "Key: Suffocation/Toxin/Burn/Brute")
+ to_chat(user, "\tDamage specifics: 0 - 0 - 0 - 0")
to_chat(user, "Body temperature: ???")
return
@@ -130,19 +130,30 @@ REAGENT SCANNER
var/TX = H.getToxLoss() > 50 ? "[H.getToxLoss()]" : H.getToxLoss()
var/BU = H.getFireLoss() > 50 ? "[H.getFireLoss()]" : H.getFireLoss()
var/BR = H.getBruteLoss() > 50 ? "[H.getBruteLoss()]" : H.getBruteLoss()
- if(HAS_TRAIT(H, TRAIT_FAKEDEATH))
- OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy
- to_chat(user, "Analyzing Results for [H]:\n\t Overall Status: dead")
- else
- to_chat(user, "Analyzing Results for [H]:\n\t Overall Status: [H.stat > 1 ? "dead" : "[H.health]% healthy"]")
+
+ var/status = "Dead" // Dead by default to make it simpler
+ var/mob/dead/observer/ghost = H.get_ghost(TRUE)
+ var/DNR = (ghost && !ghost.can_reenter_corpse)
+ if(H.stat == DEAD)
+ if(DNR)
+ status = "Dead \[DNR]"
+ else // Alive or unconscious
+ if(HAS_TRAIT(H, TRAIT_FAKEDEATH)) // status still shows as "Dead"
+ OX = fake_oxy > 50 ? "[fake_oxy]" : fake_oxy
+ else
+ status = "[H.health]% Healthy"
+
+ to_chat(user, "Analyzing Results for [H]:\n\t Overall Status: [status]")
to_chat(user, "\t Key: Suffocation/Toxin/Burns/Brute")
to_chat(user, "\t Damage Specifics: [OX] - [TX] - [BU] - [BR]")
to_chat(user, "Body Temperature: [H.bodytemperature-T0C]°C ([H.bodytemperature*1.8-459.67]°F)")
if(H.timeofdeath && (H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH))))
to_chat(user, "Time of Death: [station_time_timestamp("hh:mm:ss", H.timeofdeath)]")
var/tdelta = round(world.time - H.timeofdeath)
- if(tdelta < DEFIB_TIME_LIMIT)
+ if(tdelta < DEFIB_TIME_LIMIT && !DNR)
to_chat(user, "Subject died [DisplayTimeText(tdelta)] ago, defibrillation may be possible!")
+ else
+ to_chat(user, "Subject died [DisplayTimeText(tdelta)] ago.")
if(mode == 1)
var/list/damaged = H.get_damaged_organs(1,1)
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 43808c9105f..d7993768fec 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -363,7 +363,7 @@
if(do_after(user, 30 * toolspeed, target = M)) //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 [M.name]'s chest.", "You place [src] on [M.name]'s chest.")
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
- var/mob/dead/observer/ghost = H.get_ghost()
+ var/mob/dead/observer/ghost = H.get_ghost(TRUE)
if(ghost && !ghost.client)
// In case the ghost's not getting deleted for some reason
H.key = ghost.key
@@ -446,10 +446,13 @@
else if(total_burn >= 180 || total_brute >= 180)
user.visible_message("[defib] buzzes: Resuscitation failed - Severe tissue damage detected.")
else if(ghost)
- user.visible_message("[defib] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.")
- to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)")
- window_flash(ghost.client)
- ghost << sound('sound/effects/genetics.ogg')
+ if(!ghost.can_reenter_corpse) // DNR or AntagHUD
+ user.visible_message("[defib] buzzes: Resucitation failed: No electrical brain activity detected.")
+ else
+ user.visible_message("[defib] buzzes: Resuscitation failed: Patient's brain is unresponsive. Further attempts may succeed.")
+ to_chat(ghost, "Your heart is being defibrillated. Return to your body if you want to be revived! (Verbs -> Ghost -> Re-enter corpse)")
+ window_flash(ghost.client)
+ ghost << sound('sound/effects/genetics.ogg')
else
user.visible_message("[defib] buzzes: Resuscitation failed.")
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 47edad1c4fa..08324fb937a 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -387,6 +387,30 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(usr, "AntagHud Toggled OFF")
M.antagHUD = FALSE
+/mob/dead/observer/verb/set_dnr()
+ set name = "Set DNR"
+ set category = "Ghost"
+ set desc = "Prevent your character from being revived."
+
+ if(!isobserver(src)) // Somehow
+ return
+ if(!can_reenter_corpse)
+ to_chat(src, "You are already set to DNR!")
+ return
+ if(!mind || QDELETED(mind.current))
+ to_chat(src, "You have no body.")
+ return
+ if(mind.current.stat != DEAD)
+ to_chat(src, "Your body is still alive!")
+ return
+
+ var/choice = alert(src, "If you enable this, your body will be unrevivable for the remainder of the round.", "Are you sure?", "Yes", "No")
+ if(choice == "Yes")
+ to_chat(src, "Do Not Revive state enabled.")
+ can_reenter_corpse = FALSE
+ if(!QDELETED(mind.current)) // Could change while they're choosing
+ mind.current.med_hud_set_status()
+
/mob/dead/observer/proc/dead_tele()
set category = "Ghost"
set name = "Teleport"
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 8b0f8961e53..077b4073ca1 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -215,7 +215,7 @@
if(stat == DEAD)
if(M != src)
M.visible_message("[M] desperately shakes [src] trying to wake [p_them()] up, but sadly there is no reaction!", \
- "You shake [src] trying to wake [p_them()] sadly they appear to be too far gone!")
+ "You shake [src] trying to wake [p_them()], sadly they appear to be too far gone!")
return
if(health >= HEALTH_THRESHOLD_CRIT)
if(src == M && ishuman(src))
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index c05b578a42c..dd676794f74 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -774,6 +774,11 @@
if(M.getBruteLoss() + M.getFireLoss() + M.getCloneLoss() >= 150)
M.delayed_gib()
return
+ var/mob/dead/observer/ghost = M.get_ghost(TRUE)
+ if(ghost && !ghost.can_reenter_corpse) // DNR or AntagHUD
+ M.visible_message("[M] twitches slightly, but is otherwise unresponsive!")
+ return
+
if(!M.suiciding && !HAS_TRAIT(M, TRAIT_HUSK) && !HAS_TRAIT(M, TRAIT_BADDNA))
var/time_dead = world.time - M.timeofdeath
M.visible_message("[M] seems to rise from the dead!")