diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 0478141abe3..d3cbc93d4f0 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) @@ -326,7 +326,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)) @@ -463,9 +463,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.") @@ -479,23 +477,7 @@ to_chat(M, "[on_enter_occupant_message]") to_chat(M, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.") - occupant = M - name = "[name] ([occupant.name])" - time_entered = world.time - - if(findtext("[M.key]","@",1,2)) - var/FT = replacetext(M.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(M)] has entered a stasis pod.") - message_admins("[key_name_admin(M)] has entered a stasis pod. (JMP)") - - //Despawning occurs when process() is called with an occupant without a client. - add_fingerprint(M) + take_occupant(M, willing) /obj/machinery/cryopod/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) @@ -560,38 +542,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(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" @@ -733,3 +713,18 @@ qdel(R.module) return ..() + +/proc/cryo_ssd(var/mob/living/carbon/person_to_cryo) + if(istype(person_to_cryo.loc, /obj/machinery/cryopod)) + return 0 + 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 + if(free_cryopods.len) + target_cryopod = safepick(free_cryopods) + if(target_cryopod.check_occupant_allowed(person_to_cryo)) + target_cryopod.take_occupant(person_to_cryo, 1) + return 1 + return 0 \ No newline at end of file diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 4ddab9ccf2c..d05cc25a476 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1,4 +1,3 @@ - var/global/BSACooldown = 0 var/global/nologevent = 0 @@ -103,9 +102,14 @@ var/global/nologevent = 0 Narrate to | Subtle message "} + if(check_rights(R_EVENT, 0)) body += {" | Bless | Smite"} + if(isLivingSSD(M)) + if(!istype(M.loc, /obj/machinery/cryopod)) + body += {" | Cryo "} + if(M.client) if(!istype(M, /mob/new_player)) body += "

" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 4c9194d1225..db1c39aeb1a 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/list_ssds, ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 91f2fec4f06..3aabfd3150a 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1950,6 +1950,20 @@ if(logmsg) log_admin("[key_name(owner)] answered [key_name(M)]'s prayer with a smiting: [logmsg]") message_admins("[key_name_admin(owner)] answered [key_name_admin(M)]'s prayer with a smiting: [logmsg]") + else if(href_list["cryossd"]) + if(!check_rights(R_ADMIN)) + return + var/mob/living/carbon/human/H = locateUID(href_list["cryossd"]) + if(!istype(H)) + to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") + return + if(!isLivingSSD(H)) + to_chat(usr, "This can only be used on living, SSD players.") + return + var/success = cryo_ssd(H) + if(success) + log_admin("[key_name(usr)] sent [H.job] [H] to cryo.") + message_admins("[key_name_admin(usr)] sent [H.job] [H] to cryo.") else if(href_list["FaxReplyTemplate"]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 6b5f6f16249..fdfbdfba6b2 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -882,6 +882,48 @@ 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/list_ssds() + set category = "Admin" + set name = "List SSDs" + set desc = "Lists SSD players" + + if(!check_rights(R_ADMIN)) + return + + var/msg = "SSD Report" + msg += "SSD Players:
" + msg += "" + var/mins_ssd + var/job_string + var/key_string + var/role_string + for(var/mob/living/carbon/human/H in living_mob_list) + if(!isLivingSSD(H)) + continue + mins_ssd = round((world.time - H.last_logout) / 600) + if(H.job) + job_string = H.job + else + job_string = "-" + key_string = H.key + if(job_string in command_positions) + job_string = "" + job_string + "" + role_string = "-" + if(H.mind) + if(H.mind.special_role) + role_string = "[H.mind.special_role]" + if(!H.key && H.mind.key) + key_string = H.mind.key + msg += "" + msg += "" + if(istype(H.loc, /obj/machinery/cryopod)) + msg += "" + else + msg += "" + msg += "" + msg += "
KeyReal NameJobMins SSDSpecial RoleAreaPPNCryo
[key_string][H.real_name][job_string][mins_ssd][role_string][get_area(H)]PPIn CryoCryo
" + src << browse(msg, "window=Player_ssd_check") + /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 e275d855328..5031ec9c061 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -188,6 +188,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.