Files
Aurora.3/code/controllers/subsystems/machinery.dm
2017-12-09 13:51:25 -06:00

229 lines
7.0 KiB
Plaintext

#define MACHINERY_GO_TO_NEXT if (no_mc_tick) { CHECK_TICK; } else if (MC_TICK_CHECK) { return; } else { continue; }
/var/datum/controller/subsystem/machinery/SSmachinery
/datum/controller/subsystem/machinery
name = "Machinery"
priority = SS_PRIORITY_MACHINERY
init_order = SS_INIT_MACHINERY
flags = SS_POST_FIRE_TIMING
var/tmp/list/all_machines = list() // A list of all machines. Including the non-processing ones.
var/tmp/list/processing_machines = list() // A list of machines that process.
var/tmp/list/working_machinery = list() // A list of machinery left to process this work cycle.
var/tmp/list/working_powersinks = list() // A list of machinery draining power to process this work cycle.
var/tmp/powernets_reset_yet
var/tmp/processes_this_tick = 0
var/tmp/powerusers_this_tick = 0
var/list/all_cameras = list()
var/list/all_status_displays = list() // Note: This contains both ai_status_display and status_display.
var/list/gravity_generators = list()
var/rcon_update_queued = FALSE
var/powernet_update_queued = FALSE
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
recipe_datums = SSmachinery.recipe_datums
/datum/controller/subsystem/machinery/proc/queue_rcon_update()
rcon_update_queued = TRUE
/datum/controller/subsystem/machinery/New()
NEW_SS_GLOBAL(SSmachinery)
#define ADD_TO_RDATUMS(i,t) if (R.appliance & i) { LAZYADD(recipe_datums["[i]"], t); added++; }
/datum/controller/subsystem/machinery/Initialize(timeofday)
for (var/type in subtypesof(/datum/recipe))
var/datum/recipe/R = new type
var/added = 0
ADD_TO_RDATUMS(MICROWAVE, R)
ADD_TO_RDATUMS(FRYER, R)
ADD_TO_RDATUMS(OVEN, R)
ADD_TO_RDATUMS(CANDYMAKER, R)
ADD_TO_RDATUMS(CEREALMAKER, R)
if (!added)
log_debug("SSmachinery: warning: type '[type]' does not have a valid machine type.")
qdel(R)
fire(FALSE, TRUE) // Tick machinery once to pare down the list so we don't hammer the server on round-start.
..(timeofday)
#undef ADD_TO_RDATUMS
/datum/controller/subsystem/machinery/fire(resumed = 0, no_mc_tick = FALSE)
if (!resumed)
src.working_machinery = processing_machines.Copy()
src.working_powersinks = processing_power_items.Copy()
powernets_reset_yet = FALSE
// Reset accounting vars.
processes_this_tick = 0
powerusers_this_tick = 0
if (rcon_update_queued)
rcon_update_queued = FALSE
SSpower.build_rcon_lists()
if (powernet_update_queued)
makepowernets()
powernet_update_queued = FALSE
if (cameranet.cameras_unsorted)
sortTim(cameranet.cameras, /proc/cmp_camera)
cameranet.cameras_unsorted = FALSE
var/list/curr_machinery = working_machinery
var/list/curr_powersinks = working_powersinks
while (curr_machinery.len)
var/obj/machinery/M = curr_machinery[curr_machinery.len]
curr_machinery.len--
if (QDELETED(M))
log_debug("SSmachinery: QDELETED machine [DEBUG_REF(M)] found in machines list! Removing.")
remove_machine(M, TRUE)
continue
var/start_tick = world.time
if (M.machinery_processing)
processes_this_tick++
switch (M.machinery_process())
if (PROCESS_KILL)
remove_machine(M, FALSE)
if (M_NO_PROCESS)
M.machinery_processing = FALSE
if (start_tick != world.time)
// Slept.
if (!slept_in_process[M.type])
log_debug("SSmachinery: Type '[M.type]' slept during machinery_process().")
slept_in_process[M.type] = TRUE
// I'm sorry.
if (M.use_power && isturf(M.loc))
powerusers_this_tick++
if (M.has_special_power_checks)
M.auto_use_power()
else
var/area/A = M.loc.loc
var/chan = M.power_channel
if ((A.has_weird_power && !A.powered(chan)))
MACHINERY_GO_TO_NEXT
if (A.requires_power)
if (A.always_unpowered)
MACHINERY_GO_TO_NEXT
switch (chan)
if (EQUIP)
if (!A.power_equip)
MACHINERY_GO_TO_NEXT
if (LIGHT)
if (!A.power_light)
MACHINERY_GO_TO_NEXT
if (ENVIRON)
if (!A.power_environ)
MACHINERY_GO_TO_NEXT
else // ?!
log_debug("SSmachinery: Type '[M.type]' has insane channel [chan] (expected value in range 1-3).")
M.use_power = FALSE
MACHINERY_GO_TO_NEXT
if (A.has_weird_power)
A.use_power(M.use_power == 2 ? M.active_power_usage : M.idle_power_usage, chan)
else
switch (chan)
if (EQUIP)
A.used_equip += M.use_power == 2 ? M.active_power_usage : M.idle_power_usage
if (LIGHT)
A.used_light += M.use_power == 2 ? M.active_power_usage : M.idle_power_usage
if (ENVIRON)
A.used_environ += M.use_power == 2 ? M.active_power_usage : M.idle_power_usage
else // ?!
log_debug("SSmachinery: Type '[M.type]' has insane channel [chan] (expected value in range 1-3).")
M.use_power = FALSE
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
return
if (!powernets_reset_yet)
SSpower.reset_powernets()
powernets_reset_yet = TRUE
while (curr_powersinks.len)
var/obj/item/I = curr_powersinks[curr_powersinks.len]
curr_powersinks.len--
if (QDELETED(I) || !I.pwr_drain())
processing_power_items -= I
log_debug("SSmachinery: QDELETED item [DEBUG_REF(I)] found in processing power items list.")
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
return
/datum/controller/subsystem/machinery/stat_entry()
var/list/out = list()
out += "AM:[all_machines.len] PM:[processing_machines.len] PI:[processing_power_items.len]"
out += "LT:{T:[processes_this_tick]|P:[powerusers_this_tick]}"
..(out.Join("\n\t"))
/datum/controller/subsystem/machinery/proc/setup_template_powernets(list/cables)
for(var/A in cables)
var/obj/structure/cable/PC = A
if(!PC.powernet)
var/datum/powernet/NewPN = new()
NewPN.add_cable(PC)
propagate_network(PC, PC.powernet)
/**
* @brief Adds a machine to the SSmachinery.processing_machines and the SSmachinery.all_machines list.
*
* Must be called in every machine's Initialize(). Is called in the parent override of that proc
* by default.
*
* @param M The machine we want to add.
*/
/proc/add_machine(obj/machinery/M)
if (QDELETED(M))
crash_with("Attempted add of QDELETED machine [M ? M : "NULL"] to machines list, ignoring.")
return
M.machinery_processing = TRUE
if (SSmachinery.processing_machines[M])
crash_with("Type [M.type] was added to the processing machines list twice! Ignoring duplicate.")
SSmachinery.processing_machines[M] = TRUE
SSmachinery.all_machines[M] = TRUE
/**
* @brief Removes a machine from all of the default global lists it's in.
*
* @param M The machine we want to remove.
* @param remove_from_global Boolean to indicate wether or not the machine should
* also be removed from the all_machines list. Defaults to FALSE.
*/
/proc/remove_machine(obj/machinery/M, remove_from_global = FALSE)
if (M)
M.machinery_processing = FALSE
SSmachinery.processing_machines -= M
SSmachinery.working_machinery -= M
if (remove_from_global)
SSmachinery.all_machines -= M
#undef MACHINERY_GO_TO_NEXT