diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index f69f5f6b2a..e2f999b0da 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -68,10 +68,12 @@ anchored = 1 circuit = /obj/item/weapon/circuitboard/sleeper var/mob/living/carbon/human/occupant = null - var/list/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin") + var/list/available_chemicals = list("inaprovaline" = "Inaprovaline", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin") var/obj/item/weapon/reagent_containers/glass/beaker = null var/filtering = 0 var/obj/machinery/sleep_console/console + var/stasis_level = 0 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1) + var/stasis_choices = list("Complete (1%)" = 100, "Deep (10%)" = 10, "Moderate (20%)" = 5, "Light (50%)" = 2, "None (100%)" = 0) use_power = 1 idle_power_usage = 15 @@ -98,18 +100,23 @@ /obj/machinery/sleeper/process() if(stat & (NOPOWER|BROKEN)) return + if(occupant) + occupant.Stasis(stasis_level) + if(stasis_level >= 100 && occupant.timeofdeath) + occupant.timeofdeath += 1 SECOND + + if(filtering > 0) + if(beaker) + 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() - if(filtering > 0) - if(beaker) - 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"]" @@ -154,6 +161,13 @@ data["beaker"] = -1 data["filtering"] = filtering + var/stasis_level_name = "Error!" + for(var/N in stasis_choices) + if(stasis_choices[N] == stasis_level) + stasis_level_name = N + break + data["stasis"] = stasis_level_name + 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) @@ -182,6 +196,10 @@ 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"])) + if(href_list["change_stasis"]) + var/new_stasis = input("Levels deeper than 50% metabolic rate will render the patient unconscious.","Stasis Level") as null|anything in stasis_choices + if(new_stasis && CanUseTopic(usr, default_state) == STATUS_INTERACTIVE) + stasis_level = stasis_choices[new_stasis] return 1 @@ -261,6 +279,7 @@ if(occupant.client) occupant.client.eye = occupant.client.mob occupant.client.perspective = MOB_PERSPECTIVE + occupant.Stasis(0) occupant.loc = src.loc occupant = null for(var/atom/movable/A in src) // In case an object was dropped inside or something diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 6441a5e72a..672a6a425b 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -534,7 +534,7 @@ time_entered = world.time if(ishuman(M) && applies_stasis) var/mob/living/carbon/human/H = M - H.in_stasis = 1 + H.Stasis(1000) // Book keeping! var/turf/location = get_turf(src) @@ -602,7 +602,7 @@ set_occupant(usr) if(ishuman(usr) && applies_stasis) var/mob/living/carbon/human/H = occupant - H.in_stasis = 1 + H.Stasis(1000) icon_state = occupied_icon_state @@ -638,7 +638,7 @@ occupant.forceMove(get_turf(src)) if(ishuman(occupant) && applies_stasis) var/mob/living/carbon/human/H = occupant - H.in_stasis = 0 + H.Stasis(0) set_occupant(null) icon_state = base_icon_state diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index ffe30bf3fd..1e10e03f4f 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -7,7 +7,7 @@ energy_drain = 20 range = MELEE equip_cooldown = 50 - var/mob/living/carbon/occupant = null + var/mob/living/carbon/human/occupant = null var/datum/global_iterator/pr_mech_sleeper var/inject_amount = 10 required_type = /obj/mecha/medical @@ -28,7 +28,7 @@ Exit(atom/movable/O) return 0 - action(var/mob/living/carbon/target) + action(var/mob/living/carbon/human/target) if(!action_checks(target)) return if(!istype(target)) @@ -56,6 +56,7 @@ target.forceMove(src) occupant = target target.reset_view(src) + occupant.Stasis(3) /* if(target.client) target.client.perspective = EYE_PERSPECTIVE @@ -80,6 +81,7 @@ occupant.client.eye = occupant.client.mob occupant.client.perspective = MOB_PERSPECTIVE */ + occupant.Stasis(0) occupant = null pr_mech_sleeper.stop() set_ready_state(1) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 1450fa94ce..e04796069c 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -77,14 +77,14 @@ /obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location) ..() if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src)))) - if(!ishuman(usr)) return + if(!ishuman(usr)) return 0 if(opened) return 0 if(contents.len) return 0 visible_message("[usr] folds up the [src.name]") - new item_path(get_turf(src)) + var/folded = new item_path(get_turf(src)) spawn(0) qdel(src) - return + return folded /obj/structure/closet/body_bag/proc/get_occupants() var/list/occupants = list() @@ -109,34 +109,43 @@ /obj/item/bodybag/cryobag name = "stasis bag" - desc = "A folded, non-reusable bag designed to prevent additional damage to an occupant, especially useful if short on time or in \ - a hostile enviroment." + desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \ + especially useful if short on time or in a hostile enviroment." icon = 'icons/obj/cryobag.dmi' icon_state = "bodybag_folded" item_state = "bodybag_cryo_folded" origin_tech = list(TECH_BIO = 4) + var/obj/item/weapon/reagent_containers/syringe/syringe /obj/item/bodybag/cryobag/attack_self(mob/user) var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc) R.add_fingerprint(user) + if(syringe) + R.syringe = syringe + syringe = null qdel(src) /obj/structure/closet/body_bag/cryobag name = "stasis bag" - desc = "A non-reusable plastic bag designed to prevent additional damage to an occupant, especially useful if short on time or in \ - a hostile enviroment." + desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \ + especially useful if short on time or in a hostile enviroment." icon = 'icons/obj/cryobag.dmi' item_path = /obj/item/bodybag/cryobag store_misc = 0 store_items = 0 var/used = 0 var/obj/item/weapon/tank/tank = null + var/stasis_level = 3 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1) + var/obj/item/weapon/reagent_containers/syringe/syringe /obj/structure/closet/body_bag/cryobag/New() tank = new /obj/item/weapon/tank/emergency/oxygen(null) //It's in nullspace to prevent ejection when the bag is opened. ..() /obj/structure/closet/body_bag/cryobag/Destroy() + if(syringe) + qdel(syringe) + syringe = null qdel(tank) tank = null ..() @@ -151,11 +160,19 @@ O.desc = "Pretty useless now.." qdel(src) +/obj/structure/closet/body_bag/cryobag/MouseDrop(over_object, src_location, over_location) + . = ..() + if(. && syringe) + var/obj/item/bodybag/cryobag/folded = . + folded.syringe = syringe + syringe = null + /obj/structure/closet/body_bag/cryobag/Entered(atom/movable/AM) if(ishuman(AM)) var/mob/living/carbon/human/H = AM - H.in_stasis = 1 + H.Stasis(stasis_level) src.used = 1 + inject_occupant(H) if(istype(AM, /obj/item/organ)) var/obj/item/organ/O = AM @@ -167,7 +184,7 @@ /obj/structure/closet/body_bag/cryobag/Exited(atom/movable/AM) if(ishuman(AM)) var/mob/living/carbon/human/H = AM - H.in_stasis = 0 + H.Stasis(0) if(istype(AM, /obj/item/organ)) var/obj/item/organ/O = AM @@ -181,10 +198,19 @@ return tank.air_contents ..() +/obj/structure/closet/body_bag/cryobag/proc/inject_occupant(var/mob/living/carbon/human/H) + if(!syringe) + return + + if(H.reagents) + syringe.reagents.trans_to_mob(H, 30, CHEM_BLOOD) + /obj/structure/closet/body_bag/cryobag/examine(mob/user) ..() if(Adjacent(user)) //The bag's rather thick and opaque from a distance. user << "You peer into \the [src]." + if(syringe) + user << "It has a syringe added to it." for(var/mob/living/L in contents) L.examine(user) @@ -196,5 +222,28 @@ var/obj/item/device/healthanalyzer/analyzer = W for(var/mob/living/L in contents) analyzer.attack(L,user) + + else if(istype(W,/obj/item/weapon/reagent_containers/syringe)) + if(syringe) + to_chat(user,"\The [src] already has an injector! Remove it first.") + else + var/obj/item/weapon/reagent_containers/syringe/syringe = W + to_chat(user,"You insert \the [syringe] into \the [src], and it locks into place.") + user.unEquip(syringe) + src.syringe = syringe + syringe.loc = null + for(var/mob/living/carbon/human/H in contents) + inject_occupant(H) + break + + else if(istype(W,/obj/item/weapon/screwdriver)) + if(syringe) + if(used) + to_chat(user,"The injector cannot be removed now that the stasis bag has been used!") + else + syringe.forceMove(src.loc) + to_chat(user,"You pry \the [syringe] out of \the [src].") + syringe = null + else ..() diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index fa3d19ebab..6237e43e0f 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -153,6 +153,12 @@ wearing_rig.notify_ai("Warning: user consciousness failure. Mobility control passed to integrated intelligence system.") ..() +/mob/living/carbon/human/proc/Stasis(amount) + if((species.flags & NO_SCAN) || isSynthetic()) + in_stasis = 0 + else + in_stasis = amount + /mob/living/carbon/human/getCloneLoss() if((species.flags & NO_SCAN) || isSynthetic()) cloneloss = 0 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index e6563a28a1..8308c35034 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -63,7 +63,10 @@ voice = GetVoice() //No need to update all of these procs if the guy is dead. - if(stat != DEAD && !in_stasis) + if(stat != DEAD && (!in_stasis || life_tick % in_stasis == 1)) + if(in_stasis > 2) + Sleeping(10) + //Updates the number of stored chemicals for powers handle_changeling() @@ -82,7 +85,6 @@ if(!client) species.handle_npc(src) - if(!handle_some_updates()) return //We go ahead and process them 5 times for HUD images and other stuff though. @@ -97,7 +99,7 @@ return 1 /mob/living/carbon/human/breathe() - if(!in_stasis) + if(!in_stasis || life_tick % in_stasis == 1) ..() // Calculate how vulnerable the human is to under- and overpressure. @@ -207,7 +209,7 @@ /mob/living/carbon/human/handle_mutations_and_radiation() - if(in_stasis) + if(in_stasis && life_tick % in_stasis != 1) return if(getFireLoss()) @@ -789,7 +791,7 @@ /mob/living/carbon/human/handle_chemicals_in_body() - if(in_stasis) + if(in_stasis && life_tick % in_stasis != 1) return if(reagents) @@ -1339,7 +1341,7 @@ if(!druggy && !seer) see_invisible = SEE_INVISIBLE_LIVING /mob/living/carbon/human/handle_random_events() - if(in_stasis) + if(in_stasis && life_tick % in_stasis != 1) return // Puke if toxloss is too high diff --git a/nano/templates/sleeper.tmpl b/nano/templates/sleeper.tmpl index 49fb0ae8d7..7ee370e890 100644 --- a/nano/templates/sleeper.tmpl +++ b/nano/templates/sleeper.tmpl @@ -88,4 +88,12 @@ {{/if}} +