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