diff --git a/.gitignore b/.gitignore index 6213071d42a..e08d9f49870 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,9 @@ /cfg/**/* config/starmap/starmap.json +# NSV13 - leave the linux, actually # Ignore compiled linux libs in the root folder, e.g. librust_g.so -/*.so +#/*.so #Ignore compiled files and other files generated during compilation. beestation_unit_test_focus_file.dm diff --git a/Dockerfile b/Dockerfile index 4425537854d..5614c8331fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM beestation/byond:514.1589 as base +FROM beestation/byond:515.1633 as base # Install the tools needed to compile our rust dependencies FROM base as rust-build @@ -28,13 +28,14 @@ RUN git init \ && cargo build --release --all-features --target i686-unknown-linux-gnu # Build auxmos +# NSV13 - different fork and katmos hooks FROM rust-build as auxmos RUN git init \ - && git remote add origin https://github.com/Putnam3145/auxmos \ + && git remote add origin https://github.com/covertcorvid/auxmos \ && /bin/bash -c "source dependencies.sh \ && git fetch --depth 1 origin \$AUXMOS_VERSION" \ && git checkout FETCH_HEAD \ - && cargo rustc --target=i686-unknown-linux-gnu --release --features=trit_fire_hook,plasma_fire_hook,generic_fire_hook + && cargo rustc --target=i686-unknown-linux-gnu --release --features=katmos # Install nodejs which is required to deploy BeeStation FROM base as node diff --git a/SpacemanDMM.toml b/SpacemanDMM.toml index cdb93e083b3..d0be3b9a18e 100644 --- a/SpacemanDMM.toml +++ b/SpacemanDMM.toml @@ -1,3 +1,5 @@ +environment = "nsv13.dme" + [langserver] dreamchecker = true diff --git a/_maps/map_files/Tycoon/Tycoon2.dmm b/_maps/map_files/Tycoon/Tycoon2.dmm index 5511dae02d0..d8e5ef7b4d1 100644 --- a/_maps/map_files/Tycoon/Tycoon2.dmm +++ b/_maps/map_files/Tycoon/Tycoon2.dmm @@ -41415,7 +41415,7 @@ dir = 8 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - filter_types = list(/datum/gas/nucleium); + filter_types = list("nucleium"); name = "Nucleium FTL Fuel Scrubber #3" }, /turf/open/floor/monotile/steel, @@ -42811,7 +42811,7 @@ "gCM" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8; - filter_types = list(/datum/gas/nucleium); + filter_types = list("nucleium"); name = "Nucleium FTL Fuel Scrubber #1" }, /turf/open/floor/monotile/steel, @@ -53120,7 +53120,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8; - filter_types = list(/datum/gas/nucleium); + filter_types = list("nucleium"); name = "Nucleium FTL Fuel Scrubber #2" }, /turf/open/floor/monotile/steel, diff --git a/auxmos.dll b/auxmos.dll new file mode 100644 index 00000000000..4c3ed2f8860 Binary files /dev/null and b/auxmos.dll differ diff --git a/auxtools/auxmos.dll b/auxtools/auxmos.dll deleted file mode 100644 index c7ec6332312..00000000000 Binary files a/auxtools/auxmos.dll and /dev/null differ diff --git a/code/__DEFINES/_auxtools.dm b/code/__DEFINES/_auxtools.dm new file mode 100644 index 00000000000..a907be8ecf8 --- /dev/null +++ b/code/__DEFINES/_auxtools.dm @@ -0,0 +1,8 @@ +/proc/auxtools_stack_trace(msg) + CRASH(msg) + +/proc/auxtools_expr_stub() + CRASH("auxtools not loaded") + +/proc/enable_debugging(mode, port) + CRASH("auxtools not loaded") diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 72ed8f4002c..153cf0ee66f 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -147,8 +147,23 @@ #define ATMOS_ADJACENT_ANY (1<<0) #define ATMOS_ADJACENT_FIRELOCK (1<<1) -#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) ) -#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) ) +#ifdef TESTING +GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0)) +#define CALCULATE_ADJACENT_TURFS(T, state) if (SSair.adjacent_rebuild[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSair.adjacent_rebuild[T] = state} +#else +#define CALCULATE_ADJACENT_TURFS(T, state) SSair.adjacent_rebuild[T] = state +#endif + +//If you're doing spreading things related to atmos, DO NOT USE CANATMOSPASS, IT IS NOT CHEAP. use this instead, the info is cached after all. it's tweaked just a bit to allow for circular checks +#define TURFS_CAN_SHARE(T1, T2) (LAZYACCESS(T2.atmos_adjacent_turfs, T1) || LAZYLEN(T1.atmos_adjacent_turfs & T2.atmos_adjacent_turfs)) +//Use this to see if a turf is fully blocked or not, think windows or firelocks. Fails with 1x1 non full tile windows, but it's not worth the cost. +#define TURF_SHARES(T) (LAZYLEN(T.atmos_adjacent_turfs)) + +#define CANATMOSPASS(A, O, V) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O, V) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) ) + +///Used to define the temperature of a tile, arg is the temperature it should be at. Should always be put at the end of the atmos list. +///This is solely to be used after compile-time. +#define TURF_TEMPERATURE(temperature) "TEMP=[temperature]" //OPEN TURF ATMOS #define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15" //the default air mix that open turfs spawn @@ -164,6 +179,9 @@ #define ATMOS_TANK_PLASMA "plasma=70000;TEMP=293.15" #define ATMOS_TANK_O2 "o2=100000;TEMP=293.15" #define ATMOS_TANK_N2 "n2=100000;TEMP=293.15" +#define ATMOS_TANK_BZ "bz=100000;TEMP=293.15" +#define ATMOS_TANK_PLUOXIUM "pluox=100000;TEMP=293.15" +#define ATMOS_TANK_TRITIUM "tritium=100000;TEMP=293.15" #define ATMOS_TANK_AIRMIX "o2=2644;n2=10580;TEMP=293.15" //LAVALAND @@ -325,3 +343,8 @@ GLOBAL_LIST_INIT(pipe_paint_colors, sortList(list( #define PIPENET_UPDATE_STATUS_DORMANT 0 #define PIPENET_UPDATE_STATUS_REACT_NEEDED 1 #define PIPENET_UPDATE_STATUS_RECONCILE_NEEDED 2 + +// NSV13 - auxmos +#define ATMOS_ALARM_SEVERE "severe" +#define ATMOS_ALARM_MINOR "minor" +#define ATMOS_ALARM_CLEAR "clear" diff --git a/code/__DEFINES/bindings.dm b/code/__DEFINES/bindings.dm new file mode 100644 index 00000000000..0f101d376fd --- /dev/null +++ b/code/__DEFINES/bindings.dm @@ -0,0 +1,185 @@ +//THIS FILE IS AUTOMATICALLY GENERATED BY AUXMOS, PLEASE DO NOT TOUCH IT +//PROC DEFINITIONS MAY MOVE AROUND, THIS IS NORMAL + +/* This comment bypasses grep checks */ /var/__auxmos + +/proc/__detect_auxmos() + if (world.system_type == UNIX) + return __auxmos = "libauxmos" + else + return __auxmos = "auxmos" + +#define AUXMOS (__auxmos || __detect_auxmos()) + +/turf/proc/__update_auxtools_turf_adjacency_info() + return call_ext(AUXMOS, "byond:hook_infos_ffi")(src) + +/turf/proc/update_air_ref(flag) + return call_ext(AUXMOS, "byond:hook_register_turf_ffi")(src, flag) + +/datum/controller/subsystem/air/proc/process_turfs_auxtools(remaining) + return call_ext(AUXMOS, "byond:process_turf_hook_ffi")(src, remaining) + +/datum/controller/subsystem/air/proc/finish_turf_processing_auxtools(time_remaining) + return call_ext(AUXMOS, "byond:finish_process_turfs_ffi")(time_remaining) + +/datum/controller/subsystem/air/proc/thread_running() + return call_ext(AUXMOS, "byond:thread_running_hook_ffi")() + +/proc/finalize_gas_refs() + return call_ext(AUXMOS, "byond:finalize_gas_refs_ffi")() + +/datum/controller/subsystem/air/proc/auxtools_update_reactions() + return call_ext(AUXMOS, "byond:update_reactions_ffi")() + +/proc/auxtools_atmos_init(gas_data) + return call_ext(AUXMOS, "byond:hook_init_ffi")(gas_data) + +/proc/_auxtools_register_gas(gas) + return call_ext(AUXMOS, "byond:hook_register_gas_ffi")(gas) + +/datum/controller/subsystem/air/proc/process_turf_equalize_auxtools(remaining) + return call_ext(AUXMOS, "byond:equalize_hook_ffi")(src, remaining) + +/datum/controller/subsystem/air/proc/process_excited_groups_auxtools(remaining) + return call_ext(AUXMOS, "byond:groups_hook_ffi")(src, remaining) + +/datum/gas_mixture/proc/__auxtools_parse_gas_string(string) + return call_ext(AUXMOS, "byond:parse_gas_string_ffi")(src, string) + +/datum/controller/subsystem/air/proc/get_max_gas_mixes() + return call_ext(AUXMOS, "byond:hook_max_gas_mixes_ffi")() + +/datum/controller/subsystem/air/proc/get_amt_gas_mixes() + return call_ext(AUXMOS, "byond:hook_amt_gas_mixes_ffi")() + +/proc/equalize_all_gases_in_list(gas_list) + return call_ext(AUXMOS, "byond:equalize_all_hook_ffi")(gas_list) + +/datum/gas_mixture/proc/get_oxidation_power(temp) + return call_ext(AUXMOS, "byond:oxidation_power_hook_ffi")(src, temp) + +/datum/gas_mixture/proc/get_fuel_amount(temp) + return call_ext(AUXMOS, "byond:fuel_amount_hook_ffi")(src, temp) + +/datum/gas_mixture/proc/equalize_with(total) + return call_ext(AUXMOS, "byond:equalize_with_hook_ffi")(src, total) + +/datum/gas_mixture/proc/transfer_ratio_to(other, ratio) + return call_ext(AUXMOS, "byond:transfer_ratio_hook_ffi")(src, other, ratio) + +/datum/gas_mixture/proc/transfer_to(other, moles) + return call_ext(AUXMOS, "byond:transfer_hook_ffi")(src, other, moles) + +/datum/gas_mixture/proc/adjust_heat(temp) + return call_ext(AUXMOS, "byond:adjust_heat_hook_ffi")(src, temp) + +/datum/gas_mixture/proc/react(holder) + return call_ext(AUXMOS, "byond:react_hook_ffi")(src, holder) + +/datum/gas_mixture/proc/compare(other) + return call_ext(AUXMOS, "byond:compare_hook_ffi")(src, other) + +/datum/gas_mixture/proc/clear() + return call_ext(AUXMOS, "byond:clear_hook_ffi")(src) + +/datum/gas_mixture/proc/mark_immutable() + return call_ext(AUXMOS, "byond:mark_immutable_hook_ffi")(src) + +/datum/gas_mixture/proc/scrub_into(into, ratio_v, gas_list) + return call_ext(AUXMOS, "byond:scrub_into_hook_ffi")(src, into, ratio_v, gas_list) + +/datum/gas_mixture/proc/get_by_flag(flag_val) + return call_ext(AUXMOS, "byond:get_by_flag_hook_ffi")(src, flag_val) + +/datum/gas_mixture/proc/__remove_by_flag(into, flag_val, amount_val) + return call_ext(AUXMOS, "byond:remove_by_flag_hook_ffi")(src, into, flag_val, amount_val) + +/datum/gas_mixture/proc/divide(num_val) + return call_ext(AUXMOS, "byond:divide_hook_ffi")(src, num_val) + +/datum/gas_mixture/proc/multiply(num_val) + return call_ext(AUXMOS, "byond:multiply_hook_ffi")(src, num_val) + +/datum/gas_mixture/proc/subtract(num_val) + return call_ext(AUXMOS, "byond:subtract_hook_ffi")(src, num_val) + +/datum/gas_mixture/proc/add(num_val) + return call_ext(AUXMOS, "byond:add_hook_ffi")(src, num_val) + +/datum/gas_mixture/proc/adjust_multi(...) + var/list/args_copy = args.Copy() + args_copy.Insert(1, src) + return call_ext(AUXMOS, "byond:adjust_multi_hook_ffi")(arglist(args_copy)) + +/datum/gas_mixture/proc/adjust_moles_temp(id_val, num_val, temp_val) + return call_ext(AUXMOS, "byond:adjust_moles_temp_hook_ffi")(src, id_val, num_val, temp_val) + +/datum/gas_mixture/proc/adjust_moles(id_val, num_val) + return call_ext(AUXMOS, "byond:adjust_moles_hook_ffi")(src, id_val, num_val) + +/datum/gas_mixture/proc/set_moles(gas_id, amt_val) + return call_ext(AUXMOS, "byond:set_moles_hook_ffi")(src, gas_id, amt_val) + +/datum/gas_mixture/proc/get_moles(gas_id) + return call_ext(AUXMOS, "byond:get_moles_hook_ffi")(src, gas_id) + +/datum/gas_mixture/proc/set_volume(vol_arg) + return call_ext(AUXMOS, "byond:set_volume_hook_ffi")(src, vol_arg) + +/datum/gas_mixture/proc/partial_heat_capacity(gas_id) + return call_ext(AUXMOS, "byond:partial_heat_capacity_ffi")(src, gas_id) + +/datum/gas_mixture/proc/set_temperature(arg_temp) + return call_ext(AUXMOS, "byond:set_temperature_hook_ffi")(src, arg_temp) + +/datum/gas_mixture/proc/get_gases() + return call_ext(AUXMOS, "byond:get_gases_hook_ffi")(src) + +/datum/gas_mixture/proc/temperature_share(...) + var/list/args_copy = args.Copy() + args_copy.Insert(1, src) + return call_ext(AUXMOS, "byond:temperature_share_hook_ffi")(arglist(args_copy)) + +/datum/gas_mixture/proc/copy_from(giver) + return call_ext(AUXMOS, "byond:copy_from_hook_ffi")(src, giver) + +/datum/gas_mixture/proc/__remove(into, amount_arg) + return call_ext(AUXMOS, "byond:remove_hook_ffi")(src, into, amount_arg) + +/datum/gas_mixture/proc/__remove_ratio(into, ratio_arg) + return call_ext(AUXMOS, "byond:remove_ratio_hook_ffi")(src, into, ratio_arg) + +/datum/gas_mixture/proc/merge(giver) + return call_ext(AUXMOS, "byond:merge_hook_ffi")(src, giver) + +/datum/gas_mixture/proc/thermal_energy() + return call_ext(AUXMOS, "byond:thermal_energy_hook_ffi")(src) + +/datum/gas_mixture/proc/return_volume() + return call_ext(AUXMOS, "byond:return_volume_hook_ffi")(src) + +/datum/gas_mixture/proc/return_temperature() + return call_ext(AUXMOS, "byond:return_temperature_hook_ffi")(src) + +/datum/gas_mixture/proc/return_pressure() + return call_ext(AUXMOS, "byond:return_pressure_hook_ffi")(src) + +/datum/gas_mixture/proc/total_moles() + return call_ext(AUXMOS, "byond:total_moles_hook_ffi")(src) + +/datum/gas_mixture/proc/set_min_heat_capacity(arg_min) + return call_ext(AUXMOS, "byond:min_heat_cap_hook_ffi")(src, arg_min) + +/datum/gas_mixture/proc/heat_capacity() + return call_ext(AUXMOS, "byond:heat_cap_hook_ffi")(src) + +/datum/gas_mixture/proc/__gasmixture_unregister() + return call_ext(AUXMOS, "byond:unregister_gasmixture_hook_ffi")(src) + +/datum/gas_mixture/proc/__gasmixture_register() + return call_ext(AUXMOS, "byond:register_gasmixture_hook_ffi")(src) + +/proc/process_atmos_callbacks(remaining) + return call_ext(AUXMOS, "byond:atmos_callback_handle_ffi")(remaining) + diff --git a/code/__DEFINES/spaceman_dmm.dm b/code/__DEFINES/spaceman_dmm.dm index 818908fdc8a..47073ca253e 100644 --- a/code/__DEFINES/spaceman_dmm.dm +++ b/code/__DEFINES/spaceman_dmm.dm @@ -29,15 +29,6 @@ #define VAR_PROTECTED var #endif -/proc/auxtools_stack_trace(msg) - CRASH(msg) - -/proc/auxtools_expr_stub() - CRASH("auxtools not loaded") - -/proc/enable_debugging(mode, port) - CRASH("auxtools not loaded") - /world/Del() var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") if (debug_server) diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 511e436dba9..83e042b32e6 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -184,6 +184,7 @@ #define FIRE_PRIORITY_DEFAULT 50 #define FIRE_PRIORITY_PARALLAX 65 #define FIRE_PRIORITY_INSTRUMENTS 80 +#define FIRE_PRIORITY_CALLBACKS 90 #define FIRE_PRIORITY_MOBS 100 #define FIRE_PRIORITY_TGUI 110 #define FIRE_PRIORITY_TICKER 200 @@ -193,7 +194,6 @@ #define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_RUNECHAT 410 #define FIRE_PRIORITY_OVERLAYS 500 -#define FIRE_PRIORITY_CALLBACKS 600 #define FIRE_PRIORITY_EXPLOSIONS 666 #define FIRE_PRIORITY_TIMER 700 #define FIRE_PRIORITY_SOUND_LOOPS 800 @@ -224,6 +224,10 @@ #define SSAIR_ATMOSMACHINERY_AIR 12 #define SSAIR_DEFERRED_AIRS 13 +//Pipeline rebuild helper defines, these suck but it'll do for now //Fools you actually merged it +#define SSAIR_REBUILD_PIPELINE 1 +#define SSAIR_REBUILD_QUEUE 2 + // Explosion Subsystem subtasks #define SSEXPLOSIONS_MOVABLES 1 #define SSEXPLOSIONS_TURFS 2 diff --git a/code/__HELPERS/_extools_api.dm b/code/__HELPERS/_extools_api.dm deleted file mode 100644 index 16c70f7d2dc..00000000000 --- a/code/__HELPERS/_extools_api.dm +++ /dev/null @@ -1,23 +0,0 @@ -//#define EXTOOLS_LOGGING // rust_g is used as a fallback if this is undefined - -/proc/extools_log_write() - -/proc/extools_finalize_logging() - -GLOBAL_LIST_EMPTY(auxtools_initialized) - -#define AUXTOOLS_CHECK(LIB)\ - if (!GLOB.auxtools_initialized[LIB] && fexists(LIB)) {\ - var/string = LIBCALL(LIB,"auxtools_init")();\ - if(findtext(string, "SUCCESS")) {\ - GLOB.auxtools_initialized[LIB] = TRUE;\ - } else {\ - CRASH(string);\ - }\ - }\ - -#define AUXTOOLS_SHUTDOWN(LIB)\ - if (GLOB.auxtools_initialized[LIB] && fexists(LIB)){\ - LIBCALL(LIB,"auxtools_shutdown")();\ - GLOB.auxtools_initialized[LIB] = FALSE;\ - }\ diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index 69c808d9ef0..367b8358693 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -37,7 +37,7 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(list( if(break_if_found[checkT.type] || break_if_found[checkT.loc.type]) return FALSE var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE) - if(!cardinal_cache["[dir]"] || checkT.blocks_air || !CANATMOSPASS(sourceT, checkT)) + if(!cardinal_cache["[dir]"] || checkT.blocks_air || !TURFS_CAN_SHARE(sourceT, checkT)) continue found_turfs += checkT // Since checkT is connected, add it to the list to be processed @@ -58,7 +58,7 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(list( var/static/blacklisted_areas = typecacheof(list( /area/space, )) - var/list/turfs = detect_room(get_turf(creator), area_or_turf_fail_types) + var/list/turf/turfs = detect_room(get_turf(creator), area_or_turf_fail_types) if(!turfs) to_chat(creator, "The new area must be completely airtight and not a part of a shuttle.") return @@ -72,6 +72,8 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(list( continue if(!place.requires_power || place.teleport_restriction || place.area_flags & HIDDEN_AREA) continue // No expanding powerless rooms etc + if(!TURF_SHARES(turfs[i])) // No expanding areas of walls/something blocking this turf because that defeats the whole point of them used to separate areas + continue areas[place.name] = place var/area_choice = input(creator, "Choose an area to expand or make a new area.", "Area Expansion") as null|anything in areas area_choice = areas[area_choice] diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 89c70e94cc6..0752b2a90e9 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -549,7 +549,7 @@ if(!istype(T)) return var/datum/gas_mixture/environment = T.return_air() - if(!istype(environment)) + if(!environment) return var/pressure = environment.return_pressure() if(pressure <= MAXIMUM_LAVALAND_EQUIPMENT_EFFECT_PRESSURE) //NSV13 makes PKAs work in space again diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 9c22eb59a6e..2f0b0d7a2e3 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -114,18 +114,3 @@ #error Building with Dream Maker is no longer supported and will result in errors. #error Switch to VSCode and when prompted install the recommended extensions, you can then either use the UI or press Ctrl+Shift+B to build the codebase. #endif - -#define AUXMOS (world.system_type == MS_WINDOWS ? "auxtools/auxmos.dll" : __detect_auxmos()) - -/proc/__detect_auxmos() - var/static/auxmos_path - if(!auxmos_path) - if (fexists("./libauxmos.so")) - auxmos_path = "./libauxmos.so" - else if (fexists("./auxtools/libauxmos.so")) - auxmos_path = "./auxtools/libauxmos.so" - else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so")) - auxmos_path = "[world.GetConfig("env", "HOME")]/.byond/bin/libauxmos.so" - else - CRASH("Could not find libauxmos.so") - return auxmos_path diff --git a/code/_debugger.dm b/code/_debugger.dm index e570b351f24..1518908fa9a 100644 --- a/code/_debugger.dm +++ b/code/_debugger.dm @@ -2,7 +2,6 @@ //Datum gets created in master.dm because for whatever reason global code in there gets runs first //In case we ever figure out how to manipulate global init order please move the datum creation into this file /datum/debugger - var/enabled = FALSE /datum/debugger/New() enable_debugger() @@ -12,4 +11,3 @@ if (dll) LIBCALL(dll, "auxtools_init")() enable_debugging() - enabled = TRUE diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 4df37094a90..09f6adfea21 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -6,17 +6,20 @@ SUBSYSTEM_DEF(air) flags = SS_BACKGROUND runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + var/cached_cost = 0 + var/cost_turfs = 0 + var/cost_adjacent = 0 var/cost_groups = 0 var/cost_highpressure = 0 - var/cost_deferred_airs var/cost_hotspots = 0 var/cost_post_process = 0 var/cost_superconductivity = 0 var/cost_pipenets = 0 + var/cost_machinery = 0 var/cost_rebuilds = 0 - var/cost_atmos_machinery = 0 var/cost_equalize = 0 + var/thread_wait_ticks = 0 var/cur_thread_wait_ticks = 0 @@ -26,15 +29,19 @@ SUBSYSTEM_DEF(air) var/num_group_turfs_processed = 0 var/num_equalize_processed = 0 + var/gas_mixes_count = 0 + var/gas_mixes_allocated = 0 + + var/list/excited_groups = list() + var/list/active_turfs = list() var/list/hotspots = list() var/list/networks = list() - var/list/pipenets_needing_rebuilt = list() - var/list/deferred_airs = list() - var/cur_deferred_airs = 0 //NSV13 - ported fastmos from Citadel - var/max_deferred_airs = 0 - var/list/obj/machinery/atmos_machinery = list() - var/list/obj/machinery/atmos_air_machinery = list() + var/list/rebuild_queue = list() + var/list/expansion_queue = list() + /// List of turfs to recalculate adjacent turfs on before processing + var/list/adjacent_rebuild = list() var/list/pipe_init_dirs_cache = list() + var/list/obj/machinery/atmos_machinery = list() //atmos singletons var/list/gas_reactions = list() @@ -44,9 +51,12 @@ SUBSYSTEM_DEF(air) var/list/currentrun = list() - var/currentpart = SSAIR_REBUILD_PIPENETS + var/currentpart = SSAIR_PIPENETS var/map_loading = TRUE + var/list/queued_for_activation + + var/lasttick = 0 var/log_explosive_decompression = TRUE // If things get spammy, admemes can turn this off. @@ -56,22 +66,14 @@ SUBSYSTEM_DEF(air) var/equalize_hard_turf_limit = 400 //NSV13 - please do not eat our entire processing power kthanks. - down from 2000 // Whether equalization is enabled. Can be disabled for performance reasons. var/equalize_enabled = TRUE //NSV13 - set to true - // Whether equalization should be enabled. - var/should_do_equalization = TRUE //NSV13 - set to true - // When above 0, won't equalize; performance handling - var/eq_cooldown = 0 //NSV13 - ported fastmos from citadel // Whether turf-to-turf heat exchanging should be enabled. var/heat_enabled = FALSE // Max number of times process_turfs will share in a tick. var/share_max_steps = 3 // Target for share_max_steps; can go below this, if it determines the thread is taking too long. - var/share_max_steps_target = 3 //NSV13 - ported fastmos from citadel - // Excited group processing will try to equalize groups with total pressure difference less than this amount. var/excited_group_pressure_goal = 1 - // Target for excited_group_pressure_goal; can go below this, if it determines the thread is taking too long. - var/excited_group_pressure_goal_target = 1 //NSV13 - ported fastmos from citadel - // If this is set to 0, monstermos won't process planet atmos - var/planet_equalize_enabled = 0 //NSV13 - ported fastmos from citadel + /// Planet airs will share this ratio with the planet turfs per tick + var/planet_share_ratio = 0.25 var/list/paused_z_levels //Paused z-levels will not add turfs to active @@ -79,10 +81,10 @@ SUBSYSTEM_DEF(air) msg += "C:{" msg += "HP:[round(cost_highpressure,1)]|" msg += "HS:[round(cost_hotspots,1)]|" - msg += "HE:[round(heat_process_time(),1)]|" msg += "SC:[round(cost_superconductivity,1)]|" msg += "PN:[round(cost_pipenets,1)]|" - msg += "AM:[round(cost_atmos_machinery,1)]" + msg += "MC:[round(cost_machinery,1)]|" + msg += "RB:[round(cost_rebuilds,1)]|" msg += "} " msg += "TC:{" msg += "AT:[round(cost_turfs,1)]|" @@ -98,25 +100,46 @@ SUBSYSTEM_DEF(air) msg += "LT:[low_pressure_turfs]|" msg += "ET:[num_equalize_processed]|" msg += "GT:[num_group_turfs_processed]|" - msg += "DF:[max_deferred_airs]|" - msg += "GA:[get_amt_gas_mixes()]|" - msg += "MG:[get_max_gas_mixes()]" + msg += "GA:[gas_mixes_count]|" + msg += "MG:[gas_mixes_allocated]" return ..() +/datum/controller/subsystem/air/get_metrics() + . = ..() + var/list/custom = list() + custom["cost_turfs"] = cost_turfs + custom["cost_groups"] = cost_groups + custom["cost_highpressure"] = cost_highpressure + custom["cost_hotspots"] = cost_hotspots + custom["cost_post_process"] = cost_post_process + custom["cost_superconductivity"] = cost_superconductivity + custom["cost_pipenets"] = cost_pipenets + custom["cost_machinery"] = cost_machinery + custom["cost_rebuilds"] = cost_rebuilds + custom["cost_equalize"] = cost_equalize + custom["hotspts"] = hotspots.len + custom["networks"] = networks.len + custom["gas_mixes_count"] = gas_mixes_count + custom["gas_mixes_allocated"] = gas_mixes_allocated + custom["high_pressure_turfs"] = high_pressure_turfs + custom["low_pressure_turfs"] = low_pressure_turfs + custom["num_equalize_processed"] = num_equalize_processed + custom["num_group_turfs_processed"] = num_group_turfs_processed + custom["high_pressure_delta"] = high_pressure_delta.len + .["custom"] = custom + /datum/controller/subsystem/air/Initialize(timeofday) map_loading = FALSE setup_allturfs() setup_atmos_machinery() setup_pipenets() gas_reactions = init_gas_reactions() - should_do_equalization = CONFIG_GET(flag/atmos_equalize_enabled) //NSV13 - config for fastmos + equalize_enabled = CONFIG_GET(flag/atmos_equalize_enabled) //NSV13 - config for fastmos auxtools_update_reactions() return ..() /datum/controller/subsystem/air/proc/extools_update_ssair() -/datum/controller/subsystem/air/proc/auxtools_update_reactions() - /proc/reset_all_air() SSair.can_fire = 0 message_admins("Air reset begun.") @@ -126,99 +149,107 @@ SUBSYSTEM_DEF(air) message_admins("Air reset done.") SSair.can_fire = 1 -/datum/controller/subsystem/air/proc/thread_running() - return FALSE - -/proc/fix_corrupted_atmos() - -/datum/admins/proc/fixcorruption() - set category = "Debug" - set desc="Fixes air that has weird NaNs (-1.#IND and such). Hopefully." - set name="Fix Infinite Air" - fix_corrupted_atmos() +/datum/controller/subsystem/air/proc/check_threads() + if(thread_running()) + cur_thread_wait_ticks++ + pause() + return FALSE + return TRUE /datum/controller/subsystem/air/fire(resumed = 0) - var/timer = TICK_USAGE_REAL - if(currentpart == SSAIR_REBUILD_PIPENETS) + thread_wait_ticks = MC_AVERAGE(thread_wait_ticks, cur_thread_wait_ticks) + cur_thread_wait_ticks = 0 + + gas_mixes_count = get_amt_gas_mixes() + gas_mixes_allocated = get_max_gas_mixes() + + if(length(rebuild_queue) || length(expansion_queue)) timer = TICK_USAGE_REAL - var/list/pipenet_rebuilds = pipenets_needing_rebuilt - for(var/thing in pipenet_rebuilds) - var/obj/machinery/atmospherics/AT = thing - if(!istype(AT)) - continue - AT.build_network() - cost_rebuilds = MC_AVERAGE(cost_rebuilds, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - pipenets_needing_rebuilt.Cut() + process_rebuilds() + //This does mean that the apperent rebuild costs fluctuate very quickly, this is just the cost of having them always process, no matter what + cost_rebuilds = TICK_USAGE_REAL - timer if(state != SS_RUNNING) return - resumed = FALSE - currentpart = SSAIR_PIPENETS if(currentpart == SSAIR_PIPENETS || !resumed) timer = TICK_USAGE_REAL + if(!resumed) + cached_cost = 0 process_pipenets(resumed) - cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) + cached_cost += TICK_USAGE_REAL - timer if(state != SS_RUNNING) return + cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(cached_cost)) resumed = 0 currentpart = SSAIR_ATMOSMACHINERY - // This is only machinery like filters, mixers that don't interact with air + if(currentpart == SSAIR_ATMOSMACHINERY) timer = TICK_USAGE_REAL + if(!resumed) + cached_cost = 0 process_atmos_machinery(resumed) - cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) + cached_cost += TICK_USAGE_REAL - timer if(state != SS_RUNNING) return resumed = 0 - currentpart = SSAIR_HIGHPRESSURE + cost_machinery = MC_AVERAGE(cost_machinery, TICK_DELTA_TO_MS(cached_cost)) + currentpart = SSAIR_ACTIVETURFS - if(currentpart == SSAIR_HIGHPRESSURE) + if(currentpart == SSAIR_ACTIVETURFS) timer = TICK_USAGE_REAL - process_high_pressure_delta(resumed) - cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) + process_turfs(resumed) if(state != SS_RUNNING) return resumed = 0 - currentpart = SSAIR_FINALIZE_TURFS - // This literally just waits for the turf processing thread to finish, doesn't do anything else. - // this is necessary cause the next step after this interacts with the air--we get consistency - // issues if we don't wait for it, disappearing gases etc. - if(currentpart == SSAIR_FINALIZE_TURFS) - finish_turf_processing(resumed) + currentpart = SSAIR_EQUALIZE + + if(currentpart == SSAIR_EQUALIZE) + process_turf_equalize(resumed) if(state != SS_RUNNING) - cur_thread_wait_ticks++ return resumed = 0 - thread_wait_ticks = MC_AVERAGE(thread_wait_ticks, cur_thread_wait_ticks) - cur_thread_wait_ticks = 0 - currentpart = SSAIR_DEFERRED_AIRS - if(currentpart == SSAIR_DEFERRED_AIRS) - timer = TICK_USAGE_REAL - process_deferred_airs(resumed) - cost_deferred_airs = MC_AVERAGE(cost_deferred_airs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) + currentpart = SSAIR_EXCITEDGROUPS + + if(currentpart == SSAIR_EXCITEDGROUPS) + process_excited_groups(resumed) + if(state != SS_RUNNING) + return + resumed = 0 + currentpart = SSAIR_FINALIZE_TURFS + + if(currentpart == SSAIR_FINALIZE_TURFS) + finish_turf_processing(resumed) if(state != SS_RUNNING) return resumed = 0 - currentpart = SSAIR_ATMOSMACHINERY_AIR - if(currentpart == SSAIR_ATMOSMACHINERY_AIR) + currentpart = SSAIR_HIGHPRESSURE + + if(currentpart == SSAIR_HIGHPRESSURE) timer = TICK_USAGE_REAL - process_atmos_air_machinery(resumed) - cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) + if(!resumed) + cached_cost = 0 + process_high_pressure_delta(resumed) + cached_cost += TICK_USAGE_REAL - timer if(state != SS_RUNNING) return + cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(cached_cost)) resumed = 0 currentpart = SSAIR_HOTSPOTS if(currentpart == SSAIR_HOTSPOTS) timer = TICK_USAGE_REAL + if(!resumed) + cached_cost = 0 process_hotspots(resumed) - cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) + cached_cost += TICK_USAGE_REAL - timer if(state != SS_RUNNING) return + cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(cached_cost)) resumed = 0 - currentpart = heat_enabled ? SSAIR_TURF_CONDUCTION : SSAIR_ACTIVETURFS + currentpart = heat_enabled ? SSAIR_TURF_CONDUCTION : SSAIR_PIPENETS + // Heat -- slow and of questionable usefulness. Off by default for this reason. Pretty cool, though. if(currentpart == SSAIR_TURF_CONDUCTION) timer = TICK_USAGE_REAL @@ -228,48 +259,7 @@ SUBSYSTEM_DEF(air) if(state != SS_RUNNING) return resumed = 0 - currentpart = SSAIR_ACTIVETURFS - // This simply starts the turf thread. It runs in the background until the FINALIZE_TURFS step, at which point it's waited for. - // This also happens to do all the commented out stuff below, all in a single separate thread. This is mostly so that the - // waiting is consistent. - if(currentpart == SSAIR_ACTIVETURFS) - run_delay_heuristics() //NSV13 - ported fastmos from citadel - timer = TICK_USAGE_REAL - process_turfs(resumed) - cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - /* - // Monstermos and/or Putnamos--making large pressure deltas move faster - if(currentpart == SSAIR_EQUALIZE) - timer = TICK_USAGE_REAL - process_turf_equalize(resumed) - cost_equalize = MC_AVERAGE(cost_equalize, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - currentpart = SSAIR_EXCITEDGROUPS - // Making small pressure deltas equalize immediately so they don't process anymore - 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_TURF_POST_PROCESS - // Quick multithreaded "should we display/react?" checks followed by finishing those up before the next step - if(currentpart == SSAIR_TURF_POST_PROCESS) - timer = TICK_USAGE_REAL - post_process_turfs(resumed) - cost_post_process = MC_AVERAGE(cost_post_process, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - currentpart = SSAIR_HOTSPOTS - */ - currentpart = SSAIR_REBUILD_PIPENETS + currentpart = SSAIR_PIPENETS /datum/controller/subsystem/air/Recover() thread_wait_ticks = SSair.thread_wait_ticks @@ -280,12 +270,8 @@ SUBSYSTEM_DEF(air) num_equalize_processed = SSair.num_equalize_processed hotspots = SSair.hotspots networks = SSair.networks - pipenets_needing_rebuilt = SSair.pipenets_needing_rebuilt - deferred_airs = SSair.deferred_airs - cur_deferred_airs = SSair.max_deferred_airs // NSV13 - ported fastmos from Citadel - max_deferred_airs = SSair.max_deferred_airs - atmos_machinery = SSair.atmos_machinery - atmos_air_machinery = SSair.atmos_air_machinery + rebuild_queue = SSair.rebuild_queue + expansion_queue = SSair.expansion_queue pipe_init_dirs_cache = SSair.pipe_init_dirs_cache gas_reactions = SSair.gas_reactions high_pressure_delta = SSair.high_pressure_delta @@ -296,13 +282,9 @@ SUBSYSTEM_DEF(air) equalize_turf_limit = SSair.equalize_turf_limit equalize_hard_turf_limit = SSair.equalize_hard_turf_limit equalize_enabled = SSair.equalize_enabled - should_do_equalization = SSair.should_do_equalization //NSV13 - ported fastmos from citadel heat_enabled = SSair.heat_enabled share_max_steps = SSair.share_max_steps - share_max_steps_target = SSair.share_max_steps_target //NSV13 - ported fastmos from citadel excited_group_pressure_goal = SSair.excited_group_pressure_goal - excited_group_pressure_goal_target = SSair.excited_group_pressure_goal_target //NSV13 - ported fastmos from citadel - planet_equalize_enabled = SSair.planet_equalize_enabled //NSV13 - ported fastmos from citadel paused_z_levels = SSair.paused_z_levels /datum/controller/subsystem/air/proc/process_pipenets(resumed = FALSE) @@ -320,66 +302,86 @@ SUBSYSTEM_DEF(air) if(MC_TICK_CHECK) return -/datum/controller/subsystem/air/proc/add_to_rebuild_queue(atmos_machine) - if(istype(atmos_machine, /obj/machinery/atmospherics)) - pipenets_needing_rebuilt += atmos_machine - -/datum/controller/subsystem/air/proc/process_deferred_airs(resumed = 0) - cur_deferred_airs = deferred_airs.len //NSV13 - ported fastmos from citadel - max_deferred_airs = max(cur_deferred_airs,max_deferred_airs) - while(deferred_airs.len) - var/list/cur_op = deferred_airs[deferred_airs.len] - deferred_airs.len-- - var/datum/gas_mixture/air1 - var/datum/gas_mixture/air2 - if(isopenturf(cur_op[1])) - var/turf/open/T = cur_op[1] - air1 = T.return_air() - else - air1 = cur_op[1] - if(isopenturf(cur_op[2])) - var/turf/open/T = cur_op[2] - air2 = T.return_air() - else - air2 = cur_op[2] - if(istype(cur_op[3], /datum/callback)) - var/datum/callback/cb = cur_op[3] - cb.Invoke(air1, air2) - else - if(cur_op[3] == 0) - air1.transfer_to(air2, air1.total_moles()) - else - air1.transfer_ratio_to(air2, cur_op[3]) - if(MC_TICK_CHECK) +/datum/controller/subsystem/air/proc/add_to_rebuild_queue(obj/machinery/atmospherics/atmos_machine) + if(istype(atmos_machine, /obj/machinery/atmospherics) && !atmos_machine.rebuilding) + rebuild_queue += atmos_machine + atmos_machine.rebuilding = TRUE + +/datum/controller/subsystem/air/proc/add_to_expansion(datum/pipeline/line, starting_point) + var/list/new_packet = new(SSAIR_REBUILD_QUEUE) + new_packet[SSAIR_REBUILD_PIPELINE] = line + new_packet[SSAIR_REBUILD_QUEUE] = list(starting_point) + expansion_queue += list(new_packet) + +/datum/controller/subsystem/air/proc/remove_from_expansion(datum/pipeline/line) + for(var/list/packet in expansion_queue) + if(packet[SSAIR_REBUILD_PIPELINE] == line) + expansion_queue -= packet return -/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0) - 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 == null) - atmos_machinery.Remove(M) - if(!M || (M.process_atmos() == PROCESS_KILL)) - atmos_machinery.Remove(M) - if(MC_TICK_CHECK) - return - -/datum/controller/subsystem/air/proc/process_atmos_air_machinery(resumed = 0) - var/seconds = wait * 0.1 - if (!resumed) - src.currentrun = atmos_air_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_air_machinery.Remove(M) - if(MC_TICK_CHECK) +/datum/controller/subsystem/air/proc/process_rebuilds() + //Yes this does mean rebuilding pipenets can freeze up the subsystem forever, but if we're in that situation something else is very wrong + var/list/currentrun = rebuild_queue + while(currentrun.len || length(expansion_queue)) + while(currentrun.len && !length(expansion_queue)) //If we found anything, process that first + var/obj/machinery/atmospherics/remake = currentrun[currentrun.len] + currentrun.len-- + if (!remake) + continue + remake.rebuild_pipes() + if (MC_TICK_CHECK) + return + + var/list/queue = expansion_queue + while(queue.len) + var/list/pack = queue[queue.len] + //We operate directly with the pipeline like this because we can trust any rebuilds to remake it properly + var/datum/pipeline/linepipe = pack[SSAIR_REBUILD_PIPELINE] + var/list/border = pack[SSAIR_REBUILD_QUEUE] + expand_pipeline(linepipe, border) + if(state != SS_RUNNING) //expand_pipeline can fail a tick check, we shouldn't let things get too fucky here + return + + linepipe.building = FALSE + queue.len-- + if (MC_TICK_CHECK) + return + +///Rebuilds a pipeline by expanding outwards, while yielding when sane +/datum/controller/subsystem/air/proc/expand_pipeline(datum/pipeline/net, list/border) + while(border.len) + var/obj/machinery/atmospherics/borderline = border[border.len] + border.len-- + + var/list/result = borderline.pipeline_expansion(net) + if(!length(result)) + continue + for(var/obj/machinery/atmospherics/considered_device in result) + if(!istype(considered_device, /obj/machinery/atmospherics/pipe)) + considered_device.set_pipenet(net, borderline) + net.add_machinery_member(considered_device) + continue + var/obj/machinery/atmospherics/pipe/item = considered_device + if(net.members.Find(item)) + continue + if(item.parent) + var/static/pipenetwarnings = 10 + if(pipenetwarnings > 0) + log_mapping("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) around [AREACOORD(item)].") + pipenetwarnings-- + if(pipenetwarnings == 0) + log_mapping("build_pipeline(): further messages about pipenets will be suppressed") + + net.members += item + border += item + + net.air.set_volume(net.air.return_volume() + item.volume) + item.parent = net + + if(item.air_temporary) + net.air.merge(item.air_temporary) + item.air_temporary = null + if (MC_TICK_CHECK) return /datum/controller/subsystem/air/proc/process_turf_heat() @@ -410,65 +412,31 @@ SUBSYSTEM_DEF(air) if(MC_TICK_CHECK) return -/datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0) - if(process_turf_equalize_auxtools(resumed,MC_TICK_REMAINING_MS)) - pause() - /* - //cache for sanic speed - var/fire_count = times_fired +/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0) if (!resumed) - src.currentrun = active_turfs.Copy() + src.currentrun = atmos_machinery.Copy() //cache for sanic speed (lists are references anyways) var/list/currentrun = src.currentrun while(currentrun.len) - var/turf/open/T = currentrun[currentrun.len] + var/obj/machinery/M = currentrun[currentrun.len] currentrun.len-- - if (T) - T.equalize_pressure_in_zone(fire_count) - //equalize_pressure_in_zone(T, fire_count) - if (MC_TICK_CHECK) + if(M == null) + atmos_machinery.Remove(M) + if(!M || (M.process_atmos(wait / (1 SECONDS)) == PROCESS_KILL)) + stop_processing_machine(M) + if(MC_TICK_CHECK) return - */ - -//NSV13 - ported fastmos from citadel -/datum/controller/subsystem/air/proc/run_delay_heuristics() - if(!equalize_enabled) - cost_equalize = 0 - if(should_do_equalization) - eq_cooldown-- - if(eq_cooldown <= 0) - equalize_enabled = TRUE - var/total_thread_time = cost_turfs + cost_equalize + cost_groups + cost_post_process - if(total_thread_time) - var/wait_ms = wait * 100 - var/delay_threshold = 1-(total_thread_time/wait_ms + cur_deferred_airs / 50) - share_max_steps = max(1,round(share_max_steps_target * delay_threshold, 1)) - eq_cooldown += (1-delay_threshold) * (cost_equalize / total_thread_time) * 2 - if(eq_cooldown > 0.5) - equalize_enabled = FALSE - excited_group_pressure_goal = max(0,excited_group_pressure_goal_target * delay_threshold) //NSV13 - fix applied by Putnam somewhere else that previously slowed auxmos. + +/datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0) + if(process_turf_equalize_auxtools(MC_TICK_REMAINING_MS)) + pause() /datum/controller/subsystem/air/proc/process_turfs(resumed = 0) - if(process_turfs_auxtools(resumed,MC_TICK_REMAINING_MS)) + if(process_turfs_auxtools(MC_TICK_REMAINING_MS)) pause() - /* - //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/open/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(process_excited_groups_auxtools(resumed,MC_TICK_REMAINING_MS)) + if(process_excited_groups_auxtools(MC_TICK_REMAINING_MS)) pause() /datum/controller/subsystem/air/proc/finish_turf_processing(resumed = 0) @@ -476,20 +444,6 @@ SUBSYSTEM_DEF(air) if(finish_turf_processing_auxtools(MC_TICK_REMAINING_MS) || thread_running()) pause() -/datum/controller/subsystem/air/proc/post_process_turfs(resumed = 0) - if(post_process_turfs_auxtools(resumed,MC_TICK_REMAINING_MS)) - pause() - -/datum/controller/subsystem/air/proc/finish_turf_processing_auxtools() -/datum/controller/subsystem/air/proc/process_turfs_auxtools() -/datum/controller/subsystem/air/proc/post_process_turfs_auxtools() -/datum/controller/subsystem/air/proc/process_turf_equalize_auxtools() -/datum/controller/subsystem/air/proc/process_excited_groups_auxtools() -/datum/controller/subsystem/air/proc/get_amt_gas_mixes() -/datum/controller/subsystem/air/proc/get_max_gas_mixes() -/datum/controller/subsystem/air/proc/turf_process_time() -/datum/controller/subsystem/air/proc/heat_process_time() - /datum/controller/subsystem/air/StartLoadingMap() map_loading = TRUE @@ -498,10 +452,6 @@ SUBSYSTEM_DEF(air) /datum/controller/subsystem/air/proc/pause_z(z_level) LAZYADD(paused_z_levels, z_level) - var/list/turfs_to_disable = block(locate(1, 1, z_level), locate(world.maxx, world.maxy, z_level)) - for(var/turf/T as anything in turfs_to_disable) - T.ImmediateDisableAdjacency(FALSE) - CHECK_TICK /datum/controller/subsystem/air/proc/unpause_z(z_level) var/list/turfs_to_reinit = block(locate(1, 1, z_level), locate(world.maxx, world.maxy, z_level)) @@ -517,38 +467,39 @@ SUBSYSTEM_DEF(air) // Clear active turfs - faster than removing every single turf in the world // one-by-one, and Initalize_Atmos only ever adds `src` back in. - for(var/thing in turfs_to_init) - var/turf/T = thing - if (T.blocks_air) + for(var/turf/setup in turfs_to_init) + if (setup.blocks_air) continue - T.Initalize_Atmos(times_fired) + setup.Initalize_Atmos(times_fired) CHECK_TICK /datum/controller/subsystem/air/proc/setup_atmos_machinery() - for (var/obj/machinery/atmospherics/AM in atmos_machinery + atmos_air_machinery) - AM.atmosinit() + for (var/obj/machinery/atmospherics/AM in atmos_machinery) + AM.atmos_init() CHECK_TICK //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() - for (var/obj/machinery/atmospherics/AM in atmos_machinery + atmos_air_machinery) - AM.build_network() + for (var/obj/machinery/atmospherics/AM in atmos_machinery) + var/list/targets = AM.get_rebuild_targets() + for(var/datum/pipeline/build_off as anything in targets) + build_off.build_pipeline_blocking(AM) CHECK_TICK /datum/controller/subsystem/air/proc/setup_template_machinery(list/atmos_machines) - if(!initialized) // yogs - fixes randomized bars - return // yogs var/obj/machinery/atmospherics/AM for(var/A in 1 to atmos_machines.len) AM = atmos_machines[A] - AM.atmosinit() + AM.atmos_init() CHECK_TICK for(var/A in 1 to atmos_machines.len) AM = atmos_machines[A] - AM.build_network() + var/list/targets = AM.get_rebuild_targets() + for(var/datum/pipeline/build_off as anything in targets) + build_off.build_pipeline_blocking(AM) CHECK_TICK /datum/controller/subsystem/air/proc/get_init_dirs(type, dir) @@ -557,19 +508,20 @@ SUBSYSTEM_DEF(air) if(!pipe_init_dirs_cache[type]["[dir]"]) var/obj/machinery/atmospherics/temp = new type(null, FALSE, dir) - pipe_init_dirs_cache[type]["[dir]"] = temp.GetInitDirections() + pipe_init_dirs_cache[type]["[dir]"] = temp.get_init_directions() qdel(temp) return pipe_init_dirs_cache[type]["[dir]"] -#undef SSAIR_PIPENETS -#undef SSAIR_ATMOSMACHINERY -#undef SSAIR_EXCITEDGROUPS -#undef SSAIR_HIGHPRESSURE -#undef SSAIR_HOTSPOTS -#undef SSAIR_TURF_CONDUCTION -#undef SSAIR_EQUALIZE -#undef SSAIR_ACTIVETURFS -#undef SSAIR_TURF_POST_PROCESS -#undef SSAIR_FINALIZE_TURFS -#undef SSAIR_ATMOSMACHINERY_AIR +/datum/controller/subsystem/air/proc/start_processing_machine(obj/machinery/machine) + if(machine.atmos_processing) + return + machine.atmos_processing = TRUE + atmos_machinery += machine + +/datum/controller/subsystem/air/proc/stop_processing_machine(obj/machinery/machine) + if(!machine.atmos_processing) + return + machine.atmos_processing = FALSE + atmos_machinery -= machine + currentrun -= machine diff --git a/code/controllers/subsystem/callback.dm b/code/controllers/subsystem/callback.dm index ecc65760f4e..b105dfd8657 100644 --- a/code/controllers/subsystem/callback.dm +++ b/code/controllers/subsystem/callback.dm @@ -4,11 +4,10 @@ SUBSYSTEM_DEF(callbacks) wait = 1 priority = FIRE_PRIORITY_CALLBACKS -/proc/process_atmos_callbacks() - SScallbacks.can_fire = 0 - SScallbacks.flags |= SS_NO_FIRE - CRASH("Auxtools not found! Callback subsystem shutting itself off.") - /datum/controller/subsystem/callbacks/fire() + if(SSair.thread_running()) + pause() + return + if(process_atmos_callbacks(MC_TICK_REMAINING_MS)) pause() diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 5877d0fab85..8147c8a8094 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -130,7 +130,7 @@ if(end == start) return TRUE var/turf/Temp = get_step_towards(end, start) - if(!CANATMOSPASS(end, Temp)) + if(!TURFS_CAN_SHARE(end, Temp)) return FALSE end = Temp diff --git a/code/game/atoms.dm b/code/game/atoms.dm index a9bf421feb8..03d726d3b36 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -435,10 +435,7 @@ ///Return the current air environment in this atom /atom/proc/return_air() - if(loc) - return loc.return_air() - else - return null + return null ///Return the air if we can analyze it /atom/proc/return_analyzable_air() diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index daf81664efd..a02e5437641 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -483,7 +483,7 @@ //Restore air flow if we were blocking it (movables with ATMOS_PASS_PROC will need to do this manually if necessary) if(((CanAtmosPass == ATMOS_PASS_DENSITY && density) || CanAtmosPass == ATMOS_PASS_NO) && isturf(loc)) CanAtmosPass = ATMOS_PASS_YES - air_update_turf(TRUE) + air_update_turf() loc.handle_atom_del(src) for(var/atom/movable/AM in contents) qdel(AM) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 0c6c3579dd2..3959033234e 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -414,7 +414,7 @@ continue // No parent vent // Stops Aliens getting stuck in small networks. // See: Security, Virology - if(length(temp_vent_parent.other_atmosmch) > 20) + if(length(temp_vent_parent.other_atmos_machines) > 20) vents += temp_vent if(!length(vents)) log_game("DYNAMIC: [ruletype] ruleset [name] execute failed due to no valid spawn locations.") diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index d8e16c54d37..090980b76f7 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -138,6 +138,9 @@ Class Procs: /// Maximum time an EMP will disable this machine for var/emp_disable_time = 2 MINUTES + ///Boolean on whether this machines interact with atmos + var/atmos_processing = FALSE + /obj/machinery/Initialize(mapload) if(!armor) armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70, "stamina" = 0) diff --git a/code/game/machinery/airlock_cycle_control.dm b/code/game/machinery/airlock_cycle_control.dm index 951034d42fe..3501f18b0b4 100644 --- a/code/game/machinery/airlock_cycle_control.dm +++ b/code/game/machinery/airlock_cycle_control.dm @@ -117,12 +117,12 @@ qdel(wires) wires = null cut_links() - SSair.atmos_machinery -= src + SSair.stop_processing_machine(src) return ..() /obj/machinery/advanced_airlock_controller/Initialize(mapload) . = ..() - SSair.atmos_machinery += src + SSair.start_processing_machine(src) scan_on_late_init = mapload if(mapload && (. != INITIALIZE_HINT_QDEL)) return INITIALIZE_HINT_LATELOAD @@ -139,14 +139,12 @@ airlock.bolt() /obj/machinery/advanced_airlock_controller/update_icon(use_hash = FALSE) - var/turf/location = get_turf(src) - if(!location) + if(!isopenturf(get_turf(src))) return var/pressure = 0 - if(location) - var/datum/gas_mixture/environment = location.return_air() - if(environment) - pressure = environment.return_pressure() + var/datum/gas_mixture/environment = return_air() + if(environment) + pressure = environment.return_pressure() var/maxpressure = (exterior_pressure && (cyclestate == AIRLOCK_CYCLESTATE_OUTCLOSING || cyclestate == AIRLOCK_CYCLESTATE_OUTOPENING || cyclestate == AIRLOCK_CYCLESTATE_OUTOPEN)) ? exterior_pressure : interior_pressure var/pressure_bars = round(pressure / maxpressure * 5 + 0.01) @@ -299,15 +297,13 @@ update_icon(TRUE) return - var/turf/location = get_turf(src) - if(!location) + if(!isopenturf(get_turf(src))) update_icon(TRUE) return var/pressure = 0 - if(location) - var/datum/gas_mixture/environment = location.return_air() - if(environment) - pressure = environment.return_pressure() + var/datum/gas_mixture/environment = return_air() + if(environment) + pressure = environment.return_pressure() update_error_status() var/doors_valid = TRUE @@ -605,10 +601,9 @@ ui.open() /obj/machinery/advanced_airlock_controller/ui_data(mob/user) - var/turf/T = get_turf(src) var/pressure = 0 - if(T) - var/datum/gas_mixture/environment = T.return_air() + if(isopenturf(get_turf(src))) + var/datum/gas_mixture/environment = return_air() if(environment) pressure = environment.return_pressure() diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 1b0feb1bc5e..ae629c7930c 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -77,9 +77,9 @@ minor_alarms -= zone priority_alarms -= zone - if(severity == "severe") + if(severity == ATMOS_ALARM_SEVERE) priority_alarms += zone - else if (severity == "minor") + else if (severity == ATMOS_ALARM_MINOR) minor_alarms += zone update_icon() ui_update() diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index bfa01dfc90c..b7be9043cdb 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -75,11 +75,11 @@ /obj/machinery/air_sensor/Initialize(mapload) . = ..() - SSair.atmos_air_machinery += src + SSair.start_processing_machine(src) set_frequency(frequency) /obj/machinery/air_sensor/Destroy() - SSair.atmos_air_machinery -= src + SSair.stop_processing_machine(src) SSradio.remove_object(src, frequency) return ..() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index d4776194848..212c2beb241 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1230,7 +1230,7 @@ sleep(door_animation_speed) //Nsv13 - SPEEDY DOORS density = FALSE flags_1 &= ~PREVENT_CLICK_UNDER_1//NSV make it so prevent_click_under doesn't need density - air_update_turf(1) + air_update_turf() sleep(1) layer = OPEN_DOOR_LAYER update_icon(AIRLOCK_OPEN, 1) @@ -1278,13 +1278,13 @@ density = TRUE if(!(flags_1 & ON_BORDER_1))//NSV but not border firelocks flags_1 |= PREVENT_CLICK_UNDER_1//NSV make it so prevent_click_under doesn't need density - air_update_turf(1) + air_update_turf() sleep(1) if(!air_tight) density = TRUE if(!(flags_1 & ON_BORDER_1))//NSV but not border firelocks flags_1 |= PREVENT_CLICK_UNDER_1//NSV make it so prevent_click_under doesn't need density - air_update_turf(1) + air_update_turf() sleep(door_animation_speed) //Nsv13 - SPEEDY DOORS if(!safe) crush() diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index 5c58a3fb352..c8447b49baa 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -35,9 +35,9 @@ if(alarm_area == get_area_name(src)) switch(alert) - if("severe") + if(ATMOS_ALARM_SEVERE) autoclose = TRUE close() - if("minor", "clear") + if(ATMOS_ALARM_MINOR, ATMOS_ALARM_CLEAR) autoclose = FALSE open() diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 092b2e0cfd3..3aac9fb3535 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -62,7 +62,7 @@ flags_1 &= ~PREVENT_CLICK_UNDER_1 set_init_door_layer() update_freelook_sight() - air_update_turf(1) + air_update_turf() GLOB.airlocks += src spark_system = new /datum/effect_system/spark_spread spark_system.set_up(2, 1, src) @@ -96,6 +96,7 @@ if(spark_system) qdel(spark_system) spark_system = null + air_update_turf() return ..() /obj/machinery/door/Bumped(atom/movable/AM) @@ -222,9 +223,9 @@ // okay this is a bit hacky. First, we set density to 0 and recalculate our adjacent turfs density = FALSE flags_1 &= ~PREVENT_CLICK_UNDER_1//NSV make it so prevent_click_under doesn't need density - T.ImmediateCalculateAdjacentTurfs() + var/list/adj_turfs = TURF_SHARES(T) // then we use those adjacent turfs to figure out what the difference between the lowest and highest pressures we'd be holding is - for(var/turf/open/T2 in T.atmos_adjacent_turfs) + for(var/turf/open/T2 in adj_turfs) if((flags_1 & ON_BORDER_1) && get_dir(src, T2) != dir) continue var/moles = T2.air.total_moles() @@ -235,7 +236,6 @@ density = TRUE if(!(flags_1 & ON_BORDER_1))//NSV but not border firelocks flags_1 |= PREVENT_CLICK_UNDER_1//NSV make it so prevent_click_under doesn't need density - T.ImmediateCalculateAdjacentTurfs() // alright lets put it back return max_moles - min_moles > 20 /obj/machinery/door/attackby(obj/item/I, mob/user, params) @@ -322,7 +322,7 @@ update_icon() set_opacity(0) operating = FALSE - air_update_turf(1) + air_update_turf() update_freelook_sight() if(autoclose) spawn(autoclose) @@ -358,7 +358,7 @@ if(visible && !glass) set_opacity(1) operating = FALSE - air_update_turf(1) + air_update_turf() update_freelook_sight() if(safe) CheckForMobs() diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 660d16aa0dd..34284639b40 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -94,6 +94,7 @@ /obj/machinery/door/firedoor/Destroy() remove_from_areas() affecting_areas.Cut() + air_update_turf() return ..() /obj/machinery/door/firedoor/Bumped(atom/movable/AM) @@ -327,6 +328,7 @@ icon_state = "door_open" if(welded) add_overlay("welded_open") + air_update_turf() /obj/machinery/door/firedoor/open() if(density && !operating) //This is hacky but gets the sound to play on time. @@ -354,16 +356,15 @@ process_ticker = 0 update_icon() -/obj/machinery/door/firedoor/proc/whack_a_mole(reconsider_immediately = FALSE) - set waitfor = 0 +/obj/machinery/door/firedoor/proc/whack_a_mole() for(var/cdir in GLOB.cardinals) if((flags_1 & ON_BORDER_1) && cdir != dir) continue - whack_a_mole_part(get_step(src, cdir), reconsider_immediately) + whack_a_mole_part(get_step(src, cdir)) if(flags_1 & ON_BORDER_1) - whack_a_mole_part(get_turf(src), reconsider_immediately) + whack_a_mole_part(get_turf(src)) -/obj/machinery/door/firedoor/proc/whack_a_mole_part(turf/start_point, reconsider_immediately) +/obj/machinery/door/firedoor/proc/whack_a_mole_part(turf/start_point) set waitfor = 0 var/list/doors_to_close = list() var/list/turfs = list() @@ -397,17 +398,24 @@ return // too big, don't bother for(var/obj/machinery/door/firedoor/FD in doors_to_close) FD.emergency_pressure_stop(FALSE) - if(reconsider_immediately) - var/turf/open/T = FD.loc - if(istype(T)) - T.ImmediateCalculateAdjacentTurfs() /obj/machinery/door/firedoor/proc/emergency_pressure_stop(consider_timer = TRUE) - set waitfor = 0 if(density || operating || welded) return if(world.time >= emergency_close_timer || !consider_timer) - close() + emergency_pressure_close() + +//this is here to prevent sleeps from messing with decomp, by closing firedoors instantly +/obj/machinery/door/firedoor/proc/emergency_pressure_close() + density = TRUE + air_update_turf() + layer = closingLayer + update_icon() + if(visible && !glass) + set_opacity(1) + update_freelook_sight() + if(!(flags_1 & ON_BORDER_1)) + crush() /obj/machinery/door/firedoor/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) @@ -446,7 +454,6 @@ if(set_dir) setDir(set_dir) ini_dir = dir - air_update_turf(1) var/static/list/loc_connections = list( COMSIG_ATOM_EXIT = PROC_REF(on_exit), @@ -456,7 +463,6 @@ /obj/machinery/door/firedoor/border_only/Destroy() density = FALSE - air_update_turf(1) return ..() /obj/machinery/door/firedoor/border_only/closed @@ -470,6 +476,14 @@ set_opacity(1) if(operating || welded) return + check_pulls() + ..() + +/obj/machinery/door/firedoor/border_only/emergency_pressure_close() + check_pulls() + . = ..() + +/obj/machinery/door/firedoor/border_only/proc/check_pulls() var/turf/T1 = get_turf(src) var/turf/T2 = get_step(T1, dir) for(var/mob/living/M in T1) @@ -486,7 +500,6 @@ to_chat(M, "You pull [M.pulling] through [src] right as it closes.") M.pulling.forceMove(T2) M.start_pulling(M2) - . = ..() /obj/machinery/door/firedoor/border_only/check_safety(mob/user) var/area/A = get_area(src) @@ -545,6 +558,11 @@ return !density else return 1 + +/obj/machinery/door/firedoor/border_only/BlockThermalConductivity(opp_dir) + if(opp_dir == dir) + return density + return FALSE //NSV13 end /obj/machinery/door/firedoor/heavy diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index a68429216a1..6fe3a34af1e 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -47,7 +47,6 @@ /obj/machinery/door/window/Destroy() density = FALSE - air_update_turf(1) QDEL_LIST(debris) if(obj_integrity == 0) playsound(src, "shatter", 70, 1) @@ -156,7 +155,7 @@ sleep(10) density = FALSE - air_update_turf(1) + air_update_turf() update_freelook_sight() if(operating == 1) //emag again @@ -178,7 +177,7 @@ icon_state = base_state density = TRUE - air_update_turf(1) + air_update_turf() update_freelook_sight() sleep(10) diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 9ca09099583..c43ce4d8349 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -69,9 +69,9 @@ Buildable meters /obj/item/pipe/dropped() ..() if(loc) - setPipingLayer(piping_layer) + set_piping_layer(piping_layer) -/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT) +/obj/item/pipe/proc/set_piping_layer(new_layer = PIPING_LAYER_DEFAULT) var/obj/machinery/atmospherics/fakeA = pipe_type if(initial(fakeA.pipe_flags) & PIPING_ALL_LAYER) @@ -143,7 +143,7 @@ Buildable meters return TRUE if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) //don't continue if either pipe goes across all layers continue - if(M.GetInitDirections() & SSair.get_init_dirs(pipe_type, fixed_dir())) // matches at least one direction on either type of pipe + if(M.get_init_directions() & SSair.get_init_dirs(pipe_type, fixed_dir())) // matches at least one direction on either type of pipe to_chat(user, "There is already a pipe at that location!") return TRUE // no conflicts found @@ -163,7 +163,7 @@ Buildable meters /obj/item/pipe/proc/build_pipe(obj/machinery/atmospherics/A) A.setDir(fixed_dir()) - A.SetInitDirections() + A.set_init_directions() if(pipename) A.name = pipename diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index b56efbce182..55329a97806 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -47,7 +47,7 @@ return var/p_dir = text2num(href_list["dir"]) var/obj/item/pipe/P = new (loc, p_type, p_dir) - P.setPipingLayer(piping_layer) + P.set_piping_layer(piping_layer) P.add_fingerprint(usr) wait = world.time + 10 if(href_list["makemeter"]) @@ -95,7 +95,7 @@ //Allow you to drag-drop disposal pipes and transit tubes into it /obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/pipe, mob/usr) - if(!usr.incapacitated()) + if(usr.incapacitated()) return if (!istype(pipe, /obj/structure/disposalconstruct) && !istype(pipe, /obj/structure/c_transit_tube) && !istype(pipe, /obj/structure/c_transit_tube_pod)) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index b6c361a9d7c..583cd90848c 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -14,7 +14,11 @@ /obj/structure/emergency_shield/Initialize(mapload) . = ..() setDir(pick(GLOB.cardinals)) - air_update_turf(1) + air_update_turf() + +/obj/structure/emergency_shield/Destroy() + air_update_turf() + . = ..() /obj/structure/emergency_shield/Move() var/turf/T = loc diff --git a/code/game/machinery/shuttle/shuttle_engine.dm b/code/game/machinery/shuttle/shuttle_engine.dm index f5920926bc7..bd31005c282 100644 --- a/code/game/machinery/shuttle/shuttle_engine.dm +++ b/code/game/machinery/shuttle/shuttle_engine.dm @@ -112,10 +112,11 @@ //Thanks to spaceheater.dm for inspiration :) /obj/machinery/shuttle/engine/proc/fireEngine() - var/turf/heatTurf = loc - if(!heatTurf) + if(!isopenturf(get_turf(src))) + return + var/datum/gas_mixture/env = return_air() + if(!env) return - var/datum/gas_mixture/env = heatTurf.return_air() var/heat_cap = env.heat_capacity() var/req_power = abs(env.return_temperature() - ENGINE_HEAT_TARGET) * heat_cap req_power = min(req_power, ENGINE_HEATING_POWER) @@ -123,7 +124,6 @@ if(deltaTemperature < 0) return env.set_temperature(env.return_temperature() + deltaTemperature) - air_update_turf() /obj/machinery/shuttle/engine/attackby(obj/item/I, mob/living/user, params) check_setup() diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm index 01964b1fb6a..ac8f848916c 100644 --- a/code/game/machinery/shuttle/shuttle_heater.dm +++ b/code/game/machinery/shuttle/shuttle_heater.dm @@ -35,7 +35,7 @@ /obj/machinery/atmospherics/components/unary/shuttle/heater/New() . = ..() GLOB.custom_shuttle_machines += src - SetInitDirections() + set_init_directions() update_adjacent_engines() updateGasStats() @@ -46,27 +46,27 @@ /obj/machinery/atmospherics/components/unary/shuttle/heater/on_construction() ..(dir, dir) - SetInitDirections() + set_init_directions() update_adjacent_engines() /obj/machinery/atmospherics/components/unary/shuttle/heater/default_change_direction_wrench(mob/user, obj/item/I) if(!..()) return FALSE - SetInitDirections() + set_init_directions() var/obj/machinery/atmospherics/node = nodes[1] if(node) node.disconnect(src) nodes[1] = null if(!parents[1]) return - nullifyPipenet(parents[1]) + nullify_pipenet(parents[1]) - atmosinit() + atmos_init() node = nodes[1] if(node) - node.atmosinit() - node.addMember(src) - build_network() + node.atmos_init() + node.add_member(src) + SSair.add_to_rebuild_queue(src) return TRUE /obj/machinery/atmospherics/components/unary/shuttle/heater/RefreshParts() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index ac321815c59..4b8cbacc5c9 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -96,7 +96,7 @@ return var/heat_capacity = env.heat_capacity() - var/requiredPower = abs(env.return_temperature() - targetTemperature) * heat_capacity + var/requiredPower = abs(env.return_temperature() - targetTemperature) requiredPower = min(requiredPower, heatingPower) if(requiredPower < 1) @@ -107,7 +107,6 @@ deltaTemperature *= -1 if(deltaTemperature) env.set_temperature(env.return_temperature() + deltaTemperature) - air_update_turf() cell.use(requiredPower / efficiency) else on = FALSE @@ -189,13 +188,10 @@ data["minTemp"] = max(settableTemperatureMedian - settableTemperatureRange - T0C, TCMB) data["maxTemp"] = settableTemperatureMedian + settableTemperatureRange - T0C - var/turf/L = get_turf(loc) var/curTemp - if(istype(L)) - var/datum/gas_mixture/env = L.return_air() - curTemp = env.return_temperature() - else if(isturf(L)) - curTemp = L.return_temperature() + if(isopenturf(get_turf(src))) + var/datum/gas_mixture/env = return_air() + curTemp = env?.return_temperature() if(isnull(curTemp)) data["currentTemp"] = "N/A" else @@ -212,7 +208,9 @@ usr.visible_message("[usr] switches [on ? "on" : "off"] \the [src].", "You switch [on ? "on" : "off"] \the [src].") update_icon() if (on) - SSair.atmos_air_machinery += src + SSair.start_processing_machine(src) //NSV13 - Citadel auxmos + else + SSair.stop_processing_machine(src) . = TRUE if("mode") setMode = params["mode"] diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 569a395e030..8da3810b612 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -46,7 +46,6 @@ absorbed_plasma += plas_amt if(G.return_temperature() > T20C) G.set_temperature(max(G.return_temperature()/2,T20C)) - T.air_update_turf() /obj/effect/particle_effect/foam/firefighting/kill_foam() STOP_PROCESSING(SSfastprocess, src) @@ -271,7 +270,7 @@ /obj/structure/foamedmetal/Initialize(mapload) . = ..() - air_update_turf(1) + air_update_turf() /obj/structure/foamedmetal/Move() var/turf/T = loc @@ -321,7 +320,6 @@ if(I == GAS_O2 || I == GAS_N2) continue G.set_moles(I, 0) - O.air_update_turf() for(var/obj/machinery/atmospherics/components/unary/U in O) if(!U.welded) U.welded = TRUE diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index 83b2ee814de..de40ba2e225 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -160,7 +160,6 @@ var/datum/gas_mixture/G = T.air if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air G.set_temperature(temperature) - T.air_update_turf() for(var/obj/effect/hotspot/H in T) qdel(H) if(G.get_moles(GAS_PLASMA)) diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm index d490a92b851..bef5e69836f 100644 --- a/code/game/objects/effects/glowshroom.dm +++ b/code/game/objects/effects/glowshroom.dm @@ -84,6 +84,8 @@ /obj/structure/glowshroom/proc/Spread() var/turf/ownturf = get_turf(src) + if(!TURF_SHARES(ownturf)) // if we are in a 1x1 room + return var/shrooms_planted = 0 for(var/i in 1 to myseed.yield) if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2... @@ -96,7 +98,7 @@ for(var/turf/open/floor/earth in view(3,src)) if(is_type_in_typecache(earth, blacklisted_glowshroom_turfs)) continue - if(!ownturf.CanAtmosPass(earth)) + if(!TURF_SHARES(earth)) continue if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,earth)) possibleLocs += earth diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 4bb7c0f7241..97d0d89e46a 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -123,16 +123,14 @@ return FALSE atmos_source.atmos_adjacent_turfs[atmos_destination] = TRUE atmos_destination.atmos_adjacent_turfs[atmos_source] = TRUE - atmos_source.air_update_turf(FALSE) - atmos_destination.air_update_turf(FALSE) /obj/effect/portal/proc/unlink_atmos() if(istype(atmos_source)) - if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !CANATMOSPASS(atmos_destination, atmos_source)) + if(istype(atmos_destination) && !atmos_source.Adjacent(atmos_destination) && !TURFS_CAN_SHARE(atmos_destination, atmos_source)) LAZYREMOVE(atmos_source.atmos_adjacent_turfs, atmos_destination) atmos_source = null if(istype(atmos_destination)) - if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !CANATMOSPASS(atmos_source, atmos_destination)) + if(istype(atmos_source) && !atmos_destination.Adjacent(atmos_source) && !TURFS_CAN_SHARE(atmos_source, atmos_destination)) LAZYREMOVE(atmos_destination.atmos_adjacent_turfs, atmos_source) atmos_destination = null diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index d3070e74129..b6ebd17cd46 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -133,7 +133,7 @@ if(get_dist(src, entry_vent) <= 1) var/list/vents = list() var/datum/pipeline/entry_vent_parent = entry_vent.parents[1] - for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch) + for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmos_machines) vents.Add(temp_vent) if(!vents.len) entry_vent = null diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index a083c74a594..2c165d946a0 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -390,7 +390,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( return if(mode & PAINT_MODE) - var/obj/machinery/atmospherics/M = A + var/obj/machinery/atmospherics/pipe/M = A if(istype(M) && M.paintable) to_chat(user, "You start painting \the [M] [paint_color]...") playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) @@ -441,7 +441,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( P.update() P.add_fingerprint(usr) - P.setPipingLayer(piping_layer) + P.set_piping_layer(piping_layer) if(findtext("[queued_p_type]", "/obj/machinery/atmospherics/pipe") && !findtext("[queued_p_type]", "layer_manifold")) P.add_atom_colour(GLOB.pipe_paint_colors[paint_color], FIXED_COLOUR_PRIORITY) if(mode&WRENCH_MODE) diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 935918b8ea6..f32be1059ad 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -257,7 +257,13 @@ return BULLET_ACT_HIT /obj/structure/chrono_field/assume_air() - return 0 + return null + +/obj/effect/chrono_field/assume_air_moles() + return null + +/obj/effect/chrono_field/assume_air_ratio() + return null /obj/structure/chrono_field/return_air() //we always have nominal air and temperature var/datum/gas_mixture/GM = new diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 1490d617343..829c52073fe 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -132,7 +132,7 @@ target_self = TRUE if(change_volume) if(!target_self) - target.set_volume(target.return_volume() + tank_two.air_contents.return_volume()) + target.set_volume(target.return_volume() + tank_two.volume) target.set_volume(target.return_volume() + tank_one.air_contents.return_volume()) tank_one.air_contents.transfer_ratio_to(target, 1) if(!target_self) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 0856a81ab61..309b44ac826 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -672,7 +672,6 @@ T.visible_message("[T] smacks into [src] and rapidly flashes to ash.",\ "You hear a loud crack as you are washed with a wave of heat.") shard.Consume() - T.ImmediateCalculateAdjacentTurfs() /obj/item/melee/supermatter_sword/add_blood_DNA(list/blood_dna) return FALSE diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index a7b5c858ba7..be776dfa481 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -80,7 +80,6 @@ if(!T) return T.assume_air(gasused) - T.air_update_turf() if(!gasused) to_chat(user, "\The [src]'s tank is empty!") force = (baseforce / 5) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 65554caa90a..55f0d76ea91 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -117,7 +117,6 @@ var/turf/T = get_turf(src) if(T) T.assume_air(air_contents) - air_update_turf() playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3) qdel(src) diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index 8707db401c2..aa1de82ef20 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -66,7 +66,7 @@ /obj/structure/alien/resin/Initialize(mapload) . = ..() - air_update_turf(TRUE) + air_update_turf() /obj/structure/alien/resin/Move() var/turf/T = loc diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm index 9a136367e90..9c3c2b67b0a 100644 --- a/code/game/objects/structures/crates_lockers/crates/critter.dm +++ b/code/game/objects/structures/crates_lockers/crates/critter.dm @@ -70,7 +70,7 @@ if(tank) return tank.air_contents else - return loc.return_air() + return loc?.return_air() /obj/structure/closet/crate/critter/return_analyzable_air() if(tank) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index d428267011d..2306894cae9 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -35,7 +35,7 @@ /obj/structure/falsewall/Initialize(mapload) . = ..() - air_update_turf(TRUE) + air_update_turf() /obj/structure/falsewall/ratvar_act() new /obj/structure/falsewall/brass(loc) @@ -63,7 +63,7 @@ set_opacity(density) opening = FALSE update_icon() - air_update_turf(TRUE) + air_update_turf() /obj/structure/falsewall/update_icon()//Calling icon_update will refresh the smoothwalls if it's closed, otherwise it will make sure the icon is correct if it's open if(opening) diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 71a1efb1e86..93e9df5f9d8 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -100,7 +100,7 @@ . = ..() var/turf/local = get_turf(loc) ADD_TRAIT(local, TRAIT_FIREDOOR_STOP, TRAIT_GENERIC) - air_update_turf(TRUE) + air_update_turf() /obj/structure/holosign/barrier/atmos/Destroy() var/turf/local = get_turf(loc) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 793973e5455..dae58ae3758 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -27,7 +27,7 @@ /obj/structure/mineral_door/Initialize(mapload) . = ..() - air_update_turf(TRUE) + air_update_turf() /obj/structure/mineral_door/Move() var/turf/T = loc @@ -91,7 +91,7 @@ sleep(10) density = FALSE door_opened = TRUE - air_update_turf(1) + air_update_turf() update_icon() isSwitchingStates = FALSE @@ -111,7 +111,7 @@ density = TRUE set_opacity(TRUE) door_opened = FALSE - air_update_turf(1) + air_update_turf() update_icon() isSwitchingStates = FALSE @@ -129,7 +129,7 @@ /obj/structure/mineral_door/setAnchored(anchorvalue) //called in default_unfasten_wrench() chain . = ..() set_opacity(anchored ? !door_opened : FALSE) - air_update_turf(TRUE) + air_update_turf() /obj/structure/mineral_door/wrench_act(mob/living/user, obj/item/I) default_unfasten_wrench(user, I, 40) diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 84ba6ff765a..f65ddca1a4c 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -103,10 +103,10 @@ /obj/structure/plasticflaps/Initialize(mapload) . = ..() - air_update_turf(TRUE) + air_update_turf() /obj/structure/plasticflaps/Destroy() var/atom/oldloc = loc . = ..() if (oldloc) - oldloc.air_update_turf(1) + oldloc.air_update_turf() diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 29811cf0728..b33006e8702 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -124,7 +124,6 @@ return TRUE /obj/structure/railing/proc/after_rotation(mob/user,rotation_type) - air_update_turf(1) ini_dir = dir add_fingerprint(user) diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index b082356aa00..86d7f6252d0 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -154,7 +154,6 @@ if(!QDELETED(pod)) var/datum/gas_mixture/floor_mixture = loc.return_air() equalize_all_gases_in_list(list(pod.air_contents,floor_mixture)) - air_update_turf() /obj/structure/transit_tube/station/init_tube_dirs() switch(dir) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 156f2182962..7d3f47937e9 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -34,7 +34,7 @@ if(set_dir) setDir(set_dir) ini_dir = dir - air_update_turf(1) + air_update_turf() var/static/list/loc_connections = list( COMSIG_ATOM_EXIT = PROC_REF(on_exit), @@ -44,7 +44,7 @@ /obj/structure/windoor_assembly/Destroy() density = FALSE - air_update_turf(1) + air_update_turf() return ..() /obj/structure/windoor_assembly/Move() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 0dff721d8df..e486ae547b3 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -57,7 +57,7 @@ state = WINDOW_SCREWED_TO_FRAME ini_dir = dir - air_update_turf(1) + air_update_turf() if(fulltile) setDir() @@ -241,7 +241,7 @@ /obj/structure/window/setAnchored(anchorvalue) ..() - air_update_turf(TRUE) + air_update_turf() update_nearby_icons() /obj/structure/window/proc/check_state(checked_state) @@ -317,13 +317,13 @@ return TRUE /obj/structure/window/proc/after_rotation(mob/user,rotation_type) - air_update_turf(1) + air_update_turf() ini_dir = dir add_fingerprint(user) /obj/structure/window/Destroy() density = FALSE - air_update_turf(1) + air_update_turf() update_nearby_icons() return ..() @@ -440,6 +440,11 @@ if (fulltile) . += new /obj/item/shard/plasma(location) +/obj/structure/window/plasma/BlockThermalConductivity(opp_dir) + if(!anchored || !density) + return FALSE + return FULLTILE_WINDOW_DIR == dir || dir == opp_dir + /obj/structure/window/plasma/spawner/east dir = EAST diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index b6bbee8b561..1f84a486de0 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -14,16 +14,15 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( qdel(thing, force=TRUE) if(turf_type) - var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags) - newT.ImmediateCalculateAdjacentTurfs() + ChangeTurf(turf_type, baseturf_type, flags) -/turf/proc/copyTurf(turf/T) +/turf/proc/copyTurf(turf/T, copy_air, flags) if(T.type != type) var/obj/O if(underlays.len) //we have underlays, which implies some sort of transparency, so we want to a snapshot of the previous turf as an underlay O = new() O.underlays.Add(T) - T.ChangeTurf(type) + T.ChangeTurf(type, null, flags) if(underlays.len) T.underlays = O.underlays if(T.icon_state != icon_state) @@ -151,6 +150,9 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( return W /turf/open/ChangeTurf(path, list/new_baseturfs, flags) + //don't + if(!SSair.initialized) + return ..() if ((flags & CHANGETURF_INHERIT_AIR) && ispath(path, /turf/open)) var/datum/gas_mixture/stashed_air = new() stashed_air.copy_from(air) @@ -159,19 +161,19 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( QDEL_NULL(stashed_air) return var/turf/open/newTurf = . - newTurf.air.copy_from(stashed_air) - newTurf.update_air_ref(planetary_atmos ? 1 : 2) - QDEL_NULL(stashed_air) + if (!istype(newTurf.air, /datum/gas_mixture/immutable/space)) + QDEL_NULL(newTurf.air) + newTurf.air = stashed_air + update_air_ref(planetary_atmos ? 1 : 2) else - flags |= CHANGETURF_RECALC_ADJACENT if(ispath(path,/turf/closed)) + flags |= CHANGETURF_RECALC_ADJACENT + update_air_ref(-1) . = ..() - var/turf/open/newTurf = . - newTurf.update_air_ref(-1) else . = ..() - var/turf/open/newTurf = . - newTurf.Initalize_Atmos(0) + if(!istype(air,/datum/gas_mixture)) + Initalize_Atmos(0) /turf/closed/ChangeTurf(path, list/new_baseturfs, flags) if(ispath(path,/turf/open)) @@ -274,7 +276,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( // Copy an existing turf and put it on top // Returns the new turf -/turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY, copy_air = FALSE) +/turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY, copy_air = FALSE, flags) var/list/new_baseturfs = list() new_baseturfs += baseturfs new_baseturfs += type @@ -291,7 +293,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( target_baseturfs -= new_baseturfs & GLOB.blacklisted_automated_baseturfs new_baseturfs += target_baseturfs - var/turf/newT = copytarget.copyTurf(src, copy_air) + var/turf/newT = copytarget.copyTurf(src, copy_air, flags) newT?.baseturfs = new_baseturfs return newT diff --git a/code/game/turfs/closed/_closed.dm b/code/game/turfs/closed/_closed.dm index e930b0cc0d6..fd33a3a46c3 100644 --- a/code/game/turfs/closed/_closed.dm +++ b/code/game/turfs/closed/_closed.dm @@ -7,9 +7,6 @@ rad_insulation = RAD_MEDIUM_INSULATION pass_flags_self = PASSCLOSEDTURF -/turf/closed/Initialize(mapload) - . = ..() - /turf/closed/AfterChange() . = ..() SSair.high_pressure_delta -= src diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index d08c4a8f7ed..e810a948fba 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -149,10 +149,11 @@ baseturfs = /turf/open/indestructible/airblock /turf/open/Initalize_Atmos(times_fired) - if(!istype(air,/datum/gas_mixture/turf)) - air = new(2500,src) - air.copy_from_turf(src) - update_air_ref(planetary_atmos ? 1 : 2) + if(!blocks_air) + if(!istype(air,/datum/gas_mixture/turf)) + air = new(2500,src) + air.copy_from_turf(src) + update_air_ref(planetary_atmos ? 1 : 2) update_visuals() @@ -167,7 +168,6 @@ /turf/open/proc/TakeTemperature(temp) air.set_temperature(air.return_temperature() + temp) - air_update_turf() /turf/open/proc/freon_gas_act() for(var/obj/I in contents) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index f0b67c1e753..01172088bd8 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -119,6 +119,8 @@ GLOBAL_LIST_EMPTY(created_baseturf_lists) /turf/proc/__auxtools_update_turf_temp_info() +/turf/proc/__auxtools_update_turf_infos(immediate) + /turf/return_temperature() /turf/proc/set_temperature() diff --git a/code/game/world.dm b/code/game/world.dm index 343175c9746..855301d28a2 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -5,8 +5,10 @@ GLOBAL_VAR(restart_counter) //This happens after the Master subsystem new(s) (it's a global datum) //So subsystems globals exist, but are not initialised /world/New() - //Keep the auxtools stuff at the top - AUXTOOLS_CHECK(AUXMOS) + var/dll = GetConfig("env", "AUXTOOLS_DEBUG_DLL") + if (dll) + LIBCALL(dll, "auxtools_init")() + //enable_debugging() log_world("World loaded at [time_stamp()]!") SSmetrics.world_init_time = REALTIMEOFDAY // Important @@ -303,15 +305,20 @@ GLOBAL_VAR(restart_counter) log_world("World hard rebooted at [time_stamp()]") shutdown_logging() // See comment below. TgsEndProcess() + var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") + if (debug_server) + LIBCALL(debug_server, "auxtools_shutdown")() log_world("World rebooted at [time_stamp()]") shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. - AUXTOOLS_SHUTDOWN(AUXMOS) + var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") + if (debug_server) + LIBCALL(debug_server, "auxtools_shutdown")() ..() /world/Del() shutdown_logging() // makes sure the thread is closed before end, else we terminate - AUXTOOLS_SHUTDOWN(AUXMOS) + //__auxmos_shutdown() var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL") if (debug_server) LIBCALL(debug_server, "auxtools_shutdown")() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index b6aedb6184e..6ca432cae1a 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -198,7 +198,6 @@ GLOBAL_PROTECT(admin_verbs_debug) /client/proc/reload_configuration, /client/proc/give_all_spells, /datum/admins/proc/create_or_modify_area, - /datum/admins/proc/fixcorruption, #ifdef TESTING /client/proc/run_dynamic_simulations, #endif diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm index 20dfcbb3aef..bb49515d8f7 100644 --- a/code/modules/antagonists/blob/structures/_blob.dm +++ b/code/modules/antagonists/blob/structures/_blob.dm @@ -32,7 +32,7 @@ setDir(pick(GLOB.cardinals)) update_icon() if(atmosblock) - air_update_turf(1) + air_update_turf() ConsumeTile() /obj/structure/blob/proc/creation_action() //When it's created by the overmind, do this. @@ -41,7 +41,7 @@ /obj/structure/blob/Destroy() if(atmosblock) atmosblock = FALSE - air_update_turf(1) + air_update_turf() if(overmind) overmind.blobs_legit -= src //if it was in the legit blobs list, it isn't now GLOB.blobs -= src //it's no longer in the all blobs list either diff --git a/code/modules/antagonists/blob/structures/shield.dm b/code/modules/antagonists/blob/structures/shield.dm index cb773d53480..720e0dda759 100644 --- a/code/modules/antagonists/blob/structures/shield.dm +++ b/code/modules/antagonists/blob/structures/shield.dm @@ -31,7 +31,7 @@ name = initial(name) desc = initial(desc) atmosblock = TRUE - air_update_turf(1) + air_update_turf() /obj/structure/blob/shield/reflective name = "reflective blob" diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 4f5d58cf7c7..32708352b98 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -709,7 +709,7 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/wall/proc/update_state() deltimer(density_timer) - air_update_turf(1) + air_update_turf() if(density) var/mutable_appearance/shimmer = mutable_appearance('icons/effects/effects.dmi', "barriershimmer", ABOVE_MOB_LAYER) shimmer.appearance_flags |= RESET_COLOR diff --git a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm index 4335cc18c6c..638232c3c98 100644 --- a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm +++ b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm @@ -138,5 +138,3 @@ for(var/turf/T as() in RANGE_TURFS(1,user)) env = T.return_air() env.set_temperature(env.return_temperature() + 5 ) - T.air_update_turf() - L.air_update_turf() diff --git a/code/modules/atmospherics/auxgm/gas_types.dm b/code/modules/atmospherics/auxgm/gas_types.dm index 6c12fb1cf1e..069dbcebca0 100644 --- a/code/modules/atmospherics/auxgm/gas_types.dm +++ b/code/modules/atmospherics/auxgm/gas_types.dm @@ -3,10 +3,21 @@ specific_heat = 20 name = "Oxygen" oxidation_temperature = T0C - 100 // it checks max of this and fire temperature, so rarely will things spontaneously combust + powermix = 1 + heat_penalty = 1 + transmit_modifier = 1.5 + +/datum/gas/oxygen/generate_TLV() + return new/datum/tlv(16, 19, 40, 50) /datum/gas/nitrogen id = GAS_N2 specific_heat = 20 + name = "Nitrogen" + powermix = -1 + heat_penalty = -1.5 + fire_burn_rate = 1 + fire_temperature = 2300 breath_alert_info = list( not_enough_alert = list( alert_category = "not_enough_nitro", @@ -17,12 +28,14 @@ alert_type = /atom/movable/screen/alert/too_much_nitro ) ) - name = "Nitrogen" /datum/gas/carbon_dioxide //what the fuck is this? id = GAS_CO2 specific_heat = 30 name = "Carbon Dioxide" + powermix = 1 + heat_penalty = 0.1 + powerloss_inhibition = 1 breath_results = GAS_O2 breath_alert_info = list( not_enough_alert = list( @@ -37,6 +50,9 @@ fusion_power = 3 enthalpy = -393500 +/datum/gas/carbon_dioxide/generate_TLV() + return new/datum/tlv(-1, -1, 5, 10) + /datum/gas/plasma id = GAS_PLASMA specific_heat = 200 @@ -44,25 +60,22 @@ gas_overlay = "plasma" moles_visible = MOLES_GAS_VISIBLE flags = GAS_FLAG_DANGEROUS - // no fire info cause it has its own bespoke reaction for trit generation reasons + heat_penalty = 15 + transmit_modifier = 4 + powermix = 1 + fire_burn_rate = OXYGEN_BURN_RATE_BASE // named when plasma fires were the only fires, surely + fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST enthalpy = FIRE_PLASMA_ENERGY_RELEASED // 3000000, 3 megajoules, 3000 kj - -/datum/gas/water_vapor - id = GAS_H2O - specific_heat = 40 - name = "Water Vapor" - gas_overlay = "water_vapor" - moles_visible = MOLES_GAS_VISIBLE - fusion_power = 8 - breath_reagent = /datum/reagent/water - enthalpy = -241800 // FIRE_HYDROGEN_ENERGY_RELEASED is actually what this was supposed to be - -/datum/gas/hypernoblium - id = GAS_HYPERNOB - specific_heat = 2000 - name = "Hyper-noblium" - gas_overlay = "freon" - moles_visible = MOLES_GAS_VISIBLE + breath_alert_info = list( + not_enough_alert = list( + alert_category = "not_enough_tox", + alert_type = /atom/movable/screen/alert/not_enough_tox, + ), + too_much_alert = list( + alert_category = "too_much_tox", + alert_type = /atom/movable/screen/alert/too_much_tox, + ) + ) /datum/gas/nitrous_oxide id = GAS_NITROUS @@ -75,18 +88,38 @@ oxidation_rate = 0.5 oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100 enthalpy = 81600 + heat_resistance = 6 -/datum/gas/nitryl - id = GAS_NITRYL - specific_heat = 20 - name = "Nitryl" - gas_overlay = "nitryl" +/datum/gas/water_vapor + id = GAS_H2O + specific_heat = 40 + name = "Water Vapor" + gas_overlay = "water_vapor" moles_visible = MOLES_GAS_VISIBLE flags = GAS_FLAG_DANGEROUS - fusion_power = 15 - fire_products = list(GAS_N2 = 0.5) - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 - enthalpy = 33200 + fusion_power = 8 + heat_penalty = 8 + enthalpy = -241800 // FIRE_HYDROGEN_ENERGY_RELEASED is actually what this was supposed to be + powermix = 1 + breath_reagent = /datum/reagent/water + + +/datum/gas/pluoxium + id = GAS_PLUOXIUM + specific_heat = 80 + name = "Pluoxium" + fusion_power = 10 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 25 // it is VERY stable + oxidation_rate = 8 // when it can oxidize, it can oxidize a LOT + enthalpy = -2000000 // but it reduces the heat output a great deal (plasma fires add 3000000 per mole) + powermix = -1 + heat_penalty = -1 + transmit_modifier = -5 + heat_resistance = 3 + price = 6 + +/datum/gas/pluoxium/generate_TLV() + return new/datum/tlv(-1, -1, 5, 6) /datum/gas/tritium id = GAS_TRITIUM @@ -96,13 +129,36 @@ moles_visible = MOLES_GAS_VISIBLE flags = GAS_FLAG_DANGEROUS fusion_power = 1 - /* - these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons - fire_provides = list(GAS_H2O = 2) + powermix = 1 + heat_penalty = 10 + transmit_modifier = 30 + fire_products = list(GAS_H2O = 1) + enthalpy = 300000 fire_burn_rate = 2 - enthalpy = FIRE_HYDROGEN_ENERGY_RELEASED + fire_radiation_released = 50 // arbitrary number, basically 60 moles of trit burning will just barely start to harm you fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 - */ + price = 7 + +/datum/gas/nitryl + id = GAS_NITRYL + specific_heat = 20 + name = "Nitrogen dioxide" + gas_overlay = "nitryl" + moles_visible = MOLES_GAS_VISIBLE + flags = GAS_FLAG_DANGEROUS + fusion_power = 15 + fire_products = list(GAS_N2 = 0.5) + enthalpy = 33200 + oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50 + price = 3 + +/datum/gas/hypernoblium + id = GAS_HYPERNOB + specific_heat = 2000 + name = "Hyper-noblium" + gas_overlay = "freon" + moles_visible = MOLES_GAS_VISIBLE + price = 50 /datum/gas/bz id = GAS_BZ @@ -110,22 +166,21 @@ name = "BZ" flags = GAS_FLAG_DANGEROUS fusion_power = 8 + powermix = 1 + heat_penalty = 5 enthalpy = FIRE_CARBON_ENERGY_RELEASED // it is a mystery + transmit_modifier = -2 + radioactivity_modifier = 5 + price = 3 /datum/gas/stimulum id = GAS_STIMULUM specific_heat = 5 + odor = "the color blue" // fast + odor_strength = 10 name = "Stimulum" fusion_power = 7 - -/datum/gas/pluoxium - id = GAS_PLUOXIUM - specific_heat = 80 - name = "Pluoxium" - fusion_power = 10 - oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 1000 // it is VERY stable - oxidation_rate = 8 - enthalpy = -50000 // but it reduces the heat output a bit + price = 25 /datum/gas/constricted_plasma //NSV13 - words C++ monstermos expects 14 gas types to exist, we only had 13 id = "constricted_plasma" diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm index 4a6a5c83fe8..9d3178e139d 100644 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ b/code/modules/atmospherics/environmental/LINDA_fire.dm @@ -1,20 +1,27 @@ - +#define IGNITE_TURF_LOW_POWER 8 +#define IGNITE_TURF_HIGH_POWER 22 /atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) return null - +/turf/open/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + //if(prob(flammability * 100)) + // ignite_turf(rand(IGNITE_TURF_LOW_POWER,IGNITE_TURF_HIGH_POWER)) + return ..() /turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) return + /turf/open/hotspot_expose(exposed_temperature, exposed_volume, soh) if(!air) return - if (air.get_oxidation_power(exposed_temperature) < 0.5) + if (air.get_moles(GAS_O2) < 0.5 || air.get_moles(GAS_HYPERNOB) > REACTION_OPPRESSION_THRESHOLD) return - var/has_fuel = (air.get_moles(GAS_PLASMA) + air.get_moles(GAS_CONSTRICTED_PLASMA)) > 0.5 || air.get_moles(GAS_TRITIUM) > 0.5 || air.get_fuel_amount(exposed_temperature) > 0.5 //NSV13 - constricted plasma + + var/has_fuel = (air.get_moles(GAS_PLASMA) + air.get_moles(GAS_CONSTRICTED_PLASMA)) > 0.5 || air.get_moles(GAS_TRITIUM) > 0.5 + if(active_hotspot) if(soh) if(has_fuel) @@ -42,10 +49,9 @@ var/volume = 125 var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + var/just_spawned = TRUE var/bypassing = FALSE var/visual_update_tick = 0 - var/first_cycle = TRUE - /obj/effect/hotspot/Initialize(mapload, starting_volume, starting_temperature) . = ..() @@ -54,9 +60,9 @@ volume = starting_volume if(!isnull(starting_temperature)) temperature = starting_temperature - perform_exposure() + if(!perform_exposure()) + return INITIALIZE_HINT_QDEL setDir(pick(GLOB.cardinals)) - air_update_turf() var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) @@ -65,13 +71,17 @@ /obj/effect/hotspot/proc/perform_exposure() var/turf/open/location = loc if(!istype(location) || !(location.air)) - return + return FALSE + + //if(SEND_SIGNAL(location, COMSIG_TURF_HOTSPOT_EXPOSE) & SUPPRESS_FIRE) + // return FALSE + + if(location.active_hotspot != src) + qdel(location.active_hotspot) location.active_hotspot = src - bypassing = !first_cycle && volume > CELL_VOLUME*0.95 || location.air.return_temperature() > FUSION_TEMPERATURE_THRESHOLD - if(first_cycle) - first_cycle = FALSE + bypassing = !just_spawned && (volume > CELL_VOLUME*0.95) if(bypassing) volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE @@ -89,7 +99,7 @@ var/atom/AT = A if(!QDELETED(AT) && AT != src) // It's possible that the item is deleted in temperature_expose AT.fire_act(temperature, volume) - return + return TRUE /obj/effect/hotspot/proc/gauss_lerp(x, x1, x2) var/b = (x1 + x2) * 0.5 @@ -151,6 +161,10 @@ #define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5) /obj/effect/hotspot/process() + if(just_spawned) + just_spawned = FALSE + return + var/turf/open/location = loc if(!istype(location)) qdel(src) @@ -161,11 +175,15 @@ if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1)) qdel(src) return - if(!location.air || location.air.get_oxidation_power() < 0.5 || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM) && INSUFFICIENT(GAS_CONSTRICTED_PLASMA) && location.air.get_fuel_amount() < 0.5)) //NSV13 - constricted plasma + + //Not enough / nothing to burn + if(!location.air || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM)) && INSUFFICIENT(GAS_CONSTRICTED_PLASMA) || INSUFFICIENT(GAS_O2)) qdel(src) return - perform_exposure() + if(!perform_exposure()) + qdel(src) + return if(bypassing) icon_state = "3" @@ -234,3 +252,5 @@ light_range = LIGHT_RANGE_FIRE #undef INSUFFICIENT +#undef IGNITE_TURF_LOW_POWER +#undef IGNITE_TURF_HIGH_POWER diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm index c129cfdcd2b..5135cd6c413 100644 --- a/code/modules/atmospherics/environmental/LINDA_system.dm +++ b/code/modules/atmospherics/environmental/LINDA_system.dm @@ -18,74 +18,107 @@ /turf/open/CanAtmosPass(turf/T, vertical = FALSE) var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T) - var/opp = REVERSE_DIR(dir) + var/opposite_dir = REVERSE_DIR(dir) . = TRUE if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src))) . = FALSE if(blocks_air || T.blocks_air) . = FALSE + //This path is a bit weird, if we're just checking with ourselves no sense asking objects on the turf if (T == src) return . + + //Can't just return if false here, we need to set superconductivity for(var/obj/O in contents+T.contents) var/turf/other = (O.loc == src ? T : src) - if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other)))) - . = FALSE - if(O.BlockThermalConductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments + if(CANATMOSPASS(O, other, vertical)) + continue + . = FALSE + if(other.block_all_conductivity()) + conductivity_blocked_directions |= dir + T.conductivity_blocked_directions |= opposite_dir + return FALSE + //Superconductivity is a bitfield of directions we can't conduct with + //Yes this is really weird + conductivity_blocked_directions &= ~dir + T.conductivity_blocked_directions &= ~opposite_dir + +/turf/proc/update_conductivity(turf/T) + var/dir = get_dir_multiz(src, T) + var/opp = REVERSE_DIR(dir) + + if(T == src) + return + + //all these must be above zero for auxmos to even consider them + if(!thermal_conductivity || !heat_capacity || !T.thermal_conductivity || !T.heat_capacity) + conductivity_blocked_directions |= dir + T.conductivity_blocked_directions |= opp + return + + for(var/obj/O in contents+T.contents) + if(O.BlockThermalConductivity(opp)) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments conductivity_blocked_directions |= dir T.conductivity_blocked_directions |= opp - if(!.) - return . -/atom/movable/proc/BlockThermalConductivity() // Objects that don't let heat through. +/turf/proc/block_all_conductivity() + conductivity_blocked_directions |= NORTH | SOUTH | EAST | WEST | UP | DOWN + +/atom/movable/proc/BlockThermalConductivity(dir) // Objects that don't let heat through. return FALSE /turf/proc/ImmediateCalculateAdjacentTurfs() - var/canpass = CANATMOSPASS(src, src) - var/canvpass = CANVERTICALATMOSPASS(src, src) + var/canpass = CANATMOSPASS(src, src, FALSE) + + conductivity_blocked_directions = 0 + + var/src_contains_firelock = 1 + if(locate(/obj/machinery/door/firedoor) in src) + src_contains_firelock |= 2 + for(var/direction in GLOB.cardinals_multiz) var/turf/T = get_step_multiz(src, direction) if(!istype(T)) + conductivity_blocked_directions |= direction continue - if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) ) + + var/other_contains_firelock = 1 + if(locate(/obj/machinery/door/firedoor) in T) + other_contains_firelock |= 2 + + update_conductivity(T) + + if(canpass && isopenturf(T) && !(blocks_air || T.blocks_air) && (CANATMOSPASS(T, src, direction & (UP|DOWN)))) LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(T.atmos_adjacent_turfs) - atmos_adjacent_turfs[T] = ATMOS_ADJACENT_ANY - T.atmos_adjacent_turfs[src] = ATMOS_ADJACENT_ANY + atmos_adjacent_turfs[T] = other_contains_firelock | src_contains_firelock + T.atmos_adjacent_turfs[src] = src_contains_firelock else if (atmos_adjacent_turfs) atmos_adjacent_turfs -= T if (T.atmos_adjacent_turfs) T.atmos_adjacent_turfs -= src UNSETEMPTY(T.atmos_adjacent_turfs) - T.set_sleeping(T.blocks_air) - T.__update_auxtools_turf_adjacency_info(isspaceturf(T.get_z_base_turf()), -1) + T.__update_auxtools_turf_adjacency_info() UNSETEMPTY(atmos_adjacent_turfs) src.atmos_adjacent_turfs = atmos_adjacent_turfs - set_sleeping(blocks_air) - for(var/t in atmos_adjacent_turfs) - var/turf/open/T = t - for(var/obj/machinery/door/firedoor/FD in T) - FD.UpdateAdjacencyFlags() - for(var/obj/machinery/door/firedoor/FD in src) - FD.UpdateAdjacencyFlags() - __update_auxtools_turf_adjacency_info(isspaceturf(get_z_base_turf())) - -/turf/proc/ImmediateDisableAdjacency(disable_adjacent = TRUE) - if(disable_adjacent) - for(var/direction in GLOB.cardinals_multiz) - var/turf/T = get_step_multiz(src, direction) - if(!istype(T)) - continue - if (T.atmos_adjacent_turfs) - T.atmos_adjacent_turfs -= src - UNSETEMPTY(T.atmos_adjacent_turfs) - T.__update_auxtools_turf_adjacency_info(isspaceturf(T.get_z_base_turf()), -1) - LAZYCLEARLIST(atmos_adjacent_turfs) - __update_auxtools_turf_adjacency_info(isspaceturf(get_z_base_turf())) + __update_auxtools_turf_adjacency_info() -/turf/proc/set_sleeping(should_sleep) +/turf/proc/clear_adjacencies() + block_all_conductivity() + for(var/direction in GLOB.cardinals_multiz) + var/turf/T = get_step_multiz(src, direction) + if(!T) + continue + if (atmos_adjacent_turfs) + atmos_adjacent_turfs -= T + if (T.atmos_adjacent_turfs) + T.atmos_adjacent_turfs -= src + UNSETEMPTY(T.atmos_adjacent_turfs) -/turf/proc/__update_auxtools_turf_adjacency_info() + T.__update_auxtools_turf_adjacency_info() + LAZYNULL(atmos_adjacent_turfs) + __update_auxtools_turf_adjacency_info() //returns a list of adjacent turfs that can share air with this one. //alldir includes adjacent diagonal tiles that can share @@ -122,20 +155,19 @@ return adjacent_turfs -/atom/proc/air_update_turf(command = 0) - if(!isturf(loc) && command) - return +/atom/proc/air_update_turf() var/turf/T = get_turf(loc) - T.air_update_turf(command) + if(!T) + return + T.air_update_turf() -/turf/air_update_turf(command = 0) - if(command) - ImmediateCalculateAdjacentTurfs() +/turf/air_update_turf() + ImmediateCalculateAdjacentTurfs() /atom/movable/proc/move_update_air(turf/T) if(isturf(T)) - T.air_update_turf(1) - air_update_turf(1) + T.air_update_turf() + air_update_turf() /atom/proc/atmos_spawn_air(text) //because a lot of people loves to copy paste awful code lets just make an easy proc to spawn your plasma fires var/turf/open/T = get_turf(src) diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index c39cbcebe6a..3e432cb01c7 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -1,31 +1,49 @@ /turf //conductivity is divided by 10 when interacting with air for balance purposes var/thermal_conductivity = 0.05 + ///Amount of heat necessary to activate some atmos processes (there is a weird usage of this var because is compared directly to the temperature instead of heat energy) var/heat_capacity = 1 //list of open turfs adjacent to us var/list/atmos_adjacent_turfs - //bitfield of dirs in which we thermal conductivity is blocked + ///bitfield of dirs in which we thermal conductivity is blocked var/conductivity_blocked_directions = NONE - //used for mapping and for breathing while in walls (because that's a thing that needs to be accounted for...) - //string parsed by /datum/gas/proc/copy_from_turf + /** + * used for mapping and for breathing while in walls (because that's a thing that needs to be accounted for...) + * string parsed by /datum/gas/proc/copy_from_turf + * approximation of MOLES_O2STANDARD and MOLES_N2STANDARD pending byond allowing constant expressions to be embedded in constant strings + * If someone will place 0 of some gas there, SHIT WILL BREAK. Do not do that. + **/ var/initial_gas_mix = OPENTURF_DEFAULT_ATMOS - //approximation of MOLES_O2STANDARD and MOLES_N2STANDARD pending byond allowing constant expressions to be embedded in constant strings - // If someone will place 0 of some gas there, SHIT WILL BREAK. Do not do that. /turf/open //used for spacewind + ///Pressure difference between two turfs var/pressure_difference = 0 + ///Where the difference come from (from higher pressure to lower pressure) var/pressure_direction = 0 - var/turf/pressure_specific_target + ///Our gas mix var/datum/gas_mixture/turf/air + ///If there is an active hotspot on us store a reference to it here var/obj/effect/hotspot/active_hotspot - var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time + /// air will slowly revert to initial_gas_mix + var/planetary_atmos = FALSE + /// once our paired turfs are finished with all other shares, do one 100% share + /// exists so things like space can ask to take 100% of a tile's gas + var/run_later = FALSE + + ///gas IDs of current active gas overlays + var/list/atmos_overlay_types + /// How much fuel this open turf provides to turf fires, and how easily they can be ignited in the first place. Can be negative to make fires die out faster. + var/flammability = 0.3 + var/obj/effect/abstract/turf_fire/turf_fire + var/turf/pressure_specific_target - var/list/atmos_overlay_types //gas IDs of current active gas overlays +/turf/proc/should_conduct_to_space() + return get_z_base_turf() == /turf/open/space /turf/open/Initialize(mapload) if(!blocks_air) @@ -39,8 +57,6 @@ QDEL_NULL(active_hotspot) return ..() -/turf/proc/update_air_ref() - /////////////////GAS MIXTURE PROCS/////////////////// /turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air @@ -49,55 +65,34 @@ /turf/open/assume_air_moles(datum/gas_mixture/giver, moles) if(!giver) return FALSE - if(SSair.thread_running()) - var giver_moles = giver.total_moles() - if(giver_moles > 0) - SSair.deferred_airs += list(list(giver, air, moles / giver_moles)) - else - SSair.deferred_airs += list(list(giver, air, 0)) - else - giver.transfer_to(air, moles) - update_visuals() + giver.transfer_to(air, moles) + update_visuals() return TRUE /turf/open/assume_air_ratio(datum/gas_mixture/giver, ratio) if(!giver) return FALSE - if(SSair.thread_running()) - SSair.deferred_airs += list(list(giver, air, ratio)) - else - giver.transfer_ratio_to(air, ratio) - update_visuals() + giver.transfer_ratio_to(air, ratio) + update_visuals() return TRUE /turf/open/transfer_air(datum/gas_mixture/taker, moles) if(!taker || !return_air()) // shouldn't transfer from space return FALSE - if(SSair.thread_running()) - var air_moles = air.total_moles() - if(air_moles > 0) - SSair.deferred_airs += list(list(air, taker, moles / air_moles)) - else - SSair.deferred_airs += list(list(air, taker, 0)) - else - air.transfer_to(taker, moles) - update_visuals() + air.transfer_to(taker, moles) + update_visuals() return TRUE /turf/open/transfer_air_ratio(datum/gas_mixture/taker, ratio) if(!taker || !return_air()) return FALSE - if(SSair.thread_running()) - SSair.deferred_airs += list(list(air, taker, ratio)) - else - air.transfer_ratio_to(taker, ratio) - update_visuals() + air.transfer_ratio_to(taker, ratio) + update_visuals() return TRUE /turf/open/remove_air(amount) var/datum/gas_mixture/ours = return_air() var/datum/gas_mixture/removed = ours.remove(amount) - update_visuals() return removed /turf/open/remove_air_ratio(ratio) @@ -177,6 +172,7 @@ UNSETEMPTY(new_overlay_types) src.atmos_overlay_types = new_overlay_types +//called by auxmos, do not remove /turf/open/proc/set_visuals(list/new_overlay_types) if (atmos_overlay_types) for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added @@ -203,25 +199,14 @@ /turf/open/proc/equalize_pressure_in_zone(cyclenum) /turf/open/proc/consider_firelocks(turf/T2) - var/reconsider_adj = FALSE for(var/obj/machinery/door/firedoor/FD in T2) - if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, src) != FD.dir) - continue FD.emergency_pressure_stop() - reconsider_adj = TRUE for(var/obj/machinery/door/firedoor/FD in src) - if((FD.flags_1 & ON_BORDER_1) && get_dir(src, T2) != FD.dir) - continue FD.emergency_pressure_stop() - reconsider_adj = TRUE - if(reconsider_adj) - T2.ImmediateCalculateAdjacentTurfs() // We want those firelocks closed yesterday. /turf/proc/handle_decompression_floor_rip() - return - /turf/open/floor/handle_decompression_floor_rip(sum) - if(sum > 20 && prob(CLAMP(sum / 20, 0, 15))) + if(sum > 20 && prob(clamp(sum / 20, 0, 15))) if(floor_tile) new floor_tile(src) make_plating() @@ -256,18 +241,17 @@ M = thing if (!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired) M.experience_pressure_difference(pressure_difference * multiplier, pressure_direction, 0, pressure_specific_target) + //if(pressure_difference > 100) + // new /obj/effect/temp_visual/dir_setting/space_wind(src, pressure_direction, clamp(round(sqrt(pressure_difference) * 2), 10, 255)) /atom/movable/var/pressure_resistance = 10 /atom/movable/var/last_high_pressure_movement_air_cycle = 0 /atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0, throw_target) - set waitfor = FALSE - if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_PRESSURE_PUSH) & COMSIG_MOVABLE_BLOCKS_PRESSURE) - return - var/const/PROBABILITY_OFFSET = 40 var/const/PROBABILITY_BASE_PRECENT = 10 var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5) + set waitfor = 0 var/move_prob = 100 //NSV13 - depressurzation does not drag things upwards - caused infinite loops with objects being sucked out, then falling through openspace. if(direction == UP) @@ -277,14 +261,14 @@ if(pressure_resistance > 0) move_prob = (pressure_difference/pressure_resistance*PROBABILITY_BASE_PRECENT)-PROBABILITY_OFFSET move_prob += pressure_resistance_prob_delta - if(move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO)))) - var/move_force = max_force * CLAMP(move_prob, 0, 100) / 100 + if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO)))) + var/move_force = max_force * clamp(move_prob, 0, 100) / 100 if(move_force > 6000) // WALLSLAM HELL TIME OH BOY var/turf/throw_turf = get_ranged_target_turf(get_turf(src), direction, round(move_force / 2000)) if(throw_target && (get_dir(src, throw_target) & direction)) throw_turf = get_turf(throw_target) - var/throw_speed = CLAMP(round(move_force / 3000), 1, 10) + var/throw_speed = clamp(round(move_force / 3000), 1, 10) throw_at(throw_turf, move_force / 3000, throw_speed) else step(src, direction) diff --git a/code/modules/atmospherics/gasmixtures/auxgm.dm b/code/modules/atmospherics/gasmixtures/auxgm.dm index 25e58dd50e8..c37ba41694d 100644 --- a/code/modules/atmospherics/gasmixtures/auxgm.dm +++ b/code/modules/atmospherics/gasmixtures/auxgm.dm @@ -12,9 +12,8 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA // Also allows you to add new gases at runtime -/proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas - /datum/auxgm + var/done_initializing = FALSE var/list/datums = list() var/list/specific_heats = list() var/list/names = list() @@ -24,6 +23,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/list/ids = list() var/list/typepaths = list() var/list/fusion_powers = list() + var/list/TLV = list() var/list/breathing_classes = list() var/list/breath_results = list() var/list/breath_reagents = list() @@ -35,26 +35,50 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA var/list/enthalpies = list() var/list/fire_products = list() var/list/fire_burn_rates = list() - + var/list/supermatter = list() + var/list/groups_by_gas = list() + var/list/groups = list() + var/list/TLVs = list() + var/list/odors = list() + var/list/odor_strengths = list() + var/list/prices = list() /datum/gas var/id = "" var/specific_heat = 0 var/name = "" var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi + var/color = "#ffff" // Tints the overlay by this color. Use instead of gas_overlay, usually (but not necessarily). + var/odor = null // Odor string. Null means none; if not null, anyone who breathes the gas will smell it. + var/odor_strength = INFINITY // How strong the odor is; minimal partial pressure to smell, so lower = more. var/moles_visible = null var/flags = NONE //currently used by canisters + var/group = null // groups for scrubber/filter listing var/fusion_power = 0 // How much the gas destabilizes a fusion reaction var/breath_results = GAS_CO2 // what breathing this breathes out - var/breath_reagent = null // what breathing this adds to your reagents - var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold + var/datum/reagent/breath_reagent = null // what breathing this adds to your reagents + var/datum/reagent/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something + var/price = 0 // How much this gas is worth when sold, per mole. var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material var/fire_temperature = null // temperature above which gas may catch fire; null for none var/list/fire_products = null // what results when this gas is burned (oxidizer or fuel); null for none - var/enthalpy = 0 // how much energy is released per mole of fuel burned + var/enthalpy = 0 // Standard enthalpy of formation in joules, used for fires var/fire_burn_rate = 1 // how many moles are burned per product released + var/fire_radiation_released = 0 // How much radiation is released when this gas burns + var/powermix = 0 // how much this gas contributes to the supermatter's powermix ratio + var/heat_penalty = 0 // heat and waste penalty from having the supermatter crystal surrounded by this gas; negative numbers reduce + var/transmit_modifier = 0 // bonus to supermatter power generation (multiplicative, since it's % based, and divided by 10) + var/radioactivity_modifier = 0 // improves effect of transmit modifiers, must be from -10 to 10 + var/heat_resistance = 0 // makes the crystal more resistant against heat damage. + var/powerloss_inhibition = 0 // Reduces how much power the supermatter loses each tick + +/datum/gas/proc/generate_TLV() + if(flags & GAS_FLAG_DANGEROUS) + return new/datum/tlv/dangerous + else + return new/datum/tlv(-1, -1, 1000, 1000) /datum/gas/proc/breath(partial_pressure, light_threshold, heavy_threshold, moles, mob/living/carbon/C, obj/item/organ/lungs/lungs) // This is only called on gases with the GAS_FLAG_BREATH_PROC flag. When possible, do NOT use this-- @@ -67,11 +91,15 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA datums[g] = gas specific_heats[g] = gas.specific_heat names[g] = gas.name + TLVs[g] = gas.generate_TLV() if(gas.moles_visible) visibility[g] = gas.moles_visible overlays[g] = new /list(FACTOR_GAS_VISIBLE_MAX) for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX) - overlays[g][i] = new /obj/effect/overlay/gas(gas.gas_overlay, i * 255 / FACTOR_GAS_VISIBLE_MAX) + var/obj/effect/overlay/gas/overlay = new(gas.gas_overlay) + overlay.color = gas.color + overlay.alpha = i * 255 / FACTOR_GAS_VISIBLE_MAX + overlays[g][i] = overlay else visibility[g] = 0 overlays[g] = 0 @@ -100,10 +128,22 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA if(gas.fire_products) fire_products[g] = gas.fire_products enthalpies[g] = gas.enthalpy - + if(gas.group) + if(!(gas.group in groups)) + groups[gas.group] = list() + groups[gas.group] += g + groups_by_gas[g] = gas.group + if(gas.odor) + odor_strengths[g] = gas.odor_strength + odors[g] = gas.odor + if(gas.price) + prices[g] = gas.price _auxtools_register_gas(gas) - -/proc/finalize_gas_refs() + if(done_initializing) + for(var/r in SSair.gas_reactions) + var/datum/gas_reaction/R = r + R.init_reqs() + SSair.auxtools_update_reactions() /datum/auxgm/New() for(var/gas_path in subtypesof(/datum/gas)) @@ -112,8 +152,21 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA for(var/breathing_class_path in subtypesof(/datum/breathing_class)) var/datum/breathing_class/class = new breathing_class_path breathing_classes[breathing_class_path] = class + done_initializing = TRUE finalize_gas_refs() +/datum/auxgm/proc/get_by_flag(flag) + var/static/list/gases_by_flag + if(!gases_by_flag) + gases_by_flag = list() + if(!(flag in gases_by_flag)) + gases_by_flag += flag + gases_by_flag[flag] = list() + for(var/g in flags) + if(flags[g] & flag) + gases_by_flag[flag] += g + return gases_by_flag[flag] + GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) /obj/effect/overlay/gas @@ -124,7 +177,6 @@ GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new) appearance_flags = TILE_BOUND vis_flags = NONE -/obj/effect/overlay/gas/New(state, alph) +/obj/effect/overlay/gas/New(state) . = ..() icon_state = state - alpha = alph diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index ad06e761ccb..303a08fef5e 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -14,17 +14,15 @@ What are the archived variables for? var/initial_volume = CELL_VOLUME //liters var/list/reaction_results var/list/analyzer_results //used for analyzer feedback - not initialized until its used + // DON'T rename this, you'd also have to change the auxmos library var/_extools_pointer_gasmixture // Contains the index in the gas vector for this gas mixture in rust land. Don't. Touch. This. Var. GLOBAL_LIST_INIT(auxtools_atmos_initialized, FALSE) -/proc/auxtools_atmos_init() - /datum/gas_mixture/New(volume) if (!isnull(volume)) initial_volume = volume - AUXTOOLS_CHECK(AUXMOS) - if(!GLOB.auxtools_atmos_initialized && auxtools_atmos_init()) + if(!GLOB.auxtools_atmos_initialized && auxtools_atmos_init(GLOB.gas_data)) GLOB.auxtools_atmos_initialized = TRUE __gasmixture_register() reaction_results = new @@ -37,15 +35,15 @@ we use a hook instead */ /datum/gas_mixture/vv_edit_var(var_name, var_value) - if(var_name == "_extools_pointer_gasmixture") + if(var_name == NAMEOF(src, _extools_pointer_gasmixture)) return FALSE // please no. segfaults bad. - if(var_name == "gas_list_view_only") + if(var_name == NAMEOF(src, gas_list_view_only)) return FALSE return ..() /datum/gas_mixture/vv_get_var(var_name) . = ..() - if(var_name == "gas_list_view_only") + if(var_name == NAMEOF(src, gas_list_view_only)) var/list/dummy = get_gases() for(var/gas in dummy) dummy[gas] = get_moles(gas) @@ -113,9 +111,6 @@ we use a hook instead message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Changed volume to [volume].") set_volume(volume) -/datum/gas_mixture/proc/__gasmixture_unregister() -/datum/gas_mixture/proc/__gasmixture_register() - /proc/gas_types() var/list/L = subtypesof(/datum/gas) for(var/gt in L) @@ -123,51 +118,10 @@ we use a hook instead L[gt] = initial(G.specific_heat) return L -/datum/gas_mixture/proc/heat_capacity() //joules per kelvin - -/datum/gas_mixture/proc/partial_heat_capacity(gas_type) - -/datum/gas_mixture/proc/total_moles() - -/datum/gas_mixture/proc/return_pressure() //kilopascals - -/datum/gas_mixture/proc/return_temperature() //kelvins - -/datum/gas_mixture/proc/set_min_heat_capacity(n) -/datum/gas_mixture/proc/set_temperature(new_temp) -/datum/gas_mixture/proc/set_volume(new_volume) -/datum/gas_mixture/proc/get_moles(gas_type) -/datum/gas_mixture/proc/get_by_flag(flag) -/datum/gas_mixture/proc/set_moles(gas_type, moles) -/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, ratio, list/gases) -/datum/gas_mixture/proc/mark_immutable() -/datum/gas_mixture/proc/get_gases() -/datum/gas_mixture/proc/add(amt) -/datum/gas_mixture/proc/subtract(amt) -/datum/gas_mixture/proc/multiply(factor) -/datum/gas_mixture/proc/divide(factor) -/datum/gas_mixture/proc/get_last_share() -/datum/gas_mixture/proc/clear() - -/datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0) - set_moles(gas_type, clamp(get_moles(gas_type) + amt,0,INFINITY)) - -/datum/gas_mixture/proc/adjust_moles_temp(gas_type, amt, temperature) - -/datum/gas_mixture/proc/adjust_multi() - -/datum/gas_mixture/proc/return_volume() //liters - -/datum/gas_mixture/proc/thermal_energy() //joules - /datum/gas_mixture/proc/archive() //Update archived versions of variables //Returns: 1 in all cases -/datum/gas_mixture/proc/merge(datum/gas_mixture/giver) - //Merges all air from giver into self. Does NOT delete the giver. - //Returns: 1 if we are mutable, 0 otherwise - /datum/gas_mixture/proc/remove(amount) //Proportionally removes amount of gas from the gas_mixture //Returns: gas_mixture with the gases removed @@ -176,11 +130,6 @@ we use a hook instead //Removes amount of gas from the gas mixture by flag //Returns: gas_mixture with gases that match the flag removed -/datum/gas_mixture/proc/transfer_to(datum/gas_mixture/target, amount) - -/datum/gas_mixture/proc/transfer_ratio_to(datum/gas_mixture/target, ratio) - //Transfers ratio of gas to target. Equivalent to target.merge(remove_ratio(amount)) but faster. - /datum/gas_mixture/proc/remove_ratio(ratio) //Proportionally removes amount of gas from the gas_mixture //Returns: gas_mixture with the gases removed @@ -189,10 +138,6 @@ we use a hook instead //Creates new, identical gas mixture //Returns: duplicate gas mixture -/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample) - //Copies variables from sample - //Returns: 1 if we are mutable, 0 otherwise - /datum/gas_mixture/proc/copy_from_turf(turf/model) //Copies all gas info from the turf into the gas list along with temperature //Returns: 1 if we are mutable, 0 otherwise @@ -205,52 +150,18 @@ we use a hook instead //Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length //Returns: amount of gas exchanged (+ if sharer received) -/datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient) - //Performs temperature sharing calculations (via conduction) between two gas_mixtures assuming only 1 boundary length - //Returns: new temperature of the sharer - -/datum/gas_mixture/proc/compare(datum/gas_mixture/sample) - //Compares sample to self to see if within acceptable ranges that group processing may be enabled - //Returns: a string indicating what check failed, or "" if check passes - -/datum/gas_mixture/proc/react(turf/open/dump_location) - //Performs various reactions such as combustion or fusion (LOL) - //Returns: 1 if any reaction took place; 0 otherwise - -/datum/gas_mixture/proc/adjust_heat(amt) - //Adjusts the thermal energy of the gas mixture, rather than having to do the full calculation. - //Returns: null - -/datum/gas_mixture/proc/equalize_with(datum/gas_mixture/giver) - //Makes this mix have the same temperature and gas ratios as the giver, but with the same pressure, accounting for volume. - //Returns: null - -/datum/gas_mixture/proc/get_oxidation_power(temp) - //Gets how much oxidation this gas can do, optionally at a given temperature. - -/datum/gas_mixture/proc/get_fuel_amount(temp) - //Gets how much fuel for fires (not counting trit/plasma!) this gas has, optionally at a given temperature. - -/proc/equalize_all_gases_in_list(list/L) - //Makes every gas in the given list have the same pressure, temperature and gas proportions. - //Returns: null - -/datum/gas_mixture/proc/__remove_by_flag() - /datum/gas_mixture/remove_by_flag(flag, amount) var/datum/gas_mixture/removed = new type __remove_by_flag(removed, flag, amount) return removed -/datum/gas_mixture/proc/__remove() /datum/gas_mixture/remove(amount) var/datum/gas_mixture/removed = new type __remove(removed, amount) return removed -/datum/gas_mixture/proc/__remove_ratio() /datum/gas_mixture/remove_ratio(ratio) var/datum/gas_mixture/removed = new type __remove_ratio(removed, ratio) @@ -268,8 +179,6 @@ we use a hook instead parse_gas_string(model.initial_gas_mix) return 1 -/datum/gas_mixture/proc/__auxtools_parse_gas_string(gas_string) - /datum/gas_mixture/parse_gas_string(gas_string) return __auxtools_parse_gas_string(gas_string) /* diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 2637c2d9825..ef40db337ff 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -277,7 +277,7 @@ var/datum/tlv/cur_tlv data["environment_data"] = list() - var/pressure = environment.return_pressure() + var/pressure = environment?.return_pressure() cur_tlv = TLV["pressure"] data["environment_data"] += list(list( "name" = "Pressure", @@ -285,7 +285,7 @@ "unit" = "kPa", "danger_level" = cur_tlv.get_danger_level(pressure) )) - var/temperature = environment.return_temperature() + var/temperature = environment?.return_temperature() cur_tlv = TLV["temperature"] data["environment_data"] += list(list( "name" = "Temperature", @@ -293,17 +293,17 @@ "unit" = "K ([round(temperature - T0C, 0.1)]C)", "danger_level" = cur_tlv.get_danger_level(temperature) )) - var/total_moles = environment.total_moles() - var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume() - for(var/gas_id in environment.get_gases()) + var/total_moles = environment?.total_moles() + var/partial_pressure = R_IDEAL_GAS_EQUATION * environment?.return_temperature() / environment?.return_volume() + for(var/gas_id in environment?.get_gases()) if(!(gas_id in TLV)) // We're not interested in this gas, it seems. continue cur_tlv = TLV[gas_id] data["environment_data"] += list(list( "name" = GLOB.gas_data.names[gas_id], - "value" = environment.get_moles(gas_id) / total_moles * 100, + "value" = environment?.get_moles(gas_id) / total_moles * 100, "unit" = "%", - "danger_level" = cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure) + "danger_level" = cur_tlv.get_danger_level(environment?.get_moles(gas_id) * partial_pressure) )) if(!locked || user.has_unlimited_silicon_privilege) @@ -658,13 +658,15 @@ if((machine_stat & (NOPOWER|BROKEN)) || shorted) return - var/turf/location = get_turf(src) - if(!location) + if(!isopenturf(get_turf(src))) return var/datum/tlv/cur_tlv - var/datum/gas_mixture/environment = location.return_air() + var/datum/gas_mixture/environment = return_air() + if(!environment) + return + var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume() cur_tlv = TLV["pressure"] @@ -703,12 +705,12 @@ )) var/area/A = get_area(src) if(alert_level==2) - alert_signal.data["alert"] = "severe" + alert_signal.data["alert"] = ATMOS_ALARM_SEVERE A.set_vacuum_alarm_effect() else if (alert_level==1) - alert_signal.data["alert"] = "minor" + alert_signal.data["alert"] = ATMOS_ALARM_MINOR else if (alert_level==0) - alert_signal.data["alert"] = "clear" + alert_signal.data["alert"] = ATMOS_ALARM_CLEAR A.unset_vacuum_alarm_effect() frequency.post_signal(src, alert_signal, range = -1) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index e35d19313e9..26ecf61f19d 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -20,6 +20,10 @@ resistance_flags = FIRE_PROOF max_integrity = 200 obj_flags = CAN_BE_HIT | ON_BLUEPRINTS + ///Is the thing being rebuilt by SSair or not. Prevents list bloat + var/rebuilding = FALSE + ///If we should init and immediately start processing + var/init_processing = FALSE var/can_unwrench = 0 var/initialize_directions = 0 var/pipe_color @@ -28,6 +32,7 @@ var/static/list/iconsetids = list() var/static/list/pipeimages = list() + var/hide = TRUE var/image/pipe_vision_img = null @@ -39,7 +44,12 @@ var/on = FALSE /// whether it can be painted var/paintable = FALSE - var/interacts_with_air = FALSE + ///Can this be quick-toggled on and off using right click or ctrl-click? + var/quick_toggle = FALSE + +/obj/machinery/atmospherics/LateInitialize() + . = ..() + update_name() /obj/machinery/atmospherics/examine(mob/user) . = ..() @@ -56,21 +66,21 @@ nodes = new(device_type) if (!armor) armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70, "stamina" = 0) + init_processing = process ..() - if(process) - if(interacts_with_air) - SSair.atmos_air_machinery += src - else - SSair.atmos_machinery += src - SetInitDirections() + set_init_directions() + +/obj/machinery/atmospherics/Initialize(mapload) + if(init_processing) + SSair.start_processing_machine(src) + return ..() /obj/machinery/atmospherics/Destroy() for(var/i in 1 to device_type) - nullifyNode(i) + nullify_node(i) - SSair.atmos_machinery -= src - SSair.atmos_air_machinery -= src - SSair.pipenets_needing_rebuilt -= src + SSair.stop_processing_machine(src) + SSair.rebuild_queue -= src dropContents() if(pipe_vision_img) @@ -79,30 +89,62 @@ return ..() //return QDEL_HINT_FINDREFERENCE +/obj/machinery/atmospherics/proc/toggle_on(mob/user) + on = !on + var/msg = "was turned [on ? "on" : "off"] by [user ? key_name(user) : "a remote signal"]" + investigate_log(msg, "atmos") + investigate_log(msg, "supermatter") // yogs - make supermatter invest useful + update_appearance(UPDATE_ICON) + +/obj/machinery/atmospherics/attack_hand(mob/user, modifiers) + if(!quick_toggle) + return ..() + toggle_on(user) + return TRUE + +/obj/machinery/atmospherics/attack_ai(mob/user, modifiers) + if(quick_toggle && modifiers[RIGHT_CLICK]) + toggle_on(user) + return + return ..() + +/obj/machinery/atmospherics/CtrlClick(mob/user) + if(quick_toggle && can_interact(user)) + toggle_on(user) + return ..() + /obj/machinery/atmospherics/proc/destroy_network() return -/obj/machinery/atmospherics/proc/build_network() - // Called to build a network from this node +/obj/machinery/atmospherics/proc/rebuild_pipes() + var/list/targets = get_rebuild_targets() + rebuilding = FALSE + for(var/datum/pipeline/build_off as anything in targets) + build_off.build_pipeline(src) //This'll add to the expansion queue + +/obj/machinery/atmospherics/proc/get_rebuild_targets() return -/obj/machinery/atmospherics/proc/nullifyNode(i) - if(nodes[i]) - var/obj/machinery/atmospherics/N = nodes[i] - N.disconnect(src) - nodes[i] = null +/obj/machinery/atmospherics/proc/nullify_node(i) + if(!nodes[i]) + return + var/obj/machinery/atmospherics/N = nodes[i] + N.disconnect(src) + nodes[i] = null -/obj/machinery/atmospherics/proc/getNodeConnects() +/obj/machinery/atmospherics/proc/get_node_connects() var/list/node_connects = list() node_connects.len = device_type + var/init_directions = get_init_directions() for(var/i in 1 to device_type) - for(var/D in GLOB.cardinals) - if(D & GetInitDirections()) - if(D in node_connects) - continue - node_connects[i] = D - break + for(var/direction in GLOB.cardinals) + if(!(direction & init_directions)) + continue + if(direction in node_connects) + continue + node_connects[i] = direction + break return node_connects /obj/machinery/atmospherics/proc/normalize_cardinal_directions() @@ -113,9 +155,9 @@ setDir(EAST) //this is called just after the air controller sets up turfs -/obj/machinery/atmospherics/proc/atmosinit(list/node_connects) +/obj/machinery/atmospherics/proc/atmos_init(list/node_connects) if(!node_connects) //for pipes where order of nodes doesn't matter - node_connects = getNodeConnects() + node_connects = get_node_connects() for(var/i in 1 to device_type) for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[i])) @@ -124,66 +166,79 @@ break update_icon() -/obj/machinery/atmospherics/proc/setPipingLayer(new_layer) +/obj/machinery/atmospherics/proc/set_piping_layer(new_layer) piping_layer = (pipe_flags & PIPING_DEFAULT_LAYER_ONLY) ? PIPING_LAYER_DEFAULT : new_layer update_icon() +/obj/machinery/atmospherics/update_icon(updates=ALL) + . = ..() + update_layer() + /obj/machinery/atmospherics/proc/can_be_node(obj/machinery/atmospherics/target, iteration) return connection_check(target, piping_layer) //Find a connecting /obj/machinery/atmospherics in specified direction -/obj/machinery/atmospherics/proc/findConnecting(direction, prompted_layer) - for(var/obj/machinery/atmospherics/target in get_step(src, direction)) - if(target.initialize_directions & get_dir(target,src)) - if(connection_check(target, prompted_layer)) - return target +/obj/machinery/atmospherics/proc/find_connecting(direction, prompted_layer) + for(var/obj/machinery/atmospherics/target in get_step_multiz(src, direction)) + if(!(target.initialize_directions & get_dir(target,src))) + continue + if(connection_check(target, prompted_layer)) + return target /obj/machinery/atmospherics/proc/connection_check(obj/machinery/atmospherics/target, given_layer) - if(isConnectable(target, given_layer) && target.isConnectable(src, given_layer) && (target.initialize_directions & get_dir(target,src))) - return TRUE - return FALSE + if(!((initialize_directions & get_dir(src, target)) && (target.initialize_directions & get_dir(target, src)))) + return FALSE + + if(!is_connectable(target, given_layer) || !target.is_connectable(src, given_layer)) + return FALSE + + return TRUE -/obj/machinery/atmospherics/proc/isConnectable(obj/machinery/atmospherics/target, given_layer) +/obj/machinery/atmospherics/proc/is_connectable(obj/machinery/atmospherics/target, given_layer) if(isnull(given_layer)) given_layer = piping_layer + + if(target.loc == loc) + return FALSE + if((target.piping_layer == given_layer) || (target.pipe_flags & PIPING_ALL_LAYER)) return TRUE + return FALSE /obj/machinery/atmospherics/proc/pipeline_expansion() return nodes -/obj/machinery/atmospherics/proc/SetInitDirections() +/obj/machinery/atmospherics/proc/set_init_directions() return -/obj/machinery/atmospherics/proc/GetInitDirections() +/obj/machinery/atmospherics/proc/get_init_directions() return initialize_directions -/obj/machinery/atmospherics/proc/returnPipenet() +/obj/machinery/atmospherics/proc/return_pipenet() return -/obj/machinery/atmospherics/proc/returnPipenetAir() +/obj/machinery/atmospherics/proc/return_pipenet_airs() return -/obj/machinery/atmospherics/proc/setPipenet() +/obj/machinery/atmospherics/proc/set_pipenet() return -/obj/machinery/atmospherics/proc/replacePipenet() +/obj/machinery/atmospherics/proc/replace_pipenet() return /obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference) if(istype(reference, /obj/machinery/atmospherics/pipe)) var/obj/machinery/atmospherics/pipe/P = reference P.destroy_network() - if(nodes.len >= nodes.Find(reference)) // for some reason things can still be acted on even though they've been deleted this is a really fucky way of detecting that - nodes[nodes.Find(reference)] = null - update_icon() + nodes[nodes.Find(reference)] = null // for some reason things can still be acted on even though they've been deleted this is a really fucky way of detecting that + update_icon() /obj/machinery/atmospherics/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/pipe)) //lets you autodrop var/obj/item/pipe/pipe = W if(user.dropItemToGround(pipe)) - pipe.setPipingLayer(piping_layer) //align it with us + pipe.set_piping_layer(piping_layer) //align it with us return TRUE else return ..() @@ -192,10 +247,10 @@ if(!can_unwrench(user)) return ..() - var/turf/T = get_turf(src) - if (level==1 && isturf(T) && T.intact) - to_chat(user, "You must remove the plating first!") - return TRUE + //var/turf/T = get_turf(src) + /*if (level==1 && isturf(T) && T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE) + to_chat(user, span_warning("You must remove the plating first!")) + return TRUE*/ var/datum/gas_mixture/int_air = return_air() var/datum/gas_mixture/env_air = loc.return_air() @@ -204,13 +259,30 @@ var/unsafe_wrenching = FALSE var/internal_pressure = int_air.return_pressure()-env_air.return_pressure() - to_chat(user, "You begin to unfasten \the [src]...") + var/empty_pipe = FALSE + + if(istype(src, /obj/machinery/atmospherics/components)) + var/list/datum/gas_mixture/all_gas_mixes = return_analyzable_air() + var/empty_mixes = 0 + for(var/gas_mix_number in 1 to device_type) + var/datum/gas_mixture/gas_mix = all_gas_mixes[gas_mix_number] + if(!(gas_mix.total_moles() > 0)) + empty_mixes++ + if(empty_mixes == device_type) + empty_pipe = TRUE + + if(!(int_air.total_moles() > MINIMUM_MOLE_COUNT || unsafe_wrenching)) + empty_pipe = TRUE + + if(!empty_pipe) + to_chat(user, "You begin to unfasten \the [src]...") if (internal_pressure > 2*ONE_ATMOSPHERE) to_chat(user, "As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?") unsafe_wrenching = TRUE //Oh dear oh dear - if(I.use_tool(src, user, 20, volume=50)) + var/time_taken = empty_pipe ? 0 : 2 SECONDS + if(I.use_tool(src, user, time_taken, volume=50)) user.visible_message( \ "[user] unfastens \the [src].", \ "You unfasten \the [src].", \ @@ -258,42 +330,52 @@ if(!(flags_1 & NODECONSTRUCT_1)) if(can_unwrench) var/obj/item/pipe/stored = new construction_type(loc, null, dir, src) - stored.setPipingLayer(piping_layer) + stored.set_piping_layer(piping_layer) if(!disassembled) stored.obj_integrity = stored.max_integrity * 0.5 transfer_fingerprints_to(stored) ..() -/obj/machinery/atmospherics/proc/getpipeimage(iconset, iconstate, direction, col=rgb(255,255,255), piping_layer=3, trinary = FALSE) +/** + * Getter for piping layer shifted, pipe colored overlays + * + * Creates the image for the pipe underlay that all components use, called by get_pipe_underlay() in components_base.dm + * Arguments: + * * iconfile - path of the iconstate we are using (ex: 'icons/obj/machines/atmospherics/thermomachine.dmi') + * * iconstate - the image we are using inside the file + * * direction - the direction of our device + * * color - the color (in hex value, like #559900) that the pipe should have + * * piping_layer - the piping_layer the device is in, used inside PIPING_LAYER_SHIFT + * * trinary - if TRUE we also use PIPING_FORWARD_SHIFT on layer 1 and 5 for trinary devices (filters and mixers) + */ +/obj/machinery/atmospherics/proc/get_pipe_image(iconfile, iconstate, direction, color = rgb(200,200,200), piping_layer = 3, trinary = FALSE) //Add identifiers for the iconset - if(iconsetids[iconset] == null) - iconsetids[iconset] = num2text(iconsetids.len + 1) + if(iconsetids[iconfile] == null) + iconsetids[iconfile] = num2text(iconsetids.len + 1) //Generate a unique identifier for this image combination - var/identifier = iconsetids[iconset] + "_[iconstate]_[direction]_[col]_[piping_layer]" + var/identifier = iconsetids[iconfile] + "_[iconstate]_[direction]_[color]_[piping_layer]" if((!(. = pipeimages[identifier]))) var/image/pipe_overlay - pipe_overlay = . = pipeimages[identifier] = image(iconset, iconstate, dir = direction) - pipe_overlay.color = col + pipe_overlay = . = pipeimages[identifier] = image(iconfile, iconstate, dir = direction) + pipe_overlay.color = color PIPING_LAYER_SHIFT(pipe_overlay, piping_layer) - if(trinary && (piping_layer == 1 || piping_layer == 5)) + if(trinary == TRUE && (piping_layer == 1 || piping_layer == 5)) PIPING_FORWARD_SHIFT(pipe_overlay, piping_layer, 2) /obj/machinery/atmospherics/on_construction(obj_color, set_layer) if(can_unwrench) add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY) pipe_color = obj_color - setPipingLayer(set_layer) - var/turf/T = get_turf(src) - level = T.intact ? 2 : 1 - atmosinit() + set_piping_layer(set_layer) + atmos_init() var/list/nodes = pipeline_expansion() for(var/obj/machinery/atmospherics/A in nodes) - A.atmosinit() - A.addMember(src) - build_network() + A.atmos_init() + A.add_member(src) + SSair.add_to_rebuild_queue(src) /obj/machinery/atmospherics/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) if(istype(arrived, /mob/living)) @@ -316,14 +398,16 @@ if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug return - var/obj/machinery/atmospherics/target_move = findConnecting(direction, user.ventcrawl_layer) + var/obj/machinery/atmospherics/target_move = find_connecting(direction, user.ventcrawl_layer) if(target_move) if(target_move.can_crawl_through()) if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery)) + if(!do_after(user, 2 SECONDS, get_turf(target_move))) + return user.forceMove(target_move.loc) //handle entering and so on. user.visible_message("You hear something squeezing through the ducts...", "You climb out the ventilation system.") else - var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets() + var/list/pipenetdiff = return_pipenets() ^ target_move.return_pipenets() if(pipenetdiff.len) user.update_pipe_vision(target_move) user.forceMove(target_move) @@ -338,16 +422,16 @@ //PLACEHOLDER COMMENT FOR ME TO READD THE 1 (?) DS DELAY THAT WAS IMPLEMENTED WITH A... TIMER? /obj/machinery/atmospherics/AltClick(mob/living/L) - . = ..() if(istype(L) && is_type_in_list(src, GLOB.ventcrawl_machinery)) L.handle_ventcrawl(src) return + ..() /obj/machinery/atmospherics/proc/can_crawl_through() return TRUE -/obj/machinery/atmospherics/proc/returnPipenets() +/obj/machinery/atmospherics/proc/return_pipenets() return list() /obj/machinery/atmospherics/update_remote_sight(mob/user) @@ -358,7 +442,4 @@ return TRUE /obj/machinery/atmospherics/proc/update_layer() - layer = initial(layer) + (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE - -/obj/machinery/atmospherics/proc/paint(paint_color) - return FALSE + return diff --git a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm index 445d518a814..6fb1b5a3267 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/binary_devices.dm @@ -6,7 +6,7 @@ device_type = BINARY layer = GAS_PUMP_LAYER -/obj/machinery/atmospherics/components/binary/SetInitDirections() +/obj/machinery/atmospherics/components/binary/set_init_directions() switch(dir) if(NORTH, SOUTH) initialize_directions = NORTH|SOUTH @@ -17,9 +17,13 @@ update_icon() ..() -/obj/machinery/atmospherics/components/binary/getNodeConnects() +/obj/machinery/atmospherics/components/binary/get_node_connects() return list(turn(dir, 180), dir) ///Used by binary devices to set what the offset will be for each layer /obj/machinery/atmospherics/components/binary/proc/set_overlay_offset(pipe_layer) - return pipe_layer & 1 ? 1 : 2 + switch(pipe_layer) + if(1, 3, 5) + return 1 + if(2, 4) + return 2 diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm index 467773a1752..33ce59d2c43 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm @@ -69,7 +69,6 @@ last_pressure_delta = 0 /obj/machinery/atmospherics/components/binary/circulator/process_atmos() - ..() update_icon() /obj/machinery/atmospherics/components/binary/circulator/update_icon() @@ -99,35 +98,35 @@ if(node1) node1.disconnect(src) nodes[1] = null - nullifyPipenet(parents[1]) + nullify_pipenet(parents[1]) if(node2) node2.disconnect(src) nodes[2] = null - nullifyPipenet(parents[2]) + nullify_pipenet(parents[2]) if(anchored) - SetInitDirections() - atmosinit() + set_init_directions() + atmos_init() node1 = nodes[1] if(node1) - node1.atmosinit() - node1.addMember(src) + node1.atmos_init() + node1.add_member(src) node2 = nodes[2] if(node2) - node2.atmosinit() - node2.addMember(src) + node2.atmos_init() + node2.add_member(src) SSair.add_to_rebuild_queue(src) return TRUE -/obj/machinery/atmospherics/components/binary/circulator/SetInitDirections() +/obj/machinery/atmospherics/components/binary/circulator/set_init_directions() switch(dir) if(NORTH, SOUTH) initialize_directions = EAST|WEST if(EAST, WEST) initialize_directions = NORTH|SOUTH -/obj/machinery/atmospherics/components/binary/circulator/getNodeConnects() +/obj/machinery/atmospherics/components/binary/circulator/get_node_connects() if(flipped) return list(turn(dir, 270), turn(dir, 90)) return list(turn(dir, 90), turn(dir, 270)) @@ -168,7 +167,7 @@ generator.update_icon() generator = null -/obj/machinery/atmospherics/components/binary/circulator/setPipingLayer(new_layer) +/obj/machinery/atmospherics/components/binary/circulator/set_piping_layer(new_layer) ..() pixel_x = 0 pixel_y = 0 diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index 801065ab343..17dcbf184cd 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -18,8 +18,6 @@ level = 1 - interacts_with_air = TRUE - var/frequency = 0 var/id = null var/datum/radio_frequency/radio_connection @@ -47,7 +45,7 @@ /obj/machinery/atmospherics/components/binary/dp_vent_pump/update_icon_nopipes() cut_overlays() if(showpipe) - var/image/cap = getpipeimage(icon, "dpvent_cap", dir, piping_layer = piping_layer) + var/image/cap = get_pipe_image(icon, "dpvent_cap", dir, piping_layer = piping_layer) add_overlay(cap) if(welded) @@ -60,7 +58,6 @@ icon_state = pump_direction ? "vent_out" : "vent_in" /obj/machinery/atmospherics/components/binary/dp_vent_pump/process_atmos() - ..() if(welded || !is_operational || !isopenturf(loc)) return FALSE if(!on) @@ -85,11 +82,9 @@ loc.assume_air_moles(air1, transfer_moles) - air_update_turf() + var/datum/pipeline/parent1 = parents[1] - if(!parent1) - return parent1.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED else //external -> output @@ -103,13 +98,12 @@ if(moles_delta > 0) loc.transfer_air(air2, moles_delta) - air_update_turf() + var/datum/pipeline/parent2 = parents[2] parent2.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED - //Radio remote control - +//Radio remote control /obj/machinery/atmospherics/components/binary/dp_vent_pump/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency @@ -133,7 +127,7 @@ )) radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) -/obj/machinery/atmospherics/components/binary/dp_vent_pump/atmosinit() +/obj/machinery/atmospherics/components/binary/dp_vent_pump/atmos_init() ..() if(frequency) set_frequency(frequency) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 45b7fb4c556..37afa24a7ae 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -53,10 +53,9 @@ Passive gate is similar to the regular pump except: cut_overlays() icon_state = "passgate_off-[set_overlay_offset(piping_layer)]" if(on) - add_overlay(getpipeimage(icon, "passgate_on-[set_overlay_offset(piping_layer)]")) + add_overlay(get_pipe_image(icon, "passgate_on-[set_overlay_offset(piping_layer)]")) /obj/machinery/atmospherics/components/binary/passive_gate/process_atmos() - ..() if(!on) return @@ -125,7 +124,7 @@ Passive gate is similar to the regular pump except: if(.) update_icon() -/obj/machinery/atmospherics/components/binary/passive_gate/atmosinit() +/obj/machinery/atmospherics/components/binary/passive_gate/atmos_init() ..() if(frequency) set_frequency(frequency) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm index c136cb3b746..91fb80dfc48 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm @@ -62,8 +62,10 @@ if(air1.release_gas_to(air2, air1.return_pressure())) update_parents() is_gas_flowing = TRUE + else + is_gas_flowing = FALSE //unable to release gas (valve mechanism underpressurized, or etc) else - is_gas_flowing = FALSE + is_gas_flowing = FALSE //simply not enough pressure to activate update_icon_nopipes() /obj/machinery/atmospherics/components/binary/pressure_valve/proc/set_frequency(new_frequency) @@ -119,7 +121,7 @@ investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) update_icon() -/obj/machinery/atmospherics/components/binary/pressure_valve/atmosinit() +/obj/machinery/atmospherics/components/binary/pressure_valve/atmos_init() . = ..() if(frequency) set_frequency(frequency) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index d98d53852fd..fdd97d69a4e 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -55,7 +55,6 @@ icon_state = "pump_[on && is_operational ? "on" : "off"]-[set_overlay_offset(piping_layer)]" /obj/machinery/atmospherics/components/binary/pump/process_atmos() -// ..() if(!on || !is_operational) return var/datum/gas_mixture/air1 = airs[1] @@ -132,7 +131,7 @@ if(.) update_icon() -/obj/machinery/atmospherics/components/binary/pump/atmosinit() +/obj/machinery/atmospherics/components/binary/pump/atmos_init() ..() if(frequency) set_frequency(frequency) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm index b5ce94fc1a4..c7de9e0c0ba 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm @@ -49,7 +49,7 @@ if(coolant_temperature_delta > 0) var/input_capacity = remove_input.heat_capacity() - var/output_capacity = air_output.heat_capacity() + var/output_capacity = remove_output.heat_capacity() var/cooling_heat_amount = (heat_transfer_rate * 0.01) * coolant_temperature_delta * (input_capacity * output_capacity / (input_capacity + output_capacity)) remove_input.set_temperature(max(remove_input.return_temperature() - (cooling_heat_amount / input_capacity), TCMB)) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm index 5e0831ab2eb..d902e3b01fa 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm @@ -14,6 +14,8 @@ It's like a regular ol' straight pipe, but you can turn it on and off. interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_OPEN //Intentionally no allow_silicon flag pipe_flags = PIPING_CARDINAL_AUTONORMALIZE + custom_reconciliation = TRUE + var/frequency = 0 var/id = null @@ -34,6 +36,15 @@ It's like a regular ol' straight pipe, but you can turn it on and off. parents[2].update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED . = ..() +// This is what handles the actual functionality of combining 2 pipenets when the valve is open +// Basically when a pipenet updates it will consider both sides to be the same for the purpose of the gas update +/obj/machinery/atmospherics/components/binary/valve/return_pipenets_for_reconcilation(datum/pipeline/requester) + . = ..() + if(!on) + return + . |= parents[1] + . |= parents[2] + /obj/machinery/atmospherics/components/binary/valve/update_icon_nopipes(animation = FALSE) normalize_cardinal_directions() if(animation) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index d956e43dd6a..f461c56902c 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -54,7 +54,6 @@ icon_state = "volpump_[on && is_operational ? "on" : "off"]-[set_overlay_offset(piping_layer)]" /obj/machinery/atmospherics/components/binary/volume_pump/process_atmos() -// ..() if(!on || !is_operational) return @@ -77,7 +76,6 @@ if(istype(T)) var/datum/gas_mixture/leaked = air1.remove_ratio(VOLUME_PUMP_LEAK_AMOUNT) T.assume_air(leaked) - T.air_update_turf() var/transfer_ratio = transfer_rate / air1.return_volume() air1.transfer_ratio_to(air2,transfer_ratio) @@ -125,7 +123,7 @@ data["max_rate"] = round(MAX_TRANSFER_RATE) return data -/obj/machinery/atmospherics/components/binary/volume_pump/atmosinit() +/obj/machinery/atmospherics/components/binary/volume_pump/atmos_init() ..() set_frequency(frequency) diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index cab40dbcee9..78f027bc452 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -7,7 +7,14 @@ var/shift_underlay_only = TRUE //Layering only shifts underlay? var/list/datum/pipeline/parents + ///If this is queued for a rebuild this var signifies whether parents should be updated after it's done + var/update_parents_after_rebuild = FALSE + ///Stores the gasmix for each node, used in components var/list/datum/gas_mixture/airs + ///Handles whether the custom reconcilation handling should be used + var/custom_reconciliation = FALSE + + var/startingvolume = 200 /obj/machinery/atmospherics/components/New() parents = new(device_type) @@ -16,8 +23,11 @@ ..() for(var/i in 1 to device_type) - var/datum/gas_mixture/A = new(200) - airs[i] = A + if(airs[i]) + continue + var/datum/gas_mixture/component_mixture = new + component_mixture.set_volume(startingvolume) + airs[i] = component_mixture // Iconnery @@ -58,71 +68,79 @@ /obj/machinery/atmospherics/components/proc/get_pipe_underlay(state, dir, color = null) if(color) - . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color, piping_layer = shift_underlay_only ? piping_layer : 3) + . = get_pipe_image('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, color, piping_layer = shift_underlay_only ? piping_layer : 3) else - . = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, piping_layer = shift_underlay_only ? piping_layer : 3) + . = get_pipe_image('icons/obj/atmospherics/components/binary_devices.dmi', state, dir, piping_layer = shift_underlay_only ? piping_layer : 3) // Pipenet stuff; housekeeping -/obj/machinery/atmospherics/components/nullifyNode(i) +/obj/machinery/atmospherics/components/nullify_node(i) // Every node has a parent pipeline and an air associated with it, but we need to accomdate for edge cases like init dir cache building... if(parents[i]) - nullifyPipenet(parents[i]) - if(airs[i]) - QDEL_NULL(airs[i]) - ..() + nullify_pipenet(parents[i]) + airs[i] = null + return ..() /obj/machinery/atmospherics/components/on_construction() ..() update_parents() -/obj/machinery/atmospherics/components/build_network() - for(var/i in 1 to device_type) - if(QDELETED(parents[i])) - parents[i] = new /datum/pipeline() - var/datum/pipeline/P = parents[i] - P.build_pipeline(src) +/obj/machinery/atmospherics/components/rebuild_pipes() + . = ..() + if(update_parents_after_rebuild) + update_parents() -/obj/machinery/atmospherics/components/proc/nullifyPipenet(datum/pipeline/reference) +/obj/machinery/atmospherics/components/get_rebuild_targets() + var/list/to_return = list() + for(var/i in 1 to device_type) + if(parents[i]) + continue + parents[i] = new /datum/pipeline() + to_return += parents[i] + return to_return + +/** + * Called by nullify_node(), used to remove the pipeline the component is attached to + * Arguments: + * * -reference: the pipeline the component is attached to + */ +/obj/machinery/atmospherics/components/proc/nullify_pipenet(datum/pipeline/reference) if(!reference) - CRASH("nullifyPipenet(null) called by [type] on [COORD(src)]") - var/i = parents.Find(reference) - reference.other_airs -= airs[i] - reference.other_atmosmch -= src - /** - * We explicitly qdel pipeline when this particular pipeline - * is projected to have no member and cause GC problems. - * We have to do this because components don't qdel pipelines - * while pipes must and will happily wreck and rebuild everything again - * every time they are qdeleted. - */ - if(!(reference.other_atmosmch.len || reference.members.len || QDESTROYING(reference))) + CRASH("nullify_pipenet(null) called by [type] on [COORD(src)]") + + for (var/i in 1 to parents.len) + if (parents[i] == reference) + reference.other_airs -= airs[i] // Disconnects from the pipeline side + parents[i] = null // Disconnects from the machinery side. + + reference.other_atmos_machines -= src + + if(!length(reference.other_atmos_machines) && !length(reference.members)) + if(QDESTROYING(reference)) + CRASH("nullify_pipenet() called on qdeleting [reference]") qdel(reference) - parents[i] = null // We should return every air sharing a parent -/obj/machinery/atmospherics/components/returnPipenetAir(datum/pipeline/reference) - for(var/i in 1 to device_type) - if(parents[i] == reference) - if(.) - if(!islist(.)) - . = list(.) - . += airs[i] - else - . = airs[i] +/obj/machinery/atmospherics/components/return_pipenet_airs(datum/pipeline/reference) + var/list/returned_air = list() + + for (var/i in 1 to parents.len) + if (parents[i] == reference) + returned_air += airs[i] + return returned_air /obj/machinery/atmospherics/components/pipeline_expansion(datum/pipeline/reference) if(reference) return list(nodes[parents.Find(reference)]) return ..() -/obj/machinery/atmospherics/components/setPipenet(datum/pipeline/reference, obj/machinery/atmospherics/A) +/obj/machinery/atmospherics/components/set_pipenet(datum/pipeline/reference, obj/machinery/atmospherics/A) parents[nodes.Find(A)] = reference -/obj/machinery/atmospherics/components/returnPipenet(obj/machinery/atmospherics/A = nodes[1]) //returns parents[1] if called without argument +/obj/machinery/atmospherics/components/return_pipenet(obj/machinery/atmospherics/A = nodes[1]) //returns parents[1] if called without argument return parents[nodes.Find(A)] -/obj/machinery/atmospherics/components/replacePipenet(datum/pipeline/Old, datum/pipeline/New) +/obj/machinery/atmospherics/components/replace_pipenet(datum/pipeline/Old, datum/pipeline/New) parents[parents.Find(Old)] = New /obj/machinery/atmospherics/components/unsafe_pressure_release(var/mob/user, var/pressures) @@ -143,7 +161,6 @@ for(var/i in 1 to device_type) var/datum/gas_mixture/air = airs[i] T.assume_air_moles(air, shared_loss) - air_update_turf(1) /obj/machinery/atmospherics/components/proc/safe_input(var/title, var/text, var/default_set) var/new_value = input(usr,text,title,default_set) as num @@ -153,20 +170,34 @@ // Helpers +/** + * Called in most atmos processes and gas handling situations, update the parents pipelines of the devices connected to the source component + * This way gases won't get stuck + */ /obj/machinery/atmospherics/components/proc/update_parents() + if(!SSair.initialized) + return + if(rebuilding) + update_parents_after_rebuild = TRUE + return for(var/i in 1 to device_type) var/datum/pipeline/parent = parents[i] if(!parent) - //WARNING("Component is missing a pipenet! Rebuilding...") - //At pre-SSair_rebuild_pipenets times, not having a parent wasn't supposed to happen + WARNING("Component is missing a pipenet! Rebuilding...") SSair.add_to_rebuild_queue(src) - continue - parent.update = PIPENET_UPDATE_STATUS_RECONCILE_NEEDED + else + parent.update = TRUE -/obj/machinery/atmospherics/components/returnPipenets() +/obj/machinery/atmospherics/components/return_pipenets() . = list() for(var/i in 1 to device_type) - . += returnPipenet(nodes[i]) + . += return_pipenet(nodes[i]) + +/obj/machinery/atmospherics/components/proc/return_pipenets_for_reconcilation(datum/pipeline/requester) + return list() + +/obj/machinery/atmospherics/components/proc/return_airs_for_reconcilation(datum/pipeline/requester) + return list() // UI Stuff @@ -178,5 +209,30 @@ // Tool acts +/obj/machinery/atmospherics/components/proc/disconnect_nodes() + for(var/i in 1 to device_type) + var/obj/machinery/atmospherics/node = nodes[i] + if(node) + if(src in node.nodes) //Only if it's actually connected. On-pipe version would is one-sided. + node.disconnect(src) + nodes[i] = null + if(parents[i]) + nullify_pipenet(parents[i]) + +/obj/machinery/atmospherics/components/proc/connect_nodes() + atmos_init() + for(var/i in 1 to device_type) + var/obj/machinery/atmospherics/node = nodes[i] + if(node) + node.atmos_init() + node.add_member(src) + SSair.add_to_rebuild_queue(src) + +/obj/machinery/atmospherics/components/proc/change_nodes_connection(disconnect) + if(disconnect) + disconnect_nodes() + return + connect_nodes() + /obj/machinery/atmospherics/components/return_analyzable_air() return airs diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 99b6e6dd0f6..6a3abec2f88 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -47,13 +47,13 @@ for(var/direction in GLOB.cardinals) if(!(direction & initialize_directions)) continue - var/obj/machinery/atmospherics/node = findConnecting(direction) + var/obj/machinery/atmospherics/node = find_connecting(direction) var/image/cap if(node) - cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE) + cap = get_pipe_image(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE) else - cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE) + cap = get_pipe_image(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE) add_overlay(cap) @@ -102,7 +102,7 @@ update_parents() -/obj/machinery/atmospherics/components/trinary/filter/atmosinit() +/obj/machinery/atmospherics/components/trinary/filter/atmos_init() set_frequency(frequency) return ..() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 0bd377ae165..dc0d87aded1 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -39,13 +39,13 @@ for(var/direction in GLOB.cardinals) if(!(direction & initialize_directions)) continue - var/obj/machinery/atmospherics/node = findConnecting(direction) + var/obj/machinery/atmospherics/node = find_connecting(direction) var/image/cap if(node) - cap = getpipeimage(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE) + cap = get_pipe_image(icon, "cap", direction, node.pipe_color, piping_layer = piping_layer, trinary = TRUE) else - cap = getpipeimage(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE) + cap = get_pipe_image(icon, "cap", direction, piping_layer = piping_layer, trinary = TRUE) add_overlay(cap) @@ -68,7 +68,6 @@ airs[3] = air3 /obj/machinery/atmospherics/components/trinary/mixer/process_atmos() - ..() if(!on || !(nodes[1] && nodes[2] && nodes[3]) && !is_operational) return diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm index 01b89560d68..d96b7244eb4 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_devices.dm @@ -9,7 +9,7 @@ var/flipped = FALSE -/obj/machinery/atmospherics/components/trinary/SetInitDirections() +/obj/machinery/atmospherics/components/trinary/set_init_directions() switch(dir) if(NORTH) initialize_directions = EAST|NORTH|SOUTH @@ -24,7 +24,7 @@ Housekeeping and pipe network stuff */ -/obj/machinery/atmospherics/components/trinary/getNodeConnects() +/obj/machinery/atmospherics/components/trinary/get_node_connects() //Mixer: //1 and 2 is input diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index e3ce6063fdb..639785a2d5d 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -79,6 +79,16 @@ /obj/machinery/atmospherics/components/unary/cryo_cell/Destroy() QDEL_NULL(radio) QDEL_NULL(beaker) + ///Take the turf the cryotube is on + var/turf/T = get_turf(src) + if(T) + ///Take the air composition of the turf + var/datum/gas_mixture/env = T.return_air() + ///Take the air composition inside the cryotube + var/datum/gas_mixture/air1 = airs[1] + env.merge(air1) + T.air_update_turf() + return ..() /obj/machinery/atmospherics/components/unary/cryo_cell/contents_explosion(severity, target) @@ -174,6 +184,8 @@ open_machine() /obj/machinery/atmospherics/components/unary/cryo_cell/process(delta_time) + ..() + if(!on) return @@ -228,8 +240,6 @@ return 1 /obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos() - ..() - if(!on) return @@ -476,17 +486,18 @@ /obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W) . = ..() if(.) - SetInitDirections() + set_init_directions() var/obj/machinery/atmospherics/node = nodes[1] if(node) node.disconnect(src) nodes[1] = null - nullifyPipenet(parents[1]) - atmosinit() + if(parents[1]) + nullify_pipenet(parents[1]) + atmos_init() node = nodes[1] if(node) - node.atmosinit() - node.addMember(src) + node.atmos_init() + node.add_member(src) SSair.add_to_rebuild_queue(src) #undef CRYOMOBS diff --git a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm index 0021cebdc80..6b6e4e30b0f 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm @@ -32,7 +32,7 @@ icon_state = "he0" PIPING_LAYER_SHIFT(src, piping_layer) -/obj/machinery/atmospherics/components/unary/heat_exchanger/atmosinit() +/obj/machinery/atmospherics/components/unary/heat_exchanger/atmos_init() var/obj/machinery/atmospherics/components/unary/heat_exchanger/partner = partner_ref?.resolve() if(!partner) partner_ref = null diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 5304d18c9e2..424c06421ce 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -19,7 +19,6 @@ var/datum/radio_frequency/radio_connection level = 1 - interacts_with_air = TRUE layer = GAS_SCRUBBER_LAYER pipe_state = "injector" @@ -50,7 +49,7 @@ cut_overlays() if(showpipe) // everything is already shifted so don't shift the cap - add_overlay(getpipeimage(icon, "inje_cap", initialize_directions)) + add_overlay(get_pipe_image(icon, "inje_cap", initialize_directions)) if(!nodes[1] || !on || !is_operational) icon_state = "inje_off" @@ -64,8 +63,6 @@ update_icon() /obj/machinery/atmospherics/components/unary/outlet_injector/process_atmos() - ..() - injecting = 0 if(!on || !is_operational || !isopenturf(loc)) @@ -76,8 +73,6 @@ if(air_contents != null) if(air_contents.return_temperature() > 0) loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume()) - air_update_turf() - update_parents() /obj/machinery/atmospherics/components/unary/outlet_injector/proc/inject() @@ -116,7 +111,7 @@ )) radio_connection.post_signal(src, signal) -/obj/machinery/atmospherics/components/unary/outlet_injector/atmosinit() +/obj/machinery/atmospherics/components/unary/outlet_injector/atmos_init() set_frequency(frequency) broadcast_status() ..() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm index ff0c95a105b..84acf70d180 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -6,7 +6,6 @@ can_unwrench = TRUE level = 1 - interacts_with_air = TRUE layer = GAS_SCRUBBER_LAYER shift_underlay_only = FALSE @@ -15,7 +14,7 @@ /obj/machinery/atmospherics/components/unary/passive_vent/update_icon_nopipes() cut_overlays() if(showpipe) - var/image/cap = getpipeimage(icon, "vent_cap", initialize_directions) + var/image/cap = get_pipe_image(icon, "vent_cap", initialize_directions) add_overlay(cap) icon_state = "passive_vent" @@ -38,7 +37,6 @@ active = internal.temperature_share(external, OPEN_HEAT_TRANSFER_COEFFICIENT) || active if(active) - air_update_turf() update_parents() /obj/machinery/atmospherics/components/unary/passive_vent/can_crawl_through() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm index 2fd8dfef583..9c15a8c8632 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm @@ -13,6 +13,7 @@ pipe_flags = PIPING_ONE_PER_TURF pipe_state = "connector" + custom_reconciliation = TRUE var/obj/machinery/portable_atmospherics/connected_device @@ -26,10 +27,21 @@ connected_device.disconnect() return ..() +/obj/machinery/atmospherics/components/unary/portables_connector/return_airs_for_reconcilation(datum/pipeline/requester) + . = ..() + if(!connected_device) + return + if(istype(connected_device, /obj/mecha)) + var/obj/mecha/connected_mech = connected_device + if(connected_mech.internal_tank) + . += connected_mech.internal_tank.return_air() + else + . += connected_device.return_air() + /obj/machinery/atmospherics/components/unary/portables_connector/update_icon_nopipes() icon_state = "connector" if(showpipe) - var/image/cap = getpipeimage(icon, "connector_cap", initialize_directions) + var/image/cap = get_pipe_image(icon, "connector_cap", initialize_directions) add_overlay(cap) /obj/machinery/atmospherics/components/unary/portables_connector/process_atmos() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm index 3ca9fd77e69..1af388e8bc5 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm @@ -14,23 +14,23 @@ var/volume = 10000 //in liters var/gas_type = null -/obj/machinery/atmospherics/components/unary/tank/New() - ..() +/obj/machinery/atmospherics/components/unary/tank/Initialize(mapload) + . = ..() var/datum/gas_mixture/air_contents = airs[1] air_contents.set_volume(volume) air_contents.set_temperature(T20C) if(gas_type) air_contents.set_moles(gas_type, AIR_CONTENTS) name = "[name] ([GLOB.gas_data.names[gas_type]])" - setPipingLayer(piping_layer) + set_piping_layer(piping_layer) /obj/machinery/atmospherics/components/unary/tank/air icon_state = "grey" name = "pressure tank (Air)" -/obj/machinery/atmospherics/components/unary/tank/air/New() - ..() +/obj/machinery/atmospherics/components/unary/tank/air/Initialize(mapload) + . = ..() var/datum/gas_mixture/air_contents = airs[1] air_contents.set_moles(GAS_O2, AIR_CONTENTS * 0.2) air_contents.set_moles(GAS_N2, AIR_CONTENTS * 0.8) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index cc41313cbc3..ee4f859db78 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -82,12 +82,12 @@ else icon_state = icon_state_off - add_overlay(getpipeimage(icon, "pipe", dir, , piping_layer)) + add_overlay(get_pipe_image(icon, "pipe", dir, , piping_layer)) /obj/machinery/atmospherics/components/unary/thermomachine/update_icon_nopipes() cut_overlays() if(showpipe) - add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions)) + add_overlay(get_pipe_image(icon, "scrub_cap", initialize_directions)) /obj/machinery/atmospherics/components/unary/thermomachine/examine(mob/user) . = ..() @@ -108,7 +108,6 @@ balloon_alert(user, "You set the target temperature to [target_temperature] K.") /obj/machinery/atmospherics/components/unary/thermomachine/process_atmos() - ..() if(!is_operational || !on || !nodes[1]) //if it has no power or its switched off, dont process atmos return var/datum/gas_mixture/air_contents = airs[1] @@ -136,6 +135,7 @@ /obj/machinery/atmospherics/components/unary/thermomachine/attackby(obj/item/I, mob/user, params) if(!on) if(default_deconstruction_screwdriver(user, icon_state_open, icon_state_off, I)) + change_pipe_connection(panel_open) return if(default_change_direction_wrench(user, I)) return @@ -146,21 +146,8 @@ /obj/machinery/atmospherics/components/unary/thermomachine/default_change_direction_wrench(mob/user, obj/item/I) if(!..()) return FALSE - SetInitDirections() - var/obj/machinery/atmospherics/node = nodes[1] - if(node) - node.disconnect(src) - nodes[1] = null - //Sometimes this gets called more than once per atmos tick; i.e. before the incoming build_network call by SSAIR_REBUILD_PIPENETS, so we check this here. - if(parents[1]) - nullifyPipenet(parents[1]) - - atmosinit() - node = nodes[1] - if(node) - node.atmosinit() - node.addMember(src) - SSair.add_to_rebuild_queue(src) + set_init_directions() + update_icon(UPDATE_ICON) return TRUE /obj/machinery/atmospherics/components/unary/thermomachine/ui_status(mob/user) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm index b3a8f76aaef..208053e4e6c 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm @@ -12,7 +12,7 @@ pipe_interference_group = "atmos-[piping_layer]"\ ) -/obj/machinery/atmospherics/components/unary/SetInitDirections() +/obj/machinery/atmospherics/components/unary/set_init_directions() initialize_directions = dir /obj/machinery/atmospherics/components/unary/on_construction() @@ -26,3 +26,27 @@ /obj/machinery/atmospherics/components/unary/proc/assign_uid_vents() uid = num2text(gl_uid++) return uid + +/obj/machinery/atmospherics/components/unary/proc/change_pipe_connection(disconnect) + if(disconnect) + disconnect_pipes() + return + connect_pipes() + +/obj/machinery/atmospherics/components/unary/proc/connect_pipes() + var/obj/machinery/atmospherics/node1 = nodes[1] + atmos_init() + node1 = nodes[1] + if(node1) + node1.atmos_init() + node1.add_member(src) + SSair.add_to_rebuild_queue(src) + +/obj/machinery/atmospherics/components/unary/proc/disconnect_pipes() + var/obj/machinery/atmospherics/node1 = nodes[1] + if(node1) + if(src in node1.nodes) //Only if it's actually connected. On-pipe version would is one-sided. + node1.disconnect(src) + nodes[1] = null + if(parents[1]) + nullify_pipenet(parents[1]) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 033dfc0a566..793739b90cd 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -18,8 +18,6 @@ layer = GAS_SCRUBBER_LAYER shift_underlay_only = FALSE - interacts_with_air = TRUE - var/pump_direction = RELEASING var/pressure_checks = EXT_BOUND @@ -58,7 +56,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/update_icon_nopipes() cut_overlays() if(showpipe) - var/image/cap = getpipeimage(icon, "vent_cap", initialize_directions) + var/image/cap = get_pipe_image(icon, "vent_cap", initialize_directions) add_overlay(cap) else PIPING_LAYER_SHIFT(src, PIPING_LAYER_DEFAULT) @@ -93,7 +91,6 @@ icon_state = "vent_in" /obj/machinery/atmospherics/components/unary/vent_pump/process_atmos() - ..() if(!is_operational || !isopenturf(loc)) return if(!nodes[1]) @@ -104,7 +101,7 @@ var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/environment = loc.return_air() - if(environment == null) + if(!environment) return var/environment_pressure = environment.return_pressure() @@ -122,7 +119,6 @@ var/transfer_moles = pressure_delta*environment.return_volume()/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION) loc.assume_air_moles(air_contents, transfer_moles) - air_update_turf() else // external -> internal if(environment.return_pressure() > 0) @@ -135,7 +131,6 @@ if(moles_delta > 0) loc.transfer_air(air_contents, moles_delta) - air_update_turf() update_parents() //Radio remote control @@ -173,7 +168,7 @@ radio_connection.post_signal(src, signal, radio_filter_out) -/obj/machinery/atmospherics/components/unary/vent_pump/atmosinit() +/obj/machinery/atmospherics/components/unary/vent_pump/atmos_init() //some vents work his own spesial way radio_filter_in = frequency==FREQ_ATMOS_CONTROL?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==FREQ_ATMOS_CONTROL?(RADIO_TO_AIRALARM):null diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 1880093fc48..aed74558ab7 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -15,8 +15,6 @@ layer = GAS_SCRUBBER_LAYER shift_underlay_only = FALSE - interacts_with_air = TRUE - var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing var/filter_types = list(GAS_CO2, GAS_BZ) @@ -66,7 +64,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes() cut_overlays() if(showpipe) - var/image/cap = getpipeimage(icon, "scrub_cap", initialize_directions) + var/image/cap = get_pipe_image(icon, "scrub_cap", initialize_directions) add_overlay(cap) else PIPING_LAYER_SHIFT(src, PIPING_LAYER_DEFAULT) @@ -122,7 +120,7 @@ return TRUE -/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit() +/obj/machinery/atmospherics/components/unary/vent_scrubber/atmos_init() radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null if(frequency) @@ -132,7 +130,6 @@ ..() /obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos() - ..() if(welded || !is_operational) return FALSE if(!nodes[1] || !on) @@ -150,16 +147,17 @@ var/datum/gas_mixture/environment = tile.return_air() var/datum/gas_mixture/air_contents = airs[1] + if(!environment) + return FALSE + if(air_contents.return_pressure() >= 50 * ONE_ATMOSPHERE || !islist(filter_types)) return FALSE if(scrubbing & SCRUBBING) environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types) - tile.air_update_turf() else //Just siphoning all air environment.transfer_ratio_to(air_contents, volume_rate/environment.return_volume()) - tile.air_update_turf() update_parents() @@ -225,7 +223,7 @@ return /obj/machinery/atmospherics/components/unary/vent_scrubber/power_change() - ..() + . = ..() update_icon_nopipes() /obj/machinery/atmospherics/components/unary/vent_scrubber/welder_act(mob/living/user, obj/item/I) diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index 2bae4e25e77..8633350aa1c 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -3,136 +3,175 @@ var/list/datum/gas_mixture/other_airs var/list/obj/machinery/atmospherics/pipe/members - var/list/obj/machinery/atmospherics/components/other_atmosmch + var/list/obj/machinery/atmospherics/components/other_atmos_machines var/update = TRUE + var/building = FALSE + /datum/pipeline/New() other_airs = list() members = list() - other_atmosmch = list() + other_atmos_machines = list() SSair.networks += src /datum/pipeline/Destroy() SSair.networks -= src + if(building) + SSair.remove_from_expansion(src) if(air && air.return_volume()) temporarily_store_air() - for(var/obj/machinery/atmospherics/pipe/P in members) - P.parent = null - for(var/obj/machinery/atmospherics/components/C in other_atmosmch) - C.nullifyPipenet(src) + for(var/obj/machinery/atmospherics/pipe/considered_pipe in members) + considered_pipe.parent = null + if(QDELETED(considered_pipe)) + continue + SSair.add_to_rebuild_queue(considered_pipe) + for(var/obj/machinery/atmospherics/components/considered_component in other_atmos_machines) + considered_component.nullify_pipenet(src) return ..() /datum/pipeline/process() - if(update) - update = FALSE - reconcile_air() + if(!update || building) + return + update = FALSE + reconcile_air() update = air.react(src) /datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base) + building = TRUE var/volume = 0 if(istype(base, /obj/machinery/atmospherics/pipe)) - var/obj/machinery/atmospherics/pipe/E = base - volume = E.volume - members += E - if(E.air_temporary) - air = E.air_temporary - E.air_temporary = null + var/obj/machinery/atmospherics/pipe/considered_pipe = base + volume = considered_pipe.volume + members += considered_pipe + if(considered_pipe.air_temporary) + air = considered_pipe.air_temporary + considered_pipe.air_temporary = null else - addMachineryMember(base) + add_machinery_member(base) + if(!air) + air = new + air.set_volume(volume) + SSair.add_to_expansion(src, base) + +///Has the same effect as build_pipeline(), but this doesn't queue its work, so overrun abounds. It's useful for the pregame +/datum/pipeline/proc/build_pipeline_blocking(obj/machinery/atmospherics/base) + var/volume = 0 + if(istype(base, /obj/machinery/atmospherics/pipe)) + var/obj/machinery/atmospherics/pipe/considered_pipe = base + volume = considered_pipe.volume + members += considered_pipe + if(considered_pipe.air_temporary) + air = considered_pipe.air_temporary + considered_pipe.air_temporary = null + else + add_machinery_member(base) + if(!air) air = new var/list/possible_expansions = list(base) - while(possible_expansions.len>0) + while(possible_expansions.len) for(var/obj/machinery/atmospherics/borderline in possible_expansions) - var/list/result = borderline.pipeline_expansion(src) - - if(result.len>0) - for(var/obj/machinery/atmospherics/P in result) - if(istype(P, /obj/machinery/atmospherics/pipe)) - var/obj/machinery/atmospherics/pipe/item = P - if(!members.Find(item)) - - if(item.parent) - var/static/pipenetwarnings = 10 - if(pipenetwarnings > 0) - log_mapping("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) Nearby: ([item.x], [item.y], [item.z]).") - pipenetwarnings -= 1 - if(pipenetwarnings == 0) - log_mapping("build_pipeline(): further messages about pipenets will be suppressed") - members += item - possible_expansions += item - - volume += item.volume - item.parent = src - - if(item.air_temporary) - air.merge(item.air_temporary) - item.air_temporary = null - else - P.setPipenet(src, borderline) - addMachineryMember(P) + if(!result?.len) + possible_expansions -= borderline + continue + for(var/obj/machinery/atmospherics/considered_device in result) + if(!istype(considered_device, /obj/machinery/atmospherics/pipe)) + considered_device.set_pipenet(src, borderline) + add_machinery_member(considered_device) + continue + var/obj/machinery/atmospherics/pipe/item = considered_device + if(members.Find(item)) + continue + if(item.parent) + var/static/pipenetwarnings = 10 + if(pipenetwarnings > 0) + log_mapping("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) around [AREACOORD(item)].") + pipenetwarnings-- + if(pipenetwarnings == 0) + log_mapping("build_pipeline(): further messages about pipenets will be suppressed") + + members += item + possible_expansions += item + + volume += item.volume + item.parent = src + + if(item.air_temporary) + air.merge(item.air_temporary) + item.air_temporary = null possible_expansions -= borderline air.set_volume(volume) -/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/components/C) - other_atmosmch |= C - var/datum/gas_mixture/G = C.returnPipenetAir(src) - if(!G) - stack_trace("addMachineryMember: Null gasmix added to pipeline datum from [C] which is of type [C.type]. Nearby: ([C.x], [C.y], [C.z])") - other_airs |= G - -/datum/pipeline/proc/addMember(obj/machinery/atmospherics/A, obj/machinery/atmospherics/N) - if(istype(A, /obj/machinery/atmospherics/pipe)) - var/obj/machinery/atmospherics/pipe/P = A - if(P.parent) - merge(P.parent) - P.parent = src - var/list/adjacent = P.pipeline_expansion() - for(var/obj/machinery/atmospherics/pipe/I in adjacent) - if(I.parent == src) - continue - var/datum/pipeline/E = I.parent - merge(E) - if(!members.Find(P)) - members += P - air.set_volume(air.return_volume() + P.volume) +/** + * For a machine to properly "connect" to a pipeline and share gases, + * the pipeline needs to acknowledge a gas mixture as it's member. + * This is currently handled by the other_airs list in the pipeline datum. + * + * Other_airs itself is populated by gas mixtures through the parents list that each machineries have. + * This parents list is populated when a machinery calls update_parents and is then added into the queue by the controller. + */ +/datum/pipeline/proc/add_machinery_member(obj/machinery/atmospherics/components/considered_component) + other_atmos_machines |= considered_component + var/list/returned_airs = considered_component.return_pipenet_airs(src) + if (!length(returned_airs) || (null in returned_airs)) + stack_trace("add_machinery_member: Nonexistent (empty list) or null machinery gasmix added to pipeline datum from [considered_component] \ + which is of type [considered_component.type]. Nearby: ([considered_component.x], [considered_component.y], [considered_component.z])") + other_airs |= returned_airs + +/datum/pipeline/proc/add_member(obj/machinery/atmospherics/reference_device, obj/machinery/atmospherics/device_to_add) + if(!istype(reference_device, /obj/machinery/atmospherics/pipe)) + reference_device.set_pipenet(src, device_to_add) + add_machinery_member(reference_device) else - A.setPipenet(src, N) - addMachineryMember(A) - -/datum/pipeline/proc/merge(datum/pipeline/E) - if(E == src) + var/obj/machinery/atmospherics/pipe/reference_pipe = reference_device + if(reference_pipe.parent) + merge(reference_pipe.parent) + reference_pipe.parent = src + var/list/adjacent = reference_pipe.pipeline_expansion() + for(var/obj/machinery/atmospherics/pipe/adjacent_pipe in adjacent) + if(adjacent_pipe.parent == src) + continue + var/datum/pipeline/parent_pipeline = adjacent_pipe.parent + merge(parent_pipeline) + if(!members.Find(reference_pipe)) + members += reference_pipe + air.set_volume(air.return_volume() + reference_pipe.volume) + +/datum/pipeline/proc/merge(datum/pipeline/parent_pipeline) + if(parent_pipeline == src) return - air.set_volume(air.return_volume() + E.air.return_volume()) - members.Add(E.members) - for(var/obj/machinery/atmospherics/pipe/S in E.members) - S.parent = src - air.merge(E.air) - for(var/obj/machinery/atmospherics/components/C in E.other_atmosmch) - C.replacePipenet(E, src) - other_atmosmch.Add(E.other_atmosmch) - other_airs.Add(E.other_airs) - E.members.Cut() - E.other_atmosmch.Cut() + air.set_volume(air.return_volume() + parent_pipeline.air.return_volume()) + members.Add(parent_pipeline.members) + for(var/obj/machinery/atmospherics/pipe/reference_pipe in parent_pipeline.members) + reference_pipe.parent = src + air.merge(parent_pipeline.air) + for(var/obj/machinery/atmospherics/components/reference_component in parent_pipeline.other_atmos_machines) + reference_component.replace_pipenet(parent_pipeline, src) + other_atmos_machines |= parent_pipeline.other_atmos_machines + other_airs |= parent_pipeline.other_airs + parent_pipeline.members.Cut() + parent_pipeline.other_atmos_machines.Cut() update = TRUE - qdel(E) + qdel(parent_pipeline) -/obj/machinery/atmospherics/proc/addMember(obj/machinery/atmospherics/A) +/obj/machinery/atmospherics/proc/add_member(obj/machinery/atmospherics/considered_device) return -/obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A) - parent.addMember(A, src) - -/obj/machinery/atmospherics/components/addMember(obj/machinery/atmospherics/A) - var/datum/pipeline/P = returnPipenet(A) - if(!P) - CRASH("null.addMember() called by [type] on [COORD(src)]") - P.addMember(A, src) +/obj/machinery/atmospherics/pipe/add_member(obj/machinery/atmospherics/considered_device) + // NSV13 - more safety + if(QDELETED(parent)) + parent = new + parent.add_member(considered_device, src) +/obj/machinery/atmospherics/components/add_member(obj/machinery/atmospherics/considered_device) + var/datum/pipeline/device_pipeline = return_pipenet(considered_device) + if(!device_pipeline) + CRASH("null.add_member() called by [type] on [COORD(src)]") + device_pipeline.add_member(considered_device, src) /datum/pipeline/proc/temporarily_store_air() //Update individual gas_mixtures by volume ratio @@ -204,35 +243,30 @@ /datum/pipeline/proc/return_air() . = other_airs + air - if(null in .) - stack_trace("[src]([REF(src)]) has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().") - listclearnulls(.) + if(listclearnulls(.)) + stack_trace("[src] has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().") /datum/pipeline/proc/empty() - for(var/datum/gas_mixture/GM in get_all_connected_airs()) - GM.clear() + for(var/datum/gas_mixture/GM as anything in get_all_connected_airs()) + GM?.clear() /datum/pipeline/proc/get_all_connected_airs() - var/list/datum/gas_mixture/GL = list() - var/list/datum/pipeline/PL = list() - PL += src + var/list/datum/gas_mixture/gas_mixture_list = list() + var/list/datum/pipeline/pipeline_list = list() + pipeline_list += src - for(var/i = 1; i <= PL.len; i++) //can't do a for-each here because we may add to the list within the loop - var/datum/pipeline/P = PL[i] - if(!P) + for(var/i = 1; i <= pipeline_list.len; i++) //can't do a for-each here because we may add to the list within the loop + var/datum/pipeline/pipeline = pipeline_list[i] + if(!pipeline) continue - GL += P.return_air() - for(var/atmosmch in P.other_atmosmch) - if (istype(atmosmch, /obj/machinery/atmospherics/components/binary/valve)) - var/obj/machinery/atmospherics/components/binary/valve/V = atmosmch - if(V.on) - PL |= V.parents[1] - PL |= V.parents[2] - else if (istype(atmosmch, /obj/machinery/atmospherics/components/unary/portables_connector)) - var/obj/machinery/atmospherics/components/unary/portables_connector/C = atmosmch - if(C.connected_device) - GL += C.portableConnectorReturnAir() - return GL + gas_mixture_list += pipeline.other_airs + gas_mixture_list += pipeline.air + for(var/obj/machinery/atmospherics/components/atmos_machine in pipeline.other_atmos_machines) + if(!atmos_machine.custom_reconciliation) + continue + pipeline_list |= atmos_machine.return_pipenets_for_reconcilation(src) + gas_mixture_list |= atmos_machine.return_airs_for_reconcilation(src) + return gas_mixture_list /datum/pipeline/proc/reconcile_air() var/list/datum/gas_mixture/GL = get_all_connected_airs() diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index c02d0a08318..6cd0b1532aa 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -26,14 +26,14 @@ id_tag = ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION /obj/machinery/meter/Destroy() - SSair.atmos_machinery -= src + SSair.stop_processing_machine(src) //NSV13 - Citadel auxmos target = null return ..() /obj/machinery/meter/Initialize(mapload, new_piping_layer) if(!isnull(new_piping_layer)) target_layer = new_piping_layer - SSair.atmos_machinery += src + SSair.start_processing_machine(src) //NSV13 - Citadel auxmos if(!target) reattach_to_layer() return ..() diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index 425c19a760d..a79006a28d9 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -13,7 +13,6 @@ icon_state = "miner" density = FALSE resistance_flags = INDESTRUCTIBLE|ACID_PROOF|FIRE_PROOF - interacts_with_air = TRUE var/spawn_id = null var/spawn_temp = T20C /// Moles of gas to spawn per second @@ -137,7 +136,6 @@ merger.set_moles(spawn_id, spawn_mol * delta_time) merger.set_temperature(spawn_temp) O.assume_air(merger) - O.air_update_turf(TRUE) /obj/machinery/atmospherics/miner/attack_ai(mob/living/silicon/user) if(broken) diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm index 3e0e53bfe25..943721f72e5 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm @@ -6,13 +6,12 @@ buckle_lying = -1 var/icon_temperature = T20C //stop small changes in temperature causing icon refresh resistance_flags = LAVA_PROOF | FIRE_PROOF - interacts_with_air = TRUE /obj/machinery/atmospherics/pipe/heat_exchanging/Initialize(mapload) . = ..() add_atom_colour("#404040", FIXED_COLOUR_PRIORITY) -/obj/machinery/atmospherics/pipe/heat_exchanging/isConnectable(obj/machinery/atmospherics/pipe/heat_exchanging/target, given_layer, HE_type_check = TRUE) +/obj/machinery/atmospherics/pipe/heat_exchanging/is_connectable(obj/machinery/atmospherics/pipe/heat_exchanging/target, given_layer, HE_type_check = TRUE) if(istype(target, /obj/machinery/atmospherics/pipe/heat_exchanging) != HE_type_check) return FALSE . = ..() diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm index 10b8fff66ae..d24950970de 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm @@ -15,17 +15,17 @@ construction_type = /obj/item/pipe/directional pipe_state = "junction" -/obj/machinery/atmospherics/pipe/heat_exchanging/junction/SetInitDirections() +/obj/machinery/atmospherics/pipe/heat_exchanging/junction/set_init_directions() switch(dir) if(NORTH, SOUTH) initialize_directions = SOUTH|NORTH if(EAST, WEST) initialize_directions = WEST|EAST -/obj/machinery/atmospherics/pipe/heat_exchanging/junction/getNodeConnects() +/obj/machinery/atmospherics/pipe/heat_exchanging/junction/get_node_connects() return list(turn(dir, 180), dir) -/obj/machinery/atmospherics/pipe/heat_exchanging/junction/isConnectable(obj/machinery/atmospherics/target, given_layer, he_type_check) +/obj/machinery/atmospherics/pipe/heat_exchanging/junction/is_connectable(obj/machinery/atmospherics/target, given_layer, he_type_check) if(dir == get_dir(target, src)) return ..(target, given_layer, FALSE) //we want a normal pipe instead return ..(target, given_layer, TRUE) diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm index ab63bddb6a1..169b942cb1d 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm @@ -22,7 +22,7 @@ center = mutable_appearance(icon, "manifold_center") return ..() -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/SetInitDirections() +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold/set_init_directions() initialize_directions = NORTH|SOUTH|EAST|WEST initialize_directions &= ~dir @@ -35,7 +35,7 @@ //Add non-broken pieces for(var/i in 1 to device_type) if(nodes[i]) - add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) + add_overlay( get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) update_layer() update_alpha() diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm index fddd9ea8b07..b55ec7497f4 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm @@ -21,7 +21,7 @@ center = mutable_appearance(icon, "manifold4w_center") return ..() -/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/SetInitDirections() +/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/set_init_directions() initialize_directions = initial(initialize_directions) /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/update_icon() @@ -33,7 +33,7 @@ //Add non-broken pieces for(var/i in 1 to device_type) if(nodes[i]) - add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) + add_overlay( get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) update_layer() update_alpha() diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm index fd013e11bd3..ce0e42edb62 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/simple.dm @@ -14,7 +14,7 @@ construction_type = /obj/item/pipe/binary/bendable pipe_state = "he" -/obj/machinery/atmospherics/pipe/heat_exchanging/simple/SetInitDirections() +/obj/machinery/atmospherics/pipe/heat_exchanging/simple/set_init_directions() if(dir in GLOB.diagonals) initialize_directions = dir return diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm index a17e33c1e25..c30dee5abaf 100644 --- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm +++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm @@ -8,6 +8,7 @@ pipe_flags = PIPING_ALL_LAYER | PIPING_DEFAULT_LAYER_ONLY | PIPING_CARDINAL_AUTONORMALIZE piping_layer = PIPING_LAYER_DEFAULT device_type = 0 + volume = 260 construction_type = /obj/item/pipe/binary pipe_state = "manifoldlayer" paintable = FALSE @@ -20,7 +21,6 @@ var/list/back_nodes /obj/machinery/atmospherics/pipe/layer_manifold/Initialize(mapload) - volume = 350 // was previously 280 which was 8 ports but now this thing has 10 front_nodes = list() back_nodes = list() icon_state = "manifoldlayer_center" @@ -43,14 +43,15 @@ /obj/machinery/atmospherics/pipe/layer_manifold/proc/get_all_connected_nodes() return front_nodes + back_nodes + nodes -/obj/machinery/atmospherics/pipe/layer_manifold/update_icon() - cut_overlays() - layer = initial(layer) + (PIPING_LAYER_MAX * PIPING_LAYER_LCHANGE) //This is above everything else. +/obj/machinery/atmospherics/pipe/layer_manifold/update_layer() + layer = initial(layer) + (PIPING_LAYER_MAX * PIPING_LAYER_LCHANGE) //This is above everything else. +/obj/machinery/atmospherics/pipe/layer_manifold/update_overlays(updates=ALL) + . = ..() for(var/node in front_nodes) - add_attached_images(node) + . += add_attached_images(node) for(var/node in back_nodes) - add_attached_images(node) + . += add_attached_images(node) update_alpha() @@ -59,29 +60,29 @@ return if(istype(A, /obj/machinery/atmospherics/pipe/layer_manifold)) for(var/i in PIPING_LAYER_MIN to PIPING_LAYER_MAX) - add_attached_image(get_dir(src, A), i) - return - add_attached_image(get_dir(src, A), A.piping_layer, A.pipe_color) + return get_attached_image(get_dir(src, A), i) + return get_attached_image(get_dir(src, A), A.piping_layer, A.pipe_color) -/obj/machinery/atmospherics/pipe/layer_manifold/proc/add_attached_image(p_dir, p_layer, p_color = null) - var/image/I +/obj/machinery/atmospherics/pipe/layer_manifold/proc/get_attached_image(p_dir, p_layer, p_color = null) + var/mutable_appearance/new_overlay + // Uses pipe-3 because we don't want the vertical shifting if(p_color) - I = getpipeimage(icon, "pipe", p_dir, p_color, piping_layer = p_layer) + new_overlay = get_pipe_image(icon, "pipe-3", p_dir, p_color, piping_layer = p_layer) else - I = getpipeimage(icon, "pipe", p_dir, piping_layer = p_layer) + new_overlay = get_pipe_image(icon, "pipe-3", p_dir, piping_layer = p_layer) - I.layer = layer - 0.01 - add_overlay(I) + new_overlay.layer = layer - 0.01 + return new_overlay -/obj/machinery/atmospherics/pipe/layer_manifold/SetInitDirections() +/obj/machinery/atmospherics/pipe/layer_manifold/set_init_directions() switch(dir) if(NORTH, SOUTH) initialize_directions = NORTH|SOUTH if(EAST, WEST) initialize_directions = EAST|WEST -/obj/machinery/atmospherics/pipe/layer_manifold/isConnectable(obj/machinery/atmospherics/target, given_layer) +/obj/machinery/atmospherics/pipe/layer_manifold/is_connectable(obj/machinery/atmospherics/target, given_layer) if(!given_layer) return TRUE . = ..() @@ -91,8 +92,8 @@ back_nodes = list() var/list/new_nodes = list() for(var/iter in PIPING_LAYER_MIN to PIPING_LAYER_MAX) - var/obj/machinery/atmospherics/foundfront = findConnecting(dir, iter) - var/obj/machinery/atmospherics/foundback = findConnecting(turn(dir, 180), iter) + var/obj/machinery/atmospherics/foundfront = find_connecting(dir, iter) + var/obj/machinery/atmospherics/foundback = find_connecting(turn(dir, 180), iter) front_nodes += foundfront back_nodes += foundback if(foundfront && !QDELETED(foundfront)) @@ -102,13 +103,13 @@ update_icon() return new_nodes -/obj/machinery/atmospherics/pipe/layer_manifold/atmosinit() +/obj/machinery/atmospherics/pipe/layer_manifold/atmos_init() normalize_cardinal_directions() findAllConnections() - var/turf/T = loc // hide if turf is not intact - hide(T.intact) + //var/turf/T = loc // hide if turf is not intact + //hide(T.underfloor_accessibility < UNDERFLOOR_VISIBLE) -/obj/machinery/atmospherics/pipe/layer_manifold/setPipingLayer() +/obj/machinery/atmospherics/pipe/layer_manifold/set_piping_layer() piping_layer = PIPING_LAYER_DEFAULT /obj/machinery/atmospherics/pipe/layer_manifold/pipeline_expansion() @@ -134,11 +135,10 @@ if(initialize_directions & dir) return ..() if((NORTH|EAST) & dir) - user.ventcrawl_layer = CLAMP(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = clamp(user.ventcrawl_layer + 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) if((SOUTH|WEST) & dir) - user.ventcrawl_layer = CLAMP(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) + user.ventcrawl_layer = clamp(user.ventcrawl_layer - 1, PIPING_LAYER_MIN, PIPING_LAYER_MAX) to_chat(user, "You align yourself with the [user.ventcrawl_layer]\th output.") /obj/machinery/atmospherics/pipe/layer_manifold/visible - level = PIPE_VISIBLE_LEVEL layer = GAS_PIPE_VISIBLE_LAYER diff --git a/code/modules/atmospherics/machinery/pipes/manifold.dm b/code/modules/atmospherics/machinery/pipes/manifold.dm index 7e1464138d0..6737c931ed2 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold.dm @@ -20,32 +20,30 @@ pipe_interference_group = "atmos-[piping_layer]"\ ) - var/mutable_appearance/center - -/* We use New() instead of Initialize() because these values are used in update_icon() - * in the mapping subsystem init before Initialize() is called in the atoms subsystem init. +/* We use New() instead of Initialize(mapload) because these values are used in update_appearance(UPDATE_ICON) + * in the mapping subsystem init before Initialize(mapload) is called in the atoms subsystem init. * This is true for the other manifolds (the 4 ways and the heat exchanges) too. */ -/obj/machinery/atmospherics/pipe/manifold/New() +/obj/machinery/atmospherics/pipe/manifold/New(mapload) icon_state = "" - center = mutable_appearance(icon, "manifold_center") return ..() -/obj/machinery/atmospherics/pipe/manifold/SetInitDirections() +/obj/machinery/atmospherics/pipe/manifold/set_init_directions() initialize_directions = NORTH|SOUTH|EAST|WEST initialize_directions &= ~dir -/obj/machinery/atmospherics/pipe/manifold/update_icon() - cut_overlays() +/obj/machinery/atmospherics/pipe/manifold/update_overlays() + . = ..() + var/mutable_appearance/center = mutable_appearance(icon, "manifold_center") if(!center) center = mutable_appearance(icon, "manifold_center") PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) - add_overlay(center) + . += center //Add non-broken pieces for(var/i in 1 to device_type) if(nodes[i]) - add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) + . += get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) update_layer() update_alpha() diff --git a/code/modules/atmospherics/machinery/pipes/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/manifold4w.dm index 75aa6804604..b266bbd0311 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold4w.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold4w.dm @@ -19,27 +19,23 @@ pipe_interference_group = "atmos-[piping_layer]"\ ) - var/mutable_appearance/center - -/obj/machinery/atmospherics/pipe/manifold4w/New() +/obj/machinery/atmospherics/pipe/manifold4w/New(mapload) icon_state = "" - center = mutable_appearance(icon, "manifold4w_center") return ..() -/obj/machinery/atmospherics/pipe/manifold4w/SetInitDirections() +/obj/machinery/atmospherics/pipe/manifold4w/set_init_directions() initialize_directions = initial(initialize_directions) -/obj/machinery/atmospherics/pipe/manifold4w/update_icon() - cut_overlays() - if(!center) - center = mutable_appearance(icon, "manifold_center") +/obj/machinery/atmospherics/pipe/manifold4w/update_overlays() + . = ..() + var/mutable_appearance/center = mutable_appearance(icon, "manifold4w_center") PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) - add_overlay(center) + . += center //Add non-broken pieces for(var/i in 1 to device_type) if(nodes[i]) - add_overlay( getpipeimage(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) ) + . += get_pipe_image(icon, "pipe-[piping_layer]", get_dir(src, nodes[i])) update_layer() update_alpha() diff --git a/code/modules/atmospherics/machinery/pipes/multiz.dm b/code/modules/atmospherics/machinery/pipes/multiz.dm index 3754779aa58..f756cdf7cd2 100644 --- a/code/modules/atmospherics/machinery/pipes/multiz.dm +++ b/code/modules/atmospherics/machinery/pipes/multiz.dm @@ -29,9 +29,12 @@ pipe = mutable_appearance(icon, "pipe-[piping_layer]") return ..() -/obj/machinery/atmospherics/pipe/multiz/SetInitDirections() +/obj/machinery/atmospherics/pipe/multiz/set_init_directions() initialize_directions = dir +/obj/machinery/atmospherics/pipe/multiz/update_layer() + return // Noop because we're moving this to /obj/machinery/atmospherics/pipe + /obj/machinery/atmospherics/pipe/multiz/update_icon() cut_overlays() pipe.color = front_node ? front_node.pipe_color : rgb(255, 255, 255) @@ -42,12 +45,12 @@ /// Attempts to locate a multiz pipe that's above us, if it finds one it merges us into its pipenet /obj/machinery/atmospherics/pipe/multiz/pipeline_expansion() - var/turf/T = get_turf(src) - for(var/obj/machinery/atmospherics/pipe/multiz/above in SSmapping.get_turf_above(T)) + var/turf/local_turf = get_turf(src) + for(var/obj/machinery/atmospherics/pipe/multiz/above in SSmapping.get_turf_above(local_turf)) if(above.piping_layer == piping_layer) nodes += above above.nodes += src // Two way travel :) - for(var/obj/machinery/atmospherics/pipe/multiz/below in SSmapping.get_turf_below(T)) + for(var/obj/machinery/atmospherics/pipe/multiz/below in SSmapping.get_turf_below(local_turf)) if(below.piping_layer == piping_layer) below.pipeline_expansion() // If we've got one below us, force it to add us on facebook return ..() diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm index ec5a561647e..9dcb2ae5caf 100644 --- a/code/modules/atmospherics/machinery/pipes/pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/pipes.dm @@ -2,8 +2,6 @@ var/datum/gas_mixture/air_temporary //used when reconstructing a pipeline that broke var/volume = 0 - level = 1 - use_power = NO_POWER_USE can_unwrench = 1 var/datum/pipeline/parent = null @@ -23,23 +21,24 @@ /obj/machinery/atmospherics/pipe/New() add_atom_colour(pipe_color, FIXED_COLOUR_PRIORITY) volume = 35 * device_type - ..() + return ..() -/obj/machinery/atmospherics/pipe/nullifyNode(i) - var/obj/machinery/atmospherics/oldN = nodes[i] - ..() - if(oldN) - SSair.add_to_rebuild_queue(oldN) +/obj/machinery/atmospherics/pipe/nullify_node(i) + var/obj/machinery/atmospherics/old_node = nodes[i] + . = ..() + if(old_node) + SSair.add_to_rebuild_queue(old_node) /obj/machinery/atmospherics/pipe/destroy_network() QDEL_NULL(parent) -/obj/machinery/atmospherics/pipe/build_network() - if(QDELETED(parent)) - parent = new - parent.build_pipeline(src) +/obj/machinery/atmospherics/pipe/get_rebuild_targets() + if(!QDELETED(parent)) + return + parent = new + return list(parent) -/obj/machinery/atmospherics/pipe/atmosinit() +/obj/machinery/atmospherics/pipe/atmos_init() var/turf/T = loc // hide if turf is not intact hide(T.intact) ..() @@ -53,20 +52,25 @@ if(air_temporary) var/turf/T = loc T.assume_air(air_temporary) - air_update_turf() /obj/machinery/atmospherics/pipe/return_air() - if(parent) - return parent.air + if(air_temporary) + return air_temporary + return parent.air /obj/machinery/atmospherics/pipe/return_analyzable_air() - if(parent) - return parent.air + if(air_temporary) + return air_temporary + return parent.air /obj/machinery/atmospherics/pipe/remove_air(amount) + if(air_temporary) + return air_temporary.remove(amount) return parent.air.remove(amount) /obj/machinery/atmospherics/pipe/remove_air_ratio(ratio) + if(air_temporary) + return air_temporary.remove_ratio(ratio) return parent.air.remove_ratio(ratio) /obj/machinery/atmospherics/pipe/attackby(obj/item/W, mob/user, params) @@ -77,11 +81,10 @@ else return ..() -/obj/machinery/atmospherics/pipe/returnPipenet() - if(parent) - return parent.air +/obj/machinery/atmospherics/pipe/return_pipenet() + return parent -/obj/machinery/atmospherics/pipe/setPipenet(datum/pipeline/P) +/obj/machinery/atmospherics/pipe/set_pipenet(datum/pipeline/P) parent = P /obj/machinery/atmospherics/pipe/Destroy() @@ -111,7 +114,7 @@ var/obj/machinery/atmospherics/N = nodes[i] N.update_icon() -/obj/machinery/atmospherics/pipe/returnPipenets() +/obj/machinery/atmospherics/pipe/return_pipenets() . = list(parent) /obj/machinery/atmospherics/pipe/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) @@ -119,9 +122,12 @@ return 0 . = ..() -/obj/machinery/atmospherics/pipe/paint(paint_color) +/obj/machinery/atmospherics/pipe/proc/paint(paint_color) if(paintable) add_atom_colour(paint_color, FIXED_COLOUR_PRIORITY) pipe_color = paint_color update_node_icon() return paintable + +/obj/machinery/atmospherics/pipe/update_layer() + layer = initial(layer) + (piping_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_LCHANGE diff --git a/code/modules/atmospherics/machinery/pipes/simple.dm b/code/modules/atmospherics/machinery/pipes/simple.dm index 00d24cebda5..409d8de932a 100644 --- a/code/modules/atmospherics/machinery/pipes/simple.dm +++ b/code/modules/atmospherics/machinery/pipes/simple.dm @@ -22,7 +22,7 @@ pipe_interference_group = "atmos-[piping_layer]"\ ) -/obj/machinery/atmospherics/pipe/simple/SetInitDirections() +/obj/machinery/atmospherics/pipe/simple/set_init_directions() if(dir in GLOB.diagonals) initialize_directions = dir return @@ -33,6 +33,7 @@ initialize_directions = EAST|WEST /obj/machinery/atmospherics/pipe/simple/update_icon() + . = ..() icon_state = "pipe[nodes[1] ? "1" : "0"][nodes[2] ? "1" : "0"]-[piping_layer]" update_layer() update_alpha() diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 70b4ce40fa7..7422259f7fa 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -8,10 +8,8 @@ greyscale_config = /datum/greyscale_config/canister/hazard greyscale_colors = "#ffff00#000000" density = TRUE - - var/icon/canister_overlay_file = 'icons/obj/atmospherics/canisters.dmi' - var/valve_open = FALSE + var/obj/machinery/atmospherics/components/binary/passive_gate/pump var/release_log = "" volume = 1000 @@ -38,7 +36,9 @@ var/restricted = FALSE req_access = list() - var/update = 0 + var/icon/canister_overlay_file = 'icons/obj/atmospherics/canisters.dmi' + + //list of canister types for relabeling var/static/list/label2types = list( "n2" = /obj/machinery/portable_atmospherics/canister/nitrogen, "o2" = /obj/machinery/portable_atmospherics/canister/oxygen, @@ -156,7 +156,6 @@ greyscale_config = /datum/greyscale_config/canister/double_stripe greyscale_colors = "#4c4e4d#f7d5d3" - /obj/machinery/portable_atmospherics/canister/proc/get_time_left() if(timing) . = round(max(0, valve_timer - world.time) / 10, 1) @@ -200,24 +199,42 @@ if(href_list[VV_HK_MODIFY_CANISTER_GAS]) usr.client.modify_canister_gas(src) -/obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture) +/obj/machinery/portable_atmospherics/canister/Initialize(mapload, datum/gas_mixture/existing_mixture) . = ..() if(existing_mixture) air_contents.copy_from(existing_mixture) else create_gas() + pump = new(src, FALSE) + pump.on = TRUE + pump.machine_stat = 0 + SSair.add_to_rebuild_queue(pump) + +/obj/machinery/portable_atmospherics/canister/Initialize(mapload) + . = ..() update_icon() +/obj/machinery/portable_atmospherics/canister/Destroy() + qdel(pump) + pump = null + return ..() /obj/machinery/portable_atmospherics/canister/proc/create_gas() if(gas_type) if(starter_temp) air_contents.set_temperature(starter_temp) - if(!air_contents.return_volume()) - CRASH("Auxtools is failing somehow! Gas with pointer [air_contents._extools_pointer_gasmixture] is not valid.") - air_contents.set_moles(gas_type, (maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature())) + if(air_contents.return_volume() == 0) + CRASH("Air content volume is zero, this shouldn't be the case volume is: [volume]!") + if(air_contents.return_temperature() == 0) + CRASH("Air content temperature is zero, this shouldn't be the case!") + if (gas_type) + air_contents.set_moles(gas_type, (maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature())) /obj/machinery/portable_atmospherics/canister/air/create_gas() + if(air_contents.return_volume() == 0) + CRASH("Air content volume is zero, this shouldn't be the case volume is: [volume]!") + if(air_contents.return_temperature() == 0) + CRASH("Air content temperature is zero, this shouldn't be the case!") air_contents.set_temperature(starter_temp) air_contents.set_moles(GAS_O2, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature())) air_contents.set_moles(GAS_N2, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature())) @@ -231,10 +248,6 @@ if(machine_stat & BROKEN) . += mutable_appearance(canister_overlay_file, "broken") return - - var/last_update = update - update = 0 - if(holding) . += mutable_appearance(canister_overlay_file, "can-open") if(connected_port) @@ -247,17 +260,13 @@ . += mutable_appearance(canister_overlay_file, "can-2") if((5 * ONE_ATMOSPHERE) to (10 * ONE_ATMOSPHERE)) . += mutable_appearance(canister_overlay_file, "can-1") - if((10) to (5 * ONE_ATMOSPHERE)) + else . += mutable_appearance(canister_overlay_file, "can-0") - if(update == last_update) - return - /obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) if(exposed_temperature > temperature_resistance) take_damage(5, BURN, 0) - /obj/machinery/portable_atmospherics/canister/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(!(machine_stat & BROKEN)) @@ -291,9 +300,9 @@ /obj/machinery/portable_atmospherics/canister/proc/canister_break() disconnect() + var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles()) var/turf/T = get_turf(src) - T.assume_air(air_contents) - air_update_turf() + T.assume_air(expelled_gas) set_machine_stat(machine_stat | BROKEN) density = FALSE @@ -331,8 +340,7 @@ var/turf/T = get_turf(src) var/datum/gas_mixture/target_air = holding ? holding.air_contents : T.return_air() - if(air_contents.release_gas_to(target_air, release_pressure) && !holding) - air_update_turf() + air_contents.release_gas_to(target_air, release_pressure) update_icon() /obj/machinery/portable_atmospherics/canister/ui_status(mob/user) @@ -484,3 +492,48 @@ . = TRUE if(.) update_icon() + + +/* yog- ADMEME CANISTERS */ + +/// Canister 1 Kelvin below the fusion point. Is highly unoptimal, do not spawn to start fusion, only good for testing low instability mixes. +/obj/machinery/portable_atmospherics/canister/fusion_test + name = "Fusion Test Canister" + desc = "This should never be spawned in game." + greyscale_config = /datum/greyscale_config/canister/hazard + greyscale_colors = "#0099ff#ff3300" + +/obj/machinery/portable_atmospherics/canister/fusion_test/create_gas() + air_contents.set_moles(GAS_TRITIUM, 10) + air_contents.set_moles(GAS_PLASMA, 500) + air_contents.set_moles(GAS_CO2, 500) + air_contents.set_moles(GAS_NITROUS, 100) + air_contents.set_temperature(FUSION_TEMPERATURE_THRESHOLD) + +/// Canister 1 Kelvin below the fusion point. Contains far too much plasma. Only good for adding more fuel to ongoing fusion reactions. + /obj/machinery/portable_atmospherics/canister/fusion_test_2 + name = "Fusion Test Canister" + desc = "This should never be spawned in game." + greyscale_config = /datum/greyscale_config/canister/hazard + greyscale_colors = "#0099ff#ff3300" + +/obj/machinery/portable_atmospherics/canister/fusion_test_2/create_gas() + air_contents.set_moles(GAS_TRITIUM, 10) + air_contents.set_moles(GAS_PLASMA, 15000) + air_contents.set_moles(GAS_CO2, 1500) + air_contents.set_moles(GAS_NITROUS, 100) + air_contents.set_temperature(FUSION_TEMPERATURE_THRESHOLD - 1) + +/// Canister at the perfect conditions to start and continue fusion for a long time. +/obj/machinery/portable_atmospherics/canister/fusion_test_3 + name = "Fusion Test Canister" + desc = "This should never be spawned in game." + greyscale_config = /datum/greyscale_config/canister/hazard + greyscale_colors = "#0099ff#ff3300" + +/obj/machinery/portable_atmospherics/canister/fusion_test_3/create_gas() + air_contents.set_moles(GAS_TRITIUM, 1000) + air_contents.set_moles(GAS_PLASMA, 4500) + air_contents.set_moles(GAS_CO2, 1500) + air_contents.set_temperature(1000000) + diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index b871486da89..efd00cf3ec9 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -14,23 +14,17 @@ var/maximum_pressure = 90 * ONE_ATMOSPHERE -/obj/machinery/portable_atmospherics/New() - ..() - SSair.atmos_air_machinery += src +/obj/machinery/portable_atmospherics/Initialize(mapload) + . = ..() + SSair.start_processing_machine(src) air_contents = new(volume) air_contents.set_temperature(T20C) - return 1 - /obj/machinery/portable_atmospherics/Destroy() - SSair.atmos_air_machinery -= src + SSair.stop_processing_machine(src) disconnect() - qdel(air_contents) - air_contents = null - - SSair.atmos_machinery -= src - + QDEL_NULL(air_contents) return ..() /obj/machinery/portable_atmospherics/ex_act(severity, target) @@ -41,7 +35,6 @@ //This explosion will destroy the can, release its air. var/turf/T = get_turf(src) T.assume_air(air_contents) - T.air_update_turf() return ..() @@ -91,9 +84,6 @@ update_icon() return TRUE -/obj/machinery/portable_atmospherics/portableConnectorReturnAir() - return air_contents - /obj/machinery/portable_atmospherics/AltClick(mob/living/user) if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, !ismonkey(user))) return diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 72858d925b2..2631247c1c8 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -29,7 +29,6 @@ /obj/machinery/portable_atmospherics/pump/Destroy() var/turf/T = get_turf(src) T.assume_air(air_contents) - air_update_turf() QDEL_NULL(pump) return ..() @@ -58,8 +57,6 @@ pump.airs[2] = holding ? holding.air_contents : air_contents pump.process_atmos() // Pump gas. - if(!holding) - air_update_turf() // Update the environment if needed. /obj/machinery/portable_atmospherics/pump/emp_act(severity) . = ..() diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 17278181ef5..9bed4b5519e 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -4,19 +4,26 @@ icon_state = "pscrubber:0" density = TRUE - - var/on = FALSE var/volume_rate = 1000 var/overpressure_m = 80 volume = 1000 - var/list/scrubbing = list(GAS_PLASMA, GAS_CO2, GAS_NITROUS, GAS_BZ, GAS_NITRYL, GAS_TRITIUM, GAS_HYPERNOB, GAS_H2O, GAS_CONSTRICTED_PLASMA, GAS_NUCLEIUM) //NSV13 - constricted plasma and nucleium + var/list/scrubbing = list( + GAS_PLASMA, + GAS_CO2, + GAS_NITROUS, + GAS_BZ, + GAS_NITRYL, + GAS_TRITIUM, + GAS_HYPERNOB, + GAS_H2O, + GAS_CONSTRICTED_PLASMA, + GAS_NUCLEIUM) //NSV13 - constricted plasma and nucleium /obj/machinery/portable_atmospherics/scrubber/Destroy() var/turf/T = get_turf(src) T.assume_air(air_contents) - air_update_turf() return ..() /obj/machinery/portable_atmospherics/scrubber/update_icon() @@ -39,13 +46,11 @@ var/turf/T = get_turf(src) scrub(T.return_air()) -/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture) +/obj/machinery/portable_atmospherics/scrubber/proc/scrub(datum/gas_mixture/mixture) if(air_contents.return_pressure() >= overpressure_m * ONE_ATMOSPHERE) return mixture.scrub_into(air_contents, volume_rate / mixture.return_volume(), scrubbing) - if(!holding) - air_update_turf() /obj/machinery/portable_atmospherics/scrubber/emp_act(severity) . = ..() @@ -150,5 +155,4 @@ if(default_unfasten_wrench(user, W)) if(!movable) on = FALSE - else - return ..() + return ..() diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 80c127420d0..4aa7b28ea54 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -241,8 +241,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(CONFIG_GET(flag/enable_localhost_rank) && !connecting_admin) var/localhost_addresses = list("127.0.0.1", "::1") if(isnull(address) || (address in localhost_addresses)) - if(Debugger?.enabled) - to_chat_immediate(src, "Debugger enabled. Make sure you untick \"Runtime errors\" in the bottom left of VSCode's Run and Debug tab.") var/datum/admin_rank/localhost_rank = new("!localhost!", R_EVERYTHING, R_DBRANKS, R_EVERYTHING) //+EVERYTHING -DBRANKS *EVERYTHING new /datum/admins(localhost_rank, ckey, 1, 1) //preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum) diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index b3579514588..525d5dcb115 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -55,7 +55,7 @@ continue//no parent vent //Stops Aliens getting stuck in small networks. //See: Security, Virology - if(temp_vent_parent.other_atmosmch.len > 20) + if(temp_vent_parent.other_atmos_machines.len > 20) vents += temp_vent if(!vents.len) diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index d9d454faa29..5414b20dfe8 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -27,7 +27,7 @@ continue if(is_station_level(temp_vent.loc.z) && !temp_vent.welded) var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] - if(temp_vent_parent.other_atmosmch.len > 20) + if(temp_vent_parent.other_atmos_machines.len > 20) vents += temp_vent while((spawncount >= 1) && vents.len) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index ec913d8f812..223804ae917 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -201,7 +201,7 @@ GLOBAL_LIST_INIT(hallucination_list, list( for(var/turf/FT in flood_turfs) for(var/dir in GLOB.cardinals) var/turf/T = get_step(FT, dir) - if((T in flood_turfs) || !FT.CanAtmosPass(T)) + if((T in flood_turfs) || !TURFS_CAN_SHARE(T, FT)) continue var/image/new_plasma = image(image_icon,T,image_state,FLY_LAYER) new_plasma.alpha = 50 diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 7bc6b546a38..08eeb2ea2a9 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -105,7 +105,7 @@ ) ) for(var/turf/affected_turf as anything in template_and_bordering_turfs) - affected_turf.air_update_turf(TRUE) + affected_turf.air_update_turf(TRUE, TRUE) affected_turf.levelupdate() /datum/map_template/proc/load_new_z(orbital_body_type, list/level_traits = list(ZTRAIT_AWAY = TRUE)) @@ -146,12 +146,6 @@ if(T.y+height > world.maxy) return - var/list/border = block(locate(max(T.x, 1), max(T.y, 1), T.z), - locate(min(T.x+width, world.maxx), min(T.y+height, world.maxy), T.z)) - for(var/L in border) - var/turf/turf_to_disable = L - turf_to_disable.ImmediateDisableAdjacency() - // Accept cached maps, but don't save them automatically - we don't want // ruins clogging up memory for the whole round. var/datum/parsed_map/parsed = cached_map || new(file(mappath)) diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 4cb6a3ba0ff..8d64fed86b6 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -313,7 +313,7 @@ /obj/structure/fans/Initialize(mapload) . = ..() - air_update_turf(1) + air_update_turf() //Inivisible, indestructible fans /obj/structure/fans/tiny/invisible diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index aea243a733b..7a44bff12c4 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -146,7 +146,6 @@ if(breath) loc.assume_air(breath) - air_update_turf() /mob/living/carbon/proc/has_smoke_protection() if(HAS_TRAIT(src, TRAIT_NOBREATH)) diff --git a/code/modules/mob/living/simple_animal/bot/atmosbot.dm b/code/modules/mob/living/simple_animal/bot/atmosbot.dm index 609be5abf0a..eacabb2e263 100644 --- a/code/modules/mob/living/simple_animal/bot/atmosbot.dm +++ b/code/modules/mob/living/simple_animal/bot/atmosbot.dm @@ -200,7 +200,6 @@ else environment.adjust_moles(GAS_N2, transfer_moles * 0.7885) environment.adjust_moles(GAS_O2, transfer_moles * 0.2115) - air_update_turf() new /obj/effect/temp_visual/vent_wind(get_turf(src)) /mob/living/simple_animal/bot/atmosbot/proc/scrub_toxins() diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 614b12269ee..8898736774d 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -47,7 +47,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( if(vent_found) var/datum/pipeline/vent_found_parent = vent_found.parents[1] - if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmosmch)) + if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmos_machines)) visible_message("[src] begins climbing into the ventilation system." ,"You begin climbing into the ventilation system.") if(!do_after(src, 25, target = vent_found)) @@ -85,9 +85,9 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( return var/list/totalMembers = list() - for(var/datum/pipeline/P in starting_machine.returnPipenets()) + for(var/datum/pipeline/P in starting_machine.return_pipenets()) totalMembers += P.members - totalMembers += P.other_atmosmch + totalMembers += P.other_atmos_machines if(!totalMembers.len) return diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 0aae7a1b9e0..9e763f30af7 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -17,7 +17,7 @@ . = ..() find_circs() connect_to_network() - SSair.atmos_machinery += src + SSair.start_processing_machine(src) //NSV13 - Citadel auxmos update_icon() component_parts = list(new /obj/item/circuitboard/machine/generator) @@ -27,7 +27,7 @@ /obj/machinery/power/generator/Destroy() kill_circs() - SSair.atmos_machinery -= src + SSair.stop_processing_machine(src) //NSV13 - Citadel auxmos return ..() /obj/machinery/power/generator/update_icon() diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index e0fc9ed1ace..cecee6ee964 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -18,7 +18,6 @@ /obj/machinery/field/containment/Initialize(mapload) . = ..() - air_update_turf(TRUE, TRUE) RegisterSignal(src, COMSIG_ATOM_SINGULARITY_TRY_MOVE, PROC_REF(block_singularity)) var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index d5d688b400c..b3864a3116c 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -114,7 +114,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/Initialize(mapload) . = ..() uid = gl_uid++ - SSair.atmos_air_machinery += src + SSair.start_processing_machine(src) //NSV13 - Citadel auxmos countdown = new(src) countdown.start() GLOB.poi_list |= src @@ -133,7 +133,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) /obj/machinery/power/supermatter_crystal/Destroy() investigate_log("has been destroyed.", INVESTIGATE_ENGINES) - SSair.atmos_air_machinery -= src + SSair.stop_processing_machine(src) //NSV13 - Citadel auxmos QDEL_NULL(radio) GLOB.poi_list -= src QDEL_NULL(countdown) @@ -423,7 +423,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(produces_gas) env.merge(removed) - air_update_turf() for(var/mob/living/carbon/human/l in viewers(HALLUCINATION_RANGE(power), src)) // If they can see it without mesons on. Bad on them. if(!HAS_TRAIT(l.mind, TRAIT_MADNESS_IMMUNE) && !HAS_TRAIT(l, TRAIT_MADNESS_IMMUNE)) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 9fe0acec809..6fcdd253dfb 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -66,10 +66,13 @@ /obj/machinery/disposal/LateInitialize() //this will get a copy of the air turf and take a SEND PRESSURE amount of air from it var/atom/L = loc + var/datum/gas_mixture/loc_air = L.return_air() var/datum/gas_mixture/env = new - env.copy_from(L.return_air()) - var/datum/gas_mixture/removed = env.remove(SEND_PRESSURE + 1) - air_contents.merge(removed) + if(loc_air) + env.copy_from(loc_air) + var/datum/gas_mixture/removed = env.remove(SEND_PRESSURE + 1) + if(removed) + air_contents.merge(removed) trunk_check() /obj/machinery/disposal/attackby(obj/item/I, mob/user, params) @@ -401,14 +404,12 @@ var/datum/gas_mixture/env = L.return_air() var/pressure_delta = (SEND_PRESSURE*1.01) - air_contents.return_pressure() - if(env.return_temperature() > 0) + if(env?.return_temperature() > 0) var/transfer_moles = 0.05 * delta_time * pressure_delta * air_contents.return_volume() / (env.return_temperature() * R_IDEAL_GAS_EQUATION) //Actually transfer the gas var/datum/gas_mixture/removed = env.remove(transfer_moles) air_contents.merge(removed) - air_update_turf() - //if full enough, switch to ready mode if(air_contents.return_pressure() >= SEND_PRESSURE) diff --git a/code/modules/recycling/disposal/holder.dm b/code/modules/recycling/disposal/holder.dm index 159024937c1..5fc7093060d 100644 --- a/code/modules/recycling/disposal/holder.dm +++ b/code/modules/recycling/disposal/holder.dm @@ -147,7 +147,6 @@ // called to vent all gas in holder to a location /obj/structure/disposalholder/proc/vent_gas(turf/T) T.assume_air(gas) - T.air_update_turf() /obj/structure/disposalholder/AllowDrop() return TRUE diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 080cb0e398d..cd0b9461fc8 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -373,7 +373,6 @@ visible_message("[src] malfunctions, melting [exp_on] and leaking hot air!") var/datum/gas_mixture/env = loc.return_air() env.adjust_heat(100000) - air_update_turf() investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) @@ -412,7 +411,6 @@ visible_message("[src] malfunctions, shattering [exp_on] and leaking cold air!") var/datum/gas_mixture/env = loc.return_air() env.adjust_heat(-75000) - air_update_turf() investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index d5297c0ed77..b7eaf6deba1 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -94,8 +94,6 @@ var/perc = max((get_env_temp() - temp_tolerance_high), 0) * temp_penalty_coefficient / base_mining_income env.adjust_heat(heating_power * perc * heat_gen) - air_update_turf() - src.air_update_turf() else current_temp = env ? env.return_temperature() : -1 diff --git a/code/modules/research/xenobiology/crossbreeding/_structures.dm b/code/modules/research/xenobiology/crossbreeding/_structures.dm index b3d820273ba..6131229acf4 100644 --- a/code/modules/research/xenobiology/crossbreeding/_structures.dm +++ b/code/modules/research/xenobiology/crossbreeding/_structures.dm @@ -150,7 +150,6 @@ GLOBAL_LIST_EMPTY(bluespace_slime_crystals) return var/datum/gas_mixture/gas = T.return_air() gas.set_temperature(T0C + 200) - T.air_update_turf() /obj/structure/slime_crystal/purple colour = "purple" @@ -191,7 +190,6 @@ GLOBAL_LIST_EMPTY(bluespace_slime_crystals) continue var/datum/gas_mixture/gas = T.return_air() gas.parse_gas_string(OPENTURF_DEFAULT_ATMOS) - T.air_update_turf() /obj/structure/slime_crystal/metal colour = "metal" diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm index 6cd340435a9..c45c8cbc0a9 100644 --- a/code/modules/research/xenobiology/crossbreeding/chilling.dm +++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm @@ -109,7 +109,6 @@ Chilling extracts: G.set_moles(GAS_PLASMA, 0) G.set_moles(GAS_CONSTRICTED_PLASMA, 0) //NSV13 filtered = TRUE - T.air_update_turf() if(filtered) user.visible_message("Cracks spread throughout [src], and some air is sucked in!") else diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 63bc1b28a81..1254ffd9a7d 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -75,10 +75,6 @@ All ShuttleMove procs go here else update_air_ref(-1) - //Air stuff - newT.air_update_turf(TRUE) - air_update_turf(TRUE) - return TRUE // Called on the new turf after everything has been moved @@ -289,17 +285,17 @@ All ShuttleMove procs go here break if(!connected) - nullifyNode(i) + nullify_node(i) if(!nodes[i]) missing_nodes = TRUE if(missing_nodes) - atmosinit() + atmos_init() for(var/obj/machinery/atmospherics/A in pipeline_expansion()) - A.atmosinit() - if(A.returnPipenet()) - A.addMember(src) + A.atmos_init() + if(A.return_pipenet()) + A.add_member(src) SSair.add_to_rebuild_queue(src) else // atmosinit() calls update_icon(), so we don't need to call it diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index 0b9aa6019a7..50cf5223e15 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -81,13 +81,13 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate /************************************Machine rotate procs************************************/ /obj/machinery/atmospherics/shuttleRotate(rotation, params) - var/list/real_node_connect = getNodeConnects() + var/list/real_node_connect = get_node_connects() for(var/i in 1 to device_type) real_node_connect[i] = angle2dir(rotation+dir2angle(real_node_connect[i])) . = ..() - SetInitDirections() - var/list/supposed_node_connect = getNodeConnects() + set_init_directions() + var/list/supposed_node_connect = get_node_connects() var/list/nodes_copy = nodes.Copy() for(var/i in 1 to device_type) diff --git a/code/modules/shuttle/super_cruise/shuttle_components/plasma_refiner.dm b/code/modules/shuttle/super_cruise/shuttle_components/plasma_refiner.dm index 75a576831e5..f6d39748537 100644 --- a/code/modules/shuttle/super_cruise/shuttle_components/plasma_refiner.dm +++ b/code/modules/shuttle/super_cruise/shuttle_components/plasma_refiner.dm @@ -43,16 +43,16 @@ /obj/machinery/atmospherics/components/unary/plasma_refiner/default_change_direction_wrench(mob/user, obj/item/I) . = ..() if(.) - SetInitDirections() + set_init_directions() var/obj/machinery/atmospherics/node = nodes[1] if(node) node.disconnect(src) nodes[1] = null if(parents[1]) - nullifyPipenet(parents[1]) - atmosinit() + nullify_pipenet(parents[1]) + atmos_init() node = nodes[1] if(node) - node.atmosinit() - node.addMember(src) + node.atmos_init() + node.add_member(src) SSair.add_to_rebuild_queue(src) diff --git a/config/config.txt b/config/config.txt index 8ec57ce7d40..5ae2a2e357a 100644 --- a/config/config.txt +++ b/config/config.txt @@ -623,3 +623,5 @@ GHOST_ROLE_COOLDOWN 3000 ## Once a typepath causes overrun from hard deletes this many times, stop hard deleting it on garbage collection failures. (set to 0 to disable) #HARD_DELETES_OVERRUN_LIMIT 0 + +ATMOS_EQUALIZE_ENABLED diff --git a/dependencies.sh b/dependencies.sh index caa899f6669..e62f898b2ef 100755 --- a/dependencies.sh +++ b/dependencies.sh @@ -5,13 +5,13 @@ # byond version export BYOND_MAJOR=515 -export BYOND_MINOR=1608 +export BYOND_MINOR=1633 #rust version -export RUST_VERSION=1.67.1 +export RUST_VERSION=1.70 #rust_g git tag -export RUST_G_VERSION=1.2.0 +export RUST_G_VERSION=3.1.3 #node version export NODE_VERSION=18 @@ -21,7 +21,7 @@ export NODE_VERSION_PRECISE=18.14.2 export SPACEMAN_DMM_VERSION=suite-1.8 #auxmos version -export AUXMOS_VERSION=2.2.2 +export AUXMOS_VERSION=2.5.2-b # Python version for mapmerge and other tools export PYTHON_VERSION=3.11.2 diff --git a/libauxmos.so b/libauxmos.so new file mode 100644 index 00000000000..4ad3cfa616e Binary files /dev/null and b/libauxmos.so differ diff --git a/nsv13.dme b/nsv13.dme index 2abd39ff698..bb3988256f3 100644 --- a/nsv13.dme +++ b/nsv13.dme @@ -18,6 +18,7 @@ #include "code\_compile_options.dm" #include "code\_debugger.dm" #include "code\world.dm" +#include "code\__DEFINES\_auxtools.dm" #include "code\__DEFINES\_click.dm" #include "code\__DEFINES\_globals.dm" #include "code\__DEFINES\_helpers.dm" @@ -40,6 +41,7 @@ #include "code\__DEFINES\atom_hud.dm" #include "code\__DEFINES\balloon_alert.dm" #include "code\__DEFINES\bans.dm" +#include "code\__DEFINES\bindings.dm" #include "code\__DEFINES\bitfields.dm" #include "code\__DEFINES\bodyparts.dm" #include "code\__DEFINES\bot_defines.dm" @@ -192,7 +194,6 @@ #include "code\__DEFINES\dcs\signals\signals_obj\signals_machine\signals_machinery.dm" #include "code\__DEFINES\dcs\signals\signals_obj\signals_machine\signals_supermatter.dm" #include "code\__DEFINES\research\anomalies.dm" -#include "code\__HELPERS\_extools_api.dm" #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" #include "code\__HELPERS\_string_lists.dm" diff --git a/nsv13/code/game/gamemodes/bloodling.dm b/nsv13/code/game/gamemodes/bloodling.dm index a075a456632..0e6b2000464 100644 --- a/nsv13/code/game/gamemodes/bloodling.dm +++ b/nsv13/code/game/gamemodes/bloodling.dm @@ -90,7 +90,7 @@ Helper proc to spawn the lil' blood alien creature in a vent! Adapted from alien continue//no parent vent //Stops Aliens getting stuck in small networks. //See: Security, Virology - if(temp_vent_parent.other_atmosmch.len > 20) + if(temp_vent_parent.other_atmos_machines.len > 20) vents += temp_vent //Okay, fallback. diff --git a/nsv13/code/game/machinery/plasma_loader.dm b/nsv13/code/game/machinery/plasma_loader.dm index 57c4e346992..3bbeb5f05e6 100644 --- a/nsv13/code/game/machinery/plasma_loader.dm +++ b/nsv13/code/game/machinery/plasma_loader.dm @@ -75,7 +75,7 @@ var/transfer_moles = air1_pressure*environment.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION) loc.assume_air_moles(air1, transfer_moles) - air_update_turf(1) + air_update_turf() non_phoron = TRUE //Stop putting suggestive variables in my code BOBBANZ1! diff --git a/nsv13/code/modules/atmospherics/machinery/components/binary_devices/constrictor.dm b/nsv13/code/modules/atmospherics/machinery/components/binary_devices/constrictor.dm index 0894c99c5e3..dccb5ca57b2 100644 --- a/nsv13/code/modules/atmospherics/machinery/components/binary_devices/constrictor.dm +++ b/nsv13/code/modules/atmospherics/machinery/components/binary_devices/constrictor.dm @@ -100,22 +100,22 @@ if(node2) node2.disconnect(src) nodes[2] = null - nullifyPipenet(parents[2]) + nullify_pipenet(parents[2]) if(node1) node1.disconnect(src) nodes[1] = null - nullifyPipenet(parents[1]) + nullify_pipenet(parents[1]) - SetInitDirections() - atmosinit() + set_init_directions() + atmos_init() node1 = nodes[1] if(node1) - node1.atmosinit() - node1.addMember(src) + node1.atmos_init() + node1.add_member(src) node2 = nodes[2] if(node2) - node2.atmosinit() - node2.addMember(src) + node2.atmos_init() + node2.add_member(src) SSair.add_to_rebuild_queue(src) update_icon(TRUE) return TRUE diff --git a/nsv13/code/modules/power/reactor/rbmk.dm b/nsv13/code/modules/power/reactor/rbmk.dm index ddd020636f9..319500aaa9e 100644 --- a/nsv13/code/modules/power/reactor/rbmk.dm +++ b/nsv13/code/modules/power/reactor/rbmk.dm @@ -457,7 +457,7 @@ The reactor CHEWS through moderator. It does not do this slowly. Be very careful //Results: Engineering becomes unusable and your engine irreparable /obj/machinery/atmospherics/components/trinary/nuclear_reactor/proc/meltdown() set waitfor = FALSE - SSair.atmos_machinery -= src //Annd we're now just a useless brick. + SSair.stop_processing_machine(src) //Annd we're now just a useless brick. slagged = TRUE update_icon() STOP_PROCESSING(SSmachines, src) diff --git a/nsv13/code/modules/power/stormdrive.dm b/nsv13/code/modules/power/stormdrive.dm index 53382b6ef45..dec1dd6dfd4 100644 --- a/nsv13/code/modules/power/stormdrive.dm +++ b/nsv13/code/modules/power/stormdrive.dm @@ -780,6 +780,12 @@ Control Rods gas_records_next_interval = world.time + gas_records_interval var/datum/gas_mixture/air1 = airs[1] + if (air1.total_moles() <= 0) + // Division by zero is bad + for (var/list/record_list in gas_records) + record_list += 0 + record_list.Cut(1, 2) + return var/list/constricted_plasma = gas_records["constricted_plasma"] constricted_plasma += (air1.get_moles(GAS_CONSTRICTED_PLASMA) / air1.total_moles()) * 100 @@ -966,6 +972,11 @@ Control Rods return if(can_alert || override) //We have an override to ignore continuous alerts like control rod reports in favour of screaming that the reactor is about to go nuclear. can_alert = FALSE + if(!radio) // Why does this keep happening? + radio = new(src) + radio.keyslot = new radio_key + radio.listening = 0 + radio.recalculateChannels() radio.talk_into(src, message, engineering_channel) addtimer(VARSET_CALLBACK(src, can_alert, TRUE), alert_cooldown) @@ -1362,48 +1373,48 @@ Control Rods /obj/machinery/computer/ship/reactor_control_computer/ui_data(mob/user) var/list/data = list() - data["heat"] = reactor.heat - data["rod_integrity"] = reactor.control_rod_integrity - data["control_rod_percent"] = reactor.control_rod_percent - data["pipe_open"] = reactor.dumping_fuel - data["last_power_produced"] = reactor.last_power_produced - data["theoretical_maximum_power"] = reactor.theoretical_maximum_power - data["reaction_rate"] = reactor.reaction_rate - data["reactor_hot"] = reactor.reactor_temperature_hot - data["reactor_critical"] = reactor.reactor_temperature_critical - data["reactor_meltdown"] = reactor.reactor_temperature_meltdown - if(reactor.state == REACTOR_STATE_MAINTENANCE) + data["heat"] = reactor ? reactor.heat : 0 + data["rod_integrity"] = reactor ? reactor.control_rod_integrity : 0 + data["control_rod_percent"] = reactor ? reactor.control_rod_percent : 0 + data["pipe_open"] = reactor ? reactor.dumping_fuel : 0 + data["last_power_produced"] = reactor ? reactor.last_power_produced : 0 + data["theoretical_maximum_power"] = reactor ? reactor.theoretical_maximum_power : 0 + data["reaction_rate"] = reactor ? reactor.reaction_rate : 0 + data["reactor_hot"] = reactor ? reactor.reactor_temperature_hot : 0 + data["reactor_critical"] = reactor ? reactor.reactor_temperature_critical : 0 + data["reactor_meltdown"] = reactor ? reactor.reactor_temperature_meltdown : 0 + if(reactor?.state == REACTOR_STATE_MAINTENANCE) data["reactor_maintenance"] = TRUE else data["reactor_maintenance"] = FALSE - var/datum/gas_mixture/air1 = reactor.airs[1] + var/datum/gas_mixture/air1 = reactor ? reactor.airs[1] : 0 - data["fuel_mix"] = air1.get_moles(GAS_PLASMA) + air1.get_moles(GAS_CONSTRICTED_PLASMA) + air1.get_moles(GAS_TRITIUM) - if(reactor.state == REACTOR_STATE_RUNNING) - data["mole_threshold_very_high"] = (reactor.reaction_rate * 18) + 20 - data["mole_threshold_high"] = (reactor.reaction_rate * 12) + 20 + data["fuel_mix"] = air1 ? air1.get_moles(GAS_PLASMA) + air1.get_moles(GAS_CONSTRICTED_PLASMA) + air1.get_moles(GAS_TRITIUM) : 0 + if(reactor?.state == REACTOR_STATE_RUNNING) + data["mole_threshold_very_high"] = reactor ? (reactor.reaction_rate * 18) + 20 : 0 + data["mole_threshold_high"] = reactor ? (reactor.reaction_rate * 12) + 20 : 0 else data["mole_threshold_very_high"] = 120 //Just need to avoid that inital orange data["mole_threshold_high"] = 80 - data["o2"] = air1.get_moles(GAS_O2) - data["n2"] = air1.get_moles(GAS_N2) - data["co2"] = air1.get_moles(GAS_CO2) - data["plasma"] = air1.get_moles(GAS_PLASMA) - data["water_vapour"] = air1.get_moles(GAS_H2O) - data["nob"] = air1.get_moles(GAS_HYPERNOB) - data["n2o"] = air1.get_moles(GAS_NITROUS) - data["no2"] = air1.get_moles(GAS_NITRYL) - data["tritium"] = air1.get_moles(GAS_TRITIUM) - data["bz"] = air1.get_moles(GAS_BZ) - data["stim"] = air1.get_moles(GAS_STIMULUM) - data["pluoxium"] = air1.get_moles(GAS_PLUOXIUM) - data["constricted_plasma"] = air1.get_moles(GAS_CONSTRICTED_PLASMA) - data["nucleium"] = air1.get_moles(GAS_NUCLEIUM) - data["total_moles"] = air1.total_moles() - - data["gas_records"] = reactor.gas_records + data["o2"] = air1 ? air1.get_moles(GAS_O2) : 0 + data["n2"] = air1 ? air1.get_moles(GAS_N2) : 0 + data["co2"] = air1 ? air1.get_moles(GAS_CO2) : 0 + data["plasma"] = air1 ? air1.get_moles(GAS_PLASMA) : 0 + data["water_vapour"] = air1 ? air1.get_moles(GAS_H2O) : 0 + data["nob"] = air1 ? air1.get_moles(GAS_HYPERNOB) : 0 + data["n2o"] = air1 ? air1.get_moles(GAS_NITROUS) : 0 + data["no2"] = air1 ? air1.get_moles(GAS_NITRYL) : 0 + data["tritium"] = air1 ? air1.get_moles(GAS_TRITIUM) : 0 + data["bz"] = air1 ? air1.get_moles(GAS_BZ) : 0 + data["stim"] = air1 ? air1.get_moles(GAS_STIMULUM) : 0 + data["pluoxium"] = air1 ? air1.get_moles(GAS_PLUOXIUM) : 0 + data["constricted_plasma"] = air1 ? air1.get_moles(GAS_CONSTRICTED_PLASMA) : 0 + data["nucleium"] = air1 ? air1.get_moles(GAS_NUCLEIUM) : 0 + data["total_moles"] = air1 ? air1.total_moles() : 0 + + data["gas_records"] = reactor ? reactor.gas_records : list() return data @@ -1649,7 +1660,7 @@ Control Rods var/atom/target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src))) M.throw_at(target, 4, 2) continue - if(isobj(AM) && !AM.anchored) + if(!QDELETED(AM) && isobj(AM) && !AM.anchored) var/atom/target = get_edge_target_turf(AM, get_dir(src, get_step_away(AM, src))) AM.throw_at(target, 4, 2) @@ -1675,7 +1686,7 @@ Control Rods /obj/effect/anomaly/stormdrive/squall/proc/equalise(mob/living/A) var/list/throwlist = orange(6, A) for(var/obj/O in throwlist) - if(!O.anchored) + if(!QDELETED(O) && !O.anchored) O.throw_at(A, 6, 3) for(var/mob/living/M in throwlist) if(!M.mob_negates_gravity()) @@ -1707,7 +1718,7 @@ Control Rods M.apply_damage(20) var/atom/target = get_edge_target_turf(M, get_dir(src, get_step_away(M, src))) M.throw_at(target, 6, 5) - if(isobj(AM) && !AM.anchored) + if(!QDELETED(AM) && isobj(AM) && !AM.anchored) var/atom/target = get_edge_target_turf(AM, get_dir(src, get_step_away(AM, src))) AM.throw_at(target, 6, 5) diff --git a/tools/ci/install_auxmos.sh b/tools/ci/install_auxmos.sh index 591bcf612f1..1557c37cd88 100644 --- a/tools/ci/install_auxmos.sh +++ b/tools/ci/install_auxmos.sh @@ -4,6 +4,7 @@ set -euo pipefail source dependencies.sh mkdir -p ~/.byond/bin -wget -O ~/.byond/bin/libauxmos.so "https://github.com/BeeStation/auxmos/releases/download/${AUXMOS_VERSION}/libauxmos.so" +# NSV13 - use fork +wget -O ~/.byond/bin/libauxmos.so "https://github.com/covertcorvid/auxmos/releases/download/v${AUXMOS_VERSION}/libauxmos.so" chmod +x ~/.byond/bin/libauxmos.so ldd ~/.byond/bin/libauxmos.so diff --git a/tools/deploy.sh b/tools/deploy.sh index d6a69ee1393..ef75086c906 100755 --- a/tools/deploy.sh +++ b/tools/deploy.sh @@ -12,7 +12,9 @@ fi mkdir -p \ $1/_maps \ $1/auxtools \ - $1/icons/runtime \ + $1/code/datums/greyscale/json_configs \ + $1/data/spritesheets \ + $1/icons \ $1/sound/runtime \ $1/strings \ $1/tgui/public \ @@ -23,9 +25,11 @@ if [ -d ".git" ]; then cp -r .git/logs/* $1/.git/logs/ fi +# NSV13 - different binary names cp nsv13.dmb nsv13.rsc $1/ cp -r _maps/* $1/_maps/ -cp -r icons/runtime/* $1/icons/runtime/ +cp -r code/datums/greyscale/json_configs/* $1/code/datums/greyscale/json_configs/ +cp -r icons/* $1/icons/ cp -r sound/runtime/* $1/sound/runtime/ cp -r strings/* $1/strings/ cp -r tgui/public/* $1/tgui/public/ diff --git a/tools/tgs4_scripts/PreCompile.sh b/tools/tgs4_scripts/PreCompile.sh index ed588b5d33d..563bb6def5a 100755 --- a/tools/tgs4_scripts/PreCompile.sh +++ b/tools/tgs4_scripts/PreCompile.sh @@ -73,7 +73,8 @@ apt-get install -y cmake build-essential gcc-multilib g++-multilib cmake wget # update auxmos if [ ! -d "auxmos" ]; then echo "Cloning Auxmos..." - git clone https://github.com/BeeStation/auxmos + # NSV13 - fork + git clone https://github.com/covertcorvid/auxmos cd auxmos else echo "Fetching Auxmos..." @@ -86,8 +87,8 @@ git checkout "$AUXMOS_VERSION" if [ -d "build" ]; then rm -R build fi -#note, if FUSION is ever fixed this needs changed to "all_reaction_hooks" -cargo rustc --target=i686-unknown-linux-gnu --release --features trit_fire_hook,plasma_fire_hook,generic_fire_hook -- -C target-cpu=native +# NSV13 - changed to katmos +cargo rustc --target=i686-unknown-linux-gnu --release --features katmos -- -C target-cpu=native mv -f target/i686-unknown-linux-gnu/release/libauxmos.so "$1/libauxmos.so" cd ../../..