diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 49d3e68c031..7228d62b24d 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -426,4 +426,47 @@ proc/isInSight(var/atom/A, var/atom/B)
return minutes * 60 * 10
/proc/SecondsToTicks(var/seconds)
- return seconds * 10
\ No newline at end of file
+ return seconds * 10
+
+proc/pollCandidates(var/Question, var/jobbanType, var/antag_age_check = 0, var/be_special_flag = 0, var/poll_time = 300)
+ var/list/mob/dead/observer/candidates = list()
+ var/time_passed = world.time
+ if (!Question)
+ Question = "Would you like to be a special role?"
+
+ for(var/mob/dead/observer/G in player_list)
+ if(!G.key || !G.client)
+ continue
+ if(be_special_flag)
+ if(!(G.client.prefs.be_special & be_special_flag))
+ continue
+ if (antag_age_check && be_special_flag)
+ if(!player_old_enough_antag(G.client,be_special_flag))
+ continue
+ if (jobbanType)
+ if(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate"))
+ continue
+ spawn(0)
+ G << 'sound/misc/notice2.ogg' //Alerting them to their consideration
+ switch(alert(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No"))
+ if("Yes")
+ G << "Choice registered: Yes."
+ if((world.time-time_passed)>poll_time)//If more than 30 game seconds passed.
+ G << "Sorry, you were too late for the consideration!"
+ G << 'sound/machines/buzz-sigh.ogg'
+ return
+ candidates += G
+ if("No")
+ G << "Choice registered: No."
+ return
+ else
+ return
+ sleep(poll_time)
+
+ //Check all our candidates, to make sure they didn't log off during the 30 second wait period.
+ for(var/mob/dead/observer/G in candidates)
+ if(!G.key || !G.client)
+ candidates.Remove(G)
+
+ return candidates
+
\ No newline at end of file
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 0553e65edfb..af4f203ebf8 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -253,6 +253,7 @@ client
body += ""
body += ""
+ body += ""
body += ""
body += ""
@@ -591,9 +592,37 @@ client
if(!istype(H))
usr << "This can only be used on instances of type /mob/living/carbon/human"
return
+
+ var/confirm = alert("Are you sure you want to turn this mob into a skeleton?","Confirm Skeleton Transformation","Yes","No")
+ if(confirm != "Yes")
+ return
H.makeSkeleton()
href_list["datumrefresh"] = href_list["make_skeleton"]
+
+ else if(href_list["offer_control"])
+ if(!check_rights(R_ADMIN)) return
+
+ var/mob/M = locate(href_list["offer_control"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+ M << "Control of your mob has been offered to dead players."
+ log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.")
+ message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts")
+ var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name]?", "Player Control", null, FALSE, 100)
+ var/mob/dead/observer/theghost = null
+
+ if(candidates.len)
+ theghost = pick(candidates)
+ M << "Your mob has been taken over by a ghost!"
+ message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])")
+ M.ghostize()
+ M.key = theghost.key
+ else
+ M << "There were no ghosts willing to take control."
+ message_admins("No ghosts were willing to take control of [key_name_admin(M)])")
+
else if(href_list["delall"])
if(!check_rights(R_DEBUG|R_SERVER)) return