From 39df196edca3c276fc50350fcf775a8313b83af4 Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Tue, 21 May 2013 22:37:50 -0700 Subject: [PATCH] Fixed disposal issue. Delayed Jungle setup until after air master initializes Master controller now properly ceases atmos simulation if runtimes occur (and are detected). Cleanup more ZAS stuff. FEA_system.dm, ZAS/ZAS_Turfs.dm, ZAS_Zones.dm. Canisters now autoconnect to portables connectors on creation. (Fixes airlocks not having attached canisters) Doors can now be made which respect directional door types (e.g. windoors and directional firelocks) and is handled better. --- .../Cael_Aislinn/Jungle/jungle.dm | 5 +- code/ZAS/Connection.dm | 8 +- code/ZAS/FEA_system.dm | 175 +----------------- code/ZAS/ZAS_Turfs.dm | 88 ++++++--- code/ZAS/ZAS_Zones.dm | 20 +- code/controllers/master_controller.dm | 5 +- code/game/machinery/atmoalter/canister.dm | 8 + code/game/machinery/doors/door.dm | 1 + code/game/machinery/doors/firedoor.dm | 1 + code/game/machinery/doors/windowdoor.dm | 1 + 10 files changed, 101 insertions(+), 211 deletions(-) diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dm index 9511d17e804..5c053434fbf 100644 --- a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dm +++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dm @@ -130,11 +130,8 @@ desc = "a mysterious and ancient piece of machinery" var/list/animal_spawners = list() - New() - ..() - Initialise() -/obj/machinery/jungle_controller/proc/Initialise() +/obj/machinery/jungle_controller/proc/initialise() world << "\red \b Setting up jungle, this may take a bleeding eternity..." //crash dat shuttle diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index 14d1f8a7aab..da41edf406b 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -83,12 +83,12 @@ connection if(A.zone && A.zone.connections) A.zone.connections.Remove(src) if(!A.zone.connections.len) - del A.zone.connections + A.zone.connections = null if(B) if(B.zone && B.zone.connections) B.zone.connections.Remove(src) if(!B.zone.connections.len) - del B.zone.connections + B.zone.connections = null //Disconnect zones while handling unusual conditions. // e.g. loss of a zone on a turf @@ -333,7 +333,7 @@ connection if(zone_A.connections) zone_A.connections.Remove(src) if(!zone_A.connections.len) - del zone_A.connections + zone_A.connections = null if(A.zone) if(!A.zone.connections) @@ -360,7 +360,7 @@ connection if(zone_B.connections) zone_B.connections.Remove(src) if(!zone_B.connections.len) - del zone_B.connections + zone_B.connections = null if(B.zone) if(!B.zone.connections) diff --git a/code/ZAS/FEA_system.dm b/code/ZAS/FEA_system.dm index 2db7e94dd54..94b7c5cf6d1 100644 --- a/code/ZAS/FEA_system.dm +++ b/code/ZAS/FEA_system.dm @@ -101,7 +101,6 @@ datum //Geometry updates lists var/list/tiles_to_update = list() var/list/connections_to_check = list() - var/list/rebuilds_to_consider = list() var/current_cycle = 0 var/update_delay = 5 //How long between check should it try to process atmos again. @@ -181,45 +180,27 @@ datum tick_progress = "update_air_properties" if(tiles_to_update.len) //If there are tiles to update, do so. for(var/turf/simulated/T in tiles_to_update) - var/output = T.update_air_properties() - if(. && T && !output) + 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()") tiles_to_update = list() - tick_progress = "reconsider_zones" - if(rebuilds_to_consider.len) - for(var/turf/T in rebuilds_to_consider) - if(istype(T, /turf/simulated) && T.zone && !T.zone.rebuild) - var/turf/simulated/other_turf = rebuilds_to_consider[T] - if(istype(other_turf)) - ConsiderRebuild(T,other_turf) - else if(istype(other_turf, /list)) - var/list/temp_turfs = other_turf - for(var/turf/NT in temp_turfs) - ConsiderRebuild(T,NT) - else if (istype(T)) - var/turf/simulated/other_turf = rebuilds_to_consider[T] - if(istype(other_turf)) - ConsiderRebuild(other_turf,T) - else if(istype(other_turf, /list)) - var/list/temp_turfs = other_turf - for(var/turf/simulated/NT in temp_turfs) - ConsiderRebuild(NT,T) - rebuilds_to_consider = list() - + //Check sanity on connection objects. tick_progress = "connections_to_check" if(connections_to_check.len) for(var/connection/C in connections_to_check) C.CheckPassSanity() connections_to_check = list() + //Ensure tiles still have zones. tick_progress = "tiles_to_reconsider_zones" if(tiles_to_reconsider_zones.len) for(var/turf/simulated/T in tiles_to_reconsider_zones) if(!T.zone) new /zone(T) + tiles_to_reconsider_zones = list() + //Process zones. tick_progress = "zone/process()" for(var/zone/Z in zones) if(Z.last_update < current_cycle) @@ -228,150 +209,10 @@ datum Z.last_update = current_cycle if(. && Z && !output) . = 0 - log_admin("ZASALERT: unable run zone/process(), [Z.progress]") - message_admins("ZASALERT. ZASALERT: unable run zone/proc/process(), [Z.progress], tell someone about this!") - + //Process fires. tick_progress = "active_hotspots (fire)" for(var/obj/fire/F in active_hotspots) - var/output = F.process() - if(. && F && !output) + if(. && F && !F.process()) . = 0 - //message_admins("ZASALERT: Unable run obj/fire/process()") - tick_progress = "success" - - proc/AddToConsiderRebuild(var/turf/simulated/T, var/turf/NT) - var/turf/existing_test = rebuilds_to_consider[T] - var/turf/existing_test_alternate = rebuilds_to_consider[NT] - - if(existing_test) - if(NT == existing_test) - return - else if(islist(existing_test) && existing_test[NT]) - return - - else if(existing_test_alternate) - if(T == existing_test_alternate) - return - else if(islist(existing_test_alternate) && existing_test_alternate[T]) - return - - if(istype(T)) - if(istype(existing_test)) - var/list/temp_list = list(NT = 1, existing_test = 1) - rebuilds_to_consider[T] = temp_list - else if(istype(existing_test, /list)) - existing_test[NT] = 1 - else - rebuilds_to_consider[T] = NT - - else if(istype(NT, /turf/simulated)) - if(istype(existing_test_alternate)) - var/list/temp_list = list(T = 1, existing_test_alternate = 1) - rebuilds_to_consider[NT] = temp_list - else if(istype(existing_test_alternate, /list)) - existing_test_alternate[T] = 1 - else - rebuilds_to_consider[NT] = T - - proc/ConsiderRebuild(var/turf/simulated/T, var/turf/NT) - - if(!istype(T)) return - //zones should naturally spread to these tiles eventually - if(!T.zone || !NT.zone) - return - - if(istype(NT, /turf/simulated) && NT.zone != T.zone) - T.zone.RemoveTurf(NT) - if(NT.zone) - NT.zone.RemoveTurf(T) - return - if(T.zone.rebuild) - return - - var/zone/zone = T.zone - - var/target_dir = get_dir(T, NT) - if(target_dir in list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) - T.zone.rebuild = 1 - return - var/test_dir = turn(target_dir, 90) - - var/turf/simulated/current = T - var/turf/simulated/next - var/stepped_back = 0 - - if( !(T.air_check_directions&test_dir || T.air_check_directions&turn(target_dir, 270)) ) - //Step back, then try to connect. - if(!(T.air_check_directions&get_dir(NT, T))) - zone.rebuild = 1 - return - current = get_step(T, get_dir(NT, T)) - if(!istype(current) || !(current.air_check_directions&test_dir || current.air_check_directions&turn(target_dir, 270)) ) - zone.rebuild = 1 - return - stepped_back = 1 - - if ( !(current.air_check_directions&test_dir) && current.air_check_directions&turn(target_dir, 270) ) - //Try to connect to the right hand side. - var/flipped = 0 - test_dir = turn(target_dir, 270) - - for(var/i = 1, i <= 10, i++) - if(get_dir(current, NT) in cardinal) - target_dir = get_dir(current, NT) - - if(!istype(current) || !(current.air_check_directions&target_dir || current.air_check_directions&test_dir)) - if(flipped) - zone.rebuild = 1 - return - current = T - test_dir = turn(target_dir, 180) - i = 0 - target_dir = get_dir(current, NT) - flipped = 1 - continue - - if(current.air_check_directions&target_dir && !stepped_back) - next = get_step(current, target_dir) - if(!next.HasDoor()) - current = next - - if(current.air_check_directions&test_dir && current != next) - next = get_step(current, test_dir) - if(!next.HasDoor()) - current = next - - if(current == NT) - return //We made it, yaaay~ - stepped_back = 0 - zone.rebuild = 1 - - else if ( current.air_check_directions&test_dir ) - //Try to connect to the left hand side. - for(var/i = 1, i <= 10, i++) - if(get_dir(current, NT) in cardinal) - target_dir = get_dir(current, NT) - - if(!istype(current) || !(current.air_check_directions&target_dir || current.air_check_directions&test_dir)) - zone.rebuild = 1 - return - - if(current.air_check_directions&target_dir && !stepped_back) - next = get_step(current, target_dir) - if(!next.HasDoor()) - current = next - - if(current.air_check_directions&test_dir && current != next) - next = get_step(current, test_dir) - if(!next.HasDoor()) - current = next - - if(current == NT) - return //We made it, yaaay~ - stepped_back = 0 - zone.rebuild = 1 - - else - //FUCK IT - zone.rebuild = 1 \ No newline at end of file + tick_progress = "success" \ No newline at end of file diff --git a/code/ZAS/ZAS_Turfs.dm b/code/ZAS/ZAS_Turfs.dm index e058cea3537..c66d77e5f37 100644 --- a/code/ZAS/ZAS_Turfs.dm +++ b/code/ZAS/ZAS_Turfs.dm @@ -165,27 +165,32 @@ turf if(!zone) //Still no zone, the floodfill determined it is not part of a larger zone. Force a zone on it. new/zone(list(src)) - if("\ref[src]" in air_master.turfs_with_connections) //Check pass sanity of the connections. + //Check pass sanity of the connections. + if("\ref[src]" in air_master.turfs_with_connections) for(var/connection/C in air_master.turfs_with_connections["\ref[src]"]) - if(!(C in air_master.connections_to_check)) - air_master.connections_to_check += C + air_master.connections_to_check |= C if(zone && !zone.rebuild) for(var/direction in cardinal) - if(zone.rebuild) - break - var/turf/T = get_step(src,direction) if(!istype(T)) continue - // var/list/zone/adjacent_zones = list() - if(air_check_directions&direction) //I can connect air in this direction - if(!CanPass(null, T, 0, 0)) //If either block air, we must look to see if the adjacent turfs need rebuilt. - if(!T.CanPass(null, T, 0, 0)) //Target blocks air + //I can connect to air in this direction + if(air_check_directions&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) - air_master.AddToConsiderRebuild(src,NT) + 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) @@ -194,17 +199,22 @@ turf consider_rebuild = 1 break if(consider_rebuild) - air_master.AddToConsiderRebuild(src,NT) //Gotta check if we need to rebuild, dammit + 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(T.zone && !T.zone.rebuild) //I block air. + //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))) - air_master.AddToConsiderRebuild(T,NT) + 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) @@ -212,30 +222,48 @@ turf 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) - air_master.AddToConsiderRebuild(T,NT) //Gotta check if we need to rebuild, dammit + T.zone.rebuild = 1 + + //Not adjacent to anything, and unsimulated. Goodbye~ else - T.zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~ + T.zone.RemoveTurf(NT) else + //Produce connection through open door. ZConnect(src,T) - else if(air_directions_archived&direction) //Something like a wall was built, changing the geometry. + //Something like a wall was built, changing the geometry. + else if(air_directions_archived&direction) var/turf/NT = get_step(T, direction) - if(istype(NT,/turf/simulated) && NT in zone.contents) - air_master.AddToConsiderRebuild(src,NT) - else if(istype(NT) && NT in zone.unsimulated_tiles) //Parse if we need to remove the tile, or rebuild the zone. + //If the tile is in our own zone, and we cannot connect to it, better rebuild. + if(istype(NT,/turf/simulated) && NT in zone.contents) + zone.rebuild = 1 + + //Parse if we need to remove the tile, or rebuild the zone. + else if(istype(NT) && NT in zone.unsimulated_tiles) var/consider_rebuild = 0 + + //Loop through all neighboring turfs to see if we should remove the turf or just rebuild. 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 + + //If we find a neighboring tile that is in the same zone, rebuild + if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) consider_rebuild = 1 break + + //The unsimulated turf is adjacent to another one of our zone's turfs, + // better rebuild to be sure we didn't get cut in twain if(consider_rebuild) - air_master.AddToConsiderRebuild(src,NT) //Gotta check if we need to rebuild, dammit + NT.zone.rebuild = 1 + + //Not adjacent to anything, and unsimulated. Goodbye~ else - zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~ + zone.RemoveTurf(NT) if(air_check_directions) processing = 1 @@ -254,8 +282,10 @@ turf if(isnum(O) && O) if(!D.density) continue if(istype(D,/obj/machinery/door/window)) - if(!O) continue - if(D.dir == get_dir(D,O)) return 1 + if(!istype(O)) + continue + if(D.dir == get_dir(D,O)) + return 1 else return 1 @@ -271,13 +301,13 @@ turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0) return 0 for(var/obj/obstacle in src) - if(istype(obstacle,/obj/machinery/door) && !istype(obstacle,/obj/machinery/door/window)) + 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) && !istype(obstacle,/obj/machinery/door/window)) + if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction) continue if(!obstacle.CanPass(null, src, 1.5, 1)) return 0 @@ -293,13 +323,13 @@ turf/proc/ZAirPass(turf/T) return 0 for(var/obj/obstacle in src) - if(istype(obstacle,/obj/machinery/door) && !istype(obstacle,/obj/machinery/door/window)) + 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) && !istype(obstacle,/obj/machinery/door/window)) + 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 213dd9393db..6401a63a9fb 100644 --- a/code/ZAS/ZAS_Zones.dm +++ b/code/ZAS/ZAS_Zones.dm @@ -20,6 +20,7 @@ zone // To make sure you're not spammed to death by airflow sound effects tmp/playsound_cooldown = 0 + //CREATION AND DELETION New(turf/start) . = ..() @@ -53,6 +54,7 @@ zone //Add this zone to the global list. zones.Add(src) + //LEGACY, DO NOT USE. Use the SoftDelete proc. Del() //Ensuring the zone list doesn't get clogged with null values. @@ -68,25 +70,27 @@ zone air = null . = ..() + //Handles deletion via garbage collection. proc/SoftDelete() zones.Remove(src) air = null + //Ensuring the zone list doesn't get clogged with null values. for(var/turf/simulated/T in contents) RemoveTurf(T) air_master.tiles_to_reconsider_zones += T + + //Removing zone connections and scheduling connection cleanup for(var/zone/Z in connected_zones) if(src in Z.connected_zones) Z.connected_zones.Remove(src) for(var/connection/C in connections) - if(C.zone_A == src) - C.zone_A = null - if(C.zone_B == src) - C.zone_B = null air_master.connections_to_check += C + return 1 + //ZONE MANAGEMENT FUNCTIONS proc/AddTurf(turf/T) //Adds the turf to contents, increases the size of the zone, and sets the zone var. @@ -270,7 +274,13 @@ zone/proc/process() if(moles_delta > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1) if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure) Airflow(src,Z) - ShareRatio( air , Z.air , connected_zones[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 = min(3, unsimulated_boost) + ShareRatio( air , Z.air , connected_zones[Z] + unsimulated_boost) for(var/zone/Z in closed_connection_zones) if(air && Z.air) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index c618079f684..3633cda3748 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -133,11 +133,12 @@ datum/controller/game_controller/proc/process() air_master.current_cycle++ var/success = air_master.tick() //Changed so that a runtime does not crash the ticker. if(!success) //Runtimed. - log_adminwarn("ZASALERT: air_system/tick() failed: [air_master.tick_progress]") air_master.failed_ticks++ if(air_master.failed_ticks > 5) world << "RUNTIMES IN ATMOS TICKER. Killing air simulation!" - kill_air = 1 + message_admins("ZASALERT: unable run [air_master.tick_progress], tell someone about this!") + log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]") + air_processing_killed = 1 air_master.failed_ticks = 0 air_cost = (world.timeofday - timer) / 10 diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index d43f7657f2c..002e7d4a251 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -18,6 +18,14 @@ use_power = 0 var/release_log = "" +/obj/machinery/portable_atmospherics/canister/New() + . = ..() + spawn() + var/obj/machinery/atmospherics/portables_connector/connector = locate() in loc + if(connector) + connected_port = connector + update_icon() + /obj/machinery/portable_atmospherics/canister/sleeping_agent name = "Canister: \[N2O\]" icon_state = "redws" diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index c09dbfdf682..465af474e69 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -18,6 +18,7 @@ var/glass = 0 var/normalspeed = 1 var/heat_proof = 0 // For glass airlocks/opacity firedoors + var/air_properties_vary_with_direction = 0 /obj/machinery/door/New() ..() diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 07a3a1b9b83..9566cd6db40 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -234,6 +234,7 @@ glass = 1 //There is a glass window so you can see through the door //This is needed due to BYOND limitations in controlling visibility heat_proof = 1 + air_properties_vary_with_direction = 1 CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(istype(mover) && mover.checkpass(PASSGLASS)) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 55aef446eaa..45ff776d401 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -11,6 +11,7 @@ opacity = 0 var/obj/item/weapon/airlock_electronics/electronics = null explosion_resistance = 5 + air_properties_vary_with_direction = 1 /obj/machinery/door/window/update_nearby_tiles(need_rebuild)