mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-01-28 18:21:51 +00:00
Electrical Storm event does nothing because it checks for valid target APCs in SSmachinery, but SSmachinery currently doesn't hold a list of APCs to use. This PR correctly registers APCs on init and unregisters them on destroy so that Electrical Storms will actually upset Engineers now. This should proooobably come with an IG bulletin on the discord or something warning engineers that their shit will actually get rocked (especially since its kind of weird in-universe that electrical storms that used to Do Nothing actually have an impact) now).
267 lines
9.0 KiB
Plaintext
267 lines
9.0 KiB
Plaintext
#define SSMACHINERY_PIPENETS 1
|
|
#define SSMACHINERY_MACHINERY 2
|
|
#define SSMACHINERY_POWERNETS 3
|
|
|
|
|
|
#define START_PROCESSING_IN_LIST(Datum, List) \
|
|
if (Datum.datum_flags & DF_ISPROCESSING) {\
|
|
crash_with("Failed to start processing. [log_info_line(Datum)] is already being processed but queue attempt occured on SSmachinery.[#List]."); \
|
|
} else {\
|
|
Datum.datum_flags |= DF_ISPROCESSING;\
|
|
SSmachinery.List += Datum;\
|
|
}
|
|
|
|
#define STOP_PROCESSING_IN_LIST(Datum, List) \
|
|
if(Datum.datum_flags & DF_ISPROCESSING) {\
|
|
if(SSmachinery.List.Remove(Datum)) {\
|
|
(Datum.datum_flags &= ~DF_ISPROCESSING);\
|
|
} else {\
|
|
crash_with("Failed to stop processing. [log_info_line(Datum)] is being processed and not found in SSmachinery.[#List]"); \
|
|
}\
|
|
}
|
|
|
|
#define START_PROCESSING_PIPENET(Datum) START_PROCESSING_IN_LIST(Datum, pipenets)
|
|
#define STOP_PROCESSING_PIPENET(Datum) STOP_PROCESSING_IN_LIST(Datum, pipenets)
|
|
|
|
#define START_PROCESSING_POWERNET(Datum) START_PROCESSING_IN_LIST(Datum, powernets)
|
|
#define STOP_PROCESSING_POWERNET(Datum) STOP_PROCESSING_IN_LIST(Datum, powernets)
|
|
|
|
SUBSYSTEM_DEF(machinery)
|
|
name = "Machinery"
|
|
init_order = INIT_ORDER_MACHINES
|
|
priority = SS_PRIORITY_MACHINERY
|
|
flags = SS_KEEP_TIMING
|
|
wait = 2 SECONDS
|
|
|
|
var/static/tmp/current_step = SSMACHINERY_PIPENETS
|
|
var/static/tmp/cost_pipenets = 0
|
|
var/static/tmp/cost_machinery = 0
|
|
var/static/tmp/cost_powernets = 0
|
|
var/static/tmp/list/pipenets = list()
|
|
var/static/tmp/list/machinery = list()
|
|
var/static/tmp/list/powernets = list()
|
|
var/static/tmp/list/processing = list()
|
|
var/static/tmp/list/queue = list()
|
|
|
|
var/list/all_cameras = list()
|
|
var/list/obj/machinery/hologram/holopad/all_holopads = list()
|
|
var/list/obj/machinery/power/apc/all_apcs = list()
|
|
var/list/all_status_displays = list() // Note: This contains both ai_status_display and status_display.
|
|
var/list/gravity_generators = list()
|
|
var/list/obj/machinery/telecomms/all_telecomms = list()
|
|
var/list/obj/machinery/telecomms/all_receivers = list()
|
|
|
|
var/list/rcon_smes_units = list()
|
|
var/list/rcon_smes_units_by_tag = list()
|
|
var/list/rcon_breaker_units = list()
|
|
var/list/rcon_breaker_units_by_tag = list()
|
|
// Not yet implemented, added for future.
|
|
var/list/rcon_apc_units = list()
|
|
// Not yet implemented, added for future.
|
|
var/list/rcon_apc_units_by_tag = list()
|
|
|
|
var/list/breaker_boxes = list()
|
|
var/list/smes_units = list()
|
|
var/list/apc_units = list()
|
|
var/list/all_sensors = list()
|
|
|
|
var/list/slept_in_process = list()
|
|
|
|
// Cooking stuff. Not substantial enough to get its own SS, so it's shoved in here.
|
|
var/list/recipe_datums = list()
|
|
|
|
/datum/controller/subsystem/machinery/Recover()
|
|
all_cameras = SSmachinery.all_cameras
|
|
all_holopads = SSmachinery.all_holopads
|
|
all_apcs = SSmachinery.all_apcs
|
|
recipe_datums = SSmachinery.recipe_datums
|
|
breaker_boxes = SSmachinery.breaker_boxes
|
|
all_sensors = SSmachinery.all_sensors
|
|
all_telecomms = SSmachinery.all_telecomms
|
|
all_receivers = SSmachinery.all_receivers
|
|
current_step = SSMACHINERY_PIPENETS
|
|
|
|
/datum/controller/subsystem/machinery/Initialize(timeofday)
|
|
makepowernets()
|
|
build_rcon_lists()
|
|
setup_atmos_machinery(machinery)
|
|
fire(FALSE, TRUE) // Tick machinery once to pare down the list so we don't hammer the server on round-start.
|
|
|
|
return SS_INIT_SUCCESS
|
|
|
|
/datum/controller/subsystem/machinery/fire(resumed = FALSE, no_mc_tick = FALSE)
|
|
var/timer
|
|
if (!resumed || current_step == SSMACHINERY_PIPENETS)
|
|
timer = world.tick_usage
|
|
process_pipenets(resumed, no_mc_tick)
|
|
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(world.tick_usage - timer))
|
|
if (state != SS_RUNNING && initialized)
|
|
return
|
|
current_step = SSMACHINERY_MACHINERY
|
|
resumed = FALSE
|
|
if (current_step == SSMACHINERY_MACHINERY)
|
|
timer = world.tick_usage
|
|
process_machinery(resumed, no_mc_tick)
|
|
cost_machinery = MC_AVERAGE(cost_machinery, TICK_DELTA_TO_MS(world.tick_usage - timer))
|
|
if(state != SS_RUNNING && initialized)
|
|
return
|
|
current_step = SSMACHINERY_POWERNETS
|
|
resumed = FALSE
|
|
if (current_step == SSMACHINERY_POWERNETS)
|
|
timer = world.tick_usage
|
|
process_powernets(resumed, no_mc_tick)
|
|
cost_powernets = MC_AVERAGE(cost_powernets, TICK_DELTA_TO_MS(world.tick_usage - timer))
|
|
if(state != SS_RUNNING && initialized)
|
|
return
|
|
current_step = SSMACHINERY_PIPENETS
|
|
resumed = FALSE
|
|
|
|
/datum/controller/subsystem/machinery/proc/makepowernets()
|
|
for(var/datum/powernet/powernet as anything in powernets)
|
|
qdel(powernet)
|
|
powernets.Cut()
|
|
setup_powernets_for_cables(GLOB.cable_list)
|
|
|
|
/datum/controller/subsystem/machinery/proc/setup_powernets_for_cables(list/cables)
|
|
for (var/obj/structure/cable/cable as anything in cables)
|
|
if (cable.powernet)
|
|
continue
|
|
var/datum/powernet/network = new
|
|
network.add_cable(cable)
|
|
propagate_network(cable, cable.powernet)
|
|
|
|
/datum/controller/subsystem/machinery/proc/setup_atmos_machinery(list/machines)
|
|
var/list/atmos_machines = list()
|
|
for (var/obj/machinery/atmospherics/machine in machines)
|
|
if(QDELETED(machine))
|
|
continue
|
|
atmos_machines += machine
|
|
admin_notice(SPAN_DANGER("Initializing atmos machinery."), R_DEBUG)
|
|
log_subsystem("machinery", "Initializing atmos machinery.")
|
|
for (var/obj/machinery/atmospherics/machine as anything in atmos_machines)
|
|
machine.atmos_init()
|
|
CHECK_TICK
|
|
admin_notice(SPAN_DANGER("Initializing pipe networks."), R_DEBUG)
|
|
log_subsystem("machinery", "Initializing pipe networks.")
|
|
for (var/obj/machinery/atmospherics/machine as anything in atmos_machines)
|
|
machine.build_network()
|
|
CHECK_TICK
|
|
|
|
/datum/controller/subsystem/machinery/proc/process_pipenets(resumed, no_mc_tick)
|
|
if (!resumed)
|
|
queue = pipenets.Copy()
|
|
var/datum/pipe_network/network
|
|
for (var/i = queue.len to 1 step -1)
|
|
network = queue[i]
|
|
if (QDELETED(network))
|
|
if (network)
|
|
network.datum_flags &= ~DF_ISPROCESSING
|
|
pipenets -= network
|
|
continue
|
|
network.process(wait * 0.1)
|
|
if (no_mc_tick)
|
|
CHECK_TICK
|
|
else if (MC_TICK_CHECK)
|
|
queue.Cut(i)
|
|
return
|
|
|
|
/datum/controller/subsystem/machinery/proc/process_machinery(resumed, no_mc_tick)
|
|
if (!resumed)
|
|
queue = processing.Copy()
|
|
var/obj/machinery/machine
|
|
for (var/i = queue.len to 1 step -1)
|
|
machine = queue[i]
|
|
|
|
if(!istype(machine)) // Below is a debugging and recovery effort. This should never happen, but has been observed recently.
|
|
if(!machine)
|
|
continue // Hard delete; unlikely but possible. Soft deletes are handled below and expected.
|
|
if(machine in processing)
|
|
processing.Remove(machine)
|
|
machine.datum_flags &= ~DF_ISPROCESSING
|
|
WARNING("[log_info_line(machine)] was found illegally queued on SSmachines.")
|
|
continue
|
|
else if(resumed)
|
|
queue.Cut() // Abandon current run; assuming that we were improperly resumed with the wrong process queue.
|
|
WARNING("[log_info_line(machine)] was in the wrong subqueue on SSmachines on a resumed fire.")
|
|
process_machinery(0)
|
|
return
|
|
else // ??? possibly dequeued by another machine or something ???
|
|
WARNING("[log_info_line(machine)] was in the wrong subqueue on SSmachines on an unresumed fire.")
|
|
continue
|
|
|
|
if (QDELETED(machine))
|
|
if (machine)
|
|
machine.datum_flags &= ~DF_ISPROCESSING
|
|
processing -= machine
|
|
continue
|
|
//process_all was moved here because of calls overhead for no benefits
|
|
if((machine.processing_flags & MACHINERY_PROCESS_SELF))
|
|
if(machine.process(wait * 0.1) == PROCESS_KILL)
|
|
STOP_PROCESSING_MACHINE(machine, MACHINERY_PROCESS_SELF)
|
|
processing -= machine
|
|
if (no_mc_tick)
|
|
CHECK_TICK
|
|
else if (MC_TICK_CHECK)
|
|
queue.Cut(i)
|
|
return
|
|
|
|
/datum/controller/subsystem/machinery/proc/process_powernets(resumed, no_mc_tick)
|
|
if (!resumed)
|
|
queue = powernets.Copy()
|
|
var/datum/powernet/network
|
|
for (var/i = queue.len to 1 step -1)
|
|
network = queue[i]
|
|
if (QDELETED(network))
|
|
if (network)
|
|
network.datum_flags &= ~DF_ISPROCESSING
|
|
powernets -= network
|
|
continue
|
|
network.reset(wait)
|
|
if (no_mc_tick)
|
|
CHECK_TICK
|
|
else if (MC_TICK_CHECK)
|
|
queue.Cut(i)
|
|
return
|
|
|
|
/datum/controller/subsystem/machinery/stat_entry(msg)
|
|
msg = {"\n\
|
|
Queues: \
|
|
Pipes [pipenets.len] \
|
|
Machines [processing.len] \
|
|
Networks [powernets.len] \
|
|
Costs: \
|
|
Pipes [round(cost_pipenets, 1)] \
|
|
Machines [round(cost_machinery, 1)] \
|
|
Networks [round(cost_powernets, 1)] \
|
|
Overall [round(cost ? processing.len / cost : 0, 0.1)]
|
|
"}
|
|
return ..()
|
|
|
|
/datum/controller/subsystem/machinery/ExplosionStart()
|
|
can_fire = FALSE
|
|
|
|
/datum/controller/subsystem/machinery/ExplosionEnd()
|
|
can_fire = TRUE
|
|
|
|
/datum/controller/subsystem/machinery/proc/build_rcon_lists()
|
|
rcon_smes_units.Cut()
|
|
rcon_breaker_units.Cut()
|
|
rcon_breaker_units_by_tag.Cut()
|
|
|
|
for(var/obj/machinery/power/smes/buildable/SMES in smes_units)
|
|
if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon)
|
|
rcon_smes_units += SMES
|
|
rcon_smes_units_by_tag[SMES.RCon_tag] = SMES
|
|
|
|
for(var/obj/machinery/power/breakerbox/breaker in breaker_boxes)
|
|
if(breaker.RCon_tag != "NO_TAG")
|
|
rcon_breaker_units += breaker
|
|
rcon_breaker_units_by_tag[breaker.RCon_tag] = breaker
|
|
|
|
sortTim(rcon_smes_units, GLOBAL_PROC_REF(cmp_rcon_smes))
|
|
sortTim(rcon_breaker_units, GLOBAL_PROC_REF(cmp_rcon_bbox))
|
|
|
|
#undef SSMACHINERY_PIPENETS
|
|
#undef SSMACHINERY_MACHINERY
|
|
#undef SSMACHINERY_POWERNETS
|