|
|
|
|
@@ -1,155 +1,3 @@
|
|
|
|
|
/////////////////////////////////////////
|
|
|
|
|
// SLEEPER CONSOLE
|
|
|
|
|
/////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleep_console
|
|
|
|
|
name = "Sleeper Console"
|
|
|
|
|
icon = 'icons/obj/Cryogenic2.dmi'
|
|
|
|
|
icon_state = "sleeperconsole"
|
|
|
|
|
var/obj/machinery/sleeper/connected = null
|
|
|
|
|
anchored = 1 //About time someone fixed this.
|
|
|
|
|
density = 1
|
|
|
|
|
var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r"
|
|
|
|
|
|
|
|
|
|
use_power = 1
|
|
|
|
|
idle_power_usage = 40
|
|
|
|
|
interact_offline = 1
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleep_console/process()
|
|
|
|
|
if(stat & (NOPOWER|BROKEN))
|
|
|
|
|
return
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleep_console/ex_act(severity)
|
|
|
|
|
switch(severity)
|
|
|
|
|
if(1.0)
|
|
|
|
|
//SN src = null
|
|
|
|
|
qdel(src)
|
|
|
|
|
return
|
|
|
|
|
if(2.0)
|
|
|
|
|
if (prob(50))
|
|
|
|
|
//SN src = null
|
|
|
|
|
qdel(src)
|
|
|
|
|
return
|
|
|
|
|
else
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleep_console/New()
|
|
|
|
|
..()
|
|
|
|
|
spawn( 5 )
|
|
|
|
|
if(orient == "RIGHT")
|
|
|
|
|
icon_state = "sleeperconsole-r"
|
|
|
|
|
src.connected = locate(/obj/machinery/sleeper, get_step(src, EAST))
|
|
|
|
|
else
|
|
|
|
|
src.connected = locate(/obj/machinery/sleeper, get_step(src, WEST))
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleep_console/attack_ai(mob/user as mob)
|
|
|
|
|
return src.attack_hand(user)
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleep_console/attack_hand(mob/user as mob)
|
|
|
|
|
if(..())
|
|
|
|
|
return
|
|
|
|
|
if(stat & (NOPOWER|BROKEN))
|
|
|
|
|
return
|
|
|
|
|
var/dat = ""
|
|
|
|
|
if (!src.connected || (connected.stat & (NOPOWER|BROKEN)))
|
|
|
|
|
dat += "This console is not connected to a sleeper or the sleeper is non-functional."
|
|
|
|
|
else
|
|
|
|
|
var/mob/living/occupant = src.connected.occupant
|
|
|
|
|
dat += "<font color='blue'><B>Occupant Statistics:</B></FONT><BR>"
|
|
|
|
|
if (occupant)
|
|
|
|
|
var/t1
|
|
|
|
|
switch(occupant.stat)
|
|
|
|
|
if(0)
|
|
|
|
|
t1 = "Conscious"
|
|
|
|
|
if(1)
|
|
|
|
|
t1 = "<font color='blue'>Unconscious</font>"
|
|
|
|
|
if(2)
|
|
|
|
|
t1 = "<font color='red'>*dead*</font>"
|
|
|
|
|
else
|
|
|
|
|
dat += text("[]\tHealth %: [] ([])</FONT><BR>", (occupant.health > 50 ? "<font color='blue'>" : "<font color='red'>"), occupant.health, t1)
|
|
|
|
|
if(iscarbon(occupant))
|
|
|
|
|
var/mob/living/carbon/C = occupant
|
|
|
|
|
dat += text("[]\t-Pulse, bpm: []</FONT><BR>", (C.pulse == PULSE_NONE || C.pulse == PULSE_THREADY ? "<font color='red'>" : "<font color='blue'>"), C.get_pulse(GETPULSE_TOOL))
|
|
|
|
|
dat += text("[]\t-Brute Damage %: []</FONT><BR>", (occupant.getBruteLoss() < 60 ? "<font color='blue'>" : "<font color='red'>"), occupant.getBruteLoss())
|
|
|
|
|
dat += text("[]\t-Respiratory Damage %: []</FONT><BR>", (occupant.getOxyLoss() < 60 ? "<font color='blue'>" : "<font color='red'>"), occupant.getOxyLoss())
|
|
|
|
|
dat += text("[]\t-Toxin Content %: []</FONT><BR>", (occupant.getToxLoss() < 60 ? "<font color='blue'>" : "<font color='red'>"), occupant.getToxLoss())
|
|
|
|
|
dat += text("[]\t-Burn Severity %: []</FONT><BR>", (occupant.getFireLoss() < 60 ? "<font color='blue'>" : "<font color='red'>"), occupant.getFireLoss())
|
|
|
|
|
dat += text("<HR>Paralysis Summary %: [] ([] seconds left!)<BR>", occupant.paralysis, round(occupant.paralysis / 4))
|
|
|
|
|
if(occupant.reagents)
|
|
|
|
|
for(var/chemical in connected.available_chemicals)
|
|
|
|
|
dat += "[connected.available_chemicals[chemical]]: [occupant.reagents.get_reagent_amount(chemical)] units<br>"
|
|
|
|
|
dat += "<A href='?src=\ref[src];refresh=1'>Refresh Meter Readings</A><BR>"
|
|
|
|
|
if(src.connected.beaker)
|
|
|
|
|
dat += "<HR><A href='?src=\ref[src];removebeaker=1'>Remove Beaker</A><BR>"
|
|
|
|
|
if(src.connected.filtering)
|
|
|
|
|
dat += "<A href='?src=\ref[src];togglefilter=1'>Stop Dialysis</A><BR>"
|
|
|
|
|
dat += text("Output Beaker has [] units of free space remaining<BR><HR>", src.connected.beaker.reagents.maximum_volume - src.connected.beaker.reagents.total_volume)
|
|
|
|
|
else
|
|
|
|
|
dat += "<HR><A href='?src=\ref[src];togglefilter=1'>Start Dialysis</A><BR>"
|
|
|
|
|
dat += text("Output Beaker has [] units of free space remaining<BR><HR>", src.connected.beaker.reagents.maximum_volume - src.connected.beaker.reagents.total_volume)
|
|
|
|
|
else
|
|
|
|
|
dat += "<HR>No Dialysis Output Beaker is present.<BR><HR>"
|
|
|
|
|
|
|
|
|
|
for(var/chemical in connected.available_chemicals)
|
|
|
|
|
dat += "Inject [connected.available_chemicals[chemical]]: "
|
|
|
|
|
for(var/amount in connected.amounts)
|
|
|
|
|
dat += "<a href ='?src=\ref[src];chemical=[chemical];amount=[amount]'>[amount] units</a><br> "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dat += "<HR><A href='?src=\ref[src];ejectify=1'>Eject Patient</A>"
|
|
|
|
|
else
|
|
|
|
|
dat += "The sleeper is empty."
|
|
|
|
|
dat += text("<BR><BR><A href='?src=\ref[];mach_close=sleeper'>Close</A>", user)
|
|
|
|
|
user << browse(dat, "window=sleeper;size=400x500")
|
|
|
|
|
onclose(user, "sleeper")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleep_console/Topic(href, href_list)
|
|
|
|
|
if(..())
|
|
|
|
|
return
|
|
|
|
|
if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
|
|
|
|
|
usr.set_machine(src)
|
|
|
|
|
if (href_list["chemical"])
|
|
|
|
|
if (src.connected)
|
|
|
|
|
if (src.connected.occupant)
|
|
|
|
|
if (src.connected.occupant.stat == DEAD)
|
|
|
|
|
usr << "<span class='danger'>This person has no life for to preserve anymore. Take them to a department capable of reanimating them.</span>"
|
|
|
|
|
else if(src.connected.occupant.health > 0 || href_list["chemical"] == "inaprovaline")
|
|
|
|
|
src.connected.inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"]))
|
|
|
|
|
else
|
|
|
|
|
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>"
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
if (href_list["refresh"])
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
if (href_list["removebeaker"])
|
|
|
|
|
src.connected.remove_beaker()
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
if (href_list["togglefilter"])
|
|
|
|
|
src.connected.toggle_filter()
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
if (href_list["ejectify"])
|
|
|
|
|
src.connected.eject()
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
src.add_fingerprint(usr)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////
|
|
|
|
|
// THE SLEEPER ITSELF
|
|
|
|
|
/////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper
|
|
|
|
|
name = "Sleeper"
|
|
|
|
|
desc = "A fancy bed with built-in injectors, a dialysis machine, and a limited health scanner."
|
|
|
|
|
@@ -159,8 +7,7 @@
|
|
|
|
|
anchored = 1
|
|
|
|
|
var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r"
|
|
|
|
|
var/mob/living/carbon/human/occupant = null
|
|
|
|
|
var/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin")
|
|
|
|
|
var/amounts = list(5, 10)
|
|
|
|
|
var/list/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin")
|
|
|
|
|
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
|
|
|
|
var/filtering = 0
|
|
|
|
|
|
|
|
|
|
@@ -168,269 +15,261 @@
|
|
|
|
|
idle_power_usage = 15
|
|
|
|
|
active_power_usage = 200 //builtin health analyzer, dialysis machine, injectors.
|
|
|
|
|
|
|
|
|
|
New()
|
|
|
|
|
..()
|
|
|
|
|
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
|
|
|
|
|
spawn( 5 )
|
|
|
|
|
if(orient == "RIGHT")
|
|
|
|
|
icon_state = "sleeper_0-r"
|
|
|
|
|
return
|
|
|
|
|
/obj/machinery/sleeper/New()
|
|
|
|
|
..()
|
|
|
|
|
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
|
|
|
|
|
spawn(5)
|
|
|
|
|
update_icon()
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/process()
|
|
|
|
|
if(stat & (NOPOWER|BROKEN))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
process()
|
|
|
|
|
if (stat & (NOPOWER|BROKEN))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(filtering > 0)
|
|
|
|
|
if(beaker)
|
|
|
|
|
if(beaker.reagents.total_volume < beaker.reagents.maximum_volume)
|
|
|
|
|
var/pumped = 0
|
|
|
|
|
for(var/datum/reagent/x in src.occupant.reagents.reagent_list)
|
|
|
|
|
src.occupant.reagents.trans_to_obj(beaker, 3)
|
|
|
|
|
pumped++
|
|
|
|
|
if (ishuman(src.occupant))
|
|
|
|
|
src.occupant.vessel.trans_to_obj(beaker, pumped + 1)
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
blob_act()
|
|
|
|
|
if(prob(75))
|
|
|
|
|
for(var/atom/movable/A as mob|obj in src)
|
|
|
|
|
A.loc = src.loc
|
|
|
|
|
A.blob_act()
|
|
|
|
|
qdel(src)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
attackby(var/obj/item/weapon/G as obj, var/mob/user as mob)
|
|
|
|
|
if(istype(G, /obj/item/weapon/reagent_containers/glass))
|
|
|
|
|
if(!beaker)
|
|
|
|
|
beaker = G
|
|
|
|
|
user.drop_item()
|
|
|
|
|
G.loc = src
|
|
|
|
|
user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!")
|
|
|
|
|
src.updateUsrDialog()
|
|
|
|
|
return
|
|
|
|
|
else
|
|
|
|
|
user << "<span class='warning'>The sleeper has a beaker already.</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
else if(istype(G, /obj/item/weapon/grab))
|
|
|
|
|
if(!ismob(G:affecting))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(src.occupant)
|
|
|
|
|
user << "<span class='warning'>The sleeper is already occupied!</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
for(var/mob/living/carbon/slime/M in range(1,G:affecting))
|
|
|
|
|
if(M.Victim == G:affecting)
|
|
|
|
|
usr << "[G:affecting.name] will not fit into the sleeper because they have a slime latched onto their head."
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
visible_message("[user] starts putting [G:affecting:name] into the sleeper.", 3)
|
|
|
|
|
|
|
|
|
|
if(do_after(user, 20))
|
|
|
|
|
if(src.occupant)
|
|
|
|
|
user << "<span class='warning'>The sleeper is already occupied!</span>"
|
|
|
|
|
return
|
|
|
|
|
if(!G || !G:affecting) return
|
|
|
|
|
var/mob/M = G:affecting
|
|
|
|
|
if(M.client)
|
|
|
|
|
M.client.perspective = EYE_PERSPECTIVE
|
|
|
|
|
M.client.eye = src
|
|
|
|
|
M.loc = src
|
|
|
|
|
update_use_power(2)
|
|
|
|
|
src.occupant = M
|
|
|
|
|
src.icon_state = "sleeper_1"
|
|
|
|
|
if(orient == "RIGHT")
|
|
|
|
|
icon_state = "sleeper_1-r"
|
|
|
|
|
|
|
|
|
|
src.add_fingerprint(user)
|
|
|
|
|
qdel(G)
|
|
|
|
|
return
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ex_act(severity)
|
|
|
|
|
if(filtering)
|
|
|
|
|
toggle_filter()
|
|
|
|
|
switch(severity)
|
|
|
|
|
if(1.0)
|
|
|
|
|
for(var/atom/movable/A as mob|obj in src)
|
|
|
|
|
A.loc = src.loc
|
|
|
|
|
ex_act(severity)
|
|
|
|
|
qdel(src)
|
|
|
|
|
return
|
|
|
|
|
if(2.0)
|
|
|
|
|
if(prob(50))
|
|
|
|
|
for(var/atom/movable/A as mob|obj in src)
|
|
|
|
|
A.loc = src.loc
|
|
|
|
|
ex_act(severity)
|
|
|
|
|
qdel(src)
|
|
|
|
|
return
|
|
|
|
|
if(3.0)
|
|
|
|
|
if(prob(25))
|
|
|
|
|
for(var/atom/movable/A as mob|obj in src)
|
|
|
|
|
A.loc = src.loc
|
|
|
|
|
ex_act(severity)
|
|
|
|
|
qdel(src)
|
|
|
|
|
return
|
|
|
|
|
return
|
|
|
|
|
emp_act(severity)
|
|
|
|
|
if(filtering)
|
|
|
|
|
toggle_filter()
|
|
|
|
|
if(stat & (BROKEN|NOPOWER))
|
|
|
|
|
..(severity)
|
|
|
|
|
return
|
|
|
|
|
if(occupant)
|
|
|
|
|
go_out()
|
|
|
|
|
..(severity)
|
|
|
|
|
|
|
|
|
|
alter_health(mob/living/M as mob)
|
|
|
|
|
if (M.health > 0)
|
|
|
|
|
if (M.getOxyLoss() >= 10)
|
|
|
|
|
var/amount = max(0.15, 1)
|
|
|
|
|
M.adjustOxyLoss(-amount)
|
|
|
|
|
else
|
|
|
|
|
M.adjustOxyLoss(-12)
|
|
|
|
|
M.updatehealth()
|
|
|
|
|
M.AdjustParalysis(-4)
|
|
|
|
|
M.AdjustWeakened(-4)
|
|
|
|
|
M.AdjustStunned(-4)
|
|
|
|
|
M.Paralyse(1)
|
|
|
|
|
M.Weaken(1)
|
|
|
|
|
M.Stun(1)
|
|
|
|
|
if (M:reagents.get_reagent_amount("inaprovaline") < 5)
|
|
|
|
|
M:reagents.add_reagent("inaprovaline", 5)
|
|
|
|
|
return
|
|
|
|
|
proc/toggle_filter()
|
|
|
|
|
if(!src.occupant)
|
|
|
|
|
filtering = 0
|
|
|
|
|
return
|
|
|
|
|
if(filtering)
|
|
|
|
|
filtering = 0
|
|
|
|
|
else
|
|
|
|
|
filtering = 1
|
|
|
|
|
|
|
|
|
|
proc/go_out()
|
|
|
|
|
if(filtering)
|
|
|
|
|
toggle_filter()
|
|
|
|
|
if(!src.occupant)
|
|
|
|
|
return
|
|
|
|
|
if(src.occupant.client)
|
|
|
|
|
src.occupant.client.eye = src.occupant.client.mob
|
|
|
|
|
src.occupant.client.perspective = MOB_PERSPECTIVE
|
|
|
|
|
src.occupant.loc = src.loc
|
|
|
|
|
src.occupant = null
|
|
|
|
|
update_use_power(1)
|
|
|
|
|
if(orient == "RIGHT")
|
|
|
|
|
icon_state = "sleeper_0-r"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc/inject_chemical(mob/living/user as mob, chemical, amount)
|
|
|
|
|
if (stat & (BROKEN|NOPOWER))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(src.occupant && src.occupant.reagents)
|
|
|
|
|
if(src.occupant.reagents.get_reagent_amount(chemical) + amount <= 20)
|
|
|
|
|
use_power(amount * CHEM_SYNTH_ENERGY)
|
|
|
|
|
src.occupant.reagents.add_reagent(chemical, amount)
|
|
|
|
|
user << "Occupant now has [src.occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in his/her bloodstream."
|
|
|
|
|
return
|
|
|
|
|
user << "There's no occupant in the sleeper or the subject has too many chemicals!"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
proc/check(mob/living/user as mob)
|
|
|
|
|
if(src.occupant)
|
|
|
|
|
user << text("<span class='notice'><B>Occupant ([]) Statistics:</B></span>", src.occupant)
|
|
|
|
|
var/t1
|
|
|
|
|
switch(src.occupant.stat)
|
|
|
|
|
if(0.0)
|
|
|
|
|
t1 = "Conscious"
|
|
|
|
|
if(1.0)
|
|
|
|
|
t1 = "Unconscious"
|
|
|
|
|
if(2.0)
|
|
|
|
|
t1 = "*dead*"
|
|
|
|
|
else
|
|
|
|
|
user << text("<span class='[]'>\t Health %: [] ([])</span>", (src.occupant.health > 50 ? "notice" : "warning"), src.occupant.health, t1)
|
|
|
|
|
user << text("<span class='[]'>\t -Core Temperature: []°C ([]°F)</span>", (src.occupant.bodytemperature > 50 ? "notice" : "warning"), src.occupant.bodytemperature-T0C, src.occupant.bodytemperature*1.8-459.67)
|
|
|
|
|
user << text("<span class='[]'>\t -Brute Damage %: []</span>", (src.occupant.getBruteLoss() < 60 ? "notice" : "warning"), src.occupant.getBruteLoss())
|
|
|
|
|
user << text("<span class='[]'>\t -Respiratory Damage %: []</span>", (src.occupant.getOxyLoss() < 60 ? "notice" : "warning"), src.occupant.getOxyLoss())
|
|
|
|
|
user << text("<span class='[]'>\t -Toxin Content %: []</span>", (src.occupant.getToxLoss() < 60 ? "notice" : "warning"), src.occupant.getToxLoss())
|
|
|
|
|
user << text("<span class='[]'>\t -Burn Severity %: []</span>", (src.occupant.getFireLoss() < 60 ? "notice" : "warning"), src.occupant.getFireLoss())
|
|
|
|
|
user << "<span class='notice'>Expected time till occupant can safely awake: (note: If health is below 20% these times are inaccurate)</span>"
|
|
|
|
|
user << text("<span class='notice'>\t [] second\s (if around 1 or 2 the sleeper is keeping them asleep.)</span>", src.occupant.paralysis / 5)
|
|
|
|
|
if(src.beaker)
|
|
|
|
|
user << text("<span class='notice'>\t Dialysis Output Beaker has [] of free space remaining.</span>", src.beaker.reagents.maximum_volume - src.beaker.reagents.total_volume)
|
|
|
|
|
else
|
|
|
|
|
user << "<span class='notice'>No Dialysis Output Beaker loaded.</span>"
|
|
|
|
|
else
|
|
|
|
|
user << "<span class='notice'>There is no one inside!</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
verb/eject()
|
|
|
|
|
set name = "Eject Sleeper"
|
|
|
|
|
set category = "Object"
|
|
|
|
|
set src in oview(1)
|
|
|
|
|
if(usr.stat != 0)
|
|
|
|
|
return
|
|
|
|
|
if(orient == "RIGHT")
|
|
|
|
|
icon_state = "sleeper_0-r"
|
|
|
|
|
src.icon_state = "sleeper_0"
|
|
|
|
|
src.go_out()
|
|
|
|
|
add_fingerprint(usr)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
verb/remove_beaker()
|
|
|
|
|
set name = "Remove Beaker"
|
|
|
|
|
set category = "Object"
|
|
|
|
|
set src in oview(1)
|
|
|
|
|
if(usr.stat != 0)
|
|
|
|
|
return
|
|
|
|
|
if(filtering > 0)
|
|
|
|
|
if(beaker)
|
|
|
|
|
filtering = 0
|
|
|
|
|
beaker.loc = usr.loc
|
|
|
|
|
beaker = null
|
|
|
|
|
add_fingerprint(usr)
|
|
|
|
|
if(beaker.reagents.total_volume < beaker.reagents.maximum_volume)
|
|
|
|
|
var/pumped = 0
|
|
|
|
|
for(var/datum/reagent/x in occupant.reagents.reagent_list)
|
|
|
|
|
occupant.reagents.trans_to_obj(beaker, 3)
|
|
|
|
|
pumped++
|
|
|
|
|
if(ishuman(occupant))
|
|
|
|
|
occupant.vessel.trans_to_obj(beaker, pumped + 1)
|
|
|
|
|
else
|
|
|
|
|
toggle_filter()
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/update_icon()
|
|
|
|
|
icon_state = "sleeper_[occupant ? "1" : "0"][orient == "RIGHT" ? "-r" : ""]"
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/attack_hand(var/mob/user)
|
|
|
|
|
if(..())
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
verb/move_inside()
|
|
|
|
|
set name = "Enter Sleeper"
|
|
|
|
|
set category = "Object"
|
|
|
|
|
set src in oview(1)
|
|
|
|
|
ui_interact(user)
|
|
|
|
|
|
|
|
|
|
if(usr.stat != 0 || !(ishuman(usr) || issmall(usr)))
|
|
|
|
|
return
|
|
|
|
|
/obj/machinery/sleeper/ui_interact(var/mob/user, var/ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = outside_state)
|
|
|
|
|
var/data[0]
|
|
|
|
|
|
|
|
|
|
if(src.occupant)
|
|
|
|
|
usr << "<span class='warning'>The sleeper is already occupied!</span>"
|
|
|
|
|
return
|
|
|
|
|
data["power"] = stat & (NOPOWER|BROKEN) ? 0 : 1
|
|
|
|
|
|
|
|
|
|
for(var/mob/living/carbon/slime/M in range(1,usr))
|
|
|
|
|
if(M.Victim == usr)
|
|
|
|
|
usr << "You're too busy getting your life sucked out of you."
|
|
|
|
|
return
|
|
|
|
|
visible_message("[usr] starts climbing into the sleeper.", 3)
|
|
|
|
|
if(do_after(usr, 20))
|
|
|
|
|
if(src.occupant)
|
|
|
|
|
usr << "<span class='warning'>The sleeper is already occupied!</span>"
|
|
|
|
|
return
|
|
|
|
|
usr.stop_pulling()
|
|
|
|
|
usr.client.perspective = EYE_PERSPECTIVE
|
|
|
|
|
usr.client.eye = src
|
|
|
|
|
usr.loc = src
|
|
|
|
|
update_use_power(2)
|
|
|
|
|
src.occupant = usr
|
|
|
|
|
src.icon_state = "sleeper_1"
|
|
|
|
|
if(orient == "RIGHT")
|
|
|
|
|
icon_state = "sleeper_1-r"
|
|
|
|
|
var/list/reagents = list()
|
|
|
|
|
for(var/T in available_chemicals)
|
|
|
|
|
var/list/reagent = list()
|
|
|
|
|
reagent["id"] = T
|
|
|
|
|
reagent["name"] = available_chemicals[T]
|
|
|
|
|
if(occupant)
|
|
|
|
|
reagent["amount"] = occupant.reagents.get_reagent_amount(T)
|
|
|
|
|
reagents += list(reagent)
|
|
|
|
|
data["reagents"] = reagents.Copy()
|
|
|
|
|
|
|
|
|
|
for(var/obj/O in src)
|
|
|
|
|
qdel(O)
|
|
|
|
|
src.add_fingerprint(usr)
|
|
|
|
|
return
|
|
|
|
|
if(occupant)
|
|
|
|
|
data["occupant"] = 1
|
|
|
|
|
switch(occupant.stat)
|
|
|
|
|
if(CONSCIOUS)
|
|
|
|
|
data["stat"] = "Conscious"
|
|
|
|
|
if(UNCONSCIOUS)
|
|
|
|
|
data["stat"] = "Unconscious"
|
|
|
|
|
if(DEAD)
|
|
|
|
|
data["stat"] = "<font color='red'>dead</font>"
|
|
|
|
|
data["health"] = occupant.health
|
|
|
|
|
if(iscarbon(occupant))
|
|
|
|
|
var/mob/living/carbon/C = occupant
|
|
|
|
|
data["pulse"] = C.get_pulse(GETPULSE_TOOL)
|
|
|
|
|
data["brute"] = occupant.getBruteLoss()
|
|
|
|
|
data["burn"] = occupant.getFireLoss()
|
|
|
|
|
data["oxy"] = occupant.getOxyLoss()
|
|
|
|
|
data["tox"] = occupant.getToxLoss()
|
|
|
|
|
else
|
|
|
|
|
data["occupant"] = 0
|
|
|
|
|
if(beaker)
|
|
|
|
|
data["beaker"] = beaker.reagents.get_free_space()
|
|
|
|
|
else
|
|
|
|
|
data["beaker"] = -1
|
|
|
|
|
data["filtering"] = filtering
|
|
|
|
|
|
|
|
|
|
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
|
|
|
if(!ui)
|
|
|
|
|
ui = new(user, src, ui_key, "sleeper.tmpl", "Sleeper UI", 600, 600, state = state)
|
|
|
|
|
ui.set_initial_data(data)
|
|
|
|
|
ui.open()
|
|
|
|
|
ui.set_auto_update(1)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
[17:55] GinjaNinja32 https://github.com/Baystation12/Baystation12/tree/dev-freeze/code/modules/nano/interaction
|
|
|
|
|
[17:55] NanoTrasen_Inc Ginja: Baystation12/code/modules/nano/interaction at dev-freeze · Baystation12/Baystation12 · GitHub
|
|
|
|
|
[17:55] PsiOmegaDelta Hmm
|
|
|
|
|
[17:55] Kelenius I suppose I could send a parameter to NanoUI and blank out the UI
|
|
|
|
|
[17:56] GinjaNinja32 use a topic state
|
|
|
|
|
[17:56] Kelenius blinks cluelessly
|
|
|
|
|
[17:56] GinjaNinja32 look at what I just linked
|
|
|
|
|
[17:57] PsiOmegaDelta What you probably want to do is extend nano/interaction/default.dm
|
|
|
|
|
[17:57] PsiOmegaDelta And override mob/living/default_can_use_topic()
|
|
|
|
|
[17:57] PsiOmegaDelta Have it first check if src is inside src_object, if so return STATUS_CLOSE
|
|
|
|
|
[17:58] PsiOmegaDelta Otherwise, return ..()
|
|
|
|
|
[17:57] PsiOmegaDelta What you probably want to do is extend nano/interaction/default.dm
|
|
|
|
|
[17:57] PsiOmegaDelta And override mob/living/default_can_use_topic()
|
|
|
|
|
[17:57] PsiOmegaDelta Have it first check if src is inside src_object, if so return STATUS_CLOSE
|
|
|
|
|
[17:58] PsiOmegaDelta Otherwise, return ..()
|
|
|
|
|
[17:58] Azlier if you dont what i say ill start quoting kurt vonnegut and the art of war
|
|
|
|
|
[17:59] PsiOmegaDelta Then, at your ui = new(...) line
|
|
|
|
|
[17:59] PsiOmegaDelta Add the argument: state = new your_new_state()
|
|
|
|
|
[17:59] PsiOmegaDelta You can make it global as with the other state handlers tho
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[18:04] Kelenius So uh, I need return 1 at the end of Topic?
|
|
|
|
|
[18:04] Kelenius Or all returns in Topic must return 1?
|
|
|
|
|
[18:04] GinjaNinja32 return 1 for any call that did something that requires a UI update
|
|
|
|
|
[18:04] GinjaNinja32 well, anything that did something, really
|
|
|
|
|
[18:04] Kelenius Do I need to up nanomanager.update_uis(src) if I do return 1?
|
|
|
|
|
[18:04] GinjaNinja32 no
|
|
|
|
|
[18:05] Kelenius Where do I need it?
|
|
|
|
|
[18:05] GinjaNinja32 nowhere
|
|
|
|
|
[18:05] Kelenius How about process()?
|
|
|
|
|
[18:05] GinjaNinja32 unless a change comes through that's not from Topic() that needs an update sent through
|
|
|
|
|
[18:05] Kelenius Because a sleeper needs to update every tick
|
|
|
|
|
[18:06] GinjaNinja32 nanoui will call ui_interact() every tick
|
|
|
|
|
[18:06] PsiOmegaDelta If you've set ui.set_auto_update(1) it will update every tick
|
|
|
|
|
[18:06] PsiOmegaDelta Or as often as the NanoUI process runs anyway
|
|
|
|
|
[18:06] Kelenius Where do I need to set it? In UI creation?
|
|
|
|
|
[18:06] Mloc yes
|
|
|
|
|
[18:06] Mloc I told you this
|
|
|
|
|
[18:06] Mloc
|
|
|
|
|
[18:06] PsiOmegaDelta You basically have the lines
|
|
|
|
|
[18:06] PsiOmegaDelta ui = new(...)
|
|
|
|
|
[18:06] PsiOmegaDelta ui.set_initial_data(data)
|
|
|
|
|
[18:07] PsiOmegaDelta ui.open()
|
|
|
|
|
[18:07] PsiOmegaDelta ui.set_auto_update(1)
|
|
|
|
|
[18:07] PsiOmegaDelta Auto-refresh go
|
|
|
|
|
[18:07] Mloc with an if(!ui) first
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/Topic(href, href_list)
|
|
|
|
|
if(..())
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(usr == occupant)
|
|
|
|
|
usr << "<span class='warning'>You can't reach the controls from the inside.</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
add_fingerprint(usr)
|
|
|
|
|
|
|
|
|
|
if(href_list["eject"])
|
|
|
|
|
go_out()
|
|
|
|
|
if(href_list["beaker"])
|
|
|
|
|
remove_beaker()
|
|
|
|
|
if(href_list["filter"])
|
|
|
|
|
toggle_filter()
|
|
|
|
|
if(href_list["chemical"] && href_list["amount"])
|
|
|
|
|
if(occupant && occupant.stat != DEAD)
|
|
|
|
|
if(href_list["chemical"] in available_chemicals) // Your hacks are bad and you should feel bad
|
|
|
|
|
inject_chemical(usr, href_list["chemical"], text2num(href_list["amount"]))
|
|
|
|
|
|
|
|
|
|
return 1
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/attack_ai(var/mob/user)
|
|
|
|
|
return attack_hand(user)
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/attackby(var/obj/item/I, var/mob/user)
|
|
|
|
|
add_fingerprint(user)
|
|
|
|
|
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
|
|
|
|
if(!beaker)
|
|
|
|
|
beaker = I
|
|
|
|
|
user.drop_item()
|
|
|
|
|
I.loc = src
|
|
|
|
|
user.visible_message("<span class='notice'>[user] adds \a [I] to \the [src].</span>", "<span class='notice'>You add \a [I] to \the [src].</span>")
|
|
|
|
|
else
|
|
|
|
|
user << "<span class='warning'>\The [src] has a beaker already.</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/MouseDrop_T(var/mob/target, var/mob/user)
|
|
|
|
|
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !ishuman(target))
|
|
|
|
|
return
|
|
|
|
|
go_in(target, user)
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/relaymove(var/mob/user)
|
|
|
|
|
..()
|
|
|
|
|
go_out()
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/emp_act(var/severity)
|
|
|
|
|
if(filtering)
|
|
|
|
|
toggle_filter()
|
|
|
|
|
|
|
|
|
|
if(stat & (BROKEN|NOPOWER))
|
|
|
|
|
..(severity)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(occupant)
|
|
|
|
|
go_out()
|
|
|
|
|
|
|
|
|
|
..(severity)
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/proc/toggle_filter()
|
|
|
|
|
if(!occupant || !beaker)
|
|
|
|
|
filtering = 0
|
|
|
|
|
return
|
|
|
|
|
if(filtering)
|
|
|
|
|
filtering = 0
|
|
|
|
|
else
|
|
|
|
|
filtering = 1
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/proc/go_in(var/mob/M, var/mob/user)
|
|
|
|
|
if(!M)
|
|
|
|
|
return
|
|
|
|
|
if(stat & (BROKEN|NOPOWER))
|
|
|
|
|
return
|
|
|
|
|
if(occupant)
|
|
|
|
|
user << "<span class='warning'>The sleeper is already occupied.</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(M == user)
|
|
|
|
|
visible_message("[user] starts climbing into \the [src].")
|
|
|
|
|
else
|
|
|
|
|
visible_message("[user] starts putting [M] into \the [src].")
|
|
|
|
|
|
|
|
|
|
if(do_after(user, 20))
|
|
|
|
|
if(occupant)
|
|
|
|
|
user << "<span class='warning'>The sleeper is already occupied.</span>"
|
|
|
|
|
return
|
|
|
|
|
M.stop_pulling()
|
|
|
|
|
if(M.client)
|
|
|
|
|
M.client.perspective = EYE_PERSPECTIVE
|
|
|
|
|
M.client.eye = src
|
|
|
|
|
M.loc = src
|
|
|
|
|
update_use_power(2)
|
|
|
|
|
occupant = M
|
|
|
|
|
update_icon()
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/proc/go_out()
|
|
|
|
|
if(!occupant)
|
|
|
|
|
return
|
|
|
|
|
if(occupant.client)
|
|
|
|
|
occupant.client.eye = occupant.client.mob
|
|
|
|
|
occupant.client.perspective = MOB_PERSPECTIVE
|
|
|
|
|
occupant.loc = loc
|
|
|
|
|
occupant = null
|
|
|
|
|
for(var/atom/movable/A in src) // In case an object was dropped inside or something
|
|
|
|
|
if(A == beaker)
|
|
|
|
|
continue
|
|
|
|
|
A.loc = loc
|
|
|
|
|
update_use_power(1)
|
|
|
|
|
update_icon()
|
|
|
|
|
toggle_filter()
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/proc/remove_beaker()
|
|
|
|
|
if(beaker)
|
|
|
|
|
beaker.loc = usr.loc
|
|
|
|
|
beaker = null
|
|
|
|
|
toggle_filter()
|
|
|
|
|
|
|
|
|
|
/obj/machinery/sleeper/proc/inject_chemical(var/mob/living/user, var/chemical, var/amount)
|
|
|
|
|
if(stat & (BROKEN|NOPOWER))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(occupant && occupant.reagents)
|
|
|
|
|
if(occupant.reagents.get_reagent_amount(chemical) + amount <= 20)
|
|
|
|
|
use_power(amount * CHEM_SYNTH_ENERGY)
|
|
|
|
|
occupant.reagents.add_reagent(chemical, amount)
|
|
|
|
|
user << "Occupant now has [occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in their bloodstream."
|
|
|
|
|
else
|
|
|
|
|
user << "The subject has too many chemicals."
|
|
|
|
|
else
|
|
|
|
|
user << "There's no suitable occupant in the sleeper."
|
|
|
|
|
|