diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm
index dd0f209d3fa..b5de82895ac 100644
--- a/code/modules/mod/mod_types.dm
+++ b/code/modules/mod/mod_types.dm
@@ -317,7 +317,7 @@
applied_modules = list(
/obj/item/mod/module/storage,
/obj/item/mod/module/noslip,
- /obj/item/mod/module/status_readout,
+ /obj/item/mod/module/status_readout/ninja,
/obj/item/mod/module/stealth/ninja,
/obj/item/mod/module/dispenser/ninja,
/obj/item/mod/module/dna_lock/reinforced,
diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm
index 785fd284c7e..ad964c9d603 100644
--- a/code/modules/mod/modules/modules_general.dm
+++ b/code/modules/mod/modules/modules_general.dm
@@ -166,6 +166,68 @@
overlay_state_active = "module_jetpackadv_on"
full_speed = TRUE
+///Status Readout - Puts a lot of information including health, nutrition, fingerprints, temperature to the suit TGUI.
+/obj/item/mod/module/status_readout
+ name = "MOD status readout module"
+ desc = "A once-common module, this technology unfortunately went out of fashion in the safer regions of space; \
+ and found new life in the research networks of the Periphery. This particular unit hooks into the suit's spine, \
+ capable of capturing and displaying all possible biometric data of the wearer; sleep, nutrition, fitness, fingerprints, \
+ and even useful information such as their overall health and wellness. The vitals monitor also comes with a speaker, loud enough \
+ to alert anyone nearby that someone has, in fact, died."
+ icon_state = "status"
+ complexity = 1
+ use_power_cost = DEFAULT_CHARGE_DRAIN * 0.1
+ incompatible_modules = list(/obj/item/mod/module/status_readout)
+ tgui_id = "status_readout"
+ /// Does this show the round ID and shift time?
+ var/show_time = FALSE
+ /// Death sound. May or may not be funny. Vareditable at your own risk.
+ var/death_sound = 'sound/effects/flatline3.ogg'
+ /// Death sound volume. Please be responsible with this.
+ var/death_sound_volume = 50
+
+/obj/item/mod/module/status_readout/add_ui_data()
+ . = ..()
+ .["show_time"] = show_time
+ .["statustime"] = station_time_timestamp()
+ .["statusid"] = GLOB.round_id
+ .["statushealth"] = mod.wearer?.health || 0
+ .["statusmaxhealth"] = mod.wearer?.getMaxHealth() || 0
+ .["statusbrute"] = mod.wearer?.getBruteLoss() || 0
+ .["statusburn"] = mod.wearer?.getFireLoss() || 0
+ .["statustoxin"] = mod.wearer?.getToxLoss() || 0
+ .["statusoxy"] = mod.wearer?.getOxyLoss() || 0
+ .["statustemp"] = mod.wearer?.bodytemperature || 0
+ .["statusnutrition"] = mod.wearer?.nutrition || 0
+ .["statusfingerprints"] = mod.wearer ? md5(mod.wearer.dna.unique_identity) : null
+ .["statusdna"] = mod.wearer?.dna.unique_enzymes
+ .["statusviruses"] = null
+ if(!length(mod.wearer?.diseases))
+ return .
+ var/list/viruses = list()
+ for(var/datum/disease/virus as anything in mod.wearer.diseases)
+ var/list/virus_data = list()
+ virus_data["name"] = virus.name
+ virus_data["type"] = virus.spread_text
+ virus_data["stage"] = virus.stage
+ virus_data["maxstage"] = virus.max_stages
+ virus_data["cure"] = virus.cure_text
+ viruses += list(virus_data)
+ .["statusviruses"] = viruses
+
+ return .
+
+/obj/item/mod/module/status_readout/on_suit_activation()
+ RegisterSignal(mod.wearer, COMSIG_LIVING_DEATH, PROC_REF(death_sound))
+
+/obj/item/mod/module/status_readout/on_suit_deactivation(deleting)
+ UnregisterSignal(mod.wearer, COMSIG_LIVING_DEATH)
+
+/obj/item/mod/module/status_readout/proc/death_sound(mob/living/carbon/human/wearer)
+ SIGNAL_HANDLER
+ if(death_sound && death_sound_volume)
+ playsound(wearer, death_sound, death_sound_volume, FALSE)
+
///Eating Apparatus - Lets the user eat/drink with the suit on.
/obj/item/mod/module/mouthhole
name = "MOD eating apparatus module"
diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm
index db5843b63b5..59497e193e7 100644
--- a/code/modules/mod/modules/modules_medical.dm
+++ b/code/modules/mod/modules/modules_medical.dm
@@ -20,17 +20,23 @@
tgui_id = "health_analyzer"
/// Scanning mode, changes how we scan something.
var/mode = HEALTH_SCAN
+ /// Do we relay the wearer's health data to the info tab? Mainly useful for turning off if you also have a status readout.
+ var/show_vitals = TRUE
/// List of all scanning modes.
var/static/list/modes = list(HEALTH_SCAN, WOUND_SCAN, CHEM_SCAN)
/obj/item/mod/module/health_analyzer/add_ui_data()
. = ..()
- .["userhealth"] = mod.wearer?.health || 0
- .["usermaxhealth"] = mod.wearer?.getMaxHealth() || 0
- .["userbrute"] = mod.wearer?.getBruteLoss() || 0
- .["userburn"] = mod.wearer?.getFireLoss() || 0
- .["usertoxin"] = mod.wearer?.getToxLoss() || 0
- .["useroxy"] = mod.wearer?.getOxyLoss() || 0
+ .["show_vitals"] = show_vitals
+ if(show_vitals)
+ .["userhealth"] = mod.wearer?.health || 0
+ .["usermaxhealth"] = mod.wearer?.getMaxHealth() || 0
+ .["userbrute"] = mod.wearer?.getBruteLoss() || 0
+ .["userburn"] = mod.wearer?.getFireLoss() || 0
+ .["usertoxin"] = mod.wearer?.getToxLoss() || 0
+ .["useroxy"] = mod.wearer?.getOxyLoss() || 0
+
+ return .
/obj/item/mod/module/health_analyzer/on_select_use(atom/target)
. = ..()
@@ -50,11 +56,16 @@
/obj/item/mod/module/health_analyzer/get_configuration()
. = ..()
.["mode"] = add_ui_configuration("Scan Mode", "list", mode, modes)
+ .["show_vitals"] = add_ui_configuration("Self Vitals Display", "bool", show_vitals)
+
+ return .
/obj/item/mod/module/health_analyzer/configure_edit(key, value)
switch(key)
if("mode")
mode = value
+ if("show_vitals")
+ show_vitals = value
#undef HEALTH_SCAN
#undef WOUND_SCAN
diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm
index c83c1e3b1d4..a17fbf972ee 100644
--- a/code/modules/mod/modules/modules_ninja.dm
+++ b/code/modules/mod/modules/modules_ninja.dm
@@ -289,46 +289,18 @@
empulse(src, heavy_range = 4, light_range = 6)
drain_power(use_power_cost)
-///Status Readout - Puts a lot of information including health, nutrition, fingerprints, temperature to the suit TGUI.
-/obj/item/mod/module/status_readout
- name = "MOD status readout module"
- desc = "A once-common module, this technology went unfortunately out of fashion; \
- and right into the arachnid grip of the Spider Clan. This hooks into the suit's spine, \
- capable of capturing and displaying all possible biometric data of the wearer; sleep, nutrition, fitness, fingerprints, \
- and even useful information such as their overall health and wellness."
- icon_state = "status"
- complexity = 1
- use_power_cost = DEFAULT_CHARGE_DRAIN * 0.1
- incompatible_modules = list(/obj/item/mod/module/status_readout)
- tgui_id = "status_readout"
-
-/obj/item/mod/module/status_readout/add_ui_data()
- . = ..()
- .["statustime"] = station_time_timestamp()
- .["statusid"] = GLOB.round_id
- .["statushealth"] = mod.wearer?.health || 0
- .["statusmaxhealth"] = mod.wearer?.getMaxHealth() || 0
- .["statusbrute"] = mod.wearer?.getBruteLoss() || 0
- .["statusburn"] = mod.wearer?.getFireLoss() || 0
- .["statustoxin"] = mod.wearer?.getToxLoss() || 0
- .["statusoxy"] = mod.wearer?.getOxyLoss() || 0
- .["statustemp"] = mod.wearer?.bodytemperature || 0
- .["statusnutrition"] = mod.wearer?.nutrition || 0
- .["statusfingerprints"] = mod.wearer ? md5(mod.wearer.dna.unique_identity) : null
- .["statusdna"] = mod.wearer?.dna.unique_enzymes
- .["statusviruses"] = null
- if(!length(mod.wearer?.diseases))
- return
- var/list/viruses = list()
- for(var/datum/disease/virus as anything in mod.wearer.diseases)
- var/list/virus_data = list()
- virus_data["name"] = virus.name
- virus_data["type"] = virus.spread_text
- virus_data["stage"] = virus.stage
- virus_data["maxstage"] = virus.max_stages
- virus_data["cure"] = virus.cure_text
- viruses += list(virus_data)
- .["statusviruses"] = viruses
+/// Ninja Status Readout - Like the normal status display (see the base type), but with a clock.
+/obj/item/mod/module/status_readout/ninja
+ name = "MOD Spider Clan status readout module"
+ desc = "A once-common module, this technology unfortunately went out of fashion in the safer regions of space; \
+ and, according to the extra markings on this particular unit's casing, right into the arachnid grip of the Spider Clan. \
+ Like other similar units, this one hooks into the suit's spine, and is capable of capturing and displaying \
+ all possible biometric data of the wearer; sleep, nutrition, fitness, fingerprints, \
+ and even useful information such as their overall health and wellness. This one comes with a clock that calibrates to the \
+ local system time, and an operational ID number display. The vital monitor's speaker has been removed."
+ show_time = TRUE
+ death_sound = null
+ death_sound_volume = null
///Energy Net - Ensnares enemies in a net that prevents movement.
/obj/item/mod/module/energy_net
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index 4e3c77dc7b0..4c5f0f83b5b 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -1910,6 +1910,19 @@
RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_MEDICAL
)
+/datum/design/module/statusreadout
+ name = "Status Readout Module"
+ id = "mod_statusreadout"
+ materials = list(
+ /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT * 3,
+ /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT,
+ /datum/material/titanium = SMALL_MATERIAL_AMOUNT * 2,
+ )
+ build_path = /obj/item/mod/module/status_readout
+ category = list(
+ RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_MEDICAL
+ )
+
/datum/design/module/patienttransport
name = "Patient Transport Module"
id = "mod_patienttransport"
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 7c52e6fb390..2a3b25c1691 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -1784,6 +1784,7 @@
"mod_defib",
"mod_threadripper",
"mod_surgicalprocessor",
+ "mod_statusreadout",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3500)
diff --git a/modular_skyrat/modules/assault_operatives/code/equipment_items/stealth_mod.dm b/modular_skyrat/modules/assault_operatives/code/equipment_items/stealth_mod.dm
index 178e04a04f8..bff6ec0ffaa 100644
--- a/modular_skyrat/modules/assault_operatives/code/equipment_items/stealth_mod.dm
+++ b/modular_skyrat/modules/assault_operatives/code/equipment_items/stealth_mod.dm
@@ -87,7 +87,7 @@
/obj/item/mod/module/magnetic_harness,
/obj/item/mod/module/tether,
/obj/item/mod/module/holster,
- /obj/item/mod/module/status_readout/generic,
+ /obj/item/mod/module/status_readout/operational,
)
/obj/machinery/suit_storage_unit/industrial/assault_operative
diff --git a/modular_skyrat/modules/novaya_ert/code/mod_suit.dm b/modular_skyrat/modules/novaya_ert/code/mod_suit.dm
index 89a10c27d9d..29f5f81de37 100644
--- a/modular_skyrat/modules/novaya_ert/code/mod_suit.dm
+++ b/modular_skyrat/modules/novaya_ert/code/mod_suit.dm
@@ -76,7 +76,7 @@
applied_modules = list(
/obj/item/mod/module/storage/syndicate,
/obj/item/mod/module/thermal_regulator,
- /obj/item/mod/module/status_readout/generic,
+ /obj/item/mod/module/status_readout/operational,
/obj/item/mod/module/auto_doc,
/obj/item/mod/module/visor/thermal,
/obj/item/mod/module/jetpack/advanced,
@@ -158,7 +158,7 @@
applied_modules = list(
/obj/item/mod/module/storage/large_capacity,
/obj/item/mod/module/thermal_regulator,
- /obj/item/mod/module/status_readout/generic,
+ /obj/item/mod/module/status_readout/operational,
/obj/item/mod/module/tether,
/obj/item/mod/module/flashlight,
/obj/item/mod/module/paper_dispenser,
@@ -170,12 +170,14 @@
)
///Unrelated-to-Spider-Clan version of the module.
-/obj/item/mod/module/status_readout/generic
- name = "MOD status readout module"
- desc = "A once-common module, this technology went unfortunately out of fashion; \
- but still remaining in older suit variations. This hooks into the suit's spine, \
+/obj/item/mod/module/status_readout/operational
+ name = "MOD operational status readout module"
+ desc = "A once-common module, this technology unfortunately went out of fashion in the safer regions of space; \
+ however, it remained in use everywhere else. This particular unit hooks into the suit's spine, \
capable of capturing and displaying all possible biometric data of the wearer; sleep, nutrition, fitness, fingerprints, \
- and even useful information such as their overall health and wellness."
+ and even useful information such as their overall health and wellness. The vitals monitor also comes with a speaker, loud enough \
+ to alert anyone nearby that someone has, in fact, died. This specific unit has a clock and operational ID readout."
+ show_time = TRUE
///Blatant copy of the adrenaline boost module.
/obj/item/mod/module/auto_doc
diff --git a/sound/effects/flatline3.ogg b/sound/effects/flatline3.ogg
new file mode 100644
index 00000000000..1430ee7429b
Binary files /dev/null and b/sound/effects/flatline3.ogg differ
diff --git a/tgui/packages/tgui/interfaces/MODsuit.js b/tgui/packages/tgui/interfaces/MODsuit.js
index 58c528b3ece..27f3832f9e9 100644
--- a/tgui/packages/tgui/interfaces/MODsuit.js
+++ b/tgui/packages/tgui/interfaces/MODsuit.js
@@ -132,6 +132,7 @@ const RadCounter = (props, context) => {
const HealthAnalyzer = (props, context) => {
const {
active,
+ show_vitals,
userhealth,
usermaxhealth,
userbrute,
@@ -140,79 +141,88 @@ const HealthAnalyzer = (props, context) => {
useroxy,
} = props;
return (
- <>
-
-
-
-
+
+ {show_vitals ? (
+ <>
+
-
-
-
-
-
-
-
-
-
-
-
- >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ ) : (
+
+ {'Health Analyzer Vitals Readout Disabled In Settings'}
+
+ )}
+
);
};
const StatusReadout = (props, context) => {
const {
active,
+ show_time,
statustime,
statusid,
statushealth,
@@ -229,18 +239,20 @@ const StatusReadout = (props, context) => {
} = props;
return (
<>
-
-
-
- {active ? statustime : '00:00:00'}
-
-
-
-
- {active ? statusid || '0' : '???'}
-
-
-
+ {!!show_time && (
+
+
+
+ {active ? statustime : '00:00:00'}
+
+
+
+
+ {active ? statusid : '???'}
+
+
+
+ )}