mirror of
https://github.com/quotefox/Hyper-Station-13.git
synced 2026-08-24 13:16:16 +01:00
@@ -156,3 +156,7 @@
|
||||
|
||||
//belly sound pref things
|
||||
#define NORMIE_HEARCHECK 4
|
||||
|
||||
#define BORGBELLY_NONE 0
|
||||
#define BORGBELLY_RED 1
|
||||
#define BORGBELLY_GREEN 2
|
||||
@@ -11,7 +11,6 @@
|
||||
var/min_health = -100
|
||||
var/cleaning = FALSE
|
||||
var/cleaning_cycles = 10
|
||||
var/patient_laststat = null
|
||||
var/list/injection_chems = list(/datum/reagent/medicine/antitoxin, /datum/reagent/medicine/epinephrine,
|
||||
/datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane)
|
||||
var/eject_port = "ingestion"
|
||||
@@ -86,16 +85,16 @@
|
||||
if(patient)
|
||||
to_chat(user, "<span class='warning'>Your [src] is already occupied.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is carefully inserting [target.name] into their [src].</span>", "<span class='notice'>You start placing [target] into your [src]...</span>")
|
||||
|
||||
user.visible_message("<span class='warning'>[hound.name] is carefully inserting [target.name] into their [src].</span>",
|
||||
"<span class='notice'>You start placing [target] into your [src]...</span>")
|
||||
|
||||
if(!patient && iscarbon(target) && !target.buckled && do_after (user, 100, target = target))
|
||||
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
|
||||
if(!in_range(src, target))
|
||||
return
|
||||
if(patient)
|
||||
return //If you try to eat two people at once, you can only eat one.
|
||||
|
||||
else //If you don't have someone in you, proceed.
|
||||
return
|
||||
else
|
||||
if(!isjellyperson(target) && ("toxin" in injection_chems))
|
||||
injection_chems -= "toxin"
|
||||
injection_chems += "antitoxin"
|
||||
@@ -104,8 +103,8 @@
|
||||
injection_chems += "toxin"
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
target.ExtinguishMob() //The tongue already puts out fire stacks but being put into the sleeper shouldn't allow you to keep burning.
|
||||
update_gut(hound)
|
||||
target.ExtinguishMob()
|
||||
UpdateGut(hound)
|
||||
user.visible_message("<span class='warning'>[voracious ? "[hound]'s [src.name] lights up and expands as [target] slips inside into their [src.name]." : "[hound]'s sleeper indicator lights up as [target] is scooped up into [hound.p_their()] [src]."]</span>", \
|
||||
"<span class='notice'>Your [voracious ? "[src.name] lights up as [target] slips into" : "sleeper indicator light shines brightly as [target] is scooped inside"] your [src]. Life support functions engaged.</span>")
|
||||
message_admins("[key_name(hound)] has sleeper'd [key_name(patient)] as a dogborg. [ADMIN_JMP(src)]")
|
||||
@@ -156,7 +155,7 @@
|
||||
items_preserved.Cut()
|
||||
cleaning = FALSE
|
||||
if(hound)
|
||||
update_gut(hound)
|
||||
UpdateGut(hound)
|
||||
|
||||
|
||||
/obj/item/dogborg/sleeper/attack_self(mob/user)
|
||||
@@ -170,13 +169,18 @@
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// TGUI TODO: do something about this UI
|
||||
ui = new(user, src, ui_key, "dogborg_sleeper", name, 375, 550, master_ui, state)
|
||||
ui = new(user, src, ui_key, "DogborgSleeper", name, 375, 550, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/dogborg/sleeper/ui_data()
|
||||
var/list/data = list()
|
||||
var/chemical_list = list()
|
||||
var/blood_percent = 0
|
||||
|
||||
data["occupied"] = patient ? 1 : 0
|
||||
data["blood_levels"] = blood_percent
|
||||
data["blood_status"] = "Patient either has no blood, or does not require it to function."
|
||||
data["chemical_list"] = chemical_list
|
||||
|
||||
if(cleaning && length(contents - items_preserved))
|
||||
data["items"] = "Self-cleaning mode active: [length(contents - items_preserved)] object(s) remaining."
|
||||
@@ -185,7 +189,7 @@
|
||||
data["chem"] = list()
|
||||
for(var/chem in injection_chems)
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
|
||||
data["chem"] += list(list("name" = R.name, "id" = R.type))
|
||||
data["chem"] += list(list("name" = R.name, "id" = R.type, "allowed" = TRUE))
|
||||
|
||||
data["occupant"] = list()
|
||||
var/mob/living/mob_occupant = patient
|
||||
@@ -213,10 +217,41 @@
|
||||
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
|
||||
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
|
||||
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
data["occupant"]["reagents"] = list()
|
||||
|
||||
if(mob_occupant.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
|
||||
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
|
||||
chemical_list += list(list("name" = R.name, "volume" = R.volume))
|
||||
else
|
||||
chemical_list = "Patient has no reagents."
|
||||
|
||||
data["occupant"]["failing_organs"] = list()
|
||||
var/mob/living/carbon/C = mob_occupant
|
||||
if(C)
|
||||
for(var/obj/item/organ/Or in C.getFailingOrgans())
|
||||
if(istype(Or, /obj/item/organ/brain))
|
||||
continue
|
||||
data["occupant"]["failing_organs"] += list(list("name" = Or.name))
|
||||
|
||||
if(istype(C)) //Non-carbons shouldn't be able to enter sleepers, but this is to prevent runtimes if something ever breaks
|
||||
if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner.
|
||||
blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
|
||||
var/blood_id = C.get_blood_id()
|
||||
var/blood_warning = ""
|
||||
if(blood_percent < 80)
|
||||
blood_warning = "Patient has low blood levels."
|
||||
if(blood_percent < 60)
|
||||
blood_warning = "Patient has DANGEROUSLY low blood levels."
|
||||
if(blood_id)
|
||||
var/blood_type = C.dna.blood_type
|
||||
if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
|
||||
if(R)
|
||||
blood_type = R.name
|
||||
else
|
||||
blood_type = blood_id
|
||||
data["blood_status"] = "Patient has [blood_type] type blood. [blood_warning]"
|
||||
data["blood_levels"] = blood_percent
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/dogborg/sleeper/ui_act(action, params)
|
||||
@@ -239,81 +274,42 @@
|
||||
to_chat(src, "Your [src] is already cleaned.")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(patient, "<span class='danger'>[usr.name]'s [src] fills with caustic enzymes around you!</span>")
|
||||
to_chat(patient, "<span class='userdanger'>[usr.name]'s [src] fills with caustic enzymes around you!</span>")
|
||||
to_chat(src, "<span class='danger'>Cleaning process enabled.</span>")
|
||||
clean_cycle(usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/update_gut(mob/living/silicon/robot/hound)
|
||||
//Well, we HAD one, what happened to them?
|
||||
if(!hound) //runetime error fix with dogborgs with no sleepers
|
||||
return
|
||||
|
||||
var/prociconupdate = FALSE
|
||||
var/currentenvy = hound.sleeper_nv
|
||||
hound.sleeper_nv = FALSE
|
||||
if(patient in contents)
|
||||
if(patient_laststat != patient.stat)
|
||||
if(patient.stat & DEAD)
|
||||
hound.sleeper_r = 1
|
||||
hound.sleeper_g = 0
|
||||
patient_laststat = patient.stat
|
||||
else
|
||||
hound.sleeper_r = 0
|
||||
hound.sleeper_g = 1
|
||||
patient_laststat = patient.stat
|
||||
prociconupdate = TRUE
|
||||
|
||||
if(!patient.client || !(patient.client.prefs.cit_toggles & MEDIHOUND_SLEEPER) || !hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
hound.sleeper_nv = TRUE
|
||||
else
|
||||
hound.sleeper_nv = FALSE
|
||||
if(hound.sleeper_nv != currentenvy)
|
||||
prociconupdate = TRUE
|
||||
|
||||
//Update icon
|
||||
if(prociconupdate)
|
||||
hound.update_icons()
|
||||
//Return original patient
|
||||
return(patient)
|
||||
//Check for a new patient
|
||||
else
|
||||
for(var/mob/living/carbon/human/C in contents)
|
||||
patient = C
|
||||
if(patient.stat & DEAD)
|
||||
hound.sleeper_r = 1
|
||||
hound.sleeper_g = 0
|
||||
patient_laststat = patient.stat
|
||||
else
|
||||
hound.sleeper_r = 0
|
||||
hound.sleeper_g = 1
|
||||
patient_laststat = patient.stat
|
||||
|
||||
if(!patient.client || !(patient.client.prefs.cit_toggles & MEDIHOUND_SLEEPER) || !hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
hound.sleeper_nv = TRUE
|
||||
else
|
||||
hound.sleeper_nv = FALSE
|
||||
|
||||
//Update icon and return new patient
|
||||
hound.update_icons()
|
||||
return
|
||||
|
||||
//Cleaning looks better with red on, even with nobody in it
|
||||
if(cleaning && !patient)
|
||||
hound.sleeper_r = 1
|
||||
hound.sleeper_g = 0
|
||||
//Couldn't find anyone, and not cleaning
|
||||
else if(!cleaning && !patient)
|
||||
hound.sleeper_r = 0
|
||||
hound.sleeper_g = 0
|
||||
|
||||
patient_laststat = null
|
||||
/obj/item/dogborg/sleeper/proc/UpdatePatient(mob/living/silicon/robot/hound)
|
||||
patient = null
|
||||
hound.update_icons()
|
||||
for(var/mob/living/carbon/human/C in contents)
|
||||
patient = C
|
||||
break
|
||||
return patient
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/CheckNeedsGutUpdate(mob/living/silicon/robot/hound)
|
||||
if(!hound) return
|
||||
var/current_belly = BORGBELLY_NONE
|
||||
UpdatePatient(hound)
|
||||
if(patient)
|
||||
var/patient_vore_enabled = patient.client?.prefs?.cit_toggles & MEDIHOUND_SLEEPER
|
||||
var/hound_vore_enabled = hound.client?.prefs?.cit_toggles & MEDIHOUND_SLEEPER
|
||||
if(patient_vore_enabled && hound_vore_enabled)
|
||||
if(patient.stat & DEAD)
|
||||
current_belly = BORGBELLY_RED
|
||||
else
|
||||
current_belly = BORGBELLY_GREEN
|
||||
else
|
||||
if(cleaning)
|
||||
current_belly = BORGBELLY_RED
|
||||
return current_belly
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/UpdateGut(mob/living/silicon/robot/hound)
|
||||
var/new_belly = CheckNeedsGutUpdate(hound)
|
||||
if(hound.sleeper_state != new_belly)
|
||||
hound.sleeper_state = new_belly
|
||||
hound.update_icons()
|
||||
|
||||
//Gurgleborg process
|
||||
/obj/item/dogborg/sleeper/proc/clean_cycle(mob/living/silicon/robot/hound)
|
||||
//Sanity
|
||||
if(!hound)
|
||||
return
|
||||
for(var/I in items_preserved)
|
||||
@@ -365,15 +361,13 @@
|
||||
if(!T.dropItemToGround(W))
|
||||
qdel(W)
|
||||
qdel(T)
|
||||
//Handle the target being anything but a mob
|
||||
else if(isobj(target))
|
||||
var/obj/T = target
|
||||
if(T.type in important_items) //If the object is in the items_preserved global list
|
||||
items_preserved += T
|
||||
//If the object is not one to preserve
|
||||
else
|
||||
qdel(T)
|
||||
update_gut()
|
||||
UpdateGut(hound)
|
||||
hound.cell.give(10)
|
||||
else
|
||||
cleaning_cycles = initial(cleaning_cycles)
|
||||
@@ -399,9 +393,8 @@
|
||||
H.playsound_local(source, null, 45, falloff = 0, S = pred_digest)
|
||||
else if(H in contents)
|
||||
H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
|
||||
|
||||
update_gut(hound)
|
||||
|
||||
|
||||
UpdateGut(hound)
|
||||
if(cleaning)
|
||||
addtimer(CALLBACK(src, .proc/clean_cycle, hound), 50)
|
||||
|
||||
@@ -462,7 +455,7 @@
|
||||
if(do_after(user, 30, target = target) && !patient && !target.buckled)
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
update_gut(hound)
|
||||
UpdateGut(hound)
|
||||
user.visible_message("<span class='warning'>[hound.name]'s mobile brig clunks in series as [target] slips inside.</span>", "<span class='notice'>Your mobile brig groans lightly as [target] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
|
||||
|
||||
@@ -490,31 +483,25 @@
|
||||
if(length(contents) > (max_item_count - 1))
|
||||
to_chat(user,"<span class='warning'>Your [src] is full. Eject or process contents to continue.</span>")
|
||||
return
|
||||
|
||||
if(isitem(target))
|
||||
var/obj/item/I = target
|
||||
if(CheckAccepted(I))
|
||||
to_chat(user,"<span class='warning'>[I] registers an error code to your [src]</span>")
|
||||
to_chat(user,"<span class='warning'>[I] registers an error code to your [src].</span>")
|
||||
return
|
||||
if(I.w_class > WEIGHT_CLASS_NORMAL)
|
||||
to_chat(user,"<span class='warning'>[I] is too large to fit into your [src]</span>")
|
||||
to_chat(user,"<span class='warning'>[I] is too large to fit into your [src].</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [I] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
||||
if(do_after(user, 15, target = target) && length(contents) < max_item_count)
|
||||
I.forceMove(src)
|
||||
I.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [I] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [I] slips inside.</span>")
|
||||
playsound(hound, 'sound/machines/disposalflush.ogg', 50, 1)
|
||||
if(length(contents) > 11) //grow that tum after a certain junk amount
|
||||
hound.sleeper_r = 1
|
||||
hound.update_icons()
|
||||
else
|
||||
hound.sleeper_r = 0
|
||||
hound.update_icons()
|
||||
return
|
||||
|
||||
if(iscarbon(target) || issilicon(target))
|
||||
else if(iscarbon(target) || issilicon(target))
|
||||
var/mob/living/trashman = target
|
||||
if(!trashman.devourable)
|
||||
to_chat(user, "<span class='warning'>[target] registers an error code to your [src]</span>")
|
||||
to_chat(user, "<span class='warning'>[target] registers an error code to your [src].</span>")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user,"<span class='warning'>Your [src] is already occupied.</span>")
|
||||
@@ -526,6 +513,14 @@
|
||||
if(do_after(user, 30, target = trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
|
||||
trashman.forceMove(src)
|
||||
trashman.reset_perspective(src)
|
||||
update_gut()
|
||||
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashman] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
|
||||
|
||||
UpdateGut(hound)
|
||||
|
||||
|
||||
/obj/item/dogborg/sleeper/compactor/CheckNeedsGutUpdate(mob/living/silicon/robot/hound)
|
||||
var/current_belly = ..()
|
||||
if(length(contents) > 11)
|
||||
current_belly = BORGBELLY_RED
|
||||
return current_belly
|
||||
@@ -25,8 +25,7 @@
|
||||
disabler = FALSE
|
||||
update_icons() //PUT THE GUN AWAY
|
||||
else if(istype(O,/obj/item/dogborg/sleeper))
|
||||
sleeper_g = FALSE
|
||||
sleeper_r = FALSE
|
||||
sleeper_state = BORGBELLY_NONE
|
||||
update_icons()
|
||||
var/obj/item/dogborg/sleeper/S = O
|
||||
S.go_out() //this should stop edgecase deletions
|
||||
|
||||
@@ -654,10 +654,14 @@
|
||||
if(disabler)
|
||||
add_overlay("disabler")//ditto
|
||||
|
||||
if(sleeper_g && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_g[sleeper_nv ? "_nv" : ""]")
|
||||
if(sleeper_r && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_r[sleeper_nv ? "_nv" : ""]")
|
||||
if(module.sleeper_overlay)
|
||||
var/sleeper_overlay_state = ""
|
||||
switch(sleeper_state)
|
||||
if(BORGBELLY_NONE) sleeper_overlay_state = ""
|
||||
if(BORGBELLY_GREEN) sleeper_overlay_state = "_g"
|
||||
if(BORGBELLY_RED) sleeper_overlay_state = "_r"
|
||||
add_overlay("[module.sleeper_overlay][sleeper_overlay_state]")
|
||||
|
||||
if(module.dogborg == TRUE)
|
||||
if(resting)
|
||||
cut_overlays()
|
||||
|
||||
@@ -309,9 +309,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
var/leap_at
|
||||
var/disabler
|
||||
var/laser
|
||||
var/sleeper_g
|
||||
var/sleeper_r
|
||||
var/sleeper_nv
|
||||
var/sleeper_state = BORGBELLY_NONE
|
||||
|
||||
#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance.
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Button, LabeledList, NoticeBox, Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { SleeperInjectChems } from './Sleeper/SleeperInjectChems';
|
||||
import { SleeperOccupantStats } from './Sleeper/SleeperOccupantStats';
|
||||
import { SleeperPatientReagents } from './Sleeper/SleeperPatientReagents';
|
||||
|
||||
export const DogborgSleeper = (props, context) => {
|
||||
const { data, act } = useBackend(context);
|
||||
const preSortChems = data.chem || [];
|
||||
const chems = preSortChems.sort((a, b) => {
|
||||
const descA = a.name.toLowerCase();
|
||||
const descB = b.name.toLowerCase();
|
||||
if (descA < descB) {
|
||||
return -1;
|
||||
}
|
||||
if (descA > descB) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content scrollable>
|
||||
<SleeperOccupantStats data={data} />
|
||||
{data.cleaning && data.items && (
|
||||
<NoticeBox>
|
||||
{data.items}
|
||||
</NoticeBox>
|
||||
) || null}
|
||||
<SleeperPatientReagents data={data} />
|
||||
{chems.length > 0 && <SleeperInjectChems chems={chems} data={data} act={act} />}
|
||||
<DogborgControls data={data} act={act} />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const DogborgControls = (props, context) => {
|
||||
const { data, act } = props;
|
||||
const { occupant, cleaning } = data;
|
||||
|
||||
return (
|
||||
<Section title="Operations">
|
||||
<Box>
|
||||
<Button
|
||||
icon="sign-out-alt"
|
||||
disabled={!occupant}
|
||||
onClick={() => act('eject')}>
|
||||
Eject Contents
|
||||
</Button>
|
||||
</Box>
|
||||
<Box>
|
||||
<Button
|
||||
icon="recycle"
|
||||
onClick={() => act('cleaning')}>
|
||||
Activate Self-Cleaning Cycle
|
||||
</Button>
|
||||
</Box>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +1,13 @@
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from '../backend';
|
||||
import { AnimatedNumber, Box, Button, LabeledList, ProgressBar, Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { SleeperInjectChems } from './Sleeper/SleeperInjectChems';
|
||||
import { SleeperOccupantStats } from './Sleeper/SleeperOccupantStats';
|
||||
import { SleeperPatientReagents } from './Sleeper/SleeperPatientReagents';
|
||||
import { SleeperPurgeChems } from './Sleeper/SleeperPurgeChems';
|
||||
import { SleeperSynthChems } from './Sleeper/SleeperSynthChems';
|
||||
|
||||
export const Sleeper = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
occupied,
|
||||
open,
|
||||
occupant = [],
|
||||
} = data;
|
||||
|
||||
const preSortChems = data.chems || [];
|
||||
const chems = preSortChems.sort((a, b) => {
|
||||
const descA = a.name.toLowerCase();
|
||||
@@ -24,161 +20,17 @@ export const Sleeper = (props, context) => {
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
const preSortSynth = data.synthchems || [];
|
||||
const synthchems = preSortSynth.sort((a, b) => {
|
||||
const descA = a.name.toLowerCase();
|
||||
const descB = b.name.toLowerCase();
|
||||
if (descA < descB) {
|
||||
return -1;
|
||||
}
|
||||
if (descA > descB) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
const damageTypes = [
|
||||
{
|
||||
label: 'Brute',
|
||||
type: 'bruteLoss',
|
||||
},
|
||||
{
|
||||
label: 'Burn',
|
||||
type: 'fireLoss',
|
||||
},
|
||||
{
|
||||
label: 'Toxin',
|
||||
type: 'toxLoss',
|
||||
},
|
||||
{
|
||||
label: 'Oxygen',
|
||||
type: 'oxyLoss',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<Section
|
||||
title={occupant.name ? occupant.name : 'No Occupant'}
|
||||
minHeight="210px"
|
||||
buttons={!!occupant.stat && (
|
||||
<Box
|
||||
inline
|
||||
bold
|
||||
color={occupant.statstate}>
|
||||
{occupant.stat}
|
||||
</Box>
|
||||
)}>
|
||||
{!!occupied && (
|
||||
<Fragment>
|
||||
<ProgressBar
|
||||
value={occupant.health}
|
||||
minValue={occupant.minHealth}
|
||||
maxValue={occupant.maxHealth}
|
||||
ranges={{
|
||||
good: [50, Infinity],
|
||||
average: [0, 50],
|
||||
bad: [-Infinity, 0],
|
||||
}} />
|
||||
<Box mt={1} />
|
||||
<LabeledList>
|
||||
{damageTypes.map(type => (
|
||||
<LabeledList.Item
|
||||
key={type.type}
|
||||
label={type.label}>
|
||||
<ProgressBar
|
||||
value={occupant[type.type]}
|
||||
minValue={0}
|
||||
maxValue={occupant.maxHealth}
|
||||
color="bad" />
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
<LabeledList.Item
|
||||
label={'Blood'}>
|
||||
<ProgressBar
|
||||
value={data.blood_levels/100}
|
||||
color="bad">
|
||||
<AnimatedNumber value={data.blood_levels} />
|
||||
</ProgressBar>
|
||||
{data.blood_status}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item
|
||||
label="Cells"
|
||||
color={occupant.cloneLoss ? 'bad' : 'good'}>
|
||||
{occupant.cloneLoss ? 'Damaged' : 'Healthy'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item
|
||||
label="Brain"
|
||||
color={occupant.brainLoss ? 'bad' : 'good'}>
|
||||
{occupant.brainLoss ? 'Abnormal' : 'Healthy'}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Fragment>
|
||||
)}
|
||||
</Section>
|
||||
<Section title="Chemical Analysis">
|
||||
<LabeledList.Item label="Chemical Contents">
|
||||
{data.chemical_list.map(specificChem => (
|
||||
<Box
|
||||
key={specificChem.id}
|
||||
color="good" >
|
||||
{specificChem.volume} units of {specificChem.name}
|
||||
</Box>
|
||||
),
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
</Section>
|
||||
<Section
|
||||
title="Inject Chemicals"
|
||||
minHeight="105px"
|
||||
buttons={(
|
||||
<Button
|
||||
icon={open ? 'door-open' : 'door-closed'}
|
||||
content={open ? 'Open' : 'Closed'}
|
||||
onClick={() => act('door')} />
|
||||
)}>
|
||||
{chems.map(chem => (
|
||||
<Button
|
||||
key={chem.name}
|
||||
icon="flask"
|
||||
content={chem.name}
|
||||
disabled={!(occupied && chem.allowed)}
|
||||
width="140px"
|
||||
onClick={() => act('inject', {
|
||||
chem: chem.id,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
</Section>
|
||||
<Section
|
||||
title="Synthesize Chemicals">
|
||||
{synthchems.map(chem => (
|
||||
<Button
|
||||
key={chem.name}
|
||||
content={chem.name}
|
||||
width="140px"
|
||||
onClick={() => act('synth', {
|
||||
chem: chem.id,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
</Section>
|
||||
<Section
|
||||
title="Purge Chemicals">
|
||||
{chems.map(chem => (
|
||||
<Button
|
||||
key={chem.name}
|
||||
content={chem.name}
|
||||
disabled={!(chem.allowed)}
|
||||
width="140px"
|
||||
onClick={() => act('purge', {
|
||||
chem: chem.id,
|
||||
})}
|
||||
/>
|
||||
))}
|
||||
</Section>
|
||||
<Window.Content scrollable>
|
||||
<SleeperOccupantStats data={data} />
|
||||
<SleeperPatientReagents data={data} />
|
||||
<SleeperInjectChems showOpenClosed chems={chems} data={data} act={act} />
|
||||
<SleeperSynthChems data={data} act={act} />
|
||||
<SleeperPurgeChems chems={chems} act={act} />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Button, Section } from '../../components';
|
||||
import { SleeperOpenButton } from "./SleeperOpenButton";
|
||||
|
||||
|
||||
export const SleeperInjectChems = (props, context) => {
|
||||
const { data, act } = props;
|
||||
const { showOpenClosed, chems } = props;
|
||||
const { occupied } = data;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Inject Chemicals"
|
||||
minHeight="105px"
|
||||
buttons={showOpenClosed && <SleeperOpenButton data={data} act={act} />}>
|
||||
{chems.map(chem => (
|
||||
<Button
|
||||
key={chem.name}
|
||||
icon="flask"
|
||||
content={chem.name}
|
||||
disabled={!(occupied && chem.allowed)}
|
||||
width="140px"
|
||||
onClick={() => act('inject', {
|
||||
chem: chem.id,
|
||||
})} />
|
||||
))}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
import { Fragment } from 'inferno';
|
||||
import { AnimatedNumber, Box, LabeledList, ProgressBar, Section } from '../../components';
|
||||
|
||||
|
||||
export const SleeperOccupantStats = (props, context) => {
|
||||
const { data } = props;
|
||||
const { occupant, occupied } = data;
|
||||
const damageTypes = [
|
||||
{
|
||||
label: 'Brute',
|
||||
type: 'bruteLoss',
|
||||
},
|
||||
{
|
||||
label: 'Burn',
|
||||
type: 'fireLoss',
|
||||
},
|
||||
{
|
||||
label: 'Toxin',
|
||||
type: 'toxLoss',
|
||||
},
|
||||
{
|
||||
label: 'Oxygen',
|
||||
type: 'oxyLoss',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Section
|
||||
title={occupant.name ? occupant.name : 'No Occupant'}
|
||||
minHeight="210px"
|
||||
buttons={!!occupant.stat && (
|
||||
<Box
|
||||
inline
|
||||
bold
|
||||
color={occupant.statstate}>
|
||||
{occupant.stat}
|
||||
</Box>
|
||||
)}>
|
||||
{!!occupied && (
|
||||
<Fragment>
|
||||
<ProgressBar
|
||||
value={occupant.health}
|
||||
minValue={occupant.minHealth}
|
||||
maxValue={occupant.maxHealth}
|
||||
ranges={{
|
||||
good: [50, Infinity],
|
||||
average: [0, 50],
|
||||
bad: [-Infinity, 0],
|
||||
}} />
|
||||
<Box mt={1} />
|
||||
<LabeledList>
|
||||
{damageTypes.map(type => (
|
||||
<LabeledList.Item
|
||||
key={type.type}
|
||||
label={type.label}>
|
||||
<ProgressBar
|
||||
value={occupant[type.type]}
|
||||
minValue={0}
|
||||
maxValue={occupant.maxHealth}
|
||||
color="bad" />
|
||||
</LabeledList.Item>
|
||||
))}
|
||||
<LabeledList.Item
|
||||
label={'Blood'}>
|
||||
<ProgressBar
|
||||
value={data.blood_levels / 100}
|
||||
color="bad">
|
||||
<AnimatedNumber value={data.blood_levels} />
|
||||
</ProgressBar>
|
||||
{data.blood_status}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item
|
||||
label="Cells"
|
||||
color={occupant.cloneLoss ? 'bad' : 'good'}>
|
||||
{occupant.cloneLoss ? 'Damaged' : 'Healthy'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item
|
||||
label="Brain"
|
||||
color={occupant.brainLoss ? 'bad' : 'good'}>
|
||||
{occupant.brainLoss ? 'Abnormal' : 'Healthy'}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Fragment>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Button } from '../../components';
|
||||
|
||||
|
||||
export const SleeperOpenButton = (props, context) => {
|
||||
const { data, act } = props;
|
||||
const { open } = data;
|
||||
|
||||
return (
|
||||
<Button
|
||||
icon={open ? 'door-open' : 'door-closed'}
|
||||
content={open ? 'Open' : 'Closed'}
|
||||
onClick={() => act('door')} />
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Box, LabeledList, Section } from '../../components';
|
||||
|
||||
|
||||
export const SleeperPatientReagents = (props, context) => {
|
||||
const { data } = props;
|
||||
const { chemical_list } = data;
|
||||
|
||||
return (
|
||||
<Section title="Chemical Analysis">
|
||||
<LabeledList.Item label="Chemical Contents">
|
||||
{chemical_list.map(specificChem => (
|
||||
<Box
|
||||
key={specificChem.id}
|
||||
color="good">
|
||||
{specificChem.volume} units of {specificChem.name}
|
||||
</Box>
|
||||
),
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Button, Section } from '../../components';
|
||||
|
||||
|
||||
export const SleeperPurgeChems = (props, context) => {
|
||||
const { chems, act } = props;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Purge Chemicals">
|
||||
{chems.map(chem => (
|
||||
<Button
|
||||
key={chem.name}
|
||||
content={chem.name}
|
||||
disabled={!(chem.allowed)}
|
||||
width="140px"
|
||||
onClick={() => act('purge', {
|
||||
chem: chem.id,
|
||||
})} />
|
||||
))}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Button, Section } from '../../components';
|
||||
|
||||
|
||||
export const SleeperSynthChems = (props, context) => {
|
||||
const { data, act } = props;
|
||||
const preSortSynth = data.synthchems || [];
|
||||
const synthchems = preSortSynth.sort((a, b) => {
|
||||
const descA = a.name.toLowerCase();
|
||||
const descB = b.name.toLowerCase();
|
||||
if (descA < descB) {
|
||||
return -1;
|
||||
}
|
||||
if (descA > descB) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Synthesize Chemicals">
|
||||
{synthchems.map(chem => (
|
||||
<Button
|
||||
key={chem.name}
|
||||
content={chem.name}
|
||||
width="140px"
|
||||
onClick={() => act('synth', {
|
||||
chem: chem.id,
|
||||
})} />
|
||||
))}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user