diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 1e31207b574..d1fa3e999c5 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -101,7 +101,7 @@
visible_message("The console beeps happily as it disgorges \the [I].")
- I.loc = get_turf(src)
+ I.forceMove(get_turf(src))
frozen_items -= I
else if(href_list["allitems"])
@@ -117,7 +117,7 @@
visible_message("The console beeps happily as it disgorges the desired objects.")
for(var/obj/item/I in frozen_items)
- I.loc = get_turf(src)
+ I.forceMove(get_turf(src))
frozen_items -= I
updateUsrDialog()
@@ -281,7 +281,7 @@
//Drop all items into the pod.
for(var/obj/item/W in occupant)
occupant.unEquip(W)
- W.loc = src
+ W.forceMove(src)
if(W.contents.len) //Make sure we catch anything not handled by qdel() on the items.
var/preserve = null
@@ -294,7 +294,7 @@
for(var/obj/item/O in W.contents)
if(istype(O,/obj/item/weapon/tank)) //Stop eating pockets, you fuck!
continue
- O.loc = src
+ O.forceMove(src)
for(var/obj/machinery/computer/cloning/cloner in machines)
for(var/datum/dna2/record/R in cloner.records)
@@ -328,7 +328,7 @@
control_computer.frozen_items += W
W.loc = null
else
- W.loc = loc
+ W.forceMove(loc)
// Skip past any cult sacrifice objective using this person
if(GAMEMODE_IS_CULT && is_sacrifice_target(occupant.mind))
@@ -466,9 +466,7 @@
to_chat(user, "\The [src] is in use.")
return
- M.forceMove(src)
-
- time_till_despawn = initial(time_till_despawn) / willing
+ take_occupant(M, willing)
else //because why the fuck would you keep going if the mob isn't in the pod
to_chat(user, "You stop putting [M] into the cryopod.")
@@ -563,38 +561,36 @@
if(occupant)
to_chat(user, "\The [src] is in use.")
return
- L.forceMove(src)
- time_till_despawn = initial(time_till_despawn) / willing
+ take_occupant(L, willing)
else
to_chat(user, "You stop [L == user ? "climbing into the cryo pod." : "putting [L] into the cryo pod."]")
- return
- if(orient_right)
- icon_state = "[occupied_icon_state]-r"
- else
- icon_state = occupied_icon_state
+/obj/machinery/cryopod/proc/take_occupant(var/mob/living/carbon/E, var/willing_factor = 1)
+ if(src.occupant)
+ return
+ if(!E)
+ return
+ E.forceMove(src)
+ time_till_despawn = initial(time_till_despawn) / willing_factor
+ if(orient_right)
+ icon_state = "[occupied_icon_state]-r"
+ else
+ icon_state = occupied_icon_state
+ to_chat(E, "[on_enter_occupant_message]")
+ to_chat(E, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")
+ occupant = E
+ name = "[name] ([occupant.name])"
+ time_entered = world.time
+ if(findtext("[E.key]","@",1,2))
+ var/FT = replacetext(E.key, "@", "")
+ for(var/mob/dead/observer/Gh in respawnable_list) //this may not be foolproof but it seemed like a better option than 'in world'
+ if(Gh.key == FT)
+ if(Gh.client && Gh.client.holder) //just in case someone has a byond name with @ at the start, which I don't think is even possible but whatever
+ to_chat(Gh, "Warning: Your body has entered cryostorage.")
+ log_admin("[key_name(E)] entered a stasis pod.")
+ message_admins("[key_name_admin(E)] entered a stasis pod. (JMP)")
+ add_fingerprint(E)
- to_chat(L, "[on_enter_occupant_message]")
- to_chat(L, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")
- occupant = L
- name = "[name] ([occupant.name])"
- time_entered = world.time
-
- if(findtext("[L.key]","@",1,2))
- var/FT = replacetext(L.key, "@", "")
- for(var/mob/dead/observer/Gh in respawnable_list) //this may not be foolproof but it seemed like a better option than 'in world'
- if(Gh.key == FT)
- if(Gh.client && Gh.client.holder) //just in case someone has a byond name with @ at the start, which I don't think is even possible but whatever
- to_chat(Gh, "Warning: Your body has entered cryostorage.")
-
- // Book keeping!
- log_admin("[key_name_admin(L)] has entered a stasis pod. (JMP)")
- message_admins("[key_name_admin(L)] has entered a stasis pod.")
-
- //Despawning occurs when process() is called with an occupant without a client.
- add_fingerprint(L)
-
- return
/obj/machinery/cryopod/verb/eject()
set name = "Eject Pod"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 4c9194d1225..07328008574 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -79,6 +79,7 @@ var/list/admin_verbs_admin = list(
/client/proc/reset_all_tcs, /*resets all telecomms scripts*/
/client/proc/toggle_mentor_chat,
/client/proc/toggle_advanced_interaction, /*toggle admin ability to interact with not only machines, but also atoms such as buttons and doors*/
+ /client/proc/cryo_ssds,
)
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index af865f7f5c8..da2c998dc79 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -882,6 +882,58 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[key_name_admin(usr)] blanked all telecomms scripts.")
feedback_add_details("admin_verb","RAT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/proc/cryo_ssds()
+ set category = "Admin"
+ set name = "Cryo SSDs"
+ set desc = "Sends SSD players to cryo"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ var/confirm = alert(src, "You sure you want to teleport 10+m SSD players into cryo?", "Confirm", "Yes", "No")
+ if(confirm != "Yes")
+ return
+
+ var/list/people_to_cryo = list()
+ for(var/mob/living/carbon/human/H in living_mob_list)
+ if(!H.player_logged)
+ continue
+ if(!H.last_logout)
+ continue
+ if((H.last_logout + 6000) > world.time)
+ continue
+ if(!is_station_level(H.z))
+ continue
+ if(!isLivingSSD(H))
+ continue
+ if(H.anchored)
+ continue
+ if(H.stunned)
+ continue
+ if(H.handcuffed)
+ continue
+ if(H.buckled)
+ continue
+ if(H.pulledby)
+ continue
+ people_to_cryo += H
+ var/list/free_cryopods = list()
+ for(var/obj/machinery/cryopod/P in machines)
+ if(!P.occupant && istype(get_area(P), /area/crew_quarters/sleep))
+ free_cryopods += P
+ var/obj/machinery/cryopod/target_cryopod = null
+ var/people_cryoed = 0
+ for(var/mob/living/carbon/human/T in people_to_cryo)
+ if(free_cryopods.len)
+ target_cryopod = safepick(free_cryopods)
+ if(target_cryopod.check_occupant_allowed(T))
+ target_cryopod.take_occupant(T, 1)
+ people_cryoed++
+ to_chat(usr, "Sent [people_cryoed] people to cryostorage.")
+ log_admin("[key_name(usr)] sent SSDs to cryo.")
+ message_admins("[key_name_admin(usr)] sent SSDs to cryo.")
+ feedback_add_details("admin_verb","SSDCRY") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
/client/proc/toggle_ert_calling()
set category = "Event"
set name = "Toggle ERT"
diff --git a/code/modules/mob/living/logout.dm b/code/modules/mob/living/logout.dm
index 6235aecf2c4..910a72aeca3 100644
--- a/code/modules/mob/living/logout.dm
+++ b/code/modules/mob/living/logout.dm
@@ -9,3 +9,4 @@
if(mind.active)
Sleeping(2)
player_logged = 1
+ last_logout = world.time
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 959913972fa..1e65b368ef0 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -189,6 +189,8 @@
var/last_movement = -100 // Last world.time the mob actually moved of its own accord.
+ var/last_logout = 0
+
var/resize = 1 //Badminnery resize
var/datum/vision_override/vision_type = null //Vision override datum.