diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index e1a9f994907..59391551701 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -146,9 +146,11 @@
/obj/mecha/Destroy()
go_out()
+ var/mob/living/silicon/ai/AI
for(var/mob/M in src) //Let's just be ultra sure
if(isAI(M))
- M.gib() //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. Forever.
+ occupant = null
+ AI = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck.
else
M.forceMove(loc)
@@ -156,7 +158,7 @@
explosion(get_turf(loc), 0, 0, 1, 3)
if(wreckage)
- var/obj/structure/mecha_wreckage/WR = new wreckage(loc)
+ var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
if(E.salvageable && prob(30))
WR.crowbar_salvage += E
@@ -180,6 +182,8 @@
qdel(cell)
if(internal_tank)
qdel(internal_tank)
+ if(AI)
+ AI.gib() //No wreck, no AI to recover
STOP_PROCESSING(SSobj, src)
poi_list.Remove(src)
equipment.Cut()
@@ -636,9 +640,6 @@
if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot
user << "No AI detected in the [name] onboard computer."
return
- if(AI.mind.special_role) //Malf AIs cannot leave mechs. Except through death.
- user << "ACCESS DENIED."
- return
AI.ai_restore_power()//So the AI initially has power.
AI.control_disabled = 1
AI.radio_enabled = 0
@@ -690,9 +691,9 @@
AI.remote_control = src
AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES.
- AI << "[interaction == AI_MECH_HACK ? "Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!" \
+ AI << "[interaction == AI_MECH_HACK ? "Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!" \
: "You have been uploaded to a mech's onboard computer."]"
- AI << "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions."
+ AI << "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions."
GrantActions(AI)
diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm
index f60b14f7202..29a5fa39737 100644
--- a/code/game/mecha/mecha_wreckage.dm
+++ b/code/game/mecha/mecha_wreckage.dm
@@ -14,6 +14,23 @@
var/list/wirecutters_salvage = list(/obj/item/stack/cable_coil)
var/list/crowbar_salvage = list()
var/salvage_num = 5
+ var/mob/living/silicon/ai/AI //AIs to be salvaged
+
+/obj/structure/mecha_wreckage/New(loc, mob/living/silicon/ai/AI_pilot)
+ ..()
+ if(AI_pilot) //Type-checking for this is already done in mecha/Destroy()
+ AI = AI_pilot
+ AI.apply_damage(150, BURN) //Give the AI a bit of damage from the "shock" of being suddenly shut down
+ AI.death() //The damage is not enough to kill the AI, but to be 'corrupted files' in need of repair.
+ AI.forceMove(src) //Put the dead AI inside the wreckage for recovery
+ add_overlay(image('icons/obj/projectiles.dmi', icon_state = "green_laser")) //Overlay for the recovery beacon
+ AI.controlled_mech = null
+ AI.remote_control = null
+
+/obj/structure/mecha_wreckage/examine(mob/user)
+ ..()
+ if(AI)
+ user << "The AI recovery beacon is active."
/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/weldingtool))
@@ -58,6 +75,25 @@
else
user << "You don't see anything that can be pried with [I]!"
+
+/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, null, obj/item/device/aicard/card)
+ if(!..())
+ return
+
+ //Proc called on the wreck by the AI card.
+ if(interaction == AI_TRANS_TO_CARD) //AIs can only be transferred in one direction, from the wreck to the card.
+ if(!AI) //No AI in the wreck
+ user << "No AI backups found."
+ return
+ cut_overlays() //Remove the recovery beacon overlay
+ AI.forceMove(card) //Move the dead AI to the card.
+ card.AI = AI
+ if(AI.client) //AI player is still in the dead AI and is connected
+ AI << "The remains of your file system have been recovered on a mobile storage device."
+ else //Give the AI a heads-up that it is probably going to get fixed.
+ AI.notify_ghost_cloning("You have been recovered from the wreckage!", source = card)
+ user << "Backup files recovered: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory."
+
else
return ..()