From d0c0315d53d9dca24534491f99ad74b4797a2995 Mon Sep 17 00:00:00 2001 From: Aryn Date: Fri, 21 Feb 2014 08:19:12 -0700 Subject: [PATCH] Added documentation, split ConnectionManager.dm, removed some unused procs. Added a proc to find the other zone in an edge for future procs. Fixed the stupid .int again. --- baystation12.dme | 1 + baystation12.int | 3 - code/ZAS/Connection.dm | 96 ++++++++++++-------------------- code/ZAS/ConnectionGroup.dm | 64 ++++++++++++++++++++- code/ZAS/ConnectionManager.dm | 102 ++++++++++++++++++++++++++++++++++ code/ZAS/Controller.dm | 66 +++++++++++++++++++++- code/ZAS/Zone.dm | 47 ++++++++++++++-- code/ZAS/_docs.dm | 6 ++ 8 files changed, 311 insertions(+), 74 deletions(-) create mode 100644 code/ZAS/ConnectionManager.dm diff --git a/baystation12.dme b/baystation12.dme index 430d3b1377..3e1ea6b03f 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1331,6 +1331,7 @@ #include "code\ZAS\Atom.dm" #include "code\ZAS\Connection.dm" #include "code\ZAS\ConnectionGroup.dm" +#include "code\ZAS\ConnectionManager.dm" #include "code\ZAS\Controller.dm" #include "code\ZAS\Debug.dm" #include "code\ZAS\Diagnostic.dm" diff --git a/baystation12.int b/baystation12.int index b9efdebddf..b82874fded 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,9 +1,6 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 -WINDOW: code\ZAS\Turf.dm;code\game\turfs\turf.dm;code\ZAS\Zone.dm -DIR: code code\game code\game\turfs code\ZAS -FILE: code\game\turfs\turf.dm AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index 00a676664c..b9cf2278a1 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -2,78 +2,52 @@ #define CONNECTION_SPACE 4 #define CONNECTION_INVALID 8 -/turf/var/tmp/connection_manager/connections +/* +Overview: + Connections are made between turfs by air_master.connect(). They represent a single point where two zones converge. -/connection_manager/var/connection/N -/connection_manager/var/connection/S -/connection_manager/var/connection/E -/connection_manager/var/connection/W +Class Vars: + A - Always a simulated turf. + B - A simulated or unsimulated turf. -#ifdef ZLEVELS -/connection_manager/var/connection/U -/connection_manager/var/connection/D -#endif + zoneA - The archived zone of A. Used to check that the zone hasn't changed. + zoneB - The archived zone of B. May be null in case of unsimulated connections. -/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 + edge - Stores the edge this connection is in. Can reference an edge that is no longer processed + after this connection is removed, so make sure to check edge.coefficient > 0 before re-adding it. - #ifdef ZLEVELS - if(UP) - if(check(U)) return U - else return null - if(DOWN) - if(check(D)) return D - else return null - #endif +Class Procs: -/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 + mark_direct() + Marks this connection as direct. Does not update the edge. + Called when the connection is made and there are no doors between A and B. + Also called by update() as a correction. - #ifdef ZLEVELS - if(UP) U = c - if(DOWN) D = c - #endif + mark_indirect() + Unmarks this connection as direct. Does not update the edge. + Called by update() as a correction. -/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() - #ifdef ZLEVELS - if(check(U)) U.update() - if(check(D)) D.update() - #endif + mark_space() + Marks this connection as unsimulated. Updating the connection will check the validity of this. + Called when the connection is made. + This will not be called as a correction, any connections failing a check against this mark are erased and rebuilt. -/connection_manager/proc/erase_all() - if(check(N)) N.erase() - if(check(S)) S.erase() - if(check(E)) E.erase() - if(check(W)) W.erase() - #ifdef ZLEVELS - if(check(U)) U.erase() - if(check(D)) D.erase() - #endif + direct() + Returns 1 if no doors are in between A and B. -/connection_manager/proc/check(connection/c) - return c && c.valid() + valid() + Returns 1 if the connection has not been erased. + erase() + Called by update() and connection_manager/erase_all(). + Marks the connection as erased and removes it from its edge. + + update() + Called by connection_manager/update_all(). + Makes numerous checks to decide whether the connection is still valid. Erases it automatically if not. + +*/ /connection/var/turf/simulated/A /connection/var/turf/simulated/B diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index bd100b8fdc..2c7e4373c0 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -1,10 +1,68 @@ +/* + +Overview: + These are what handle gas transfers between zones and into space. + They are found in a zone's edges list and in air_master.edges. + Each edge updates every air tick due to their role in gas transfer. + They come in two flavors, /connection_edge/zone and /connection_edge/unsimulated. + As the type names might suggest, they handle inter-zone and spacelike connections respectively. + +Class Vars: + + A - This always holds a zone. In unsimulated edges, it holds the only zone. + + connecting_turfs - This holds a list of connected turfs, mainly for the sake of airflow. + + coefficent - This is a marker for how many connections are on this edge. Used to determine the ratio of flow. + + connection_edge/zone + + B - This holds the second zone with which the first zone equalizes. + + direct - This counts the number of direct (i.e. with no doors) connections on this edge. + Any value of this is sufficient to make the zones mergeable. + + connection_edge/unsimulated + + B - This holds an unsimulated turf which has the gas values this edge is mimicing. + + air - Retrieved from B on creation and used as an argument for the legacy ShareSpace() proc. + +Class Procs: + + add_connection(connection/c) + Adds a connection to this edge. Usually increments the coefficient and adds a turf to connecting_turfs. + + remove_connection(connection/c) + Removes a connection from this edge. This works even if c is not in the edge, so be careful. + If the coefficient reaches zero as a result, the edge is erased. + + contains_zone(zone/Z) + Returns true if either A or B is equal to Z. Unsimulated connections return true only on A. + + erase() + Removes this connection from processing and zone edge lists. + + tick() + Called every air tick on edges in the processing list. Equalizes gas. + + flow(list/movable, differential, repelled) + Airflow proc causing all objects in movable to be checked against a pressure differential. + If repelled is true, the objects move away from any turf in connecting_turfs, otherwise they approach. + A check against vsc.lightest_airflow_pressure should generally be performed before calling this. + + get_connected_zone(zone/from) + Helper proc that allows getting the other zone of an edge given one of them. + Only on /connection_edge/zone, otherwise use A. + +*/ + /connection_edge/var/zone/A /connection_edge/var/list/connecting_turfs = list() /connection_edge/var/coefficient = 0 -/connection_edge/var/id /connection_edge/New() CRASH("Cannot make connection edge without specifications.") @@ -115,6 +173,10 @@ flow(attracted, abs(differential), 0) flow(repelled, abs(differential), 1) +//Helper proc to get connections for a zone. +/connection_edge/zone/proc/get_connected_zone(zone/from) + if(A == from) return B + else return A /connection_edge/unsimulated/var/turf/B /connection_edge/unsimulated/var/datum/gas_mixture/air diff --git a/code/ZAS/ConnectionManager.dm b/code/ZAS/ConnectionManager.dm new file mode 100644 index 0000000000..1c101f4b45 --- /dev/null +++ b/code/ZAS/ConnectionManager.dm @@ -0,0 +1,102 @@ +/* + +Overview: + The connection_manager class stores connections in each cardinal direction on a turf. + It isn't always present if a turf has no connections, check if(connections) before using. + Contains procs for mass manipulation of connection data. + +Class Vars: + + NSEWUD - Connections to this turf in each cardinal direction. + +Class Procs: + + get(d) + Returns the connection (if any) in this direction. + Preferable to accessing the connection directly because it checks validity. + + place(connection/c, d) + Called by air_master.connect(). Sets the connection in the specified direction to c. + + update_all() + Called after turf/update_air_properties(). Updates the validity of all connections on this turf. + + erase_all() + Called when the turf is changed with ChangeTurf(). Erases all existing connections. + + check(connection/c) + Checks for connection validity. It's possible to have a reference to a connection that has been erased. + + +*/ + +/turf/var/tmp/connection_manager/connections + +/connection_manager/var/connection/N +/connection_manager/var/connection/S +/connection_manager/var/connection/E +/connection_manager/var/connection/W + +#ifdef ZLEVELS +/connection_manager/var/connection/U +/connection_manager/var/connection/D +#endif + +/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 + + #ifdef ZLEVELS + if(UP) + if(check(U)) return U + else return null + if(DOWN) + if(check(D)) return D + else return null + #endif + +/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 + + #ifdef ZLEVELS + if(UP) U = c + if(DOWN) D = c + #endif + +/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() + #ifdef ZLEVELS + if(check(U)) U.update() + if(check(D)) D.update() + #endif + +/connection_manager/proc/erase_all() + if(check(N)) N.erase() + if(check(S)) S.erase() + if(check(E)) E.erase() + if(check(W)) W.erase() + #ifdef ZLEVELS + if(check(U)) U.erase() + if(check(D)) D.erase() + #endif + +/connection_manager/proc/check(connection/c) + return c && c.valid() \ No newline at end of file diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index b074358193..429906a649 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -2,6 +2,69 @@ var/datum/controller/air_system/air_master var/tick_multiplier = 2 +/* + +Overview: + The air controller does everything. There are tons of procs in here. + +Class Vars: + zones - All zones currently holding one or more turfs. + edges - All processing edges. + + tiles_to_update - Tiles scheduled to update next tick. + zones_to_update - Zones which have had their air changed and need air archival. + active_hotspots - All processing fire objects. + + active_zones - The number of zones which were archived last tick. Used in debug verbs. + next_id - The next UID to be applied to a zone. Mostly useful for debugging purposes as zones do not need UIDs to function. + +Class Procs: + + mark_for_update(turf/T) + Adds the turf to the update list. When updated, update_air_properties() will be called. + When stuff changes that might affect airflow, call this. It's basically the only thing you need. + + add_zone(zone/Z) and remove_zone(zone/Z) + Adds zones to the zones list. Does not mark them for update. + + air_blocked(turf/A, turf/B) + Returns a bitflag consisting of: + AIR_BLOCKED - The connection between turfs is physically blocked. No air can pass. + ZONE_BLOCKED - There is a door between the turfs, so zones cannot cross. Air may or may not be permeable. + + has_valid_zone(turf/T) + Checks the presence and validity of T's zone. + May be called on unsimulated turfs, returning 0. + + merge(zone/A, zone/B) + Called when zones have a direct connection and equivalent pressure and temperature. + Merges the zones to create a single zone. + + connect(turf/simulated/A, turf/B) + Called by turf/update_air_properties(). The first argument must be simulated. + Creates a connection between A and B. + + mark_zone_update(zone/Z) + Adds zone to the update list. Unlike mark_for_update(), this one is called automatically whenever + air is returned from a simulated turf. + + equivalent_pressure(zone/A, zone/B) + Currently identical to A.air.compare(B.air). Returns 1 when directly connected zones are ready to be merged. + + get_edge(zone/A, zone/B) + get_edge(zone/A, turf/B) + Gets a valid connection_edge between A and B, creating a new one if necessary. + + has_same_air(turf/A, turf/B) + Used to determine if an unsimulated edge represents a specific turf. + Simulated edges use connection_edge/contains_zone() for the same purpose. + Returns 1 if A has identical gases and temperature to B. + + remove_edge(connection_edge/edge) + Called when an edge is erased. Removes it from processing. + +*/ + //Geometry lists /datum/controller/air_system/var/list/zones = list() @@ -228,9 +291,6 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun /datum/controller/air_system/proc/equivalent_pressure(zone/A, zone/B) return A.air.compare(B.air) -/datum/controller/air_system/proc/active_zones() - return active_zones - /datum/controller/air_system/proc/get_edge(zone/A, zone/B) if(istype(B)) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 4edfb2ecfb..8373771ae2 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -1,3 +1,44 @@ +/* + +Overview: + Each zone is a self-contained area where gas values would be the same if tile-based equalization were run indefinitely. + If you're unfamiliar with ZAS, FEA's air groups would have similar functionality if they didn't break in a stiff breeze. + +Class Vars: + name - A name of the format "Zone [#]", used for debugging. + invalid - True if the zone has been erased and is no longer eligible for processing. + needs_update - True if the zone has been added to the update list. + edges - A list of edges that connect to this zone. + air - The gas mixture that any turfs in this zone will return. Values are per-tile with a group multiplier. + +Class Procs: + add(turf/simulated/T) + Adds a turf to the contents, sets its zone and merges its air. + + remove(turf/simulated/T) + Removes a turf, sets its zone to null and erases any gas graphics. + Invalidates the zone if it has no more tiles. + + c_merge(zone/into) + Invalidates this zone and adds all its former contents to into. + + c_invalidate() + Marks this zone as invalid and removes it from processing. + + rebuild() + Invalidates the zone and marks all its former tiles for updates. + + add_tile_air(turf/simulated/T) + Adds the air contained in T.air to the zone's air supply. Called when adding a turf. + + tick() + Called only when the gas content is changed. Archives values and changes gas graphics. + + dbg_data(mob/M) + Sends M a printout of important figures for the zone. + +*/ + /zone/var/name /zone/var/invalid = 0 @@ -86,12 +127,6 @@ for(var/turf/simulated/T in contents) T.set_graphic(air.graphic) -/zone/proc/remove_connection(connection/c) - return - -/zone/proc/add_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]" diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index 2f763f2b1a..26bb4d3b21 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -19,6 +19,12 @@ air_master.mark_for_update(turf) When stuff happens, call this. It works on everything. You basically don't need to worry about any other functions besides CanPass(). +Notes for people who used ZAS before: + There is no connected_zones anymore. + To get the zones that are connected to a zone, use this loop: + for(var/connection_edge/zone/edge in zone.edges) + var/zone/connected_zone = edge.get_connected_zone(zone) + */ #define ZASDBG