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.
This commit is contained in:
SkyMarshal
2013-07-25 21:34:12 -07:00
parent 8124f7bfe7
commit 72c331bfa7
7 changed files with 76 additions and 50 deletions

View File

@@ -367,6 +367,7 @@ Indirect connections will not merge the two zones after they reach equilibrium.
if(zone_A && zone_B) if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B) DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect) ConnectZones(A.zone, B.zone, indirect)
zone_A = A.zone
//The "B" zone changed. //The "B" zone changed.
else if(B.zone && B.zone != zone_B) 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) if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B) DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect) ConnectZones(A.zone, B.zone, indirect)
zone_B = B.zone
#undef CONNECTION_DIRECT #undef CONNECTION_DIRECT

View File

@@ -8,7 +8,8 @@ client/proc/Zone_Info(turf/T as null|turf)
mob << "No zone here." mob << "No zone here."
else else
if(zone_debug_images) if(zone_debug_images)
images -= zone_debug_images for(var/zone in zone_debug_images)
images -= zone_debug_images[zone]
zone_debug_images = null zone_debug_images = null
client/var/list/zone_debug_images client/var/list/zone_debug_images
@@ -23,12 +24,12 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
"South" = SOUTH,\ "South" = SOUTH,\
"East" = EAST,\ "East" = EAST,\
"West" = WEST,\ "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 var/direction = input("What direction do you wish to test?","Set direction") as null|anything in direction_list
if(!direction) if(!direction)
return return
if(direction == "None") if(direction == "N/A")
if(T.CanPass(null, T, 0,0)) if(T.CanPass(null, T, 0,0))
mob << "The turf can pass air! :D" mob << "The turf can pass air! :D"
else else
@@ -64,11 +65,14 @@ zone/proc/DebugDisplay(client/client)
if(!client.zone_debug_images) if(!client.zone_debug_images)
client.zone_debug_images = list() client.zone_debug_images = list()
var/list/current_zone_images = list()
for(var/turf/T in contents) 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) 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 << "<u>Zone Air Contents</u>" client << "<u>Zone Air Contents</u>"
client << "Oxygen: [air.oxygen]" client << "Oxygen: [air.oxygen]"
@@ -85,8 +89,8 @@ zone/proc/DebugDisplay(client/client)
for(var/connection/C in connections) for(var/connection/C in connections)
client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]" client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
client.zone_debug_images += image('debug_connect.dmi', C.A) current_zone_images += image('debug_connect.dmi', C.A, null, TURF_LAYER)
client.zone_debug_images += image('debug_connect.dmi', C.B) current_zone_images += image('debug_connect.dmi', C.B, null, TURF_LAYER)
client << "Connected Zones:" client << "Connected Zones:"
for(var/zone/zone in connected_zones) for(var/zone/zone in connected_zones)
@@ -99,13 +103,17 @@ zone/proc/DebugDisplay(client/client)
if(!istype(C,/connection)) if(!istype(C,/connection))
client << "[C] (Not 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 else
dbg_output = 0 dbg_output = 0
client.images -= client.zone_debug_images client.images -= client.zone_debug_images[src]
client.zone_debug_images = null client.zone_debug_images.Remove(src)
for(var/zone/Z in zones) for(var/zone/Z in zones)
if(Z.air == air && Z != src) if(Z.air == air && Z != src)

View File

@@ -85,7 +85,7 @@ atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
return 1 return 1
var/global/datum/controller/air_system/air_master var/datum/controller/air_system/air_master
/datum/controller/air_system/ /datum/controller/air_system/
//Geoemetry lists //Geoemetry lists
@@ -180,17 +180,20 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
if(. && T && !T.update_air_properties()) if(. && T && !T.update_air_properties())
. = 0 //If a runtime occured, make sure we can sense it. . = 0 //If a runtime occured, make sure we can sense it.
//message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()") //message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
tiles_to_update = list() if(.)
tiles_to_update = list()
//Check sanity on connection objects. //Check sanity on connection objects.
tick_progress = "connections_to_check" if(.)
tick_progress = "connections_to_check"
if(connections_to_check.len) if(connections_to_check.len)
for(var/connection/C in connections_to_check) for(var/connection/C in connections_to_check)
C.CheckPassSanity() C.CheckPassSanity()
connections_to_check = list() connections_to_check = list()
//Ensure tiles still have zones. //Ensure tiles still have zones.
tick_progress = "tiles_to_reconsider_zones" if(.)
tick_progress = "tiles_to_reconsider_zones"
if(tiles_to_reconsider_zones.len) if(tiles_to_reconsider_zones.len)
for(var/turf/simulated/T in tiles_to_reconsider_zones) for(var/turf/simulated/T in tiles_to_reconsider_zones)
if(!T.zone) if(!T.zone)
@@ -198,7 +201,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
tiles_to_reconsider_zones = list() tiles_to_reconsider_zones = list()
//Process zones. //Process zones.
tick_progress = "zone/process()" if(.)
tick_progress = "zone/process()"
for(var/zone/Z in zones) for(var/zone/Z in zones)
if(Z.last_update < current_cycle) if(Z.last_update < current_cycle)
var/output = Z.process() var/output = Z.process()
@@ -207,9 +211,11 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
if(. && Z && !output) if(. && Z && !output)
. = 0 . = 0
//Process fires. //Process fires.
tick_progress = "active_hotspots (fire)" if(.)
tick_progress = "active_hotspots (fire)"
for(var/obj/fire/F in active_hotspots) for(var/obj/fire/F in active_hotspots)
if(. && F && !F.process()) if(. && F && !F.process())
. = 0 . = 0
tick_progress = "success" if(.)
tick_progress = "success"

