From 67671bf190e3b5fb59497932062893250cd2bc00 Mon Sep 17 00:00:00 2001
From: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
Date: Tue, 29 Jul 2025 21:01:27 -0400
Subject: [PATCH] Allows people to toggle the cryocell auto-eject timer on and
off (#29716)
* Adds toggle to cryocell auto-eject timer
* Removed unnecessary return
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
* Adds examine message
* Adds alert when entering cryocell with auto-eject disabled. Clicking it lets you resist out after 1 minute, even if unconscious.
---------
Signed-off-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
---
code/__DEFINES/status_effects.dm | 1 +
code/_onclick/hud/alert.dm | 5 +++
code/datums/status_effects/neutral.dm | 3 ++
.../components/unary_devices/cryo.dm | 33 ++++++++++++++++++-
.../modules/mob/living/carbon/carbon_procs.dm | 13 ++++++++
code/modules/mob/living/living.dm | 4 +++
6 files changed, 58 insertions(+), 1 deletion(-)
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)