From 12b73a4d450bc2b6f3980b5006c68dd203127f23 Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Sun, 22 Oct 2023 12:49:59 -0400 Subject: [PATCH] Improves admin interaction with AIs (#22769) * admin-ai improvements * Update code/modules/admin/misc_admin_procs.dm Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> * brug --------- Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> --- code/modules/admin/admin_verbs.dm | 4 ++ code/modules/admin/misc_admin_procs.dm | 43 +++++++++++++++---- code/modules/mob/living/silicon/ai/ai_mob.dm | 7 +++ .../modules/mob/living/silicon/ai/latejoin.dm | 1 + 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 10cc7b27384..d3918481b0f 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -368,6 +368,7 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list( if(isobserver(mob)) //re-enter var/mob/dead/observer/ghost = mob + var/old_turf = get_turf(ghost) ghost.can_reenter_corpse = 1 //just in-case. ghost.reenter_corpse() log_admin("[key_name(usr)] re-entered their body") @@ -375,6 +376,9 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list( if(ishuman(mob)) var/mob/living/carbon/human/H = mob H.regenerate_icons() // workaround for #13269 + if(isAI(mob)) // client.mob, built in byond client var + var/mob/living/silicon/ai/ai = mob + ai.eyeobj.setLoc(old_turf) else if(isnewplayer(mob)) to_chat(src, "Error: Aghost: Can't admin-ghost whilst in the lobby. Join or observe first.") else diff --git a/code/modules/admin/misc_admin_procs.dm b/code/modules/admin/misc_admin_procs.dm index 212836ece75..005fa9861bf 100644 --- a/code/modules/admin/misc_admin_procs.dm +++ b/code/modules/admin/misc_admin_procs.dm @@ -889,27 +889,27 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space //returns 1 to let the dragdrop code know we are trapping this event //returns 0 if we don't plan to trap the event -/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, tothing) +/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, atom/tothing) if(!istype(frommob)) return //extra sanity check to make sure only observers are shoved into things //same as assume-direct-control perm requirements. if(!check_rights(R_VAREDIT,0)) //no varedit, check if they have r_admin and r_debug if(!check_rights(R_ADMIN|R_DEBUG,0)) //if they don't have r_admin and r_debug, return - return 0 //otherwise, if they have no varedit, but do have r_admin and r_debug, execute the rest of the code + return FALSE //otherwise, if they have no varedit, but do have r_admin and r_debug, execute the rest of the code if(!frommob.ckey) - return 0 + return FALSE if(isitem(tothing)) var/mob/living/toitem = tothing var/ask = alert("Are you sure you want to allow [frommob.name]([frommob.key]) to possess [toitem.name]?", "Place ghost in control of item?", "Yes", "No") if(ask != "Yes") - return 1 + return TRUE if(!frommob || !toitem) //make sure the mobs don't go away while we waited for a response - return 1 + return TRUE var/mob/living/simple_animal/possessed_object/tomob = new(toitem) @@ -931,10 +931,10 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space var/ask = alert(question, "Place ghost in control of mob?", "Yes", "No") if(ask != "Yes") - return 1 + return TRUE if(!frommob || !tomob) //make sure the mobs don't go away while we waited for a response - return 1 + return TRUE if(tomob.client) //no need to ghostize if there is no client tomob.ghostize(0) @@ -946,7 +946,34 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space tomob.ckey = frommob.ckey qdel(frommob) - return 1 + return TRUE + + if(istype(tothing, /obj/structure/AIcore/deactivated)) + + var/question = "Are you sure you want to place [frommob.name]([frommob.key]) in control of an empty AI core?" + + var/ask = alert(question, "Place ghost in control of an empty AI core?", "Yes", "No") + if(ask != "Yes") + return TRUE + + if(QDELETED(frommob) || QDELETED(tothing)) //make sure the mobs don't go away while we waited for a response + return TRUE + + message_admins("[key_name_admin(usr)] has put [frommob.ckey] in control of an empty AI core.") + log_admin("[key_name(usr)] stuffed [frommob.ckey] into an empty AI core.") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Ghost Drag") + + var/transfer_key = frommob.key // frommob is qdel'd in frommob.AIize() + var/mob/living/silicon/ai/ai_character = frommob.AIize() + ai_character.key = transfer_key // this wont occur in mind transferring if the mind is not active, which causes some weird stuff. This fixes it. + GLOB.empty_playable_ai_cores -= tothing + + ai_character.forceMove(get_turf(tothing)) + ai_character.view_core() + + qdel(tothing) + + return TRUE // Returns a list of the number of admins in various categories // result[1] is the number of staff that match the rank mask and are active diff --git a/code/modules/mob/living/silicon/ai/ai_mob.dm b/code/modules/mob/living/silicon/ai/ai_mob.dm index ae0fcb3f72b..c4edfb8b070 100644 --- a/code/modules/mob/living/silicon/ai/ai_mob.dm +++ b/code/modules/mob/living/silicon/ai/ai_mob.dm @@ -1518,4 +1518,11 @@ GLOBAL_LIST_INIT(ai_verbs_default, list( stored_locations[location_number] = eyeobj.loc return TRUE +/mob/living/silicon/ai/ghostize(can_reenter_corpse) + var/old_turf = get_turf(eyeobj) + . = ..() + if(isobserver(.)) + var/mob/dead/observer/ghost = . + ghost.forceMove(old_turf) + #undef TEXT_ANNOUNCEMENT_COOLDOWN diff --git a/code/modules/mob/living/silicon/ai/latejoin.dm b/code/modules/mob/living/silicon/ai/latejoin.dm index 0824a740a64..e198fc92b47 100644 --- a/code/modules/mob/living/silicon/ai/latejoin.dm +++ b/code/modules/mob/living/silicon/ai/latejoin.dm @@ -33,6 +33,7 @@ GLOBAL_LIST_EMPTY(empty_playable_ai_cores) continue O.on_target_cryo() + view_core() // Ghost the current player and disallow them to return to the body if(TOO_EARLY_TO_GHOST) ghostize(FALSE)