diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 954c0c0ac44..6d9db65e94a 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -144,6 +144,7 @@ module = R.module ? R.module.name : "No Module Detected", synchronization = R.connected_ai, is_hacked = R.connected_ai && R.emagged, + emagged = R.emagged, hackable = can_hack(user, R), ) data["cyborgs"] += list(cyborg_data) diff --git a/code/game/machinery/doors/door_vr.dm b/code/game/machinery/doors/door_vr.dm index 7a2ba190cd3..4455a6c99d0 100644 --- a/code/game/machinery/doors/door_vr.dm +++ b/code/game/machinery/doors/door_vr.dm @@ -54,6 +54,7 @@ var/obj/item/stack/stack = I var/amount_given = amount_needed - reinforcing var/mats_given = stack.get_amount() + var/singular_name = stack.singular_name if(reinforcing && amount_given <= 0) to_chat(user, "You must weld or remove \the plasteel from \the [src] before you can add anything else.") else @@ -65,7 +66,7 @@ reinforcing += mats_given amount_given = mats_given if(amount_given) - to_chat(user, "You fit [amount_given] [stack.singular_name]\s on \the [src].") + to_chat(user, "You fit [amount_given] [singular_name]\s on \the [src].") return TRUE @@ -141,4 +142,4 @@ if(D.icon_tinted && (D.id_tint == src.id || !D.id_tint)) spawn(0) D.toggle() - return \ No newline at end of file + return diff --git a/code/modules/pda/cart_apps.dm b/code/modules/pda/cart_apps.dm index eaf0db739de..0b93f261a46 100644 --- a/code/modules/pda/cart_apps.dm +++ b/code/modules/pda/cart_apps.dm @@ -138,7 +138,7 @@ else for(var/datum/data/record/R as anything in sortRecord(data_core.general)) if(R) - records += list(list(Name = R.fields["name"], "ref" = "\ref[R]")) + records += list(list(name = R.fields["name"], "ref" = "\ref[R]")) data["recordsList"] = records data["records"] = null return null diff --git a/code/modules/resleeving/designer.dm b/code/modules/resleeving/designer.dm index b597fd5733d..da166a18bc8 100644 --- a/code/modules/resleeving/designer.dm +++ b/code/modules/resleeving/designer.dm @@ -196,6 +196,7 @@ var/datum/preferences/designer/P = new() apply_markings_to_prefs(mannequin, P) data["activeBodyRecord"]["markings"] = P.body_markings + data["activeBodyRecord"]["digitigrade"] = mannequin.digitigrade data["menu"] = menu data["temp"] = temp @@ -283,7 +284,6 @@ /obj/machinery/computer/transhuman/designer/proc/update_preview_icon() if(!mannequin) mannequin = new () - mannequin.delete_inventory(TRUE) update_preview_mob(mannequin) mannequin.ImmediateOverlayUpdate() @@ -357,6 +357,14 @@ H.sync_organ_dna() // Do this because sprites depend on DNA-gender of organs (chest etc) H.resize(active_br.sizemult, FALSE) + // Emissiive... + if(H.ear_style) + H.ear_style.em_block = FALSE + if(H.tail_style) + H.tail_style.em_block = FALSE + if(H.wing_style) + H.wing_style.em_block = FALSE + // And as for clothing... // We don't actually dress them! This is a medical machine, handle the nakedness DOCTOR! diff --git a/code/modules/vore/persist/persist_vr.dm b/code/modules/vore/persist/persist_vr.dm index 67bb1103c02..60311e9889b 100644 --- a/code/modules/vore/persist/persist_vr.dm +++ b/code/modules/vore/persist/persist_vr.dm @@ -130,15 +130,41 @@ prefs.f_style = character.f_style prefs.b_type = character.b_type -// Saves mob's current custom species, ears, and tail state to prefs +// Saves mob's current custom species, ears, tail, wings and digitigrade legs state to prefs // This basically needs to be the reverse of /datum/category_item/player_setup_item/vore/ears/copy_to_mob() ~Leshana /proc/apply_ears_to_prefs(var/mob/living/carbon/human/character, var/datum/preferences/prefs) - if(character.ear_style) prefs.ear_style = character.ear_style.type - if(character.tail_style) prefs.tail_style = character.tail_style.type + if(character.ear_style) prefs.ear_style = character.ear_style.name + if(character.tail_style) prefs.tail_style = character.tail_style.name + if(character.wing_style) prefs.wing_style = character.wing_style.name + prefs.r_ears = character.r_ears + prefs.g_ears = character.g_ears + prefs.b_ears = character.b_ears + prefs.r_ears2 = character.r_ears2 + prefs.g_ears2 = character.g_ears2 + prefs.b_ears2 = character.b_ears2 + prefs.r_ears3 = character.r_ears3 + prefs.g_ears3 = character.g_ears3 + prefs.b_ears3 = character.b_ears3 prefs.r_tail = character.r_tail prefs.b_tail = character.b_tail prefs.g_tail = character.g_tail + prefs.r_tail2 = character.r_tail2 + prefs.b_tail2 = character.b_tail2 + prefs.g_tail2 = character.g_tail2 + prefs.r_tail3 = character.r_tail3 + prefs.b_tail3 = character.b_tail3 + prefs.g_tail3 = character.g_tail3 + prefs.r_wing = character.r_wing + prefs.b_wing = character.b_wing + prefs.g_wing = character.g_wing + prefs.r_wing2 = character.r_wing2 + prefs.b_wing2 = character.b_wing2 + prefs.g_wing2 = character.g_wing2 + prefs.r_wing3 = character.r_wing3 + prefs.b_wing3 = character.b_wing3 + prefs.g_wing3 = character.g_wing3 prefs.custom_species = character.custom_species + prefs.digitigrade = character.digitigrade // Saves mob's current organ state to prefs. // This basically needs to be the reverse of /datum/category_item/player_setup_item/general/body/copy_to_mob() ~Leshana diff --git a/tgui/packages/tgui/components/Box.tsx b/tgui/packages/tgui/components/Box.tsx index 2ee476fddd9..4891624d59d 100644 --- a/tgui/packages/tgui/components/Box.tsx +++ b/tgui/packages/tgui/components/Box.tsx @@ -203,6 +203,7 @@ const booleanStyleMap = { }, inline: mapBooleanPropTo('display', 'inline-block'), italic: mapBooleanPropTo('fontStyle', 'italic'), + underline: mapBooleanPropTo('textDecorationLine', 'underline'), // Vorestation Add nowrap: mapBooleanPropTo('whiteSpace', 'nowrap'), preserveWhitespace: mapBooleanPropTo('whiteSpace', 'pre-wrap'), } as const; diff --git a/tgui/packages/tgui/interfaces/Autolathe.tsx b/tgui/packages/tgui/interfaces/Autolathe.tsx index 97c00ad02ee..cf27ce81d60 100644 --- a/tgui/packages/tgui/interfaces/Autolathe.tsx +++ b/tgui/packages/tgui/interfaces/Autolathe.tsx @@ -7,7 +7,7 @@ import { useBackend, useSharedState } from '../backend'; import { Box, Button, Dropdown, Flex, Input, Section } from '../components'; import { Window } from '../layouts'; import { mat } from './common/CommonTypes'; -import { Materials } from './ExosuitFabricator'; +import { Materials } from './ExosuitFabricator/Material'; const canBeMade = (recipe, materials, mult: number = 1) => { if (recipe.requirements === null) { @@ -53,7 +53,7 @@ export const Autolathe = (props) => { const [category, setCategory] = useSharedState('category', 0); const [searchText, setSearchText] = useSharedState('search_text', ''); - const testSearch = createSearch(searchText, (recipe) => recipe.name); + const testSearch = createSearch(searchText, (recipe: recipe) => recipe.name); const recipesToShow = flow([ filter((recipe: recipe) => recipe.category === categories[category]), diff --git a/tgui/packages/tgui/interfaces/BodyDesigner/BodyDesignerSpecificRecord.tsx b/tgui/packages/tgui/interfaces/BodyDesigner/BodyDesignerSpecificRecord.tsx index b6fd5e67f44..8b22f1be3b6 100644 --- a/tgui/packages/tgui/interfaces/BodyDesigner/BodyDesignerSpecificRecord.tsx +++ b/tgui/packages/tgui/interfaces/BodyDesigner/BodyDesignerSpecificRecord.tsx @@ -113,7 +113,9 @@ export const BodyDesignerSpecificRecord = (props: { > {style.style} - ) : null} + ) : ( + '' + )} {style.colorHref ? ( + - - )) || - null} - {(data.manufacturers && ( - - Manufacturer: - - - )) || - null} - - - - - - -
act('sync_rnd')}>R&D Sync - } - > - -
-
- - - - - - - - -
-
- - - - ); -}; - -const EjectMaterial = (props) => { - const { act } = useBackend(); - - const { material } = props; - - const { name, removable, sheets } = material; - - const [removeMaterials, setRemoveMaterials] = useSharedState( - 'remove_mats_' + name, - 1, - ); - - if (removeMaterials > 1 && sheets < removeMaterials) { - setRemoveMaterials(sheets || 1); - } - - return ( - <> - { - const newVal = parseInt(val, 10); - if (Number.isInteger(newVal)) { - setRemoveMaterials(newVal); - } - }} - /> - - } - > - {!parts.length && placeholder} - {parts.map((part) => ( - - - - - )) || ( - - )} - - } - > - - - - - - - - - - - {!!queue.length && ( - -
- -
-
- )} -
- ); -}; - -const QueueMaterials = (props) => { - const { queueMaterials, missingMaterials } = props; - - return ( - - {Object.keys(queueMaterials).map((material) => ( - - - {!!missingMaterials[material] && ( - - {formatMoney(missingMaterials[material])} - - )} - - ))} - - ); -}; - -const QueueList = (props) => { - const { act, data } = useBackend(); - - const { textColors } = props; - - const queue = data.queue || []; - - if (!queue.length) { - return <>No parts in queue.; - } - - return queue.map((part, index) => ( - - - - + } + > + {!parts.length && placeholder} + {parts.map((part) => ( + + + + + )) || ( + + )} + + } + > + + + + + + + + + + + {!!length && ( + +
+ +
+
+ )} +
+ ); +}; + +const QueueMaterials = (props: { + queueMaterials: Record; + missingMaterials: Record; +}) => { + const { queueMaterials, missingMaterials } = props; + + return ( + + {Object.keys(queueMaterials).map((material) => ( + + + {!!missingMaterials[material] && ( + + {formatMoney(missingMaterials[material])} + + )} + + ))} + + ); +}; + +const QueueList = (props: { textColors: Record }) => { + const { act, data } = useBackend(); + + const { textColors } = props; + + const { queue = [] } = data; + + if (!queue || !queue.length) { + return <>No parts in queue.; + } + + return queue.map((part, index) => ( + + + + + + )) || + null} + {(manufacturers && ( + + Manufacturer: + + + )) || + null} + +
+
+ + + +
act('sync_rnd')}>R&D Sync + } + > + +
+
+ + + + + + + + +
+
+ + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/ExosuitFabricator/types.ts b/tgui/packages/tgui/interfaces/ExosuitFabricator/types.ts new file mode 100644 index 00000000000..2a7b85710a6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ExosuitFabricator/types.ts @@ -0,0 +1,42 @@ +import { BooleanLike } from 'common/react'; + +export type Data = { + partSets: string[]; + buildableParts: Record | []; + materials: material[]; + buildingPart: { name: string; duration: number; printTime: number } | null; + queue: part[] | null; + storedPart: string | null; + isProcessingQueue: BooleanLike; + species_types: string[]; + species: string; + manufacturers: { id: string; company: string }; + manufacturer: string; +}; + +export type part = { + name: string; + desc: string; + printTime: number; + cost: number; + id: string; + subCategory: string[]; + categoryOverride: string[]; + searchMeta: string | null; +}; + +export type material = { + name: string; + amount: number; + sheets: number; + removable: BooleanLike; +}; + +export type queueFormat = { + materialTally: Record; + missingMatTally: Record; + matFormat: { color: number; deficit: number } | {}; + textColors: Record; +}; + +export type internalPart = Required; diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl.jsx b/tgui/packages/tgui/interfaces/GeneralAtmoControl.jsx deleted file mode 100644 index 0ec31e6a0a3..00000000000 --- a/tgui/packages/tgui/interfaces/GeneralAtmoControl.jsx +++ /dev/null @@ -1,310 +0,0 @@ -import { useBackend } from '../backend'; -import { Box, Button, Flex, LabeledList, Section, Slider } from '../components'; -import { Window } from '../layouts'; - -export const GeneralAtmoControl = (props) => { - const { act, data } = useBackend(); - - // While many of these variables are unused, it's helpful to have a consistent - // list of all possible parameters in the core component of this UI. - // So, keep them here and update them as necessary, pretty please. - const { - // All - sensors, - // Tanks /obj/machinery/computer/general_air_control - tanks, - // Tanks+Core /obj/machinery/computer/general_air_control/large_tank_control - input_info, - output_info, - input_flow_setting, - pressure_setting, - max_pressure, - max_flowrate, - // Core /obj/machinery/computer/general_air_control/supermatter_core - core, - // Fuel /obj/machinery/computer/general_air_control/fuel_injection - fuel, - automation, - device_info, - } = data; - - return ( - - - - {(core || tanks) && } - {fuel && } - - - ); -}; - -const AtmoControlSensors = (props) => { - const { act } = useBackend(); - - const { sensors } = props; - - if (!sensors) { - return ( -
- No Sensors Connected. -
- ); - } else { - return ( -
- {sensors.map((sensor) => ( -
- -
- ))} -
- ); - } -}; - -const AtmoSensor = (props) => { - const { sensor } = props; - - if (!sensor.sensor_data) { - return UNABLE TO FIND SENSOR; - } - - const { pressure, temperature, oxygen, nitrogen, carbon_dioxide, phoron } = - sensor.sensor_data; - - let labeledListContents = []; - if (pressure) { - labeledListContents.push( - {pressure} kPa, - ); - } - - if (temperature) { - labeledListContents.push( - {temperature} K, - ); - } - - if (oxygen || nitrogen || carbon_dioxide || phoron) { - labeledListContents.push( - - - {oxygen ? ({oxygen}% O²) : null} - {nitrogen ? ({nitrogen}% N²) : null} - {carbon_dioxide ? ( - ({carbon_dioxide}% CO²) - ) : null} - {phoron ? ({phoron}% TX) : null} - - , - ); - } - - return {labeledListContents.map((item) => item)}; -}; - -const AtmoControlTankCore = (props) => { - const { act, data } = useBackend(); - - const { - // Tanks /obj/machinery/computer/general_air_control - tanks, - // Tanks+Core /obj/machinery/computer/general_air_control/large_tank_control - input_info, - output_info, - input_flow_setting, - pressure_setting, - max_pressure, - max_flowrate, - // Core /obj/machinery/computer/general_air_control/supermatter_core - core, - } = data; - - let sectionName = 'Unknown Control System'; - if (tanks) { - sectionName = 'Tank Control System'; - } else if (core) { - sectionName = 'Core Cooling Control System'; - } - - const inputActions = { - power: () => act('in_toggle_injector'), - apply: () => act('in_set_flowrate'), - refresh: () => act('in_refresh_status'), - slider: (e, val) => - act('adj_input_flow_rate', { - adj_input_flow_rate: val, - }), - }; - - const outputActions = { - power: () => act('out_toggle_power'), - apply: () => act('out_set_pressure'), - refresh: () => act('out_refresh_status'), - slider: (e, val) => act('adj_pressure', { adj_pressure: val }), - }; - - return ( -
- - -
- ); -}; - -const AtmoControlTankCoreControl = (props) => { - const { - info, - maxSliderValue, - sliderControl, - sliderFill, - unit, - name, - limitName, - actions, - } = props; - - return ( -
- - - - } - > - - {(info && ( - - {info.power ? 'Injecting' : 'On Hold'} - - )) || ( - - ERROR: Cannot Find {name} Port - - - )} - actions.apply()} - > - Apply - - } - > - actions.slider(e, val)} - > - {sliderFill ? sliderFill : 'UNK'} {unit} / {sliderControl} {unit} - - - -
- ); -}; - -const AtmoControlFuel = (props) => { - const { act, data } = useBackend(); - - const { fuel, automation, device_info } = data; - return ( -
- - - - - } - > - {device_info ? ( - - - {device_info.power ? 'Injecting' : 'On Hold'} - - - {device_info.volume_rate} - - - - - - ) : ( - <> - ERROR: Cannot Find Device - - - )} -
- ); -}; diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl/FuelControls.tsx b/tgui/packages/tgui/interfaces/GeneralAtmoControl/FuelControls.tsx new file mode 100644 index 00000000000..1a1796428c6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralAtmoControl/FuelControls.tsx @@ -0,0 +1,63 @@ +import { useBackend } from '../../backend'; +import { Box, Button, LabeledList, Section } from '../../components'; +import { Data } from './types'; + +export const AtmoControlFuel = (props) => { + const { act, data } = useBackend(); + + const { automation, device_info } = data; + return ( +
+ + + + + } + > + {device_info ? ( + + + {device_info.power ? 'Injecting' : 'On Hold'} + + + {device_info.volume_rate} + + + + + + ) : ( + <> + ERROR: Cannot Find Device + + + )} +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl/Sensors.tsx b/tgui/packages/tgui/interfaces/GeneralAtmoControl/Sensors.tsx new file mode 100644 index 00000000000..b1024b08fc8 --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralAtmoControl/Sensors.tsx @@ -0,0 +1,65 @@ +import { Box, Flex, LabeledList, Section } from '../../components'; +import { sensor } from './types'; + +export const AtmoControlSensors = (props: { sensors: sensor[] }) => { + const { sensors } = props; + + if (!sensors) { + return ( +
+ No Sensors Connected. +
+ ); + } else { + return ( +
+ {sensors.map((sensor) => ( +
+ +
+ ))} +
+ ); + } +}; + +const AtmoSensor = (props: { sensor: sensor }) => { + const { sensor } = props; + + if (!sensor.sensor_data) { + return UNABLE TO FIND SENSOR; + } + + const { pressure, temperature, oxygen, nitrogen, carbon_dioxide, phoron } = + sensor.sensor_data; + + let labeledListContents: React.JSX.Element[] = []; + if (pressure) { + labeledListContents.push( + {pressure} kPa, + ); + } + + if (temperature) { + labeledListContents.push( + {temperature} K, + ); + } + + if (oxygen || nitrogen || carbon_dioxide || phoron) { + labeledListContents.push( + + + {oxygen ? ({oxygen}% O²) : null} + {nitrogen ? ({nitrogen}% N²) : null} + {carbon_dioxide ? ( + ({carbon_dioxide}% CO²) + ) : null} + {phoron ? ({phoron}% TX) : null} + + , + ); + } + + return {labeledListContents.map((item) => item)}; +}; diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl/TankControls.tsx b/tgui/packages/tgui/interfaces/GeneralAtmoControl/TankControls.tsx new file mode 100644 index 00000000000..bd11ac243ee --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralAtmoControl/TankControls.tsx @@ -0,0 +1,148 @@ +import { useBackend } from '../../backend'; +import { Box, Button, LabeledList, Section, Slider } from '../../components'; +import { Data } from './types'; + +export const AtmoControlTankCore = (props) => { + const { act, data } = useBackend(); + + const { + // Tanks /obj/machinery/computer/general_air_control + tanks, + // Tanks+Core /obj/machinery/computer/general_air_control/large_tank_control + input_info, + output_info, + input_flow_setting, + pressure_setting, + max_pressure, + max_flowrate, + // Core /obj/machinery/computer/general_air_control/supermatter_core + core, + } = data; + + let sectionName = 'Unknown Control System'; + if (tanks) { + sectionName = 'Tank Control System'; + } else if (core) { + sectionName = 'Core Cooling Control System'; + } + + const inputActions = { + power: () => act('in_toggle_injector'), + apply: () => act('in_set_flowrate'), + refresh: () => act('in_refresh_status'), + slider: (e, val: number) => + act('adj_input_flow_rate', { + adj_input_flow_rate: val, + }), + }; + + const outputActions = { + power: () => act('out_toggle_power'), + apply: () => act('out_set_pressure'), + refresh: () => act('out_refresh_status'), + slider: (e, val: number) => act('adj_pressure', { adj_pressure: val }), + }; + + return ( +
+ + +
+ ); +}; + +const AtmoControlTankCoreControl = (props) => { + const { + info, + maxSliderValue, + sliderControl, + sliderFill, + unit, + name, + limitName, + actions, + } = props; + + return ( +
+ + + + } + > + + {(info && ( + + {info.power ? 'Injecting' : 'On Hold'} + + )) || ( + + ERROR: Cannot Find {name} Port + + + )} + actions.apply()} + > + Apply + + } + > + actions.slider(e, val)} + > + {sliderFill ? sliderFill : 'UNK'} {unit} / {sliderControl} {unit} + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl/index.tsx b/tgui/packages/tgui/interfaces/GeneralAtmoControl/index.tsx new file mode 100644 index 00000000000..22d8ac79efe --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralAtmoControl/index.tsx @@ -0,0 +1,34 @@ +import { useBackend } from '../../backend'; +import { Window } from '../../layouts'; +import { AtmoControlFuel } from './FuelControls'; +import { AtmoControlSensors } from './Sensors'; +import { AtmoControlTankCore } from './TankControls'; +import { Data } from './types'; + +export const GeneralAtmoControl = (props) => { + const { data } = useBackend(); + + // While many of these variables are unused, it's helpful to have a consistent + // list of all possible parameters in the core component of this UI. + // So, keep them here and update them as necessary, pretty please. + const { + // All + sensors, + // Tanks /obj/machinery/computer/general_air_control + tanks, + // Core /obj/machinery/computer/general_air_control/supermatter_core + core, + // Fuel /obj/machinery/computer/general_air_control/fuel_injection + fuel, + } = data; + + return ( + + + + {(core || tanks) && } + {fuel && } + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/GeneralAtmoControl/types.ts b/tgui/packages/tgui/interfaces/GeneralAtmoControl/types.ts new file mode 100644 index 00000000000..f430e495dee --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralAtmoControl/types.ts @@ -0,0 +1,29 @@ +import { BooleanLike } from 'common/react'; + +export type Data = { + sensors: sensor[]; + tanks: BooleanLike; + core: BooleanLike; + fuel: BooleanLike; + automation: BooleanLike; + input_info: { power: number; volume_rate: number } | null | undefined; + output_info: { power: number; output_pressure: number } | null | undefined; + device_info: { power: number; volume_rate: number } | null | undefined; + input_flow_setting: number | undefined; + pressure_setting: number | undefined; + max_pressure: number | undefined; + max_flowrate: number | undefined; +}; + +export type sensor = { + long_name: string; + sensor_data: { + pressure: number; + temperature: number; + oxygen: number; + nitrogen: number; + carbon_dioxide: number; + phoron: number; + other: number; + }; +}; diff --git a/tgui/packages/tgui/interfaces/GeneralRecords.jsx b/tgui/packages/tgui/interfaces/GeneralRecords.jsx deleted file mode 100644 index 958b3de10c7..00000000000 --- a/tgui/packages/tgui/interfaces/GeneralRecords.jsx +++ /dev/null @@ -1,280 +0,0 @@ -import { filter } from 'common/collections'; -import { flow } from 'common/fp'; -import { createSearch } from 'common/string'; -import { useState } from 'react'; - -import { useBackend } from '../backend'; -import { - Box, - Button, - Icon, - Input, - LabeledList, - Section, - Tabs, -} from '../components'; -import { Window } from '../layouts'; -import { ComplexModal, modalOpen } from './common/ComplexModal'; -import { LoginInfo } from './common/LoginInfo'; -import { LoginScreen } from './common/LoginScreen'; -import { TemporaryNotice } from './common/TemporaryNotice'; - -const doEdit = (field) => { - modalOpen('edit', { - field: field.edit, - value: field.value, - }); -}; - -export const GeneralRecords = (_properties) => { - const { data } = useBackend(); - const { authenticated, screen } = data; - if (!authenticated) { - return ( - - - - - - ); - } - - let body; - if (screen === 2) { - // List Records - body = ; - } else if (screen === 3) { - // Record Maintenance - body = ; - } else if (screen === 4) { - // View Records - body = ; - } - - return ( - - - - - - -
- {body} -
-
-
- ); -}; - -/** - * Record selector. - * - * Filters records, applies search terms and sorts the alphabetically. - */ -const selectRecords = (records, searchText = '') => { - const nameSearch = createSearch(searchText, (record) => record.name); - const idSearch = createSearch(searchText, (record) => record.id); - const dnaSearch = createSearch(searchText, (record) => record.b_dna); - let fl = flow([ - // Optional search term - searchText && - filter((record) => { - return nameSearch(record) || idSearch(record) || dnaSearch(record); - }), - ])(records); - return fl; -}; - -const GeneralRecordsList = (_properties) => { - const { act, data } = useBackend(); - - const [searchText, setSearchText] = useState(''); - - const records = selectRecords(data.records, searchText); - return ( - <> - - - - setSearchText(value)} - /> - - {records.map((record, i) => ( - - ))} - - - ); -}; - -const GeneralRecordsMaintenance = (_properties) => { - const { act } = useBackend(); - return ( - act('del_all')}> - Delete All Employment Records - - ); -}; - -const GeneralRecordsView = (_properties) => { - const { act, data } = useBackend(); - const { general, printing } = data; - return ( - <> -
- -
-
- act('del_r')} - > - Delete Employment Record - - -
- -
- - ); -}; - -const GeneralRecordsViewGeneral = (_properties) => { - const { act, data } = useBackend(); - const { general } = data; - if (!general || !general.fields) { - return ( - - General record lost! - - - ); - } - return ( - <> - - - {general.fields.map((field, i) => ( - - - {field.value} - - {!!field.edit && ( - - - - - {!!general.has_photos && - general.photos.map((p, i) => ( - - -
- Photo #{i + 1} -
- ))} -
- - ); -}; - -const GeneralRecordsNavigation = (_properties) => { - const { act, data } = useBackend(); - const { screen } = data; - return ( - - act('screen', { screen: 2 })} - > - - List Records - - act('screen', { screen: 3 })} - > - - Record Maintenance - - - ); -}; diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsList.tsx b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsList.tsx new file mode 100644 index 00000000000..99ea8a12476 --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsList.tsx @@ -0,0 +1,40 @@ +import { useState } from 'react'; + +import { useBackend } from '../../backend'; +import { Box, Button, Input } from '../../components'; +import { selectRecords } from './functions'; +import { Data, record } from './types'; + +export const GeneralRecordsList = (props) => { + const { act, data } = useBackend(); + + const [searchText, setSearchText] = useState(''); + + const records: record[] = selectRecords(data.records!, searchText); + return ( + <> + + + + setSearchText(value)} + /> + + {records.map((record, i) => ( + + ))} + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsOptions.tsx b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsOptions.tsx new file mode 100644 index 00000000000..5db9a5c321d --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsOptions.tsx @@ -0,0 +1,75 @@ +import { useBackend } from '../../backend'; +import { Button, Icon, Section, Tabs } from '../../components'; +import { GeneralRecordsViewGeneral } from './GeneralRecordsViewGeneral'; +import { Data } from './types'; + +export const GeneralRecordsMaintenance = (props) => { + const { act } = useBackend(); + return ( + act('del_all')}> + Delete All Employment Records + + ); +}; + +export const GeneralRecordsView = (props) => { + const { act, data } = useBackend(); + const { general, printing } = data; + return ( + <> +
+ +
+
+ act('del_r')} + > + Delete Employment Record + + +
+ +
+ + ); +}; + +export const GeneralRecordsNavigation = (props) => { + const { act, data } = useBackend(); + const { screen } = data; + return ( + + act('screen', { screen: 2 })} + > + + List Records + + act('screen', { screen: 3 })} + > + + Record Maintenance + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsViewGeneral.tsx b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsViewGeneral.tsx new file mode 100644 index 00000000000..5d762469830 --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsViewGeneral.tsx @@ -0,0 +1,104 @@ +import { useBackend } from '../../backend'; +import { Box, Button, Image, LabeledList, Section } from '../../components'; +import { modalOpen } from '../common/ComplexModal'; +import { doEdit } from './functions'; +import { Data } from './types'; + +export const GeneralRecordsViewGeneral = (props) => { + const { act, data } = useBackend(); + const { general } = data; + if (!general || !general.fields) { + return ( + + General record lost! + + + ); + } + return ( + <> + + + {general.fields.map((field, i) => ( + + + {field.value} + {!!field.edit && ( + + + + + {!!general.has_photos && + general.photos!.map((p, i) => ( + + +
+ Photo #{i + 1} +
+ ))} +
+ + ); +}; diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/functions.ts b/tgui/packages/tgui/interfaces/GeneralRecords/functions.ts new file mode 100644 index 00000000000..f546f955dc9 --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralRecords/functions.ts @@ -0,0 +1,32 @@ +import { filter } from 'common/collections'; +import { flow } from 'common/fp'; +import { createSearch } from 'common/string'; + +import { modalOpen } from '../common/ComplexModal'; +import { field, record } from './types'; + +export function doEdit(field: field) { + modalOpen('edit', { + field: field.edit, + value: field.value, + }); +} + +/** + * Record selector. + * + * Filters records, applies search terms and sorts the alphabetically. + */ +export function selectRecords(records: record[], searchText = ''): record[] { + const nameSearch = createSearch(searchText, (record: record) => record.name); + const idSearch = createSearch(searchText, (record: record) => record.id); + const dnaSearch = createSearch(searchText, (record: record) => record.b_dna); + const fl: record[] = flow([ + // Optional search term + searchText && + filter((record: record) => { + return nameSearch(record) || idSearch(record) || dnaSearch(record); + }), + ])(records); + return fl; +} diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/index.tsx b/tgui/packages/tgui/interfaces/GeneralRecords/index.tsx new file mode 100644 index 00000000000..e752cc59106 --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralRecords/index.tsx @@ -0,0 +1,47 @@ +import { useBackend } from '../../backend'; +import { Section } from '../../components'; +import { Window } from '../../layouts'; +import { ComplexModal } from '../common/ComplexModal'; +import { LoginInfo } from '../common/LoginInfo'; +import { LoginScreen } from '../common/LoginScreen'; +import { TemporaryNotice } from '../common/TemporaryNotice'; +import { GeneralRecordsList } from './GeneralRecordsList'; +import { + GeneralRecordsMaintenance, + GeneralRecordsNavigation, + GeneralRecordsView, +} from './GeneralRecordsOptions'; +import { Data } from './types'; + +export const GeneralRecords = (props) => { + const { data } = useBackend(); + const { authenticated, screen } = data; + if (!authenticated) { + return ( + + + + + + ); + } + + const body: React.JSX.Element[] = []; + body[2] = ; + body[3] = ; + body[4] = ; + + return ( + + + + + + +
+ {(screen && body[screen]) || ''} +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/types.ts b/tgui/packages/tgui/interfaces/GeneralRecords/types.ts new file mode 100644 index 00000000000..d2990bfdb6f --- /dev/null +++ b/tgui/packages/tgui/interfaces/GeneralRecords/types.ts @@ -0,0 +1,31 @@ +import { BooleanLike } from 'common/react'; + +export type Data = { + temp: { color: string; text: string } | null; + scan: string | null; + authenticated: BooleanLike; + rank: string | null; + screen: number | null; + printing: BooleanLike; + isAI: BooleanLike; + isRobot: BooleanLike; + records: record[] | undefined; + general: + | { + fields: field[] | undefined; + photos: string[] | undefined; + has_photos: BooleanLike; + skills: string[] | undefined; + comments: { header: string; text: string }[] | undefined; + empty: BooleanLike; + } + | undefined; +}; + +export type record = { ref: string; id: string; name: string; b_dna: string }; + +export type field = { + field: string; + value: string | number; + edit: string | null; +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords.jsx b/tgui/packages/tgui/interfaces/MedicalRecords.jsx deleted file mode 100644 index e7df9755313..00000000000 --- a/tgui/packages/tgui/interfaces/MedicalRecords.jsx +++ /dev/null @@ -1,427 +0,0 @@ -import { Fragment } from 'react'; - -import { useBackend } from '../backend'; -import { - Box, - Button, - Collapsible, - Icon, - Input, - LabeledList, - Section, - Tabs, -} from '../components'; -import { - ComplexModal, - modalOpen, - modalRegisterBodyOverride, -} from '../interfaces/common/ComplexModal'; -import { Window } from '../layouts'; -import { LoginInfo } from './common/LoginInfo'; -import { LoginScreen } from './common/LoginScreen'; -import { TemporaryNotice } from './common/TemporaryNotice'; - -const severities = { - Minor: 'good', - Medium: 'average', - 'Dangerous!': 'bad', - Harmful: 'bad', - 'BIOHAZARD THREAT!': 'bad', -}; - -const doEdit = (field) => { - modalOpen('edit', { - field: field.edit, - value: field.value, - }); -}; - -const virusModalBodyOverride = (modal) => { - const { act } = useBackend(); - const virus = modal.args; - return ( -
act('modal_close')} /> - } - > - - - - {virus.spread_text} Transmission - - - {virus.antigen} - - - {virus.rate} - - - {virus.resistance}% - - - {virus.species} - - - - {virus.symptoms.map((s) => ( - - - Strength: - {' '} - {s.strength}  - - Aggressiveness: - {' '} - {s.aggressiveness} - - ))} - - - - -
- ); -}; - -export const MedicalRecords = (_properties) => { - const { data } = useBackend(); - const { authenticated, screen } = data; - if (!authenticated) { - return ( - - - - - - ); - } - - let body; - if (screen === 2) { - // List Records - body = ; - } else if (screen === 3) { - // Record Maintenance - body = ; - } else if (screen === 4) { - // View Records - body = ; - } else if (screen === 5) { - // Virus Database - body = ; - } else if (screen === 6) { - // Medbot Tracking - body = ; - } - - return ( - - - - - - -
- {body} -
-
-
- ); -}; - -const MedicalRecordsList = (_properties) => { - const { act, data } = useBackend(); - const { records } = data; - return ( - <> - act('search', { t1: value })} - /> - - {records.map((record, i) => ( - - ))} - - - ); -}; - -const MedicalRecordsMaintenance = (_properties) => { - const { act } = useBackend(); - return ( - <> - -
- -
- act('del_all')}> - Delete All Medical Records - - - ); -}; - -const MedicalRecordsView = (_properties) => { - const { act, data } = useBackend(); - const { medical, printing } = data; - return ( - <> -
- -
-
- -
-
- act('del_r')} - > - Delete Medical Record - - -
- -
- - ); -}; - -const MedicalRecordsViewGeneral = (_properties) => { - const { data } = useBackend(); - const { general } = data; - if (!general || !general.fields) { - return General records lost!; - } - return ( - <> - - - {general.fields.map((field, i) => ( - - - {field.value} - - {!!field.edit && ( - - - ); - } - return ( - <> - - {medical.fields.map((field, i) => ( - - - {field.value} - - - - ); -}; - -const MedicalRecordsViruses = (_properties) => { - const { act, data } = useBackend(); - const { virus } = data; - virus.sort((a, b) => (a.name > b.name ? 1 : -1)); - return virus.map((vir, i) => ( - - -
-
- )); -}; - -const MedicalRecordsMedbots = (_properties) => { - const { data } = useBackend(); - const { medbots } = data; - if (medbots.length === 0) { - return There are no Medbots.; - } - return medbots.map((medbot, i) => ( - - - - - {medbot.area || 'Unknown'} ({medbot.x}, {medbot.y}) - - - {medbot.on ? ( - <> - Online - - {medbot.use_beaker - ? 'Reservoir: ' + - medbot.total_volume + - '/' + - medbot.maximum_volume - : 'Using internal synthesizer.'} - - - ) : ( - Offline - )} - - - - - )); -}; - -const MedicalRecordsNavigation = (_properties) => { - const { act, data } = useBackend(); - const { screen } = data; - return ( - - act('screen', { screen: 2 })} - > - - List Records - - act('screen', { screen: 5 })} - > - - Virus Database - - act('screen', { screen: 6 })} - > - - Medbot Tracking - - act('screen', { screen: 3 })} - > - - Record Maintenance - - - ); -}; - -modalRegisterBodyOverride('virus', virusModalBodyOverride); diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsList.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsList.tsx new file mode 100644 index 00000000000..ae0fc26729d --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsList.tsx @@ -0,0 +1,29 @@ +import { useBackend } from '../../backend'; +import { Box, Button, Input } from '../../components'; +import { Data } from './types'; + +export const MedicalRecordsList = (props) => { + const { act, data } = useBackend(); + const { records } = data; + return ( + <> + act('search', { t1: value })} + /> + + {records.map((record, i) => ( + + ))} + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsMedbots.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsMedbots.tsx new file mode 100644 index 00000000000..f0389b1c483 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsMedbots.tsx @@ -0,0 +1,39 @@ +import { useBackend } from '../../backend'; +import { Box, Collapsible, LabeledList } from '../../components'; +import { Data } from './types'; + +export const MedicalRecordsMedbots = (props) => { + const { data } = useBackend(); + const { medbots } = data; + if (!medbots || medbots.length === 0) { + return There are no Medbots.; + } + return medbots.map((medbot, i) => ( + + + + + {medbot.area || 'Unknown'} ({medbot.x}, {medbot.y}) + + + {medbot.on ? ( + <> + Online + + {medbot.use_beaker + ? 'Reservoir: ' + + medbot.total_volume + + '/' + + medbot.maximum_volume + : 'Using internal synthesizer.'} + + + ) : ( + Offline + )} + + + + + )); +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsOptions.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsOptions.tsx new file mode 100644 index 00000000000..037fa47dda5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsOptions.tsx @@ -0,0 +1,103 @@ +import { useBackend } from '../../backend'; +import { Button, Icon, Section, Tabs } from '../../components'; +import { MedicalRecordsViewGeneral } from './MedicalRecordsViewGeneral'; +import { MedicalRecordsViewMedical } from './MedicalRecordsViewMedical'; +import { Data } from './types'; + +export const MedicalRecordsMaintenance = (props) => { + const { act } = useBackend(); + return ( + <> + +
+ +
+ act('del_all')}> + Delete All Medical Records + + + ); +}; + +export const MedicalRecordsView = (props) => { + const { act, data } = useBackend(); + const { medical, printing } = data; + return ( + <> +
+ +
+
+ +
+
+ act('del_r')} + > + Delete Medical Record + + +
+ +
+ + ); +}; + +export const MedicalRecordsNavigation = (props) => { + const { act, data } = useBackend(); + const { screen } = data; + return ( + + act('screen', { screen: 2 })} + > + + List Records + + act('screen', { screen: 5 })} + > + + Virus Database + + act('screen', { screen: 6 })} + > + + Medbot Tracking + + act('screen', { screen: 3 })} + > + + Record Maintenance + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsViewGeneral.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsViewGeneral.tsx new file mode 100644 index 00000000000..01ca768df89 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsViewGeneral.tsx @@ -0,0 +1,61 @@ +import { useBackend } from '../../backend'; +import { Box, Button, Image, LabeledList } from '../../components'; +import { doEdit } from '../GeneralRecords/functions'; +import { Data } from './types'; + +export const MedicalRecordsViewGeneral = (props) => { + const { data } = useBackend(); + const { general } = data; + if (!general || !general.fields) { + return General records lost!; + } + return ( + <> + + + {general.fields.map((field, i) => ( + + + {field.value} + {!!field.edit && ( + + + ); + } + return ( + <> + + {medical.fields.map((field, i) => ( + + + {field.value} + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsViruses.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsViruses.tsx new file mode 100644 index 00000000000..eb7ea731b9d --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsViruses.tsx @@ -0,0 +1,26 @@ +import { Fragment } from 'react'; + +import { useBackend } from '../../backend'; +import { Button } from '../../components'; +import { Data } from './types'; + +export const MedicalRecordsViruses = (props) => { + const { act, data } = useBackend(); + const { virus } = data; + virus && virus.sort((a, b) => (a.name > b.name ? 1 : -1)); + return ( + virus && + virus.map((vir, i) => ( + + +
+
+ )) + ); +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/constants.ts b/tgui/packages/tgui/interfaces/MedicalRecords/constants.ts new file mode 100644 index 00000000000..08b21c0b9f5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/constants.ts @@ -0,0 +1,7 @@ +export const severities = { + Minor: 'good', + Medium: 'average', + 'Dangerous!': 'bad', + Harmful: 'bad', + 'BIOHAZARD THREAT!': 'bad', +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/index.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/index.tsx new file mode 100644 index 00000000000..61fd434ab91 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/index.tsx @@ -0,0 +1,62 @@ +import { useBackend } from '../../backend'; +import { Section } from '../../components'; +import { + ComplexModal, + modalRegisterBodyOverride, +} from '../../interfaces/common/ComplexModal'; +import { Window } from '../../layouts'; +import { LoginInfo } from '../common/LoginInfo'; +import { LoginScreen } from '../common/LoginScreen'; +import { TemporaryNotice } from '../common/TemporaryNotice'; +import { MedicalRecordsList } from './MedicalRecordsList'; +import { MedicalRecordsMedbots } from './MedicalRecordsMedbots'; +import { + MedicalRecordsMaintenance, + MedicalRecordsNavigation, + MedicalRecordsView, +} from './MedicalRecordsOptions'; +import { MedicalRecordsViruses } from './MedicalRecordsViruses'; +import { Data } from './types'; +import { virusModalBodyOverride } from './virusModalBodyOverride'; + +export const MedicalRecords = (props) => { + const { data } = useBackend(); + const { authenticated, screen } = data; + if (!authenticated) { + return ( + + + + + + ); + } + + const body: React.JSX.Element[] = []; + // List Records + body[2] = ; + // Record Maintenance + body[3] = ; + // View Records + body[4] = ; + // Virus Database + body[5] = ; + // Medbot Tracking + body[6] = ; + + return ( + + + + + + +
+ {(screen && body[screen]) || ''} +
+
+
+ ); +}; + +modalRegisterBodyOverride('virus', virusModalBodyOverride); diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/types.ts b/tgui/packages/tgui/interfaces/MedicalRecords/types.ts new file mode 100644 index 00000000000..2f8e1e0a61c --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/types.ts @@ -0,0 +1,73 @@ +import { BooleanLike } from 'common/react'; + +import { field } from '../GeneralRecords/types'; + +export type Data = { + temp: { color: string; text: string } | null; + scan: string | null; + authenticated: BooleanLike; + rank: string | null; + screen: number | null; + printing: BooleanLike; + isAI: BooleanLike; + isRobot: BooleanLike; + records: record[]; + general: + | { + fields: field[] | undefined; + photos: string[] | undefined; + has_photos: BooleanLike; + empty: BooleanLike; + } + | undefined; + medical: + | { + fields: field[] | undefined; + comments: { header: string; text: string }[] | undefined; + empty: BooleanLike; + } + | undefined; + virus: { name: string; D: string }[] | undefined; + medbots: + | { + name: string; + area: string; + x: number; + y: number; + z: number; + on: BooleanLike; + use_beaker: BooleanLike; + total_volume: number | undefined; + maximum_volume: number | undefined; + }[] + | undefined; + modal: modalData; +}; + +export type modalData = { + id: string; + text: string; + args: { + name: string; + spreadtype: string; + antigen: string; + rate: number; + resistance: number; + species: string; + ref: string; + symptoms: { + stage: number; + name: string; + strength: string; + aggressiveness: string; + }[]; + record: string; + }; + modal_type: string; +}; + +type record = { + ref: string; + id: string; + name: string; +}; diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/virusModalBodyOverride.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/virusModalBodyOverride.tsx new file mode 100644 index 00000000000..06f0af5a868 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/virusModalBodyOverride.tsx @@ -0,0 +1,53 @@ +import { useBackend } from '../../backend'; +import { Box, Button, LabeledList, Section } from '../../components'; +import { modalData } from './types'; + +export const virusModalBodyOverride = (modal: modalData) => { + const { act } = useBackend(); + const virus = modal.args; + return ( +
act('modal_close')} /> + } + > + + + + {virus.spreadtype} Transmission + + + {virus.antigen} + + + {virus.rate} + + + {virus.resistance}% + + + {virus.species} + + + + {virus.symptoms.map((s) => ( + + + Strength: + {' '} + {s.strength}  + + Aggressiveness: + {' '} + {s.aggressiveness} + + ))} + + + + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/MessageMonitor/types.ts b/tgui/packages/tgui/interfaces/MessageMonitor/types.ts index 9ec9d76c239..c38fb0b2ee8 100644 --- a/tgui/packages/tgui/interfaces/MessageMonitor/types.ts +++ b/tgui/packages/tgui/interfaces/MessageMonitor/types.ts @@ -5,7 +5,7 @@ export type Data = { customrecepient: string; customjob: string; custommessage: string; - temp: string | null; + temp: { color: string; text: string } | null; hacking: BooleanLike; emag: BooleanLike; auth: BooleanLike; diff --git a/tgui/packages/tgui/interfaces/NIF.jsx b/tgui/packages/tgui/interfaces/NIF.jsx deleted file mode 100644 index f3e8d77b335..00000000000 --- a/tgui/packages/tgui/interfaces/NIF.jsx +++ /dev/null @@ -1,289 +0,0 @@ -import { useState } from 'react'; - -import { useBackend } from '../backend'; -import { - AnimatedNumber, - Box, - Button, - Dropdown, - Flex, - LabeledList, - Modal, - NoticeBox, - ProgressBar, - Section, - Table, -} from '../components'; -import { Window } from '../layouts'; - -const NIF_WORKING = 0; -const NIF_POWFAIL = 1; -const NIF_TEMPFAIL = 2; -const NIF_INSTALLING = 3; -const NIF_PREINSTALL = 4; - -export const NIF = (props) => { - const { act, config, data } = useBackend(); - - const { theme, last_notification } = data; - - const [settingsOpen, setSettingsOpen] = useState(false); - const [viewingModule, setViewing] = useState(null); - - return ( - - - {!!last_notification && ( - - - - - {last_notification} - - -
-
- )} - {!!viewingModule && ( - -
- { - act('uninstall', { module: viewingModule.ref }); - setViewing(null); - }} - > - Uninstall - -
-
- )} -
setSettingsOpen(!settingsOpen)} - /> - } - > - {(settingsOpen && ) || ( - - )} -
-
-
- ); -}; - -const getNifCondition = (nif_stat, nif_percent) => { - switch (nif_stat) { - case NIF_WORKING: - if (nif_percent < 25) { - return 'Service Needed Soon'; - } else { - return 'Operating Normally'; - } - case NIF_POWFAIL: - return 'Insufficient Energy!'; - case NIF_TEMPFAIL: - return 'System Failure!'; - case NIF_INSTALLING: - return 'Adapting To User'; - } - return 'Unknown'; -}; - -const getNutritionText = (nutrition, isSynthetic) => { - if (isSynthetic) { - if (nutrition >= 450) { - return 'Overcharged'; - } else if (nutrition >= 250) { - return 'Good Charge'; - } - return 'Low Charge'; - } - - if (nutrition >= 250) { - return 'NIF Power Requirement met.'; - } else if (nutrition >= 150) { - return 'Fluctuations in available power.'; - } - return 'Power failure imminent.'; -}; - -const NIFMain = (props) => { - const { act, config, data } = useBackend(); - - const { nif_percent, nif_stat, nutrition, isSynthetic, modules } = data; - - const { setViewing } = props; - - return ( - - - - - {getNifCondition(nif_stat, nif_percent)} ( - - %) - - - - - {getNutritionText(nutrition, isSynthetic)} - - - -
- - {modules.map((module) => ( - - act('uninstall', { module: module.ref })} - /> -
-
- ); -}; - -const NIFSettings = (props) => { - const { act, data } = useBackend(); - - const { valid_themes, theme } = data; - - return ( - - - - - act('setTheme', { theme: val })} - /> - - {theme ? ( - -