// the SMES // stores power #define SMESMAXCHARGELEVEL 200000 #define SMESMAXOUTPUT 200000 /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 ..() /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 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/n_tag = null var/obj/machinery/power/terminal/terminal = null /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() /obj/machinery/power/smes/proc/updateicon() overlays = null if(stat & BROKEN) return overlays += image('power.dmi', "smes-op[online]") if(charging) overlays += image('power.dmi', "smes-oc1") else if(chargemode) overlays += image('power.dmi', "smes-oc0") var/clevel = chargedisplay() if(clevel>0) overlays += image('power.dmi', "smes-og[clevel]") /obj/machinery/power/smes/proc/chargedisplay() return round(5.5*charge/capacity) #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() for(var/mob/M in viewers(1, src)) if ((M.client && M.machine == src)) src.interact(M) AutoUpdateAI(src) // 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() /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) if(stat & BROKEN) return interact(user) /obj/machinery/power/smes/attack_hand(mob/user) add_fingerprint(user) if(stat & BROKEN) return if(ishuman(user)) var/mob/living/carbon/human/U = user if(istype(U.gloves, /obj/item/clothing/gloves/space_ninja)&&U.gloves:candrain&&!U.gloves:draining) var/obj/item/clothing/suit/space/space_ninja/S = U.wear_suit var/obj/item/clothing/gloves/space_ninja/G = U.gloves user << "\blue Now charging battery..." G.draining = 1 if(charge) var/drain = 0 var/totaldrain = 0 var/datum/effects/system/spark_spread/spark_system = new /datum/effects/system/spark_spread() spark_system.set_up(5, 0, src.loc) while(charge>0) drain = rand(100,300) if(charge[totaldrain] energy from the SMES cell." G.draining = 0 return else U << "\red This SMES cell has run dry of power. You must find another source." return interact(user) /obj/machinery/power/smes/proc/interact(mob/user) if ( (get_dist(src, user) > 1 )) if (!istype(user, /mob/living/silicon/ai)) user.machine = null user << browse(null, "window=smes") return user.machine = src var/t = "SMES Power Storage Unit [n_tag? "([n_tag])" : null]
"

	t += "Stored capacity : [round(100.0*charge/capacity, 0.1)]%

" t += "Input: [charging ? "Charging" : "Not Charging"] [chargemode ? "Auto Off" : "Auto Off "]
" t += "Input level: M - - - [add_lspace(chargelevel,5)] + + + M
" t += "

" t += "Output: [online ? "Online Offline" : "Online Offline "]
" t += "Output level: M - - - [add_lspace(output,5)] + + + M
" t += "Output load: [round(loaddemand)] W
" t += "

Close" t += "
" user << browse(t, "window=smes;size=460x300") onclose(user, "smes") return /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 (( usr.machine==src && ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) if( href_list["close"] ) usr << browse(null, "window=smes") usr.machine = null return else if( href_list["cmode"] ) chargemode = !chargemode if(!chargemode) charging = 0 updateicon() else if( href_list["online"] ) online = !online updateicon() else if( href_list["input"] ) var/i = text2num(href_list["input"]) var/d = 0 switch(i) if(-4) chargelevel = 0 if(4) chargelevel = SMESMAXCHARGELEVEL //30000 if(1) d = 100 if(-1) d = -100 if(2) d = 1000 if(-2) d = -1000 if(3) d = 10000 if(-3) d = -10000 chargelevel += d chargelevel = max(0, min(SMESMAXCHARGELEVEL, chargelevel)) // clamp to range else if( href_list["output"] ) var/i = text2num(href_list["output"]) var/d = 0 switch(i) if(-4) output = 0 if(4) output = SMESMAXOUTPUT //30000 if(1) d = 100 if(-1) d = -100 if(2) d = 1000 if(-2) d = -1000 if(3) d = 10000 if(-3) d = -10000 output += d output = max(0, min(SMESMAXOUTPUT, output)) // clamp to range src.updateUsrDialog() else usr << browse(null, "window=smes") usr.machine = null return /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) ..() /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