// the SMES // stores power #define SMESMAXCHARGELEVEL 200000 #define SMESMAXOUTPUT 200000 /obj/machinery/power/smes name = "power storage unit" desc = "A high-capacity superconducting magnetic energy storage (SMES) unit." icon_state = "smes" density = 1 anchored = 1 use_power = 0 var/output = 50000 var/lastout = 0 var/loaddemand = 0 var/capacity = 5e6 var/charge = 1e6 var/charging = 0 var/chargemode = 0 var/chargecount = 0 var/chargelevel = 50000 var/online = 1 var/name_tag = null var/obj/machinery/power/terminal/terminal = null //Holders for powerout event. var/last_output = 0 var/last_charge = 0 var/last_online = 0 /obj/machinery/power/smes/New() ..() spawn(5) dir_loop: for(var/d in cardinal) var/turf/T = get_step(src, d) for(var/obj/machinery/power/terminal/term in T) if(term && term.dir == turn(d, 180)) terminal = term break dir_loop if(!terminal) stat |= BROKEN return terminal.master = src updateicon() return /obj/machinery/power/smes/proc/updateicon() overlays.Cut() if(stat & BROKEN) return overlays += image('icons/obj/power.dmi', "smes-op[online]") if(charging) overlays += image('icons/obj/power.dmi', "smes-oc1") else if(chargemode) overlays += image('icons/obj/power.dmi', "smes-oc0") var/clevel = chargedisplay() if(clevel>0) overlays += image('icons/obj/power.dmi', "smes-og[clevel]") return /obj/machinery/power/smes/proc/chargedisplay() return round(5.5*charge/(capacity ? capacity : 5e6)) #define SMESRATE 0.05 // rate of internal charge to external power /obj/machinery/power/smes/process() if(stat & BROKEN) return //store machine state to see if we need to update the icon overlays var/last_disp = chargedisplay() var/last_chrg = charging var/last_onln = online if(terminal) var/excess = terminal.surplus() if(charging) if(excess >= 0) // if there's power available, try to charge var/load = min((capacity-charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity charge += load * SMESRATE // increase the charge add_load(load) // add the load to the terminal side network else // if not enough capcity charging = 0 // stop charging chargecount = 0 else if(chargemode) if(chargecount > rand(3,6)) charging = 1 chargecount = 0 if(excess > chargelevel) chargecount++ else chargecount = 0 else chargecount = 0 if(online) // if outputting lastout = min( charge/SMESRATE, output) //limit output to that stored charge -= lastout*SMESRATE // reduce the storage (may be recovered in /restore() if excessive) add_avail(lastout) // add output to powernet (smes side) if(charge < 0.0001) online = 0 // stop output if charge falls to zero // only update icon if state changed if(last_disp != chargedisplay() || last_chrg != charging || last_onln != online) updateicon() return // called after all power processes are finished // restores charge level to smes if there was excess this ptick /obj/machinery/power/smes/proc/restore() if(stat & BROKEN) return if(!online) loaddemand = 0 return var/excess = powernet.netexcess // this was how much wasn't used on the network last ptick, minus any removed by other SMESes excess = min(lastout, excess) // clamp it to how much was actually output by this SMES last ptick excess = min((capacity-charge)/SMESRATE, excess) // for safety, also limit recharge by space capacity of SMES (shouldn't happen) // now recharge this amount var/clev = chargedisplay() charge += excess * SMESRATE powernet.netexcess -= excess // remove the excess from the powernet, so later SMESes don't try to use it loaddemand = lastout-excess if(clev != chargedisplay() ) updateicon() return /obj/machinery/power/smes/add_load(var/amount) if(terminal && terminal.powernet) terminal.powernet.newload += amount /obj/machinery/power/smes/attack_ai(mob/user) add_fingerprint(user) ui_interact(user) /obj/machinery/power/smes/attack_hand(mob/user) add_fingerprint(user) ui_interact(user) /obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null) if(stat & BROKEN) return // this is the data which will be sent to the ui var/data[0] data["nameTag"] = name_tag data["storedCapacity"] = round(100.0*charge/capacity, 0.1) data["charging"] = charging data["chargeMode"] = chargemode data["chargeLevel"] = chargelevel data["chargeMax"] = SMESMAXCHARGELEVEL data["outputOnline"] = online data["outputLevel"] = output data["outputMax"] = SMESMAXOUTPUT data["outputLoad"] = round(loaddemand) // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data) if (!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "smes.tmpl", "SMES Power Storage Unit", 540, 380) // when the ui is first opened this is the data it will use ui.set_initial_data(data) // open the new ui window ui.open() // auto update every Master Controller tick ui.set_auto_update(1) /obj/machinery/power/smes/Topic(href, href_list) ..() if (usr.stat || usr.restrained() ) return if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") if(!istype(usr, /mob/living/silicon/ai)) usr << "\red You don't have the dexterity to do this!" return //world << "[href] ; [href_list[href]]" if (!istype(src.loc, /turf) && !istype(usr, /mob/living/silicon/)) return 0 // Do not update ui if( href_list["cmode"] ) chargemode = !chargemode if(!chargemode) charging = 0 updateicon() else if( href_list["online"] ) online = !online updateicon() else if( href_list["input"] ) switch( href_list["input"] ) if("min") chargelevel = 0 if("max") chargelevel = SMESMAXCHARGELEVEL //30000 if("set") chargelevel = input(usr, "Enter new input level (0-[SMESMAXCHARGELEVEL])", "SMES Input Power Control", chargelevel) as num chargelevel = max(0, min(SMESMAXCHARGELEVEL, chargelevel)) // clamp to range else if( href_list["output"] ) switch( href_list["output"] ) if("min") output = 0 if("max") output = SMESMAXOUTPUT //30000 if("set") output = input(usr, "Enter new output level (0-[SMESMAXOUTPUT])", "SMES Output Power Control", output) as num output = max(0, min(SMESMAXOUTPUT, output)) // clamp to range investigate_log("input/output; [chargelevel>output?"":""][chargelevel]/[output] | Output-mode: [online?"on":"off"] | Input-mode: [chargemode?"auto":"off"] by [usr.key]","singulo") return 1 /obj/machinery/power/smes/proc/ion_act() if(src.z == 1) if(prob(1)) //explosion world << "\red SMES explosion in [src.loc.loc]" for(var/mob/M in viewers(src)) M.show_message("\red The [src.name] is making strange noises!", 3, "\red You hear sizzling electronics.", 2) sleep(10*pick(4,5,6,7,10,14)) var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() smoke.set_up(3, 0, src.loc) smoke.attach(src) smoke.start() explosion(src.loc, -1, 0, 1, 3, 0) del(src) return if(prob(15)) //Power drain world << "\red SMES power drain in [src.loc.loc]" var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() if(prob(50)) emp_act(1) else emp_act(2) if(prob(5)) //smoke only world << "\red SMES smoke in [src.loc.loc]" var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() smoke.set_up(3, 0, src.loc) smoke.attach(src) smoke.start() /obj/machinery/power/smes/emp_act(severity) online = 0 charging = 0 output = 0 charge -= 1e6/severity if (charge < 0) charge = 0 spawn(100) output = initial(output) charging = initial(charging) online = initial(online) ..() /obj/machinery/power/smes/magical name = "magical power storage unit" desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. Magically produces power." process() capacity = INFINITY charge = INFINITY ..() /proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null) var/href = "-[href]=-[Min]'>- [(C?C : 0)] [href]=[Min]'>+[href]=[Max]'>+" if(Limit) return "[href]=-[Limit]'>-"+rate+"[href]=[Limit]'>+" return rate #undef SMESRATE