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 : '???'} +
+
+
+ )}