diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 4b652b5265d..a5c17a62b74 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -235,6 +235,7 @@ #define STATUS_EFFECT_REMOVE_CUFFS /datum/status_effect/action_status_effect/remove_handcuffs #define STATUS_EFFECT_REMOVE_MUZZLE /datum/status_effect/action_status_effect/remove_muzzle #define STATUS_EFFECT_UNBUCKLE /datum/status_effect/action_status_effect/unbuckle +#define STATUS_EFFECT_EXIT_CRYOCELL /datum/status_effect/action_status_effect/exit_cryocell ////////////////////////// // Mind batter variants // diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 2347714184b..bbc3bc53fb4 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -819,6 +819,11 @@ so as to remain in compliance with the most up-to-date laws." name = "Legcuffed" desc = "You're legcuffed, which slows you down considerably. Click the alert to free yourself." +/atom/movable/screen/alert/restrained/cryocell + name = "Cryogenics" + desc = "You're inside a freezing cold medical cell. Click the alert to free yourself." + icon_state = "asleep" + /atom/movable/screen/alert/restrained/Click() if(!isliving(usr) || !..()) return diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 1b8c182b92b..e443fe4f2c2 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -402,3 +402,6 @@ /datum/status_effect/action_status_effect/unbuckle id = "unbuckle" + +/datum/status_effect/action_status_effect/exit_cryocell + id = "exit_cryocell" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index f2ad17cfb28..d4289187fef 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -26,6 +26,8 @@ var/efficiency /// Timer that we use to remove people that are in us for too long var/removal_timer + /// Auto-eject the occupant after 1 minute + var/force_eject = TRUE light_color = LIGHT_COLOR_WHITE @@ -36,6 +38,8 @@ . += "You see [occupant.name] inside. [occupant.p_they(TRUE)] [occupant.p_are()] dead!" else . += "You see [occupant.name] inside." + if(!force_eject) + . += "The auto-eject light is off!" . += "The Cryogenic cell chamber is effective at treating those with genetic damage, but all other damage types at a moderate rate." . += "Mostly using cryogenic chemicals, such as cryoxadone for it's medical purposes, requires that the inside of the cell be kept cool at all times. Hooking up a freezer and cooling the pipeline will do this nicely." . += "Click-drag someone to a cell to place them in it, Alt-Click it to remove it." @@ -372,6 +376,21 @@ var/mutable_appearance/lid = mutable_appearance(icon = icon, icon_state = "lid[on]", layer = occupant_overlay.layer + 0.01) . += lid +/obj/machinery/atmospherics/unary/cryo_cell/proc/attempt_escape(mob/living/carbon/user, effective_breakout_time) + if(effective_breakout_time) + user.visible_message("[user] attempts to trigger the release on [src]!", "You attempt to trigger the release on [src]...") + to_chat(user, "You attempt to trigger the release on [src]. (This will take around [DisplayTimeText(effective_breakout_time)].)") + + if(!do_after(user, effective_breakout_time, FALSE, user, hidden = TRUE, allow_sleeping_or_dead = TRUE)) + user.remove_status_effect(STATUS_EFFECT_EXIT_CRYOCELL) + to_chat(user, "You fail to trigger the release on [src]!") + return + + user.remove_status_effect(STATUS_EFFECT_EXIT_CRYOCELL) + go_out() + +/obj/machinery/atmospherics/unary/cryo_cell/container_resist(mob/living/carbon/C) + C.cryo_resist(src) /obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant() if(air_contents.total_moles() < 10) @@ -417,6 +436,7 @@ if(ishuman(occupant) && occupant.bodytemperature < occupant.dna.species.cold_level_1) // Hacky fix for people taking burn damage after being ejected. Xenos also fit in these and they don't have dna occupant.bodytemperature = occupant.dna.species.cold_level_1 + occupant.clear_alert("cryogenics") occupant = null update_icon(UPDATE_OVERLAYS) deltimer(removal_timer) @@ -457,9 +477,20 @@ add_fingerprint(usr) update_icon(UPDATE_OVERLAYS) M.ExtinguishMob() - removal_timer = addtimer(CALLBACK(src, PROC_REF(auto_eject)), 1 MINUTES, TIMER_STOPPABLE) + if(force_eject) + removal_timer = addtimer(CALLBACK(src, PROC_REF(auto_eject)), 1 MINUTES, TIMER_STOPPABLE) + else + M.throw_alert("cryogenics", /atom/movable/screen/alert/restrained/cryocell) return TRUE +/obj/machinery/atmospherics/unary/cryo_cell/multitool_act(mob/living/user, obj/item/I) + . = TRUE + if(!I.use_tool(src, user, 0, volume = I.tool_volume)) + return + if(panel_open) + force_eject = !force_eject + to_chat(user, "You turn [force_eject ? "on" : "off"] the auto-ejection timer on [src].") + /obj/machinery/atmospherics/unary/cryo_cell/AltClick(mob/user) if(user.stat || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !Adjacent(user)) return diff --git a/code/modules/mob/living/carbon/carbon_procs.dm b/code/modules/mob/living/carbon/carbon_procs.dm index 089bb367379..562b62a9781 100644 --- a/code/modules/mob/living/carbon/carbon_procs.dm +++ b/code/modules/mob/living/carbon/carbon_procs.dm @@ -1009,6 +1009,19 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven update_inv_handcuffed() update_hands_hud() +// Called to escape a cryocell +/mob/living/carbon/proc/cryo_resist(obj/machinery/atmospherics/unary/cryo_cell/cell) + var/effective_breakout_time = 1 MINUTES + if(stat != UNCONSCIOUS) + effective_breakout_time = 5 SECONDS + + if(has_status_effect(STATUS_EFFECT_EXIT_CRYOCELL)) + to_chat(src, "You are already trying to exit [cell].") + return + + apply_status_effect(STATUS_EFFECT_EXIT_CRYOCELL) + cell.attempt_escape(src, effective_breakout_time) + /mob/living/carbon/get_standard_pixel_y_offset() if(IS_HORIZONTAL(src)) if(buckled) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index db736cef4ed..f76a627203f 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -733,6 +733,10 @@ ///proc extender of [/mob/living/verb/resist] meant to make the process queable if the server is overloaded when the verb is called /mob/living/proc/run_resist() + if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) + var/obj/C = loc + C.container_resist(src) + return if(!can_resist()) return changeNext_move(CLICK_CD_RESIST)