mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
This was probably bound to happen either way the previous version was based upon a faulty understanding of how the areas worked this is much more robust and only messes with the master areas and master areas needing power updates call power updates for the each of it's child areas. Also added where messing with SMESes called for an update on all areas power consumption, probably not required but doing so either way. We also rebuild the active_areas list every 5 minutes, if you get a engineer that wants to build a new area off of the station with APC's set rebuild_all_areas in the master controller and it will update instantly, otherwise wait 5 minutes. The only downside to this 5 minutes is you might get free energy until that area becomes active.
323 lines
9.0 KiB
Plaintext
323 lines
9.0 KiB
Plaintext
// 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
|
|
|
|
for(var/area/A in active_areas)
|
|
A.master.powerupdate = 3
|
|
|
|
|
|
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?"<font color='green'>":"<font color='red'>"][chargelevel]/[output]</font> | Output-mode: [online?"<font color='green'>on</font>":"<font color='red'>off</font>"] | Input-mode: [chargemode?"<font color='green'>auto</font>":"<font color='red'>off</font>"] 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 = "<A href='?src=\ref[S];rate control=1;[V]"
|
|
var/rate = "[href]=-[Max]'>-</A>[href]=-[Min]'>-</A> [(C?C : 0)] [href]=[Min]'>+</A>[href]=[Max]'>+</A>"
|
|
if(Limit) return "[href]=-[Limit]'>-</A>"+rate+"[href]=[Limit]'>+</A>"
|
|
return rate
|
|
|
|
|
|
#undef SMESRATE
|