diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index b2185b15d33..843e4e1258b 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -340,7 +340,8 @@ var/round_start_time = 0
if(player.ready && player.mind)
if(player.mind.assigned_role == "AI")
player.close_spawn_windows()
- player.AIize()
+ var/mob/living/silicon/ai/ai_character = player.AIize()
+ ai_character.moveToAILandmark()
else if(!player.mind.assigned_role)
continue
else
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index f06771cc288..29e315ec001 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -264,9 +264,9 @@ atom/proc/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/A
if(interaction == AI_TRANS_FROM_CARD)
AI.control_disabled = 0
AI.aiRadio.disabledAi = 0
- AI.loc = loc//To replace the terminal.
+ AI.forceMove(loc)//To replace the terminal.
to_chat(AI, "You have been uploaded to a stationary terminal. Remote device connection restored.")
- to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
+ to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.")
qdel(src)
else //If for some reason you use an empty card on an empty AI terminal.
to_chat(user, "There is no AI loaded on this terminal!")
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 6d2e116edb2..0f971300225 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1416,7 +1416,8 @@
message_admins("\red Admin [key_name_admin(usr)] AIized [key_name_admin(H)]!", 1)
log_admin("[key_name(usr)] AIized [key_name(H)]")
- H.AIize()
+ var/mob/living/silicon/ai/ai_character = H.AIize()
+ ai_character.moveToAILandmark()
else if(href_list["makemask"])
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 577d16233d8..b776eb9a649 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -416,6 +416,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
call(/datum/game_mode/proc/add_law_zero)(new_character)
if("AI")
new_character = new_character.AIize()
+ var/mob/living/silicon/ai/ai_character = new_character
+ ai_character.moveToAILandmark()
if(new_character.mind.special_role=="traitor")
call(/datum/game_mode/proc/add_law_zero)(new_character)
//Add aliens.
diff --git a/code/modules/mob/living/silicon/ai/latejoin.dm b/code/modules/mob/living/silicon/ai/latejoin.dm
index d869b72eff3..56cee4f651f 100644
--- a/code/modules/mob/living/silicon/ai/latejoin.dm
+++ b/code/modules/mob/living/silicon/ai/latejoin.dm
@@ -37,4 +37,42 @@ var/global/list/empty_playable_ai_cores = list()
var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode
current_mode.possible_traitors.Remove(src)
- qdel(src)
\ No newline at end of file
+ qdel(src)
+
+// TODO: Move away from the insane name-based landmark system
+/mob/living/silicon/ai/proc/moveToAILandmark()
+ var/obj/loc_landmark
+ for(var/obj/effect/landmark/start/sloc in landmarks_list)
+ if(sloc.name != "AI")
+ continue
+ if(locate(/mob/living) in sloc.loc)
+ continue
+ loc_landmark = sloc
+ if(!loc_landmark)
+ for(var/obj/effect/landmark/tripai in landmarks_list)
+ if(tripai.name == "tripai")
+ if(locate(/mob/living) in tripai.loc)
+ continue
+ loc_landmark = tripai
+ if(!loc_landmark)
+ to_chat(src, "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone.")
+ for(var/obj/effect/landmark/start/sloc in landmarks_list)
+ if(sloc.name == "AI")
+ loc_landmark = sloc
+
+ forceMove(loc_landmark.loc)
+
+// Before calling this, make sure an empty core exists, or this will no-op
+/mob/living/silicon/ai/proc/moveToEmptyCore()
+ if(!empty_playable_ai_cores.len)
+ log_debug("moveToEmptyCore called without any available cores")
+ return
+
+ // IsJobAvailable for AI checks that there is an empty core available in this list
+ var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
+ empty_playable_ai_cores -= C
+
+ forceMove(C.loc)
+
+
+ qdel(C)
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 682abdb383d..d820f984ec1 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -296,18 +296,13 @@
// AIs don't need a spawnpoint, they must spawn at an empty core
if(character.mind.assigned_role == "AI")
- character = character.AIize(move=0) // AIize the character, but don't move them yet
+ var/mob/living/silicon/ai/ai_character = character.AIize() // AIize the character, but don't move them yet
// IsJobAvailable for AI checks that there is an empty core available in this list
- var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
- empty_playable_ai_cores -= C
+ ai_character.moveToEmptyCore()
+ AnnounceCyborg(ai_character, rank, "has been downloaded to the empty core in \the [get_area(ai_character)]")
- character.loc = C.loc
-
- AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [get_area(character)]")
- ticker.mode.latespawn(character)
-
- qdel(C)
+ ticker.mode.latespawn(ai_character)
qdel(src)
return
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 98e33ee5f6b..92435b2635f 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -7,14 +7,6 @@
spawning = 1
return ..()
-/mob/living/carbon/human/AIize(move=1) // 'move' argument needs defining here too because BYOND is dumb
- if(notransform)
- return
- for(var/t in organs)
- qdel(t)
-
- return ..(move)
-
/mob/living/carbon/AIize()
if(notransform)
return
@@ -40,34 +32,12 @@
else
O.key = key
- var/obj/loc_landmark
- for(var/obj/effect/landmark/start/sloc in landmarks_list)
- if(sloc.name != "AI")
- continue
- if(locate(/mob/living) in sloc.loc)
- continue
- loc_landmark = sloc
- if(!loc_landmark)
- for(var/obj/effect/landmark/tripai in landmarks_list)
- if(tripai.name == "tripai")
- if(locate(/mob/living) in tripai.loc)
- continue
- loc_landmark = tripai
- if(!loc_landmark)
- to_chat(O, "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone.")
- for(var/obj/effect/landmark/start/sloc in landmarks_list)
- if(sloc.name == "AI")
- loc_landmark = sloc
-
- O.loc = loc_landmark.loc
-
O.on_mob_init()
O.add_ai_verbs()
O.rename_self("AI",1)
- spawn
- qdel(src)
+ qdel(src)
return O
/mob/living/carbon/human/make_into_mask(var/should_gib = 0)