diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 616ef4c6c9..1a3cce2cf9 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -112,23 +112,6 @@ Class Procs: var/interact_offline = 0 // Can the machine be interacted with while de-powered. var/global/gl_uid = 1 -/obj/machinery/drain_power(var/drain_check) - - if(drain_check) - return 1 - - if(!powered()) - return 0 - - var/area/area = get_area(src) - if(!area) - return 0 - - var/obj/machinery/power/apc/apc = area.get_apc() - if(!apc) - return 0 - return apc.drain_power() - /obj/machinery/New(l, d=0) ..(l) if(d) diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index e8ca9c3929..cf92db9a39 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -100,11 +100,17 @@ // now look for APCs and drain their cells if(drained < drain_rate) for(var/obj/machinery/power/terminal/T in PN.nodes) + // Enough power drained this tick, no need to torture more APCs + if(drained >= drain_rate) + break if(istype(T.master, /obj/machinery/power/apc)) var/obj/machinery/power/apc/A = T.master if(A.operating && A.cell) - A.cell.charge = max(0, A.cell.charge - (2000 * CELLRATE)) - power_drained += 2000 + var/cur_charge = A.cell.charge / CELLRATE + var/drain_val = min(2000, cur_charge) + + A.cell.use(drain_val * CELLRATE) + drained += drain_val if(power_drained > max_power * 0.95) diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 71293ef450..1b2befa59a 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -411,30 +411,33 @@ drain_complete(H) return - var/target_drained = interfaced_with.drain_power() + if(holder.cell.fully_charged()) + H << "Your power sink flashes an amber light; your rig cell is full." + drain_complete(H) + return + + // Attempts to drain up to 40kW, determines this value from remaining cell capacity to ensure we don't drain too much.. + var/to_drain = min(40000, ((holder.cell.maxcharge - holder.cell.charge) / CELLRATE)) + var/target_drained = interfaced_with.drain_power(0,0,to_drain) if(target_drained <= 0) H << "Your power sink flashes a red light; there is no power left in [interfaced_with]." drain_complete(H) return - holder.cell.charge += target_drained + holder.cell.give(target_drained * CELLRATE) total_power_drained += target_drained - if(holder.cell.charge > holder.cell.maxcharge) - H << "Your power sink flashes an amber light; your rig cell is full." - holder.cell.charge = holder.cell.maxcharge - drain_complete(H) - return + return 1 /obj/item/rig_module/power_sink/proc/drain_complete(var/mob/living/M) if(!interfaced_with) - if(M) M << "Total power drained: [total_power_drained]W." + if(M) M << "Total power drained: [round(total_power_drained/1000)]kJ." else - if(M) M << "Total power drained from [interfaced_with]: [total_power_drained]W." - interfaced_with.drain_power(0,1) // Damage the victim. + if(M) M << "Total power drained from [interfaced_with]: [round(total_power_drained/1000)]kJ." + interfaced_with.drain_power(0,1,0) // Damage the victim. interfaced_with = null total_power_drained = 0 \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 05c1953822..aeebc30bb3 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -182,7 +182,7 @@ var/list/robot_verbs_default = list( lawsync() photosync() -/mob/living/silicon/robot/drain_power(var/drain_check) +/mob/living/silicon/robot/drain_power(var/drain_check, var/surge, var/amount = 0) if(drain_check) return 1 @@ -190,14 +190,15 @@ var/list/robot_verbs_default = list( if(!cell || !cell.charge) return 0 - if(cell.charge) - src << "Warning: Unauthorized access through power channel 12 detected." - var/drained_power = rand(200,400) - if(cell.charge < drained_power) - drained_power = cell.charge - cell.use(drained_power) - return drained_power + // Actual amount to drain from cell, using CELLRATE + var/cell_amount = amount * CELLRATE + if(cell.charge > cell_amount) + // Spam Protection + if(prob(10)) + src << "Warning: Unauthorized access through power channel [rand(11,29)] detected!" + cell.use(cell_amount) + return amount return 0 // setup the PDA and its name diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f414fbf915..1d0150ecf6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -66,7 +66,7 @@ // If drain_check is set it will not actually drain power, just return a value. // If surge is set, it will destroy/damage the recipient and not return any power. // Not sure where to define this, so it can sit here for the rest of time. -/atom/proc/drain_power(var/drain_check,var/surge) +/atom/proc/drain_power(var/drain_check,var/surge, var/amount = 0) return -1 // Show a message to all mobs in earshot of this one diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 2e766d2f83..d6fd780a40 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -116,7 +116,7 @@ if(terminal) terminal.connect_to_network() -/obj/machinery/power/apc/drain_power(var/drain_check, var/surge) +/obj/machinery/power/apc/drain_power(var/drain_check, var/surge, var/amount = 0) if(drain_check) return 1 @@ -131,7 +131,10 @@ update_icon() return 0 - return cell.drain_power(drain_check) + if(terminal && terminal.powernet) + terminal.powernet.trigger_warning() + + return cell.drain_power(drain_check, surge, amount) /obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0) ..() @@ -178,10 +181,10 @@ del(cell) // qdel if(terminal) disconnect_terminal() - + //If there's no more APC then there shouldn't be a cause for alarm I guess area.poweralert(1, src) //so that alarms don't go on forever - + ..() /obj/machinery/power/apc/proc/make_terminal() diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 27e1fc3a2b..de072d8d5a 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -36,7 +36,7 @@ By design, d1 is the smallest direction and d2 is the highest color = COLOR_RED var/obj/machinery/power/breakerbox/breaker_box -/obj/structure/cable/drain_power(var/drain_check) +/obj/structure/cable/drain_power(var/drain_check, var/surge, var/amount = 0) if(drain_check) return 1 @@ -44,18 +44,7 @@ By design, d1 is the smallest direction and d2 is the highest var/datum/powernet/PN = get_powernet() if(!PN) return 0 - var/drained_power = round(rand(200,400)/2) - var/drained_this_tick = PN.draw_power(drained_power) - - if(drained_this_tick < drained_power) - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/AP = T.master - if(AP.emagged) - continue - drained_power += AP.drain_power() //Indirect draw won't emag the APC, should this be amended? - - return drained_power + return PN.draw_power(amount) /obj/structure/cable/yellow color = COLOR_YELLOW diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index b76086b567..36ab1047a3 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -9,16 +9,17 @@ spawn(5) updateicon() -/obj/item/weapon/cell/drain_power(var/drain_check) +/obj/item/weapon/cell/drain_power(var/drain_check, var/surge, var/amount = 0) if(drain_check) return 1 - var/drained_power = rand(200,400) - if(charge < drained_power) - drained_power = charge - use(drained_power) - return drained_power + if(charge <= 0) + return 0 + + var/cell_amt = min((amount * CELLRATE), charge) + use(cell_amt) + return cell_amt / CELLRATE /obj/item/weapon/cell/proc/updateicon() overlays.Cut() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 76b712d4cb..4836c3601c 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -24,6 +24,14 @@ ////////////////////////////// // common helper procs for all power machines +/obj/machinery/power/drain_power(var/drain_check, var/surge, var/amount = 0) + if(drain_check) + return 1 + + if(powernet && powernet.avail) + powernet.trigger_warning() + return powernet.draw_power(amount) + /obj/machinery/power/proc/add_avail(var/amount) if(powernet) powernet.newavail += amount diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 61677068b8..11bcef5881 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -1,6 +1,7 @@ // the SMES // stores power +#define SMESRATE 0.05 #define SMESMAXCHARGELEVEL 250000 #define SMESMAXOUTPUT 250000 @@ -43,22 +44,15 @@ var/obj/machinery/power/terminal/terminal = null var/should_be_mapped = 0 // If this is set to 0 it will send out warning on New() -/obj/machinery/power/smes/drain_power(var/drain_check) +/obj/machinery/power/smes/drain_power(var/drain_check, var/surge, var/amount = 0) if(drain_check) return 1 - if(!charge) - return 0 + var/smes_amt = min((amount * SMESRATE), charge) + charge -= smes_amt + return smes_amt / SMESRATE - if(charge) - var/drained_power = rand(200,400) - if(charge < drained_power) - drained_power = charge - charge -= drained_power - return drained_power - - return 0 /obj/machinery/power/smes/New() ..() @@ -112,9 +106,6 @@ /obj/machinery/power/smes/proc/chargedisplay() return round(5.5*charge/(capacity ? capacity : 5e6)) -#define SMESRATE 0.05 // rate of internal charge to external power - - /obj/machinery/power/smes/process() if(stat & BROKEN) return @@ -420,4 +411,4 @@ /obj/machinery/power/smes/magical/process() charge = 5000000 - ..() + ..()