mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-27 15:01:04 +01:00
Updates the health analyzer TGUI to be prettier (#22498)
This fixes a few minor bugs for non-handheld health analyzers, as well as updating the UI for them to be prettier. <img width="521" height="823" alt="image" src="https://github.com/user-attachments/assets/f0c121f1-e84c-4615-b4c5-1ec1f6620222" />
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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("<b>[user_vehicle]</b> starts scanning \the [target_mob] with \the [src].",
|
||||
SPAN_NOTICE("You start scanning \the [target_mob] with \the [src]."))
|
||||
|
||||
@@ -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."))
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]..."))
|
||||
|
||||
@@ -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."
|
||||
@@ -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<LimbResult | string>;
|
||||
internal_results: string[];
|
||||
reagent_results: string[];
|
||||
};
|
||||
|
||||
type LimbResult = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export const HealthAnalyzer = (props, context) => {
|
||||
const { act, data } = useBackend<HealthAnalyzerData>(context);
|
||||
const { scan_title, scan_results, reagent_results } = data;
|
||||
const {
|
||||
scan_title,
|
||||
status_results,
|
||||
trauma_results,
|
||||
limb_results,
|
||||
internal_results,
|
||||
reagent_results,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Window theme="zenghu">
|
||||
<Window.Content scrollable>
|
||||
{/* Basic info, brain damage and such */}
|
||||
<Section
|
||||
title={scan_title || 'Health Analyzer'}
|
||||
buttons={
|
||||
@@ -23,11 +39,11 @@ export const HealthAnalyzer = (props, context) => {
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{!scan_results?.length ? (
|
||||
{!status_results?.length ? (
|
||||
<Box color="label">No scan data.</Box>
|
||||
) : (
|
||||
<Stack vertical>
|
||||
{scan_results.map((line, i) => (
|
||||
{status_results.map((line, i) => (
|
||||
<Stack.Item key={i}>
|
||||
<Box
|
||||
className="HealthAnalyzer__line"
|
||||
@@ -38,10 +54,89 @@ export const HealthAnalyzer = (props, context) => {
|
||||
</Stack>
|
||||
)}
|
||||
</Section>
|
||||
{/* Anatomy related injuries. Limb injuries, major trauma, so on*/}
|
||||
<Section title="Anatomical Scan">
|
||||
{!trauma_results?.length &&
|
||||
!limb_results?.length &&
|
||||
!internal_results?.length ? (
|
||||
<Box color="label">No scan data.</Box>
|
||||
) : (
|
||||
<Stack vertical>
|
||||
{!!trauma_results?.length && (
|
||||
<Stack.Item>
|
||||
<Stack vertical>
|
||||
{trauma_results.map((line, i) => (
|
||||
<Stack.Item key={i}>
|
||||
<Box
|
||||
className="HealthAnalyzer__line"
|
||||
dangerouslySetInnerHTML={{ __html: line }}
|
||||
/>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
)}
|
||||
|
||||
{!!limb_results?.length && (
|
||||
<Stack.Item>
|
||||
<Box className="HealthAnalyzer__limb_List">
|
||||
<LabeledList>
|
||||
{limb_results.map((entry, i) =>
|
||||
typeof entry === 'string' ? (
|
||||
<LabeledList.Item key={i}>
|
||||
<Box
|
||||
className="HealthAnalyzer__line"
|
||||
dangerouslySetInnerHTML={{ __html: entry }}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
) : (
|
||||
<LabeledList.Item
|
||||
key={i}
|
||||
className="HealthAnalyzer__limb_List_Item"
|
||||
label={
|
||||
<Box
|
||||
bold
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: entry.label,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Box
|
||||
className="HealthAnalyzer__line"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: entry.value,
|
||||
}}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
),
|
||||
)}
|
||||
</LabeledList>
|
||||
</Box>
|
||||
</Stack.Item>
|
||||
)}
|
||||
|
||||
{!!internal_results?.length && (
|
||||
<Stack.Item>
|
||||
<Stack vertical>
|
||||
{internal_results.map((line, i) => (
|
||||
<Stack.Item key={i}>
|
||||
<Box
|
||||
className="HealthAnalyzer__line"
|
||||
dangerouslySetInnerHTML={{ __html: line }}
|
||||
/>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
)}
|
||||
</Stack>
|
||||
)}
|
||||
</Section>
|
||||
{/* Reagents. Things in stomach and blood */}
|
||||
<Section title="Reagent Scan">
|
||||
{!reagent_results?.length ? (
|
||||
<Box color="label">No results.</Box>
|
||||
<Box color="label">No scan data.</Box>
|
||||
) : (
|
||||
<Stack vertical>
|
||||
{reagent_results.map((line, i) => (
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user