diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index ee031e21043..dad177b7c5a 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -305,12 +305,14 @@ #define SSEXPLOSIONS_THROWS 3 // Machines subsystem subtasks. -#define SSMACHINES_MACHINES 1 +#define SSMACHINES_MACHINES_EARLY 1 #define SSMACHINES_APCS_EARLY 2 #define SSMACHINES_APCS_ENVIRONMENT 3 #define SSMACHINES_APCS_LIGHTS 4 #define SSMACHINES_APCS_EQUIPMENT 5 #define SSMACHINES_APCS_LATE 6 +#define SSMACHINES_MACHINES 7 +#define SSMACHINES_MACHINES_LATE 8 // Wardrobe subsystem tasks #define SSWARDROBE_STOCK 1 diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm index 25c2b3365fb..a9950f1f4d8 100644 --- a/code/controllers/subsystem/machines.dm +++ b/code/controllers/subsystem/machines.dm @@ -11,15 +11,17 @@ SUBSYSTEM_DEF(machines) VAR_PRIVATE/list/all_machines = list() var/list/processing = list() + var/list/processing_early = list() + var/list/processing_late = list() var/list/processing_apcs = list() var/list/currentrun = list() - var/current_part = SSMACHINES_MACHINES + var/current_part = SSMACHINES_MACHINES_EARLY var/list/apc_steps = list( + SSMACHINES_APCS_EARLY, SSMACHINES_APCS_ENVIRONMENT, SSMACHINES_APCS_LIGHTS, SSMACHINES_APCS_EQUIPMENT, - SSMACHINES_APCS_EARLY, SSMACHINES_APCS_LATE ) ///List of all powernets on the server. @@ -89,18 +91,18 @@ SUBSYSTEM_DEF(machines) if (!resumed) for(var/datum/powernet/powernet as anything in powernets) powernet.reset() //reset the power state. - current_part = SSMACHINES_MACHINES - src.currentrun = processing.Copy() + current_part = SSMACHINES_MACHINES_EARLY + src.currentrun = processing_early.Copy() - //Processing all machines - if(current_part == SSMACHINES_MACHINES) + //Processing machines that get the priority power draw + if(current_part == SSMACHINES_MACHINES_EARLY) //cache for sanic speed (lists are references anyways) var/list/currentrun = src.currentrun while(currentrun.len) var/obj/machinery/thing = currentrun[currentrun.len] currentrun.len-- - if(QDELETED(thing) || thing.process(wait * 0.1) == PROCESS_KILL) - processing -= thing + if(QDELETED(thing) || thing.process_early(wait * 0.1) == PROCESS_KILL) + processing_early -= thing thing.datum_flags &= ~DF_ISPROCESSING if (MC_TICK_CHECK) return @@ -129,10 +131,40 @@ SUBSYSTEM_DEF(machines) return var/next_index = apc_steps.Find(current_part) + 1 if (next_index > apc_steps.len) - return + current_part = SSMACHINES_MACHINES + src.currentrun = processing.Copy() + break current_part = apc_steps[next_index] src.currentrun = processing_apcs.Copy() + //Processing all machines + if(current_part == SSMACHINES_MACHINES) + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + while(currentrun.len) + var/obj/machinery/thing = currentrun[currentrun.len] + currentrun.len-- + if(QDELETED(thing) || thing.process(wait * 0.1) == PROCESS_KILL) + processing -= thing + thing.datum_flags &= ~DF_ISPROCESSING + if (MC_TICK_CHECK) + return + current_part = SSMACHINES_MACHINES_LATE + src.currentrun = processing_late.Copy() + + //Processing machines that record the power usage statistics + if(current_part == SSMACHINES_MACHINES_LATE) + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + while(currentrun.len) + var/obj/machinery/thing = currentrun[currentrun.len] + currentrun.len-- + if(QDELETED(thing) || thing.process_late(wait * 0.1) == PROCESS_KILL) + processing_late -= thing + thing.datum_flags &= ~DF_ISPROCESSING + if (MC_TICK_CHECK) + return + /datum/controller/subsystem/machines/proc/setup_template_powernets(list/cables) var/obj/structure/cable/PC for(var/A in 1 to cables.len) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 66384921496..2c84ce1c37c 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -284,9 +284,17 @@ /obj/machinery/proc/locate_machinery() return +///Early process for machines added to SSmachines.processing_early to prioritize power draw +/obj/machinery/proc/process_early() + return PROCESS_KILL + /obj/machinery/process()//If you dont use process or power why are you here return PROCESS_KILL +///Late process for machines added to SSmachines.processing_late to gather accurate recordings +/obj/machinery/proc/process_late() + return PROCESS_KILL + /obj/machinery/proc/process_atmos()//If you dont use process why are you here return PROCESS_KILL diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 1ef5e9d18c0..d5dc9e3a26e 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -324,6 +324,8 @@ /obj/machinery/power/shieldwallgen/Initialize(mapload) . = ..() + //Add to the early process queue to prioritize power draw + SSmachines.processing_early += src if(anchored) connect_to_network() RegisterSignal(src, COMSIG_ATOM_SINGULARITY_TRY_MOVE, PROC_REF(block_singularity_if_active)) @@ -356,7 +358,7 @@ return FALSE . = ..() -/obj/machinery/power/shieldwallgen/process() +/obj/machinery/power/shieldwallgen/process_early() if(active) if(active == ACTIVE_SETUPFIELDS) var/fields = 0 diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index b536fa39352..891212b6b0d 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -371,7 +371,7 @@ "powerCellStatus" = cell ? cell.percent() : null, "chargeMode" = chargemode, "chargingStatus" = charging, - "chargingPowerDisplay" = display_power(area.energy_usage[AREA_USAGE_APC_CHARGE]), + "chargingPowerDisplay" = display_power(lastused_charge), "totalLoad" = display_power(lastused_total), "coverLocked" = coverlocked, "remoteAccess" = (user == remote_control_user), @@ -529,6 +529,9 @@ * This adds up the total static power usage for the apc's area, then draw that power usage from the grid or APC cell. */ /obj/machinery/power/apc/proc/early_process() + if(cell && cell.charge < cell.maxcharge) + last_charging = charging + charging = APC_NOT_CHARGING if(isnull(area)) return @@ -536,6 +539,8 @@ total_static_energy_usage += APC_CHANNEL_IS_ON(lighting) * area.energy_usage[AREA_USAGE_STATIC_LIGHT] total_static_energy_usage += APC_CHANNEL_IS_ON(equipment) * area.energy_usage[AREA_USAGE_STATIC_EQUIP] total_static_energy_usage += APC_CHANNEL_IS_ON(environ) * area.energy_usage[AREA_USAGE_STATIC_ENVIRON] + area.clear_usage() + if(total_static_energy_usage) //Use power from static power users. draw_energy(total_static_energy_usage) @@ -560,7 +565,7 @@ lastused_light = APC_CHANNEL_IS_ON(lighting) ? area.energy_usage[AREA_USAGE_LIGHT] + area.energy_usage[AREA_USAGE_STATIC_LIGHT] : 0 lastused_equip = APC_CHANNEL_IS_ON(equipment) ? area.energy_usage[AREA_USAGE_EQUIP] + area.energy_usage[AREA_USAGE_STATIC_EQUIP] : 0 lastused_environ = APC_CHANNEL_IS_ON(environ) ? area.energy_usage[AREA_USAGE_ENVIRON] + area.energy_usage[AREA_USAGE_STATIC_ENVIRON] : 0 - area.clear_usage() + lastused_charge = charging == APC_CHARGING ? area.energy_usage[AREA_USAGE_APC_CHARGE] : 0 lastused_total = lastused_light + lastused_equip + lastused_environ + lastused_charge @@ -629,26 +634,16 @@ lighting = autoset(lighting, AUTOSET_FORCE_OFF) environ = autoset(environ, AUTOSET_FORCE_OFF) alarm_manager.send_alarm(ALARM_POWER) - // update icon & area power if anything changed if(last_lt != lighting || last_eq != equipment || last_en != environ || force_update) force_update = FALSE queue_icon_update() update() - if(charging != last_charging) + else if(charging != last_charging) queue_icon_update() - // show cell as fully charged if so - if(cell.charge >= cell.maxcharge) - cell.charge = cell.maxcharge - charging = APC_FULLY_CHARGED // charge until the battery is full or to the treshold of the provided channel /obj/machinery/power/apc/proc/charge_channel(channel = null, seconds_per_tick) - if(channel == SSMACHINES_APCS_ENVIRONMENT) - lastused_charge = 0 - last_charging = charging - charging = APC_NOT_CHARGING - if(!cell || shorted || !operating || !chargemode || !surplus() || !cell.used_charge()) return @@ -664,14 +659,21 @@ else need_charge_for_channel = cell.used_charge() - var/remaining_charge_rate = min(cell.chargerate, cell.maxcharge * CHARGELEVEL) - lastused_charge + var/charging_used = area ? area.energy_usage[AREA_USAGE_APC_CHARGE] : 0 + var/remaining_charge_rate = min(cell.chargerate, cell.maxcharge * CHARGELEVEL) - charging_used var/need_charge = min(need_charge_for_channel, remaining_charge_rate) * seconds_per_tick //check if we can charge the battery if(need_charge < 0) return - lastused_charge += charge_cell(need_charge, cell = cell, grid_only = TRUE, channel = AREA_USAGE_APC_CHARGE) - charging = APC_CHARGING + charge_cell(need_charge, cell = cell, grid_only = TRUE, channel = AREA_USAGE_APC_CHARGE) + + // show cell as fully charged if so + if(cell.charge >= cell.maxcharge) + cell.charge = cell.maxcharge + charging = APC_FULLY_CHARGED + else + charging = APC_CHARGING /obj/machinery/power/apc/proc/reset(wire) switch(wire) diff --git a/code/modules/power/monitor.dm b/code/modules/power/monitor.dm index 289b2d46fab..3794fc7f796 100644 --- a/code/modules/power/monitor.dm +++ b/code/modules/power/monitor.dm @@ -19,11 +19,13 @@ /obj/machinery/computer/monitor/Initialize(mapload) . = ..() + //Add to the late process queue to record the accurate power usage data + SSmachines.processing_late += src search() history["supply"] = list() history["demand"] = list() -/obj/machinery/computer/monitor/process() +/obj/machinery/computer/monitor/process_late() if(!get_powernet()) update_use_power(IDLE_POWER_USE) search() diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 5cab751e6e7..414baedec34 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -60,6 +60,8 @@ /obj/machinery/power/emitter/Initialize(mapload) . = ..() + //Add to the early process queue to prioritize power draw + SSmachines.processing_early += src RefreshParts() set_wires(new /datum/wires/emitter(src)) if(welded) @@ -187,7 +189,7 @@ togglelock(user) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/machinery/power/emitter/process(seconds_per_tick) +/obj/machinery/power/emitter/process_early(seconds_per_tick) var/power_usage = active_power_usage * seconds_per_tick if(machine_stat & (BROKEN)) return