Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
24b069c
sleeper rework
SomeguyManperson Sep 2, 2021
9657d3d
stuff
SomeguyManperson Sep 2, 2021
455ed50
Update Sleeper.js
SomeguyManperson Sep 2, 2021
7f28047
Update Sleeper.js
SomeguyManperson Sep 2, 2021
fdd7761
Update Sleeper.js
SomeguyManperson Sep 2, 2021
ae12097
Update Sleeper.dm
SomeguyManperson Sep 2, 2021
46e935b
stasis now activates by stat
SomeguyManperson Sep 2, 2021
3be05a3
fix runtime when oipening sleeper
SomeguyManperson Sep 3, 2021
95e650e
adds some EXTREME POWERCREEP by making the chempurge option only purg…
SomeguyManperson Sep 3, 2021
a857a98
Update Sleeper.dm
SomeguyManperson Sep 3, 2021
95b9086
gives the clockwork sleeper access to all the shit since it healing o…
SomeguyManperson Sep 4, 2021
c07760b
clockwork sleeper can't be demoted to no stasis by zapping it with pa…
SomeguyManperson Sep 4, 2021
f50f1d3
actually properly hardcodes clockwork sleeper values
SomeguyManperson Sep 4, 2021
f13cdac
i am stuoipeid
SomeguyManperson Sep 4, 2021
0b2b055
undefines the defines
SomeguyManperson Sep 4, 2021
4afbfc7
fix a potential runtime when healing an organ that doesn't exist
SomeguyManperson Sep 4, 2021
ddd0b3d
increases the healing rate of the sleeper by 2 and makes it a define…
SomeguyManperson Sep 4, 2021
dc77864
Merge branch 'master' into tjeosnerfsmedbayagain
JamieD1 Sep 4, 2021
1fe9168
Fix merge from upstream master
SomeguyManperson Sep 5, 2021
1fa68f3
No chooms
SomeguyManperson Sep 5, 2021
0c23776
Might fix linter
SomeguyManperson Sep 5, 2021
bc55de7
chemical purging reduced from 1-4 to 0.5 to 2, putting it closer in l…
SomeguyManperson Sep 8, 2021
ec42ca2
Merge branch 'master' into tjeosnerfsmedbayagain
JamieD1 Sep 17, 2021
14a0423
adds an emag effect: people inside sleepers are constantly injected w…
SomeguyManperson Oct 11, 2021
c065dc1
whops
SomeguyManperson Oct 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 107 additions & 53 deletions code/game/machinery/Sleeper.dm
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#define SLEEPER_TEND "Treat Injuries"
#define SLEEPER_ORGANS "Repair Organs"
#define SLEEPER_CHEMPURGE "Purge Toxins"
#define SLEEPER_HEAL_RATE 2

/obj/machinery/sleep_console
name = "sleeper console"
icon = 'icons/obj/machines/sleeper.dmi'
Expand All @@ -13,27 +18,33 @@
state_open = TRUE
circuit = /obj/item/circuitboard/machine/sleeper

///efficiency, used to increase the effect of some healing methods
var/efficiency = 1
var/min_health = -25
var/list/available_chems
///maximum status stasis will activate at, occurs automatically
var/stasis_health = UNCONSCIOUS
///treatments currently available for use
var/list/available_treatments
///if the patient is able to use the sleeper's controls
var/controls_inside = FALSE
var/list/possible_chems = list(
list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/morphine, /datum/reagent/medicine/perfluorodecalin, /datum/reagent/medicine/c2/libital, /datum/reagent/medicine/c2/aiuri),
list(/datum/reagent/medicine/potass_iodide),
list(/datum/reagent/medicine/charcoal, /datum/reagent/medicine/salbutamol),
list(/datum/reagent/medicine/omnizine)
///treatments unlocked by manipulator by tier
var/list/treatments = list(
list(SLEEPER_TEND),
list(SLEEPER_ORGANS),
list(SLEEPER_CHEMPURGE),
list()
)
var/list/chem_buttons //Used when emagged to scramble which chem is used, eg: mutadone -> morphine
var/scrambled_chems = FALSE //Are chem buttons scrambled? used as a warning
var/enter_message = span_notice("<b>You feel cool air surround you. You go numb as your senses turn inward.</b>")
///the current active treatment
var/active_treatment = null
///if the sleeper puts its patient into stasis
var/stasis = FALSE
var/enter_message = "<span class='notice'><b>You feel cool air surround you. You go numb as your senses turn inward.</b></span>"
payment_department = ACCOUNT_MED
fair_market_price = 5

/obj/machinery/sleeper/Initialize()
. = ..()
occupant_typecache = GLOB.typecache_living
update_icon()
reset_chem_buttons()

/obj/machinery/sleeper/RefreshParts()
var/E
Expand All @@ -44,11 +55,12 @@
I += M.rating

