diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm
index 8b7ab992c93..5e2e64cb6e5 100644
--- a/code/ZAS/FEA_gas_mixture.dm
+++ b/code/ZAS/FEA_gas_mixture.dm
@@ -8,7 +8,7 @@ What are the archived variables for?
#define SPECIFIC_HEAT_AIR 20
#define SPECIFIC_HEAT_CDO 30
#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \
- (carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*SPECIFIC_HEAT_TOXIN)
+ max(0, carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + toxins * SPECIFIC_HEAT_TOXIN)
#define MINIMUM_HEAT_CAPACITY 0.0003
#define QUANTIZE(variable) (round(variable,0.0001))
diff --git a/code/ZAS/FEA_system.dm b/code/ZAS/FEA_system.dm
index c2a33ad99db..0f246fa6ee3 100644
--- a/code/ZAS/FEA_system.dm
+++ b/code/ZAS/FEA_system.dm
@@ -87,17 +87,24 @@ atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
var/datum/controller/air_system/air_master
-/datum/controller/air_system/
- //Geoemetry lists
+/datum/controller/air_system
+ //Geometry lists
var/list/turfs_with_connections = list()
var/list/active_hotspots = list()
//Special functions lists
+ var/reconsidering_zones = FALSE
var/list/tiles_to_reconsider_zones = list()
+ var/list/tiles_to_reconsider_alternate
//Geometry updates lists
+ var/updating_tiles = FALSE
var/list/tiles_to_update = list()
+ var/list/tiles_to_update_alternate
+
+ var/checking_connections = FALSE
var/list/connections_to_check = list()
+ var/list/connections_to_check_alternate
var/current_cycle = 0
var/update_delay = 5 //How long between check should it try to process atmos again.
@@ -106,20 +113,7 @@ var/datum/controller/air_system/air_master
var/tick_progress = 0
-/* process()
- //Call this to process air movements for a cycle
-
- process_rebuild_select_groups()
- //Used by process()
- //Warning: Do not call this
-
- rebuild_group(datum/air_group)
- //Used by process_rebuild_select_groups()
- //Warning: Do not call this, add the group to air_master.groups_to_rebuild instead
- */
-
-
-/datum/controller/air_system/proc/setup()
+/datum/controller/air_system/proc/Tetup()
//Purpose: Call this at the start to setup air groups geometry
// (Warning: Very processor intensive but only must be done once per round)
//Called by: Gameticker/Master controller
@@ -147,10 +141,11 @@ var/datum/controller/air_system/air_master
Total Simulated Turfs: [simulated_turf_count]
Total Zones: [zones.len]
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]"}
- /*
- spawn start()
-/datum/controller/air_system/proc/start()
+// spawn Start()
+
+
+/datum/controller/air_system/proc/Start()
//Purpose: This is kicked off by the master controller, and controls the processing of all atmosphere.
//Called by: Master controller
//Inputs: None.
@@ -162,26 +157,38 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
while(1)
if(!kill_air)
current_cycle++
- var/success = tick() //Changed so that a runtime does not crash the ticker.
+ var/success = Tick() //Changed so that a runtime does not crash the ticker.
if(!success) //Runtimed.
failed_ticks++
if(failed_ticks > 20)
world << "ERROR IN ATMOS TICKER. Killing air simulation!"
kill_air = 1
sleep(max(5,update_delay*tick_multiplier))
- */
-/datum/controller/air_system/proc/tick()
+
+/datum/controller/air_system/proc/Tick()
. = 1 //Set the default return value, for runtime detection.
+ //If there are tiles to update, do so.
tick_progress = "update_air_properties"
- if(tiles_to_update.len) //If there are tiles to update, do so.
+ if(tiles_to_update.len)
+ updating_tiles = TRUE
+
for(var/turf/simulated/T in tiles_to_update)
if(. && T && !T.update_air_properties())
- . = 0 //If a runtime occured, make sure we can sense it.
- //message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
+ //If a runtime occured, make sure we can sense it.
+ . = 0
+
+ updating_tiles = FALSE
+
if(.)
- tiles_to_update = list()
+ if(tiles_to_update_alternate)
+ tiles_to_update = tiles_to_update_alternate
+ else
+ tiles_to_update = list()
+
+ else if(tiles_to_update_alternate)
+ tiles_to_update |= tiles_to_update_alternate
//Check sanity on connection objects.
if(.)
@@ -218,4 +225,25 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
. = 0
if(.)
- tick_progress = "success"
\ No newline at end of file
+ tick_progress = "success"
+
+
+/datum/controller/air_system/proc/AddTurfToUpdate(turf/simulated/outdated_turf)
+ var/list/tiles_to_check = list()
+
+ if(istype(outdated_turf))
+ tiles_to_check |= outdated_turf
+
+ if(istype(outdated_turf, /turf))
+ for(var/direction in cardinal)
+ var/turf/simulated/adjacent_turf = get_step(outdated_turf, direction)
+ if(istype(adjacent_turf))
+ tiles_to_check |= adjacent_turf
+
+ if(updating_tiles)
+ if(!tiles_to_update_alternate)
+ tiles_to_update_alternate = tiles_to_check
+ else
+ tiles_to_update_alternate |= tiles_to_check
+ else
+ tiles_to_update |= tiles_to_check
\ No newline at end of file
diff --git a/code/ZAS/ZAS_Turfs.dm b/code/ZAS/ZAS_Turfs.dm
index 04af9a05283..9851eb2fa5e 100644
--- a/code/ZAS/ZAS_Turfs.dm
+++ b/code/ZAS/ZAS_Turfs.dm
@@ -135,8 +135,8 @@
if(!zone && !blocks_air) //No zone, but not a wall.
for(var/direction in DoorDirections) //Check door directions first.
- if(air_check_directions&direction)
- var/turf/simulated/T = get_step(src,direction)
+ if(air_check_directions & direction)
+ var/turf/simulated/T = get_step(src, direction)
if(!istype(T))
continue
if(T.zone)
@@ -144,7 +144,7 @@
break
if(!zone) //Still no zone
for(var/direction in CounterDoorDirections) //Check the others second.
- if(air_check_directions&direction)
+ if(air_check_directions & direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
@@ -161,73 +161,20 @@
for(var/connection/C in air_master.turfs_with_connections["\ref[src]"])
air_master.connections_to_check |= C
- if(zone && !zone.rebuild)
+ if(zone && !zone.rebuild && CanPass(null, src, 0, 0))
+
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(!istype(T))
continue
//I can connect to air in this direction
- if(air_check_directions&direction)
+ if(air_check_directions & direction && !(air_directions_archived & direction))
- //If either block air, we must look to see if the adjacent turfs need rebuilt.
- if(!CanPass(null, T, 0, 0))
-
- //Target blocks air
- if(!T.CanPass(null, T, 0, 0))
- var/turf/NT = get_step(T, direction)
-
- //If that turf is in my zone still, rebuild.
- if(istype(NT,/turf/simulated) && NT in zone.contents)
- zone.rebuild = 1
-
- //If that is an unsimulated tile in my zone, see if we need to rebuild or just remove.
- else if(istype(NT) && NT in zone.unsimulated_tiles)
- var/consider_rebuild = 0
- for(var/d in cardinal)
- var/turf/UT = get_step(NT,d)
- if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
- consider_rebuild = 1
- break
- if(consider_rebuild)
- zone.rebuild = 1 //Gotta check if we need to rebuild, dammit
- else
- zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
-
- //To make a closed connection through closed door.
- ZConnect(T, src)
-
- //If I block air.
- else if(T.zone && !T.zone.rebuild)
- var/turf/NT = get_step(src, reverse_direction(direction))
-
- //If I am splitting a zone, rebuild.
- if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))
- T.zone.rebuild = 1
-
- //If NT is unsimulated, parse if I should remove it or rebuild.
- else if(istype(NT) && NT in T.zone.unsimulated_tiles)
- var/consider_rebuild = 0
- for(var/d in cardinal)
- var/turf/UT = get_step(NT,d)
- if(istype(UT, /turf/simulated) && UT.zone == T.zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
- consider_rebuild = 1
- break
-
- //Needs rebuilt.
- if(consider_rebuild)
- T.zone.rebuild = 1
-
- //Not adjacent to anything, and unsimulated. Goodbye~
- else
- T.zone.RemoveTurf(NT)
-
- else
- //Produce connection through open door.
- ZConnect(src,T)
+ ZConnect(src,T)
//Something like a wall was built, changing the geometry.
- else if(air_directions_archived&direction)
+ else if(!(air_check_directions & direction) && air_directions_archived & direction)
var/turf/NT = get_step(T, direction)
//If the tile is in our own zone, and we cannot connect to it, better rebuild.
@@ -289,13 +236,13 @@
return 0
for(var/obj/obstacle in src)
- if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
+ if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, T, 1.5, 1))
return 0
for(var/obj/obstacle in T)
- if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
+ if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, src, 1.5, 1))
return 0
@@ -311,13 +258,13 @@
return 0
for(var/obj/obstacle in src)
- if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
+ if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, T, 0, 0))
return 0
for(var/obj/obstacle in T)
- if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
+ if(istype(obstacle, /obj/machinery/door) && !(obstacle:air_properties_vary_with_direction))
continue
if(!obstacle.CanPass(null, src, 0, 0))
return 0
diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm
index 860f57cd370..a3667a0180d 100644
--- a/code/ZAS/ZAS_Zones.dm
+++ b/code/ZAS/ZAS_Zones.dm
@@ -383,7 +383,7 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
unsim_co2 *= correction_ratio
unsim_nitrogen *= correction_ratio
unsim_plasma *= correction_ratio
- unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen,unsim_co2,unsim_nitrogen,unsim_plasma)
+ unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma)
var
ratio = sharing_lookup_table[6]
@@ -402,6 +402,9 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
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 >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index be684e32010..1a543381da4 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -56,7 +56,7 @@ datum/controller/game_controller/proc/setup()
if(!air_master)
air_master = new /datum/controller/air_system()
- air_master.setup()
+ air_master.Setup()
if(!ticker)
ticker = new /datum/controller/gameticker()
@@ -127,7 +127,7 @@ datum/controller/game_controller/proc/process()
last_thing_processed = air_master.type
air_master.current_cycle++
- if(!air_master.tick()) //Runtimed.
+ if(!air_master.Tick()) //Runtimed.
air_master.failed_ticks++
if(air_master.failed_ticks > 5)
world << "RUNTIMES IN ATMOS TICKER. Killing air simulation!"
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 6aec44f7f17..0f64866f459 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -257,36 +257,12 @@
return 1
/obj/machinery/door/proc/update_nearby_tiles(need_rebuild)
- if(!air_master) return 0
+ if(!air_master)
+ return 0
- var/turf/simulated/source = loc
- var/turf/simulated/north = get_step(source,NORTH)
- var/turf/simulated/south = get_step(source,SOUTH)
- var/turf/simulated/east = get_step(source,EAST)
- var/turf/simulated/west = get_step(source,WEST)
-
- update_heat_protection(loc)
-
- if(istype(source)) air_master.tiles_to_update += source
- if(istype(north)) air_master.tiles_to_update += north
- if(istype(south)) air_master.tiles_to_update += south
- if(istype(east)) air_master.tiles_to_update += east
- if(istype(west)) air_master.tiles_to_update += west
-
- if(width > 1)
- var/turf/simulated/next_turf = src
- var/step_dir = turn(dir, 180)
- for(var/current_step = 2, current_step <= width, current_step++)
- next_turf = get_step(src, step_dir)
- north = get_step(next_turf, step_dir)
- east = get_step(next_turf, turn(step_dir, 90))
- south = get_step(next_turf, turn(step_dir, -90))
-
- update_heat_protection(next_turf)
-
- if(istype(north)) air_master.tiles_to_update |= north
- if(istype(south)) air_master.tiles_to_update |= south
- if(istype(east)) air_master.tiles_to_update |= east
+ for(var/turf/simulated/turf in locs)
+ update_heat_protection(turf)
+ air_master.AddTurfToUpdate(turf)
return 1
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 66184774c49..c8d0d4d110b 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -15,13 +15,10 @@
/obj/machinery/door/window/update_nearby_tiles(need_rebuild)
- if(!air_master) return 0
+ if(!air_master)
+ return 0
- var/turf/simulated/source = get_turf(src)
- var/turf/simulated/target = get_step(source,dir)
-
- if(istype(source)) air_master.tiles_to_update |= source
- if(istype(target)) air_master.tiles_to_update |= target
+ air_master.AddTurfToUpdate(get_turf(src))
return 1
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 6b657bda789..640fc00afcd 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -27,19 +27,10 @@
//Looks like copy/pasted code... I doubt 'need_rebuild' is even used here - Nodrak
/obj/machinery/shield/proc/update_nearby_tiles(need_rebuild)
- if(!air_master) return 0
+ if(!air_master)
+ return 0
- var/turf/simulated/source = get_turf(src)
- var/turf/simulated/north = get_step(source,NORTH)
- var/turf/simulated/south = get_step(source,SOUTH)
- var/turf/simulated/east = get_step(source,EAST)
- var/turf/simulated/west = get_step(source,WEST)
-
- if(istype(source)) air_master.tiles_to_update |= source
- if(istype(north)) air_master.tiles_to_update |= north
- if(istype(south)) air_master.tiles_to_update |= south
- if(istype(east)) air_master.tiles_to_update |= east
- if(istype(west)) air_master.tiles_to_update |= west
+ air_master.AddTurfToUpdate(get_turf(src))
return 1
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index d3e7144297a..c0f783c52d6 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -1030,19 +1030,10 @@ steam.start() -- spawns the effect
proc/update_nearby_tiles(need_rebuild)
- if(!air_master) return 0
+ if(!air_master)
+ return 0
- var/turf/simulated/source = get_turf(src)
- var/turf/simulated/north = get_step(source,NORTH)
- var/turf/simulated/south = get_step(source,SOUTH)
- var/turf/simulated/east = get_step(source,EAST)
- var/turf/simulated/west = get_step(source,WEST)
-
- if(istype(source)) air_master.tiles_to_update |= source
- if(istype(north)) air_master.tiles_to_update |= north
- if(istype(south)) air_master.tiles_to_update |= south
- if(istype(east)) air_master.tiles_to_update |= east
- if(istype(west)) air_master.tiles_to_update |= west
+ air_master.AddTurfToUpdate(get_turf(src))
return 1
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 04b3bdc19c5..64e9623fcaf 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -156,20 +156,9 @@
return
proc/update_nearby_tiles(need_rebuild) //Copypasta from airlock code
- if(!air_master) return 0
-
- var/turf/simulated/source = loc
- var/turf/simulated/north = get_step(source,NORTH)
- var/turf/simulated/south = get_step(source,SOUTH)
- var/turf/simulated/east = get_step(source,EAST)
- var/turf/simulated/west = get_step(source,WEST)
-
- if(istype(source)) air_master.tiles_to_update += source
- if(istype(north)) air_master.tiles_to_update += north
- if(istype(south)) air_master.tiles_to_update += south
- if(istype(east)) air_master.tiles_to_update += east
- if(istype(west)) air_master.tiles_to_update += west
-
+ if(!air_master)
+ return 0
+ air_master.AddTurfToUpdate(get_turf(src))
return 1
/obj/structure/mineral_door/iron
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 478f6989baa..f13f3f1decc 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -294,12 +294,9 @@ obj/structure/windoor_assembly/Del()
return
/obj/structure/windoor_assembly/proc/update_nearby_tiles(need_rebuild)
- if(!air_master) return 0
+ if(!air_master)
+ return 0
- var/turf/simulated/source = loc
- var/turf/simulated/target = get_step(source,dir)
-
- if(istype(source)) air_master.tiles_to_update += source
- if(istype(target)) air_master.tiles_to_update += target
+ air_master.AddTurfToUpdate(loc)
return 1
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index bb38bbcd854..22d9c1a0b63 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -316,21 +316,9 @@
//This proc has to do with airgroups and atmos, it has nothing to do with smoothwindows, that's update_nearby_tiles().
/obj/structure/window/proc/update_nearby_tiles(need_rebuild)
- if(!air_master) return 0
- if(!dir in cardinal)
- var/turf/simulated/source = get_turf(src)
- if(istype(source))
- air_master.tiles_to_update |= source
- for(var/dir in cardinal)
- var/turf/simulated/target = get_step(source,dir)
- if(istype(target)) air_master.tiles_to_update |= target
- return 1
-
- var/turf/simulated/source = get_turf(src)
- var/turf/simulated/target = get_step(source,dir)
-
- if(istype(source)) air_master.tiles_to_update |= source
- if(istype(target)) air_master.tiles_to_update |= target
+ if(!air_master)
+ return 0
+ AddTurfToUpdate(
return 1