mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Willburd <7099514+Willburd@users.noreply.github.com>
230 lines
7.5 KiB
Plaintext
230 lines
7.5 KiB
Plaintext
#define SSMACHINES_PIPENETS 1
|
|
#define SSMACHINES_MACHINERY 2
|
|
#define SSMACHINES_POWERNETS 3
|
|
#define SSMACHINES_POWER_OBJECTS 4
|
|
|
|
//
|
|
// SSmachines subsystem - Processing machines, pipenets, and powernets!
|
|
//
|
|
|
|
SUBSYSTEM_DEF(machines)
|
|
name = "Machines"
|
|
priority = FIRE_PRIORITY_MACHINES
|
|
init_order = INIT_ORDER_MACHINES
|
|
flags = SS_KEEP_TIMING
|
|
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
|
|
|
|
var/current_step = SSMACHINES_PIPENETS
|
|
|
|
var/cost_pipenets = 0
|
|
var/cost_machinery = 0
|
|
var/cost_powernets = 0
|
|
var/cost_power_objects = 0
|
|
|
|
var/list/current_run = list()
|
|
|
|
var/list/all_machines = list()
|
|
var/list/hibernating_vents = list()
|
|
|
|
var/list/networks = list()
|
|
var/list/processing_machines = list()
|
|
var/list/powernets = list()
|
|
var/list/powerobjs = list()
|
|
|
|
/datum/controller/subsystem/machines/Initialize()
|
|
makepowernets()
|
|
admin_notice(span_danger("Initializing atmos machinery."), R_DEBUG)
|
|
setup_atmos_machinery(all_machines)
|
|
fire()
|
|
return SS_INIT_SUCCESS
|
|
|
|
/datum/controller/subsystem/machines/fire(resumed = 0)
|
|
var/timer = TICK_USAGE
|
|
|
|
INTERNAL_PROCESS_STEP(SSMACHINES_POWER_OBJECTS,FALSE,process_power_objects,cost_power_objects,SSMACHINES_PIPENETS) // Higher priority, damnit
|
|
INTERNAL_PROCESS_STEP(SSMACHINES_PIPENETS,TRUE,process_pipenets,cost_pipenets,SSMACHINES_MACHINERY)
|
|
INTERNAL_PROCESS_STEP(SSMACHINES_MACHINERY,FALSE,process_machinery,cost_machinery,SSMACHINES_POWERNETS)
|
|
INTERNAL_PROCESS_STEP(SSMACHINES_POWERNETS,FALSE,process_powernets,cost_powernets,SSMACHINES_POWER_OBJECTS)
|
|
|
|
// rebuild all power networks from scratch - only called at world creation or by the admin verb
|
|
// The above is a lie. Turbolifts also call this proc.
|
|
/datum/controller/subsystem/machines/proc/makepowernets()
|
|
// TODO - check to not run while in the middle of a tick!
|
|
for(var/datum/powernet/PN as anything in powernets)
|
|
qdel(PN)
|
|
powernets.Cut()
|
|
setup_powernets_for_cables(cable_list)
|
|
|
|
/datum/controller/subsystem/machines/proc/setup_powernets_for_cables(list/cables)
|
|
for(var/obj/structure/cable/PC as anything in cables)
|
|
if(!PC.powernet)
|
|
var/datum/powernet/NewPN = new()
|
|
NewPN.add_cable(PC)
|
|
propagate_network(PC,PC.powernet)
|
|
|
|
/datum/controller/subsystem/machines/proc/setup_atmos_machinery(list/atmos_machines)
|
|
var/list/actual_atmos_machines = list()
|
|
|
|
for(var/obj/machinery/atmospherics/machine in atmos_machines)
|
|
machine.atmos_init()
|
|
actual_atmos_machines += machine
|
|
CHECK_TICK
|
|
|
|
for(var/obj/machinery/atmospherics/machine as anything in actual_atmos_machines)
|
|
machine.build_network()
|
|
CHECK_TICK
|
|
|
|
for(var/obj/machinery/atmospherics/unary/U as anything in actual_atmos_machines)
|
|
if(istype(U, /obj/machinery/atmospherics/unary/vent_pump))
|
|
var/obj/machinery/atmospherics/unary/vent_pump/T = U
|
|
T.broadcast_status()
|
|
else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber))
|
|
var/obj/machinery/atmospherics/unary/vent_scrubber/T = U
|
|
T.broadcast_status()
|
|
CHECK_TICK
|
|
|
|
/datum/controller/subsystem/machines/stat_entry(msg)
|
|
msg = "C:{"
|
|
msg += "PI:[round(cost_pipenets,1)]|"
|
|
msg += "MC:[round(cost_machinery,1)]|"
|
|
msg += "PN:[round(cost_powernets,1)]|"
|
|
msg += "PO:[round(cost_power_objects,1)]"
|
|
msg += "} "
|
|
msg += "PI:[SSmachines.networks.len]|"
|
|
msg += "MC:[SSmachines.processing_machines.len]|"
|
|
msg += "PN:[SSmachines.powernets.len]|"
|
|
msg += "PO:[SSmachines.powerobjs.len]|"
|
|
msg += "HV:[SSmachines.hibernating_vents.len]|"
|
|
msg += "MC/MS:[round((cost ? SSmachines.processing_machines.len/cost_machinery : 0),0.1)]"
|
|
return ..()
|
|
|
|
/datum/controller/subsystem/machines/proc/process_pipenets(resumed = 0)
|
|
if (!resumed)
|
|
src.current_run = networks.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/wait = src.wait
|
|
var/list/current_run = src.current_run
|
|
while(current_run.len)
|
|
var/datum/pipe_network/PN = current_run[current_run.len]
|
|
current_run.len--
|
|
if(!PN || QDELETED(PN))
|
|
networks.Remove(PN)
|
|
DISABLE_BITFIELD(PN?.datum_flags, DF_ISPROCESSING)
|
|
else
|
|
PN.process(wait)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/machines/proc/process_machinery(resumed = 0)
|
|
if (!resumed)
|
|
update_hibernating_vents()
|
|
src.current_run = processing_machines.Copy()
|
|
|
|
var/wait = src.wait
|
|
var/list/current_run = src.current_run
|
|
while(current_run.len)
|
|
var/obj/machinery/M = current_run[current_run.len]
|
|
current_run.len--
|
|
if(!istype(M) || QDELETED(M) || (M.process(wait) == PROCESS_KILL))
|
|
processing_machines.Remove(M)
|
|
DISABLE_BITFIELD(M?.datum_flags, DF_ISPROCESSING)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/machines/proc/process_powernets(resumed = 0)
|
|
if (!resumed)
|
|
src.current_run = powernets.Copy()
|
|
|
|
var/wait = src.wait
|
|
var/list/current_run = src.current_run
|
|
while(current_run.len)
|
|
var/datum/powernet/PN = current_run[current_run.len]
|
|
current_run.len--
|
|
if(!PN)
|
|
powernets.Remove(PN)
|
|
DISABLE_BITFIELD(PN?.datum_flags, DF_ISPROCESSING)
|
|
else
|
|
PN.reset(wait)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
// Actually only processes power DRAIN objects.
|
|
// Currently only used by powersinks. These items get priority processed before machinery
|
|
/datum/controller/subsystem/machines/proc/process_power_objects(resumed = 0)
|
|
if (!resumed)
|
|
src.current_run = powerobjs.Copy()
|
|
|
|
var/wait = src.wait
|
|
var/list/current_run = src.current_run
|
|
while(current_run.len)
|
|
var/obj/item/I = current_run[current_run.len]
|
|
current_run.len--
|
|
if(!I || (I.pwr_drain(wait) == PROCESS_KILL))
|
|
powerobjs.Remove(I)
|
|
DISABLE_BITFIELD(I?.datum_flags, DF_ISPROCESSING)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/machines/Recover()
|
|
for(var/datum/D as anything in SSmachines.networks)
|
|
if(!istype(D, /datum/pipe_network))
|
|
error("Found wrong type during SSmachinery recovery: list=SSmachines.networks, item=[D], type=[D?.type]")
|
|
SSmachines.networks -= D
|
|
for(var/datum/D as anything in SSmachines.processing_machines)
|
|
if(!istype(D, /obj/machinery))
|
|
error("Found wrong type during SSmachinery recovery: list=SSmachines.machines, item=[D], type=[D?.type]")
|
|
SSmachines.processing_machines -= D
|
|
for(var/datum/D as anything in SSmachines.powernets)
|
|
if(!istype(D, /datum/powernet))
|
|
error("Found wrong type during SSmachinery recovery: list=SSmachines.powernets, item=[D], type=[D?.type]")
|
|
SSmachines.powernets -= D
|
|
for(var/datum/D as anything in SSmachines.powerobjs)
|
|
if(!istype(D, /obj/item))
|
|
error("Found wrong type during SSmachinery recovery: list=SSmachines.powerobjs, item=[D], type=[D?.type]")
|
|
SSmachines.powerobjs -= D
|
|
|
|
all_machines = SSmachines.all_machines
|
|
networks = SSmachines.networks
|
|
processing_machines = SSmachines.processing_machines
|
|
powernets = SSmachines.powernets
|
|
powerobjs = SSmachines.powerobjs
|
|
|
|
/datum/controller/subsystem/machines/proc/update_hibernating_vents()
|
|
// pick at random
|
|
var/i = rand(20,40)
|
|
while(i-- > 0)
|
|
if(!hibernating_vents.len)
|
|
break
|
|
wake_vent(hibernating_vents[pick(hibernating_vents)])
|
|
// do first 10 entries
|
|
i = 10
|
|
for(var/key in hibernating_vents)
|
|
if(i <= 0 || !hibernating_vents.len)
|
|
break
|
|
wake_vent(hibernating_vents[key])
|
|
i--
|
|
|
|
/datum/controller/subsystem/machines/proc/hibernate_vent(var/obj/machinery/atmospherics/unary/V)
|
|
if(!V)
|
|
return
|
|
var/datum/weakref/WR = WEAKREF(V)
|
|
if(!WR)
|
|
return
|
|
hibernating_vents[WR.reference] = WR
|
|
STOP_MACHINE_PROCESSING(V)
|
|
|
|
/datum/controller/subsystem/machines/proc/wake_vent(var/datum/weakref/WR)
|
|
if(!WR)
|
|
return
|
|
var/obj/machinery/atmospherics/unary/V = WR.resolve()
|
|
if(V)
|
|
START_MACHINE_PROCESSING(V)
|
|
if(WR.reference)
|
|
hibernating_vents[WR.reference] = null
|
|
hibernating_vents.Remove(WR.reference)
|
|
|
|
#undef SSMACHINES_PIPENETS
|
|
#undef SSMACHINES_MACHINERY
|
|
#undef SSMACHINES_POWERNETS
|
|
#undef SSMACHINES_POWER_OBJECTS
|