Merge pull request #4545 from Ccomp5950/apc_rewrite

Effeciency Project: APC / Machinery power usage.
This commit is contained in:
Chinsky
2014-03-10 15:53:29 +04:00
17 changed files with 123 additions and 68 deletions

View File

@@ -255,11 +255,28 @@ datum/controller/game_controller/proc/process_machines()
last_thing_processed = Machine.type
if(Machine.process() != PROCESS_KILL)
if(Machine)
if(Machine.use_power)
Machine.auto_use_power()
// if(Machine.use_power)
// Machine.auto_use_power()
i++
continue
machines.Cut(i,i+1)
i=1
while(i<=active_areas.len)
var/area/A = active_areas[i]
if(A.powerupdate)
A.powerupdate -= 1
for(var/obj/machinery/M in A)
if(M)
if(M.use_power)
M.auto_use_power()
if(A.apc.len)
i++
continue
active_areas.Cut(i,i+1)
datum/controller/game_controller/proc/process_objects()
var/i = 1

View File

@@ -14,6 +14,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
*/
/area
var/fire = null
var/atmos = 1
@@ -31,6 +32,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/eject = null
var/debug = 0
var/powerupdate = 10 //We give everything 10 ticks to settle out it's power usage.
var/requires_power = 1
var/always_unpowered = 0 //this gets overriden to 1 for space in area/New()
@@ -43,7 +46,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/used_environ = 0
var/has_gravity = 1
var/list/apc = list()
var/no_air = null
var/area/master // master area used for power calcluations
// (original area before splitting due to sd_DAL)

View File

@@ -13,6 +13,8 @@
master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn
uid = ++global_uid
related = list(src)
active_areas += src
all_areas += src
if(type == /area) // override defaults for space. TODO: make space areas of type /area/space rather than /area
requires_power = 1
@@ -216,6 +218,7 @@
// called when power status changes
/area/proc/power_change()
master.powerupdate = 2
for(var/area/RA in related)
for(var/obj/machinery/M in RA) // for each machine in the area
M.power_change() // reverify power status (to update icons etc.)

View File

@@ -181,10 +181,12 @@
return
return
/*
/obj/machinery/body_scanconsole/process() //not really used right now
if(stat & (NOPOWER|BROKEN))
return
use_power(250) // power stuff
//use_power(250) // power stuff
// var/mob/M //occupant
// if (!( src.status )) //remove this
@@ -200,6 +202,8 @@
// src.updateDialog()
// return
*/
/obj/machinery/body_scanconsole/attack_paw(user as mob)
return src.attack_hand(user)

View File

@@ -10,7 +10,7 @@
var/id
use_power = 1
idle_power_usage = 2
active_power_usage = 4
active_power_usage = 5
/obj/machinery/meter/New()
..()
@@ -30,7 +30,7 @@
icon_state = "meter0"
return 0
use_power(5)
//use_power(5)
var/datum/gas_mixture/environment = target.return_air()
if(!environment)

View File

@@ -273,7 +273,7 @@
src.locked = 0
if (!src.mess)
icon_state = "pod_0"
use_power(200)
//use_power(200)
return
return

View File

@@ -75,4 +75,4 @@
..(severity)
return
power_change()
..(severity)
..(severity)

View File

@@ -67,8 +67,10 @@ Class Procs:
Checks to see if area that contains the object has power available for power
channel given in 'chan'.
use_power(amount, chan=EQUIP) 'modules/power/power.dm'
use_power(amount, chan=EQUIP, autocalled) 'modules/power/power.dm'
Deducts 'amount' from the power channel 'chan' of the area that contains the object.
If it's autocalled then everything is normal, if something else calls use_power we are going to
need to recalculate the power two ticks in a row.
power_change() 'modules/power/power.dm'
Called by the area that contains the object when ever that area under goes a
@@ -159,9 +161,9 @@ Class Procs:
if(!powered(power_channel))
return 0
if(src.use_power == 1)
use_power(idle_power_usage,power_channel)
use_power(idle_power_usage,power_channel, 1)
else if(src.use_power >= 2)
use_power(active_power_usage,power_channel)
use_power(active_power_usage,power_channel, 1)
return 1
/obj/machinery/Topic(href, href_list)
@@ -189,6 +191,10 @@ Class Procs:
return 1
src.add_fingerprint(usr)
var/area/A = get_area(src)
A.powerupdate = 1
return 0
/obj/machinery/attack_ai(mob/user as mob)
@@ -228,6 +234,10 @@ Class Procs:
return 1
src.add_fingerprint(user)
var/area/A = get_area(src)
A.powerupdate = 1
return 0
/obj/machinery/proc/RefreshParts() //Placeholder proc for machines that are built using frames.

