From 83fdc0942cb0b46373db19760e416b0cc2be4532 Mon Sep 17 00:00:00 2001 From: Aryn Date: Wed, 19 Feb 2014 16:56:53 -0700 Subject: [PATCH] Completed arduous process of standardizing new code. --- baystation12.dme | 3 - code/ZAS/Connection.dm | 259 +++++------ code/ZAS/ConnectionGroup.dm | 576 ++++++++++++----------- code/ZAS/Debug.dm | 8 +- code/ZAS/Functions.dm | 243 ---------- code/ZAS/Turf.dm | 26 +- code/ZAS/ZAS_Zones.dm | 906 ------------------------------------ code/ZAS/Zone.dm | 213 +++++---- 8 files changed, 534 insertions(+), 1700 deletions(-) delete mode 100644 code/ZAS/Functions.dm delete mode 100644 code/ZAS/ZAS_Zones.dm diff --git a/baystation12.dme b/baystation12.dme index 83a200fc15c..712a0adaafc 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1328,13 +1328,10 @@ #include "code\ZAS\Airflow.dm" #include "code\ZAS\Connection.dm" #include "code\ZAS\Debug.dm" -#include "code\ZAS\FEA_gas_mixture.dm" -#include "code\ZAS\FEA_system.dm" #include "code\ZAS\Fire.dm" #include "code\ZAS\Functions.dm" #include "code\ZAS\Plasma.dm" #include "code\ZAS\Variable Settings.dm" -#include "code\ZAS\ZAS_Turfs.dm" #include "code\ZAS\ZAS_Zones.dm" #include "interface\interface.dm" #include "interface\skin.dmf" diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index 35970fbc597..2615effaa25 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -2,161 +2,154 @@ #define CONNECTION_SPACE 4 #define CONNECTION_INVALID 8 -turf/simulated/var/tmp/connection_manager/connections = new - -connection_manager - var/connection/N - var/connection/S - var/connection/E - var/connection/W - - proc/get(d) - switch(d) - if(NORTH) - if(check(N)) return N - else return null - if(SOUTH) - if(check(S)) return S - else return null - if(EAST) - if(check(E)) return E - else return null - if(WEST) - if(check(W)) return W - else return null - - proc/place(connection/c, d) - switch(d) - if(NORTH) N = c - if(SOUTH) S = c - if(EAST) E = c - if(WEST) W = c - - proc/close(d) - if(check(N) && (NORTH & d) && !N.direct()) N.erase() - if(check(S) && (SOUTH & d) && !S.direct()) S.erase() - if(check(E) && (EAST & d) && !E.direct()) E.erase() - if(check(W) && (WEST & d) && !W.direct()) W.erase() - - proc/update_all() - if(check(N)) N.update() - if(check(S)) S.update() - if(check(E)) E.update() - if(check(W)) W.update() - - /*proc/open(d) - if(check(N) && (NORTH & d) && N.indirect()) N.open() - if(check(S) && (SOUTH & d) && S.indirect()) S.open() - if(check(E) && (EAST & d) && E.indirect()) E.open() - if(check(W) && (WEST & d) && W.indirect()) W.open()*/ - - proc/check(connection/c) - return c && c.valid() +/turf/simulated/var/tmp/connection_manager/connections = new -connection - var/turf/simulated/A - var/turf/simulated/B - var/zone/zoneA - var/zone/zoneB +/connection_manager/var/connection/N +/connection_manager/var/connection/S +/connection_manager/var/connection/E +/connection_manager/var/connection/W - var/connection_edge/edge +/connection_manager/proc/get(d) + switch(d) + if(NORTH) + if(check(N)) return N + else return null + if(SOUTH) + if(check(S)) return S + else return null + if(EAST) + if(check(E)) return E + else return null + if(WEST) + if(check(W)) return W + else return null - var/state = 0 +/connection_manager/proc/place(connection/c, d) + switch(d) + if(NORTH) N = c + if(SOUTH) S = c + if(EAST) E = c + if(WEST) W = c - New(turf/simulated/A, turf/simulated/B) - #ifdef ZASDBG - ASSERT(air_master.has_valid_zone(A)) - //ASSERT(air_master.has_valid_zone(B)) - #endif - src.A = A - src.B = B - zoneA = A.zone - if(!istype(B)) - mark_space() - edge = air_master.get_edge(A.zone,B) - edge.add_connection(src) - else - zoneB = B.zone - edge = air_master.get_edge(A.zone,B.zone) - edge.add_connection(src) +/connection_managerproc/close(d) + if(check(N) && (NORTH & d) && !N.direct()) N.erase() + if(check(S) && (SOUTH & d) && !S.direct()) S.erase() + if(check(E) && (EAST & d) && !E.direct()) E.erase() + if(check(W) && (WEST & d) && !W.direct()) W.erase() - proc/mark_direct() - state |= CONNECTION_DIRECT +/connection_manager/proc/update_all() + if(check(N)) N.update() + if(check(S)) S.update() + if(check(E)) E.update() + if(check(W)) W.update() - proc/mark_indirect() - state &= ~CONNECTION_DIRECT +/connection_manager/proc/check(connection/c) + return c && c.valid() - proc/mark_space() - state |= CONNECTION_SPACE - proc/direct() - return (state & CONNECTION_DIRECT) +/connection/var/turf/simulated/A +/connection/var/turf/simulated/B +/connection/var/zone/zoneA +/connection/var/zone/zoneB - proc/valid() - return !(state & CONNECTION_INVALID) +/connection/var/connection_edge/edge - proc/erase() - edge.remove_connection(src) - state |= CONNECTION_INVALID +/connection/var/state = 0 - proc/update() - //world << "Updated, \..." - if(!istype(A,/turf/simulated)) - //world << "Invalid A." - erase() - return +/connection/New(turf/simulated/A, turf/simulated/B) + #ifdef ZASDBG + ASSERT(air_master.has_valid_zone(A)) + //ASSERT(air_master.has_valid_zone(B)) + #endif + src.A = A + src.B = B + zoneA = A.zone + if(!istype(B)) + mark_space() + edge = air_master.get_edge(A.zone,B) + edge.add_connection(src) + else + zoneB = B.zone + edge = air_master.get_edge(A.zone,B.zone) + edge.add_connection(src) - if(air_master.air_blocked(A,B)) - //world << "Blocked connection." - erase() - return +/connection/proc/mark_direct() + state |= CONNECTION_DIRECT - var/b_is_space = !istype(B,/turf/simulated) +/connection/proc/mark_indirect() + state &= ~CONNECTION_DIRECT - if(state & CONNECTION_SPACE) - if(!b_is_space) - //world << "Invalid B." - erase() - return - if(A.zone != zoneA) - //world << "Zone changed, \..." - if(!A.zone) - erase() - //world << "erased." - return - else - edge.remove_connection(src) - edge = air_master.get_edge(A.zone, B) - edge.add_connection(src) - zoneA = A.zone +/connection/proc/mark_space() + state |= CONNECTION_SPACE - //world << "valid." - return +/connection/proc/direct() + return (state & CONNECTION_DIRECT) - else if(b_is_space) +/connection/proc/valid() + return !(state & CONNECTION_INVALID) + +/connection/proc/erase() + edge.remove_connection(src) + state |= CONNECTION_INVALID + +/connection/proc/update() + //world << "Updated, \..." + if(!istype(A,/turf/simulated)) + //world << "Invalid A." + erase() + return + + if(air_master.air_blocked(A,B)) + //world << "Blocked connection." + erase() + return + + var/b_is_space = !istype(B,/turf/simulated) + + if(state & CONNECTION_SPACE) + if(!b_is_space) //world << "Invalid B." erase() return + if(A.zone != zoneA) + //world << "Zone changed, \..." + if(!A.zone) + erase() + //world << "erased." + return + else + edge.remove_connection(src) + edge = air_master.get_edge(A.zone, B) + edge.add_connection(src) + zoneA = A.zone - if(A.zone == B.zone) - //world << "A == B" + //world << "valid." + return + + else if(b_is_space) + //world << "Invalid B." + erase() + return + + if(A.zone == B.zone) + //world << "A == B" + erase() + return + + if(A.zone != zoneA || (zoneB && (B.zone != zoneB))) + + //world << "Zones changed, \..." + if(A.zone && B.zone) + edge.remove_connection(src) + edge = air_master.get_edge(A.zone, B.zone) + edge.add_connection(src) + zoneA = A.zone + zoneB = B.zone + else + //world << "erased." erase() return - if(A.zone != zoneA || (zoneB && (B.zone != zoneB))) - //world << "Zones changed, \..." - if(A.zone && B.zone) - edge.remove_connection(src) - edge = air_master.get_edge(A.zone, B.zone) - edge.add_connection(src) - zoneA = A.zone - zoneB = B.zone - else - //world << "erased." - erase() - return - - - //world << "valid." \ No newline at end of file + //world << "valid." \ No newline at end of file diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index b114e559aeb..360372a83a9 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -1,348 +1,344 @@ -connection_edge - var/zone/A - var/list/connecting_turfs = list() +/connection_edge/var/zone/A - var/coefficient = 0 - var/id +/connection_edge/var/list/connecting_turfs = list() - New() - CRASH("Cannot make connection edge without specifications.") +/connection_edge/var/coefficient = 0 +/connection_edge/var/id - proc/add_connection(connection/c) - coefficient++ - //world << "Connection added. Coefficient: [coefficient]" +/connection_edge/New() + CRASH("Cannot make connection edge without specifications.") - proc/remove_connection(connection/c) - //world << "Connection removed. Coefficient: [coefficient-1]" - coefficient-- - if(coefficient <= 0) +/connection_edge/proc/add_connection(connection/c) + coefficient++ + //world << "Connection added. Coefficient: [coefficient]" + +/connection_edge/proc/remove_connection(connection/c) + //world << "Connection removed. Coefficient: [coefficient-1]" + coefficient-- + if(coefficient <= 0) + erase() + +/connection_edge/proc/contains_zone(zone/Z) + +/connection_edge/proc/erase() + air_master.remove_edge(src) + //world << "Erased." + +/connection_edge/proc/tick() + +/connection_edge/proc/flow(list/movable, differential, repelled) + for(var/atom/movable/M in movable) + + //If they're already being tossed, don't do it again. + if(M.last_airflow > world.time - vsc.airflow_delay) continue + if(M.airflow_speed) continue + + //Check for knocking people over + if(ismob(M) && differential > vsc.airflow_stun_pressure) + if(M:status_flags & GODMODE) continue + M:airflow_stun() + + if(M.check_airflow_movable(differential)) + //Check for things that are in range of the midpoint turfs. + var/list/close_turfs = list() + for(var/turf/U in connecting_turfs) + if(get_dist(M,U) < world.view) close_turfs += U + if(!close_turfs.len) continue + + M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards. + + if(repelled) spawn if(M) M.RepelAirflowDest(differential/5) + else spawn if(M) M.GotoAirflowDest(differential/10) + + + + +/connection_edge/zone/var/zone/B +/connection_edge/zone/var/direct = 0 + +/connection_edge/zone/New(zone/A, zone/B) + + src.A = A + src.B = B + A.edges.Add(src) + B.edges.Add(src) + //id = edge_id(A,B) + //world << "New edge between [A] and [B]" + +/connection_edge/zone/add_connection(connection/c) + . = ..() + connecting_turfs.Add(c.A) + if(c.direct()) direct++ + +/connection_edge/zone/remove_connection(connection/c) + connecting_turfs.Remove(c.A) + if(c.direct()) direct-- + . = ..() + +/connection_edge/zone/contains_zone(zone/Z) + return A == Z || B == Z + +/connection_edge/zone/erase() + A.edges.Remove(src) + B.edges.Remove(src) + . = ..() + +/connection_edge/zone/tick() + //world << "[id]: Tick [air_master.current_cycle]: \..." + if(direct) + if(air_master.equivalent_pressure(A, B)) + //world << "merged." erase() + air_master.merge(A, B) + //world << "zones merged." + return - proc/contains_zone(zone/Z) + //air_master.equalize(A, B) + ShareRatio(A.air,B.air,coefficient) + air_master.mark_zone_update(A) + air_master.mark_zone_update(B) + //world << "equalized." - proc/erase() - air_master.remove_edge(src) - //world << "Erased." + var/differential = A.air.return_pressure() - B.air.return_pressure() + if(abs(differential) < vsc.airflow_lightest_pressure) return - proc/tick() + var/list/attracted + var/list/repelled + if(differential > 0) + attracted = A.movables() + repelled = B.movables() + else + attracted = B.movables() + repelled = A.movables() - proc/flow(list/movable, differential, repelled) - for(var/atom/movable/M in movable) - - //If they're already being tossed, don't do it again. - if(M.last_airflow > world.time - vsc.airflow_delay) continue - if(M.airflow_speed) continue - - //Check for knocking people over - if(ismob(M) && differential > vsc.airflow_stun_pressure) - if(M:status_flags & GODMODE) continue - M:airflow_stun() - - if(M.check_airflow_movable(differential)) - //Check for things that are in range of the midpoint turfs. - var/list/close_turfs = list() - for(var/turf/U in connecting_turfs) - if(get_dist(M,U) < world.view) close_turfs += U - if(!close_turfs.len) continue - - M.airflow_dest = pick(close_turfs) //Pick a random midpoint to fly towards. - - if(repelled) spawn if(M) M.RepelAirflowDest(differential/5) - else spawn if(M) M.GotoAirflowDest(differential/10) + flow(attracted, abs(differential), 0) + flow(repelled, abs(differential), 1) -connection_edge/zone +/connection_edge/unsimulated/var/turf/B +/connection_edge/unsimulated/var/datum/gas_mixture/air - var/zone/B - var/direct = 0 +/connection_edge/unsimulated/New(zone/A, turf/B) + src.A = A + src.B = B + A.edges.Add(src) + air = B.return_air() + //id = 52*A.id + //world << "New edge from [A.id] to [B]." - New(zone/A, zone/B) +/connection_edge/unsimulated/add_connection(connection/c) + . = ..() + connecting_turfs.Add(c.B) - src.A = A - src.B = B - A.edges.Add(src) - B.edges.Add(src) - //id = edge_id(A,B) - //world << "New edge between [A] and [B]" +/connection_edge/unsimulated/remove_connection(connection/c) + connecting_turfs.Remove(c.B) + . = ..() - add_connection(connection/c) - . = ..() - connecting_turfs.Add(c.A) - if(c.direct()) direct++ +/connection_edge/unsimulated/contains_zone(zone/Z) + return A == Z - remove_connection(connection/c) - connecting_turfs.Remove(c.A) - if(c.direct()) direct-- - . = ..() +/connection_edge/unsimulated/tick() + //world << "[id]: Tick [air_master.current_cycle]: To [B]!" + //A.air.mimic(B, coefficient) + ShareSpace(A.air,air) + air_master.mark_zone_update(A) - contains_zone(zone/Z) - return A == Z || B == Z + var/differential = A.air.return_pressure() - air.return_pressure() + if(abs(differential) < vsc.airflow_lightest_pressure) return - erase() - A.edges.Remove(src) - B.edges.Remove(src) - . = ..() - - tick() - //world << "[id]: Tick [air_master.current_cycle]: \..." - if(direct) - if(air_master.equivalent_pressure(A, B)) - //world << "merged." - erase() - air_master.merge(A, B) - //world << "zones merged." - return - - //air_master.equalize(A, B) - ShareRatio(A.air,B.air,coefficient) - air_master.mark_zone_update(A) - air_master.mark_zone_update(B) - //world << "equalized." - - var/differential = A.air.return_pressure() - B.air.return_pressure() - if(abs(differential) < vsc.airflow_lightest_pressure) return - - var/list/attracted - var/list/repelled - if(differential > 0) - attracted = A.movables() - repelled = B.movables() - else - attracted = B.movables() - repelled = A.movables() - - flow(attracted, abs(differential), 0) - flow(repelled, abs(differential), 1) - -connection_edge/unsimulated - var/turf/B - var/datum/gas_mixture/air - - New(zone/A, turf/B) - src.A = A - src.B = B - A.edges.Add(src) - air = B.return_air() - //id = 52*A.id - //world << "New edge from [A.id] to [B]." - - add_connection(connection/c) - . = ..() - connecting_turfs.Add(c.B) - - remove_connection(connection/c) - connecting_turfs.Remove(c.B) - . = ..() - - contains_zone(zone/Z) - return A == Z - - tick() - //world << "[id]: Tick [air_master.current_cycle]: To [B]!" - //A.air.mimic(B, coefficient) - ShareSpace(A.air,air) - air_master.mark_zone_update(A) - - var/differential = A.air.return_pressure() - air.return_pressure() - if(abs(differential) < vsc.airflow_lightest_pressure) return - - var/list/attracted = A.movables() - flow(attracted, abs(differential), differential < 0) - - -//proc/edge_id(zone/A, zone/B) -// return 52 * A.id + B.id + var/list/attracted = A.movables() + flow(attracted, abs(differential), differential < 0) var/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66) proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) - //Shares a specific ratio of gas between mixtures using simple weighted averages. - var - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - ratio = sharing_lookup_table[6] - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - - size = max(1,A.group_multiplier) - share_size = max(1,B.group_multiplier) - - full_oxy = A.oxygen * size - full_nitro = A.nitrogen * size - full_co2 = A.carbon_dioxide * size - full_plasma = A.toxins * size - - full_heat_capacity = A.heat_capacity() * size - - s_full_oxy = B.oxygen * share_size - s_full_nitro = B.nitrogen * share_size - s_full_co2 = B.carbon_dioxide * share_size - s_full_plasma = B.toxins * share_size - - s_full_heat_capacity = B.heat_capacity() * share_size - - oxy_avg = (full_oxy + s_full_oxy) / (size + share_size) - nit_avg = (full_nitro + s_full_nitro) / (size + share_size) - co2_avg = (full_co2 + s_full_co2) / (size + share_size) - plasma_avg = (full_plasma + s_full_plasma) / (size + share_size) - - temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity) - +//Shares a specific ratio of gas between mixtures using simple weighted averages. +var //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[connecting_tiles] + ratio = sharing_lookup_table[6] //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) - A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg ) - A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) - A.toxins = max(0, (A.toxins - plasma_avg) * (1-ratio) + plasma_avg ) + size = max(1,A.group_multiplier) + share_size = max(1,B.group_multiplier) - A.temperature = max(0, (A.temperature - temp_avg) * (1-ratio) + temp_avg ) + full_oxy = A.oxygen * size + full_nitro = A.nitrogen * size + full_co2 = A.carbon_dioxide * size + full_plasma = A.toxins * size - B.oxygen = max(0, (B.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) - B.nitrogen = max(0, (B.nitrogen - nit_avg) * (1-ratio) + nit_avg ) - B.carbon_dioxide = max(0, (B.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) - B.toxins = max(0, (B.toxins - plasma_avg) * (1-ratio) + plasma_avg ) + full_heat_capacity = A.heat_capacity() * size - B.temperature = max(0, (B.temperature - temp_avg) * (1-ratio) + temp_avg ) + s_full_oxy = B.oxygen * share_size + s_full_nitro = B.nitrogen * share_size + s_full_co2 = B.carbon_dioxide * share_size + s_full_plasma = B.toxins * share_size - for(var/datum/gas/G in A.trace_gases) - var/datum/gas/H = locate(G.type) in B.trace_gases - if(H) - var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + s_full_heat_capacity = B.heat_capacity() * share_size - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg - else - H = new G.type - B.trace_gases += H - var/G_avg = (G.moles*size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + oxy_avg = (full_oxy + s_full_oxy) / (size + share_size) + nit_avg = (full_nitro + s_full_nitro) / (size + share_size) + co2_avg = (full_co2 + s_full_co2) / (size + share_size) + plasma_avg = (full_plasma + s_full_plasma) / (size + share_size) - for(var/datum/gas/G in B.trace_gases) - var/datum/gas/H = locate(G.type) in A.trace_gases - if(!H) - H = new G.type - A.trace_gases += H - var/G_avg = (G.moles*size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity) - A.update_values() - B.update_values() +//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD +if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. + ratio = sharing_lookup_table[connecting_tiles] +//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - if(A.compare(B)) return 1 - else return 0 +A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) +A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg ) +A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) +A.toxins = max(0, (A.toxins - plasma_avg) * (1-ratio) + plasma_avg ) + +A.temperature = max(0, (A.temperature - temp_avg) * (1-ratio) + temp_avg ) + +B.oxygen = max(0, (B.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) +B.nitrogen = max(0, (B.nitrogen - nit_avg) * (1-ratio) + nit_avg ) +B.carbon_dioxide = max(0, (B.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) +B.toxins = max(0, (B.toxins - plasma_avg) * (1-ratio) + plasma_avg ) + +B.temperature = max(0, (B.temperature - temp_avg) * (1-ratio) + temp_avg ) + +for(var/datum/gas/G in A.trace_gases) + var/datum/gas/H = locate(G.type) in B.trace_gases + if(H) + var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + else + H = new G.type + B.trace_gases += H + var/G_avg = (G.moles*size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + +for(var/datum/gas/G in B.trace_gases) + var/datum/gas/H = locate(G.type) in A.trace_gases + if(!H) + H = new G.type + A.trace_gases += H + var/G_avg = (G.moles*size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + +A.update_values() +B.update_values() + +if(A.compare(B)) return 1 +else return 0 proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) - //A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room. - if(!unsimulated_tiles) +//A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room. +if(!unsimulated_tiles) + return 0 + +var + unsim_oxygen = 0 + unsim_nitrogen = 0 + unsim_co2 = 0 + unsim_plasma = 0 + unsim_heat_capacity = 0 + unsim_temperature = 0 + + size = max(1,A.group_multiplier) + +var/tileslen +var/share_size + +if(istype(unsimulated_tiles, /datum/gas_mixture)) + var/datum/gas_mixture/avg_unsim = unsimulated_tiles + unsim_oxygen = avg_unsim.oxygen + unsim_co2 = avg_unsim.carbon_dioxide + unsim_nitrogen = avg_unsim.nitrogen + unsim_plasma = avg_unsim.toxins + unsim_temperature = avg_unsim.temperature + share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier) + tileslen = avg_unsim.group_multiplier + +else if(istype(unsimulated_tiles, /list)) + if(!unsimulated_tiles.len) return 0 + // We use the same size for the potentially single space tile + // as we use for the entire room. Why is this? + // Short answer: We do not want larger rooms to depressurize more + // slowly than small rooms, preserving our good old "hollywood-style" + // oh-shit effect when large rooms get breached, but still having small + // rooms remain pressurized for long enough to make escape possible. + share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len) + var/correction_ratio = share_size / unsimulated_tiles.len - var - unsim_oxygen = 0 - unsim_nitrogen = 0 - unsim_co2 = 0 - unsim_plasma = 0 - unsim_heat_capacity = 0 - unsim_temperature = 0 + for(var/turf/T in unsimulated_tiles) + unsim_oxygen += T.oxygen + unsim_co2 += T.carbon_dioxide + unsim_nitrogen += T.nitrogen + unsim_plasma += T.toxins + unsim_temperature += T.temperature/unsimulated_tiles.len - size = max(1,A.group_multiplier) + //These values require adjustment in order to properly represent a room of the specified size. + unsim_oxygen *= correction_ratio + unsim_co2 *= correction_ratio + unsim_nitrogen *= correction_ratio + unsim_plasma *= correction_ratio + tileslen = unsimulated_tiles.len - var/tileslen - var/share_size +else //invalid input type + return 0 - if(istype(unsimulated_tiles, /datum/gas_mixture)) - var/datum/gas_mixture/avg_unsim = unsimulated_tiles - unsim_oxygen = avg_unsim.oxygen - unsim_co2 = avg_unsim.carbon_dioxide - unsim_nitrogen = avg_unsim.nitrogen - unsim_plasma = avg_unsim.toxins - unsim_temperature = avg_unsim.temperature - share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier) - tileslen = avg_unsim.group_multiplier +unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma) - else if(istype(unsimulated_tiles, /list)) - if(!unsimulated_tiles.len) - return 0 - // We use the same size for the potentially single space tile - // as we use for the entire room. Why is this? - // Short answer: We do not want larger rooms to depressurize more - // slowly than small rooms, preserving our good old "hollywood-style" - // oh-shit effect when large rooms get breached, but still having small - // rooms remain pressurized for long enough to make escape possible. - share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len) - var/correction_ratio = share_size / unsimulated_tiles.len +var + ratio = sharing_lookup_table[6] - for(var/turf/T in unsimulated_tiles) - unsim_oxygen += T.oxygen - unsim_co2 += T.carbon_dioxide - unsim_nitrogen += T.nitrogen - unsim_plasma += T.toxins - unsim_temperature += T.temperature/unsimulated_tiles.len + old_pressure = A.return_pressure() - //These values require adjustment in order to properly represent a room of the specified size. - unsim_oxygen *= correction_ratio - unsim_co2 *= correction_ratio - unsim_nitrogen *= correction_ratio - unsim_plasma *= correction_ratio - tileslen = unsimulated_tiles.len + full_oxy = A.oxygen * size + full_nitro = A.nitrogen * size + full_co2 = A.carbon_dioxide * size + full_plasma = A.toxins * size - else //invalid input type - return 0 + full_heat_capacity = A.heat_capacity() * size - unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma) + oxy_avg = (full_oxy + unsim_oxygen) / (size + share_size) + nit_avg = (full_nitro + unsim_nitrogen) / (size + share_size) + co2_avg = (full_co2 + unsim_co2) / (size + share_size) + plasma_avg = (full_plasma + unsim_plasma) / (size + share_size) - var - ratio = sharing_lookup_table[6] + temp_avg = 0 - old_pressure = A.return_pressure() +if((full_heat_capacity + unsim_heat_capacity) > 0) + temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity) - full_oxy = A.oxygen * size - full_nitro = A.nitrogen * size - full_co2 = A.carbon_dioxide * size - full_plasma = A.toxins * size +if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick. + ratio = sharing_lookup_table[tileslen] - full_heat_capacity = A.heat_capacity() * size +A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg ) +A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) +A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1 - ratio) + co2_avg ) +A.toxins = max(0, (A.toxins - plasma_avg) * (1 - ratio) + plasma_avg ) - oxy_avg = (full_oxy + unsim_oxygen) / (size + share_size) - nit_avg = (full_nitro + unsim_nitrogen) / (size + share_size) - co2_avg = (full_co2 + unsim_co2) / (size + share_size) - plasma_avg = (full_plasma + unsim_plasma) / (size + share_size) +A.temperature = max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_avg ) - temp_avg = 0 +for(var/datum/gas/G in A.trace_gases) + var/G_avg = (G.moles * size) / (size + share_size) + G.moles = (G.moles - G_avg) * (1 - ratio) + G_avg - if((full_heat_capacity + unsim_heat_capacity) > 0) - temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity) +A.update_values() - if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[tileslen] - - A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg ) - A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) - A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1 - ratio) + co2_avg ) - A.toxins = max(0, (A.toxins - plasma_avg) * (1 - ratio) + plasma_avg ) - - A.temperature = max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_avg ) - - for(var/datum/gas/G in A.trace_gases) - var/G_avg = (G.moles * size) / (size + share_size) - G.moles = (G.moles - G_avg) * (1 - ratio) + G_avg - - A.update_values() - - return abs(old_pressure - A.return_pressure()) +return abs(old_pressure - A.return_pressure()) proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) - //This implements a simplistic version of the Stefan-Boltzmann law. - var/energy_delta = ((A.temperature - B.temperature) ** 4) * 5.6704e-8 * connecting_tiles * 2.5 - var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier)) - if(maximum_energy_delta > abs(energy_delta)) - if(energy_delta < 0) - maximum_energy_delta *= -1 - energy_delta = maximum_energy_delta +//This implements a simplistic version of the Stefan-Boltzmann law. +var/energy_delta = ((A.temperature - B.temperature) ** 4) * 5.6704e-8 * connecting_tiles * 2.5 +var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier)) +if(maximum_energy_delta > abs(energy_delta)) + if(energy_delta < 0) + maximum_energy_delta *= -1 + energy_delta = maximum_energy_delta - A.temperature -= energy_delta / (A.heat_capacity() * A.group_multiplier) - B.temperature += energy_delta / (B.heat_capacity() * B.group_multiplier) \ No newline at end of file +A.temperature -= energy_delta / (A.heat_capacity() * A.group_multiplier) +B.temperature += energy_delta / (B.heat_capacity() * B.group_multiplier) \ No newline at end of file diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index 61303ae8025..e9ac325d53b 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -7,14 +7,14 @@ var/image/zone_blocked = image('icons/Testing/Zone.dmi', icon_state = "zoneblock var/image/blocked = image('icons/Testing/Zone.dmi', icon_state = "fullblock") var/image/mark = image('icons/Testing/Zone.dmi', icon_state = "mark") -turf/var/tmp/dbg_img -turf/proc/dbg(image/img, d = 0) +/turf/var/tmp/dbg_img +/turf/proc/dbg(image/img, d = 0) if(d > 0) img.dir = d overlays -= dbg_img overlays += img dbg_img = img -turf/simulated/var/verbose = 0 -turf/simulated/verb/Verbose() +/turf/simulated/var/verbose = 0 +/turf/simulated/verb/Verbose() set src in world verbose = !verbose \ No newline at end of file diff --git a/code/ZAS/Functions.dm b/code/ZAS/Functions.dm deleted file mode 100644 index d0f5e593295..00000000000 --- a/code/ZAS/Functions.dm +++ /dev/null @@ -1,243 +0,0 @@ -//Global Functions -//Contents: FloodFill, ZMerge, ZConnect - -//Floods outward from an initial turf to fill everywhere it's zone would reach. -proc/FloodFill(turf/simulated/start) - - if(!istype(start)) - return list() - - //The list of tiles waiting to be evaulated. - var/list/open = list(start) - //The list of tiles which have been evaulated. - var/list/closed = list() -/////// Z-Level stuff - //List of all space tiles bordering the zone - var/list/list_space = list() - //List of all Z-Levels of the zone where it borders space - var/list/z_space = list() -/////// Z-Level stuff - - //Loop through the turfs in the open list in order to find which adjacent turfs should be added to the zone. - while(open.len) - var/turf/simulated/T = pick(open) - - //sanity! - if(!istype(T)) - open -= T - continue - - //Check all cardinal directions - for(var/d in cardinal) - var/turf/simulated/O = get_step(T,d) - - //Ensure the turf is of proper type, that it is not in either list, and that air can reach it. - if(istype(O) && !(O in open) && !(O in closed) && O.ZCanPass(T)) - - //Handle connections from a tile with a door. - if(T.HasDoor()) - //If they both have doors, then they are not able to connect period. - if(O.HasDoor()) - continue - - //Connect first to north and west - if(d == NORTH || d == WEST) - open += O - - //If that fails, and north/west cannot be connected to, see if west or south can be connected instead. - else - var/turf/simulated/W = get_step(O, WEST) - var/turf/simulated/N = get_step(O, NORTH) - - if( !O.ZCanPass(N) && !O.ZCanPass(W) ) - //If it cannot connect either to the north or west, connect it! - open += O - - //If no doors are involved, add it immediately. - else if(!O.HasDoor()) - open += O - - //Handle connecting to a tile with a door. - else - if(d == SOUTH || d == EAST) - //doors prefer connecting to zones to the north or west - closed += O - - else - //see if we need to force an attempted connection - //(there are no potentially viable zones to the north/west of the door) - var/turf/simulated/W = get_step(O, WEST) - var/turf/simulated/N = get_step(O, NORTH) - - if( !O.ZCanPass(N) && !O.ZCanPass(W) ) - //If it cannot connect either to the north or west, connect it! - closed += O - -/////// Z-Level stuff - if(istype(O,/turf/space)) - if(!(O in list_space)) - list_space += O - if(!(O.z in z_space)) - z_space += O.z - - // handle Z-level connections - var/turf/controllerlocation = locate(1, 1, T.z) - for(var/obj/effect/landmark/zcontroller/controller in controllerlocation) - // connect upwards - if(controller.up) - var/turf/above_me = locate(T.x, T.y, controller.up_target) - // add the turf above this - if(istype(above_me, /turf/simulated/floor/open) && !(above_me in open) && !(above_me in closed)) - open += above_me - - if(istype(above_me,/turf/space)) - if(!(above_me in list_space)) - list_space += above_me - if(!(above_me.z in z_space)) - z_space += above_me.z - // connect downwards - if(controller.down && istype(T, /turf/simulated/floor/open)) - var/turf/below_me = locate(T.x, T.y, controller.down_target) - // add the turf below this - if(!(below_me in open) && !(below_me in closed)) - open += below_me -/////// Z-Level stuff - - //This tile is now evaluated, and can be moved to the list of evaluated tiles. - open -= T - closed += T - -/////// Z-Level stuff - // once the zone is done, check if there is space that needs to be changed to open space - if(!open.len) - var/list/temp = list() - while(list_space.len) - var/turf/S = pick(list_space) - //check if the zone has any space borders below the evaluated space tile - //if there is some, we dont need to make open_space since the zone can vent and the zone above can vent - //through the evaluated tile - //if there is none, the zone can connect upwards to either vent from there or connect with the zone there - //also check if the turf below the space is actually part of this zone to prevent the edge tiles from transforming - var/turf/controllerloc = locate(1, 1, S.z) - for(var/obj/effect/landmark/zcontroller/controller in controllerloc) - if(controller.down) - var/turf/below = locate(S.x, S.y, controller.down_target) - if(!((S.z - 1) in z_space) && below in closed) - open += S.ChangeTurf(/turf/simulated/floor/open) - list_space -= S - else - list_space -= S - temp += S - else - list_space -= S - temp += S - // make sure the turf is removed from the list - list_space -= S - z_space -= z_space - while(temp.len) - var/turf/S = pick(temp) - if(!(S.z in z_space)) - z_space += S.z - list_space += S - temp -= S -/////// Z-Level stuff - - return closed - - -//Procedure to merge two zones together. -proc/ZMerge(zone/A,zone/B) - - //Sanity~ - if(!istype(A) || !istype(B)) - return - - var/new_contents = A.contents + B.contents - - //Set all the zone vars. - for(var/turf/simulated/T in B.contents) - T.zone = A - - if(istype(A.air) && istype(B.air)) - //Merges two zones so that they are one. - var/a_size = A.air.group_multiplier - var/b_size = B.air.group_multiplier - var/c_size = a_size + b_size - - //Set air multipliers to one so air represents gas per tile. - A.air.group_multiplier = 1 - B.air.group_multiplier = 1 - - //Remove some air proportional to the size of this zone. - A.air.remove_ratio(a_size/c_size) - B.air.remove_ratio(b_size/c_size) - - //Merge the gases and set the multiplier to the sum of the old ones. - A.air.merge(B.air) - A.air.group_multiplier = c_size - - //I hate when the air datum somehow disappears. - // Try to make it sorta work anyways. Fakit - else if(istype(B.air)) - A.air = B.air - A.air.group_multiplier = A.contents.len - - else if(istype(A.air)) - A.air.group_multiplier = A.contents.len - - //Doublefakit. - else - A.air = new - - //Check for connections to merge into the new zone. - for(var/connection/C in B.connections) - //The Cleanup proc will delete the connection if the zones are the same. - // It will also set the zone variables correctly. - C.Cleanup() - - //Add space tiles. - if(A.unsimulated_tiles && B.unsimulated_tiles) - A.unsimulated_tiles |= B.unsimulated_tiles - else if (B.unsimulated_tiles) - A.unsimulated_tiles = B.unsimulated_tiles - - //Add contents. - A.contents = new_contents - - //Remove the "B" zone, finally. - B.SoftDelete() - - -//Connects two zones by forming a connection object representing turfs A and B. -proc/ZConnect(turf/simulated/A,turf/simulated/B) - - //Make sure that if it's space, it gets added to unsimulated_tiles instead. - if(!istype(B)) - if(A.zone) - A.zone.AddTurf(B) - return - if(!istype(A)) - if(B.zone) - B.zone.AddTurf(A) - return - - if(!istype(A) || !istype(B)) - return - - //Make some preliminary checks to see if the connection is valid. - if(!A.zone || !B.zone) return - if(A.zone == B.zone) - air_master.AddIntrazoneConnection(A,B) - return - - if(A.CanPass(null, B, 1.5, 1) && A.zone.air.compare(B.zone.air)) - return ZMerge(A.zone,B.zone) - - //Ensure the connection isn't already made. - if(A in air_master.turfs_with_connections) - for(var/connection/C in air_master.turfs_with_connections[A]) - if(C.B == B || C.A == B) - return - - //Make the connection. - new /connection(A,B) diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index 60db8de2f7e..096eaebefea 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -1,11 +1,11 @@ -turf/simulated/var/zone/zone -turf/simulated/var/open_directions -turf/simulated/var/gas_graphic +/turf/simulated/var/zone/zone +/turf/simulated/var/open_directions +/turf/simulated/var/gas_graphic -turf/var/needs_air_update = 0 -turf/var/datum/gas_mixture/air +/turf/var/needs_air_update = 0 +/turf/var/datum/gas_mixture/air -turf/simulated/proc/set_graphic(new_graphic) +/turf/simulated/proc/set_graphic(new_graphic) if(isnum(new_graphic)) if(new_graphic == 1) new_graphic = plmaster else if(new_graphic == 2) new_graphic = slmaster @@ -13,7 +13,7 @@ turf/simulated/proc/set_graphic(new_graphic) if(new_graphic) overlays += new_graphic gas_graphic = new_graphic -turf/proc/c_update_air_properties() +/turf/proc/c_update_air_properties() var/block = c_airblock(src) if(block & AIR_BLOCKED) //dbg(blocked) @@ -35,7 +35,7 @@ turf/proc/c_update_air_properties() air_master.connect(sim, src) -turf/simulated/c_update_air_properties() +/turf/simulated/c_update_air_properties() if(zone && zone.invalid) c_copy_air() zone = null //Easier than iterating through the list at the zone. @@ -182,15 +182,15 @@ turf/simulated/c_update_air_properties() return GM -turf/simulated/assume_air(datum/gas_mixture/giver) +/turf/simulated/assume_air(datum/gas_mixture/giver) var/datum/gas_mixture/my_air = return_air() my_air.merge(giver) -turf/simulated/remove_air(amount as num) +/turf/simulated/remove_air(amount as num) var/datum/gas_mixture/my_air = return_air() return my_air.remove(amount) -turf/simulated/return_air() +/turf/simulated/return_air() if(zone) if(!zone.invalid) air_master.mark_zone_update(zone) @@ -205,14 +205,14 @@ turf/simulated/return_air() make_air() return air -turf/proc/make_air() +/turf/proc/make_air() air = new/datum/gas_mixture air.temperature = temperature air.adjust(oxygen, carbon_dioxide, nitrogen, toxins) air.group_multiplier = 1 air.volume = CELL_VOLUME -turf/simulated/proc/c_copy_air() +/turf/simulated/proc/c_copy_air() if(!air) air = new/datum/gas_mixture air.copy_from(zone.air) air.group_multiplier = 1 \ No newline at end of file diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm deleted file mode 100644 index 1726d04f5c4..00000000000 --- a/code/ZAS/ZAS_Zones.dm +++ /dev/null @@ -1,906 +0,0 @@ -var/list/DoorDirections = list(NORTH,WEST) //Which directions doors turfs can connect to zones -var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs can connect to zones - -/zone - var/dbg_output = 0 //Enables debug output. - - var/datum/gas_mixture/air //The air contents of the zone. - var/datum/gas_mixture/archived_air - - var/list/contents //All the tiles that are contained in this zone. - var/list/unsimulated_tiles // Any space tiles in this list will cause air to flow out. - - var/datum/gas_mixture/air_unsim //Overall average of the air in connected unsimualted tiles. - var/unsim_air_needs_update = 0 //Set to 1 on geometry changes, marks air_unsim as needing update. - - var/list/connections //connection objects which refer to connections with other zones, e.g. through a door. - var/list/direct_connections //connections which directly connect two zones. - - var/list/connected_zones //Parallels connections, but lists zones to which this one is connected and the number - //of points they're connected at. - var/list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed. - - var/last_update = 0 - var/last_rebuilt = 0 - var/status = ZONE_ACTIVE - var/interactions_with_neighbors = 0 - var/interactions_with_unsim = 0 - var/progress = "nothing" - -//CREATION AND DELETION -/zone/New(turf/start) - . = ..() - //Get the turfs that are part of the zone using a floodfill method - if(istype(start,/list)) - contents = start - else - contents = FloodFill(start) - - //Change all the zone vars of the turfs, check for space to be added to unsimulated_tiles. - for(var/turf/T in contents) - if(T.zone && T.zone != src) - T.zone.RemoveTurf(T) - T.zone = src - if(!istype(T,/turf/simulated)) - AddTurf(T) - - //Generate the gas_mixture for use in txhis zone by using the average of the gases - //defined at startup. - //Changed to try and find the source of the error. - air = new - air.group_multiplier = contents.len - for(var/turf/simulated/T in contents) - if(!T.air) - continue - air.oxygen += T.air.oxygen / air.group_multiplier - air.nitrogen += T.air.nitrogen / air.group_multiplier - air.carbon_dioxide += T.air.carbon_dioxide / air.group_multiplier - air.toxins += T.air.toxins / air.group_multiplier - air.temperature += T.air.temperature / air.group_multiplier - for(var/datum/gas/trace in T.air.trace_gases) - var/datum/gas/corresponding_gas = locate(trace.type) in air.trace_gases - if(!corresponding_gas) - corresponding_gas = new trace.type() - air.trace_gases.Add(corresponding_gas) - corresponding_gas.moles += trace.moles - air.update_values() - - //Add this zone to the global list. - if(air_master) - air_master.zones.Add(src) - air_master.active_zones.Add(src) - - -//DO NOT USE. Use the SoftDelete proc. -/zone/Del() - //Ensuring the zone list doesn't get clogged with null values. - for(var/turf/simulated/T in contents) - RemoveTurf(T) - air_master.ReconsiderTileZone(T) - - if(air_master) - air_master.AddConnectionToCheck(connections) - - air = null - - . = ..() - - -//Handles deletion via garbage collection. -/zone/proc/SoftDelete() - air = null - - if(air_master) - air_master.zones.Remove(src) - air_master.active_zones.Remove(src) - air_master.zones_needing_rebuilt.Remove(src) - air_master.AddConnectionToCheck(connections) - - connections = null - for(var/connection/C in direct_connections) - if(C.A.zone == src) - C.A.zone = null - if(C.B.zone == src) - C.B.zone = null - if(C.zone_A == src) - C.zone_A = null - if(C.zone_B == src) - C.zone_B = null - direct_connections = null - - //Ensuring the zone list doesn't get clogged with null values. - for(var/turf/simulated/T in contents) - RemoveTurf(T) - air_master.ReconsiderTileZone(T) - - contents.Cut() - - //Removing zone connections and scheduling connection cleanup - for(var/zone/Z in connected_zones) - Z.connected_zones.Remove(src) - if(!Z.connected_zones.len) - Z.connected_zones = null - - if(Z.closed_connection_zones) - Z.closed_connection_zones.Remove(src) - if(!Z.closed_connection_zones.len) - Z.closed_connection_zones = null - - connected_zones = null - closed_connection_zones = null - - return 1 - - -//ZONE MANAGEMENT FUNCTIONS -/zone/proc/AddTurf(turf/T) - //Adds the turf to contents, increases the size of the zone, and sets the zone var. - if(istype(T, /turf/simulated)) - if(T in contents) - return - if(T.zone) - T.zone.RemoveTurf(T) - contents += T - if(air) - air.group_multiplier++ - - T.zone = src - -///// Z-Level Stuff - // also add the tile below it if its open space - if(istype(T, /turf/simulated/floor/open)) - var/turf/simulated/floor/open/T2 = T - src.AddTurf(T2.floorbelow) -///// Z-Level Stuff - - else - if(!unsimulated_tiles) - unsimulated_tiles = list() - else if(T in unsimulated_tiles) - return - unsimulated_tiles += T - contents -= T - - unsim_air_needs_update = 1 - -/zone/proc/RemoveTurf(turf/T) - //Same, but in reverse. - if(istype(T, /turf/simulated)) - if(!(T in contents)) - return - contents -= T - if(air) - air.group_multiplier-- - - if(T.zone == src) - T.zone = null - - if(!contents.len) - SoftDelete() - - else if(unsimulated_tiles) - unsimulated_tiles -= T - if(!unsimulated_tiles.len) - unsimulated_tiles = null - - unsim_air_needs_update = 1 - -//Updates the air_unsim var -/zone/proc/UpdateUnsimAvg() - if(!unsimulated_tiles || !unsimulated_tiles.len) //if we don't have any unsimulated tiles, we can't do much. - return - - if(!unsim_air_needs_update && air_unsim) //if air_unsim doesn't exist, we need to create it even if we don't need an update. - return - - //Tempfix. - if(!air) - return - - unsim_air_needs_update = 0 - - if(!air_unsim) - air_unsim = new /datum/gas_mixture - - air_unsim.oxygen = 0 - air_unsim.nitrogen = 0 - air_unsim.carbon_dioxide = 0 - air_unsim.toxins = 0 - air_unsim.temperature = 0 - - var/correction_ratio = max(1, max(max(1, air.group_multiplier) + 3, 1) + unsimulated_tiles.len) / unsimulated_tiles.len - - for(var/turf/T in unsimulated_tiles) - if(!istype(T, /turf/simulated)) - air_unsim.oxygen += T.oxygen - air_unsim.carbon_dioxide += T.carbon_dioxide - air_unsim.nitrogen += T.nitrogen - air_unsim.toxins += T.toxins - air_unsim.temperature += T.temperature/unsimulated_tiles.len - - //These values require adjustment in order to properly represent a room of the specified size. - air_unsim.oxygen *= correction_ratio - air_unsim.carbon_dioxide *= correction_ratio - air_unsim.nitrogen *= correction_ratio - air_unsim.toxins *= correction_ratio - - air_unsim.group_multiplier = unsimulated_tiles.len - - air_unsim.update_values() - return - - ////////////// - //PROCESSING// -////////////// - -#define QUANTIZE(variable) (round(variable,0.0001)) - -/zone/proc/process() - . = 1 - - progress = "problem with: SoftDelete()" - - //Deletes zone if empty. - if(!contents.len) - return SoftDelete() - - progress = "problem with: Rebuild()" - - if(!contents.len) //If we got soft deleted. - return - - progress = "problem with: air regeneration" - - //Sometimes explosions will cause the air to be deleted for some reason. - if(!air) - air = new() - air.oxygen = MOLES_O2STANDARD - air.nitrogen = MOLES_N2STANDARD - air.temperature = T0C - air.total_moles() - world.log << "Air object lost in zone. Regenerating." - - - progress = "problem with: ShareSpace()" - - if(unsim_air_needs_update) - unsim_air_needs_update = 0 - UpdateUnsimAvg() - - if(unsimulated_tiles) - if(locate(/turf/simulated) in unsimulated_tiles) - for(var/turf/simulated/T in unsimulated_tiles) - unsimulated_tiles -= T - - if(unsimulated_tiles.len) - var/moved_air = ShareSpace(air, air_unsim) - - if(!air.compare(air_unsim)) - interactions_with_unsim++ - - if(moved_air > vsc.airflow_lightest_pressure) - AirflowSpace(src) - else - unsimulated_tiles = null - - //Check the graphic. - progress = "problem with: modifying turf graphics" - - air.graphic = 0 - if(air.toxins > MOLES_PLASMA_VISIBLE) - air.graphic = 1 - else if(air.trace_gases.len) - var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air.trace_gases - if(sleeping_agent && (sleeping_agent.moles > 1)) - air.graphic = 2 - - progress = "problem with an inbuilt byond function: some conditional checks" - - //Only run through the individual turfs if there's reason to. - if(air.graphic != air.graphic_archived || air.temperature > PLASMA_FLASHPOINT) - - progress = "problem with: turf/simulated/update_visuals()" - - for(var/turf/simulated/S in contents) - //Update overlays. - if(air.graphic != air.graphic_archived) - if(S.HasDoor(1)) - S.update_visuals() - else - S.update_visuals(air) - - progress = "problem with: item or turf temperature_expose()" - - //Expose stuff to extreme heat. - if(air.temperature > PLASMA_FLASHPOINT) - for(var/atom/movable/item in S) - item.temperature_expose(air, air.temperature, CELL_VOLUME) - S.hotspot_expose(air.temperature, CELL_VOLUME) - - progress = "problem with: calculating air graphic" - - //Archive graphic so we can know if it's different. - air.graphic_archived = air.graphic - - progress = "problem with: calculating air temp" - - //Ensure temperature does not reach absolute zero. - air.temperature = max(TCMB,air.temperature) - - progress = "problem with an inbuilt byond function: length(connections)" - - //Handle connections to other zones. - if(length(connections)) - - progress = "problem with: ZMerge(), a couple of misc procs" - - if(length(direct_connections)) - for(var/connection/C in direct_connections) - - //Do merging if conditions are met. Specifically, if there's a non-door connection - //to somewhere with space, the zones are merged regardless of equilibrium, to speed - //up spacing in areas with double-plated windows. - if(C.A.zone && C.B.zone) - if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles) - ZMerge(C.A.zone,C.B.zone) - - progress = "problem with: ShareRatio(), Airflow(), a couple of misc procs" - - //Share some - for(var/zone/Z in connected_zones) - //If that zone has already processed, skip it. - if(Z.last_update > last_update) - continue - - //Handle adjacent zones that are sleeping - if(Z.status == ZONE_SLEEPING) - if(air.compare(Z.air)) - continue - - else - Z.SetStatus(ZONE_ACTIVE) - - if(air && Z.air) - //Ensure we're not doing pointless calculations on equilibrium zones. - if(!air.compare(Z.air)) - if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure) - Airflow(src,Z) - var/unsimulated_boost = 0 - if(unsimulated_tiles) - unsimulated_boost += unsimulated_tiles.len - if(Z.unsimulated_tiles) - unsimulated_boost += Z.unsimulated_tiles.len - unsimulated_boost = max(0, min(3, unsimulated_boost)) - ShareRatio( air , Z.air , connected_zones[Z] + unsimulated_boost) - - Z.interactions_with_neighbors++ - interactions_with_neighbors++ - - if(!vsc.connection_insulation) - for(var/zone/Z in closed_connection_zones) - //If that zone has already processed, skip it. - if(Z.last_update > last_update || !Z.air) - continue - - var/handle_temperature = abs(air.temperature - Z.air.temperature) > vsc.connection_temperature_delta - - if(Z.status == ZONE_SLEEPING) - if (handle_temperature) - Z.SetStatus(ZONE_ACTIVE) - else - continue - - if(air && Z.air) - if( handle_temperature ) - ShareHeat(air, Z.air, closed_connection_zones[Z]) - - Z.interactions_with_neighbors++ - interactions_with_neighbors++ - - if(!interactions_with_neighbors && !interactions_with_unsim) - SetStatus(ZONE_SLEEPING) - - interactions_with_neighbors = 0 - interactions_with_unsim = 0 - - progress = "all components completed successfully, the problem is not here" - - -/zone/proc/SetStatus(var/new_status) - if(status == ZONE_SLEEPING && new_status == ZONE_ACTIVE) - air_master.active_zones.Add(src) - status = ZONE_ACTIVE - - else if(status == ZONE_ACTIVE && new_status == ZONE_SLEEPING) - air_master.active_zones.Remove(src) - status = ZONE_SLEEPING - - if(unsimulated_tiles && unsimulated_tiles.len) - UpdateUnsimAvg() - air.copy_from(air_unsim) - - if(!archived_air) - archived_air = new - archived_air.copy_from(air) - - -/zone/proc/CheckStatus() - return status - - -/zone/proc/ActivateIfNeeded() - if(status == ZONE_ACTIVE) return - - var/difference = 0 - - if(unsimulated_tiles && unsimulated_tiles.len) - UpdateUnsimAvg() - if(!air.compare(air_unsim)) - difference = 1 - - if(!difference) - for(var/zone/Z in connected_zones) //Check adjacent zones for air difference. - if(!air.compare(Z.air)) - difference = 1 - break - - if(difference) //We have a difference, activate the zone. - SetStatus(ZONE_ACTIVE) - - return - - -/zone/proc/assume_air(var/datum/gas_mixture/giver) - if(status == ZONE_ACTIVE) - return air.merge(giver) - - else - if(unsimulated_tiles && unsimulated_tiles.len) - UpdateUnsimAvg() - var/datum/gas_mixture/compare_air = new - compare_air.copy_from(giver) - compare_air.add(air_unsim) - compare_air.divide(air.group_multiplier) - - if(air_unsim.compare(compare_air)) - return 0 - - var/result = air.merge(giver) - - if(!archived_air.compare(air)) - SetStatus(ZONE_ACTIVE) - return result - - -/zone/proc/remove_air(var/amount) - if(status == ZONE_ACTIVE) - return air.remove(amount) - - else - var/result = air.remove(amount) - - if(!archived_air.compare(air)) - SetStatus(ZONE_ACTIVE) - - return result - - //////////////// - //Air Movement// -//////////////// - -var/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66) - -proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) - //Shares a specific ratio of gas between mixtures using simple weighted averages. - var - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - ratio = sharing_lookup_table[6] - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - - size = max(1,A.group_multiplier) - share_size = max(1,B.group_multiplier) - - full_oxy = A.oxygen * size - full_nitro = A.nitrogen * size - full_co2 = A.carbon_dioxide * size - full_plasma = A.toxins * size - - full_heat_capacity = A.heat_capacity() * size - - s_full_oxy = B.oxygen * share_size - s_full_nitro = B.nitrogen * share_size - s_full_co2 = B.carbon_dioxide * share_size - s_full_plasma = B.toxins * share_size - - s_full_heat_capacity = B.heat_capacity() * share_size - - oxy_avg = (full_oxy + s_full_oxy) / (size + share_size) - nit_avg = (full_nitro + s_full_nitro) / (size + share_size) - co2_avg = (full_co2 + s_full_co2) / (size + share_size) - plasma_avg = (full_plasma + s_full_plasma) / (size + share_size) - - temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity) - - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[connecting_tiles] - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - - A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) - A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg ) - A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) - A.toxins = max(0, (A.toxins - plasma_avg) * (1-ratio) + plasma_avg ) - - A.temperature = max(0, (A.temperature - temp_avg) * (1-ratio) + temp_avg ) - - B.oxygen = max(0, (B.oxygen - oxy_avg) * (1-ratio) + oxy_avg ) - B.nitrogen = max(0, (B.nitrogen - nit_avg) * (1-ratio) + nit_avg ) - B.carbon_dioxide = max(0, (B.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg ) - B.toxins = max(0, (B.toxins - plasma_avg) * (1-ratio) + plasma_avg ) - - B.temperature = max(0, (B.temperature - temp_avg) * (1-ratio) + temp_avg ) - - for(var/datum/gas/G in A.trace_gases) - var/datum/gas/H = locate(G.type) in B.trace_gases - if(H) - var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg - else - H = new G.type - B.trace_gases += H - var/G_avg = (G.moles*size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg - - for(var/datum/gas/G in B.trace_gases) - var/datum/gas/H = locate(G.type) in A.trace_gases - if(!H) - H = new G.type - A.trace_gases += H - var/G_avg = (G.moles*size) / (size+share_size) - G.moles = (G.moles - G_avg) * (1-ratio) + G_avg - H.moles = (H.moles - G_avg) * (1-ratio) + G_avg - - A.update_values() - B.update_values() - - if(A.compare(B)) return 1 - else return 0 - -proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) - //A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room. - if(!unsimulated_tiles) - return 0 - - var - unsim_oxygen = 0 - unsim_nitrogen = 0 - unsim_co2 = 0 - unsim_plasma = 0 - unsim_heat_capacity = 0 - unsim_temperature = 0 - - size = max(1,A.group_multiplier) - - var/tileslen - var/share_size - - if(istype(unsimulated_tiles, /datum/gas_mixture)) - var/datum/gas_mixture/avg_unsim = unsimulated_tiles - unsim_oxygen = avg_unsim.oxygen - unsim_co2 = avg_unsim.carbon_dioxide - unsim_nitrogen = avg_unsim.nitrogen - unsim_plasma = avg_unsim.toxins - unsim_temperature = avg_unsim.temperature - share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier) - tileslen = avg_unsim.group_multiplier - - else if(istype(unsimulated_tiles, /list)) - if(!unsimulated_tiles.len) - return 0 - // We use the same size for the potentially single space tile - // as we use for the entire room. Why is this? - // Short answer: We do not want larger rooms to depressurize more - // slowly than small rooms, preserving our good old "hollywood-style" - // oh-shit effect when large rooms get breached, but still having small - // rooms remain pressurized for long enough to make escape possible. - share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len) - var/correction_ratio = share_size / unsimulated_tiles.len - - for(var/turf/T in unsimulated_tiles) - unsim_oxygen += T.oxygen - unsim_co2 += T.carbon_dioxide - unsim_nitrogen += T.nitrogen - unsim_plasma += T.toxins - unsim_temperature += T.temperature/unsimulated_tiles.len - - //These values require adjustment in order to properly represent a room of the specified size. - unsim_oxygen *= correction_ratio - unsim_co2 *= correction_ratio - unsim_nitrogen *= correction_ratio - unsim_plasma *= correction_ratio - tileslen = unsimulated_tiles.len - - else //invalid input type - return 0 - - unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma) - - var - ratio = sharing_lookup_table[6] - - old_pressure = A.return_pressure() - - full_oxy = A.oxygen * size - full_nitro = A.nitrogen * size - full_co2 = A.carbon_dioxide * size - full_plasma = A.toxins * size - - full_heat_capacity = A.heat_capacity() * size - - oxy_avg = (full_oxy + unsim_oxygen) / (size + share_size) - nit_avg = (full_nitro + unsim_nitrogen) / (size + share_size) - co2_avg = (full_co2 + unsim_co2) / (size + share_size) - plasma_avg = (full_plasma + unsim_plasma) / (size + share_size) - - temp_avg = 0 - - if((full_heat_capacity + unsim_heat_capacity) > 0) - temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity) - - if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[tileslen] - - A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg ) - A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) - A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1 - ratio) + co2_avg ) - A.toxins = max(0, (A.toxins - plasma_avg) * (1 - ratio) + plasma_avg ) - - A.temperature = max(TCMB, (A.temperature - temp_avg) * (1 - ratio) + temp_avg ) - - for(var/datum/gas/G in A.trace_gases) - var/G_avg = (G.moles * size) / (size + share_size) - G.moles = (G.moles - G_avg) * (1 - ratio) + G_avg - - A.update_values() - - return abs(old_pressure - A.return_pressure()) - - -proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles) - //This implements a simplistic version of the Stefan-Boltzmann law. - var/energy_delta = ((A.temperature - B.temperature) ** 4) * 5.6704e-8 * connecting_tiles * 2.5 - var/maximum_energy_delta = max(0, min(A.temperature * A.heat_capacity() * A.group_multiplier, B.temperature * B.heat_capacity() * B.group_multiplier)) - if(maximum_energy_delta > abs(energy_delta)) - if(energy_delta < 0) - maximum_energy_delta *= -1 - energy_delta = maximum_energy_delta - - A.temperature -= energy_delta / (A.heat_capacity() * A.group_multiplier) - B.temperature += energy_delta / (B.heat_capacity() * B.group_multiplier) - - /* This was bad an I feel bad. - //Shares a specific ratio of gas between mixtures using simple weighted averages. - var - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - ratio = sharing_lookup_table[6] - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - - full_heat_capacity = A.heat_capacity() - - s_full_heat_capacity = B.heat_capacity() - - temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity) - - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick. - ratio = sharing_lookup_table[connecting_tiles] - //WOOT WOOT TOUCH THIS AND YOU ARE A RETARD - - //We need to adjust it to account for the insulation settings. - ratio *= 1 - vsc.connection_insulation - - A.temperature = max(0, (A.temperature - temp_avg) * (1- (ratio / max(1,A.group_multiplier)) ) + temp_avg ) - B.temperature = max(0, (B.temperature - temp_avg) * (1- (ratio / max(1,B.group_multiplier)) ) + temp_avg ) - */ - - /////////////////// - //Zone Rebuilding// -/////////////////// -//Used for updating zone geometry when a zone is cut into two parts. - -zone/proc/Rebuild() - if(last_rebuilt == air_master.current_cycle) - return - - last_rebuilt = air_master.current_cycle - - var/list/new_zone_contents = IsolateContents() - if(new_zone_contents.len == 1) - return - - var/list/current_contents - var/list/new_zones = list() - - contents = new_zone_contents[1] - air.group_multiplier = contents.len - - for(var/identifier in 2 to new_zone_contents.len) - current_contents = new_zone_contents[identifier] - var/zone/new_zone = new (current_contents) - new_zone.air.copy_from(air) - new_zones += new_zone - - for(var/connection/connection in connections) - connection.Cleanup() - - var/turf/simulated/adjacent - - for(var/turf/unsimulated in unsimulated_tiles) - for(var/direction in cardinal) - adjacent = get_step(unsimulated, direction) - - if(istype(adjacent) && adjacent.CanPass(null, unsimulated, 0, 0)) - for(var/zone/zone in new_zones) - if(adjacent in zone) - zone.AddTurf(unsimulated) - - -//Implements a two-pass connected component labeling algorithm to determine if the zone is, in fact, split. - -/zone/proc/IsolateContents() - var/list/current_adjacents = list() - var/adjacent_id - var/lowest_id - - var/list/identical_ids = list() - var/list/turfs = contents.Copy() - var/current_identifier = 1 - - for(var/turf/simulated/current in turfs) - lowest_id = null - current_adjacents = list() - - for(var/direction in cardinal) - var/turf/simulated/adjacent = get_step(current, direction) - if(!current.ZCanPass(adjacent)) - continue - if(adjacent in turfs) - current_adjacents += adjacent - adjacent_id = turfs[adjacent] - - if(adjacent_id && (!lowest_id || adjacent_id < lowest_id)) - lowest_id = adjacent_id - -/////// Z-Level stuff - var/turf/controllerlocation = locate(1, 1, current.z) - for(var/obj/effect/landmark/zcontroller/controller in controllerlocation) - // upwards - if(controller.up) - var/turf/simulated/adjacent = locate(current.x, current.y, controller.up_target) - - if(adjacent in turfs && istype(adjacent, /turf/simulated/floor/open)) - current_adjacents += adjacent - adjacent_id = turfs[adjacent] - - if(adjacent_id && (!lowest_id || adjacent_id < lowest_id)) - lowest_id = adjacent_id - - // downwards - if(controller.down && istype(current, /turf/simulated/floor/open)) - var/turf/simulated/adjacent = locate(current.x, current.y, controller.down_target) - - if(adjacent in turfs) - current_adjacents += adjacent - adjacent_id = turfs[adjacent] - - if(adjacent_id && (!lowest_id || adjacent_id < lowest_id)) - lowest_id = adjacent_id -/////// Z-Level stuff - - if(!lowest_id) - lowest_id = current_identifier++ - identical_ids += lowest_id - - for(var/turf/simulated/adjacent in current_adjacents) - adjacent_id = turfs[adjacent] - if(adjacent_id != lowest_id) - if(adjacent_id) - identical_ids[adjacent_id] = lowest_id - turfs[adjacent] = lowest_id - turfs[current] = lowest_id - - var/list/final_arrangement = list() - - for(var/turf/simulated/current in turfs) - current_identifier = identical_ids[turfs[current]] - - if( current_identifier > final_arrangement.len ) - final_arrangement.len = current_identifier - final_arrangement[current_identifier] = list(current) - - else - //Sanity check. - if(!islist(final_arrangement[current_identifier])) - final_arrangement[current_identifier] = list() - final_arrangement[current_identifier] += current - - //lazy but fast - final_arrangement.Remove(null) - - return final_arrangement - - -/* - if(!RequiresRebuild()) - return - - //Choose a random turf and regenerate the zone from it. - var/list/new_contents - var/list/new_unsimulated - - var/list/turfs_needing_zones = list() - - var/list/zones_to_check_connections = list(src) - - if(!locate(/turf/simulated/floor) in contents) - for(var/turf/simulated/turf in contents) - air_master.ReconsiderTileZone(turf) - return SoftDelete() - - var/turfs_to_ignore = list() - if(direct_connections) - for(var/connection/connection in direct_connections) - if(connection.A.zone != src) - turfs_to_ignore += A - else if(connection.B.zone != src) - turfs_to_ignore += B - - new_unsimulated = ( unsimulated_tiles ? unsimulated_tiles : list() ) - - //Now, we have allocated the new turfs into proper lists, and we can start actually rebuilding. - - //If something isn't carried over, it will need a new zone. - for(var/turf/T in contents) - if(!(T in new_contents)) - RemoveTurf(T) - turfs_needing_zones += T - - //Handle addition of new turfs - for(var/turf/S in new_contents) - if(!istype(S, /turf/simulated)) - new_unsimulated |= S - new_contents.Remove(S) - - //If something new is added, we need to deal with it seperately. - else if(!(S in contents) && istype(S, /turf/simulated)) - if(!(S.zone in zones_to_check_connections)) - zones_to_check_connections += S.zone - - S.zone.RemoveTurf(S) - AddTurf(S) - - //Handle the addition of new unsimulated tiles. - unsimulated_tiles = null - - if(new_unsimulated.len) - for(var/turf/S in new_unsimulated) - if(istype(S, /turf/simulated)) - continue - for(var/direction in cardinal) - var/turf/simulated/T = get_step(S,direction) - if(istype(T) && T.zone && S.CanPass(null, T, 0, 0)) - T.zone.AddTurf(S) - - //Finally, handle the orphaned turfs - - for(var/turf/simulated/T in turfs_needing_zones) - if(!T.zone) - zones_to_check_connections += new /zone(T) - - for(var/zone/zone in zones_to_check_connections) - for(var/connection/C in zone.connections) - C.Cleanup()*/ - diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 4e32562bbf4..605dfce30a7 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -1,128 +1,125 @@ -zone - var/name - var/invalid = 0 - var/list/contents = list() - var/list/unsimulated_contents = list() - var/needs_update = 0 +/zone/var/name +/zone/var/invalid = 0 +/zone/var/list/contents = list() +/zone/var/list/unsimulated_contents = list() - var/list/edges = list() +/zone/var/needs_update = 0 - var/datum/gas_mixture/air = new +/zone/var/list/edges = list() - New() - air_master.new_zone(src) - air.temperature = TCMB - air.group_multiplier = 1 - air.volume = CELL_VOLUME +/zone/var/datum/gas_mixture/air = new - proc/add(turf/simulated/T) - #ifdef ZASDBG - ASSERT(!invalid) - ASSERT(istype(T)) - ASSERT(!air_master.has_valid_zone(T)) - #endif +/zone/New() + air_master.new_zone(src) + air.temperature = TCMB + air.group_multiplier = 1 + air.volume = CELL_VOLUME - var/datum/gas_mixture/turf_air = T.return_air() - add_tile_air(turf_air) - T.zone = src - contents.Add(T) - T.set_graphic(air.graphic) +/zone/proc/add(turf/simulated/T) +#ifdef ZASDBG + ASSERT(!invalid) + ASSERT(istype(T)) + ASSERT(!air_master.has_valid_zone(T)) +#endif + + var/datum/gas_mixture/turf_air = T.return_air() + add_tile_air(turf_air) + T.zone = src + contents.Add(T) + T.set_graphic(air.graphic) - proc/add_unsimulated(turf/T) - #ifdef ZASDBG - ASSERT(!invalid) - ASSERT(istype(T)) - ASSERT(!istype(T,/turf/simulated)) - #endif - unsimulated_contents |= T +/zone/proc/add_unsimulated(turf/T) +#ifdef ZASDBG + ASSERT(!invalid) + ASSERT(istype(T)) + ASSERT(!istype(T,/turf/simulated)) +#endif + unsimulated_contents |= T - proc/remove(turf/simulated/T) - #ifdef ZASDBG - ASSERT(!invalid) - ASSERT(istype(T)) - ASSERT(T.zone == src) - #endif - contents.Remove(T) - T.zone = null - if(contents.len) - air.group_multiplier = contents.len - else - c_invalidate() - - proc/c_merge(zone/into) - #ifdef ZASDBG - ASSERT(!invalid) - ASSERT(istype(into)) - ASSERT(into != src) - ASSERT(!into.invalid) - #endif +/zone/proc/remove(turf/simulated/T) +#ifdef ZASDBG + ASSERT(!invalid) + ASSERT(istype(T)) + ASSERT(T.zone == src) +#endif + contents.Remove(T) + T.zone = null + if(contents.len) + air.group_multiplier = contents.len + else c_invalidate() - for(var/turf/simulated/T in contents) - into.add(T) - #ifdef ZASDBG - T.dbg(merged) - #endif - into.unsimulated_contents |= unsimulated_contents - proc/c_invalidate() - invalid = 1 - air_master.invalid_zone(src) +/zone/proc/c_merge(zone/into) +#ifdef ZASDBG + ASSERT(!invalid) + ASSERT(istype(into)) + ASSERT(into != src) + ASSERT(!into.invalid) +#endif + c_invalidate() + for(var/turf/simulated/T in contents) + into.add(T) #ifdef ZASDBG - for(var/turf/simulated/T in contents) - T.dbg(invalid_zone) + T.dbg(merged) #endif + into.unsimulated_contents |= unsimulated_contents - proc/rebuild() - c_invalidate() +/zone/proc/c_invalidate() + invalid = 1 + air_master.invalid_zone(src) + #ifdef ZASDBG + for(var/turf/simulated/T in contents) + T.dbg(invalid_zone) + #endif + +/zone/proc/rebuild() + c_invalidate() + for(var/turf/simulated/T in contents) + //T.dbg(invalid_zone) + air_master.mark_for_update(T) + +/zone/proc/add_tile_air(datum/gas_mixture/tile_air) + //air.volume += CELL_VOLUME + air.group_multiplier = 1 + air.multiply(contents.len) + air.merge(tile_air) + air.divide(contents.len+1) + air.group_multiplier = contents.len+1 + +/zone/proc/tick() + air.archive() + if(air.check_tile_graphic()) for(var/turf/simulated/T in contents) - //T.dbg(invalid_zone) - air_master.mark_for_update(T) + T.set_graphic(air.graphic) - proc/add_tile_air(datum/gas_mixture/tile_air) - //air.volume += CELL_VOLUME - air.group_multiplier = 1 - air.multiply(contents.len) - air.merge(tile_air) - air.divide(contents.len+1) - air.group_multiplier = contents.len+1 +/zone/proc/remove_connection(connection/c) + return - proc/tick() - air.archive() - if(air.check_tile_graphic()) - for(var/turf/simulated/T in contents) - T.set_graphic(air.graphic) +/zone/proc/add_connection(connection/c) + return - proc/remove_connection(connection/c) - return +/zone/proc/dbg_data(mob/M) + M << name + M << "O2: [air.oxygen] N2: [air.nitrogen] CO2: [air.carbon_dioxide] P: [air.toxins]" + M << "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]°K ([air.temperature - T0C]°C)" + M << "O2 per N2: [(air.nitrogen ? air.oxygen/air.nitrogen : "N/A")] Moles: [air.total_moles]" + M << "Simulated: [contents.len] ([air.group_multiplier])" + //M << "Unsimulated: [unsimulated_contents.len]" + //M << "Edges: [edges.len]" + if(invalid) M << "Invalid!" + var/zone_edges = 0 + var/space_edges = 0 + var/space_coefficient = 0 + for(var/connection_edge/E in edges) + if(E.type == /connection_edge/zone) zone_edges++ + else + space_edges++ + space_coefficient += E.coefficient - proc/add_connection(connection/c) - return + M << "Zone Edges: [zone_edges]" + M << "Space Edges: [space_edges] ([space_coefficient] connections)" - proc/dbg_data(mob/M) - M << name - M << "O2: [air.oxygen] N2: [air.nitrogen] CO2: [air.carbon_dioxide] P: [air.toxins]" - M << "P: [air.return_pressure()] kPa V: [air.volume]L T: [air.temperature]°K ([air.temperature - T0C]°C)" - M << "O2 per N2: [(air.nitrogen ? air.oxygen/air.nitrogen : "N/A")] Moles: [air.total_moles]" - M << "Simulated: [contents.len] ([air.group_multiplier])" - //M << "Unsimulated: [unsimulated_contents.len]" - //M << "Edges: [edges.len]" - if(invalid) M << "Invalid!" - var/zone_edges = 0 - var/space_edges = 0 - var/space_coefficient = 0 - for(var/connection_edge/E in edges) - if(E.type == /connection_edge/zone) zone_edges++ - else - space_edges++ - space_coefficient += E.coefficient - - M << "Zone Edges: [zone_edges]" - M << "Space Edges: [space_edges] ([space_coefficient] connections)" - - //for(var/turf/T in unsimulated_contents) - // M << "[T] at ([T.x],[T.y])" - - proc/status() - return 1 \ No newline at end of file + //for(var/turf/T in unsimulated_contents) + // M << "[T] at ([T.x],[T.y])" \ No newline at end of file