#define APC_WIRE_IDSCAN 1 #define APC_WIRE_MAIN_POWER1 2 #define APC_WIRE_MAIN_POWER2 3 #define APC_WIRE_AI_CONTROL 4 // the Area Power Controller (APC), formerly Power Distribution Unit (PDU) // one per area, needs wire conection to power network // controls power to devices in that area // may be opened to change power cell // three different channels (lighting/equipment/environ) - may each be set to on, off, or auto //NOTE: STUFF STOLEN FROM AIRLOCK.DM thx /obj/machinery/power/apc name = "area power controller" icon_state = "apc0" anchored = 1 req_access = list(access_engine_equip) var/area/area var/areastring = null var/obj/item/weapon/cell/cell var/start_charge = 90 // initial cell charge % var/cell_type = 2500 // 0=no cell, 1=regular, 2=high-cap (x5) <- old, now it's just 0=no cell, otherwise dictate cellcapacity by changing this value. 1 used to be 1000, 2 was 2500 var/opened = 0 //0=closed, 1=opened, 2=cover removed var/shorted = 0 var/lighting = 3 var/equipment = 3 var/environ = 3 var/operating = 1 var/charging = 0 var/chargemode = 1 var/chargecount = 0 var/locked = 1 var/coverlocked = 1 var/aidisabled = 0 var/tdir = null var/obj/machinery/power/terminal/terminal = null var/lastused_light = 0 var/lastused_equip = 0 var/lastused_environ = 0 var/lastused_total = 0 var/main_status = 0 var/light_consumption = 0 //not used var/equip_consumption = 0 //not used var/environ_consumption = 0 //not used var/emagged = 0 var/wiresexposed = 0 var/apcwires = 15 netnum = -1 // set so that APCs aren't found as powernet nodes var/malfhack = 0 //New var for my changes to AI malf. --NeoFite var/mob/living/silicon/ai/malfai = null //See above --NeoFite // luminosity = 1 var/has_electronics = 0 // 0 - none, 1 - plugged in, 2 - secured by screwdriver var/overload = 1 //used for the Blackout malf module /proc/RandomAPCWires() //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). var/list/apcwires = list(0, 0, 0, 0) APCIndexToFlag = list(0, 0, 0, 0) APCIndexToWireColor = list(0, 0, 0, 0) APCWireColorToIndex = list(0, 0, 0, 0) var/flagIndex = 1 for (var/flag=1, flag<16, flag+=flag) var/valid = 0 while (!valid) var/colorIndex = rand(1, 4) if (apcwires[colorIndex]==0) valid = 1 apcwires[colorIndex] = flag APCIndexToFlag[flagIndex] = flag APCIndexToWireColor[flagIndex] = colorIndex APCWireColorToIndex[colorIndex] = flagIndex flagIndex+=1 return apcwires /obj/machinery/power/apc/updateDialog() if (stat & (BROKEN|MAINT)) return var/list/nearby = viewers(1, src) for(var/mob/M in nearby) if (M.client && M.machine == src) src.interact(M) AutoUpdateAI(src) /obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0) ..() // offset 24 pixels in direction of dir // this allows the APC to be embedded in a wall, yet still inside an area if (building) dir = ndir src.tdir = dir // to fix Vars bug dir = SOUTH pixel_x = (src.tdir & 3)? 0 : (src.tdir == 4 ? 24 : -24) pixel_y = (src.tdir & 3)? (src.tdir ==1 ? 24 : -24) : 0 if (building==0) init() else area = src.loc.loc:master opened = 1 operating = 0 name = "[area.name] APC" stat |= MAINT src.updateicon() spawn(5) src.update() /obj/machinery/power/apc/proc/make_terminal() // create a terminal object at the same position as original turf loc // wires will attach to this terminal = new/obj/machinery/power/terminal(src.loc) terminal.dir = tdir terminal.master = src /obj/machinery/power/apc/proc/init() has_electronics = 2 //installed and secured // is starting with a power cell installed, create it and set its charge level if(cell_type) src.cell = new/obj/item/weapon/cell(src) cell.maxcharge = cell_type // cell_type is maximum charge (old default was 1000 or 2500 (values one and two respectively) cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value) var/area/A = src.loc.loc //if area isn't specified use current if(isarea(A) && src.areastring == null) src.area = A else src.area = get_area_name(areastring) updateicon() make_terminal() spawn(5) src.update() /obj/machinery/power/apc/examine() set src in oview(1) if(usr /*&& !usr.stat*/) usr << "A control terminal for the area electrical systems." if(stat & BROKEN) usr << "Looks broken." return if(opened) if(has_electronics && terminal) usr << "The cover is [opened==2?"removed":"open"] and the power cell is [ cell ? "installed" : "missing"]." else if (!has_electronics && terminal) usr << "There are some wires but no any electronics." else if (has_electronics && !terminal) usr << "Electronics installed but not wired." else /* if (!has_electronics && !terminal) */ usr << "There is no electronics nor connected wires." else if (stat & MAINT) usr << "The cover is closed. Something wrong with it: it's doesn't work." else if (malfhack) usr << "The cover is broken. It's may be hard to force it open." else usr << "The cover is closed." // update the APC icon to show the three base states // also add overlays for indicator lights /obj/machinery/power/apc/proc/updateicon() src.overlays = null if(opened) var/basestate = "apc[ cell ? "2" : "1" ]" // if opened, show cell if it's inserted if (opened==1) if (stat & (MAINT|BROKEN)) icon_state = "apcmaint" //disassembled APC cannot hold cell else icon_state = basestate else if (opened == 2) if ((stat & BROKEN) || malfhack ) icon_state = "[basestate]-b-nocover" else /* if (emagged)*/ icon_state = "[basestate]-nocover" else if (stat & BROKEN) icon_state = "apc-b" else if(emagged || malfhack) icon_state = "apcemag" else if(wiresexposed) icon_state = "apcewires" else icon_state = "apc0" // if closed, update overlays for channel status if (!(stat & (BROKEN|MAINT))) overlays += image('power.dmi', "apcox-[locked]") // 0=blue 1=red overlays += image('power.dmi', "apco3-[charging]") // 0=red, 1=yellow/black 2=green if(operating) overlays += image('power.dmi', "apco0-[equipment]") // 0=red, 1=green, 2=blue overlays += image('power.dmi', "apco1-[lighting]") overlays += image('power.dmi', "apco2-[environ]") //attack with an item - open/close cover, insert cell, or (un)lock interface /obj/machinery/power/apc/attackby(obj/item/W, mob/user) if (istype(user, /mob/living/silicon) && get_dist(src,user)>1) return src.attack_hand(user) if (istype(W, /obj/item/weapon/crowbar) && opened) if (has_electronics==1) if (terminal) user << "\red Disconnect wires first." return playsound(src.loc, 'Crowbar.ogg', 50, 1) user << "You trying to remove the power control board..." if(do_after(user, 50)) has_electronics = 0 if ((stat & BROKEN) || malfhack) user.visible_message(\ "\red [user.name] has broken the power control board inside [src.name]!",\ "You broke the charred power control board and remove remains.", "You hear crack") //ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0 else user.visible_message(\ "\red [user.name] has removed the power control board from [src.name]!",\ "You remove the power control board.") new /obj/item/weapon/module/power_control(loc) else if (opened!=2) //cover isn't removed opened = 0 updateicon() else if (istype(W, /obj/item/weapon/crowbar) && !((stat & BROKEN) || malfhack) ) if(coverlocked && !(stat & MAINT)) user << "\red The cover is locked and cannot be opened." return else opened = 1 updateicon() else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside if(cell) user << "There is a power cell already installed." return else if (stat & MAINT) user << "\red There is no any connector for your power cell." return user.drop_item() W.loc = src cell = W user.visible_message(\ "\red [user.name] has inserted the power cell to [src.name]!",\ "You insert the power cell.") chargecount = 0 updateicon() else if (istype(W, /obj/item/weapon/screwdriver)) // haxing if(opened) if (cell) user << "\red Close the APC first." //Less hints more mystery! return else if (has_electronics==1 && terminal) has_electronics = 2 stat &= ~MAINT playsound(src.loc, 'Screwdriver.ogg', 50, 1) user << "You screw the circuit electronics into place." else if (has_electronics==2) has_electronics = 1 stat |= MAINT playsound(src.loc, 'Screwdriver.ogg', 50, 1) user << "You unfasten the electronics." else /* has_electronics==0 */ user << "\red There is nothing to secure." return updateicon() else if(emagged || malfhack) user << "The interface is broken" else wiresexposed = !wiresexposed user << "The wires have been [wiresexposed ? "exposed" : "unexposed"]" updateicon() else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card if(emagged || malfhack) user << "The interface is broken." else if(opened) user << "You must close the cover to swipe an ID card." else if(wiresexposed) user << "You must close the panel" else if(stat & (BROKEN|MAINT)) user << "Nothing happens." else if(src.allowed(usr)) locked = !locked user << "You [ locked ? "lock" : "unlock"] the APC interface." updateicon() else user << "\red Access denied." else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || malfhack)) // trying to unlock with an emag card if(opened) user << "You must close the cover to swipe an ID card." else if(wiresexposed) user << "You must close the panel first" else if(stat & (BROKEN|MAINT)) user << "Nothing happens." else flick("apc-spark", src) if (do_after(user,6)) if(prob(50)) emagged = 1 locked = 0 user << "You emag the APC interface." updateicon() else user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." else if (istype(W, /obj/item/weapon/cable_coil) && !terminal && opened && has_electronics!=2) if (src.loc:intact) user << "\red You must remove the floor plating first." return var/obj/item/weapon/cable_coil/C = W if(C.amount < 10) user << "\red You need more wires." return user << "You start adding cables to the APC frame..." playsound(src.loc, 'Deconstruct.ogg', 50, 1) if(do_after(user, 20) && C.amount >= 10) var/turf/T = get_turf_loc(src) var/obj/cable/N = T.get_cable_node() if (prob(50) && electrocute_mob(usr, N, N)) var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread s.set_up(5, 1, src) s.start() return C.use(10) user.visible_message(\ "\red [user.name] has added cables to the APC frame!",\ "You add cables to the APC frame.") make_terminal() terminal.connect_to_network() else if (istype(W, /obj/item/weapon/wirecutters) && terminal && opened && has_electronics!=2) if (src.loc:intact) user << "\red You must remove the floor plating first." return user << "You begin to cut cables..." playsound(src.loc, 'Deconstruct.ogg', 50, 1) if(do_after(user, 50)) if (prob(50) && electrocute_mob(usr, terminal.powernet, terminal)) var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread s.set_up(5, 1, src) s.start() return new /obj/item/weapon/cable_coil(loc,10) user.visible_message(\ "\red [user.name] cut cables and dismantled the power terminal.",\ "You cut cables and dismantle the power terminal.") del(terminal) else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN) || malfhack)) user << "You trying to insert the power control board into the frame..." playsound(src.loc, 'Deconstruct.ogg', 50, 1) if(do_after(user, 10)) has_electronics = 1 user << "You place the power control board inside the frame." del(W) else if (istype(W, /obj/item/weapon/weldingtool) && W:welding && opened && has_electronics==0 && !terminal) if (W:get_fuel() < 3) user << "\blue You need more welding fuel to complete this task." return user << "You start welding APC frame..." if(W:remove_fuel(2,user)) playsound(src.loc, 'Welder.ogg', 50, 1) if(do_after(user, 50)) if (emagged || malfhack || (stat & BROKEN) || opened==2) new /obj/item/stack/sheet/metal(loc) user.visible_message(\ "\red [src] has been cut apart by [user.name] with the weldingtool.",\ "You disassembled brocken APC frame.",\ "\red You hear welding.") else new /obj/item/apc_frame(loc) user.visible_message(\ "\red [src] has been cut from the wall by [user.name] with the weldingtool.",\ "You cut APC frame from the wall.",\ "\red You hear welding.") del(src) return else if (istype(W, /obj/item/apc_frame) && opened && emagged) emagged = 0 if (opened==2) opened = 1 user.visible_message(\ "\red [user.name] has replaced the damaged APC frontal panel with new one.",\ "You replace the damaged APC frontal panel with new one.") del(W) updateicon() else if (istype(W, /obj/item/apc_frame) && opened && ((stat & BROKEN) || malfhack)) if (has_electronics) user << "You cannot repair this heavy damaged APC until broken electronics stills inside." return user << "You begin to replace the damaged APC frame..." if(do_after(user, 50)) user.visible_message(\ "\red [user.name] has replaced the damaged APC frame with new one.",\ "You replace the damaged APC frame with new one.") del(W) stat &= ~BROKEN malfai = null malfhack = 0 if (opened==2) opened = 1 updateicon() else if ( ((stat & BROKEN) || malfhack) \ && !opened \ && W.force >= 5 \ && W.w_class >= 3.0 \ && prob(20) ) opened = 2 user.visible_message("\red The APC cover was knocked down with the [W.name] by [user.name]!", \ "\red You knock down the APC cover with your [W.name]!", \ "You hear bang") updateicon() else if (istype(user, /mob/living/silicon)) return src.attack_hand(user) if (wiresexposed && \ (istype(W, /obj/item/device/multitool) || \ istype(W, /obj/item/weapon/wirecutters))) return src.attack_hand(user) user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ "\red You hit the [src.name] with your [W.name]!", \ "You hear bang") // attack with hand - remove cell (if cover open) or interact with the APC /obj/machinery/power/apc/attack_hand(mob/user) add_fingerprint(user) if(opened && (!istype(user, /mob/living/silicon))) if(cell) usr.put_in_hand(cell) cell.add_fingerprint(user) cell.updateicon() src.cell = null user.visible_message("\red [user.name] removes the power cell from [src.name]!", "You remove the power cell.") //user << "You remove the power cell." charging = 0 src.updateicon() else if(stat & (BROKEN|MAINT)) return // do APC interaction user.machine = src src.interact(user) /obj/machinery/power/apc/proc/interact(mob/user) if ( (get_dist(src, user) > 1 )) if (!istype(user, /mob/living/silicon)) user.machine = null user << browse(null, "window=apc") return else if (istype(user, /mob/living/silicon) && src.aidisabled && !src.malfhack) user << "AI control for this APC interface has been disabled." user << browse(null, "window=apc") return else if (src.malfai) if (src.malfai != user) user << "AI control for this APC interface has been disabled." user << browse(null, "window=apc") return if(wiresexposed && (!istype(user, /mob/living/silicon))) var/t1 = text("
"
var/list/L = list ("Off","Off (Auto)", "On", "On (Auto)")
t += "Equipment: [add_lspace(lastused_equip, 6)] W : [L[equipment+1]]
"
t += "Lighting: [add_lspace(lastused_light, 6)] W : [L[lighting+1]]
"
t += "Environmental:[add_lspace(lastused_environ, 6)] W : [L[environ+1]]
"
t += "
Total load: [lastused_light + lastused_equip + lastused_environ] W"
t += "" t += "Equipment: [add_lspace(lastused_equip, 6)] W : " switch(equipment) if(0) t += "Off On Auto" if(1) t += "Off On Auto (Off)" if(2) t += "Off On Auto" if(3) t += "Off On Auto (On)" t +="" t += "
" t += "Lighting: [add_lspace(lastused_light, 6)] W : " switch(lighting) if(0) t += "Off On Auto" if(1) t += "Off On Auto (Off)" if(2) t += "Off On Auto" if(3) t += "Off On Auto (On)" t +="
" t += "Environmental:[add_lspace(lastused_environ, 6)] W : " switch(environ) if(0) t += "Off On Auto" if(1) t += "Off On Auto (Off)" if(2) t += "Off On Auto" if(3) t += "Off On Auto (On)" t += "
Total load: [lastused_light + lastused_equip + lastused_environ] W