From d98c0112c4e5fe5aa11829592b3911998520e36c Mon Sep 17 00:00:00 2001
From: trickyfox-inc <128976622+trickyfox-inc@users.noreply.github.com>
Date: Sun, 11 Jan 2026 02:46:39 +0300
Subject: [PATCH] Context menu option (adminverb) - Open player panel of mobs
inside vehicles/crates/machinery/etc. (#94787)
## About The Pull Request
This PR adds an option to the context menu of objects that allows admins
to open player panel of mobs inside closets/crates/coffins, body bags
(both folded and unfolded), machinery, vehicles, morgue trays and
crematoriums without selecting particular mob in VV of the object.
Supported types of objects:
/obj/vehicle;
/obj/structure/closet;
/obj/structure/bodycontainer;
/obj/machinery;
/obj/item/bodybag.
The selection menu displays mob names and tags. If an /obj/vehicle is
selected, its driver is marked accordingly in the menu. This verb also
checks /obj/structure/closet and /obj/structure/bodycontainer for body
bags (both folded and unfolded), adding any mobs inside them to the
list.
https://github.com/user-attachments/assets/2c75b7f8-5879-4476-973b-38f2fa638d10
## Why It's Good For The Game
QOL. You don't have to open PP via object's
VV->occupants/contents->list->VV of a particular mob->show PP.
## Changelog
:cl:
admin: New adminverb "show occupants PP". You can now open the PP of
mobs inside vehicles, closets, machinery, body bags, etc. via the RMB
context menu.
/:cl:
---------
Co-authored-by: AlexTheEng1neer <128976622+AlexTheEng1neer@users.noreply.github.com>
Co-authored-by: Cornka <112967882+Kocma-san@users.noreply.github.com>
---
code/modules/admin/verbs/admingame.dm | 70 +++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm
index b444ad57337..fb00b96f783 100644
--- a/code/modules/admin/verbs/admingame.dm
+++ b/code/modules/admin/verbs/admingame.dm
@@ -151,6 +151,76 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo
user << browse(body, "window=adminplayeropts-[REF(player)];size=550x540")
BLACKBOX_LOG_ADMIN_VERB("Player Panel")
+ADMIN_VERB_ONLY_CONTEXT_MENU(show_occupants_player_panel, R_ADMIN, "Show Occupants PP", obj/target in world)
+ var/list/options = list()
+
+ // Vehicles
+ if(istype(target, /obj/vehicle))
+ var/obj/vehicle/target_vehicle = target
+ if(istype(target_vehicle.occupants, /list) && target_vehicle.occupants.len)
+ for(var/mob/mob_occupant in target_vehicle.occupants)
+ options["[mob_occupant.name] ([mob_occupant.tag])[target_vehicle.is_driver(mob_occupant) ? " (Driver)" : ""]"] = "\ref[mob_occupant]"
+ // Searching for mobs in exosuit equipment (e.g. seccage, sleepers)
+ for(var/obj/item/mecha_parts/mecha_equipment/obj_contents in target.contents)
+ for(var/mob/mob_in_equipment in obj_contents.contents)
+ options["[mob_in_equipment.name] ([mob_in_equipment.tag])"] = "\ref[mob_in_equipment]"
+
+ // Closets, crates, bodybags, coffins, etc.
+ else if(istype(target, /obj/structure/closet))
+ for(var/mob/mob_occupant in target.contents)
+ options["[mob_occupant.name] ([mob_occupant.tag])"] = "\ref[mob_occupant]"
+ // Searching for mobs in bodybags placed inside closet
+ for(var/obj/structure/closet/obj_contents in target.contents)
+ for(var/mob/mob_in_bodybag in obj_contents.contents)
+ options["[mob_in_bodybag.name] ([mob_in_bodybag.tag])"] = "\ref[mob_in_bodybag]"
+ // That's basically the same for folded bodybags (e.g. bluespace bodybags with mobs inside)
+ for(var/obj/item/bodybag/obj_contents_folded in target.contents)
+ for(var/mob/mob_in_bodybag_folded in obj_contents_folded.contents)
+ options["[mob_in_bodybag_folded.name] ([mob_in_bodybag_folded.tag])"] = "\ref[mob_in_bodybag_folded]"
+
+ // Folded bodybags (e.g. bluespace bodybags with mobs inside)
+ else if(istype(target, /obj/item/bodybag))
+ for(var/mob/mob_occupant in target.contents)
+ options["[mob_occupant.name] ([mob_occupant.tag])"] = "\ref[mob_occupant]"
+
+ // Body containers (morgue trays, crematoriums)
+ else if(istype(target, /obj/structure/bodycontainer))
+ for(var/mob/mob_occupant in target.contents)
+ options["[mob_occupant.name] ([mob_occupant.tag])"] = "\ref[mob_occupant]"
+ // Searching for mobs in bodybags placed inside body container
+ for(var/obj/structure/closet/obj_contents in target.contents)
+ for(var/mob/mob_in_bodybag in obj_contents.contents)
+ options["[mob_in_bodybag.name] ([mob_in_bodybag.tag])"] = "\ref[mob_in_bodybag]"
+ // That's basically the same for folded bodybags (e.g. bluespace bodybags with mobs inside)
+ for(var/obj/item/bodybag/obj_contents_folded in target.contents)
+ for(var/mob/mob_in_bodybag_folded in obj_contents_folded.contents)
+ options["[mob_in_bodybag_folded.name] ([mob_in_bodybag_folded.tag])"] = "\ref[mob_in_bodybag_folded]"
+
+ // Machinery
+ else if(istype(target, /obj/machinery))
+ for(var/mob/mob_occupant in target.contents)
+ options["[mob_occupant.name] ([mob_occupant.tag])"] = "\ref[mob_occupant]"
+
+ else
+ tgui_alert(user,"Unsupported object type! Supported types: /obj/vehicle; /obj/structure/closet; /obj/structure/bodycontainer; /obj/machinery; /obj/item/bodybag.")
+ return
+
+ if(!options.len)
+ tgui_alert(user, "No occupants found!")
+ return
+
+ var/choice
+ if(options.len == 1)
+ choice = options[1]
+ else
+ choice = tgui_input_list(user, "Select mob", "Player Panel", options)
+
+ if(choice)
+ var/mob/selected_mob = locate(options[choice])
+ if(selected_mob)
+ SSadmin_verbs.dynamic_invoke_verb(user, /datum/admin_verb/show_player_panel, selected_mob)
+ return
+
/client/proc/cmd_admin_godmode(mob/mob in GLOB.mob_list)
set category = "Admin.Game"
set name = "Godmode"