Improve cryo tubes (#17919)

* Improve cryo tubes

* JS --> TSX

* Fix lack of type

* Cryo tube improvements

* Update code/game/machinery/cryo.dm

Co-authored-by: Fluffy <65877598+FluffyGhoster@users.noreply.github.com>

---------

Co-authored-by: Cody Brittain <cbrittain10@live.com>
Co-authored-by: Fluffy <65877598+FluffyGhoster@users.noreply.github.com>
This commit is contained in:
Cody Brittain
2023-12-22 15:03:41 -05:00
committed by GitHub
parent f81de5387e
commit 40e5d511d5
7 changed files with 505 additions and 111 deletions
+158 -102
View File
@@ -22,7 +22,7 @@
icon_state = "pod_preview"
density = TRUE
anchored = TRUE
layer = 2.8
layer = ABOVE_ALL_MOB_LAYER
interact_offline = TRUE
var/on = 0
@@ -37,17 +37,28 @@
var/current_heat_capacity = 50
/obj/machinery/atmospherics/unary/cryo_cell/New()
..()
var/temperature_warning_threshold = 170
var/temperature_danger_threshold = T0C
var/fast_stasis_mult = 0.8
var/slow_stasis_mult = 1.25
var/current_stasis_mult = 1
var/global/list/screen_overlays
/obj/machinery/atmospherics/unary/cryo_cell/Initialize()
. = ..()
icon = 'icons/obj/cryogenics_split.dmi'
generate_overlays()
update_icon()
initialize_directions = dir
atmos_init()
/obj/machinery/atmospherics/unary/cryo_cell/Destroy()
var/turf/T = loc
var/turf/T = src.loc
T.contents += contents
if(beaker)
beaker.forceMove(get_step(loc, SOUTH)) //Beaker is carefully ejected from the wreckage of the cryotube
beaker = null
return ..()
/obj/machinery/atmospherics/unary/cryo_cell/atmos_init()
@@ -58,10 +69,32 @@
node = target
break
/obj/machinery/atmospherics/unary/cryo_cell/examine(mob/user, distance, is_adjacent)
. = ..()
if(is_adjacent)
if(beaker)
to_chat(user, SPAN_NOTICE("It is loaded with a beaker."))
if(occupant)
occupant.examine(arglist(args))
/obj/machinery/atmospherics/unary/cryo_cell/proc/generate_overlays(force = FALSE)
if(LAZYLEN(screen_overlays) && !force)
return
LAZYINITLIST(screen_overlays)
screen_overlays["cryo-off"] = make_screen_overlay(icon, "lights_off")
screen_overlays["cryo-off-top"] = make_screen_overlay(icon, "lights_off_top")
screen_overlays["cryo-safe"] = make_screen_overlay(icon, "lights_safe")
screen_overlays["cryo-safe-top"] = make_screen_overlay(icon, "lights_safe_top")
screen_overlays["cryo-warn"] = make_screen_overlay(icon, "lights_warn")
screen_overlays["cryo-warn-top"] = make_screen_overlay(icon, "lights_warn_top")
screen_overlays["cryo-danger"] = make_screen_overlay(icon, "lights_danger")
screen_overlays["cryo-danger-top"] = make_screen_overlay(icon, "lights_danger_top")
/obj/machinery/atmospherics/unary/cryo_cell/process()
..()
if(!node)
return
if(!on)
return
@@ -76,66 +109,73 @@
if(abs(temperature_archived-air_contents.temperature) > 1)
network.update = 1
update_icon()
return 1
/obj/machinery/atmospherics/unary/cryo_cell/relaymove(mob/user as mob)
if(user != occupant) //Put this in because apparently if you open the ui and press a button, you're counted as user and can trigger relaymove, this checks if you're inside, and if you aren't it ignores you for the purposes of the relaymove. - Risingvaliant
return
if(user.stat)
return
go_out()
return
if(src.occupant == user && !user.stat)
go_out()
/obj/machinery/atmospherics/unary/cryo_cell/attack_hand(mob/user)
ui_interact(user)
/**
* The ui_interact proc is used to open and update Nano UIs
* If ui_interact is not used then the UI will not update correctly
* ui_interact is currently defined for /atom/movable (which is inherited by /obj and /mob)
*
* @param user /mob The mob who is interacting with this ui
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
*
* @return nothing
*/
/obj/machinery/atmospherics/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
/obj/machinery/atmospherics/unary/cryo_cell/ui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "CryoTube", "Cryo Cell")
ui.open()
if(user == occupant || user.stat)
return
// this is the data which will be sent to the ui
/obj/machinery/atmospherics/unary/cryo_cell/ui_data(mob/user)
var/list/data = list()
data["isOperating"] = on
data["hasOccupant"] = occupant ? 1 : 0
data["hasOccupant"] = occupant ? TRUE : FALSE
var/list/occupantData = list()
if (occupant)
if(occupant)
occupantData["name"] = occupant.name
occupantData["stat"] = occupant.stat
occupantData["bodyTemperature"] = occupant.bodytemperature
occupantData["brain_activity"] = occupant.get_brain_status()
occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL)
occupantData["blood_o2"] = occupant.get_blood_oxygenation()
occupantData["blood_pressure"] = occupant.get_blood_pressure()
occupantData["cloneLoss"] = occupant.getCloneLoss()
var/displayed_stat = occupant.stat
var/blood_oxygenation = occupant.get_blood_oxygenation()
if(HAS_FLAG(occupant.status_flags, FAKEDEATH))
displayed_stat = DEAD
blood_oxygenation = min(blood_oxygenation, BLOOD_VOLUME_SURVIVE)
var/pulse_result
if(occupant.should_have_organ(BP_HEART))
var/obj/item/organ/internal/heart/heart = occupant.internal_organs_by_name[BP_HEART]
if(!heart)
pulse_result = 0
else if(BP_IS_ROBOTIC(heart))
pulse_result = -2
else if(occupant.status_flags & FAKEDEATH)
pulse_result = 0
else
pulse_result = occupant.get_pulse(GETPULSE_TOOL)
else
pulse_result = -1
if(pulse_result == ">250")
pulse_result = -3
occupantData["stat"] = displayed_stat
occupantData["bruteLoss"] = occupant.getBruteLoss()
occupantData["fireLoss"] = occupant.getFireLoss()
occupantData["toxLoss"] = occupant.getToxLoss()
occupantData["oxyLoss"] = occupant.getOxyLoss()
occupantData["cryostasis"] = "[occupant.stasis_value]"
data["occupant"] = occupantData
occupantData["cloneLoss"] = occupant.getCloneLoss()
occupantData["bodyTemperature"] = occupant.bodytemperature
occupantData["brainActivity"] = occupant.get_brain_result()
occupantData["pulse"] = text2num(pulse_result)
occupantData["cryostasis"] = occupant.stasis_value
occupantData["bloodPressure"] = occupant.get_blood_pressure()
occupantData["bloodPressureLevel"] = occupant.get_blood_pressure_alert()
occupantData["bloodOxygenation"] = blood_oxygenation
data["occupant"] = occupantData;
data["cellTemperature"] = round(air_contents.temperature)
data["cellTemperatureStatus"] = "good"
if(air_contents.temperature > T0C) // if greater than 273.15 kelvin (0 celcius)
if(air_contents.temperature >= temperature_danger_threshold)
data["cellTemperatureStatus"] = "bad"
else if(air_contents.temperature > 225)
else if(air_contents.temperature >= temperature_warning_threshold)
data["cellTemperatureStatus"] = "average"
data["isBeakerLoaded"] = beaker ? 1 : 0
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
data["beakerLabel"] = null
data["beakerVolume"] = 0
if(beaker)
@@ -143,46 +183,62 @@
for(var/_R in beaker.reagents.reagent_volumes)
data["beakerVolume"] += REAGENT_VOLUME(beaker.reagents, _R)
// update the ui if it exists, returns null if no ui is passed/found
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 410)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
data["fastStasisMult"] = fast_stasis_mult
data["slowStasisMult"] = slow_stasis_mult
data["currentStasisMult"] = current_stasis_mult
return data
/obj/machinery/atmospherics/unary/cryo_cell/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
/obj/machinery/atmospherics/unary/cryo_cell/Topic(href, href_list)
if(usr == occupant)
return 0 // don't update UIs attached to this object
return
if(..())
return 0 // don't update UIs attached to this object
. = TRUE
if(href_list["switchOn"])
on = 1
update_icon()
switch(action)
if("switchOn")
on = TRUE
update_icon()
if(href_list["switchOff"])
on = 0
update_icon()
if("switchOff")
on = FALSE
update_icon()
if(href_list["ejectBeaker"])
if(beaker)
beaker.forceMove(get_step(loc, SOUTH))
beaker = null
if("ejectBeaker")
if(beaker)
beaker.forceMove(get_step(loc, SOUTH))
beaker = null
if(href_list["ejectOccupant"])
if(!occupant || isslime(usr) || ispAI(usr))
return 0 // don't update UIs attached to this object
go_out()
if("ejectOccupant")
if(!occupant || isslime(usr) || ispAI(usr))
return
go_out()
if("goFast")
current_stasis_mult = fast_stasis_mult
update_icon()
if("goRegular")
current_stasis_mult = 1
update_icon()
if("goSlow")
current_stasis_mult = slow_stasis_mult
update_icon()
else
return FALSE
add_fingerprint(usr)
return 1 // update UIs attached to this object
/obj/machinery/atmospherics/unary/cryo_cell/attackby(var/obj/item/G as obj, var/mob/user as mob)
if(istype(G, /obj/item/reagent_containers/glass))
if(beaker)
to_chat(user, "<span class='warning'>A beaker is already loaded into the machine.</span>")
FEEDBACK_FAILURE(user, "A beaker is already loaded into the machine!")
return TRUE
beaker = G
@@ -243,51 +299,51 @@
/obj/machinery/atmospherics/unary/cryo_cell/update_icon()
cut_overlays()
var/list/ovr = list()
icon_state = "pod[on]"
var/image/I
if(panel_open)
add_overlay("pod_panel")
I = image(icon, "pod[on]_top")
I.layer = 5 // this needs to be fairly high so it displays over most things, but it needs to be under lighting (at 10)
I.pixel_z = 32
ovr += I
add_overlay(I)
if(occupant)
var/image/pickle = image(occupant.icon, occupant.icon_state)
pickle.overlays = occupant.overlays
pickle.pixel_z = 18
pickle.layer = 5
ovr += pickle
pickle.pixel_z = 11
add_overlay(pickle)
I = image(icon, "lid[on]")
I.layer = 5
ovr += I
add_overlay(I)
I = image(icon, "lid[on]_top")
I.layer = 5
I.pixel_z = 32
ovr += I
add_overlay(I)
add_overlay(ovr)
if(powered())
var/warn_state = "off"
if(on)
warn_state = "safe"
if(air_contents.temperature >= temperature_danger_threshold)
warn_state = "danger"
else if(air_contents.temperature >= temperature_warning_threshold)
warn_state = "warn"
add_overlay(screen_overlays["cryo-[warn_state]"])
I = screen_overlays["cryo-[warn_state]-top"]
I.pixel_z = 32
add_overlay(I)
/obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant()
if(air_contents.total_moles < 10)
return
if(occupant)
if(occupant.stat == 2)
if(occupant.stat == DEAD)
return
occupant.bodytemperature += 2*(air_contents.temperature - occupant.bodytemperature)*current_heat_capacity/(current_heat_capacity + air_contents.heat_capacity())
occupant.bodytemperature = max(occupant.bodytemperature, air_contents.temperature) // this is so ugly i'm sorry for doing it i'll fix it later i promise
occupant.set_stat(UNCONSCIOUS)
if(occupant.bodytemperature < T0C)
//severe damage should heal waaay slower without proper chemicals
if(occupant.bodytemperature < 225)
if(!occupant.is_diona())
var/heal_brute = occupant.getBruteLoss() ? min(1, 20/occupant.getBruteLoss()) : 0
var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0
occupant.heal_organ_damage(heal_brute,heal_fire)
else
occupant.adjustFireLoss(3)//Cryopods kill diona. This damage combines with the normal cold temp damage, and their disabled regen
var/has_cryo = REAGENT_VOLUME(occupant.reagents, /singleton/reagent/cryoxadone) >= 1
var/has_clonexa = REAGENT_VOLUME(occupant.reagents, /singleton/reagent/clonexadone) >= 1
var/has_cryo_medicine = has_cryo || has_clonexa
@@ -306,19 +362,10 @@
/obj/machinery/atmospherics/unary/cryo_cell/proc/expel_gas()
if(air_contents.total_moles < 1)
return
// var/datum/gas_mixture/expel_gas = new
// var/remove_amount = air_contents.total_moles()/50
// expel_gas = air_contents.remove(remove_amount)
// Just have the gas disappear to nowhere.
//expel_gas.temperature = T20C // Lets expel hot gas and see if that helps people not die as they are removed
//loc.assume_air(expel_gas)
/obj/machinery/atmospherics/unary/cryo_cell/proc/go_out()
if(!( occupant ))
if(!(occupant))
return
//for(var/obj/O in src)
// O.forceMove(loc)
if (occupant.client)
occupant.client.eye = occupant.client.mob
occupant.client.perspective = MOB_PERSPECTIVE
@@ -404,6 +451,15 @@
if(loc)
return loc.return_air()
/obj/machinery/atmospherics/unary/cryo_cell/RefreshParts()
..()
var/man_rating = 0
for(var/obj/item/stock_parts/P in component_parts)
if(ismanipulator(P))
man_rating += P.rating
fast_stasis_mult = max(1 - (man_rating * 0.06), 0.66)
slow_stasis_mult = min(1 + (man_rating * 0.06), 1.5)
/datum/data/function/proc/reset()
return
@@ -261,6 +261,11 @@
else
. = 80 * (1 - bodytemperature / species.cold_level_3)
. = max(20, .)
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/obj/machinery/atmospherics/unary/cryo_cell/cryo = loc
if(cryo.current_stasis_mult)
var/gcf_stasis_mult = cryo.current_stasis_mult
. = . * gcf_stasis_mult
return round(.)
// Martial Art Helpers
@@ -223,12 +223,18 @@
/singleton/reagent/cryoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
M.add_chemical_effect(CE_CRYO, 1)
if(M.bodytemperature < 170)
if(M.bodytemperature < 170 && !M.is_diona())
M.add_chemical_effect(CE_PULSE, -2)
M.add_chemical_effect(CE_OXYGENATED, 1)
M.adjustCloneLoss(-100 * removed)
M.adjustOxyLoss(-10 * removed)
M.heal_organ_damage(10 * removed, 10 * removed)
M.adjustToxLoss(-10 * removed)
M.heal_organ_damage(30 * removed, 30 * removed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
for(var/obj/item/organ/internal/I in H.internal_organs)
if(!BP_IS_ROBOTIC(I))
I.heal_damage(20*removed)
else if(M.is_diona() && M.bodytemperature < 170)
M.adjustFireLoss(5 * removed)//Cryopods kill diona. This damage combines with the normal cold temp damage, and their disabled regen
/singleton/reagent/clonexadone
name = "Clonexadone"
@@ -241,12 +247,18 @@
/singleton/reagent/clonexadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
M.add_chemical_effect(CE_CRYO, 1)
if(M.bodytemperature < 170)
if(M.bodytemperature < 170 && !M.is_diona())
M.add_chemical_effect(CE_PULSE, -2)
M.adjustCloneLoss(-100 * removed)
M.adjustOxyLoss(-30 * removed)
M.heal_organ_damage(30 * removed, 30 * removed)
M.adjustToxLoss(-30 * removed)
M.add_chemical_effect(CE_OXYGENATED, 2)
M.adjustCloneLoss(-300 * removed)
M.heal_organ_damage(50 * removed, 50 * removed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
for(var/obj/item/organ/internal/I in H.internal_organs)
if(!BP_IS_ROBOTIC(I))
I.heal_damage(30*removed)
else if(M.is_diona() && M.bodytemperature < 170)
M.adjustFireLoss(15 * removed)//Cryopods kill diona. This damage combines with the normal cold temp damage, and their disabled regen
/* Painkillers */
@@ -0,0 +1,50 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
# balance
# admin
# backend
# security
# refactor
#################################
# Your name.
author: GeneralCamo
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- tweak: "Ported the cryo tubes to use tgui."
- tweak: "Replaced the cryo tube sprites. Credit to Remission, cuddleandtea, and SierraKomodo of baystation12."
- rscdel: "Cryo tubes no longer heal without chemicals; putting someone inside without cryo chems will kill them."
- balance: "Buffed cryoxadone to heal 30 brute damage per metabolism tick from 10."
- balance: "Buffed clonexadone to heal 50 brute damage per metabolism tick from 30."
- balance: "Buffed clonexadone to heal 300 clone damage per metabolism tick from 100."
- rscadd: "Cryoxadone and clonexadone now heal internal organ damage."
- rscdel: "Cryoxadone and clonexadone no longer heal toxin or oxygen damage; both now provide an oxygenation effect in place of healing oxygen damage."
- rscdel: "Cryo tubes no longer show toxin, oxygen, or burn damage, as it cannot heal these types of damage."
- rscadd: "Added metabolism-boosted and stasis-boosted modes on the cryo tubes. Both will trade off stasis level or metabolism respectively, in favor of the alternative stat."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

+271
View File
@@ -0,0 +1,271 @@
import { Fragment } from 'inferno';
import { Window } from '../layouts';
import { useBackend } from '../backend';
import { AnimatedNumber, Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from '../components';
import { BooleanLike } from 'common/react';
export type CryoData = {
isOperating: BooleanLike;
hasOccupant: BooleanLike;
cellTemperature: number;
cellTemperatureStatus: string;
occupant: Occupant;
isBeakerLoaded: BooleanLike;
currentStasisMult: number;
fastStasisMult: number;
slowStasisMult: number;
};
export type BeakerData = {
isBeakerLoaded: BooleanLike;
beakerLabel: string;
beakerVolume: number;
};
type Occupant = {
name: string;
stat: number;
bruteLoss: string;
cloneLoss: string;
bodyTemperature: number;
brainActivity: number;
pulse: number;
cryostasis: number;
bloodPressure: number;
bloodPressureLevel: number;
bloodOxygenation: number;
};
const damageTypes = [
{
label: 'Physical Damage',
type: 'bruteLoss',
},
{
label: 'Genetic Damage',
type: 'cloneLoss',
},
];
const statNames = [
['good', 'Conscious'],
['average', 'Unconscious'],
['bad', 'DEAD'],
];
const progressClass = (value) => {
if (value <= 50) {
return 'bad';
} else if (value <= 90) {
return 'average';
} else {
return 'green';
}
};
export const CryoTube = (props, context) => {
const { act, data } = useBackend<CryoData>(context);
return (
<Window resizable theme="zenghu">
<Window.Content className="Layout__content--flexColumn">
<CryoContent />
</Window.Content>
</Window>
);
};
export const CryoContent = (props, context) => {
const { act, data } = useBackend<CryoData>(context);
return (
<Fragment>
<Section
title="Occupant"
flexGrow="1"
buttons={
<Button
icon="user-slash"
onClick={() => act('ejectOccupant')}
disabled={!data.hasOccupant}>
Eject
</Button>
}>
{data.hasOccupant ? (
<LabeledList>
<LabeledList.Item label="Occupant">
{data.occupant.name || 'Unknown'}
</LabeledList.Item>
<LabeledList.Item
label="Status"
color={statNames[data.occupant.stat][0]}>
{statNames[data.occupant.stat][1]}
</LabeledList.Item>
<LabeledList.Divider />
<LabeledList.Item
label="Brain Activity"
color={progressClass(data.occupant.brainActivity)}>
{brainText(data.occupant.brainActivity)}
</LabeledList.Item>
<LabeledList.Item
label="Pulse Rate"
color={progressClass(data.occupant.brainActivity)}>
{data.occupant.pulse} BPM
</LabeledList.Item>
<LabeledList.Item
label="Blood Pressure"
color={getPressureClass(data.occupant.bloodPressureLevel)}>
{data.occupant.bloodPressure}
</LabeledList.Item>
<LabeledList.Item label="Blood Oxygenation">
<ProgressBar
value={data.occupant.bloodOxygenation}
ranges={{
bad: [0.01, 50],
average: [50.01, 90],
good: [90.01, Infinity],
}}>
<AnimatedNumber
value={Math.round(data.occupant.bloodOxygenation)}
/>
{'%'}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Temperature">
<AnimatedNumber
value={Math.round(data.occupant.bodyTemperature)}
/>
{' K'}
</LabeledList.Item>
<LabeledList.Item label="Cryostasis Multiplier">
<AnimatedNumber value={Math.round(data.occupant.cryostasis)} />
{'x'}
</LabeledList.Item>
<LabeledList.Divider />
{damageTypes.map((damageType) => (
<LabeledList.Item key={damageType.label} label={damageType.label}>
<ProgressBar
value={data.occupant[damageType.type] / 100}
ranges={{ bad: [0.01, Infinity] }}>
<AnimatedNumber
value={Math.round(data.occupant[damageType.type])}
/>
</ProgressBar>
</LabeledList.Item>
))}
</LabeledList>
) : (
<Flex height="100%" textAlign="center">
<Flex.Item grow="1" align="center" color="label">
<Icon name="user-slash" mb="0.5rem" size="5" />
<br />
No occupant detected.
</Flex.Item>
</Flex>
)}
</Section>
<Section
title="Cell"
buttons={
<Button
icon="eject"
onClick={() => act('ejectBeaker')}
disabled={!data.isBeakerLoaded}>
Eject Beaker
</Button>
}>
<LabeledList>
<LabeledList.Item label="Power">
<Button
icon="power-off"
onClick={() => act(data.isOperating ? 'switchOff' : 'switchOn')}
selected={data.isOperating}>
{data.isOperating ? 'On' : 'Off'}
</Button>
</LabeledList.Item>
<LabeledList.Item
label="Temperature"
color={data.cellTemperatureStatus}>
<AnimatedNumber value={data.cellTemperature} /> K
</LabeledList.Item>
<LabeledList.Item label="Beaker">
<CryoBeaker />
</LabeledList.Item>
</LabeledList>
<LabeledList>
<LabeledList.Item label="Cryostasis Mode">
<Button
icon="play"
onClick={() => act('goSlow')}
selected={data.currentStasisMult === data.slowStasisMult}>
Prioritize Stasis
</Button>
<Button
icon="forward"
onClick={() => act('goRegular')}
selected={data.currentStasisMult === 1}>
Balanced
</Button>
<Button
icon="forward-fast"
onClick={() => act('goFast')}
selected={data.currentStasisMult === data.fastStasisMult}>
Prioritize Metabolism
</Button>
</LabeledList.Item>
</LabeledList>
</Section>
</Fragment>
);
};
const CryoBeaker = (props, context) => {
const { act, data } = useBackend<BeakerData>(context);
if (data.isBeakerLoaded) {
return (
<Fragment>
{data.beakerLabel ? (
data.beakerLabel
) : (
<Box color="average">No label</Box>
)}
<Box color={!data.beakerVolume && 'bad'}>
{data.beakerVolume ? (
<AnimatedNumber
value={data.beakerVolume}
format={(v) => Math.round(v) + ' units remaining'}
/>
) : (
'Beaker is empty'
)}
</Box>
</Fragment>
);
} else {
return <Box color="average">No beaker loaded</Box>;
}
};
const brainText = (value) => {
switch (value) {
case 0:
return 'None, patient is braindead';
case -1:
return 'ERROR - Non-Standard Biology';
default:
return value.toString().concat('%');
}
};
const getPressureClass = (tpressure) => {
switch (tpressure) {
case 1:
return 'red';
case 2:
return 'green';
case 3:
return 'good';
case 4:
return 'red';
default:
return 'teal';
}
};