From dff635b7f609fdc401c6cffb5d292142bbf4a99f Mon Sep 17 00:00:00 2001 From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Date: Tue, 6 Sep 2022 02:53:46 -0700 Subject: [PATCH] Atmos init speedup, saves 4 seconds (#69697) * Micro optimizes ssair's turf init, saving 2 seconds Most of this is making existing operations do more legwork, or cheaper. I did add cycle checking to ONLY init turf linking, which required creating a new proc. Did some horrible horrible things in said proc to save like 0.8 seconds. I think it was worth it. --- code/controllers/subsystem/air.dm | 52 +++++++++++++-- .../objects/items/grenades/atmos_grenades.dm | 3 +- code/game/turfs/closed/_closed.dm | 1 + code/game/turfs/open/_open.dm | 16 +++-- code/game/turfs/open/space/space.dm | 5 +- code/game/turfs/turf.dm | 6 +- code/modules/admin/verbs/fix_air.dm | 3 +- .../environmental/LINDA_system.dm | 65 +++++++++++++++++-- .../environmental/LINDA_turf_tile.dm | 18 +++-- .../atmospherics/gasmixtures/gas_mixture.dm | 65 ++++--------------- .../gasmixtures/immutable_mixtures.dm | 6 -- .../atmospherics/machinery/atmosmachinery.dm | 10 ++- .../machinery/components/components_base.dm | 2 +- .../components/unary_devices/thermomachine.dm | 2 +- .../atmospherics/machinery/pipes/pipes.dm | 2 +- code/modules/awaymissions/cordon.dm | 1 + .../mapGeneratorModules/helpers.dm | 2 +- code/modules/unit_tests/breath.dm | 6 +- 18 files changed, 165 insertions(+), 100 deletions(-) diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index e49518324d6..e224b195780 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -36,6 +36,9 @@ SUBSYSTEM_DEF(air) var/list/gas_reactions = list() var/list/atmos_gen var/list/planetary = list() //Lets cache static planetary mixes + /// List of gas string -> canonical gas mixture + var/list/strings_to_mix = list() + //Special functions lists var/list/turf/active_super_conductivity = list() @@ -521,7 +524,7 @@ SUBSYSTEM_DEF(air) /datum/controller/subsystem/air/proc/setup_allturfs() var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)) var/list/active_turfs = src.active_turfs - var/times_fired = ++src.times_fired + times_fired++ // Clear active turfs - faster than removing every single turf in the world // one-by-one, and Initalize_Atmos only ever adds `src` back in. @@ -531,13 +534,16 @@ SUBSYSTEM_DEF(air) active.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, COLOR_VIBRANT_LIME) #endif active_turfs.Cut() + var/time = 0 - for(var/thing in turfs_to_init) - var/turf/T = thing - if (T.blocks_air) + for(var/turf/T as anything in turfs_to_init) + if (!T.init_air) continue - T.Initalize_Atmos(times_fired) - CHECK_TICK + // We pass the tick as the current step so if we sleep the step changes + // This way we can make setting up adjacent turfs O(n) rather then O(n^2) + T.Initalize_Atmos(time) + if(CHECK_TICK) + time++ if(active_turfs.len) var/starting_ats = active_turfs.len @@ -561,8 +567,8 @@ SUBSYSTEM_DEF(air) active_turfs += new_turfs_to_check turfs_to_check = new_turfs_to_check - while (turfs_to_check.len) + var/ending_ats = active_turfs.len for(var/thing in excited_groups) var/datum/excited_group/EG = thing @@ -663,6 +669,38 @@ GLOBAL_LIST_EMPTY(colored_images) var/datum/atmosphere/atmostype = T atmos_gen[initial(atmostype.id)] = new atmostype +/// Takes a gas string, returns the matching mutable gas_mixture +/datum/controller/subsystem/air/proc/parse_gas_string(gas_string) + var/datum/gas_mixture/cached = strings_to_mix[gas_string] + if(cached) + if(istype(cached, /datum/gas_mixture/immutable)) + return cached + return cached.copy() + + var/datum/gas_mixture/canonical_mix = new() + // We set here so any future key changes don't fuck us + strings_to_mix[gas_string] = canonical_mix + gas_string = preprocess_gas_string(gas_string) + + var/list/gases = canonical_mix.gases + var/list/gas = params2list(gas_string) + if(gas["TEMP"]) + canonical_mix.temperature = text2num(gas["TEMP"]) + canonical_mix.temperature_archived = canonical_mix.temperature + gas -= "TEMP" + else // if we do not have a temp in the new gas mix lets assume room temp. + canonical_mix.temperature = T20C + for(var/id in gas) + var/path = id + if(!ispath(path)) + path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around + ADD_GAS(path, gases) + gases[path][MOLES] = text2num(gas[id]) + + if(istype(canonical_mix, /datum/gas_mixture/immutable)) + return canonical_mix + return canonical_mix.copy() + /datum/controller/subsystem/air/proc/preprocess_gas_string(gas_string) if(!atmos_gen) generate_atmos() diff --git a/code/game/objects/items/grenades/atmos_grenades.dm b/code/game/objects/items/grenades/atmos_grenades.dm index ba2fc8f4857..42e60b72f96 100644 --- a/code/game/objects/items/grenades/atmos_grenades.dm +++ b/code/game/objects/items/grenades/atmos_grenades.dm @@ -38,8 +38,7 @@ update_mob() playsound(src, 'sound/effects/spray2.ogg', 100, TRUE) var/list/connected_turfs = detect_room(origin = get_turf(src), max_size = fix_range) - var/datum/gas_mixture/base_mix = new - base_mix.parse_gas_string(OPENTURF_DEFAULT_ATMOS) + var/datum/gas_mixture/base_mix = SSair.parse_gas_string(OPENTURF_DEFAULT_ATMOS) for(var/turf/open/turf_fix in connected_turfs) if(turf_fix.blocks_air) continue diff --git a/code/game/turfs/closed/_closed.dm b/code/game/turfs/closed/_closed.dm index 66a9568c497..d5c64980d75 100644 --- a/code/game/turfs/closed/_closed.dm +++ b/code/game/turfs/closed/_closed.dm @@ -4,6 +4,7 @@ opacity = TRUE density = TRUE blocks_air = TRUE + init_air = FALSE rad_insulation = RAD_MEDIUM_INSULATION pass_flags_self = PASSCLOSEDTURF diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index e8d99e2558d..3e38126396c 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -160,21 +160,23 @@ /turf/open/indestructible/airblock icon_state = "bluespace" blocks_air = TRUE + init_air = FALSE baseturfs = /turf/open/indestructible/airblock -/turf/open/Initalize_Atmos(times_fired) +/turf/open/Initalize_Atmos(time) excited = FALSE update_visuals() - current_cycle = times_fired - immediate_calculate_adjacent_turfs() - for(var/i in atmos_adjacent_turfs) - var/turf/open/enemy_tile = i - var/datum/gas_mixture/enemy_air = enemy_tile.return_air() - if(!excited && air.compare(enemy_air)) + current_cycle = time + + init_immediate_calculate_adjacent_turfs() + for(var/turf/open/enemy_tile as anything in atmos_adjacent_turfs) + if(air.compare(enemy_tile.return_air())) //testing("Active turf found. Return value of compare(): [is_active]") excited = TRUE SSair.active_turfs += src + // No sense continuing to iterate + return /turf/open/GetHeatCapacity() . = air.heat_capacity() diff --git a/code/game/turfs/open/space/space.dm b/code/game/turfs/open/space/space.dm index fc6cf61dcc3..567894543d3 100644 --- a/code/game/turfs/open/space/space.dm +++ b/code/game/turfs/open/space/space.dm @@ -14,6 +14,8 @@ var/destination_y var/static/datum/gas_mixture/immutable/space/space_gas = new + // We do NOT want atmos adjacent turfs + init_air = FALSE run_later = TRUE plane = PLANE_SPACE layer = SPACE_LAYER @@ -75,9 +77,6 @@ var/turf/T = locate(destination_x, destination_y, destination_z) user.forceMove(T) -/turf/open/space/Initalize_Atmos(times_fired) - return - /turf/open/space/TakeTemperature(temp) /turf/open/space/RemoveLattice() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b7ebe82b58a..07ceaa284db 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -28,6 +28,9 @@ GLOBAL_LIST_EMPTY(station_turfs) var/max_fire_temperature_sustained = 0 var/blocks_air = FALSE + // If this turf should initialize atmos adjacent turfs or not + // Optimization, not for setting outside of initialize + var/init_air = TRUE var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes @@ -167,7 +170,8 @@ GLOBAL_LIST_EMPTY(station_turfs) return INITIALIZE_HINT_NORMAL -/turf/proc/Initalize_Atmos(times_fired) +/// Initializes our adjacent turfs. If you want to avoid this, do not override it, instead set init_air to FALSE +/turf/proc/Initalize_Atmos(time) CALCULATE_ADJACENT_TURFS(src, NORMAL_TURF) /turf/Destroy(force) diff --git a/code/modules/admin/verbs/fix_air.dm b/code/modules/admin/verbs/fix_air.dm index 998214297c1..ef67528c729 100644 --- a/code/modules/admin/verbs/fix_air.dm +++ b/code/modules/admin/verbs/fix_air.dm @@ -11,11 +11,10 @@ var/range=input("Enter range:","Num",2) as num message_admins("[key_name_admin(usr)] fixed air with range [range] in area [T.loc.name]") usr.log_message("fixed air with range [range] in area [T.loc.name]", LOG_ADMIN) - var/datum/gas_mixture/GM = new for(var/turf/open/F in range(range,T)) if(F.blocks_air) //skip walls continue - GM.parse_gas_string(F.initial_gas_mix) + var/datum/gas_mixture/GM = SSair.parse_gas_string(F.initial_gas_mix) F.copy_air(GM) F.update_visuals() diff --git a/code/modules/atmospherics/environmental/LINDA_system.dm b/code/modules/atmospherics/environmental/LINDA_system.dm index 9fa29217a80..ee78cb51b90 100644 --- a/code/modules/atmospherics/environmental/LINDA_system.dm +++ b/code/modules/atmospherics/environmental/LINDA_system.dm @@ -53,27 +53,81 @@ /atom/movable/proc/block_superconductivity() // objects that block air and don't let superconductivity act return FALSE -/turf/proc/immediate_calculate_adjacent_turfs() +/// This proc is a more deeply optimized version of immediate_calculate_adjacent_turfs +/// It contains dumbshit, and also stuff I just can't do at runtime +/// If you're not editing behavior, just read that proc. It's less bad +/turf/proc/init_immediate_calculate_adjacent_turfs() //Basic optimization, if we can't share why bother asking other people ya feel? + // You know it's gonna be stupid when they include a unit test in the atmos code + // Yes, inlining the string concat does save 0.1 seconds + #ifdef UNIT_TESTS + ASSERT(UP == 16) + ASSERT(DOWN == 32) + #endif + LAZYINITLIST(src.atmos_adjacent_turfs) + var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs + var/canpass = CANATMOSPASS(src, src, FALSE) + // I am essentially inlineing two get_dir_multizs here, because they're way too slow on their own. I'm sorry brother + var/list/z_traits = SSmapping.multiz_levels[z] + for(var/direction in GLOB.cardinals_multiz) + // Yes this is a reimplementation of get_step_mutliz. It's faster tho. fuck you + // Oh also yes UP and DOWN do just point to +1 and -1 and not z offsets + // Multiz is shitcode welcome home + var/turf/current_turf = (direction & (UP|DOWN)) ? \ + (direction & UP) ? \ + (z_traits["16"]) ? \ + (get_step(locate(x, y, z + 1), NONE)) : \ + (null) : \ + (z_traits["32"]) ? \ + (get_step(locate(x, y, z - 1), NONE)) : \ + (null) : \ + (get_step(src, direction)) + if(!isopenturf(current_turf)) // not interested in you brother + continue + // The assumption is that ONLY DURING INIT if two tiles have the same cycle, there's no way canpass(a->b) will be different then canpass(b->a), so this is faster + // Saves like 1.2 seconds + if(current_turf.current_cycle >= current_cycle) + continue + + //Can you and me form a deeper relationship, or is this just a passing wind + // (direction & (UP | DOWN)) is just "is this vertical" by the by + if(canpass && CANATMOSPASS(current_turf, src, (direction & (UP|DOWN))) && !(blocks_air || current_turf.blocks_air)) + LAZYINITLIST(current_turf.atmos_adjacent_turfs) + atmos_adjacent_turfs[current_turf] = TRUE + current_turf.atmos_adjacent_turfs[src] = TRUE + else + atmos_adjacent_turfs -= current_turf + if (current_turf.atmos_adjacent_turfs) + current_turf.atmos_adjacent_turfs -= src + UNSETEMPTY(current_turf.atmos_adjacent_turfs) + SEND_SIGNAL(current_turf, COMSIG_TURF_CALCULATED_ADJACENT_ATMOS) + + UNSETEMPTY(atmos_adjacent_turfs) + src.atmos_adjacent_turfs = atmos_adjacent_turfs + SEND_SIGNAL(src, COMSIG_TURF_CALCULATED_ADJACENT_ATMOS) + +/turf/proc/immediate_calculate_adjacent_turfs() + LAZYINITLIST(src.atmos_adjacent_turfs) + var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs var/canpass = CANATMOSPASS(src, src, FALSE) for(var/direction in GLOB.cardinals_multiz) var/turf/current_turf = get_step_multiz(src, direction) if(!isopenturf(current_turf)) // not interested in you brother continue + //Can you and me form a deeper relationship, or is this just a passing wind // (direction & (UP | DOWN)) is just "is this vertical" by the by if(canpass && CANATMOSPASS(current_turf, src, (direction & (UP|DOWN))) && !(blocks_air || current_turf.blocks_air)) - LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(current_turf.atmos_adjacent_turfs) atmos_adjacent_turfs[current_turf] = TRUE current_turf.atmos_adjacent_turfs[src] = TRUE else - if (atmos_adjacent_turfs) - atmos_adjacent_turfs -= current_turf + atmos_adjacent_turfs -= current_turf if (current_turf.atmos_adjacent_turfs) current_turf.atmos_adjacent_turfs -= src UNSETEMPTY(current_turf.atmos_adjacent_turfs) SEND_SIGNAL(current_turf, COMSIG_TURF_CALCULATED_ADJACENT_ATMOS) + UNSETEMPTY(atmos_adjacent_turfs) src.atmos_adjacent_turfs = atmos_adjacent_turfs SEND_SIGNAL(src, COMSIG_TURF_CALCULATED_ADJACENT_ATMOS) @@ -153,8 +207,7 @@ if(!text || !air) return - var/datum/gas_mixture/turf_mixture = new - turf_mixture.parse_gas_string(text) + var/datum/gas_mixture/turf_mixture = SSair.parse_gas_string(text) air.merge(turf_mixture) archive() diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index d85d70ac01f..135a518e9bf 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -56,8 +56,7 @@ /turf/open/Initialize(mapload) if(!blocks_air) - air = new - air.copy_from_turf(src) + air = create_gas_mixture() if(planetary_atmos) if(!SSair.planetary[initial_gas_mix]) var/datum/gas_mixture/immutable/planetary/mix = new @@ -75,6 +74,18 @@ /////////////////GAS MIXTURE PROCS/////////////////// +///Copies all gas info from the turf into a new gas_mixture, along with our temperature +///Returns the created gas_mixture +/turf/proc/create_gas_mixture() + var/datum/gas_mixture/mix = SSair.parse_gas_string(initial_gas_mix) + + //acounts for changes in temperature + var/turf/parent = parent_type + if(temperature != initial(temperature) || temperature != initial(parent.temperature)) + mix.temperature = temperature + + return mix + /turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air if(!giver) return FALSE @@ -100,8 +111,7 @@ /turf/return_air() RETURN_TYPE(/datum/gas_mixture) - var/datum/gas_mixture/copied_mixture = new - copied_mixture.copy_from_turf(src) + var/datum/gas_mixture/copied_mixture = create_gas_mixture() return copied_mixture /turf/open/return_air() diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index acb8b58f0db..22150051ee9 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -288,7 +288,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) return copy ///Copies variables from sample, moles multiplicated by partial -///Returns: 1 if we are mutable, 0 otherwise +///Returns: TRUE if we are mutable, FALSE otherwise /datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample, partial = 1) var/list/cached_gases = gases //accessing datum vars is slower than proc vars var/list/sample_gases = sample.gases @@ -301,42 +301,8 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) ASSERT_GAS(id,src) cached_gases[id][MOLES] = sample_gases[id][MOLES] * partial - return 1 - -///Copies all gas info from the turf into the gas list along with temperature -///Returns: TRUE if we are mutable, FALSE otherwise -/datum/gas_mixture/proc/copy_from_turf(turf/model) - parse_gas_string(model.initial_gas_mix) - - //acounts for changes in temperature - var/turf/model_parent = model.parent_type - if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature)) - temperature = model.temperature - return TRUE -///Copies variables from a particularly formatted string. -///Returns: 1 if we are mutable, 0 otherwise -/datum/gas_mixture/proc/parse_gas_string(gas_string) - gas_string = SSair.preprocess_gas_string(gas_string) - - var/list/gases = src.gases - var/list/gas = params2list(gas_string) - if(gas["TEMP"]) - temperature = text2num(gas["TEMP"]) - temperature_archived = temperature - gas -= "TEMP" - else // if we do not have a temp in the new gas mix lets assume room temp. - temperature = T20C - gases.Cut() - for(var/id in gas) - var/path = id - if(!ispath(path)) - path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around - ADD_GAS(path, gases) - gases[path][MOLES] = text2num(gas[id]) - return 1 - /// Performs air sharing calculations between two gas_mixtures /// share() is communitive, which means A.share(B) needs to be the same as B.share(A) /// If we don't retain this, we will get negative moles. Don't do it @@ -459,25 +425,22 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) /datum/gas_mixture/proc/compare(datum/gas_mixture/sample) var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars var/list/cached_gases = gases + var/moles_sum = 0 for(var/id in cached_gases | sample_gases) // compare gases from either mixture - var/gas_moles = cached_gases[id] - gas_moles = gas_moles ? gas_moles[MOLES] : 0 - var/sample_moles = sample_gases[id] - sample_moles = sample_moles ? sample_moles[MOLES] : 0 - var/delta = abs(gas_moles - sample_moles) - if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \ - delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE) - return id + // Yes this is actually fast. I too hate it here + var/gas_moles = cached_gases[id]?[MOLES] || 0 + var/sample_moles = sample_gases[id]?[MOLES] || 0 + // Brief explanation. We are much more likely to not pass this first check then pass the first and fail the second + // Because of this, double calculating the delta is FASTER then inserting it into a var + if(abs(gas_moles - sample_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) + if(abs(gas_moles - sample_moles) > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE) + return id + // similarly, we will rarely get cut off, so this is cheaper then doing it later + moles_sum += gas_moles - var/our_moles - TOTAL_MOLES(cached_gases, our_moles) - if(our_moles > MINIMUM_MOLES_DELTA_TO_MOVE) //Don't consider temp if there's not enough mols - var/temp = temperature - var/sample_temp = sample.temperature - - var/temperature_delta = abs(temp - sample_temp) - if(temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) + if(moles_sum > MINIMUM_MOLES_DELTA_TO_MOVE) //Don't consider temp if there's not enough mols + if(abs(temperature - sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) return "temp" return "" diff --git a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm index e6cd8f75499..103c2653fd4 100644 --- a/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm +++ b/code/modules/atmospherics/gasmixtures/immutable_mixtures.dm @@ -34,12 +34,6 @@ /datum/gas_mixture/immutable/copy_from() return FALSE //we're immutable. -/datum/gas_mixture/immutable/copy_from_turf() - return FALSE //we're immutable. - -/datum/gas_mixture/immutable/parse_gas_string() - return FALSE //we're immutable. - /datum/gas_mixture/immutable/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity) . = ..() temperature = initial_temperature diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index e879cbc76ed..76263b9a5c7 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -294,7 +294,7 @@ * * obj/machinery/atmospherics/target - the machinery we want to connect to */ /obj/machinery/atmospherics/proc/check_connectable_color(obj/machinery/atmospherics/target) - if(lowertext(target.pipe_color) == lowertext(pipe_color) || ((target.pipe_flags | pipe_flags) & PIPING_ALL_COLORS) || lowertext(target.pipe_color) == lowertext(COLOR_VERY_LIGHT_GRAY) || lowertext(pipe_color) == lowertext(COLOR_VERY_LIGHT_GRAY)) + if(target.pipe_color == pipe_color || ((target.pipe_flags | pipe_flags) & PIPING_ALL_COLORS) || target.pipe_color == COLOR_VERY_LIGHT_GRAY || pipe_color == COLOR_VERY_LIGHT_GRAY) return TRUE return FALSE @@ -467,8 +467,7 @@ /obj/machinery/atmospherics/on_construction(obj_color, set_layer = PIPING_LAYER_DEFAULT) if(can_unwrench) add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY) - pipe_color = obj_color - update_name() + set_pipe_color(obj_color) set_piping_layer(set_layer) atmos_init() var/list/nodes = pipeline_expansion() @@ -588,3 +587,8 @@ */ /obj/machinery/atmospherics/proc/paint(paint_color) return FALSE + +/// Setter for pipe color, so we can ensure it's all uniform and save cpu time +/obj/machinery/atmospherics/proc/set_pipe_color(pipe_colour) + src.pipe_color = uppertext(pipe_colour) + update_name() diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index 691c95ba87e..08a2ab22ccd 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -242,7 +242,7 @@ /obj/machinery/atmospherics/components/paint(paint_color) if(paintable) add_atom_colour(paint_color, FIXED_COLOUR_PRIORITY) - pipe_color = paint_color + set_pipe_color(paint_color) update_node_icon() return paintable diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index a8ef69eadae..a5cdc8100b7 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -197,7 +197,7 @@ if(!panel_open) return color_index = (color_index >= GLOB.pipe_paint_colors.len) ? (color_index = 1) : (color_index = 1 + color_index) - pipe_color = GLOB.pipe_paint_colors[GLOB.pipe_paint_colors[color_index]] + set_pipe_color(GLOB.pipe_paint_colors[GLOB.pipe_paint_colors[color_index]]) visible_message("You set [src]'s pipe color to [GLOB.pipe_color_name[pipe_color]].") update_appearance() return TOOL_ACT_TOOLTYPE_SUCCESS diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm index bbd122b43dc..ab04990906c 100644 --- a/code/modules/atmospherics/machinery/pipes/pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/pipes.dm @@ -124,7 +124,7 @@ /obj/machinery/atmospherics/pipe/paint(paint_color) if(paintable) add_atom_colour(paint_color, FIXED_COLOUR_PRIORITY) - pipe_color = paint_color + set_pipe_color(pipe_color) update_node_icon() return paintable diff --git a/code/modules/awaymissions/cordon.dm b/code/modules/awaymissions/cordon.dm index 5da64bd2084..3eee15e8839 100644 --- a/code/modules/awaymissions/cordon.dm +++ b/code/modules/awaymissions/cordon.dm @@ -9,6 +9,7 @@ opacity = TRUE density = TRUE blocks_air = TRUE + init_air = FALSE always_lit = TRUE bullet_bounce_sound = null turf_flags = NOJAUNT diff --git a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm index 844b41c05c7..38381d569ca 100644 --- a/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm +++ b/code/modules/procedural_mapping/mapGeneratorModules/helpers.dm @@ -14,7 +14,7 @@ SSair.remove_from_active(T) for(var/turf/open/T in map) if(T.air) - T.air.copy_from_turf(T) + T.air = T.create_gas_mixture() SSair.add_to_active(T, TRUE) /datum/map_generator_module/bottom_layer/massdelete diff --git a/code/modules/unit_tests/breath.dm b/code/modules/unit_tests/breath.dm index d564b291a60..428a120511b 100644 --- a/code/modules/unit_tests/breath.dm +++ b/code/modules/unit_tests/breath.dm @@ -25,8 +25,7 @@ var/turf/open/to_fill = run_loc_floor_bottom_left //Prep the floor to_fill.initial_gas_mix = OPENTURF_DEFAULT_ATMOS - to_fill.air = new - to_fill.air.copy_from_turf(to_fill) + to_fill.air = to_fill.create_gas_mixture() lab_rat.breathe() @@ -65,8 +64,7 @@ var/turf/open/to_fill = run_loc_floor_bottom_left //Prep the floor to_fill.initial_gas_mix = LAVALAND_DEFAULT_ATMOS - to_fill.air = new - to_fill.air.copy_from_turf(to_fill) + to_fill.air = to_fill.create_gas_mixture() lab_rat.breathe()