diff --git a/code/datums/components/medical/medicalAnalyzer.dm b/code/datums/components/medical/medicalAnalyzer.dm index 1eebdafa338..6fdb128836c 100644 --- a/code/datums/components/medical/medicalAnalyzer.dm +++ b/code/datums/components/medical/medicalAnalyzer.dm @@ -12,9 +12,17 @@ var/last_scan = 0 var/device_level = 4 var/sound_scan = FALSE - var/list/scan_results = list() - var/list/reagent_results = list() var/scan_title = null + // General status such as brain damage, blood, so on + var/list/status_results = list() + // General types of trauma + var/list/trauma_results = list() + // Limb specific traumas + var/list/limb_results = list() + // Dislocated, broken, arterials and so on + var/list/internal_results = list() + // Ingested or injected reagents - Short term only + var/list/reagent_results = list() /// The owner object, also known as parent. Defined to easily do obj specific procs var/obj/owner @@ -54,7 +62,10 @@ /datum/component/health_analyzer/ui_data(mob/user) var/list/data = list() data["scan_title"] = scan_title - data["scan_results"] = scan_results + data["status_results"] = status_results + data["trauma_results"] = trauma_results + data["limb_results"] = limb_results + data["internal_results"] = internal_results data["reagent_results"] = reagent_results return data @@ -65,9 +76,12 @@ switch(action) if("clear_list") - scan_results = list() - reagent_results = list() scan_title = null + status_results = list() + trauma_results = list() + limb_results = list() + internal_results = list() + reagent_results = list() return TRUE /datum/component/health_analyzer/proc/attack(mob/living/target_mob, mob/living/user, target_zone) @@ -82,7 +96,7 @@ if(do_after(user, time SECONDS, target_mob, DO_UNIQUE)) flick("[owner.icon_state]-scan", owner) - health_scan_mob(target_mob, user, device_level, sound_scan = sound_scan) + health_scan_mob(target_mob, user, FALSE, sound_scan = sound_scan) ui_interact(user) owner.add_fingerprint(user) @@ -94,10 +108,13 @@ owner.add_fingerprint(user) -/datum/component/health_analyzer/proc/health_scan_mob(var/mob/M, var/mob/living/user, var/device_level = 2, var/just_scan = FALSE, var/sound_scan) - scan_results = list() - reagent_results = list() +/datum/component/health_analyzer/proc/health_scan_mob(var/mob/M, var/mob/living/user, var/just_scan = FALSE, var/sound_scan = FALSE) scan_title = null + status_results = list() + trauma_results = list() + limb_results = list() + internal_results = list() + reagent_results = list() if(!just_scan) if (((user.is_clumsy()) || (user.mutations & DUMB)) && prob(50)) @@ -118,7 +135,7 @@ if(!istype(M, /mob/living/carbon/human)) scan_title = "Scan failed" - scan_results += SPAN_SCAN_WARNING("This scanner is designed for humanoid patients only.") + status_results += SPAN_SCAN_WARNING("This scanner is designed for humanoid patients only.") if(sound_scan) playsound(user.loc, 'sound/items/healthscanner/healthscanner_used.ogg', 25, extrarange = SILENCED_SOUND_EXTRARANGE) return @@ -227,6 +244,9 @@ else dat += "Blood pressure: N/A" + status_results += dat + dat = list() + // Traumatic shock. if(H.is_asystole() || (H.status_flags & FAKEDEATH)) dat += SPAN_SCAN_DANGER("Cardiovascular shock detected. Administer CPR immediately.") @@ -242,32 +262,40 @@ if(H.getBruteLoss() > 50) dat += SPAN_SCAN_RED("[b]Severe anatomical damage detected.[endb]") + trauma_results += dat + dat = list() + if(device_level >= 2) var/list/damaged = H.get_damaged_organs(1,1) if(damaged.len) for(var/obj/item/organ/external/org in damaged) - var/limb_result = "[capitalize(org.name)][BP_IS_ROBOTIC(org) ? " (Cybernetic)" : ""]:" + var/limb_name = "[capitalize(org.name)][BP_IS_ROBOTIC(org) ? " (Cybernetic)" : ""]" + var/limb_result = "" if(org.brute_dam > 0) - limb_result = "[limb_result] [SPAN_SCAN_DANGER("[get_wound_severity(org.brute_dam, (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] physical trauma")]" + limb_result = " [SPAN_SCAN_DANGER("[get_wound_severity(org.brute_dam, (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] physical trauma")]" if(org.burn_dam > 0) - limb_result = "[limb_result] [SPAN_SCAN_ORANGE_DANGER("[get_wound_severity(org.burn_dam, (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] burns")]" + limb_result = "[limb_result][limb_result ? " | " : " "][SPAN_SCAN_ORANGE_DANGER("[get_wound_severity(org.burn_dam, (org.limb_flags & ORGAN_HEALS_OVERKILL), TRUE)] burns")]" if(org.status & ORGAN_BLEEDING) - limb_result = "[limb_result] [SPAN_SCAN_DANGER("bleeding")]" + limb_result = "[limb_result][limb_result ? " | " : " "][SPAN_SCAN_DANGER("bleeding")]" var/is_bandaged = org.is_bandaged() var/is_salved = org.is_salved() if(is_bandaged && is_salved) var/icon/B = icon('icons/obj/item/stacks/medical.dmi', "bandaged") var/icon/S = icon('icons/obj/item/stacks/medical.dmi', "salved") - limb_result = "[limb_result] \[[icon2html(B, user)] | [icon2html(S, user)]\]" + limb_result = "[limb_result][limb_result ? " | " : " "]\[[icon2html(B, user)] | [icon2html(S, user)]\]" else if(is_bandaged) var/icon/B = icon('icons/obj/item/stacks/medical.dmi', "bandaged") - limb_result = "[limb_result] \[[icon2html(B, user)]\]" + limb_result = "[limb_result][limb_result ? " | " : " "]\[[icon2html(B, user)]\]" else if(is_salved) var/icon/S = icon('icons/obj/item/stacks/medical.dmi', "salved") - limb_result = "[limb_result] \[[icon2html(S, user)]\]" - dat += limb_result - else - dat += "No detectable limb injuries." + limb_result = "[limb_result][limb_result ? " | " : " "]\[[icon2html(S, user)]\]" + + dat += list(list( + "label" = limb_name, + "value" = limb_result + )) + limb_results += dat + dat = list() if(device_level >= 3) for(var/name in H.organs_by_name) @@ -303,11 +331,11 @@ if(found_disloc && found_bleed && found_tendon) break - scan_results += dat + internal_results += dat dat = list() - // Reagent data. - . += "[b]Reagent scan:[endb]" + if(!length(limb_results) && !length(trauma_results) && !length(internal_results)) + trauma_results += "No results." var/print_reagent_default_message = TRUE diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 3b3f6cb1a8f..339583fa020 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -28,6 +28,11 @@ BREATH ANALYZER src.LoadComponent(/datum/component/health_analyzer) flick("[icon_state]-scan", src) +/obj/item/healthanalyzer/mechanics_hints(mob/user, distance, is_adjacent) + . += ..() + . += "Health analyzers are faster at scanning people, the higher grade it is and the higher the anatomy skill of the user is." + . += "Clicking it in hand will pull up the last scan, if it has not been cleared." + /obj/item/healthanalyzer/attack(mob/living/target_mob, mob/living/user, target_zone) var/datum/component/health_analyzer/h_analyzer = src.GetComponent(/datum/component/health_analyzer) if(!h_analyzer) diff --git a/code/modules/heavy_vehicle/equipment/medical.dm b/code/modules/heavy_vehicle/equipment/medical.dm index dfa22ce76fa..e2b88f15aac 100644 --- a/code/modules/heavy_vehicle/equipment/medical.dm +++ b/code/modules/heavy_vehicle/equipment/medical.dm @@ -375,7 +375,7 @@ var/datum/component/health_analyzer/mech/h_analyzer = src.GetComponent(/datum/component/health_analyzer/mech) if(!h_analyzer) return - h_analyzer.health_scan_mob(target_mob, pilot, TRUE, TRUE, sound_scan = TRUE) + h_analyzer.health_scan_mob(target_mob, pilot, FALSE, TRUE) else user_vehicle.visible_message("[user_vehicle] starts scanning \the [target_mob] with \the [src].", SPAN_NOTICE("You start scanning \the [target_mob] with \the [src].")) diff --git a/code/modules/mob/abstract/ghost/observer/observer.dm b/code/modules/mob/abstract/ghost/observer/observer.dm index 5ba7ce53ac9..4ca83075414 100644 --- a/code/modules/mob/abstract/ghost/observer/observer.dm +++ b/code/modules/mob/abstract/ghost/observer/observer.dm @@ -273,7 +273,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/datum/component/health_analyzer/observer/h_analyzer = src.GetComponent(/datum/component/health_analyzer/observer) if(!h_analyzer) return - h_analyzer.health_scan_mob(orbit_target, usr, TRUE, TRUE) + h_analyzer.health_scan_mob(orbit_target, usr, TRUE, FALSE) else to_chat(src, SPAN_WARNING("This isn't a scannable target.")) diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index bb9ec343eae..8cde0d29a0b 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -564,4 +564,4 @@ var/datum/component/health_analyzer/borer/h_analyzer = src.GetComponent(/datum/component/health_analyzer/borer) if(!h_analyzer) return - h_analyzer.health_scan_mob(host, src, TRUE, TRUE) + h_analyzer.health_scan_mob(host, src, TRUE, FALSE) diff --git a/code/modules/organs/subtypes/augment/augments/health_analyzer.dm b/code/modules/organs/subtypes/augment/augments/health_analyzer.dm index c975463cd99..3f315fbb1d7 100644 --- a/code/modules/organs/subtypes/augment/augments/health_analyzer.dm +++ b/code/modules/organs/subtypes/augment/augments/health_analyzer.dm @@ -18,4 +18,4 @@ var/datum/component/health_analyzer/h_analyzer = src.GetComponent(/datum/component/health_analyzer) if(!h_analyzer) return - h_analyzer.health_scan_mob(owner, owner, TRUE, TRUE) + h_analyzer.health_scan_mob(owner, owner, TRUE, FALSE) diff --git a/code/modules/organs/subtypes/autakh.dm b/code/modules/organs/subtypes/autakh.dm index 7675fdcb349..bbb66b5d8c8 100644 --- a/code/modules/organs/subtypes/autakh.dm +++ b/code/modules/organs/subtypes/autakh.dm @@ -406,7 +406,7 @@ var/datum/component/health_analyzer/h_analyzer = src.GetComponent(/datum/component/health_analyzer) if(!h_analyzer) return - h_analyzer.health_scan_mob(H, owner) + h_analyzer.health_scan_mob(H, owner, FALSE, TRUE) /obj/item/organ/external/hand/right/autakh/security name = "security grasper" diff --git a/code/modules/organs/subtypes/vaurca.dm b/code/modules/organs/subtypes/vaurca.dm index 8ae60a4a05b..ff4c59b0eae 100644 --- a/code/modules/organs/subtypes/vaurca.dm +++ b/code/modules/organs/subtypes/vaurca.dm @@ -721,4 +721,4 @@ var/datum/component/health_analyzer/h_analyzer = src.GetComponent(/datum/component/health_analyzer) if(!h_analyzer) return - h_analyzer.health_scan_mob(H, owner) + h_analyzer.health_scan_mob(H, owner, FALSE, TRUE) diff --git a/code/modules/psionics/abilities/skinsight.dm b/code/modules/psionics/abilities/skinsight.dm index fbff089be8f..204e784ea31 100644 --- a/code/modules/psionics/abilities/skinsight.dm +++ b/code/modules/psionics/abilities/skinsight.dm @@ -57,7 +57,7 @@ var/datum/component/health_analyzer/h_analyzer = src.GetComponent(/datum/component/health_analyzer) if(!h_analyzer) return - h_analyzer.health_scan_mob(target, user, TRUE, TRUE) + h_analyzer.health_scan_mob(target, user, TRUE, FALSE) else user.visible_message(SPAN_NOTICE("[user] slowly passes [user.get_pronoun("his")] hand over [target]..."), SPAN_NOTICE("You slowly pass your hand over [target]...")) diff --git a/html/changelogs/TGUIUpdate.yml b/html/changelogs/TGUIUpdate.yml new file mode 100644 index 00000000000..6e3df4eec53 --- /dev/null +++ b/html/changelogs/TGUIUpdate.yml @@ -0,0 +1,7 @@ +author: TheGreyWolf + +delete-after: True + +changes: + - bugfix: "Fixed that certain health analyzer stuff never showed limb damage and other advanced injuries." + - qol: "Improved the readability of the health analyzer UI." diff --git a/tgui/packages/tgui/interfaces/HealthAnalyzer.tsx b/tgui/packages/tgui/interfaces/HealthAnalyzer.tsx index 1fe28aefcd4..b77f31f2500 100644 --- a/tgui/packages/tgui/interfaces/HealthAnalyzer.tsx +++ b/tgui/packages/tgui/interfaces/HealthAnalyzer.tsx @@ -1,20 +1,36 @@ import { useBackend } from '../backend'; -import { Box, Button, Section, Stack } from '../components'; +import { Box, Button, LabeledList, Section, Stack } from '../components'; import { Window } from '../layouts'; type HealthAnalyzerData = { scan_title?: string; - scan_results: string[]; + status_results: string[]; + trauma_results: string[]; + limb_results: Array; + internal_results: string[]; reagent_results: string[]; }; +type LimbResult = { + label: string; + value: string; +}; + export const HealthAnalyzer = (props, context) => { const { act, data } = useBackend(context); - const { scan_title, scan_results, reagent_results } = data; + const { + scan_title, + status_results, + trauma_results, + limb_results, + internal_results, + reagent_results, + } = data; return ( + {/* Basic info, brain damage and such */}
{ } > - {!scan_results?.length ? ( + {!status_results?.length ? ( No scan data. ) : ( - {scan_results.map((line, i) => ( + {status_results.map((line, i) => ( { )}
+ {/* Anatomy related injuries. Limb injuries, major trauma, so on*/} +
+ {!trauma_results?.length && + !limb_results?.length && + !internal_results?.length ? ( + No scan data. + ) : ( + + {!!trauma_results?.length && ( + + + {trauma_results.map((line, i) => ( + + + + ))} + + + )} + {!!limb_results?.length && ( + + + + {limb_results.map((entry, i) => + typeof entry === 'string' ? ( + + + + ) : ( + + } + > + + + ), + )} + + + + )} + + {!!internal_results?.length && ( + + + {internal_results.map((line, i) => ( + + + + ))} + + + )} + + )} +
+ {/* Reagents. Things in stomach and blood */}
{!reagent_results?.length ? ( - No results. + No scan data. ) : ( {reagent_results.map((line, i) => ( diff --git a/tgui/packages/tgui/styles/interfaces/HealthAnalyzer.scss b/tgui/packages/tgui/styles/interfaces/HealthAnalyzer.scss index c9a2a8f4187..4e12bae714c 100644 --- a/tgui/packages/tgui/styles/interfaces/HealthAnalyzer.scss +++ b/tgui/packages/tgui/styles/interfaces/HealthAnalyzer.scss @@ -44,3 +44,27 @@ color: #ffa500; font-weight: bold; } + +.HealthAnalyzer__limb_List { + border-top: 1px solid rgba(255, 255, 255, 0.18); + border-bottom: 1px solid rgba(255, 255, 255, 0.18); + margin: 0.35em 0; + padding: 0.2em 0; +} + +.HealthAnalyzer__limb_List_Item { + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding: 0.35em 0.45em; +} + +.HealthAnalyzer__limb_List_Item:first-child { + border-top: 0; +} + +.HealthAnalyzer__limb_List_Item:nth-child(odd) { + background-color: rgba(255, 255, 255, 0.015); +} + +.HealthAnalyzer__limb_List_Item:nth-child(even) { + background-color: rgba(255, 255, 255, 0.03); +}