efficiency = initial(efficiency)* E
min_health = initial(min_health) * E
available_chems = list()
available_treatments = list()
for(var/i in 1 to I)
available_chems |= possible_chems[i]
reset_chem_buttons()
if(!length(treatments[i]))
continue
available_treatments |= treatments[i]
stasis = (I >= 4)

/obj/machinery/sleeper/update_icon()
if(state_open)
Expand All @@ -71,6 +83,10 @@

/obj/machinery/sleeper/open_machine()
if(!state_open && !panel_open)
active_treatment = null
var/mob/living/mob_occupant = occupant
if(mob_occupant)
mob_occupant.remove_status_effect(STATUS_EFFECT_STASIS)
flick("[initial(icon_state)]-anim", src)
..()

Expand All @@ -81,6 +97,8 @@
var/mob/living/mob_occupant = occupant
if(mob_occupant && mob_occupant.stat != DEAD)
to_chat(occupant, "[enter_message]")
if(mob_occupant && stasis)
mob_occupant.ExtinguishMob()

/obj/machinery/sleeper/emp_act(severity)
. = ..()
Expand All @@ -89,6 +107,12 @@
if(is_operational() && occupant)
open_machine()

/obj/machinery/particle_accelerator/control_box/emag_act(mob/user)
if(obj_flags & EMAGGED)
return
to_chat(user, span_danger("You disable the chemical injection inhibitors on the sleeper..."))
obj_flags |= EMAGGED

/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user)
if(user.stat || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
Expand Down Expand Up @@ -157,6 +181,42 @@
/obj/machinery/sleeper/process()
..()
check_nap_violations()
var/mob/living/carbon/C = occupant
if(C)
if(stasis && C.stat >= stasis_health)
C.apply_status_effect(STATUS_EFFECT_STASIS, null, TRUE)
else
C.remove_status_effect(STATUS_EFFECT_STASIS)
if(obj_flags & EMAGGED)
var/existing = C.reagents.get_reagent_amount(/datum/reagent/toxin/amanitin)
C.reagents.add_reagent(/datum/reagent/toxin/amanitin, max(0, 1 - existing)) //this should be enough that you immediately eat shit on exiting but not before
switch(active_treatment)
if(SLEEPER_TEND)
C.heal_bodypart_damage(SLEEPER_HEAL_RATE,SLEEPER_HEAL_RATE) //this is slow as hell, use the rest of medbay you chumps
if(SLEEPER_ORGANS)
var/heal_reps = efficiency * 2
var/list/organs = list(ORGAN_SLOT_EARS,ORGAN_SLOT_EYES,ORGAN_SLOT_LIVER,ORGAN_SLOT_LUNGS,ORGAN_SLOT_STOMACH,ORGAN_SLOT_HEART)
for(var/i in 1 to heal_reps)
organs = shuffle(organs)
for(var/o in organs)
var/healed = FALSE
var/obj/item/organ/heal_target = C.getorganslot(o)
if(heal_target?.damage >= 1)
var/organ_healing = C.stat == DEAD ? 0.05 : 0.2
heal_target.applyOrganDamage(-organ_healing)
healed = TRUE
if(healed)
break
if(SLEEPER_CHEMPURGE)
C.adjustToxLoss(-SLEEPER_HEAL_RATE)
var/purge_rate = 0.5 * efficiency
for(var/datum/reagent/R in C.reagents.reagent_list)
if(istype(R, /datum/reagent/toxin))
C.reagents.remove_reagent(R.type,purge_rate)
if(R.overdosed)
C.reagents.remove_reagent(R.type,purge_rate)
else
active_treatment = null

/obj/machinery/sleeper/nap_violation(mob/violator)
open_machine()
Expand All @@ -166,11 +226,16 @@
data["knowledge"] = IS_MEDICAL(user)
data["occupied"] = occupant ? 1 : 0
data["open"] = state_open
data["active_treatment"] = active_treatment
data["can_sedate"] = can_sedate()

data["chems"] = list()
data["treatments"] = list()
for(var/T in available_treatments)
data["treatments"] += T
/*data["chems"] = list()
for(var/chem in available_chems)
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
data["chems"] += list(list("name" = R.name, "id" = R.type, "allowed" = chem_allowed(chem), "desc" = R.description))
data["chems"] += list(list("name" = R.name, "id" = R.type, "allowed" = chem_allowed(chem), "desc" = R.description))*/

data["occupant"] = list()
var/mob/living/mob_occupant = occupant
Expand Down Expand Up @@ -216,48 +281,27 @@
else
open_machine()
. = TRUE
if("inject")
var/chem = text2path(params["chem"])
if(!is_operational() || !mob_occupant || isnull(chem))
return
if(mob_occupant.health < min_health && chem != /datum/reagent/medicine/epinephrine)
if("set")
var/treatment = params["treatment"]
if(!is_operational() || !mob_occupant || isnull(treatment))
return
if(inject_chem(chem, usr))
active_treatment = treatment
. = TRUE
if("sedate")
if(can_sedate())
mob_occupant.reagents.add_reagent(/datum/reagent/medicine/morphine, 10)
if(usr)
log_combat(usr,occupant, "injected morphine into", addition = "via [src]")
. = TRUE
if(scrambled_chems && prob(5))
to_chat(usr, span_warning("Chemical system re-route detected, results may not be as expected!"))

/obj/machinery/sleeper/emag_act(mob/user)
scramble_chem_buttons()
to_chat(user, span_warning("You scramble the sleeper's user interface!"))

/obj/machinery/sleeper/proc/inject_chem(chem, mob/user)
if((chem in available_chems) && chem_allowed(chem))
occupant.reagents.add_reagent(chem_buttons[chem], 10) //emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU
if(user)
log_combat(user, occupant, "injected [chem] into", addition = "via [src]")
return TRUE

/obj/machinery/sleeper/proc/chem_allowed(chem)
/obj/machinery/sleeper/proc/can_sedate()
var/mob/living/mob_occupant = occupant
if(!mob_occupant || !mob_occupant.reagents)
return
var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency
var/occ_health = mob_occupant.health > min_health || chem == /datum/reagent/medicine/epinephrine
return amount && occ_health

/obj/machinery/sleeper/proc/reset_chem_buttons()
scrambled_chems = FALSE
LAZYINITLIST(chem_buttons)
for(var/chem in available_chems)
chem_buttons[chem] = chem

/obj/machinery/sleeper/proc/scramble_chem_buttons()
scrambled_chems = TRUE
var/list/av_chem = available_chems.Copy()
for(var/chem in av_chem)
chem_buttons[chem] = pick_n_take(av_chem) //no dupes, allow for random buttons to still be correct
return mob_occupant.reagents.get_reagent_amount(/datum/reagent/medicine/morphine) + 10 <= 20

/obj/machinery/sleeper/emag_act(mob/user)
to_chat(user, "<span class='warning'>You scramble the sleeper's user interface!</span>")

/obj/machinery/sleeper/syndie
icon_state = "sleeper_s"
Expand All @@ -278,7 +322,9 @@
desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."
icon_state = "sleeper_clockwork"
enter_message = "<span class='bold inathneq_small'>You hear the gentle hum and click of machinery, and are lulled into a sense of peace.</span>"
possible_chems = list(list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane, /datum/reagent/medicine/oculine, /datum/reagent/medicine/inacusiate, /datum/reagent/medicine/mannitol))
efficiency = 3
available_treatments = list(SLEEPER_TEND, SLEEPER_ORGANS, SLEEPER_CHEMPURGE)
stasis = TRUE

