diff --git a/code/modules/mod/mod_ui.dm b/code/modules/mod/mod_ui.dm index 2a9652a4a98..5c4e3328868 100644 --- a/code/modules/mod/mod_ui.dm +++ b/code/modules/mod/mod_ui.dm @@ -6,24 +6,39 @@ /obj/item/mod/control/ui_data(mob/user) var/data = list() - data["interface_break"] = interface_break - data["malfunctioning"] = malfunctioning - data["open"] = open - data["active"] = active - data["locked"] = locked - data["complexity"] = complexity - data["selected_module"] = selected_module?.name - data["wearer_name"] = wearer ? (wearer.get_authentification_name("Unknown") || "Unknown") : "No Occupant" - data["wearer_job"] = wearer ? wearer.get_assignment("Unknown", "Unknown", FALSE) : "No Job" - // SKYRAT EDIT START - pAIs in MODsuits - data["pAI"] = mod_pai?.name - data["ispAI"] = mod_pai ? mod_pai == user : FALSE - // SKYRAT EDIT END - data["core"] = core?.name - data["charge"] = get_charge_percent() - data["modules"] = list() + // Suit information + var/suit_status = list( + "core_name" = core?.name, + "cell_charge_current" = get_charge(), + "cell_charge_max" = get_max_charge(), + "active" = active, + //"ai_name" = ai?.name, // SKYRAT EDIT REMOVAL - pAIs in MODsuits + // Wires + "open" = open, + "seconds_electrified" = seconds_electrified, + "malfunctioning" = malfunctioning, + "locked" = locked, + "interface_break" = interface_break, + // Modules + "complexity" = complexity, + // SKYRAT EDIT START - pAIs in MODsuits + "pAI" = mod_pai?.name, + "ispAI" = mod_pai ? mod_pai == user : FALSE, + // SKYRAT EDIT END + ) + data["suit_status"] = suit_status + // User information + var/user_status = list( + "user_name" = wearer ? (wearer.get_authentification_name("Unknown") || "Unknown") : "", + "user_assignment" = wearer ? wearer.get_assignment("Unknown", "Unknown", FALSE) : "", + ) + data["user_status"] = user_status + // Module information + var/module_custom_status = list() + var/module_info = list() for(var/obj/item/mod/module/module as anything in modules) - var/list/module_data = list( + module_custom_status += module.add_ui_data() + module_info += list(list( "module_name" = module.name, "description" = module.desc, "module_type" = module.module_type, @@ -38,9 +53,9 @@ "id" = module.tgui_id, "ref" = REF(module), "configuration_data" = module.get_configuration() - ) - module_data += module.add_ui_data() - data["modules"] += list(module_data) + )) + data["module_custom_status"] = module_custom_status + data["module_info"] = module_info return data /obj/item/mod/control/ui_static_data(mob/user) @@ -59,7 +74,7 @@ if(.) return // allowed() doesn't allow for pAIs - if((!allowed(usr) || !ispAI(usr)) && locked) // SKYRAT EDIT - pAIs in MODsuits + if(((locked && !ispAI(usr)) && !allowed(usr))) // SKYRAT EDIT CHANGE - ORIGINAL: if(locked && !allowed(usr)) balloon_alert(usr, "insufficient access!") playsound(src, 'sound/machines/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) return diff --git a/code/modules/mod/modules/modules_engineering.dm b/code/modules/mod/modules/modules_engineering.dm index bb822b64439..068944a8e1b 100644 --- a/code/modules/mod/modules/modules_engineering.dm +++ b/code/modules/mod/modules/modules_engineering.dm @@ -165,10 +165,10 @@ /obj/item/mod/module/rad_protection/add_ui_data() . = ..() - .["userradiated"] = mod.wearer ? HAS_TRAIT(mod.wearer, TRAIT_IRRADIATED) : FALSE - .["usertoxins"] = mod.wearer?.getToxLoss() || 0 - .["usermaxtoxins"] = mod.wearer?.getMaxHealth() || 0 - .["threatlevel"] = perceived_threat_level + .["is_user_irradiated"] = mod.wearer ? HAS_TRAIT(mod.wearer, TRAIT_IRRADIATED) : FALSE + .["background_radiation_level"] = perceived_threat_level + .["health_max"] = mod.wearer?.getMaxHealth() || 0 + .["loss_tox"] = mod.wearer?.getToxLoss() || 0 /obj/item/mod/module/rad_protection/proc/on_pre_potential_irradiation(datum/source, datum/radiation_pulse_information/pulse_information, insulation_to_target) SIGNAL_HANDLER diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index fab4b2a6b0f..9b9274bc316 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -101,7 +101,7 @@ overlay_state_active = "module_jetpack_on" /// Do we give the wearer a speed buff. var/full_speed = FALSE - var/stabilize = FALSE + var/stabilize = TRUE var/thrust_callback /obj/item/mod/module/jetpack/Initialize(mapload) @@ -182,8 +182,12 @@ use_power_cost = DEFAULT_CHARGE_DRAIN * 0.1 incompatible_modules = list(/obj/item/mod/module/status_readout) tgui_id = "status_readout" + /// Does this show damage types, body temp, satiety + var/display_detailed_vitals = TRUE + /// Does this show DNA data + var/display_dna = FALSE /// Does this show the round ID and shift time? - var/show_time = FALSE + var/display_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. @@ -191,20 +195,22 @@ /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 + .["display_time"] = display_time + .["shift_time"] = station_time_timestamp() + .["shift_id"] = GLOB.round_id + .["health"] = mod.wearer?.health || 0 + .["health_max"] = mod.wearer?.getMaxHealth() || 0 + if(display_detailed_vitals) + .["loss_brute"] = mod.wearer?.getBruteLoss() || 0 + .["loss_fire"] = mod.wearer?.getFireLoss() || 0 + .["loss_tox"] = mod.wearer?.getToxLoss() || 0 + .["loss_oxy"] = mod.wearer?.getOxyLoss() || 0 + .["body_temperature"] = mod.wearer?.bodytemperature || 0 + .["nutrition"] = mod.wearer?.nutrition || 0 + if(display_dna) + .["dna_unique_identity"] = mod.wearer ? md5(mod.wearer.dna.unique_identity) : null + .["dna_unique_enzymes"] = mod.wearer?.dna.unique_enzymes + .["viruses"] = null if(!length(mod.wearer?.diseases)) return . var/list/viruses = list() @@ -216,10 +222,22 @@ virus_data["maxstage"] = virus.max_stages virus_data["cure"] = virus.cure_text viruses += list(virus_data) - .["statusviruses"] = viruses + .["viruses"] = viruses return . +/obj/item/mod/module/status_readout/get_configuration() + . = ..() + .["display_detailed_vitals"] = add_ui_configuration("Detailed Vitals", "bool", display_detailed_vitals) + .["display_dna"] = add_ui_configuration("DNA Information", "bool", display_dna) + +/obj/item/mod/module/status_readout/configure_edit(key, value) + switch(key) + if("display_detailed_vitals") + display_detailed_vitals = text2num(value) + if("display_dna") + display_dna = text2num(value) + /obj/item/mod/module/status_readout/on_suit_activation() RegisterSignal(mod.wearer, COMSIG_LIVING_DEATH, PROC_REF(death_sound)) diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm index 59497e193e7..ca662d01ef2 100644 --- a/code/modules/mod/modules/modules_medical.dm +++ b/code/modules/mod/modules/modules_medical.dm @@ -20,22 +20,19 @@ 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() . = ..() - .["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 - + .["health"] = mod.wearer?.health || 0 + .["health_max"] = mod.wearer?.getMaxHealth() || 0 + .["loss_brute"] = mod.wearer?.getBruteLoss() || 0 + .["loss_fire"] = mod.wearer?.getFireLoss() || 0 + .["loss_tox"] = mod.wearer?.getToxLoss() || 0 + .["loss_oxy"] = mod.wearer?.getOxyLoss() || 0 + return . /obj/item/mod/module/health_analyzer/on_select_use(atom/target) @@ -56,16 +53,13 @@ /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 a17fbf972ee..0b9a804dc52 100644 --- a/code/modules/mod/modules/modules_ninja.dm +++ b/code/modules/mod/modules/modules_ninja.dm @@ -298,7 +298,7 @@ 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 + display_time = TRUE death_sound = null death_sound_volume = null diff --git a/modular_skyrat/modules/novaya_ert/code/mod_suit.dm b/modular_skyrat/modules/novaya_ert/code/mod_suit.dm index 29f5f81de37..adcae3fa3c7 100644 --- a/modular_skyrat/modules/novaya_ert/code/mod_suit.dm +++ b/modular_skyrat/modules/novaya_ert/code/mod_suit.dm @@ -177,7 +177,7 @@ 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. This specific unit has a clock and operational ID readout." - show_time = TRUE + display_time = TRUE ///Blatant copy of the adrenaline boost module. /obj/item/mod/module/auto_doc diff --git a/tgui/packages/tgui/interfaces/MODsuit.js b/tgui/packages/tgui/interfaces/MODsuit.js deleted file mode 100644 index 27f3832f9e9..00000000000 --- a/tgui/packages/tgui/interfaces/MODsuit.js +++ /dev/null @@ -1,802 +0,0 @@ -import { useBackend, useLocalState } from '../backend'; -import { Button, ColorBox, LabeledList, ProgressBar, Section, Collapsible, Box, Icon, Stack, Table, Dimmer, NumberInput, Flex, AnimatedNumber, Dropdown } from '../components'; -import { Window } from '../layouts'; - -const ConfigureNumberEntry = (props, context) => { - const { name, value, module_ref } = props; - const { act } = useBackend(context); - return ( - - act('configure', { - 'key': name, - 'value': value, - 'ref': module_ref, - }) - } - /> - ); -}; - -const ConfigureBoolEntry = (props, context) => { - const { name, value, module_ref } = props; - const { act } = useBackend(context); - return ( - - act('configure', { - 'key': name, - 'value': !value, - 'ref': module_ref, - }) - } - /> - ); -}; - -const ConfigureColorEntry = (props, context) => { - const { name, value, module_ref } = props; - const { act } = useBackend(context); - return ( - <> - - - - - - ); -}; - -const displayText = (param) => { - switch (param) { - case 1: - return 'Use'; - case 2: - return 'Toggle'; - case 3: - return 'Select'; - } -}; - -const ParametersSection = (props, context) => { - const { act, data } = useBackend(context); - const { - active, - malfunctioning, - locked, - open, - selected_module, - complexity, - complexity_max, - wearer_name, - wearer_job, - pAI, // SKYRAT EDIT - pAIs in MODsuits - ispAI, // SKYRAT EDIT - pAIs in MODsuits - } = data; - const status = malfunctioning - ? 'Malfunctioning' - : active - ? 'Active' - : 'Inactive'; - return ( -
- - act('activate')} - /> - }> - {status} - - act('lock')} - /> - }> - {locked ? 'Locked' : 'Unlocked'} - - - {open ? 'Open' : 'Closed'} - - - {selected_module || 'None'} - - - {complexity} ({complexity_max}) - - - {wearer_name}, {wearer_job} - - act('remove_pai')} - /> - ) : ( - <> - ) - }> - {pAI || 'None' /* SKYRAT EDIT END */} - - -
- ); -}; - -const HardwareSection = (props, context) => { - const { act, data } = useBackend(context); - const { - active, - control, - helmet, - chestplate, - gauntlets, - boots, - core, - charge, - } = data; - return ( -
- - - {control} - {helmet || 'None'} - - {chestplate || 'None'} - - - {gauntlets || 'None'} - - {boots || 'None'} - - - - {(core && ( - - {core} - - - - - )) || ( - - No Core Detected - - )} - -
- ); -}; - -const InfoSection = (props, context) => { - const { act, data } = useBackend(context); - const { active, modules } = data; - const info_modules = modules.filter((module) => !!module.id); - - return ( -
- - {(info_modules.length !== 0 && - info_modules.map((module) => { - const Module = ID2MODULE[module.id]; - return ( - - {!active && } - - - ); - })) || No Info Modules Detected} - -
- ); -}; - -const ModuleSection = (props, context) => { - const { act, data } = useBackend(context); - const { complexity_max, modules } = data; - const [configureState, setConfigureState] = useLocalState( - context, - 'module_configuration', - null - ); - return ( -
- - {(modules.length !== 0 && - modules.map((module) => { - return ( - - -
- {configureState === module.ref && ( - setConfigureState(null)} - /> - )} - - - -
- {module.description} -
-
-
- ); - })) || ( - - No Modules Detected - - )} -
-
- ); -}; - -export const MODsuitContent = (props, context) => { - const { act, data } = useBackend(context); - const { ui_theme, interface_break } = data; - return ( -
- {(!!interface_break && ) || ( - - - - - - - - - - - - - - - )} -
- ); -}; - -export const MODsuit = (props, context) => { - const { act, data } = useBackend(context); - const { ui_theme, interface_break } = data; - return ( - - - - - - ); -}; diff --git a/tgui/packages/tgui/interfaces/MODsuit.tsx b/tgui/packages/tgui/interfaces/MODsuit.tsx new file mode 100644 index 00000000000..ab3f69c1eda --- /dev/null +++ b/tgui/packages/tgui/interfaces/MODsuit.tsx @@ -0,0 +1,736 @@ +import { BooleanLike } from 'common/react'; +import { formatSiUnit } from '../format'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ColorBox, LabeledList, ProgressBar, Section, Collapsible, Box, Icon, Stack, Table, Dimmer, NumberInput, AnimatedNumber, Dropdown, NoticeBox } from '../components'; +import { Window } from '../layouts'; + +type MODsuitData = { + // Static + ui_theme: string; + control: string; + complexity_max: number; + helmet: string; + chestplate: string; + gauntlets: string; + boots: string; + // Dynamic + suit_status: SuitStatus; + user_status: UserStatus; + module_custom_status: ModuleCustomStatus; + module_info: Module[]; +}; + +type SuitStatus = { + core_name: string; + cell_charge_current: number; + cell_charge_max: number; + active: BooleanLike; + open: BooleanLike; + seconds_electrified: number; + malfunctioning: BooleanLike; + locked: BooleanLike; + interface_break: BooleanLike; + complexity: number; + selected_module: string; + ai_name: string; + pAI: string; // SKYRAT EDIT ADDITION - pAIs in MODsuits + ispAI: BooleanLike; // SKYRAT EDIT ADDITION - pAIs in MODsuits +}; + +type UserStatus = { + user_name: string; + user_assignment: string; +}; + +type ModuleCustomStatus = { + health: number; + health_max: number; + loss_brute: number; + loss_fire: number; + loss_tox: number; + loss_oxy: number; + is_user_irradiated: BooleanLike; + background_radiation_level: number; + display_time: BooleanLike; + shift_time: string; + shift_id: string; + body_temperature: number; + nutrition: number; + dna_unique_identity: string; + dna_unique_enzymes: string; + viruses: VirusData[]; +}; + +type VirusData = { + name: string; + type: string; + stage: number; + maxstage: number; + cure: string; +}; + +type Module = { + module_name: string; + description: string; + module_type: number; + module_active: BooleanLike; + pinned: BooleanLike; + idle_power: number; + active_power: number; + use_power: number; + module_complexity: number; + cooldown_time: number; + cooldown: number; + id: string; + ref: string; + configuration_data: ModuleConfig[]; +}; + +type ModuleConfig = { + display_name: string; + type: string; + value: number; + values: []; +}; + +export const MODsuit = (props, context) => { + const { act, data } = useBackend(context); + const { ui_theme } = data; + const { interface_break } = data.suit_status; + return ( + + + + + + ); +}; + +export const MODsuitContent = (props, context) => { + const { act, data } = useBackend(context); + const { interface_break } = data.suit_status; + return ( + + {interface_break ? ( + + ) : ( + + + + + + + + + + + + + + + + + + + )} + + ); +}; + +const ConfigureNumberEntry = (props, context) => { + const { name, value, module_ref } = props; + const { act } = useBackend(context); + return ( + + act('configure', { + 'key': name, + 'value': value, + 'ref': module_ref, + }) + } + /> + ); +}; + +const ConfigureBoolEntry = (props, context) => { + const { name, value, module_ref } = props; + const { act } = useBackend(context); + return ( + + act('configure', { + 'key': name, + 'value': !value, + 'ref': module_ref, + }) + } + /> + ); +}; + +const ConfigureColorEntry = (props, context) => { + const { name, value, module_ref } = props; + const { act } = useBackend(context); + return ( + <> +