mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-09 14:15:22 +01:00
7d8c9a731a
This converts the machine and mob processes to the SMC. Additionally, it adds the Atom subsystem, which handles all Initialize() calls in place of the old gameticker. Due to incompatibility with our atmospherics (FUCK OUR ATMOSPHERICS FOR FUCKING EVER JESUS CHRIST WHO THE FUCK MADE THIS PIECE OF GODDAMN SHIT) atmospherics machines do not use Initialize() as they should, instead opting for a custom atmos_init proc that the air controller handles.
372 lines
11 KiB
Plaintext
372 lines
11 KiB
Plaintext
#define SSAIR_DEFERREDPIPENETS 1
|
|
#define SSAIR_PIPENETS 2
|
|
#define SSAIR_ATMOSMACHINERY 3
|
|
#define SSAIR_ACTIVETURFS 4
|
|
#define SSAIR_EXCITEDGROUPS 5
|
|
#define SSAIR_HIGHPRESSURE 6
|
|
#define SSAIR_HOTSPOTS 7
|
|
#define SSAIR_SUPERCONDUCTIVITY 8
|
|
|
|
SUBSYSTEM_DEF(air)
|
|
name = "Atmospherics"
|
|
init_order = INIT_ORDER_AIR
|
|
priority = FIRE_PRIORITY_AIR
|
|
wait = 5
|
|
flags = SS_BACKGROUND
|
|
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
|
|
|
var/cost_turfs = 0
|
|
var/cost_groups = 0
|
|
var/cost_highpressure = 0
|
|
var/cost_hotspots = 0
|
|
var/cost_superconductivity = 0
|
|
var/cost_pipenets = 0
|
|
var/cost_deferred_pipenets = 0
|
|
var/cost_atmos_machinery = 0
|
|
|
|
var/list/excited_groups = list()
|
|
var/list/active_turfs = list()
|
|
var/list/hotspots = list()
|
|
var/list/deferred_pipenet_rebuilds = list()
|
|
var/list/networks = list()
|
|
var/list/atmos_machinery = list()
|
|
var/list/pipe_init_dirs_cache = list()
|
|
|
|
|
|
|
|
//Special functions lists
|
|
var/list/active_super_conductivity = list()
|
|
var/list/high_pressure_delta = list()
|
|
|
|
|
|
var/list/currentrun = list()
|
|
var/currentpart = SSAIR_DEFERREDPIPENETS
|
|
|
|
/datum/controller/subsystem/air/stat_entry(msg)
|
|
msg += "C:{"
|
|
msg += "AT:[round(cost_turfs,1)]|"
|
|
msg += "EG:[round(cost_groups,1)]|"
|
|
msg += "HP:[round(cost_highpressure,1)]|"
|
|
msg += "HS:[round(cost_hotspots,1)]|"
|
|
msg += "SC:[round(cost_superconductivity,1)]|"
|
|
msg += "PN:[round(cost_pipenets,1)]|"
|
|
msg += "DPN:[round(cost_deferred_pipenets,1)]|"
|
|
msg += "AM:[round(cost_atmos_machinery,1)]"
|
|
msg += "} "
|
|
msg += "AT:[active_turfs.len]|"
|
|
msg += "EG:[excited_groups.len]|"
|
|
msg += "HS:[hotspots.len]|"
|
|
msg += "PN:[networks.len]|"
|
|
msg += "HP:[high_pressure_delta.len]|"
|
|
msg += "AS:[active_super_conductivity.len]|"
|
|
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
|
|
..(msg)
|
|
|
|
|
|
/datum/controller/subsystem/air/Initialize(timeofday)
|
|
setup_overlays() // Assign icons and such for gas-turf-overlays
|
|
setup_allturfs()
|
|
setup_atmos_machinery()
|
|
setup_pipenets()
|
|
..()
|
|
|
|
|
|
/datum/controller/subsystem/air/fire(resumed = 0)
|
|
var/timer = TICK_USAGE_REAL
|
|
|
|
if(currentpart == SSAIR_DEFERREDPIPENETS || !resumed)
|
|
process_deferred_pipenets(resumed)
|
|
cost_deferred_pipenets = MC_AVERAGE(cost_deferred_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_PIPENETS
|
|
|
|
if(currentpart == SSAIR_PIPENETS || !resumed)
|
|
process_pipenets(resumed)
|
|
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_ATMOSMACHINERY
|
|
|
|
if(currentpart == SSAIR_ATMOSMACHINERY)
|
|
timer = TICK_USAGE_REAL
|
|
process_atmos_machinery(resumed)
|
|
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_ACTIVETURFS
|
|
|
|
if(currentpart == SSAIR_ACTIVETURFS)
|
|
timer = TICK_USAGE_REAL
|
|
process_active_turfs(resumed)
|
|
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_EXCITEDGROUPS
|
|
|
|
if(currentpart == SSAIR_EXCITEDGROUPS)
|
|
timer = TICK_USAGE_REAL
|
|
process_excited_groups(resumed)
|
|
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_HIGHPRESSURE
|
|
|
|
if(currentpart == SSAIR_HIGHPRESSURE)
|
|
timer = TICK_USAGE_REAL
|
|
process_high_pressure_delta(resumed)
|
|
cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_HOTSPOTS
|
|
|
|
if(currentpart == SSAIR_HOTSPOTS)
|
|
timer = TICK_USAGE_REAL
|
|
process_hotspots(resumed)
|
|
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_SUPERCONDUCTIVITY
|
|
|
|
if(currentpart == SSAIR_SUPERCONDUCTIVITY)
|
|
timer = TICK_USAGE_REAL
|
|
process_super_conductivity(resumed)
|
|
cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
if(state != SS_RUNNING)
|
|
return
|
|
resumed = 0
|
|
currentpart = SSAIR_DEFERREDPIPENETS
|
|
|
|
/datum/controller/subsystem/air/proc/process_deferred_pipenets(resumed = 0)
|
|
if(!resumed)
|
|
src.currentrun = deferred_pipenet_rebuilds.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
while(currentrun.len)
|
|
var/obj/machinery/atmospherics/A = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
if(A)
|
|
A.build_network(remove_deferral = TRUE)
|
|
else
|
|
deferred_pipenet_rebuilds.Remove(A)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/process_pipenets(resumed = 0)
|
|
if(!resumed)
|
|
src.currentrun = networks.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
while(currentrun.len)
|
|
var/datum/pipeline/thing = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
if(thing)
|
|
thing.process()
|
|
else
|
|
networks.Remove(thing)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0)
|
|
var/seconds = wait * 0.1
|
|
if(!resumed)
|
|
src.currentrun = atmos_machinery.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
while(currentrun.len)
|
|
var/obj/machinery/M = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
if(!M || (M.process_atmos(seconds) == PROCESS_KILL))
|
|
atmos_machinery.Remove(M)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0)
|
|
if(!resumed)
|
|
src.currentrun = active_super_conductivity.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
while(currentrun.len)
|
|
var/turf/simulated/T = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
T.super_conduct()
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/process_hotspots(resumed = 0)
|
|
if(!resumed)
|
|
src.currentrun = hotspots.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
while(currentrun.len)
|
|
var/obj/effect/hotspot/H = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
if(H)
|
|
H.process()
|
|
else
|
|
hotspots -= H
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/process_high_pressure_delta(resumed = 0)
|
|
while(high_pressure_delta.len)
|
|
var/turf/simulated/T = high_pressure_delta[high_pressure_delta.len]
|
|
high_pressure_delta.len--
|
|
T.high_pressure_movements()
|
|
T.pressure_difference = 0
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
|
|
//cache for sanic speed
|
|
var/fire_count = times_fired
|
|
if(!resumed)
|
|
src.currentrun = active_turfs.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
while(currentrun.len)
|
|
var/turf/simulated/T = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
if(T)
|
|
T.process_cell(fire_count)
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
|
|
if(!resumed)
|
|
src.currentrun = excited_groups.Copy()
|
|
//cache for sanic speed (lists are references anyways)
|
|
var/list/currentrun = src.currentrun
|
|
while(currentrun.len)
|
|
var/datum/excited_group/EG = currentrun[currentrun.len]
|
|
currentrun.len--
|
|
EG.breakdown_cooldown++
|
|
if(EG.breakdown_cooldown == 10)
|
|
EG.self_breakdown()
|
|
else if(EG.breakdown_cooldown >= 20)
|
|
EG.dismantle()
|
|
if(MC_TICK_CHECK)
|
|
return
|
|
|
|
/datum/controller/subsystem/air/proc/remove_from_active(turf/simulated/T)
|
|
active_turfs -= T
|
|
active_super_conductivity -= T // bug: if a turf is hit by ex_act 1 while processing, it can end up in super conductivity as /turf/space and cause runtimes
|
|
if(currentpart == SSAIR_ACTIVETURFS || currentpart == SSAIR_SUPERCONDUCTIVITY)
|
|
currentrun -= T
|
|
if(istype(T))
|
|
T.excited = 0
|
|
if(T.excited_group)
|
|
T.excited_group.garbage_collect()
|
|
|
|
/datum/controller/subsystem/air/proc/add_to_active(turf/simulated/T, blockchanges = 1)
|
|
if(istype(T) && T.air)
|
|
T.excited = 1
|
|
active_turfs |= T
|
|
if(currentpart == SSAIR_ACTIVETURFS)
|
|
currentrun |= T
|
|
if(blockchanges && T.excited_group)
|
|
T.excited_group.garbage_collect()
|
|
else
|
|
for(var/direction in cardinal)
|
|
if(!(T.atmos_adjacent_turfs & direction))
|
|
continue
|
|
var/turf/simulated/S = get_step(T, direction)
|
|
if(istype(S))
|
|
add_to_active(S)
|
|
|
|
/datum/controller/subsystem/air/proc/setup_allturfs(var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)))
|
|
var/list/active_turfs = src.active_turfs
|
|
|
|
for(var/thing in turfs_to_init)
|
|
var/turf/T = thing
|
|
active_turfs -= T
|
|
if(T.blocks_air)
|
|
continue
|
|
T.Initialize_Atmos(times_fired)
|
|
CHECK_TICK
|
|
|
|
/turf/simulated/proc/resolve_active_graph()
|
|
. = list()
|
|
var/datum/excited_group/EG = excited_group
|
|
if(blocks_air || !air)
|
|
return
|
|
if(!EG)
|
|
EG = new
|
|
EG.add_turf(src)
|
|
|
|
for(var/turf/simulated/ET in atmos_adjacent_turfs)
|
|
if(ET.blocks_air || !ET.air)
|
|
continue
|
|
|
|
var/ET_EG = ET.excited_group
|
|
if(ET_EG)
|
|
if(ET_EG != EG)
|
|
EG.merge_groups(ET_EG)
|
|
EG = excited_group //merge_groups() may decide to replace our current EG
|
|
else
|
|
EG.add_turf(ET)
|
|
if(!ET.excited)
|
|
ET.excited = 1
|
|
. += ET
|
|
|
|
/datum/controller/subsystem/air/proc/setup_atmos_machinery()
|
|
var/watch = start_watch()
|
|
var/count = 0
|
|
log_startup_progress("Initializing atmospherics machinery...")
|
|
for(var/obj/machinery/atmospherics/A in machines)
|
|
A.atmos_init()
|
|
count++
|
|
if(istype(A, /obj/machinery/atmospherics/unary/vent_pump))
|
|
var/obj/machinery/atmospherics/unary/vent_pump/T = A
|
|
T.broadcast_status()
|
|
else if(istype(A, /obj/machinery/atmospherics/unary/vent_scrubber))
|
|
var/obj/machinery/atmospherics/unary/vent_scrubber/T = A
|
|
T.broadcast_status()
|
|
log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.")
|
|
|
|
//this can't be done with setup_atmos_machinery() because
|
|
// all atmos machinery has to initalize before the first
|
|
// pipenet can be built.
|
|
/datum/controller/subsystem/air/proc/setup_pipenets()
|
|
var/watch = start_watch()
|
|
var/count = 0
|
|
log_startup_progress("Initializing pipe networks...")
|
|
for(var/obj/machinery/atmospherics/machine in machines)
|
|
machine.build_network()
|
|
count++
|
|
log_startup_progress(" Initialized [count] pipenets in [stop_watch(watch)]s.")
|
|
|
|
/datum/controller/subsystem/air/proc/setup_overlays()
|
|
plmaster = new /obj/effect/overlay()
|
|
plmaster.icon = 'icons/effects/tile_effects.dmi'
|
|
plmaster.icon_state = "plasma"
|
|
plmaster.layer = FLY_LAYER
|
|
plmaster.mouse_opacity = 0
|
|
|
|
slmaster = new /obj/effect/overlay()
|
|
slmaster.icon = 'icons/effects/tile_effects.dmi'
|
|
slmaster.icon_state = "sleeping_agent"
|
|
slmaster.layer = FLY_LAYER
|
|
slmaster.mouse_opacity = 0
|
|
|
|
icemaster = new /obj/effect/overlay()
|
|
icemaster.icon = 'icons/turf/overlays.dmi'
|
|
icemaster.icon_state = "snowfloor"
|
|
icemaster.layer = TURF_LAYER + 0.1
|
|
icemaster.mouse_opacity = 0
|
|
|
|
#undef SSAIR_PIPENETS
|
|
#undef SSAIR_ATMOSMACHINERY
|
|
#undef SSAIR_ACTIVETURFS
|
|
#undef SSAIR_EXCITEDGROUPS
|
|
#undef SSAIR_HIGHPRESSURE
|
|
#undef SSAIR_HOTSPOT
|
|
#undef SSAIR_SUPERCONDUCTIVITY
|