diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 04368ee333a..6a1e4d20737 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -74,7 +74,7 @@
var/turf/waypoint //Holds the turf of the currently selected waypoint.
var/waypoint_mode = FALSE //Waypoint mode is for selecting a turf via clicking.
var/call_bot_cooldown = 0 //time of next call bot command
- var/apc_override = FALSE //hack for letting the AI use its APC even when visionless
+ var/obj/machinery/power/apc/apc_override //Ref of the AI's APC, used when the AI has no power in order to access their APC.
var/nuking = FALSE
var/obj/machinery/doomsday_device/doomsday_device
@@ -210,6 +210,7 @@
Bot = null
controlled_mech = null
linked_core = null
+ apc_override = null
return ..()
/// Removes all malfunction-related abilities from the AI
@@ -391,8 +392,19 @@
/mob/living/silicon/ai/Topic(href, href_list)
..()
- if(usr != src || incapacitated())
+ if(usr != src)
return
+
+ if(href_list["emergencyAPC"]) //This check comes before incapacitated() because the only time it would be useful is when we have no power.
+ if(!apc_override)
+ to_chat(src, "APC backdoor is no longer available.")
+ return
+ apc_override.ui_interact(src)
+ return
+
+ if(incapacitated())
+ return
+
if (href_list["mach_close"])
if (href_list["mach_close"] == "aialerts")
viewalerts = 0
@@ -812,7 +824,7 @@
if(isturf(loc)) //AI in core, check if on cameras
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
//apc_override is needed here because AIs use their own APC when depowered
- return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override
+ return ((GLOB.cameranet && GLOB.cameranet.checkTurfVis(get_turf_pixel(A))) || (A == apc_override))
//AI is carded/shunted
//view(src) returns nothing for carded/shunted AIs and they have X-ray vision so just use get_dist
var/list/viewscale = getviewsize(client.view)
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 028b574353c..68977d4045d 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -144,9 +144,9 @@
sleep(50)
to_chat(src, "Receiving control information from APC.")
sleep(2)
- apc_override = 1
- theAPC.ui_interact(src)
- apc_override = 0
+ to_chat(src, "APC ready for connection.")
+ apc_override = theAPC
+ apc_override.ui_interact(src)
setAiRestorePowerRoutine(POWER_RESTORATION_APC_FOUND)
sleep(50)
theAPC = null
@@ -155,10 +155,13 @@
if(aiRestorePowerRoutine)
if(aiRestorePowerRoutine == POWER_RESTORATION_APC_FOUND)
to_chat(src, "Alert cancelled. Power has been restored.")
+ if(apc_override)
+ to_chat(src, "APC backdoor has been closed.") //Fluff for why we have to hack every time.
else
to_chat(src, "Alert cancelled. Power has been restored without our assistance.")
setAiRestorePowerRoutine(POWER_RESTORATION_OFF)
set_blindness(0)
+ apc_override = null
update_sight()
/mob/living/silicon/ai/proc/ai_lose_power()
diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm
index aff19f69d4b..03989573fbd 100644
--- a/code/modules/mob/living/silicon/ai/login.dm
+++ b/code/modules/mob/living/silicon/ai/login.dm
@@ -8,6 +8,8 @@
O.mode = 1
O.emotion = "Neutral"
O.update()
+ if(lacks_power() && apc_override) //Placing this in Login() in case the AI doesn't have this link for whatever reason.
+ to_chat(usr, "Main power is unavailable, backup power in use. Diagnostics scan complete. Local APC ready for connection.")
set_eyeobj_visible(TRUE)
if(multicam_on)
end_multicam()
diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm
index 62cb2ded81d..73c053254d8 100644
--- a/code/modules/tgui/states.dm
+++ b/code/modules/tgui/states.dm
@@ -78,6 +78,8 @@
/mob/living/silicon/ai/shared_ui_interaction(src_object)
// Disable UIs if the AI is unpowered.
+ if(apc_override == src_object) //allows AI to (eventually) use the interface for their own APC even when out of power
+ return UI_INTERACTIVE
if(lacks_power())
return UI_DISABLED
return ..()