/atom/var/CanAtmosPass = ATMOS_PASS_YES /atom/var/CanAtmosPassVertical = ATMOS_PASS_YES /atom/proc/CanAtmosPass(turf/T) switch (CanAtmosPass) if (ATMOS_PASS_PROC) return ATMOS_PASS_YES if (ATMOS_PASS_DENSITY) return !density else return CanAtmosPass /turf/CanAtmosPass = ATMOS_PASS_NO /turf/CanAtmosPassVertical = ATMOS_PASS_NO /turf/open/CanAtmosPass = ATMOS_PASS_PROC /turf/open/CanAtmosPassVertical = ATMOS_PASS_PROC /turf/open/CanAtmosPass(turf/T, vertical = FALSE) var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T) var/opp = dir_inverse_multiz(dir) var/R = FALSE if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src))) R = TRUE if(blocks_air || T.blocks_air) R = TRUE if (T == src) return !R for(var/obj/O in contents+T.contents) var/turf/other = (O.loc == src ? T : src) if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other)))) R = TRUE if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments atmos_supeconductivity |= dir T.atmos_supeconductivity |= opp return FALSE //no need to keep going, we got all we asked atmos_supeconductivity &= ~dir T.atmos_supeconductivity &= ~opp return !R /atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm. return FALSE /turf/proc/ImmediateCalculateAdjacentTurfs() var/canpass = CANATMOSPASS(src, src) var/canvpass = CANVERTICALATMOSPASS(src, src) for(var/direction in GLOB.cardinals_multiz) var/turf/T = get_step_multiz(src, direction) var/opp_dir = dir_inverse_multiz(direction) if(!isopenturf(T)) continue if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) ) LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(T.atmos_adjacent_turfs) atmos_adjacent_turfs[T] = direction T.atmos_adjacent_turfs[src] = opp_dir T.__update_extools_adjacent_turfs() else if (atmos_adjacent_turfs) atmos_adjacent_turfs -= T if (T.atmos_adjacent_turfs) T.atmos_adjacent_turfs -= src T.__update_extools_adjacent_turfs() UNSETEMPTY(T.atmos_adjacent_turfs) UNSETEMPTY(atmos_adjacent_turfs) src.atmos_adjacent_turfs = atmos_adjacent_turfs __update_extools_adjacent_turfs() /turf/proc/__update_extools_adjacent_turfs() //returns a list of adjacent turfs that can share air with this one. //alldir includes adjacent diagonal tiles that can share // air with both of the related adjacent cardinal tiles /turf/proc/GetAtmosAdjacentTurfs(alldir = 0) var/adjacent_turfs if (atmos_adjacent_turfs) adjacent_turfs = atmos_adjacent_turfs.Copy() else adjacent_turfs = list() if (!alldir) return adjacent_turfs var/turf/curloc = src for (var/direction in GLOB.diagonals_multiz) var/matchingDirections = 0 var/turf/S = get_step_multiz(curloc, direction) if(!S) continue for (var/checkDirection in GLOB.cardinals_multiz) var/turf/checkTurf = get_step(S, checkDirection) if(!S.atmos_adjacent_turfs || !S.atmos_adjacent_turfs[checkTurf]) continue if (adjacent_turfs[checkTurf]) matchingDirections++ if (matchingDirections >= 2) adjacent_turfs += S break return adjacent_turfs /atom/proc/air_update_turf(command = 0) if(!isturf(loc) && command) return var/turf/T = get_turf(loc) T.air_update_turf(command) /turf/air_update_turf(command = 0) if(command) ImmediateCalculateAdjacentTurfs() SSair.add_to_active(src,command) /atom/movable/proc/move_update_air(turf/T) if(isturf(T)) T.air_update_turf(1) air_update_turf(1) /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) if(!istype(T)) return T.atmos_spawn_air(text) /turf/open/atmos_spawn_air(text) if(!text || !air) return var/datum/gas_mixture/G = new G.parse_gas_string(text) air.merge(G) archive() SSair.add_to_active(src, 0)