/obj/machinery/computer/apc_control
name = "power flow control console"
desc = "Used to remotely control the flow of power to different parts of the station."
icon_screen = "solar"
icon_keyboard = "power_key"
req_access = list(GLOB.access_engine)
circuit = /obj/item/weapon/circuitboard/computer/apc_control
light_color = LIGHT_COLOR_YELLOW
var/list/apcs //APCs the computer has access to
var/mob/living/operator //Who's operating the computer right now
var/obj/machinery/power/apc/active_apc //The APC we're using right now
var/list/filters //For sorting the results
var/checking_logs = 0
var/list/logs
var/authenticated = 0
var/auth_id = "\[NULL\]"
/obj/machinery/computer/apc_control/Initialize()
apcs = list() //To avoid BYOND making the list run through a ton of procs
filters = list("Name" = null, "Charge Above" = null, "Charge Below" = null, "Responsive" = null)
..()
/obj/machinery/computer/apc_control/process()
apcs = list() //Clear the list every tick
for(var/V in GLOB.apcs_list)
var/obj/machinery/power/apc/APC = V
if(check_apc(APC))
apcs[APC.name] = APC
if(operator && (!operator.Adjacent(src) || stat))
operator = null
if(active_apc)
if(!active_apc.locked)
active_apc.say("Remote access canceled. Interface locked.")
playsound(active_apc, 'sound/machines/BoltsDown.ogg', 25, 0)
playsound(active_apc, 'sound/machines/terminal_alert.ogg', 50, 0)
active_apc.locked = TRUE
active_apc.update_icon()
active_apc = null
/obj/machinery/computer/apc_control/attack_ai(mob/user)
if(!IsAdminGhost(user))
to_chat(user,"[src] does not support AI control.") //You already have APC access, cheater!
return
..(user)
/obj/machinery/computer/apc_control/proc/check_apc(obj/machinery/power/apc/APC)
return APC.z == z && !APC.malfhack && !APC.aidisabled && !APC.emagged && !APC.stat && !istype(APC.area, /area/ai_monitored) && !APC.area.outdoors
/obj/machinery/computer/apc_control/interact(mob/living/user)
var/dat
if(authenticated)
if(!checking_logs)
dat += "Logged in as [auth_id].
"
dat += "Filters
"
dat += "Name: [filters["Name"] ? filters["Name"] : "None set"]
"
dat += "Charge: \>[filters["Charge Above"] ? filters["Charge Above"] : "NaN"]% and \<[filters["Charge Below"] ? filters["Charge Below"] : "NaN"]%
"
dat += "Accessible: [filters["Responsive"] ? "Non-Responsive Only" : "All"]
"
for(var/A in apcs)
var/obj/machinery/power/apc/APC = apcs[A]
if(filters["Name"] && !findtext(APC.name, filters["Name"]) && !findtext(APC.area.name, filters["Name"]))
continue
if(filters["Charge Above"] && (APC.cell.charge / APC.cell.maxcharge) < filters["Charge Above"] / 100)
continue
if(filters["Charge Below"] && (APC.cell.charge / APC.cell.maxcharge) > filters["Charge Below"] / 100)
continue
if(filters["Responsive"] && !APC.aidisabled)
continue
dat += "[A]
\
Charge: [APC.cell.charge] / [APC.cell.maxcharge] W ([round((APC.cell.charge / APC.cell.maxcharge) * 100)]%)
\
Area: [APC.area]
\
[APC.aidisabled || APC.panel_open ? "APC does not respond to interface query." : "APC responds to interface query."]
"
dat += "Check Logs
"
dat += "Log Out
"
if(emagged)
dat += "WARNING: Logging functionality partially disabled from outside source.
"
dat += "Restore logging functionality?
"
else
if(logs.len)
for(var/entry in logs)
dat += "[entry]
"
else
dat += "No activity has been recorded at this time.
"
if(emagged)
dat += "@#%! CLEAR LOGS"
dat += "Return"
operator = user
else
dat = "Please swipe a valid ID to log in..."
var/datum/browser/popup = new(user, "apc_control", name, 600, 400)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/apc_control/Topic(href, href_list)
if(..())
return
if(!usr || !usr.canUseTopic(src) || usr.incapacitated() || stat || QDELETED(src))
return
if(href_list["authenticate"])
var/obj/item/weapon/card/id/ID = usr.get_active_held_item()
if(!istype(ID))
ID = usr.get_idcard()
if(ID && istype(ID))
if(check_access(ID))
authenticated = TRUE
auth_id = "[ID.registered_name] ([ID.assignment])"
log_activity("logged in")
if(!authenticated) //Check for emags
var/obj/item/weapon/card/emag/E = usr.get_active_held_item()
if(E && istype(E) && usr.Adjacent(src))
to_chat(usr, "You bypass [src]'s access requirements using your emag.")
authenticated = TRUE
log_activity("logged in") //Auth ID doesn't change, hinting that it was illicit
if(href_list["log_out"])
log_activity("logged out")
authenticated = FALSE
auth_id = "\[NULL\]"
if(href_list["restore_logging"])
to_chat(usr, "\icon[src] Logging functionality restored from backup data.")
emagged = FALSE
LAZYADD(logs, "-=- Logging restored to full functionality at this point -=-")
if(href_list["access_apc"])
playsound(src, "terminal_type", 50, 0)
var/obj/machinery/power/apc/APC = locate(href_list["access_apc"]) in GLOB.apcs_list
if(!APC || APC.aidisabled || APC.panel_open || QDELETED(APC))
to_chat(usr, "\icon[src] APC does not return interface request. Remote access may be disabled.")
return
if(active_apc)
to_chat(usr, "\icon[src] Disconnected from [active_apc].")
active_apc.say("Remote access canceled. Interface locked.")
playsound(active_apc, 'sound/machines/BoltsDown.ogg', 25, 0)
playsound(active_apc, 'sound/machines/terminal_alert.ogg', 50, 0)
active_apc.locked = TRUE
active_apc.update_icon()
active_apc = null
to_chat(usr, "\icon[src] Connected to APC in [get_area(APC)]. Interface request sent.")
log_activity("remotely accessed APC in [get_area(APC)]")
APC.interact(usr, GLOB.not_incapacitated_state)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
message_admins("[key_name_admin(usr)] remotely accessed [APC] from [src] at [get_area(src)].")
log_game("[key_name_admin(usr)] remotely accessed [APC] from [src] at [get_area(src)].")
if(APC.locked)
APC.say("Remote access detected. Interface unlocked.")
playsound(APC, 'sound/machines/BoltsUp.ogg', 25, 0)
playsound(APC, 'sound/machines/terminal_alert.ogg', 50, 0)
APC.locked = FALSE
APC.update_icon()
active_apc = APC
if(href_list["name_filter"])
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
var/new_filter = stripped_input(usr, "What name are you looking for?", name) as null|text
if(!src || !usr || !usr.canUseTopic(src) || stat || QDELETED(src))
return
log_activity("changed name filter to \"[new_filter]\"")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
filters["Name"] = new_filter
if(href_list["above_filter"])
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
var/new_filter = input(usr, "Enter a percentage from 1-100 to sort by (greater than).", name) as null|num
if(!src || !usr || !usr.canUseTopic(src) || stat || QDELETED(src))
return
log_activity("changed greater than charge filter to \"[new_filter]\"")
if(new_filter)
new_filter = Clamp(new_filter, 0, 100)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
filters["Charge Above"] = new_filter
if(href_list["below_filter"])
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
var/new_filter = input(usr, "Enter a percentage from 1-100 to sort by (lesser than).", name) as null|num
if(!src || !usr || !usr.canUseTopic(src) || stat || QDELETED(src))
return
log_activity("changed lesser than charge filter to \"[new_filter]\"")
if(new_filter)
new_filter = Clamp(new_filter, 0, 100)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
filters["Charge Below"] = new_filter
if(href_list["access_filter"])
if(isnull(filters["Responsive"]))
filters["Responsive"] = 1
log_activity("sorted by non-responsive APCs only")
else
filters["Responsive"] = !filters["Responsive"]
log_activity("sorted by all APCs")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
if(href_list["check_logs"])
checking_logs = TRUE
log_activity("checked logs")
if(href_list["check_apcs"])
checking_logs = FALSE
log_activity("checked APCs")
if(href_list["clear_logs"])
logs = list()
interact(usr) //Refresh the UI after a filter changes
/obj/machinery/computer/apc_control/emag_act(mob/living/user)
if(emagged)
return
user.visible_message("You emag [src], disabling precise logging and allowing you to clear logs.")
log_game("[key_name_admin(user)] emagged [src] at [get_area(src)], disabling operator tracking.")
playsound(src, "sparks", 50, 1)
emagged = 1
/obj/machinery/computer/apc_control/proc/log_activity(log_text)
var/op_string = operator && !emagged ? operator : "\[NULL OPERATOR\]"
LAZYADD(logs, "([worldtime2text()]) [op_string] [log_text]")
/mob/proc/using_power_flow_console()
for(var/obj/machinery/computer/apc_control/A in range(1, src))
if(A.operator && A.operator == src && !A.stat)
return TRUE
return