From dca16e60cfe55424b15009059c72b52bbd18de03 Mon Sep 17 00:00:00 2001 From: tigercat2000 Date: Fri, 2 Mar 2018 23:58:57 -0800 Subject: [PATCH] PS -> SMC Ports: LINDA, Spacedrift, Throwing This commit ports LINDA, spacedrifting, and throwing to the SMC. --- code/ATMOSPHERICS/atmospherics.dm | 4 +- .../unary_devices/heat_exchanger.dm | 6 +- code/ATMOSPHERICS/datum_pipeline.dm | 5 +- code/LINDA/LINDA_fire.dm | 8 +- code/LINDA/LINDA_system.dm | 6 +- code/LINDA/LINDA_turf_tile.dm | 65 ++- code/__HELPERS/unsorted.dm | 10 +- code/_globalvars/lists/objects.dm | 1 - code/controllers/master_controller.dm | 22 - code/controllers/subsystem/air.dm | 398 ++++++++++++++++++ code/controllers/subsystem/spacedrift.dm | 59 +++ code/controllers/subsystem/throwing.dm | 149 +++++++ code/controllers/verbs.dm | 2 +- code/game/atoms_movable.dm | 7 +- code/game/machinery/atmo_control.dm | 4 +- code/game/machinery/atmoalter/meter.dm | 4 +- .../atmoalter/portable_atmospherics.dm | 4 +- code/game/machinery/atmoalter/zvent.dm | 4 +- .../objects/items/weapons/flamethrower.dm | 2 +- code/game/turfs/turf.dm | 20 +- code/modules/awaymissions/zlevel.dm | 4 +- .../mapGeneratorModules/helpers.dm | 4 +- code/modules/shuttle/shuttle.dm | 8 +- code/world.dm | 1 - paradise.dme | 6 +- 25 files changed, 703 insertions(+), 100 deletions(-) create mode 100644 code/controllers/subsystem/air.dm create mode 100644 code/controllers/subsystem/spacedrift.dm create mode 100644 code/controllers/subsystem/throwing.dm diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index b2f58691818..23eead0c4bf 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -33,7 +33,7 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/New() ..() - atmos_machinery += src + SSair.atmos_machinery += src if(!icon_manager) icon_manager = new() @@ -54,7 +54,7 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/Destroy() QDEL_NULL(stored) - atmos_machinery -= src + SSair.atmos_machinery -= src for(var/mob/living/L in src) //ventcrawling is serious business L.remove_ventcrawl() L.forceMove(get_turf(src)) diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm index 1b726a6c066..496413c881c 100644 --- a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm +++ b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm @@ -37,11 +37,11 @@ if(!partner) return 0 - if(!air_master || air_master.current_cycle <= update_cycle) + if(!SSair || SSair.times_fired <= update_cycle) return 0 - update_cycle = air_master.current_cycle - partner.update_cycle = air_master.current_cycle + update_cycle = SSair.times_fired + partner.update_cycle = SSair.times_fired var/air_heat_capacity = air_contents.heat_capacity() var/other_air_heat_capacity = partner.air_contents.heat_capacity() diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 156d6ffa851..cd3cdfffb53 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -1,4 +1,3 @@ -var/global/list/pipe_networks = list() var/global/list/deferred_pipenet_rebuilds = list() /datum/pipeline @@ -13,10 +12,10 @@ var/global/list/deferred_pipenet_rebuilds = list() var/alert_pressure = 0 /datum/pipeline/New() - pipe_networks += src + SSair.networks += src /datum/pipeline/Destroy() - pipe_networks -= src + SSair.networks -= src if(air && air.volume) temporarily_store_air() for(var/obj/machinery/atmospherics/pipe/P in members) diff --git a/code/LINDA/LINDA_fire.dm b/code/LINDA/LINDA_fire.dm index d5ab43d4ab3..11ecc8f10e3 100644 --- a/code/LINDA/LINDA_fire.dm +++ b/code/LINDA/LINDA_fire.dm @@ -34,9 +34,9 @@ active_hotspot.temperature = exposed_temperature active_hotspot.volume = exposed_volume - active_hotspot.just_spawned = (current_cycle < air_master.current_cycle) + active_hotspot.just_spawned = (current_cycle < SSair.times_fired) //remove just_spawned protection if no longer processing this cell - air_master.add_to_active(src, 0) + SSair.add_to_active(src, 0) return igniting //This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile @@ -58,7 +58,7 @@ /obj/effect/hotspot/New() ..() - air_master.hotspots += src + SSair.hotspots += src perform_exposure() dir = pick(cardinal) air_update_turf() @@ -154,7 +154,7 @@ /obj/effect/hotspot/Destroy() set_light(0) - air_master.hotspots -= src + SSair.hotspots -= src DestroyTurf() if(istype(loc, /turf/simulated)) var/turf/simulated/T = loc diff --git a/code/LINDA/LINDA_system.dm b/code/LINDA/LINDA_system.dm index cbb3c546990..c9d168a0159 100644 --- a/code/LINDA/LINDA_system.dm +++ b/code/LINDA/LINDA_system.dm @@ -126,8 +126,8 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5) /turf/proc/air_update_turf(var/command = 0) if(command) CalculateAdjacentTurfs() - if(air_master) - air_master.add_to_active(src,command) + if(SSair) + SSair.add_to_active(src,command) /atom/movable/proc/move_update_air(var/turf/T) if(istype(T,/turf)) @@ -184,4 +184,4 @@ var/const/SPAWN_AIR = 256 G.nitrogen += MOLES_N2STANDARD * amount air.merge(G) - air_master.add_to_active(src, 0) + SSair.add_to_active(src, 0) diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index a2414d9cac3..e10e53859d7 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -141,9 +141,9 @@ /turf/simulated/proc/process_cell() - if(archived_cycle < air_master.current_cycle) //archive self if not already done + if(archived_cycle < SSair.times_fired) //archive self if not already done archive() - current_cycle = air_master.current_cycle + current_cycle = SSair.times_fired var/remove = 1 //set by non simulated turfs who are sharing with this turf @@ -184,7 +184,7 @@ share_air(enemy_simulated) //share else if(!air.compare(enemy_simulated.air)) //compare if - air_master.add_to_active(enemy_simulated) //excite enemy + SSair.add_to_active(enemy_simulated) //excite enemy if(excited_group) excited_group.add_turf(enemy_simulated) //add enemy to group else @@ -227,14 +227,14 @@ update_visuals() if(!excited_group && remove == 1) - air_master.remove_from_active(src) + SSair.remove_from_active(src) /turf/simulated/proc/archive() if(air) //For open space like floors air.archive() temperature_archived = temperature - archived_cycle = air_master.current_cycle + archived_cycle = SSair.times_fired /turf/simulated/proc/update_visuals() if(icy && !icyoverlay) @@ -288,7 +288,7 @@ last_share_check() /turf/proc/consider_pressure_difference(var/turf/simulated/T, var/difference) - air_master.high_pressure_delta |= src + SSair.high_pressure_delta |= src if(difference > pressure_difference) pressure_direction = get_dir(src, T) pressure_difference = difference @@ -309,24 +309,24 @@ /atom/movable/var/last_forced_movement = 0 /atom/movable/proc/experience_pressure_difference(pressure_difference, direction) - if(last_forced_movement >= air_master.current_cycle) + if(last_forced_movement >= SSair.times_fired) return 0 else if(!anchored && !pulledby) if(pressure_difference >= throw_pressure_limit) var/general_direction = get_edge_target_turf(src, direction) - if(last_forced_movement + 10 < air_master.current_cycle && is_valid_tochat_target(src)) //the first check prevents spamming throw to_chat + if(last_forced_movement + 10 < SSair.times_fired && is_valid_tochat_target(src)) //the first check prevents spamming throw to_chat to_chat(src, "The pressure sends you flying!") if(ishuman(src)) var/mob/living/carbon/human/H = src H.Weaken(min(pressure_difference / 50, 2)) spawn() throw_at(general_direction, pressure_difference / 10, pressure_difference / 200, null, 0, 0, null) - last_forced_movement = air_master.current_cycle + last_forced_movement = SSair.times_fired return 1 else if(pressure_difference > pressure_resistance) spawn() step(src, direction) - last_forced_movement = air_master.current_cycle + last_forced_movement = SSair.times_fired return 1 return 0 @@ -337,8 +337,8 @@ var/breakdown_cooldown = 0 /datum/excited_group/New() - if(air_master) - air_master.excited_groups += src + if(SSair) + SSair.excited_groups += src /datum/excited_group/proc/add_turf(var/turf/simulated/T) turf_list += T @@ -348,13 +348,13 @@ /datum/excited_group/proc/merge_groups(var/datum/excited_group/E) if(turf_list.len > E.turf_list.len) - air_master.excited_groups -= E + SSair.excited_groups -= E for(var/turf/simulated/T in E.turf_list) T.excited_group = src turf_list += T reset_cooldowns() else - air_master.excited_groups -= src + SSair.excited_groups -= src for(var/turf/simulated/T in turf_list) T.excited_group = E E.turf_list += T @@ -400,14 +400,14 @@ T.excited = 0 T.recently_active = 0 T.excited_group = null - air_master.active_turfs -= T + SSair.active_turfs -= T garbage_collect() /datum/excited_group/proc/garbage_collect() for(var/turf/simulated/T in turf_list) T.excited_group = null turf_list.Cut() - air_master.excited_groups -= src + SSair.excited_groups -= src @@ -424,7 +424,7 @@ turf/simulated/proc/super_conduct() //Does not participate in air exchange, so will conduct heat across all four borders at this time conductivity_directions = NORTH|SOUTH|EAST|WEST - if(archived_cycle < air_master.current_cycle) + if(archived_cycle < SSair.times_fired) archive() else //Does particate in air exchange so only consider directions not considered during process_cell() @@ -444,7 +444,7 @@ turf/simulated/proc/super_conduct() if(istype(neighbor, /turf/simulated)) //anything under this subtype will share in the exchange var/turf/simulated/T = neighbor - if(T.archived_cycle < air_master.current_cycle) + if(T.archived_cycle < SSair.times_fired) T.archive() if(T.air) @@ -452,7 +452,7 @@ turf/simulated/proc/super_conduct() air.temperature_share(T.air, WINDOW_HEAT_TRANSFER_COEFFICIENT) else //Solid but neighbor is open T.air.temperature_turf_share(src, T.thermal_conductivity) - air_master.add_to_active(T, 0) + SSair.add_to_active(T, 0) else if(air) //Open but neighbor is solid air.temperature_turf_share(T, T.thermal_conductivity) @@ -476,12 +476,12 @@ turf/simulated/proc/super_conduct() //Make sure still hot enough to continue conducting heat if(air.temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION) - air_master.active_super_conductivity -= src + SSair.active_super_conductivity -= src return 0 else if(temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION) - air_master.active_super_conductivity -= src + SSair.active_super_conductivity -= src return 0 turf/simulated/proc/consider_superconductivity(starting) @@ -497,7 +497,7 @@ turf/simulated/proc/consider_superconductivity(starting) if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)) return 0 - air_master.active_super_conductivity |= src + SSair.active_super_conductivity |= src return 1 turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space @@ -508,3 +508,24 @@ turf/simulated/proc/radiate_to_spess() //Radiate excess tile heat to space var/heat = thermal_conductivity*delta_temperature* \ (heat_capacity*700000/(heat_capacity+700000)) //700000 is the heat_capacity from a space turf, hardcoded here temperature -= heat/heat_capacity + +/turf/proc/Initialize_Atmos(times_fired) + CalculateAdjacentTurfs() + +/turf/simulated/Initialize_Atmos(times_fired) + ..() + update_visuals() + for(var/direction in cardinal) + if(!(atmos_adjacent_turfs & direction)) + continue + var/turf/enemy_tile = get_step(src, direction) + if(istype(enemy_tile, /turf/simulated)) + var/turf/simulated/enemy_simulated = enemy_tile + if(!air.compare(enemy_simulated.air)) + excited = 1 + SSair.active_turfs |= src + break + else + if(!air.check_turf_total(enemy_tile)) + excited = 1 + SSair.active_turfs |= src \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index f1ee4e5415f..852f656705c 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -777,15 +777,15 @@ proc/GaussRandRound(var/sigma,var/roundto) if(toupdate.len) for(var/turf/simulated/T1 in toupdate) - air_master.remove_from_active(T1) + SSair.remove_from_active(T1) T1.CalculateAdjacentTurfs() - air_master.add_to_active(T1,1) + SSair.add_to_active(T1,1) if(fromupdate.len) for(var/turf/simulated/T2 in fromupdate) - air_master.remove_from_active(T2) + SSair.remove_from_active(T2) T2.CalculateAdjacentTurfs() - air_master.add_to_active(T2,1) + SSair.add_to_active(T2,1) @@ -941,7 +941,7 @@ proc/GaussRandRound(var/sigma,var/roundto) if(toupdate.len) for(var/turf/simulated/T1 in toupdate) T1.CalculateAdjacentTurfs() - air_master.add_to_active(T1,1) + SSair.add_to_active(T1,1) return copiedobjs diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index cb1ce8f10a7..0cc712799c7 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -19,7 +19,6 @@ var/global/list/all_areas = list() var/global/list/machines = list() var/global/list/machine_processing = list() var/global/list/fast_processing = list() -var/global/list/atmos_machinery = list() var/global/list/processing_power_items = list() //items that ask to be called every cycle var/global/list/rcd_list = list() //list of Rapid Construction Devices. diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index cfaa3f825e7..11cd37343fe 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -82,26 +82,4 @@ var/global/pipe_processing_killed = 0 count++ log_startup_progress(" Initialized [count] objects in [stop_watch(watch)]s.") - watch = start_watch() - count = 0 - log_startup_progress("Initializing atmospherics machinery...") - for(var/obj/machinery/atmospherics/unary/U in machines) - if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) - var/obj/machinery/atmospherics/unary/vent_pump/T = U - T.broadcast_status() - count++ - else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber)) - var/obj/machinery/atmospherics/unary/vent_scrubber/T = U - T.broadcast_status() - count++ - log_startup_progress(" Initialized [count] atmospherics machines in [stop_watch(watch)]s.") - - watch = start_watch() - 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] pipes in [stop_watch(watch)]s.") - log_startup_progress("Finished object initializations in [stop_watch(overwatch)]s.") diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm new file mode 100644 index 00000000000..732863cfc13 --- /dev/null +++ b/code/controllers/subsystem/air.dm @@ -0,0 +1,398 @@ +#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/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_PIPENETS + +/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_PIPENETS + +/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() + 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 + if(currentpart == SSAIR_ACTIVETURFS) + 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 + + if(active_turfs.len) + var/starting_ats = active_turfs.len + sleep(world.tick_lag) + var/timer = world.timeofday + warning("There are [starting_ats] active turfs at roundstart, this is a mapping error caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required)") + + //now lets clear out these active turfs + var/list/turfs_to_check = active_turfs.Copy() + do + var/list/new_turfs_to_check = list() + for(var/turf/simulated/T in turfs_to_check) + new_turfs_to_check += T.resolve_active_graph() + CHECK_TICK + + active_turfs += new_turfs_to_check + turfs_to_check = new_turfs_to_check + + while (turfs_to_check.len) + var/ending_ats = active_turfs.len + for(var/thing in excited_groups) + var/datum/excited_group/EG = thing + EG.self_breakdown() + EG.dismantle() + CHECK_TICK + + var/msg = "HEY! LISTEN! [DisplayTimeText(world.timeofday - timer)] were wasted processing [starting_ats] turf(s) (connected to [ending_ats] other turfs) with atmos differences at round start." + to_chat(world, "[msg]") + warning(msg) + +/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/unary/U in machines) + if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) + var/obj/machinery/atmospherics/unary/vent_pump/T = U + T.broadcast_status() + count++ + else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber)) + var/obj/machinery/atmospherics/unary/vent_scrubber/T = U + T.broadcast_status() + count++ + 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] pipes 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 diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm new file mode 100644 index 00000000000..c251492227a --- /dev/null +++ b/code/controllers/subsystem/spacedrift.dm @@ -0,0 +1,59 @@ +SUBSYSTEM_DEF(spacedrift) + name = "Space Drift" + priority = FIRE_PRIORITY_SPACEDRIFT + wait = 5 + flags = SS_NO_INIT|SS_KEEP_TIMING + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + var/list/currentrun = list() + var/list/processing = list() + +/datum/controller/subsystem/spacedrift/stat_entry() + ..("P:[processing.len]") + + +/datum/controller/subsystem/spacedrift/fire(resumed = 0) + if (!resumed) + src.currentrun = processing.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while (currentrun.len) + var/atom/movable/AM = currentrun[currentrun.len] + currentrun.len-- + if (!AM) + processing -= AM + if (MC_TICK_CHECK) + return + continue + + if (AM.inertia_next_move > world.time) + if (MC_TICK_CHECK) + return + continue + + if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0)) + AM.inertia_dir = 0 + + if (!AM.inertia_dir) + AM.inertia_last_loc = null + processing -= AM + if (MC_TICK_CHECK) + return + continue + + var/old_dir = AM.dir + var/old_loc = AM.loc + AM.inertia_moving = TRUE + step(AM, AM.inertia_dir) + AM.inertia_moving = FALSE + AM.inertia_next_move = world.time + AM.inertia_move_delay + if (AM.loc == old_loc) + AM.inertia_dir = 0 + + AM.setDir(old_dir) + AM.inertia_last_loc = AM.loc + if (MC_TICK_CHECK) + return + diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm new file mode 100644 index 00000000000..c32b5a707ae --- /dev/null +++ b/code/controllers/subsystem/throwing.dm @@ -0,0 +1,149 @@ +#define MAX_THROWING_DIST 512 // 2 z-levels on default width +#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run. + +SUBSYSTEM_DEF(throwing) + name = "Throwing" + priority = FIRE_PRIORITY_THROWING + wait = 1 + flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + var/list/currentrun + var/list/processing = list() + +/datum/controller/subsystem/throwing/stat_entry() + ..("P:[processing.len]") + + +/datum/controller/subsystem/throwing/fire(resumed = 0) + if (!resumed) + src.currentrun = processing.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while(length(currentrun)) + var/atom/movable/AM = currentrun[currentrun.len] + var/datum/thrownthing/TT = currentrun[AM] + currentrun.len-- + if (!AM || !TT) + processing -= AM + if (MC_TICK_CHECK) + return + continue + + TT.tick() + + if (MC_TICK_CHECK) + return + + currentrun = null + +/datum/thrownthing + var/atom/movable/thrownthing + var/atom/target + var/turf/target_turf + var/init_dir + var/maxrange + var/speed + var/mob/thrower + var/diagonals_first + var/dist_travelled = 0 + var/start_time + var/dist_x + var/dist_y + var/dx + var/dy + var/pure_diagonal + var/diagonal_error + var/datum/callback/callback + var/paused = FALSE + var/delayed_time = 0 + var/last_move = 0 + +/datum/thrownthing/proc/tick() + var/atom/movable/AM = thrownthing + if (!isturf(AM.loc) || !AM.throwing) + finalize() + return + + if(paused) + delayed_time += world.time - last_move + return + + if (dist_travelled && hitcheck()) //to catch sneaky things moving on our tile while we slept + finalize() + return + + var/atom/step + + last_move = world.time + + //calculate how many tiles to move, making up for any missed ticks. + var/tilestomove = CEILING(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1) + while (tilestomove-- > 0) + if ((dist_travelled >= maxrange || AM.loc == target_turf) && has_gravity(AM, AM.loc)) + finalize() + return + + if (dist_travelled <= max(dist_x, dist_y)) //if we haven't reached the target yet we home in on it, otherwise we use the initial direction + step = get_step(AM, get_dir(AM, target_turf)) + else + step = get_step(AM, init_dir) + + if (!pure_diagonal && !diagonals_first) // not a purely diagonal trajectory and we don't want all diagonal moves to be done first + if (diagonal_error >= 0 && max(dist_x,dist_y) - dist_travelled != 1) //we do a step forward unless we're right before the target + step = get_step(AM, dx) + diagonal_error += (diagonal_error < 0) ? dist_x/2 : -dist_y + + if (!step) // going off the edge of the map makes get_step return null, don't let things go off the edge + finalize() + return + + AM.Move(step, get_dir(AM, step)) + + if (!AM.throwing) // we hit something during our move + finalize(hit = TRUE) + return + + dist_travelled++ + + if (dist_travelled > MAX_THROWING_DIST) + finalize() + return + +/datum/thrownthing/proc/finalize(hit = FALSE, target=null) + set waitfor = 0 + SSthrowing.processing -= thrownthing + //done throwing, either because it hit something or it finished moving + thrownthing.throwing = null + if (!hit) + for (var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on. + var/atom/A = thing + if (A == target) + hit = 1 + thrownthing.throw_impact(A, src) + break + if (!hit) + thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground. + thrownthing.newtonian_move(init_dir) + else + thrownthing.newtonian_move(init_dir) + + if(target) + thrownthing.throw_impact(target, src) + + if (callback) + callback.Invoke() + +/datum/thrownthing/proc/hit_atom(atom/A) + finalize(hit=TRUE, target=A) + +/datum/thrownthing/proc/hitcheck() + for (var/thing in get_turf(thrownthing)) + var/atom/movable/AM = thing + if (AM == thrownthing) + continue + if(AM.density && !(AM.pass_flags & LETPASSTHROW) && !(AM.flags & ON_BORDER)) + finalize(hit=TRUE, target=AM) + return TRUE diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 4ea43a02e08..efbe9502e7c 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -43,7 +43,7 @@ debug_variables(ticker) feedback_add_details("admin_verb","DTicker") if("Air") - debug_variables(air_master) + debug_variables(SSair) feedback_add_details("admin_verb","DAir") if("Jobs") debug_variables(job_master) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 0e982a27288..27bc98e2b42 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -217,14 +217,15 @@ return 1 inertia_last_loc = loc - drift_master.processing_list[src] = src + SSspacedrift.processing[src] = src return 1 //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum) set waitfor = 0 - return hit_atom.hitby(src) + if(!qdeleted(hit_atom)) + return hit_atom.hitby(src) /atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked) if(!anchored && hitpush) @@ -301,7 +302,7 @@ if(spin && !no_spin && !no_spin_thrown) SpinAnimation(5, 1) - throw_master.processing_list[src] = TT + SSthrowing.processing[src] = TT TT.tick() diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 62996473291..fcb9bd0d28e 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -129,11 +129,11 @@ obj/machinery/air_sensor initialize() ..() - atmos_machinery += src + SSair.atmos_machinery += src set_frequency(frequency) Destroy() - atmos_machinery -= src + SSair.atmos_machinery -= src if(radio_controller) radio_controller.remove_object(src,frequency) return ..() diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index d3f1f25a52d..7365ca39271 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -18,14 +18,14 @@ /obj/machinery/meter/New() ..() - atmos_machinery += src + SSair.atmos_machinery += src target = locate(/obj/machinery/atmospherics/pipe) in loc if(id && !id_tag)//i'm not dealing with further merge conflicts, fuck it id_tag = id return 1 /obj/machinery/meter/Destroy() - atmos_machinery -= src + SSair.atmos_machinery -= src target = null return ..() diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index 45dcb5f7880..4a9eb2fa05d 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -13,7 +13,7 @@ /obj/machinery/portable_atmospherics/New() ..() - atmos_machinery += src + SSair.atmos_machinery += src air_contents.volume = volume air_contents.temperature = T20C @@ -36,7 +36,7 @@ update_icon() /obj/machinery/portable_atmospherics/Destroy() - atmos_machinery -= src + SSair.atmos_machinery -= src disconnect() QDEL_NULL(air_contents) QDEL_NULL(holding) diff --git a/code/game/machinery/atmoalter/zvent.dm b/code/game/machinery/atmoalter/zvent.dm index a9d288fe37e..18af424c4d6 100644 --- a/code/game/machinery/atmoalter/zvent.dm +++ b/code/game/machinery/atmoalter/zvent.dm @@ -11,10 +11,10 @@ /obj/machinery/zvent/New() ..() - atmos_machinery += src + SSair.atmos_machinery += src /obj/machinery/zvent/Destroy() - atmos_machinery -= src + SSair.atmos_machinery -= src return ..() /obj/machinery/zvent/process_atmos() diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 9601b86beec..ee0a5510240 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -193,7 +193,7 @@ //Burn it based on transfered gas target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE //location.hotspot_expose(1000,500,1) - air_master.add_to_active(target, 0) + SSair.add_to_active(target, 0) return diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 2f05b738385..514d145810d 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -56,12 +56,12 @@ /turf/Destroy() // Adds the adjacent turfs to the current atmos processing - if(air_master) + if(SSair) for(var/direction in cardinal) if(atmos_adjacent_turfs & direction) var/turf/simulated/T = get_step(src, direction) if(istype(T)) - air_master.add_to_active(T) + SSair.add_to_active(T) ..() return QDEL_HINT_HARDDEL_NOW @@ -167,8 +167,8 @@ var/old_corners = corners BeforeChange() - if(air_master) - air_master.remove_from_active(src) + if(SSair) + SSair.remove_from_active(src) var/turf/W = new path(src) if(!defer_change) W.AfterChange() @@ -204,8 +204,8 @@ levelupdate() CalculateAdjacentTurfs() - if(air_master && !ignore_air) - air_master.add_to_active(src) + if(SSair && !ignore_air) + SSair.add_to_active(src) if(!keep_cabling && !can_have_cabling()) for(var/obj/structure/cable/C in contents) @@ -246,8 +246,8 @@ air.carbon_dioxide = (aco/max(turf_count,1)) air.toxins = (atox/max(turf_count,1)) air.temperature = (atemp/max(turf_count,1))//Trace gases can get bant - if(air_master) - air_master.add_to_active(src) + if(SSair) + SSair.add_to_active(src) /turf/proc/ReplaceWithLattice() src.ChangeTurf(/turf/space) @@ -457,6 +457,6 @@ T0.ChangeTurf(turf_type) - air_master.remove_from_active(T0) + SSair.remove_from_active(T0) T0.CalculateAdjacentTurfs() - air_master.add_to_active(T0,1) + SSair.add_to_active(T0,1) diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index 50b09d72788..bdb8bc01bc4 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -9,8 +9,8 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away smoothTurfs = turfs log_debug("Setting up atmos") - if(air_master) - air_master.setup_allturfs(turfs) + if(SSair) + SSair.setup_allturfs(turfs) log_debug("\tTook [stop_watch(subtimer)]s") subtimer = start_watch() diff --git a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm index a392105513a..11873b5acdf 100644 --- a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm +++ b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm @@ -11,7 +11,7 @@ return var/list/map = mother.map for(var/turf/simulated/T in map) - air_master.remove_from_active(T) + SSair.remove_from_active(T) for(var/turf/simulated/T in map) if(T.air) T.air.oxygen = T.oxygen @@ -19,7 +19,7 @@ T.air.carbon_dioxide = T.carbon_dioxide T.air.toxins = T.toxins T.air.temperature = T.temperature - air_master.add_to_active(T) + SSair.add_to_active(T) //Only places atoms/turfs on area borders /datum/mapGeneratorModule/border diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index d3406556e27..3cd9bb49432 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -490,15 +490,15 @@ T1.shuttleRotate(rotation) //lighting stuff - air_master.remove_from_active(T1) + SSair.remove_from_active(T1) T1.CalculateAdjacentTurfs() - air_master.add_to_active(T1,1) + SSair.add_to_active(T1,1) T0.ChangeTurf(turf_type) - air_master.remove_from_active(T0) + SSair.remove_from_active(T0) T0.CalculateAdjacentTurfs() - air_master.add_to_active(T0,1) + SSair.add_to_active(T0,1) for(var/A1 in L1) var/turf/T1 = A1 diff --git a/code/world.dm b/code/world.dm index 9614373c901..df7fc20437c 100644 --- a/code/world.dm +++ b/code/world.dm @@ -55,7 +55,6 @@ var/global/list/map_transition_config = MAP_TRANSITION_CONFIG processScheduler.setup() master_controller.setup() - sleep_offline = 1 if(using_map && using_map.name) map_name = "[using_map.name]" diff --git a/paradise.dme b/paradise.dme index b46d43f0b7e..923f7a2740c 100644 --- a/paradise.dme +++ b/paradise.dme @@ -187,7 +187,6 @@ #include "code\controllers\subsystem.dm" #include "code\controllers\verbs.dm" #include "code\controllers\voting.dm" -#include "code\controllers\Processes\air.dm" #include "code\controllers\Processes\alarm.dm" #include "code\controllers\Processes\event.dm" #include "code\controllers\Processes\fast_process.dm" @@ -203,14 +202,15 @@ #include "code\controllers\Processes\npcpool.dm" #include "code\controllers\Processes\obj.dm" #include "code\controllers\Processes\shuttles.dm" -#include "code\controllers\Processes\spacedrift.dm" #include "code\controllers\Processes\sun.dm" -#include "code\controllers\Processes\throwing.dm" #include "code\controllers\Processes\ticker.dm" #include "code\controllers\Processes\timer.dm" #include "code\controllers\Processes\weather.dm" #include "code\controllers\ProcessScheduler\core\process.dm" #include "code\controllers\ProcessScheduler\core\processScheduler.dm" +#include "code\controllers\subsystem\air.dm" +#include "code\controllers\subsystem\spacedrift.dm" +#include "code\controllers\subsystem\throwing.dm" #include "code\datums\action.dm" #include "code\datums\ai_law_sets.dm" #include "code\datums\ai_laws.dm"