diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index aec3dbccc69..4d740a7ba20 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -99,6 +99,7 @@
#define VV_HK_PLAYER_PANEL "player_panel"
#define VV_HK_BUILDMODE "buildmode"
#define VV_HK_DIRECT_CONTROL "direct_control"
+#define VV_HK_GIVE_DIRECT_CONTROL "give_direct_control"
#define VV_HK_OFFER_GHOSTS "offer_ghosts"
// /mob/living/carbon
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 0f1a1e9eb82..3d05b4e1f60 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -234,16 +234,45 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(M.ckey)
if(alert("This mob is being controlled by [M.key]. Are you sure you wish to assume control of it? [M.key] will be made a ghost.",,"Yes","No") != "Yes")
return
- else
- M.ghostize(FALSE)
+ if(!M || QDELETED(M))
+ to_chat(usr, "The target mob no longer exists.")
+ return
message_admins("[key_name_admin(usr)] assumed direct control of [M].")
log_admin("[key_name(usr)] assumed direct control of [M].")
- var/mob/adminmob = src.mob
- M.ckey = src.ckey
- if( isobserver(adminmob) )
+ var/mob/adminmob = mob
+ if(M.ckey)
+ M.ghostize(FALSE)
+ M.ckey = ckey
+ if(isobserver(adminmob))
qdel(adminmob)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Assume Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/proc/cmd_give_direct_control(mob/M in GLOB.mob_list)
+ set category = "Admin"
+ set name = "Give direct control"
+
+ if(!M)
+ return
+ if(M.ckey)
+ if(alert("This mob is being controlled by [M.key]. Are you sure you wish to give someone else control of it? [M.key] will be made a ghost.",,"Yes","No") != "Yes")
+ return
+ var/client/newkey = input(src, "Pick the player to put in control.", "New player") as null|anything in sortList(GLOB.clients)
+ var/mob/oldmob = newkey.mob
+ var/delmob = FALSE
+ if((isobserver(oldmob) || alert("Do you want to delete [newkey]'s old mob?","Delete?","Yes","No") != "No"))
+ delmob = TRUE
+ if(!M || QDELETED(M))
+ to_chat(usr, "The target mob no longer exists, aborting.")
+ return
+ if(M.ckey)
+ M.ghostize(FALSE)
+ M.ckey = newkey.key
+ if(delmob)
+ qdel(oldmob)
+ message_admins("[key_name_admin(usr)] gave away direct control of [M] to [newkey].")
+ log_admin("[key_name(usr)] gave away direct control of [M] to [newkey].")
+ SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
/client/proc/cmd_admin_test_atmos_controllers()
set category = "Mapping"
set name = "Test Atmos Monitoring Consoles"
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 1b02853d499..5ee9174a87f 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -30,6 +30,7 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
/client/proc/count_objects_on_z_level,
/client/proc/count_objects_all,
/client/proc/cmd_assume_direct_control, //-errorage
+ /client/proc/cmd_give_direct_control,
/client/proc/startSinglo,
/client/proc/set_server_fps, //allows you to set the ticklag.
/client/proc/cmd_admin_grantfullaccess,
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 3ac625f56fa..61b9f92d016 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -845,7 +845,7 @@
who.show_inv(src)
else
src << browse(null,"window=mob[REF(who)]")
-
+
who.update_equipment_speed_mods() // Updates speed in case stripped speed affecting item
// The src mob is trying to place an item on someone
@@ -1373,7 +1373,7 @@
. = ..()
var/refid = REF(src)
. += {"
-
[VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[ckey || "no ckey"]", NAMEOF(src, ckey))] / [VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[real_name || "no real name"]", NAMEOF(src, real_name))]
+
[VV_HREF_TARGETREF(refid, VV_HK_GIVE_DIRECT_CONTROL, "[ckey || "no ckey"]")] / [VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[real_name || "no real name"]", NAMEOF(src, real_name))]
BRUTE:[getBruteLoss()]
FIRE:[getFireLoss()]
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 2a18dc3254e..9d68c3290cc 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1140,6 +1140,7 @@
VV_DROPDOWN_OPTION(VV_HK_PLAYER_PANEL, "Show player panel")
VV_DROPDOWN_OPTION(VV_HK_BUILDMODE, "Toggle Buildmode")
VV_DROPDOWN_OPTION(VV_HK_DIRECT_CONTROL, "Assume Direct Control")
+ VV_DROPDOWN_OPTION(VV_HK_GIVE_DIRECT_CONTROL, "Give Direct Control")
VV_DROPDOWN_OPTION(VV_HK_OFFER_GHOSTS, "Offer Control to Ghosts")
/mob/vv_do_topic(list/href_list)
@@ -1184,6 +1185,10 @@
if(!check_rights(NONE))
return
usr.client.cmd_assume_direct_control(src)
+ if(href_list[VV_HK_GIVE_DIRECT_CONTROL])
+ if(!check_rights(NONE))
+ return
+ usr.client.cmd_give_direct_control(src)
if(href_list[VV_HK_OFFER_GHOSTS])
if(!check_rights(NONE))
return