TGUI Medical: Sleeper

This commit is contained in:
mochi
2020-07-11 18:52:38 +02:00
parent 3f7d088c99
commit dfa8cd07b6
4 changed files with 370 additions and 256 deletions
+52 -42
View File
@@ -135,17 +135,18 @@
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
return
ui_interact(user)
tgui_interact(user)
/obj/machinery/sleeper/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/sleeper/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "sleeper.tmpl", "Sleeper", 550, 770)
ui = new(user, src, ui_key, "Sleeper", "Sleeper", 550, 770)
ui.open()
ui.set_auto_update(1)
ui.set_autoupdate(TRUE)
/obj/machinery/sleeper/ui_data(mob/user, datum/topic_state/state)
/obj/machinery/sleeper/tgui_data(mob/user)
var/data[0]
data["amounts"] = amounts
data["hasOccupant"] = occupant ? 1 : 0
var/occupantData[0]
var/crisis = 0
@@ -210,9 +211,13 @@
if(beaker)
data["isBeakerLoaded"] = 1
if(beaker.reagents)
data["beakerMaxSpace"] = beaker.reagents.maximum_volume
data["beakerFreeSpace"] = round(beaker.reagents.maximum_volume - beaker.reagents.total_volume)
else
data["beakerMaxSpace"] = 0
data["beakerFreeSpace"] = 0
else
data["isBeakerLoaded"] = FALSE
var/chemicals[0]
for(var/re in possible_chems)
@@ -234,51 +239,50 @@
if(temp.id in occupant.reagents.overdose_list())
overdosing = 1
// Because I don't know how to do this on the nano side
pretty_amount = round(reagent_amount, 0.05)
chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("chemical" = temp.id), "occ_amount" = reagent_amount, "pretty_amount" = pretty_amount, "injectable" = injectable, "overdosing" = overdosing, "od_warning" = caution)))
data["chemicals"] = chemicals
return data
/obj/machinery/sleeper/Topic(href, href_list)
if(!controls_inside && usr == occupant)
return 0
/obj/machinery/sleeper/tgui_act(action, params)
if(..())
return 1
return
if(!controls_inside && usr == occupant)
return
if(panel_open)
to_chat(usr, "<span class='notice'>Close the maintenance panel first.</span>")
return 0
return
if((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
if(href_list["chemical"])
if(occupant)
if(occupant.stat == DEAD)
to_chat(usr, "<span class='danger'>This person has no life for to preserve anymore. Take [occupant.p_them()] to a department capable of reanimating them.</span>")
else if(occupant.health > min_health || (href_list["chemical"] in emergency_chems))
inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"]))
else
to_chat(usr, "<span class='danger'>This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!</span>")
if(href_list["removebeaker"])
. = TRUE
switch(action)
if("chemical")
if(!occupant)
return
if(occupant.stat == DEAD)
to_chat(usr, "<span class='danger'>This person has no life to preserve anymore. Take [occupant.p_them()] to a department capable of reanimating them.</span>")
return
var/chemical = params["chemid"]
var/amount = text2num(params["amount"])
if(!length(chemical) || amount <= 0)
return
if(occupant.health > min_health || (chemical in emergency_chems))
inject_chemical(usr, chemical, amount)
else
to_chat(usr, "<span class='danger'>This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!</span>")
if("removebeaker")
remove_beaker()
if(href_list["togglefilter"])
if("togglefilter")
toggle_filter()
if(href_list["ejectify"])
if("ejectify")
eject()
if(href_list["auto_eject_dead_on"])
if("auto_eject_dead_on")
auto_eject_dead = TRUE
if(href_list["auto_eject_dead_off"])
if("auto_eject_dead_off")
auto_eject_dead = FALSE
add_fingerprint(usr)
return 1
else
return FALSE
add_fingerprint(usr)
/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers/glass))
@@ -290,6 +294,7 @@
beaker = I
I.forceMove(src)
user.visible_message("[user] adds \a [I] to [src]!", "You add \a [I] to [src]!")
SStgui.update_uis(src)
return
else
@@ -328,6 +333,7 @@
to_chat(M, "<span class='boldnotice'>You feel cool air surround you. You go numb as your senses turn inward.</span>")
add_fingerprint(user)
qdel(G)
SStgui.update_uis(src)
return
return ..()
@@ -374,9 +380,11 @@
occupant = null
updateUsrDialog()
update_icon()
SStgui.update_uis(src)
if(A == beaker)
beaker = null
updateUsrDialog()
SStgui.update_uis(src)
/obj/machinery/sleeper/emp_act(severity)
if(filtering)
@@ -394,7 +402,7 @@
qdel(src)
/obj/machinery/sleeper/proc/toggle_filter()
if(filtering)
if(filtering || !beaker)
filtering = 0
else
filtering = 1
@@ -410,26 +418,25 @@
// eject trash the occupant dropped
for(var/atom/movable/A in contents - component_parts - list(beaker))
A.forceMove(loc)
SStgui.update_uis(src)
/obj/machinery/sleeper/proc/inject_chemical(mob/living/user as mob, chemical, amount)
/obj/machinery/sleeper/proc/inject_chemical(mob/living/user, chemical, amount)
if(!(chemical in possible_chems))
to_chat(user, "<span class='notice'>The sleeper does not offer that chemical!</span>")
return
if(!(amount in amounts))
return
if(occupant)
if(occupant.reagents)
if(occupant.reagents.get_reagent_amount(chemical) + amount <= max_chem)
occupant.reagents.add_reagent(chemical, amount)
return
else
to_chat(user, "You can not inject any more of this chemical.")
return
else
to_chat(user, "The patient rejects the chemicals!")
return
else
to_chat(user, "There's no occupant in the sleeper!")
return
/obj/machinery/sleeper/verb/eject()
set name = "Eject Sleeper"
@@ -456,6 +463,7 @@
filtering = 0
beaker.forceMove(usr.loc)
beaker = null
SStgui.update_uis(src)
add_fingerprint(usr)
return
@@ -508,6 +516,7 @@
add_fingerprint(user)
if(user.pulling == L)
user.stop_pulling()
SStgui.update_uis(src)
return
return
@@ -544,6 +553,7 @@
for(var/obj/O in src)
qdel(O)
add_fingerprint(usr)
SStgui.update_uis(src)
return
return
-211
View File
@@ -1,211 +0,0 @@
<!--
Title: Sleeper Status UI
Used In File(s): \code\game\machinery\Sleeper.dm
-->
<h3>Sleeper Status</h3>
<div class="statusDisplay">
{{if !data.hasOccupant}}
<div class="line">Sleeper Unoccupied</div>
{{else}}
<div class="line">
{{:data.occupant.name}}&nbsp;=>&nbsp;
{{if data.occupant.stat == 0}}
<span class="good">Conscious</span>
{{else data.occupant.stat == 1}}
<span class="average">Unconscious</span>
{{else}}
<span class="bad">DEAD</span>
{{/if}}
</div>
<div class="line">
<div class="statusLabel">Health:</div>
{{if data.occupant.health >= data.occupant.maxHealth}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'good')}}
{{else data.occupant.health > 0}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'average')}}
{{else data.occupant.health >= data.minhealth}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'average alignRight')}}
{{else}}
{{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'bad alignRight')}}
{{/if}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.health)}}</div>
</div>
<div class="line">
<div class="statusLabel">=&gt; Brute Damage:</div>
{{:helper.displayBar(data.occupant.bruteLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.bruteLoss)}}</div>
</div>
<div class="line">
<div class="statusLabel">=&gt; Resp. Damage:</div>
{{:helper.displayBar(data.occupant.oxyLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.oxyLoss)}}</div>
</div>
<div class="line">
<div class="statusLabel">=&gt; Toxin Damage:</div>
{{:helper.displayBar(data.occupant.toxLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.toxLoss)}}</div>
</div>
<div class="line">
<div class="statusLabel">=&gt; Burn Severity:</div>
{{:helper.displayBar(data.occupant.fireLoss, 0, data.occupant.maxHealth, 'bad')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.fireLoss)}}</div>
</div>
<br>
<div class="line">
<!--
<div class="statusLabel">Patient Temperature:</div>
{{if data.occupant.temperatureSuitability == -3}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'cold3')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == -2}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'cold2')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == -1}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'cold1')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 0}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'good')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 1}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'hot1')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 2}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'hot2')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 3}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'hot3')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{/if}}
If you can get the changing temperature bars to work right, congratulations
-->
<div class="statusLabel">Patient Temperature:</div>
{{if data.occupant.temperatureSuitability == -3}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'bad')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == -2}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == -1}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 0}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'good')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 1}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 2}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'average')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{else data.occupant.temperatureSuitability == 3}}
{{:helper.displayBar(data.occupant.bodyTemperature, 0, data.occupant.maxTemp, 'bad')}}
<div class="statusValue bad">{{:helper.smoothRound(data.occupant.btCelsius)}}&deg;C, {{:helper.smoothRound(data.occupant.btFaren)}}&deg;F</div>
{{/if}}
</div>
{{if data.occupant.hasBlood}}
<br>
<div class="line">
<div class="statusLabel">Pulse:</div> <div class="statusValue">{{:data.occupant.pulse}} bpm</div>
</div>
<div class="line">
<div class="statusLabel">Blood Level:</div>
{{if data.occupant.bloodPercent <= 60}}
{{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'bad')}}
<div class="statusValue">
{{:helper.smoothRound(data.occupant.bloodPercent)}}%, {{:helper.smoothRound(data.occupant.bloodLevel)}}cl
</div>
{{else data.occupant.bloodPercent <= 90}}
{{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'average')}}
<div class="statusValue">
{{:helper.smoothRound(data.occupant.bloodPercent)}}%, {{:helper.smoothRound(data.occupant.bloodLevel)}}cl
</div>
{{else}}
{{:helper.displayBar(data.occupant.bloodLevel, 0, data.occupant.bloodMax, 'good')}}
<div class="statusValue">
{{:helper.smoothRound(data.occupant.bloodPercent)}}%, {{:helper.smoothRound(data.occupant.bloodLevel)}}cl
</div>
{{/if}}
</div>
{{/if}}
{{/if}}
</div>
<h3>Sleeper Operation</h3>
<div class="item">
<div class="itemLabel">
Sleeper Status:
</div>
<div class="itemContent" style="width: 26%;">
{{:helper.link('Eject Occupant', 'arrow-circle-o-down', {'ejectify' : 1}, data.hasOccupant ? null : 'disabled')}}
</div>
</div>
<div class="item">&nbsp;</div>
<div class="item">
<div class="itemLabel">
Dialysis Beaker:
</div>
<div class="itemContent" style="width: 40%;">
{{if data.isBeakerLoaded}}
<span class="highlight">{{:helper.smoothRound(data.beakerFreeSpace)}} units of space remaining</span><br>
{{else}}
<span class="average"><i>No Dialysis Output Beaker Loaded</i></span>
{{/if}}
</div>
<div class="itemContent" style="width: 26%;">
{{:helper.link('Eject Beaker', 'eject', {'removebeaker' : 1}, data.isBeakerLoaded ? null : 'disabled')}}
{{if data.isBeakerLoaded}}
<div class="line">
<div class="itemContent">
{{:helper.link('On', 'power-off', {'togglefilter' : 1}, data.occupant.hasBlood ? (data.dialysis ? 'selected' : null) : 'disabled')}}{{:helper.link('Off', 'close', {'togglefilter' : 1}, data.dialysis ? null : 'selected')}}
</div>
</div>
{{/if}}
</div>
</div>
<div class="item">
<div class="itemLabel">
Chemicals:
</div>
{{for data.chemicals}}
<div class="line"><b>{{:value.title}}</b></div>
<div class="line">
{{if value.overdosing}}
{{:helper.displayBar(value.occ_amount, 0, data.maxchem, 'bad')}}
{{else value.od_warning}}
{{:helper.displayBar(value.occ_amount, 0, data.maxchem, 'average')}}
{{else}}
{{:helper.displayBar(value.occ_amount, 0, data.maxchem, 'good')}}
{{/if}}
<div class="statusValue">{{:helper.smoothRound(value.pretty_amount)}}/{{:data.maxchem}}</div>
<br>
</div>
<div class="line">
<div class="itemContent">
{{:helper.link('5', 'gear', {'chemical' : value.id, 'amount' : 5}, (!value.injectable || ((value.occ_amount + 5) > data.maxchem)) ? 'disabled' : null)}}
{{:helper.link('10', 'gear', {'chemical' : value.id, 'amount' : 10}, (!value.injectable || ((value.occ_amount + 10) > data.maxchem)) ? 'disabled' : null)}}
</div>
</div>
{{/for}}
<div class="item">&nbsp;</div>
<div class="item">
<div class="itemLabel" style="width: 35%">
Auto-eject dead patients:
</div>
<div class="itemContent" style="width: 30%">
{{:helper.link('On', 'power-off', {'auto_eject_dead_on' : 1}, data.auto_eject_dead ? 'selected' : null)}}{{:helper.link('Off', 'close', {'auto_eject_dead_off' : 0}, data.auto_eject_dead ? null : 'selected')}}
</div>
</div>
</div>
+315
View File
@@ -0,0 +1,315 @@
import { round, toFixed } from 'common/math';
import { Fragment } from 'inferno';
import { useBackend } from "../backend";
import { Window } from "../layouts";
import { AnimatedNumber, Box, Button, Flex, Icon, LabeledList, NumberInput, ProgressBar, Section } from "../components";
import { BeakerContents } from '../interfaces/common/BeakerContents';
const stats = [
['good', 'Alive'],
['average', 'Critical'],
['bad', 'DEAD'],
];
const damages = [
['Resp.', 'oxyLoss'],
['Toxin', 'toxLoss'],
['Brute', 'bruteLoss'],
['Burn', 'fireLoss'],
];
const damageRange = {
average: [0.25, 0.5],
bad: [0.5, Infinity],
};
const tempColors = [
'bad',
'average',
'average',
'good',
'average',
'average',
'bad',
];
export const Sleeper = (props, context) => {
const { act, data } = useBackend(context);
const {
hasOccupant,
} = data;
const body = hasOccupant ? <SleeperMain /> : <SleeperEmpty />;
return (
<Window resizable>
<Window.Content className="Layout__content--flexColumn">
{body}
</Window.Content>
</Window>
);
};
const SleeperMain = (props, context) => {
const { act, data } = useBackend(context);
const {
occupant,
} = data;
return (
<Fragment>
<SleeperOccupant />
<SleeperDamage />
<SleeperDialysis />
<SleeperChemicals />
</Fragment>
);
};
const SleeperOccupant = (props, context) => {
const { act, data } = useBackend(context);
const {
occupant,
auto_eject_dead,
} = data;
return (
<Section
title="Occupant"
buttons={(
<Fragment>
<Box color="label" display="inline">
Auto-eject if dead:&nbsp;
</Box>
<Button
icon={auto_eject_dead ? "toggle-on" : "toggle-off"}
selected={auto_eject_dead}
content={auto_eject_dead ? 'On' : 'Off'}
onClick={() =>
act('auto_eject_dead_' + (auto_eject_dead ? 'off' : 'on'))}
/>
<Button
icon="user-slash"
content="Eject"
onClick={() => act('ejectify')}
/>
</Fragment>
)}>
<LabeledList>
<LabeledList.Item label="Name">
{occupant.name}
</LabeledList.Item>
<LabeledList.Item label="Health">
<ProgressBar
min="0"
max={occupant.maxHealth}
value={occupant.health / occupant.maxHealth}
ranges={{
good: [0.5, Infinity],
average: [0, 0.5],
bad: [-Infinity, 0],
}}>
{round(occupant.health)}
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Status" color={stats[occupant.stat][0]}>
{stats[occupant.stat][1]}
</LabeledList.Item>
<LabeledList.Item label="Temperature">
<ProgressBar
min="0"
max={occupant.maxTemp}
value={occupant.bodyTemperature / occupant.maxTemp}
color={tempColors[occupant.temperatureSuitability + 3]}>
{round(occupant.btCelsius)}&deg;C, {round(occupant.btFaren)}&deg;F
</ProgressBar>
</LabeledList.Item>
{!!occupant.hasBlood && (
<Fragment>
<LabeledList.Item label="Blood Level">
<ProgressBar
min="0"
max={occupant.bloodMax}
value={occupant.bloodLevel / occupant.bloodMax}
ranges={{
bad: [-Infinity, 0.6],
average: [0.6, 0.9],
good: [0.6, Infinity],
}}>
{occupant.bloodPercent}%, {occupant.bloodLevel}cl
</ProgressBar>
</LabeledList.Item>
<LabeledList.Item label="Pulse" verticalAlign="middle">
{occupant.pulse} BPM
</LabeledList.Item>
</Fragment>
)}
</LabeledList>
</Section>
);
};
const SleeperDamage = (props, context) => {
const { data } = useBackend(context);
const {
occupant,
} = data;
return (
<Section
title="Damage">
<LabeledList>
{damages.map((d, i) => (
<LabeledList.Item key={i} label={d[0]}>
<ProgressBar
key={i}
min="0"
max="100"
value={occupant[d[1]] / 100}
ranges={damageRange}>
{round(occupant[d[1]])}
</ProgressBar>
</LabeledList.Item>
))}
</LabeledList>
</Section>
);
};
const SleeperDialysis = (props, context) => {
const { act, data } = useBackend(context);
const {
isBeakerLoaded,
beakerMaxSpace,
beakerFreeSpace,
dialysis,
} = data;
const canDialysis = dialysis && beakerFreeSpace > 0;
return (
<Section
title="Dialysis"
buttons={
<Fragment>
<Button
disabled={!isBeakerLoaded || beakerFreeSpace <= 0}
selected={canDialysis}
icon={canDialysis ? "toggle-on" : "toggle-off"}
content={canDialysis ? "Active" : "Inactive"}
onClick={() => act('togglefilter')}
/>
<Button
disabled={!isBeakerLoaded}
icon="eject"
content="Eject"
onClick={() => act('removebeaker')}
/>
</Fragment>
}>
{isBeakerLoaded ? (
<LabeledList>
<LabeledList.Item label="Remaining Space">
<ProgressBar
min="0"
max={beakerMaxSpace}
value={beakerFreeSpace / beakerMaxSpace}
ranges={{
good: [0.5, Infinity],
average: [0.25, 0.5],
bad: [-Infinity, 0.25],
}}>
{beakerFreeSpace}u
</ProgressBar>
</LabeledList.Item>
</LabeledList>
) : (
<Box color="label">
No beaker loaded.
</Box>
)}
</Section>
);
};
const SleeperChemicals = (props, context) => {
const { act, data } = useBackend(context);
const {
occupant,
chemicals,
maxchem,
amounts,
} = data;
return (
<Section title="Chemicals" flexGrow="1">
{chemicals.map((chem, i) => {
let barColor = '';
let odWarning;
if (chem.overdosing) {
barColor = 'bad';
odWarning = (
<Box color="bad">
<Icon name="exclamation-circle" />&nbsp;
Overdosing!
</Box>
);
} else if (chem.od_warning) {
barColor = 'average';
odWarning = (
<Box color="average">
<Icon name="exclamation-triangle" />&nbsp;
Close to overdosing
</Box>
);
}
return (
<Box key={i} backgroundColor="rgba(0, 0, 0, 0.33)" mb="0.5rem">
<Section
title={chem.title}
level="3"
mx="0"
lineHeight="18px"
buttons={odWarning}>
<ProgressBar
min="0"
max={maxchem}
value={chem.occ_amount / maxchem}
color={barColor}
mb="0.5rem">
{chem.pretty_amount}/{maxchem}u
</ProgressBar>
<LabeledList>
<LabeledList.Item label="Inject">
{amounts.map((a, i) => (
<Button
key={i}
disabled={!chem.injectable
|| ((chem.occ_amount + a) > maxchem)
|| occupant.stat === 2}
icon="syringe"
content={a}
onClick={() => act('chemical', {
chemid: chem.id,
amount: a,
})}
/>
))}
</LabeledList.Item>
</LabeledList>
</Section>
</Box>
);
})}
</Section>
);
};
const SleeperEmpty = (props, context) => {
return (
<Section textAlign="center" flexGrow="1">
<Flex height="100%">
<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>
);
};
File diff suppressed because one or more lines are too long