mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-13 03:33:21 +00:00
Bundle Copy
This commit is contained in:
218
tgui/packages/tgui_ch/interfaces/OperatingComputer.js
Normal file
218
tgui/packages/tgui_ch/interfaces/OperatingComputer.js
Normal file
@@ -0,0 +1,218 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { Window } from '../layouts';
|
||||
import { Box, Button, Flex, Icon, Knob, LabeledList, Section, Tabs, ProgressBar } from '../components';
|
||||
|
||||
const stats = [
|
||||
['good', 'Conscious'],
|
||||
['average', 'Unconscious'],
|
||||
['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 OperatingComputer = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { hasOccupant, choice } = data;
|
||||
let body;
|
||||
if (!choice) {
|
||||
body = hasOccupant ? <OperatingComputerPatient /> : <OperatingComputerUnoccupied />;
|
||||
} else {
|
||||
body = <OperatingComputerOptions />;
|
||||
}
|
||||
return (
|
||||
<Window width={650} height={455} resizable>
|
||||
<Window.Content>
|
||||
<Tabs>
|
||||
<Tabs.Tab selected={!choice} icon="user" onClick={() => act('choiceOff')}>
|
||||
Patient
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab selected={!!choice} icon="cog" onClick={() => act('choiceOn')}>
|
||||
Options
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
<Section flexGrow="1">{body}</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const OperatingComputerPatient = (props, context) => {
|
||||
const { data } = useBackend(context);
|
||||
const { occupant } = data;
|
||||
return (
|
||||
<Fragment>
|
||||
<Section title="Patient" level="2">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Name">{occupant.name}</LabeledList.Item>
|
||||
<LabeledList.Item label="Status" color={stats[occupant.stat][0]}>
|
||||
{stats[occupant.stat][1]}
|
||||
</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],
|
||||
}}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
{damages.map((d, i) => (
|
||||
<LabeledList.Item key={i} label={d[0] + ' Damage'}>
|
||||
<ProgressBar key={i} min="0" max="100" value={occupant[d[1]] / 100} ranges={damageRange}>
|
||||
{round(occupant[d[1]])}
|
||||
</ProgressBar>
|
||||
</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)}°C, {round(occupant.btFaren)}°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">{occupant.pulse} BPM</LabeledList.Item>
|
||||
</Fragment>
|
||||
)}
|
||||
</LabeledList>
|
||||
</Section>
|
||||
<Section title="Current Procedure" level="2">
|
||||
{occupant.surgery && occupant.surgery.length ? (
|
||||
<LabeledList>
|
||||
{occupant.surgery.map((limb) => (
|
||||
<LabeledList.Item key={limb.name} label={limb.name}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Current State">{limb.currentStage}</LabeledList.Item>
|
||||
<LabeledList.Item label="Possible Next Steps">
|
||||
{limb.nextSteps.map((step) => (
|
||||
<div key={step}>{step}</div>
|
||||
))}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
</LabeledList>
|
||||
) : (
|
||||
<Box color="label">No procedure ongoing.</Box>
|
||||
)}
|
||||
</Section>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const OperatingComputerUnoccupied = () => {
|
||||
return (
|
||||
<Flex textAlign="center" height="100%">
|
||||
<Flex.Item grow="1" align="center" color="label">
|
||||
<Icon name="user-slash" mb="0.5rem" size="5" />
|
||||
<br />
|
||||
No patient detected.
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const OperatingComputerOptions = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const { verbose, health, healthAlarm, oxy, oxyAlarm, crit } = data;
|
||||
return (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Loudspeaker">
|
||||
<Button
|
||||
selected={verbose}
|
||||
icon={verbose ? 'toggle-on' : 'toggle-off'}
|
||||
content={verbose ? 'On' : 'Off'}
|
||||
onClick={() => act(verbose ? 'verboseOff' : 'verboseOn')}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Health Announcer">
|
||||
<Button
|
||||
selected={health}
|
||||
icon={health ? 'toggle-on' : 'toggle-off'}
|
||||
content={health ? 'On' : 'Off'}
|
||||
onClick={() => act(health ? 'healthOff' : 'healthOn')}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Health Announcer Threshold">
|
||||
<Knob
|
||||
bipolar
|
||||
minValue="-100"
|
||||
maxValue="100"
|
||||
value={healthAlarm}
|
||||
stepPixelSize="5"
|
||||
ml="0"
|
||||
format={(val) => val + '%'}
|
||||
onChange={(e, val) =>
|
||||
act('health_adj', {
|
||||
new: val,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Oxygen Alarm">
|
||||
<Button
|
||||
selected={oxy}
|
||||
icon={oxy ? 'toggle-on' : 'toggle-off'}
|
||||
content={oxy ? 'On' : 'Off'}
|
||||
onClick={() => act(oxy ? 'oxyOff' : 'oxyOn')}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Oxygen Alarm Threshold">
|
||||
<Knob
|
||||
bipolar
|
||||
minValue="-100"
|
||||
maxValue="100"
|
||||
value={oxyAlarm}
|
||||
stepPixelSize="5"
|
||||
ml="0"
|
||||
onChange={(e, val) =>
|
||||
act('oxy_adj', {
|
||||
new: val,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Critical Alert">
|
||||
<Button
|
||||
selected={crit}
|
||||
icon={crit ? 'toggle-on' : 'toggle-off'}
|
||||
content={crit ? 'On' : 'Off'}
|
||||
onClick={() => act(crit ? 'critOff' : 'critOn')}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user