diff --git a/code/controllers/Processes/inactivity.dm b/code/controllers/Processes/inactivity.dm index b1029e0391..2a6cd44d2c 100644 --- a/code/controllers/Processes/inactivity.dm +++ b/code/controllers/Processes/inactivity.dm @@ -7,8 +7,30 @@ for(last_object in clients) var/client/C = last_object if(C.is_afk(config.kick_inactive MINUTES)) - if(!istype(C.mob, /mob/observer/dead)) - log_access("AFK: [key_name(C)]") - C << "You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected." - del(C) // Don't qdel, cannot override finalize_qdel behaviour for clients. + if(!istype(C.mob, /mob/observer/dead) && !istype(C.mob, /mob/new_player)) + to_chat(C,"You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.") + var/information + + if(ishuman(C.mob)) + var/job + var/mob/living/carbon/human/H = C.mob + var/datum/data/record/R = find_general_record("name", H.real_name) + if(R) + job = R.fields["real_rank"] + if(!job && H.mind) + job = H.mind.assigned_role + if(!job && H.job) + job = H.job + if(job) + information = " while [job]." + + else if(issilicon(C.mob)) + information = " while a silicon." + + var/adminlinks + adminlinks = " (JMP|CRYO)" + + log_and_message_admins("being kicked for AFK[information][adminlinks]", C.mob) + + qdel(C) SCHECK diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index d3936ca7c0..d254228795 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -346,8 +346,8 @@ // This function can not be undone; do not call this unless you are sure // Also make sure there is a valid control computer -/obj/machinery/cryopod/robot/despawn_occupant() - var/mob/living/silicon/robot/R = occupant +/obj/machinery/cryopod/robot/despawn_occupant(var/mob/to_despawn) + var/mob/living/silicon/robot/R = to_despawn if(!istype(R)) return ..() qdel(R.mmi) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 2532554193..721a959c35 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -101,7 +101,8 @@ var/list/admin_verbs_admin = list( /client/proc/toggle_attack_logs, /datum/admins/proc/paralyze_mob, /client/proc/fixatmos, - /datum/admins/proc/sendFax + /datum/admins/proc/sendFax, + /client/proc/despawn_player ) var/list/admin_verbs_ban = list( diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c2cf55ab00..81c709f6d8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1864,6 +1864,17 @@ show_player_panel(M) + else if(href_list["cryoplayer"]) + if(!check_rights(R_ADMIN)) return + + var/mob/M = locate(href_list["cryoplayer"]) + if(!istype(M)) + to_chat(usr,"Mob doesn't exist!") + return + + var/client/C = usr.client + C.despawn_player(M) + // player info stuff if(href_list["add_player_info"]) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 961dbdcdfb..9536f830fb 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -935,3 +935,63 @@ Traitors and the like can also be revived with the previous role mostly intact. usr << "Random events disabled" message_admins("Admin [key_name_admin(usr)] has disabled random events.", 1) feedback_add_details("admin_verb","TRE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/despawn_player(var/mob/M in living_mob_list) + set name = "Cryo Player" + set category = "Admin" + set desc = "Removes a player from the round as if they'd cryo'd." + set popup_menu = FALSE + + if(!check_rights(R_ADMIN)) + return + + if(!M) + return + + var/confirm = alert("Are you sure you want to cryo [M]?","Confirmation","No","Yes") + if(confirm == "No") + return + + var/list/human_cryopods = list() + var/list/robot_cryopods = list() + + for(var/obj/machinery/cryopod/CP in machines) + if(!CP.control_computer) + continue //Broken pod w/o computer, move on. + + var/listname = "[CP.name] ([CP.x],[CP.y],[CP.z])" + if(istype(CP,/obj/machinery/cryopod/robot)) + robot_cryopods[listname] = CP + else + human_cryopods[listname] = CP + + //Gotta log this up here before they get ghostized and lose their key or anything. + log_and_message_admins("[key_name(src)] admin cryo'd [key_name(M)].") + feedback_add_details("admin_verb","ACRYO") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + if(ishuman(M)) + var/obj/machinery/cryopod/CP = human_cryopods[input(usr,"Select a cryopod to use","Cryopod Choice") as null|anything in human_cryopods] + if(!CP) + return + M.ghostize() + CP.despawn_occupant(M) + return + + else if(issilicon(M)) + if(isAI(M)) + var/mob/living/silicon/ai/ai = M + empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(ai.loc) + global_announcer.autosay("[ai] has been moved to intelligence storage.", "Artificial Intelligence Oversight") + ai.clear_client() + return + else + var/obj/machinery/cryopod/robot/CP = robot_cryopods[input(usr,"Select a cryopod to use","Cryopod Choice") as null|anything in robot_cryopods] + if(!CP) + return + M.ghostize() + CP.despawn_occupant(M) + return + + else if(isliving(M)) + M.ghostize() + qdel(M) //Bye