/obj/machinery/sleeper/clockwork/process()
if(occupant && isliving(occupant))
Expand All @@ -289,5 +335,13 @@
L.adjustFireLoss(-1)
L.adjustOxyLoss(-5)

/obj/machinery/sleeper/clockwork/RefreshParts()
return

/obj/machinery/sleeper/old
icon_state = "oldpod"

#undef SLEEPER_TEND
#undef SLEEPER_ORGANS
#undef SLEEPER_CHEMPURGE
#undef SLEEPER_HEAL_RATE
32 changes: 24 additions & 8 deletions tgui/packages/tgui/interfaces/Sleeper.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ export const Sleeper = (props, context) => {
open,
occupant = {},
occupied,
active_treatment,
can_sedate,
} = data;

const chems = data.chems || [];
const treatments = data.treatments || [];

const damageTypes = [
{
Expand Down Expand Up @@ -86,7 +88,16 @@ export const Sleeper = (props, context) => {
)}
</Section>
{!!occupied && (
<Section title="Reagents" minHeight="50px">
<Section
title="Reagents"
minHeight="50px"
buttons={(
<Button
icon={'flask'}
content={'Sedate'}
disabled={!can_sedate}
onClick={() => act('sedate')} />
)} >
{occupant.reagents.map(reagent => (
<Box key={reagent.name}>
{reagent.name} -
Expand All @@ -101,25 +112,30 @@ export const Sleeper = (props, context) => {
</Section>
)}
<Section
title="Medicines"
title="Treatments"
minHeight="205px"
buttons={(
<Button
icon={open ? 'door-open' : 'door-closed'}
content={open ? 'Open' : 'Closed'}
onClick={() => act('door')} />
)}>
{chems.map(chem => (
{treatments.map(treatment => (
<Button
key={chem.name}
key={treatment}
icon="first-aid"
content={treatment}
disabled={!occupied}
color={active_treatment===treatment ? 'green' : null}
/* key={chem.name}
icon="flask"
tooltip={data.knowledge ? chem.desc : "You don\'t know what this chemical does!"}
tooltipPosition="top"
content={chem.name}
disabled={!(occupied && chem.allowed)}
disabled={!(occupied && chem.allowed)}*/
width="350px"
onClick={() => act('inject', {
chem: chem.id,
onClick={() => act('set', {
treatment: treatment,
})}
/>
))}
Expand Down