View File

@@ -6,6 +6,8 @@ var/global/obj/effect/overlay/plmaster = null
var/global/obj/effect/overlay/slmaster = null
var/global/list/active_areas = list()
var/global/list/all_areas = list()
var/global/list/machines = list()
var/global/list/processing_objects = list()
var/global/list/active_diseases = list()
@@ -114,7 +116,7 @@ var/list/reg_dna = list( )
var/mouse_respawn_time = 5 //Amount of time that must pass between a player dying as a mouse and repawning as a mouse. In minutes.
var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
var/CHARGELEVEL = 0.001 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
var/CHARGELEVEL = 0.0005 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
var/shuttle_z = 2 //default
var/airtunnel_start = 68 // default

View File

@@ -52,7 +52,7 @@
var/areastring = null
var/obj/item/weapon/cell/cell
var/start_charge = 90 // initial cell charge %
var/cell_type = 2500 // 0=no cell, 1=regular, 2=high-cap (x5) <- old, now it's just 0=no cell, otherwise dictate cellcapacity by changing this value. 1 used to be 1000, 2 was 2500
var/cell_type = 5000 // 0=no cell, 1=regular, 2=high-cap (x5) <- old, now it's just 0=no cell, otherwise dictate cellcapacity by changing this value. 1 used to be 1000, 2 was 2500
var/opened = 0 //0=closed, 1=opened, 2=cover removed
var/shorted = 0
var/lighting = 3
@@ -77,6 +77,8 @@
powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :(
var/malfhack = 0 //New var for my changes to AI malf. --NeoFite
var/mob/living/silicon/ai/malfai = null //See above --NeoFite
var/debug= 0
var/autoflag= 0 // 0 = off, 1= eqp and lights off, 2 = eqp off, 3 = all on.
// luminosity = 1
var/has_electronics = 0 // 0 - none, 1 - plugged in, 2 - secured by screwdriver
var/overload = 1 //used for the Blackout malf module
@@ -141,6 +143,7 @@
init()
else
area = src.loc.loc:master
area.apc |= src
opened = 1
operating = 0
name = "[area.name] APC"
@@ -167,6 +170,7 @@
cell.charge = start_charge * cell.maxcharge / 100.0 // (convert percentage to actual value)
var/area/A = src.loc.loc
//if area isn't specified use current
if(isarea(A) && src.areastring == null)
@@ -175,6 +179,7 @@
else
src.area = get_area_name(areastring)
name = "\improper [area.name] APC"
area.apc |= src
update_icon()
make_terminal()
@@ -914,6 +919,7 @@
if(user.lying)
user << "\red You must stand to use this [src]!"
return 0
autoflag = 5
if (istype(user, /mob/living/silicon))
var/mob/living/silicon/ai/AI = user
var/mob/living/silicon/robot/robot = user
@@ -1149,20 +1155,11 @@
return
/*
if (equipment > 1) // off=0, off auto=1, on=2, on auto=3
use_power(src.equip_consumption, EQUIP)
if (lighting > 1) // off=0, off auto=1, on=2, on auto=3
use_power(src.light_consumption, LIGHT)
if (environ > 1) // off=0, off auto=1, on=2, on auto=3
use_power(src.environ_consumption, ENVIRON)
area.calc_lighting() */
lastused_light = area.usage(LIGHT)
lastused_equip = area.usage(EQUIP)
lastused_environ = area.usage(ENVIRON)
area.clear_usage()
if(area.powerupdate)
area.clear_usage()
lastused_total = lastused_light + lastused_equip + lastused_environ
@@ -1186,13 +1183,15 @@
perapc = terminal.powernet.perapc
//if(debug)
// world.log << "Status: [main_status] - Excess: [excess] - Last Equip: [lastused_equip] - Last Light: [lastused_light] - Longterm: [longtermpower]"
//world << "Status: [main_status] - Excess: [excess] - Last Equip: [lastused_equip] - Last Light: [lastused_light]"
if(cell && !shorted)
var/cell_charge = cell.charge
var/cell_maxcharge = cell.maxcharge
// draw power from cell as before
var/cellused = min(cell.charge, CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell
var/cellused = min(cell_charge, CELLRATE * lastused_total) // clamp deduction to a max, amount left in cell
cell.use(cellused)
if(excess > 0 || perapc > lastused_total) // if power excess, or enough anyway, recharge the cell
@@ -1203,19 +1202,21 @@
else // no excess, and not enough per-apc
if( (cell.charge/CELLRATE+perapc) >= lastused_total) // can we draw enough from cell+grid to cover last usage?
if( (cell_charge/CELLRATE+perapc) >= lastused_total) // can we draw enough from cell+grid to cover last usage?
cell.charge = min(cell.maxcharge, cell.charge + CELLRATE * perapc) //recharge with what we can
cell_charge = min(cell_maxcharge, cell_charge + CELLRATE * perapc) //recharge with what we can
cell.charge = cell_charge
add_load(perapc) // so draw what we can from the grid
charging = 0
else // not enough power available to run the last tick!
else if (autoflag != 0) // not enough power available to run the last tick!
charging = 0
chargecount = 0
// This turns everything off in the case that there is still a charge left on the battery, just not enough to run the room.
equipment = autoset(equipment, 0)
lighting = autoset(lighting, 0)
environ = autoset(environ, 0)
autoflag = 0
// set channels depending on how much charge we have left
@@ -1226,39 +1227,44 @@
else if(longtermpower > -10)
longtermpower -= 2
if(cell.charge <= 0) // zero charge, turn all off
equipment = autoset(equipment, 0)
lighting = autoset(lighting, 0)
environ = autoset(environ, 0)
area.poweralert(0, src)
else if(cell.percent() < 15 && longtermpower < 0) // <15%, turn off lighting & equipment
equipment = autoset(equipment, 2)
lighting = autoset(lighting, 2)
environ = autoset(environ, 1)
area.poweralert(0, src)
else if(cell.percent() < 30 && longtermpower < 0) // <30%, turn off equipment
equipment = autoset(equipment, 2)
lighting = autoset(lighting, 1)
environ = autoset(environ, 1)
area.poweralert(0, src)
else // otherwise all can be on
equipment = autoset(equipment, 1)
lighting = autoset(lighting, 1)
environ = autoset(environ, 1)
area.poweralert(1, src)
if(cell.percent() > 75)
if(cell_charge >= 1250 || longtermpower > 0) // Put most likely at the top so we don't check it last, effeciency 101
if(autoflag != 3)
equipment = autoset(equipment, 1)
lighting = autoset(lighting, 1)
environ = autoset(environ, 1)
autoflag = 3
area.poweralert(1, src)
if(cell_charge >= 4000)
area.poweralert(1, src)
else if(cell_charge < 1250 && longtermpower < 0) // <30%, turn off equipment
if(autoflag != 2)
equipment = autoset(equipment, 2)
lighting = autoset(lighting, 1)
environ = autoset(environ, 1)
area.poweralert(0, src)
autoflag = 2
else if(cell_charge < 750 && longtermpower < 0) // <15%, turn off lighting & equipment
if(autoflag != 1)
equipment = autoset(equipment, 2)
lighting = autoset(lighting, 2)
environ = autoset(environ, 1)
area.poweralert(0, src)
autoflag = 1
else if(cell_charge <= 0) // zero charge, turn all off
if(autoflag != 0)
equipment = autoset(equipment, 0)
lighting = autoset(lighting, 0)
environ = autoset(environ, 0)
area.poweralert(0, src)
autoflag = 0
// now trickle-charge the cell
if(chargemode && charging == 1 && operating)
if(excess > 0) // check to make sure we have enough to charge
// Max charge is perapc share, capped to cell capacity, or % per second constant (Whichever is smallest)
/* var/ch = min(perapc, (cell.maxcharge - cell.charge), (cell.maxcharge*CHARGELEVEL))
add_load(ch) // Removes the power we're taking from the grid
cell.give(ch) // actually recharge the cell
*/
var/ch = min(perapc*CELLRATE, (cell.maxcharge - cell.charge), (cell.maxcharge*CHARGELEVEL))
var/ch = min(perapc*CELLRATE, (cell_maxcharge - cell_charge), (cell_maxcharge*CHARGELEVEL))
add_load(ch/CELLRATE) // Removes the power we're taking from the grid
cell.give(ch) // actually recharge the cell
@@ -1268,12 +1274,12 @@
// show cell as fully charged if so
if(cell.charge >= cell.maxcharge)
if(cell.charge >= cell_maxcharge)
charging = 2
if(chargemode)
if(!charging)
if(excess > cell.maxcharge*CHARGELEVEL)
if(excess > cell_maxcharge*CHARGELEVEL)
chargecount++
else
chargecount = 0
@@ -1295,6 +1301,8 @@
lighting = autoset(lighting, 0)
environ = autoset(environ, 0)
area.poweralert(0, src)
autoflag = 0
// update icon & area power if anything changed

View File

@@ -603,9 +603,11 @@
#define LIGHTING_POWER_FACTOR 20 //20W per unit luminosity
/*
/obj/machinery/light/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY
if(on)
use_power(luminosity * LIGHTING_POWER_FACTOR, LIGHT)
*/
// called when area power state changes
/obj/machinery/light/power_change()

View File

@@ -54,13 +54,15 @@
// increment the power usage stats for an area
/obj/machinery/proc/use_power(var/amount, var/chan = -1) // defaults to power_channel
/obj/machinery/proc/use_power(var/amount, var/chan = -1, var/autocalled = 0) // defaults to power_channel
var/area/A = src.loc.loc // make sure it's in an area
if(!A || !isarea(A) || !A.master)
return
if(chan == -1)
chan = power_channel
A.master.use_power(amount, chan)
if(!autocalled)
A.master.powerupdate = 2 // Decremented by 2 each GC tick, since it's not auto power change we're going to update power twice.
/obj/machinery/proc/power_change() // called whenever the power settings of the containing area change
// by default, check equipment channel & set flag

View File

@@ -370,7 +370,7 @@ var/list/solars_list = list()
if(stat & (NOPOWER | BROKEN))
return
use_power(250)
//use_power(250)
if(track==1 && nexttime < world.time && trackdir*trackrate)
// Increments nexttime using itself and not world.time to prevent drift
nexttime = nexttime + 6000/trackrate

View File

@@ -22,6 +22,8 @@
var/flush_every_ticks = 30 //Every 30 ticks it will look whether it is ready to flush
var/flush_count = 0 //this var adds 1 once per tick. When it reaches flush_every_ticks it resets and tries to flush.
var/last_sound = 0
active_power_usage = 600
idle_power_usage = 100
// create a new disposal
// find the attached trunk (if present) and init gas resvr.
@@ -340,6 +342,7 @@
// timed process
// charge the gas reservoir and perform flush if ready
process()
use_power = 0
if(stat & BROKEN) // nothing can happen if broken
return
@@ -363,13 +366,13 @@
if(stat & NOPOWER) // won't charge if no power
return
use_power(100) // base power usage
use_power = 1
if(mode != 1) // if off or ready, no need to charge
return
// otherwise charge
use_power(500) // charging power usage
use_power = 2
var/atom/L = loc // recharging from loc turf

View File

@@ -28,7 +28,8 @@
/obj/machinery/disease2/diseaseanalyser/process()
if(stat & (NOPOWER|BROKEN))
return
use_power(500)
//use_power(500)
if(scanning)
scanning -= 1
@@ -59,4 +60,4 @@
dish = null
src.state("\The [src.name] buzzes")
pause = 0
return
return

View File

@@ -72,7 +72,7 @@
if(stat & (NOPOWER|BROKEN))
return
use_power(500)
//use_power(500)
if(curing)
curing -= 1
@@ -151,4 +151,4 @@
var/obj/item/weapon/virusdish/dish = new/obj/item/weapon/virusdish(src.loc)
dish.virus2 = virus2
state("\The [src.name] pings", "blue")
state("\The [src.name] pings", "blue")

View File

@@ -7,7 +7,7 @@
var/analysed = 0
var/obj/item/weapon/virusdish/dish = null
var/burning = 0
var/splicing = 0
var/scanning = 0
@@ -90,7 +90,7 @@
/obj/machinery/computer/diseasesplicer/process()
if(stat & (NOPOWER|BROKEN))
return
use_power(500)
//use_power(500)
if(scanning)
scanning -= 1