From 72c331bfa797654d0515a891f287c46807fdcb5f Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Thu, 25 Jul 2013 21:34:12 -0700 Subject: [PATCH] Several ZAS fixes. Adds insulation to doors, modifiable by admins from the ZAS setting panel. Fixes a logic error with connections. (I am dumb some days) Improves the runtime detection and reporting. Improves "zone info" debug verb. --- code/ZAS/Connection.dm | 2 + code/ZAS/Debug.dm | 28 +++++++----- code/ZAS/FEA_system.dm | 20 ++++++--- code/ZAS/Variable Settings.dm | 7 +++ code/ZAS/ZAS_Zones.dm | 59 +++++++++++++------------ code/controllers/master_controller.dm | 6 +-- code/modules/flufftext/Hallucination.dm | 4 +- 7 files changed, 76 insertions(+), 50 deletions(-) diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index e612e98ea6..8a919d5043 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -367,6 +367,7 @@ Indirect connections will not merge the two zones after they reach equilibrium. if(zone_A && zone_B) DisconnectZones(zone_A, zone_B) ConnectZones(A.zone, B.zone, indirect) + zone_A = A.zone //The "B" zone changed. else if(B.zone && B.zone != zone_B) @@ -394,6 +395,7 @@ Indirect connections will not merge the two zones after they reach equilibrium. if(zone_A && zone_B) DisconnectZones(zone_A, zone_B) ConnectZones(A.zone, B.zone, indirect) + zone_B = B.zone #undef CONNECTION_DIRECT diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index 70ab3614c7..807208a5a3 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -8,7 +8,8 @@ client/proc/Zone_Info(turf/T as null|turf) mob << "No zone here." else if(zone_debug_images) - images -= zone_debug_images + for(var/zone in zone_debug_images) + images -= zone_debug_images[zone] zone_debug_images = null client/var/list/zone_debug_images @@ -23,12 +24,12 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf) "South" = SOUTH,\ "East" = EAST,\ "West" = WEST,\ - "None" = null) + "N/A" = null) var/direction = input("What direction do you wish to test?","Set direction") as null|anything in direction_list if(!direction) return - if(direction == "None") + if(direction == "N/A") if(T.CanPass(null, T, 0,0)) mob << "The turf can pass air! :D" else @@ -64,11 +65,14 @@ zone/proc/DebugDisplay(client/client) if(!client.zone_debug_images) client.zone_debug_images = list() + + var/list/current_zone_images = list() + for(var/turf/T in contents) - client.zone_debug_images += image('debug_group.dmi', T) + current_zone_images += image('debug_group.dmi', T, null, TURF_LAYER) for(var/turf/space/S in unsimulated_tiles) - client.zone_debug_images += image('debug_space.dmi', S) + current_zone_images += image('debug_space.dmi', S, null, TURF_LAYER) client << "Zone Air Contents" client << "Oxygen: [air.oxygen]" @@ -85,8 +89,8 @@ zone/proc/DebugDisplay(client/client) for(var/connection/C in connections) client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]" - client.zone_debug_images += image('debug_connect.dmi', C.A) - client.zone_debug_images += image('debug_connect.dmi', C.B) + current_zone_images += image('debug_connect.dmi', C.A, null, TURF_LAYER) + current_zone_images += image('debug_connect.dmi', C.B, null, TURF_LAYER) client << "Connected Zones:" for(var/zone/zone in connected_zones) @@ -99,13 +103,17 @@ zone/proc/DebugDisplay(client/client) if(!istype(C,/connection)) client << "[C] (Not Connection!)" - client.images += client.zone_debug_images + if(!client.zone_debug_images) + client.zone_debug_images = list() + client.zone_debug_images[src] = current_zone_images + + client.images += client.zone_debug_images[src] else dbg_output = 0 - client.images -= client.zone_debug_images - client.zone_debug_images = null + client.images -= client.zone_debug_images[src] + client.zone_debug_images.Remove(src) for(var/zone/Z in zones) if(Z.air == air && Z != src) diff --git a/code/ZAS/FEA_system.dm b/code/ZAS/FEA_system.dm index acd48aad67..c2a33ad99d 100644 --- a/code/ZAS/FEA_system.dm +++ b/code/ZAS/FEA_system.dm @@ -85,7 +85,7 @@ atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) return 1 -var/global/datum/controller/air_system/air_master +var/datum/controller/air_system/air_master /datum/controller/air_system/ //Geoemetry lists @@ -180,17 +180,20 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun 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() + if(.) + tiles_to_update = list() //Check sanity on connection objects. - tick_progress = "connections_to_check" + if(.) + 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(.) + 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) @@ -198,7 +201,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun tiles_to_reconsider_zones = list() //Process zones. - tick_progress = "zone/process()" + if(.) + tick_progress = "zone/process()" for(var/zone/Z in zones) if(Z.last_update < current_cycle) var/output = Z.process() @@ -207,9 +211,11 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun if(. && Z && !output) . = 0 //Process fires. - tick_progress = "active_hotspots (fire)" + if(.) + tick_progress = "active_hotspots (fire)" for(var/obj/fire/F in active_hotspots) if(. && F && !F.process()) . = 0 - tick_progress = "success" \ No newline at end of file + if(.) + tick_progress = "success" \ No newline at end of file diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm index 43bbebf767..80e243e3c5 100644 --- a/code/ZAS/Variable Settings.dm +++ b/code/ZAS/Variable Settings.dm @@ -62,6 +62,13 @@ var/global/vs_control/vsc = new var/airflow_mob_slowdown_NAME = "Airflow Slowdown" var/airflow_mob_slowdown_DESC = "Time in tenths of a second to add as a delay to each movement by a mob if they are fighting the pull of the airflow." + var/connection_insulation = 0.4 + var/connection_insulation_NAME = "Connections - Insulation" + var/connection_insulation_DESC = "How insulative a connection is, in terms of heat transfer. 1 is perfectly insulative, and 0 is perfectly conductive." + + var/connection_temperature_delta = 10 + var/connection_temperature_delta_NAME = "Connections - Temperature Difference" + var/connection_temperature_delta_DESC = "The smallest temperature difference which will cause heat to travel through doors." /vs_control/var/list/settings = list() diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm index 8dd39b79cb..026f6e3d45 100644 --- a/code/ZAS/ZAS_Zones.dm +++ b/code/ZAS/ZAS_Zones.dm @@ -36,14 +36,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs //Generate the gas_mixture for use in txhis zone by using the average of the gases //defined at startup. air = new - var/members = contents.len - for(var/turf/simulated/T in contents) - air.oxygen += T.oxygen / members - air.nitrogen += T.nitrogen / members - air.carbon_dioxide += T.carbon_dioxide / members - air.toxins += T.toxins / members - air.temperature += T.temperature / members air.group_multiplier = contents.len + for(var/turf/simulated/T in contents) + air.oxygen += T.oxygen / air.group_multiplier + air.nitrogen += T.nitrogen / air.group_multiplier + air.carbon_dioxide += T.carbon_dioxide / air.group_multiplier + air.toxins += T.toxins / air.group_multiplier + air.temperature += T.temperature / air.group_multiplier air.update_values() //Add this zone to the global list. @@ -80,8 +79,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs for(var/zone/Z in connected_zones) if(src in Z.connected_zones) Z.connected_zones.Remove(src) + connected_zones = null + for(var/connection/C in connections) air_master.connections_to_check += C + connections = null return 1 @@ -108,12 +110,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs /zone/proc/RemoveTurf(turf/T) //Same, but in reverse. - if(istype(T, /turf/simulated) && T in unsimulated_tiles) //It happens. Gods know why. - unsimulated_tiles -= T - if(!unsimulated_tiles.len) - unsimulated_tiles = null - src.AddTurf(T) //Make sure it gets onto the simulated list. - else if(istype(T, /turf/simulated)) + if(istype(T, /turf/simulated)) if(!(T in contents)) return contents -= T @@ -151,7 +148,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs if(!contents.len) //If we got soft deleted. return - progress = "problem with: air.adjust()" + progress = "problem with: air regeneration" //Sometimes explosions will cause the air to be deleted for some reason. if(!air) @@ -162,26 +159,23 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs air.total_moles() world.log << "Air object lost in zone. Regenerating." + progress = "problem with: ShareSpace()" + if(unsimulated_tiles) + if(locate(/turf/simulated) in unsimulated_tiles) + for(var/turf/simulated/T in unsimulated_tiles) + unsimulated_tiles -= T - if(unsimulated_tiles && length(unsimulated_tiles)) - for(var/turf/simulated/T in unsimulated_tiles) - RemoveTurf(T) - if(unsimulated_tiles && length(unsimulated_tiles)) + if(unsimulated_tiles.len) var/moved_air = ShareSpace(air,unsimulated_tiles) if(moved_air > vsc.airflow_lightest_pressure) AirflowSpace(src) - - progress = "problem with: air.react()" - - //React the air here. - //Handled by fire, no need for this. -// air.react(null,0) + else + unsimulated_tiles = null //Check the graphic. - progress = "problem with: modifying turf graphics" air.graphic = 0 @@ -236,12 +230,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs //Check if the connection is valid first. if(!C.Cleanup()) continue + //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 && C.A.zone && C.B.zone) //indirect = 2 is a direct connection. - if(C.indirect == 2 ) + if( C.indirect == 2 ) if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles) ZMerge(C.A.zone,C.B.zone) @@ -249,6 +244,10 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs //Share some for(var/zone/Z in connected_zones) + //If that zone has already processed, skip it. + if(Z.last_update > last_update) + continue + if(air && Z.air) //Ensure we're not doing pointless calculations on equilibrium zones. var/moles_delta = abs(air.total_moles() - Z.air.total_moles()) @@ -265,7 +264,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs for(var/zone/Z in closed_connection_zones) if(air && Z.air) - if( abs(air.temperature - Z.air.temperature) > 10 ) + if( abs(air.temperature - Z.air.temperature) > vsc.connection_temperature_delta ) ShareHeat(air, Z.air, closed_connection_zones[Z]) progress = "all components completed successfully, the problem is not here" @@ -274,7 +273,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs //Air Movement// //////////////// -var/list/sharing_lookup_table = list(0.15, 0.20, 0.24, 0.27, 0.30, 0.33) +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. @@ -404,7 +403,9 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick. ratio = sharing_lookup_table[unsimulated_tiles.len] - ratio *= 2 + + //We need to adjust it to account for the insulation settings. + ratio *= 1 - vsc.connection_insulation A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg ) A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index c22bf1e2dd..22a905a207 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -132,12 +132,12 @@ datum/controller/game_controller/proc/process() //src.set_debug_state("Air Master") air_master.current_cycle++ - var/success = air_master.tick() //Changed so that a runtime does not crash the ticker. - if(!success) //Runtimed. + if(!air_master.tick()) //Runtimed. air_master.failed_ticks++ if(air_master.failed_ticks > 5) world << "RUNTIMES IN ATMOS TICKER. Killing air simulation!" - message_admins("ZASALERT: unable run [air_master.tick_progress], tell someone about this!") + world.log << "### ZAS SHUTDOWN" + message_admins("ZASALERT: unable to run [air_master.tick_progress], shutting down!") log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]") air_processing_killed = 1 air_master.failed_ticks = 0 diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 0aa2b06a5f..18e4f2916a 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -77,7 +77,9 @@ mob/living/carbon/proc/handle_hallucinations() halitem.name = "Flashbang" if(client) client.screen += halitem spawn(rand(100,250)) - del halitem + if(client) + client.screen -= halitem + halitem = null if(26 to 40) //Flashes of danger //src << "Danger Flash"