View File

@@ -62,6 +62,13 @@ var/global/vs_control/vsc = new
var/airflow_mob_slowdown_NAME = "Airflow Slowdown" 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/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() /vs_control/var/list/settings = list()

View File

@@ -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 //Generate the gas_mixture for use in txhis zone by using the average of the gases
//defined at startup. //defined at startup.
air = new 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 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() air.update_values()
//Add this zone to the global list. //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) for(var/zone/Z in connected_zones)
if(src in Z.connected_zones) if(src in Z.connected_zones)
Z.connected_zones.Remove(src) Z.connected_zones.Remove(src)
connected_zones = null
for(var/connection/C in connections) for(var/connection/C in connections)
air_master.connections_to_check += C air_master.connections_to_check += C
connections = null
return 1 return 1
@@ -108,12 +110,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
/zone/proc/RemoveTurf(turf/T) /zone/proc/RemoveTurf(turf/T)
//Same, but in reverse. //Same, but in reverse.
if(istype(T, /turf/simulated) && T in unsimulated_tiles) //It happens. Gods know why. if(istype(T, /turf/simulated))
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(!(T in contents)) if(!(T in contents))
return return
contents -= T contents -= T
@@ -151,7 +148,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
if(!contents.len) //If we got soft deleted. if(!contents.len) //If we got soft deleted.
return return
progress = "problem with: air.adjust()" progress = "problem with: air regeneration"
//Sometimes explosions will cause the air to be deleted for some reason. //Sometimes explosions will cause the air to be deleted for some reason.
if(!air) if(!air)
@@ -162,26 +159,23 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
air.total_moles() air.total_moles()
world.log << "Air object lost in zone. Regenerating." world.log << "Air object lost in zone. Regenerating."
progress = "problem with: ShareSpace()" 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)) if(unsimulated_tiles.len)
for(var/turf/simulated/T in unsimulated_tiles)
RemoveTurf(T)
if(unsimulated_tiles && length(unsimulated_tiles))
var/moved_air = ShareSpace(air,unsimulated_tiles) var/moved_air = ShareSpace(air,unsimulated_tiles)
if(moved_air > vsc.airflow_lightest_pressure) if(moved_air > vsc.airflow_lightest_pressure)
AirflowSpace(src) AirflowSpace(src)
else
progress = "problem with: air.react()" unsimulated_tiles = null
//React the air here.
//Handled by fire, no need for this.
// air.react(null,0)
//Check the graphic. //Check the graphic.
progress = "problem with: modifying turf graphics" progress = "problem with: modifying turf graphics"
air.graphic = 0 air.graphic = 0
@@ -236,12 +230,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
//Check if the connection is valid first. //Check if the connection is valid first.
if(!C.Cleanup()) if(!C.Cleanup())
continue continue
//Do merging if conditions are met. Specifically, if there's a non-door connection //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 //to somewhere with space, the zones are merged regardless of equilibrium, to speed
//up spacing in areas with double-plated windows. //up spacing in areas with double-plated windows.
if(C && C.A.zone && C.B.zone) if(C && C.A.zone && C.B.zone)
//indirect = 2 is a direct connection. //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) if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles)
ZMerge(C.A.zone,C.B.zone) ZMerge(C.A.zone,C.B.zone)
@@ -249,6 +244,10 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
//Share some //Share some
for(var/zone/Z in connected_zones) 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) if(air && Z.air)
//Ensure we're not doing pointless calculations on equilibrium zones. //Ensure we're not doing pointless calculations on equilibrium zones.
var/moles_delta = abs(air.total_moles() - Z.air.total_moles()) 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) for(var/zone/Z in closed_connection_zones)
if(air && Z.air) 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]) ShareHeat(air, Z.air, closed_connection_zones[Z])
progress = "all components completed successfully, the problem is not here" 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// //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) proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
//Shares a specific ratio of gas between mixtures using simple weighted averages. //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. 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 = 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.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg )
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )

View File

@@ -132,12 +132,12 @@ datum/controller/game_controller/proc/process()
//src.set_debug_state("Air Master") //src.set_debug_state("Air Master")
air_master.current_cycle++ air_master.current_cycle++
var/success = air_master.tick() //Changed so that a runtime does not crash the ticker. if(!air_master.tick()) //Runtimed.
if(!success) //Runtimed.
air_master.failed_ticks++ air_master.failed_ticks++
if(air_master.failed_ticks > 5) if(air_master.failed_ticks > 5)
world << "<font color='red'><b>RUNTIMES IN ATMOS TICKER. Killing air simulation!</font></b>" world << "<font color='red'><b>RUNTIMES IN ATMOS TICKER. Killing air simulation!</font></b>"
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]") log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]")
air_processing_killed = 1 air_processing_killed = 1
air_master.failed_ticks = 0 air_master.failed_ticks = 0

View File

@@ -77,7 +77,9 @@ mob/living/carbon/proc/handle_hallucinations()
halitem.name = "Flashbang" halitem.name = "Flashbang"
if(client) client.screen += halitem if(client) client.screen += halitem
spawn(rand(100,250)) spawn(rand(100,250))
del halitem if(client)
client.screen -= halitem
halitem = null
if(26 to 40) if(26 to 40)
//Flashes of danger //Flashes of danger
//src << "Danger Flash" //src << "Danger Flash"