From 4b070a2de6fe0ad555b1f8166149a49aa685304c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 10 Aug 2014 00:36:40 -0400 Subject: [PATCH] Fixes #5935 Also improves apc/process() (doesnt add and then remove charge from cells when it doesn't have to). --- .../ShieldGen/shield_capacitor.dm | 6 +- code/game/gamemodes/events/ninja_equipment.dm | 6 +- code/game/machinery/shieldgen.dm | 15 ++-- code/modules/power/apc.dm | 83 +++++++++---------- code/modules/power/batteryrack.dm | 3 +- code/modules/power/cable_logic.dm | 12 +-- code/modules/power/power.dm | 26 ++++-- code/modules/power/singularity/emitter.dm | 3 +- code/modules/power/smes.dm | 5 +- code/modules/power/tracker.dm | 8 +- 10 files changed, 83 insertions(+), 84 deletions(-) diff --git a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm index d80b98c8e3..d5836c4e2e 100644 --- a/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm +++ b/code/WorkInProgress/Cael_Aislinn/ShieldGen/shield_capacitor.dm @@ -117,10 +117,8 @@ if (PN) var/power_draw = between(0, max_charge - stored_charge, charge_rate) //what we are trying to draw - power_draw = min(power_draw, surplus) //what we actually get - if (power_draw > 0) - stored_charge += power_draw - PN.newload += power_draw //use powernet power + power_draw = PN.draw_power(power_draw) //what we actually get + stored_charge += power_draw time_since_fail++ if(stored_charge < last_stored_charge) diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm index 8025fa0809..f2f62581f8 100644 --- a/code/game/gamemodes/events/ninja_equipment.dm +++ b/code/game/gamemodes/events/ninja_equipment.dm @@ -1031,8 +1031,7 @@ ________________________________________________________________________________ drain = rand(G.mindrain,G.maxdrain) var/drained = 0 if(PN&&do_after(U,10)) - drained = min(drain, PN.avail) - PN.newload += drained + drained = PN.draw_power(drain) if(drained < drain)//if no power on net, drain apcs for(var/obj/machinery/power/terminal/T in PN.nodes) if(istype(T.master, /obj/machinery/power/apc)) @@ -1083,8 +1082,7 @@ ________________________________________________________________________________ drain = (round((rand(G.mindrain,G.maxdrain))/2)) var/drained = 0 if(PN&&do_after(U,10)) - drained = min(drain, PN.avail) - PN.newload += drained + drained = PN.draw_power(drain) if(drained < drain)//if no power on net, drain apcs for(var/obj/machinery/power/terminal/T in PN.nodes) if(istype(T.master, /obj/machinery/power/apc)) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index f7eacc0f50..b67b2cee3a 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -416,20 +416,17 @@ power = 0 return 0 - var/surplus = max(PN.avail-PN.load, 0) - var/shieldload = between(500, max_stored_power - storedpower, power_draw) //what we draw - shieldload = min(shieldload, surplus) //what we actually get - - if (shieldload) - power = 1 // IVE GOT THE POWER! - if(PN) //runtime errors fixer. They were caused by PN.newload trying to access missing network in case of working on stored power. - storedpower += shieldload - PN.newload += shieldload //use powernet power. + var/shieldload = between(500, max_stored_power - storedpower, power_draw) //what we try to draw + shieldload = PN.draw_power(shieldload) //what we actually get + storedpower += shieldload //If we're still in the red, then there must not be enough available power to cover our load. if(storedpower <= 0) power = 0 return 0 + + power = 1 // IVE GOT THE POWER! + return 1 /obj/machinery/shieldwallgen/process() spawn(100) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index b76b152284..fa9fb93d55 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1144,7 +1144,8 @@ /obj/machinery/power/apc/add_load(var/amount) if(terminal && terminal.powernet) - terminal.powernet.newload += amount + return terminal.powernet.draw_power(amount) + return 0 /obj/machinery/power/apc/avail() if(terminal) @@ -1176,13 +1177,7 @@ var/last_ch = charging var/excess = surplus() - - if(!src.avail()) - main_status = 0 - else if(excess < 0) - main_status = 1 - else - main_status = 2 + var/power_excess = 0 var/perapc = 0 if(terminal && terminal.powernet) @@ -1195,36 +1190,35 @@ //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 - cell.use(cellused) - - if(excess > 0 || perapc > lastused_total) // if power excess, or enough anyway, recharge the cell - // by the same amount just used - cell.give(cellused) - add_load(cellused/CELLRATE) // add the load used to recharge the cell - - - 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? - - cell.give(CELLRATE * perapc) //recharge with what we can - add_load(perapc) // so draw what we can from the grid + // try to draw power from the grid + if (!src.avail()) + main_status = 0 + else + var/power_drawn = add_load(perapc) + + //figure out how much power is left over after meeting demand + power_excess = power_drawn - lastused_total + + if (power_excess < 0) //couldn't get enough power from the grid, we will need to take from the power cell. + main_status = 1 charging = 0 + + var/required_power = -power_excess + if( (cell.charge/CELLRATE) >= required_power) // can we draw enough from cell to cover what's left over? + cell.use(required_power*CELLRATE) - 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 + else if (autoflag != 0) // not enough power available to run the last tick! + 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 + + else + main_status = 2 - - // set channels depending on how much charge we have left + // Set channels depending on how much charge we have left // Allow the APC to operate as normal if the cell can charge if(charging && longtermpower < 10) @@ -1267,10 +1261,9 @@ // 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*CELLRATE, (cell_maxcharge - cell.charge), (cell_maxcharge*CHARGELEVEL)) - add_load(ch/CELLRATE) // Removes the power we're taking from the grid + if(power_excess > 0) // check to make sure we have enough to charge + // Max charge is available excess power, capped to cell capacity, or % per second constant (Whichever is smallest) + var/ch = min(power_excess*CELLRATE, (cell_maxcharge - cell.charge), (cell_maxcharge*CHARGELEVEL)) cell.give(ch) // actually recharge the cell else @@ -1278,13 +1271,13 @@ chargecount = 0 // show cell as fully charged if so - if(cell.charge >= cell_maxcharge) charging = 2 + //if we have excess power for long enough, think about re-enable charging. if(chargemode) if(!charging) - if(excess > cell_maxcharge*CHARGELEVEL) + if(power_excess*CELLRATE >= cell_maxcharge*CHARGELEVEL) chargecount++ else chargecount = 0 @@ -1320,21 +1313,21 @@ src.updateDialog() // val 0=off, 1=off(auto) 2=on 3=on(auto) -// on 0=off, 1=on, 2=autooff +// on 0=off, 1=auto-on, 2=auto-off /proc/autoset(var/val, var/on) - if(on==0) + if(on==0) // turn things off if(val==2) // if on, return off return 0 else if(val==3) // if auto-on, return auto-off return 1 - else if(on==1) + else if(on==1) // turn things auto-on if(val==1) // if auto-off, return auto-on return 3 - else if(on==2) + else if(on==2) // turn things auto-off if(val==3) // if auto-on, return auto-off return 1 diff --git a/code/modules/power/batteryrack.dm b/code/modules/power/batteryrack.dm index 5f327495a7..e7a46b60fd 100644 --- a/code/modules/power/batteryrack.dm +++ b/code/modules/power/batteryrack.dm @@ -222,8 +222,9 @@ if(charging) if(excess >= 0) // if there's power available, try to charge var/load = min((capacity * 1.5 - charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity + load = add_load(load) // add the load to the terminal side network charge += load * SMESRATE // increase the charge - add_load(load) // add the load to the terminal side network + else // if not enough capacity charging = 0 // stop charging diff --git a/code/modules/power/cable_logic.dm b/code/modules/power/cable_logic.dm index 3a3b6f9180..a6e6e07b2b 100644 --- a/code/modules/power/cable_logic.dm +++ b/code/modules/power/cable_logic.dm @@ -130,7 +130,7 @@ if( !(pn_input.avail >= LOGIC_HIGH)) pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before. else - pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5 + pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5 @@ -202,7 +202,7 @@ if( (pn_input1.avail >= LOGIC_HIGH) && (pn_input2.avail >= LOGIC_HIGH) ) pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before. else - pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5 + pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5 //OR GATE /obj/machinery/logic/twoinput/or/process() @@ -222,7 +222,7 @@ if( (pn_input1.avail >= LOGIC_HIGH) || (pn_input2.avail >= LOGIC_HIGH) ) pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before. else - pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5 + pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5 //XOR GATE /obj/machinery/logic/twoinput/xor/process() @@ -242,7 +242,7 @@ if( (pn_input1.avail >= LOGIC_HIGH) != (pn_input2.avail >= LOGIC_HIGH) ) pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before. else - pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5 + pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5 //XNOR GATE (EQUIVALENCE) /obj/machinery/logic/twoinput/xnor/process() @@ -262,7 +262,7 @@ if( (pn_input1.avail >= LOGIC_HIGH) == (pn_input2.avail >= LOGIC_HIGH) ) pn_output.newavail = max(pn_output.avail, LOGIC_HIGH) //Set the output avilable power to 5 or whatever it was before. else - pn_output.newload += LOGIC_HIGH //Otherwise increase the load to 5 + pn_output.draw_power(LOGIC_HIGH) //Otherwise increase the load to 5 #define RELAY_POWER_TRANSFER 2000 //How much power a relay transfers through. @@ -284,7 +284,7 @@ return if(pn_input2.avail >= RELAY_POWER_TRANSFER) - pn_input2.newload += RELAY_POWER_TRANSFER + pn_input2.draw_power(RELAY_POWER_TRANSFER) pn_output.newavail += RELAY_POWER_TRANSFER diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 67f9b2b4ad..b1a9277e83 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -20,11 +20,12 @@ /obj/machinery/power/proc/add_load(var/amount) if(powernet) - powernet.newload += amount + return powernet.draw_power(amount) + return 0 /obj/machinery/power/proc/surplus() if(powernet) - return powernet.avail-powernet.load + return powernet.surplus() else return 0 @@ -402,6 +403,19 @@ error("[S.name] (\ref[S]) had a [S.powernet ? "different (\ref[S.powernet])" : "null"] powernet to our powernet (\ref[src]).") nodes.Remove(S) + +//Returns the amount of available power +/datum/powernet/proc/surplus() + return max(avail - newload, 0) + +//Attempts to draw power from a powernet. Returns the actual amount of power drawn +/datum/powernet/proc/draw_power(var/requested_amount) + var/surplus = max(avail - newload, 0) + var/actual_draw = min(requested_amount, surplus) + newload += actual_draw + + return actual_draw + /datum/powernet/proc/get_electrocute_damage() switch(avail)/* if (1300000 to INFINITY) @@ -551,11 +565,11 @@ var/drained_energy = drained_hp*20 if (source_area) - source_area.use_power(drained_energy/CELLRATE) + source_area.use_power(drained_energy) else if (istype(power_source,/datum/powernet)) - var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" - PN.newload+=drained_power + //var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" <<< NO. THIS IS WRONG. CELLRATE DOES NOT CONVERT TO OR FROM JOULES. + PN.draw_power(drained_energy) else if (istype(power_source, /obj/item/weapon/cell)) - cell.use(drained_energy) + cell.use(drained_energy*CELLRATE) //convert to units of charge. return drained_energy diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 1796eb754c..ce059c757e 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -107,8 +107,7 @@ return if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1)) - if(!active_power_usage || avail(active_power_usage)) - add_load(active_power_usage) + if(surplus() >= active_power_usage && add_load(active_power_usage) >= active_power_usage) //does the laser have enough power to shoot? if(!powered) powered = 1 update_icon() diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 92e7f8240a..6b782ca33b 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -88,8 +88,8 @@ 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 + load = add_load(load) // add the load to the terminal side network 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 @@ -186,7 +186,8 @@ /obj/machinery/power/smes/add_load(var/amount) if(terminal && terminal.powernet) - terminal.powernet.newload += amount + return terminal.powernet.draw_power(amount) + return 0 /obj/machinery/power/smes/attack_ai(mob/user) diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index 3312ff9dee..bb8762dad2 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -11,7 +11,8 @@ anchored = 1 density = 1 directwired = 1 - use_power = 0 + use_power = 0 // doesn't use APC power + var/power_usage = 500 //W var/sun_angle = 0 // sun angle as set by sun datum @@ -73,10 +74,7 @@ // make sure we can draw power from the powernet /obj/machinery/power/tracker/process() - var/avail = surplus() - - if(avail > 500) - add_load(500) + if(surplus() >= power_usage && add_load(power_usage) >= power_usage) stat &= ~NOPOWER else stat |= NOPOWER