mirror of
https://github.com/cybergirlvannie/OpenSS13.git
synced 2026-07-10 07:13:14 +01:00
Finished code conversion of /obj/machinery/power/
This commit is contained in:
@@ -2601,47 +2601,6 @@ Total SMES charging rate should not exceed total power generation rate, or an ov
|
||||
|
||||
|
||||
|
||||
/obj/machinery/power/generator
|
||||
name = "generator"
|
||||
desc = "A high efficiency thermoelectric generator."
|
||||
icon_state = "teg"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
var/obj/machinery/circulator/circ1
|
||||
var/obj/machinery/circulator/circ2
|
||||
|
||||
var/c1on = 0
|
||||
var/c2on = 0
|
||||
var/c1rate = 10
|
||||
var/c2rate = 10
|
||||
var/lastgen = 0
|
||||
var/lastgenlev = -1
|
||||
|
||||
|
||||
|
||||
#define SMESMAXCHARGELEVEL 60000
|
||||
#define SMESMAXOUTPUT 60000
|
||||
|
||||
/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 = 30000
|
||||
var/lastout = 0
|
||||
var/loaddemand = 0
|
||||
var/capacity = 5e6
|
||||
var/charge = 1e6
|
||||
var/charging = 0
|
||||
var/chargemode = 0
|
||||
var/chargecount = 0
|
||||
var/chargelevel = 30000
|
||||
var/online = 1
|
||||
var/n_tag = null
|
||||
var/obj/machinery/power/terminal/terminal = null
|
||||
|
||||
|
||||
|
||||
/obj/machinery/power/portable_gen
|
||||
@@ -2652,32 +2611,6 @@ Total SMES charging rate should not exceed total power generation rate, or an ov
|
||||
netnum = -1
|
||||
directwired = 0
|
||||
|
||||
/obj/machinery/compressor
|
||||
name = "compressor"
|
||||
desc = "The compressor stage of a gas turbine generator."
|
||||
icon = 'pipes.dmi'
|
||||
icon_state = "compressor"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/obj/machinery/power/turbine/turbine
|
||||
var/obj/substance/gas/gas
|
||||
var/turf/inturf
|
||||
var/starter = 0
|
||||
var/rpm = 0
|
||||
var/rpmtarget = 0
|
||||
var/capacity = 1e6
|
||||
|
||||
/obj/machinery/power/turbine
|
||||
name = "gas turbine generator"
|
||||
desc = "A gas turbine used to for backup power generation."
|
||||
icon = 'pipes.dmi'
|
||||
icon_state = "turbine"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/obj/machinery/compressor/compressor
|
||||
directwired = 1
|
||||
var/turf/outturf
|
||||
var/lastgen
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ obj/machinery/power
|
||||
var/list/res = list()
|
||||
var/cdir
|
||||
|
||||
for(var/turf/T in orange(1, src))
|
||||
for(var/turf/T in orange(1, src.loc))
|
||||
|
||||
cdir = get_dir(T, src)
|
||||
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Generator - The main power generation machine
|
||||
*
|
||||
* A generator makes power using the heat difference between the gas levels in two circulator machines.
|
||||
*
|
||||
*/
|
||||
|
||||
#define GENRATE 0.0015 // generator output coefficient
|
||||
|
||||
obj/machinery/power/generator
|
||||
name = "generator"
|
||||
desc = "A high efficiency thermoelectric generator."
|
||||
icon_state = "teg"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
var
|
||||
obj/machinery/circulator/circ1 // the cold gas circulator; must be to west of generator
|
||||
obj/machinery/circulator/circ2 // the hot gas circulator; must be to east of generator
|
||||
|
||||
c1on = 0 // true if circulator 1 is on
|
||||
c2on = 0 // " " " 2 " "
|
||||
c1rate = 10 // circulator 1's pumping rate (percentage)
|
||||
c2rate = 10 // circulator 2's pumping rate (percentage)
|
||||
lastgen = 0 // the power generated in the last cycle
|
||||
lastgenlev = -1 // the last bargraph overlay level
|
||||
|
||||
|
||||
// Create a generator, and locate the two circulators on either side
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
spawn(5)
|
||||
circ1 = locate(/obj/machinery/circulator) in get_step(src,WEST)
|
||||
circ2 = locate(/obj/machinery/circulator) in get_step(src,EAST)
|
||||
if(!circ1 || !circ2)
|
||||
stat |= BROKEN
|
||||
|
||||
updateicon()
|
||||
|
||||
|
||||
// Update the icon overlays depending on status and power output level
|
||||
|
||||
proc/updateicon()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
overlays = null
|
||||
else
|
||||
overlays = null
|
||||
|
||||
if(lastgenlev != 0)
|
||||
overlays += image('power.dmi', "teg-op[lastgenlev]")
|
||||
|
||||
overlays += image('power.dmi', "teg-oc[c1on][c2on]")
|
||||
|
||||
|
||||
// Generate power, depending on the gas amounts and temperatures in the circulators
|
||||
|
||||
// The device works as a semi-realistic heat engine; heat from the hot reservoir is converted to energy
|
||||
// at a set efficiency (65% of Carnot). The waste heat is dumped into the cold reservoir
|
||||
// This can only be sustained while the cold reservoir is cooler than the hot one.
|
||||
|
||||
process()
|
||||
|
||||
if(circ1 && circ2) // both circulators must be present
|
||||
|
||||
|
||||
var/gc = circ1.gas2.shc()
|
||||
var/gh = circ2.gas2.shc()
|
||||
|
||||
var/tc = circ1.gas2.temperature
|
||||
var/th = circ2.gas2.temperature
|
||||
var/deltat = th-tc
|
||||
|
||||
var/eta = (1-tc/th)*0.65 // efficiency 65% of Carnot
|
||||
|
||||
if(gc > 0 && deltat >0) // require some cold gas (for sink) and a positive temp gradient
|
||||
var/ghoc = gh/gc
|
||||
|
||||
//var/qc = gc*tc
|
||||
//var/qh = gh*th
|
||||
|
||||
var/fdt = 1/( (1-eta)*ghoc + 1) // min timestep
|
||||
|
||||
fdt = min(fdt, 0.1) // max timestep
|
||||
|
||||
var/q = fdt*eta*gh*(deltat) // heat generated
|
||||
|
||||
var/thp = th - fdt * deltat
|
||||
var/tcp = tc + fdt * (1 - eta) * (ghoc) * deltat
|
||||
|
||||
lastgen = q * GENRATE
|
||||
add_avail(lastgen)
|
||||
|
||||
circ1.ngas2.temperature = tcp
|
||||
circ2.ngas2.temperature = thp
|
||||
|
||||
else
|
||||
lastgen = 0
|
||||
|
||||
|
||||
// update icon overlays only if displayed level has changed
|
||||
|
||||
var/genlev = max(0, min( round(11*lastgen / 100000), 11))
|
||||
if(genlev != lastgenlev)
|
||||
lastgenlev = genlev
|
||||
updateicon()
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
|
||||
|
||||
// Attack with hand, open interaction window
|
||||
|
||||
attack_hand(mob/user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
|
||||
interact(user)
|
||||
|
||||
|
||||
// Display interaction window
|
||||
|
||||
proc/interact(mob/user)
|
||||
|
||||
if ( (get_dist(src, user) > 1 ))
|
||||
user.machine = null
|
||||
user << browse(null, "window=teg")
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
|
||||
var/t = "<PRE><B>Thermo-Electric Generator</B><HR>"
|
||||
|
||||
t += "Output : [round(lastgen)] W<BR><BR>"
|
||||
|
||||
t += "<B>Cold loop</B><BR>"
|
||||
t += "Temperature Inlet: [round(circ1.ngas1.temperature, 0.1)] K Outlet: [round(circ1.ngas2.temperature, 0.1)] K<BR>"
|
||||
|
||||
t += "Circulator: [c1on ? "<B>On</B> <A href = '?src=\ref[src];c1p=1'>Off</A>" : "<A href = '?src=\ref[src];c1p=1'>On</A> <B>Off</B> "]<BR>"
|
||||
t += "Rate: <A href = '?src=\ref[src];c1r=-3'>M</A> <A href = '?src=\ref[src];c1r=-2'>-</A> <A href = '?src=\ref[src];c1r=-1'>-</A> [add_lspace(c1rate,3)]% <A href = '?src=\ref[src];c1r=1'>+</A> <A href = '?src=\ref[src];c1r=2'>+</A> <A href = '?src=\ref[src];c1r=3'>M</A><BR>"
|
||||
|
||||
t += "<B>Hot loop</B><BR>"
|
||||
t += "Temperature Inlet: [round(circ2.ngas1.temperature, 0.1)] K Outlet: [round(circ2.ngas2.temperature, 0.1)] K<BR>"
|
||||
|
||||
t += "Circulator: [c2on ? "<B>On</B> <A href = '?src=\ref[src];c2p=1'>Off</A>" : "<A href = '?src=\ref[src];c2p=1'>On</A> <B>Off</B> "]<BR>"
|
||||
t += "Rate: <A href = '?src=\ref[src];c2r=-3'>M</A> <A href = '?src=\ref[src];c2r=-2'>-</A> <A href = '?src=\ref[src];c2r=-1'>-</A> [add_lspace(c2rate,3)]% <A href = '?src=\ref[src];c2r=1'>+</A> <A href = '?src=\ref[src];c2r=2'>+</A> <A href = '?src=\ref[src];c2r=3'>M</A><BR>"
|
||||
|
||||
t += "<BR><HR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
t += "</PRE>"
|
||||
user << browse(t, "window=teg;size=460x300")
|
||||
return
|
||||
|
||||
|
||||
// Handle topic links from interaction window
|
||||
|
||||
Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if (usr.stat || usr.restrained() )
|
||||
return
|
||||
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
|
||||
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))))
|
||||
|
||||
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=teg")
|
||||
usr.machine = null
|
||||
return
|
||||
|
||||
else if( href_list["c1p"] )
|
||||
c1on = !c1on
|
||||
circ1.control(c1on, c1rate) // used to control the circulator power and rate settings
|
||||
updateicon()
|
||||
else if( href_list["c2p"] )
|
||||
c2on = !c2on
|
||||
circ2.control(c2on, c2rate)
|
||||
updateicon()
|
||||
|
||||
else if( href_list["c1r"] )
|
||||
|
||||
var/i = text2num(href_list["c1r"])
|
||||
|
||||
var/d = 0
|
||||
switch(i)
|
||||
if(-3)
|
||||
c1rate = 0
|
||||
if(3)
|
||||
c1rate = 100
|
||||
|
||||
if(1)
|
||||
d = 1
|
||||
if(-1)
|
||||
d = -1
|
||||
if(2)
|
||||
d = 10
|
||||
if(-2)
|
||||
d = -10
|
||||
|
||||
c1rate += d
|
||||
c1rate = max(1, min(100, c1rate)) // clamp to range
|
||||
|
||||
circ1.control(c1on, c1rate)
|
||||
updateicon()
|
||||
|
||||
else if( href_list["c2r"] )
|
||||
|
||||
var/i = text2num(href_list["c2r"])
|
||||
|
||||
var/d = 0
|
||||
switch(i)
|
||||
if(-3)
|
||||
c2rate = 0
|
||||
if(3)
|
||||
c2rate = 100
|
||||
|
||||
if(1)
|
||||
d = 1
|
||||
if(-1)
|
||||
d = -1
|
||||
if(2)
|
||||
d = 10
|
||||
if(-2)
|
||||
d = -10
|
||||
|
||||
c2rate += d
|
||||
c2rate = max(1, min(100, c2rate)) // clamp to range
|
||||
|
||||
circ2.control(c2on, c2rate)
|
||||
updateicon()
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
//Foreach goto(275)
|
||||
else
|
||||
usr << browse(null, "window=teg")
|
||||
usr.machine = null
|
||||
|
||||
return
|
||||
|
||||
|
||||
// When are power changes, perfrom default action and update icon overlays
|
||||
|
||||
power_change()
|
||||
..()
|
||||
updateicon()
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* SMES -- Superconduction magnetic energy storage unit
|
||||
*
|
||||
* A machine that stores power.
|
||||
*
|
||||
* SMESes have two "sides" where the are connected to the cable network: Input and output.
|
||||
* The input side is connected via a terminal to the SMES; this is where the SMES draws power from to charge
|
||||
* The output side is directly wired to the SMES object; this is where the SMES outputs stored power
|
||||
* If the two sides are part of the same powernet, the SMES will still work correctly
|
||||
*
|
||||
* TODO: See note a proc/restore() below
|
||||
*/
|
||||
|
||||
#define SMESMAXCHARGELEVEL 60000 // This is the maximum rate at which you can charge the SMES
|
||||
|
||||
#define SMESMAXOUTPUT 60000 // This is the maxmium output power of the SMES
|
||||
|
||||
#define SMESRATE 0.05 // rate of internal charge to external power output
|
||||
|
||||
|
||||
/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 = 30000 // the current power output level - limited to SMEXMAXOUTPUT
|
||||
lastout = 0 // the output during the last cycle
|
||||
loaddemand = 0 // the actual amount during the last cycle (may be lower if powernet load is lower)
|
||||
capacity = 5e6 // the total maximum charge capacity
|
||||
charge = 1e6 // the current charge level; default is 20% of maximum
|
||||
charging = 0 // true if charging
|
||||
chargemode = 0 // true if set to automatically charge
|
||||
chargecount = 0 // count of number of times excess power has been availiable (used to control when charging is started)
|
||||
chargelevel = 30000 // the amount of power to use to charge the SMES - limited to SMESMAXCHARGELEVEL
|
||||
online = 1 // true if online (outputing power)
|
||||
n_tag = null // a string nametag to display on the control panel (e.g. Main No. 1)
|
||||
obj/machinery/power/terminal/terminal = null // the input terminal connected to this SMES
|
||||
|
||||
|
||||
// Create a new SMES
|
||||
// After waiting for the powernets to be built, look for a matching terminal in the 4 cardinal directions
|
||||
// If found, store the terminal, otherwise mark the SMES as broken
|
||||
|
||||
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 must have wires pointing towards the SMES
|
||||
terminal = term
|
||||
break dir_loop
|
||||
|
||||
if(!terminal)
|
||||
stat |= BROKEN
|
||||
return
|
||||
|
||||
terminal.master = src
|
||||
|
||||
updateicon()
|
||||
|
||||
|
||||
|
||||
// Updates the SMES icon to show overlays representing charging state, online state, and charge level
|
||||
|
||||
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]")
|
||||
|
||||
|
||||
// Returns the level (0-5) of the bargraph overlay (representing the charge level) to display
|
||||
|
||||
proc/chargedisplay()
|
||||
return round(5.5*charge/capacity)
|
||||
|
||||
|
||||
|
||||
// Timed process; recharge the SMES if power is available, output power if online
|
||||
|
||||
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,10)) // random count to switch to charging reduces thrashing
|
||||
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)
|
||||
|
||||
|
||||
|
||||
// A special routine for SMES
|
||||
// Called by the main game loop after all other power processes are finished
|
||||
// SMESes make availabe a set amount of power per cycle, but should only have as much power drained
|
||||
// as the actual load that cycle. This restore() proc restores the excess charge that wasn't really used.
|
||||
|
||||
// TODO: Make the charge restoration more logical. Either need a priority setting, or some way to evenly
|
||||
// share load between SMESes.
|
||||
|
||||
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()
|
||||
|
||||
|
||||
// Add a load amount. Loading is done throught the terminal's powernet for SMESes
|
||||
|
||||
add_load(var/amount)
|
||||
if(terminal && terminal.powernet)
|
||||
terminal.powernet.newload += amount
|
||||
|
||||
|
||||
// Attack to open interaction window
|
||||
|
||||
attack_hand(mob/user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(stat & BROKEN) return
|
||||
|
||||
interact(user)
|
||||
|
||||
|
||||
// Display interaction window
|
||||
|
||||
proc/interact(mob/user)
|
||||
|
||||
if ( (get_dist(src, user) > 1 ))
|
||||
user.machine = null
|
||||
user << browse(null, "window=smes")
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
|
||||
|
||||
var/t = "<TT><B>SMES Power Storage Unit</B> [n_tag? "([n_tag])" : null]<HR><PRE>"
|
||||
|
||||
t += "Stored capacity : [round(100.0*charge/capacity, 0.1)]%<BR><BR>"
|
||||
|
||||
t += "Input: [charging ? "Charging" : "Not Charging"] [chargemode ? "<B>Auto</B> <A href = '?src=\ref[src];cmode=1'>Off</A>" : "<A href = '?src=\ref[src];cmode=1'>Auto</A> <B>Off</B> "]<BR>"
|
||||
|
||||
|
||||
t += "Input level: <A href = '?src=\ref[src];input=-4'>M</A> <A href = '?src=\ref[src];input=-3'>-</A> <A href = '?src=\ref[src];input=-2'>-</A> <A href = '?src=\ref[src];input=-1'>-</A> [add_lspace(chargelevel,5)] <A href = '?src=\ref[src];input=1'>+</A> <A href = '?src=\ref[src];input=2'>+</A> <A href = '?src=\ref[src];input=3'>+</A> <A href = '?src=\ref[src];input=4'>M</A><BR>"
|
||||
|
||||
t += "<BR><BR>"
|
||||
|
||||
t += "Output: [online ? "<B>Online</B> <A href = '?src=\ref[src];online=1'>Offline</A>" : "<A href = '?src=\ref[src];online=1'>Online</A> <B>Offline</B> "]<BR>"
|
||||
|
||||
t += "Output level: <A href = '?src=\ref[src];output=-4'>M</A> <A href = '?src=\ref[src];output=-3'>-</A> <A href = '?src=\ref[src];output=-2'>-</A> <A href = '?src=\ref[src];output=-1'>-</A> [add_lspace(output,5)] <A href = '?src=\ref[src];output=1'>+</A> <A href = '?src=\ref[src];output=2'>+</A> <A href = '?src=\ref[src];output=3'>+</A> <A href = '?src=\ref[src];output=4'>M</A><BR>"
|
||||
|
||||
t += "Output load: [round(loaddemand)] W<BR>"
|
||||
|
||||
t += "<BR></PRE><HR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
t += "</TT>"
|
||||
user << browse(t, "window=smes;size=460x300")
|
||||
return
|
||||
|
||||
|
||||
// Handle topic links from the interaction window
|
||||
|
||||
Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if (usr.stat || usr.restrained() )
|
||||
return
|
||||
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
|
||||
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))))
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
//Foreach goto(275)
|
||||
else
|
||||
usr << browse(null, "window=smes")
|
||||
usr.machine = null
|
||||
|
||||
return
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Turbine and compressor -- auxilliary power generation system
|
||||
*
|
||||
* TODO: Tweak values to make the aux generator useful. It was intended to generate large amounts of power,
|
||||
* but use up plasma too fast to be sustainable for a long time.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Compressor - not actually a power-connected machine, but only used with a turbine
|
||||
*/
|
||||
|
||||
#define COMPFRICTION 5e5 // a breaking friction coefficient (so compressor has a maximum speed
|
||||
// and spins down when unpowered)
|
||||
#define COMPSTARTERLOAD 2800 // the power load needed to run the starter
|
||||
|
||||
obj/machinery/compressor
|
||||
name = "compressor"
|
||||
desc = "The compressor stage of a gas turbine generator."
|
||||
icon = 'pipes.dmi'
|
||||
icon_state = "compressor"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var
|
||||
obj/machinery/power/turbine/turbine // the associated turbine object
|
||||
obj/substance/gas/gas // the gas reservoir inside the compressor
|
||||
turf/inturf // the inlet turf (where gas is drawn in)
|
||||
starter = 0 // true if the starter is engaged
|
||||
rpm = 0 // the current spin rate
|
||||
rpmtarget = 0 // the target spin rate
|
||||
capacity = 1e6 // maximum gas capacity
|
||||
|
||||
|
||||
// Create a compressor. Set the inlet turf (one step to west) and the turbine (one step to east)
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
gas = new/obj/substance/gas(src)
|
||||
gas.maximum = capacity
|
||||
inturf = get_step(src, WEST)
|
||||
|
||||
spawn(5)
|
||||
turbine = locate() in get_step(src, EAST)
|
||||
if(!turbine)
|
||||
stat |= BROKEN
|
||||
|
||||
|
||||
// Timed process. Make spin rate tend to the target rate, draw in gas.
|
||||
//set target rate to 1000 if starter is on, and display the icon overlay correspoinding to the current spin rate
|
||||
|
||||
process()
|
||||
|
||||
overlays = null
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
rpm = 0.9* rpm + 0.1 * rpmtarget
|
||||
|
||||
|
||||
gas.turf_take(inturf, rpm/30000*capacity)
|
||||
|
||||
|
||||
rpm = max(0, rpm - (rpm*rpm)/COMPFRICTION)
|
||||
|
||||
|
||||
if(starter && !(stat & NOPOWER))
|
||||
use_power(2800)
|
||||
if(rpm<1000)
|
||||
rpmtarget = 1000
|
||||
else
|
||||
starter = 0
|
||||
else
|
||||
if(rpm<1000)
|
||||
rpmtarget = 0
|
||||
|
||||
|
||||
|
||||
if(rpm>50000)
|
||||
overlays += image('pipes.dmi', "comp-o4", FLY_LAYER)
|
||||
else if(rpm>10000)
|
||||
overlays += image('pipes.dmi', "comp-o3", FLY_LAYER)
|
||||
else if(rpm>2000)
|
||||
overlays += image('pipes.dmi', "comp-o2", FLY_LAYER)
|
||||
if(rpm>500)
|
||||
overlays += image('pipes.dmi', "comp-o1", FLY_LAYER)
|
||||
|
||||
|
||||
/*
|
||||
* Turbine - generates power and spins compressor depending on gas parameters inside the compressor
|
||||
*/
|
||||
|
||||
#define TURBPRES 90000000 // the "pressure" (gas amount * temperature) required to generate 30000 RPM
|
||||
#define TURBGENQ 20000 // coefficient relating spin rate to power generated
|
||||
#define TURBGENG 0.8 // linearity coefficient of spinrate/power curve (1=linear)
|
||||
|
||||
|
||||
obj/machinery/power/turbine
|
||||
name = "gas turbine generator"
|
||||
desc = "A gas turbine used to for backup power generation."
|
||||
icon = 'pipes.dmi'
|
||||
icon_state = "turbine"
|
||||
anchored = 1
|
||||
density = 1
|
||||
directwired = 1
|
||||
|
||||
var
|
||||
obj/machinery/compressor/compressor // the associated compressor
|
||||
turf/outturf // the outlet turf (1 step to east)
|
||||
lastgen // the power generated last cycle
|
||||
|
||||
|
||||
|
||||
|
||||
// Create a turbine. Sets the outlet turf (1 step to east) and the compressor (1 step to west)
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
outturf = get_step(src, EAST)
|
||||
|
||||
spawn(5)
|
||||
|
||||
compressor = locate() in get_step(src, WEST)
|
||||
if(!compressor)
|
||||
stat |= BROKEN
|
||||
|
||||
|
||||
// Timed process.
|
||||
// Generate power depending on current rpm. Set new target rpm depending on compressor gas temperature and amount
|
||||
// Output gas to outlet turf. Update overlay if actually generating signifcant power
|
||||
|
||||
|
||||
process()
|
||||
|
||||
overlays = null
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) *TURBGENQ
|
||||
add_avail(lastgen)
|
||||
|
||||
if(compressor.gas.temperature > (T20C+50))
|
||||
var/newrpm = ((compressor.gas.temperature-T20C-50) * compressor.gas.tot_gas() / TURBPRES)*30000
|
||||
newrpm = max(0, newrpm)
|
||||
|
||||
if(!compressor.starter || newrpm > 1000)
|
||||
compressor.rpmtarget = newrpm
|
||||
|
||||
var/oamount = min(compressor.gas.tot_gas(), compressor.rpm/32000*compressor.capacity)
|
||||
|
||||
compressor.gas.turf_add(outturf, oamount)
|
||||
|
||||
outturf.firelevel = outturf.poison
|
||||
|
||||
if(lastgen > 100)
|
||||
overlays += image('pipes.dmi', "turb-o", FLY_LAYER)
|
||||
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
|
||||
|
||||
// Attack hand, do user interaction
|
||||
|
||||
attack_hand(mob/user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(stat & (BROKEN | NOPOWER)) return
|
||||
|
||||
interact(user)
|
||||
|
||||
|
||||
// Show the interaction window
|
||||
|
||||
proc/interact(mob/user)
|
||||
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (NOPOWER|BROKEN)) )
|
||||
user.machine = null
|
||||
user << browse(null, "window=turbine")
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
|
||||
var/t = "<TT><B>Gas Turbine Generator</B><HR><PRE>"
|
||||
|
||||
var/gen = max(0, lastgen - (compressor.starter * COMPSTARTERLOAD) )
|
||||
t += "Generated power : [round(gen)] W<BR><BR>"
|
||||
|
||||
t += "Turbine: [round(compressor.rpm)] RPM<BR>"
|
||||
|
||||
t += "Starter: [ compressor.starter ? "<A href='?src=\ref[src];str=1'>Off</A> <B>On</B>" : "<B>Off</B> <A href='?src=\ref[src];str=1'>On</A>"]<BR>"
|
||||
|
||||
//t += "Gas: [compressor.gas.tostring()]<BR>"
|
||||
|
||||
t += "</PRE><HR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
t += "</TT>"
|
||||
user << browse(t, "window=turbine")
|
||||
|
||||
return
|
||||
|
||||
|
||||
// Handle topic links from interaction window
|
||||
|
||||
Topic(href, href_list)
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
if (usr.stat || usr.restrained() )
|
||||
return
|
||||
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
|
||||
if (( usr.machine==src && (get_dist(src, usr) <= 1 && istype(src.loc, /turf))))
|
||||
|
||||
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=turbine")
|
||||
usr.machine = null
|
||||
return
|
||||
|
||||
else if( href_list["str"] )
|
||||
compressor.starter = !compressor.starter
|
||||
|
||||
spawn(0)
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
|
||||
else
|
||||
usr << browse(null, "window=turbine")
|
||||
usr.machine = null
|
||||
|
||||
return
|
||||
@@ -41,249 +41,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
// the underfloor wiring terminal for the APC
|
||||
// autogenerated when an APC is placed
|
||||
// all conduit connects go to this object instead of the APC
|
||||
// using this solves the problem of having the APC in a wall yet also inside an area
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// dummy generator object for testing
|
||||
|
||||
/*/obj/machinery/power/generator/verb/set_amount(var/g as num)
|
||||
set src in view(1)
|
||||
|
||||
gen_amount = g
|
||||
|
||||
*/
|
||||
|
||||
/obj/machinery/power/generator/New()
|
||||
..()
|
||||
|
||||
spawn(5)
|
||||
circ1 = locate(/obj/machinery/circulator) in get_step(src,WEST)
|
||||
circ2 = locate(/obj/machinery/circulator) in get_step(src,EAST)
|
||||
if(!circ1 || !circ2)
|
||||
stat |= BROKEN
|
||||
|
||||
updateicon()
|
||||
|
||||
/obj/machinery/power/generator/proc/updateicon()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
overlays = null
|
||||
else
|
||||
overlays = null
|
||||
|
||||
if(lastgenlev != 0)
|
||||
overlays += image('power.dmi', "teg-op[lastgenlev]")
|
||||
|
||||
overlays += image('power.dmi', "teg-oc[c1on][c2on]")
|
||||
|
||||
#define GENRATE 0.0015 // generator output coefficient from Q
|
||||
|
||||
/obj/machinery/power/generator/process()
|
||||
|
||||
/* if(circ && circ.gas1)
|
||||
var/gen = circ.gas2.tot_gas()*max(0, circ.gas2.temperature - 298)/300
|
||||
circ.ngas2.temperature = max(298, circ.ngas2.temperature - 50)
|
||||
|
||||
add_avail(gen)
|
||||
*/
|
||||
|
||||
if(circ1 && circ2)
|
||||
|
||||
|
||||
var/gc = circ1.gas2.shc()
|
||||
var/gh = circ2.gas2.shc()
|
||||
|
||||
var/tc = circ1.gas2.temperature
|
||||
var/th = circ2.gas2.temperature
|
||||
var/deltat = th-tc
|
||||
|
||||
var/eta = (1-tc/th)*0.65 // efficiency 65% of Carnot
|
||||
|
||||
if(gc > 0 && deltat >0) // require some cold gas (for sink) and a positive temp gradient
|
||||
var/ghoc = gh/gc
|
||||
|
||||
//var/qc = gc*tc
|
||||
//var/qh = gh*th
|
||||
|
||||
var/fdt = 1/( (1-eta)*ghoc + 1) // min timestep
|
||||
|
||||
fdt = min(fdt, 0.1) // max timestep
|
||||
|
||||
var/q = fdt*eta*gh*(deltat) // heat generated
|
||||
|
||||
var/thp = th - fdt * deltat
|
||||
var/tcp = tc + fdt * (1 - eta) * (ghoc) * deltat
|
||||
|
||||
lastgen = q * GENRATE
|
||||
add_avail(lastgen)
|
||||
|
||||
circ1.ngas2.temperature = tcp
|
||||
circ2.ngas2.temperature = thp
|
||||
|
||||
else
|
||||
lastgen = 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// update icon overlays only if displayed level has changed
|
||||
|
||||
var/genlev = max(0, min( round(11*lastgen / 100000), 11))
|
||||
if(genlev != lastgenlev)
|
||||
lastgenlev = genlev
|
||||
updateicon()
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
|
||||
/obj/machinery/power/generator/attack_hand(mob/user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
|
||||
interact(user)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/power/generator/proc/interact(mob/user)
|
||||
|
||||
if ( (get_dist(src, user) > 1 ))
|
||||
user.machine = null
|
||||
user << browse(null, "window=teg")
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
|
||||
var/t = "<PRE><B>Thermo-Electric Generator</B><HR>"
|
||||
|
||||
t += "Output : [round(lastgen)] W<BR><BR>"
|
||||
|
||||
t += "<B>Cold loop</B><BR>"
|
||||
t += "Temperature Inlet: [round(circ1.ngas1.temperature, 0.1)] K Outlet: [round(circ1.ngas2.temperature, 0.1)] K<BR>"
|
||||
|
||||
t += "Circulator: [c1on ? "<B>On</B> <A href = '?src=\ref[src];c1p=1'>Off</A>" : "<A href = '?src=\ref[src];c1p=1'>On</A> <B>Off</B> "]<BR>"
|
||||
t += "Rate: <A href = '?src=\ref[src];c1r=-3'>M</A> <A href = '?src=\ref[src];c1r=-2'>-</A> <A href = '?src=\ref[src];c1r=-1'>-</A> [add_lspace(c1rate,3)]% <A href = '?src=\ref[src];c1r=1'>+</A> <A href = '?src=\ref[src];c1r=2'>+</A> <A href = '?src=\ref[src];c1r=3'>M</A><BR>"
|
||||
|
||||
t += "<B>Hot loop</B><BR>"
|
||||
t += "Temperature Inlet: [round(circ2.ngas1.temperature, 0.1)] K Outlet: [round(circ2.ngas2.temperature, 0.1)] K<BR>"
|
||||
|
||||
t += "Circulator: [c2on ? "<B>On</B> <A href = '?src=\ref[src];c2p=1'>Off</A>" : "<A href = '?src=\ref[src];c2p=1'>On</A> <B>Off</B> "]<BR>"
|
||||
t += "Rate: <A href = '?src=\ref[src];c2r=-3'>M</A> <A href = '?src=\ref[src];c2r=-2'>-</A> <A href = '?src=\ref[src];c2r=-1'>-</A> [add_lspace(c2rate,3)]% <A href = '?src=\ref[src];c2r=1'>+</A> <A href = '?src=\ref[src];c2r=2'>+</A> <A href = '?src=\ref[src];c2r=3'>M</A><BR>"
|
||||
|
||||
t += "<BR><HR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
t += "</PRE>"
|
||||
user << browse(t, "window=teg;size=460x300")
|
||||
return
|
||||
|
||||
/obj/machinery/power/generator/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if (usr.stat || usr.restrained() )
|
||||
return
|
||||
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
|
||||
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))))
|
||||
|
||||
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=teg")
|
||||
usr.machine = null
|
||||
return
|
||||
|
||||
else if( href_list["c1p"] )
|
||||
c1on = !c1on
|
||||
circ1.control(c1on, c1rate)
|
||||
updateicon()
|
||||
else if( href_list["c2p"] )
|
||||
c2on = !c2on
|
||||
circ2.control(c2on, c2rate)
|
||||
updateicon()
|
||||
|
||||
else if( href_list["c1r"] )
|
||||
|
||||
var/i = text2num(href_list["c1r"])
|
||||
|
||||
var/d = 0
|
||||
switch(i)
|
||||
if(-3)
|
||||
c1rate = 0
|
||||
if(3)
|
||||
c1rate = 100
|
||||
|
||||
if(1)
|
||||
d = 1
|
||||
if(-1)
|
||||
d = -1
|
||||
if(2)
|
||||
d = 10
|
||||
if(-2)
|
||||
d = -10
|
||||
|
||||
c1rate += d
|
||||
c1rate = max(1, min(100, c1rate)) // clamp to range
|
||||
|
||||
circ1.control(c1on, c1rate)
|
||||
updateicon()
|
||||
|
||||
else if( href_list["c2r"] )
|
||||
|
||||
var/i = text2num(href_list["c2r"])
|
||||
|
||||
var/d = 0
|
||||
switch(i)
|
||||
if(-3)
|
||||
c2rate = 0
|
||||
if(3)
|
||||
c2rate = 100
|
||||
|
||||
if(1)
|
||||
d = 1
|
||||
if(-1)
|
||||
d = -1
|
||||
if(2)
|
||||
d = 10
|
||||
if(-2)
|
||||
d = -10
|
||||
|
||||
c2rate += d
|
||||
c2rate = max(1, min(100, c2rate)) // clamp to range
|
||||
|
||||
circ2.control(c2on, c2rate)
|
||||
updateicon()
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
//Foreach goto(275)
|
||||
else
|
||||
usr << browse(null, "window=teg")
|
||||
usr.machine = null
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/power/generator/power_change()
|
||||
..()
|
||||
updateicon()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// the power cable object
|
||||
|
||||
/obj/cable/New()
|
||||
@@ -947,455 +704,3 @@
|
||||
|
||||
|
||||
|
||||
// the power monitoring computer
|
||||
// for the moment, just report the status of all APCs in the same powernet
|
||||
|
||||
|
||||
|
||||
// the SMES
|
||||
// stores power
|
||||
|
||||
/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,10))
|
||||
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)
|
||||
|
||||
|
||||
// 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_hand(mob/user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(stat & BROKEN) return
|
||||
|
||||
interact(user)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/power/smes/proc/interact(mob/user)
|
||||
|
||||
if ( (get_dist(src, user) > 1 ))
|
||||
user.machine = null
|
||||
user << browse(null, "window=smes")
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
|
||||
|
||||
var/t = "<TT><B>SMES Power Storage Unit</B> [n_tag? "([n_tag])" : null]<HR><PRE>"
|
||||
|
||||
t += "Stored capacity : [round(100.0*charge/capacity, 0.1)]%<BR><BR>"
|
||||
|
||||
t += "Input: [charging ? "Charging" : "Not Charging"] [chargemode ? "<B>Auto</B> <A href = '?src=\ref[src];cmode=1'>Off</A>" : "<A href = '?src=\ref[src];cmode=1'>Auto</A> <B>Off</B> "]<BR>"
|
||||
|
||||
|
||||
t += "Input level: <A href = '?src=\ref[src];input=-4'>M</A> <A href = '?src=\ref[src];input=-3'>-</A> <A href = '?src=\ref[src];input=-2'>-</A> <A href = '?src=\ref[src];input=-1'>-</A> [add_lspace(chargelevel,5)] <A href = '?src=\ref[src];input=1'>+</A> <A href = '?src=\ref[src];input=2'>+</A> <A href = '?src=\ref[src];input=3'>+</A> <A href = '?src=\ref[src];input=4'>M</A><BR>"
|
||||
|
||||
t += "<BR><BR>"
|
||||
|
||||
t += "Output: [online ? "<B>Online</B> <A href = '?src=\ref[src];online=1'>Offline</A>" : "<A href = '?src=\ref[src];online=1'>Online</A> <B>Offline</B> "]<BR>"
|
||||
|
||||
t += "Output level: <A href = '?src=\ref[src];output=-4'>M</A> <A href = '?src=\ref[src];output=-3'>-</A> <A href = '?src=\ref[src];output=-2'>-</A> <A href = '?src=\ref[src];output=-1'>-</A> [add_lspace(output,5)] <A href = '?src=\ref[src];output=1'>+</A> <A href = '?src=\ref[src];output=2'>+</A> <A href = '?src=\ref[src];output=3'>+</A> <A href = '?src=\ref[src];output=4'>M</A><BR>"
|
||||
|
||||
t += "Output load: [round(loaddemand)] W<BR>"
|
||||
|
||||
t += "<BR></PRE><HR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
t += "</TT>"
|
||||
user << browse(t, "window=smes;size=460x300")
|
||||
return
|
||||
|
||||
/obj/machinery/power/smes/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
if (usr.stat || usr.restrained() )
|
||||
return
|
||||
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
|
||||
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))))
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
//Foreach goto(275)
|
||||
else
|
||||
usr << browse(null, "window=smes")
|
||||
usr.machine = null
|
||||
|
||||
return
|
||||
|
||||
|
||||
// the inlet stage of the gas turbine electricity generator
|
||||
|
||||
/obj/machinery/compressor/New()
|
||||
..()
|
||||
|
||||
gas = new/obj/substance/gas(src)
|
||||
gas.maximum = capacity
|
||||
inturf = get_step(src, WEST)
|
||||
|
||||
spawn(5)
|
||||
turbine = locate() in get_step(src, EAST)
|
||||
if(!turbine)
|
||||
stat |= BROKEN
|
||||
|
||||
|
||||
#define COMPFRICTION 5e5
|
||||
#define COMPSTARTERLOAD 2800
|
||||
|
||||
/obj/machinery/compressor/process()
|
||||
|
||||
overlays = null
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
rpm = 0.9* rpm + 0.1 * rpmtarget
|
||||
|
||||
|
||||
gas.turf_take(inturf, rpm/30000*capacity)
|
||||
|
||||
|
||||
rpm = max(0, rpm - (rpm*rpm)/COMPFRICTION)
|
||||
|
||||
|
||||
if(starter && !(stat & NOPOWER))
|
||||
use_power(2800)
|
||||
if(rpm<1000)
|
||||
rpmtarget = 1000
|
||||
else
|
||||
starter = 0
|
||||
else
|
||||
if(rpm<1000)
|
||||
rpmtarget = 0
|
||||
|
||||
|
||||
|
||||
if(rpm>50000)
|
||||
overlays += image('pipes.dmi', "comp-o4", FLY_LAYER)
|
||||
else if(rpm>10000)
|
||||
overlays += image('pipes.dmi', "comp-o3", FLY_LAYER)
|
||||
else if(rpm>2000)
|
||||
overlays += image('pipes.dmi', "comp-o2", FLY_LAYER)
|
||||
if(rpm>500)
|
||||
overlays += image('pipes.dmi', "comp-o1", FLY_LAYER)
|
||||
|
||||
|
||||
/obj/machinery/power/turbine/New()
|
||||
..()
|
||||
|
||||
outturf = get_step(src, EAST)
|
||||
|
||||
spawn(5)
|
||||
|
||||
compressor = locate() in get_step(src, WEST)
|
||||
if(!compressor)
|
||||
stat |= BROKEN
|
||||
|
||||
|
||||
#define TURBPRES 90000000
|
||||
#define TURBGENQ 20000
|
||||
#define TURBGENG 0.8
|
||||
|
||||
/obj/machinery/power/turbine/process()
|
||||
|
||||
overlays = null
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) *TURBGENQ
|
||||
add_avail(lastgen)
|
||||
|
||||
if(compressor.gas.temperature > (T20C+50))
|
||||
var/newrpm = ((compressor.gas.temperature-T20C-50) * compressor.gas.tot_gas() / TURBPRES)*30000
|
||||
newrpm = max(0, newrpm)
|
||||
|
||||
if(!compressor.starter || newrpm > 1000)
|
||||
compressor.rpmtarget = newrpm
|
||||
|
||||
var/oamount = min(compressor.gas.tot_gas(), compressor.rpm/32000*compressor.capacity)
|
||||
|
||||
compressor.gas.turf_add(outturf, oamount)
|
||||
|
||||
outturf.firelevel = outturf.poison
|
||||
|
||||
if(lastgen > 100)
|
||||
overlays += image('pipes.dmi', "turb-o", FLY_LAYER)
|
||||
|
||||
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
|
||||
|
||||
/obj/machinery/power/turbine/attack_hand(mob/user)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
if(stat & (BROKEN | NOPOWER)) return
|
||||
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/power/turbine/proc/interact(mob/user)
|
||||
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (NOPOWER|BROKEN)) )
|
||||
user.machine = null
|
||||
user << browse(null, "window=turbine")
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
|
||||
var/t = "<TT><B>Gas Turbine Generator</B><HR><PRE>"
|
||||
|
||||
var/gen = max(0, lastgen - (compressor.starter * COMPSTARTERLOAD) )
|
||||
t += "Generated power : [round(gen)] W<BR><BR>"
|
||||
|
||||
t += "Turbine: [round(compressor.rpm)] RPM<BR>"
|
||||
|
||||
t += "Starter: [ compressor.starter ? "<A href='?src=\ref[src];str=1'>Off</A> <B>On</B>" : "<B>Off</B> <A href='?src=\ref[src];str=1'>On</A>"]<BR>"
|
||||
|
||||
//t += "Gas: [compressor.gas.tostring()]<BR>"
|
||||
|
||||
t += "</PRE><HR><A href='?src=\ref[src];close=1'>Close</A>"
|
||||
|
||||
t += "</TT>"
|
||||
user << browse(t, "window=turbine")
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/power/turbine/Topic(href, href_list)
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
if (usr.stat || usr.restrained() )
|
||||
return
|
||||
if ((!( istype(usr, /mob/human) ) && (!( ticker ) || (ticker && ticker.mode != "monkey"))))
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
|
||||
if (( usr.machine==src && (get_dist(src, usr) <= 1 && istype(src.loc, /turf))))
|
||||
|
||||
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=turbine")
|
||||
usr.machine = null
|
||||
return
|
||||
|
||||
else if( href_list["str"] )
|
||||
compressor.starter = !compressor.starter
|
||||
|
||||
spawn(0)
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.interact(M)
|
||||
|
||||
else
|
||||
usr << browse(null, "window=turbine")
|
||||
usr.machine = null
|
||||
|
||||
return
|
||||
@@ -5,7 +5,7 @@
|
||||
// BEGIN_INTERNALS
|
||||
/*
|
||||
FILE: Code\!atoms.dm
|
||||
DIR: Code Code\Machinery\Atmoalter Code\Machinery\Power
|
||||
DIR: Code Code\Machinery Code\Machinery\Atmoalter Code\Machinery\Power
|
||||
MAP_ICON_TYPE: 0
|
||||
AUTO_FILE_DIR: ON
|
||||
*/
|
||||
@@ -94,9 +94,12 @@ AUTO_FILE_DIR: ON
|
||||
#include "Code\Machinery\Atmoalter\siphs.dm"
|
||||
#include "Code\Machinery\Power\_power.dm"
|
||||
#include "Code\Machinery\Power\apc.dm"
|
||||
#include "Code\Machinery\Power\generator.dm"
|
||||
#include "Code\Machinery\Power\monitor.dm"
|
||||
#include "Code\Machinery\Power\smes.dm"
|
||||
#include "Code\Machinery\Power\solar.dm"
|
||||
#include "Code\Machinery\Power\solar_control.dm"
|
||||
#include "Code\Machinery\Power\terminal.dm"
|
||||
#include "Code\Machinery\Power\turbine.dm"
|
||||
// END_INCLUDE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user