Finished code conversion of /obj/machinery/power/

This commit is contained in:
hobnob13
2008-04-16 23:35:52 +00:00
parent f5df463785
commit 5c2e598688
7 changed files with 841 additions and 764 deletions
-67
View File
@@ -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
+1 -1
View File
@@ -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)
+258
View File
@@ -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()
+338
View File
@@ -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
+240
View File
@@ -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
-695
View File
@@ -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
+4 -1
View File
@@ -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