First pass on experimental change that allows zones to "Sleep"

This commit is contained in:
SkyMarshal
2013-09-08 17:34:22 -07:00
parent 3b65251a8a
commit f76f5ae532
7 changed files with 205 additions and 64 deletions

View File

@@ -126,10 +126,11 @@ zone/proc/DebugDisplay(client/client)
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)
var/turf/zloc = pick(Z.contents)
client << "\red Illegal air datum shared by: [zloc.loc.name]"
if(air_master)
for(var/zone/Z in air_master.zones)
if(Z.air == air && Z != src)
var/turf/zloc = pick(Z.contents)
client << "\red Illegal air datum shared by: [zloc.loc.name]"
client/proc/TestZASRebuild()
@@ -181,7 +182,7 @@ client/proc/TestZASRebuild()
sleep(5)
if(turfs[current])
current.overlays += overlays[turfs[current]]
current.overlays -= overlays[turfs[current]]
turfs[current] = lowest_id
current.overlays += overlays[lowest_id]
sleep(5)
@@ -209,4 +210,4 @@ client/proc/TestZASRebuild()
for(var/turf/current in turfs)
current.overlays -= overlays
return final_arrangement
return final_arrangement

View File

@@ -53,6 +53,9 @@ Important Procedures
*/
#define ZONE_ACTIVE 1
#define ZONE_SLEEPING 0
var/tick_multiplier = 2
atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
@@ -105,6 +108,14 @@ var/datum/controller/air_system/air_master
var/list/connections_to_check = list()
var/list/connections_to_check_alternate
var/list/potential_intrazone_connections = list()
//Zone lists
var/list/active_zones = list()
var/list/zones_needing_rebuilt = list()
var/list/zones = list()
var/current_cycle = 0
var/update_delay = 5 //How long between check should it try to process atmos again.
var/failed_ticks = 0 //How many ticks have runtimed?
@@ -170,7 +181,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
current_cycle++
//If there are tiles to update, do so.
tick_progress = "update_air_properties"
tick_progress = "updating turf properties"
if(tiles_to_update.len)
updating_tiles = TRUE
@@ -192,17 +203,49 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
tiles_to_update |= tiles_to_update_alternate
tiles_to_update_alternate = null
//Rebuild zones.
if(.)
tick_progress = "rebuilding zones"
if(zones_needing_rebuilt.len)
for(var/zone/zone in zones_needing_rebuilt)
zone.Rebuild()
zones_needing_rebuilt = list()
//Check sanity on connection objects.
if(.)
tick_progress = "connections_to_check"
tick_progress = "checking/creating connections"
if(connections_to_check.len)
checking_connections = TRUE
for(var/connection/C in connections_to_check)
C.Cleanup()
for(var/turf/simulated/turf_1 in potential_intrazone_connections)
for(var/turf/simulated/turf_2 in potential_intrazone_connections[turf_1])
if(!turf_1.zone || !turf_2.zone)
continue
if(turf_1.zone == turf_2.zone)
continue
var/should_skip = FALSE
if(turf_1 in air_master.turfs_with_connections)
for(var/connection/C in turfs_with_connections[turf_1])
if(C.B == turf_2 || C.A == turf_2)
should_skip = TRUE
break
if(should_skip)
continue
new /connection(turf_1, turf_2)
checking_connections = FALSE
potential_intrazone_connections = list()
if(connections_to_check_alternate)
connections_to_check = connections_to_check_alternate
connections_to_check_alternate = null
@@ -211,8 +254,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
//Process zones.
if(.)
tick_progress = "zone/process()"
for(var/zone/Z in zones)
tick_progress = "processing zones"
for(var/zone/Z in active_zones)
if(Z.last_update < current_cycle)
var/output = Z.process()
if(Z)
@@ -222,7 +265,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
//Ensure tiles still have zones.
if(.)
tick_progress = "tiles_to_reconsider_zones"
tick_progress = "reconsidering zones on turfs"
if(tiles_to_reconsider_zones.len)
reconsidering_zones = TRUE
@@ -240,7 +283,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
//Process fires.
if(.)
tick_progress = "active_hotspots (fire)"
tick_progress = "processing fire"
for(var/obj/fire/F in active_hotspots)
if(. && F && !F.process())
. = 0
@@ -297,3 +340,21 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
else
tiles_to_reconsider_zones |= zoneless_turf
/datum/controller/air_system/proc/AddIntrazoneConnection(var/turf/simulated/A, var/turf/simulated/B)
if(!istype(A) || !istype(B))
return
if(A in potential_intrazone_connections)
if(B in potential_intrazone_connections[A])
return
if (B in potential_intrazone_connections)
if(A in potential_intrazone_connections[B])
return
potential_intrazone_connections[B] += A
else
potential_intrazone_connections[B] = list(A)

View File

@@ -155,7 +155,9 @@ proc/ZConnect(turf/simulated/A,turf/simulated/B)
//Make some preliminary checks to see if the connection is valid.
if(!A.zone || !B.zone) return
if(A.zone == B.zone) return
if(A.zone == B.zone)
air_master.AddIntrazoneConnection(A,B)
return
if(A.CanPass(null, B, 1.5, 1) && A.zone.air.compare(B.zone.air))
return ZMerge(A.zone,B.zone)

View File

@@ -20,22 +20,21 @@
return GM
/turf/remove_air(amount as num, var/filtered = 0)
/turf/remove_air(amount as num)
var/datum/gas_mixture/GM = new
var/sum = oxygen + carbon_dioxide + nitrogen + (toxins*(1-filtered))
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
if(sum>0)
GM.oxygen = (oxygen/sum)*amount
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
GM.nitrogen = (nitrogen/sum)*amount
GM.toxins = ((toxins/sum)*amount)*(1-filtered)
GM.toxins = (toxins/sum)*amount
GM.temperature = temperature
GM.update_values()
return GM
/turf/simulated/var/current_graphic = null
/turf/simulated/var/tmp/datum/gas_mixture/air
@@ -96,7 +95,7 @@
/turf/simulated/assume_air(datum/gas_mixture/giver)
if(!giver) return 0
if(zone)
zone.air.merge(giver)
zone.assume_air(giver)
return 1
else
return ..()
@@ -110,21 +109,20 @@
else
return ..()
/turf/simulated/remove_air(amount as num, var/filtered = 0)
/turf/simulated/remove_air(amount as num)
if(zone)
var/datum/gas_mixture/removed = null
removed = zone.air.remove(amount, filtered)
return removed
return zone.remove_air(amount)
else if(air)
var/datum/gas_mixture/removed = null
removed = air.remove(amount, filtered)
removed = air.remove(amount)
if(air.check_tile_graphic())
update_visuals(air)
return removed
else
return ..(amount, filtered)
return ..()
/turf/simulated/proc/update_air_properties()
var/air_directions_archived = air_check_directions
@@ -179,7 +177,7 @@
//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
air_master.zones_needing_rebuilt.Add(zone)
//Parse if we need to remove the tile, or rebuild the zone.
else if(istype(NT) && NT in zone.unsimulated_tiles)
@@ -197,7 +195,7 @@
//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)
zone.rebuild = 1
air_master.zones_needing_rebuilt.Add(zone)
//Not adjacent to anything, and unsimulated. Goodbye~
else

View File

@@ -1,11 +1,12 @@
var/list/zones = list()
var/list/DoorDirections = list(NORTH,WEST) //Which directions doors turfs can connect to zones
var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs can connect to zones
/zone
var/dbg_output = 0 //Enables debug output.
var/rebuild = 0 //If 1, zone will be rebuilt on next process. Not sure if used.
var/datum/gas_mixture/air //The air contents of the zone.
var/datum/gas_mixture/archived_air
var/list/contents //All the tiles that are contained in this zone.
var/list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
@@ -17,6 +18,9 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
var/list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed.
var/last_update = 0
var/last_rebuilt = 0
var/status = ZONE_ACTIVE
var/interactions_with_neighbors = 0
var/progress = "nothing"
@@ -50,7 +54,9 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
air.update_values()
//Add this zone to the global list.
zones.Add(src)
if(air_master)
air_master.zones.Add(src)
air_master.active_zones.Add(src)
//DO NOT USE. Use the SoftDelete proc.
@@ -63,14 +69,21 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
if(src in Z.connected_zones)
Z.connected_zones.Remove(src)
air_master.AddConnectionToCheck(connections)
zones.Remove(src)
if(air_master)
air_master.zones.Remove(src)
air_master.active_zones.Remove(src)
air_master.zones_needing_rebuilt.Remove(src)
air = null
. = ..()
//Handles deletion via garbage collection.
/zone/proc/SoftDelete()
zones.Remove(src)
if(air_master)
air_master.zones.Remove(src)
air_master.active_zones.Remove(src)
air_master.zones_needing_rebuilt.Remove(src)
air = null
//Ensuring the zone list doesn't get clogged with null values.
@@ -149,11 +162,6 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
progress = "problem with: Rebuild()"
//Does rebuilding stuff.
if(rebuild)
rebuild = 0
Rebuild() //Shoving this into a proc.
if(!contents.len) //If we got soft deleted.
return
@@ -253,10 +261,17 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
if(Z.last_update > last_update)
continue
//Handle adjacent zones that are sleeping
if(Z.status == ZONE_SLEEPING)
if(air.compare(Z.air))
continue
else
Z.SetStatus(ZONE_ACTIVE)
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())
if(moles_delta > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1)
if(!air.compare(Z.air))
if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure)
Airflow(src,Z)
var/unsimulated_boost = 0
@@ -267,17 +282,75 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
unsimulated_boost = max(0, min(3, unsimulated_boost))
ShareRatio( air , Z.air , connected_zones[Z] + unsimulated_boost)
Z.interactions_with_neighbors++
interactions_with_neighbors++
for(var/zone/Z in closed_connection_zones)
//If that zone has already processed, skip it.
if(Z.last_update > last_update)
continue
var/handle_temperature = abs(air.temperature - Z.air.temperature) > vsc.connection_temperature_delta
if(Z.status == ZONE_SLEEPING)
if (handle_temperature)
Z.SetStatus(ZONE_ACTIVE)
else
continue
if(air && Z.air)
if( abs(air.temperature - Z.air.temperature) > vsc.connection_temperature_delta )
if( handle_temperature )
ShareHeat(air, Z.air, closed_connection_zones[Z])
Z.interactions_with_neighbors++
interactions_with_neighbors++
if(!interactions_with_neighbors && !unsimulated_tiles)
SetStatus(ZONE_SLEEPING)
interactions_with_neighbors = 0
progress = "all components completed successfully, the problem is not here"
/zone/proc/SetStatus(var/new_status)
if(status == ZONE_SLEEPING && new_status == ZONE_ACTIVE)
air_master.active_zones.Add(src)
status = ZONE_ACTIVE
else if(status == ZONE_ACTIVE && new_status == ZONE_SLEEPING)
air_master.active_zones.Remove(src)
status = ZONE_SLEEPING
if(!archived_air)
archived_air = new
archived_air.copy_from(air)
/zone/proc/assume_air(var/datum/gas_mixture/giver)
if(status == ZONE_ACTIVE)
return air.merge(giver)
else
var/result = air.merge(giver)
if(!archived_air.compare(air))
SetStatus(ZONE_ACTIVE)
return result
/zone/proc/remove_air(var/amount)
if(status == ZONE_ACTIVE)
return air.remove(amount)
else
var/result = air.remove(amount)
if(!archived_air.compare(air))
SetStatus(ZONE_ACTIVE)
return result
////////////////
//Air Movement//
////////////////
@@ -463,6 +536,11 @@ proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
//Used for updating zone geometry when a zone is cut into two parts.
zone/proc/Rebuild()
if(last_rebuilt == air_master.current_cycle)
return
last_rebuilt = air_master.current_cycle
var/list/new_zone_contents = IsolateContents()
if(new_zone_contents.len == 1)
return

View File

@@ -193,7 +193,7 @@ var/list/AAlarmWireColorToIndex
#define SPEED_OF_LIGHT_SQ 9e+16
#define FIRE_DAMAGE_MODIFIER 0.0215 //Higher values result in more external fire damage to the skin (default 0.0215)
#define AIR_DAMAGE_MODIFIER 2.025 //More means less damage from hot air scalding lungs, less = more damage. (default 2.025)
#define INFINITY 1e31 //closer then enough
#define INFINITY 1.#INF
//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
#define MAX_MESSAGE_LEN 1024

View File

@@ -2,45 +2,46 @@
set category = "Debug"
set name = "Show Air Report"
/*(!master_controller || !air_master)
if(!master_controller || !air_master)
alert(usr,"Master_controller or air_master not found.","Air Report")
return 0
return
var/active_groups = 0
var/inactive_groups = 0
var/active_tiles = 0
for(var/datum/air_group/group in air_master.air_groups)
if(group.group_processing)
active_groups++
else
inactive_groups++
active_tiles += group.members.len
var/active_groups = air_master.active_zones.len
var/inactive_groups = air_master.zones.len - active_groups
var/hotspots = 0
for(var/obj/effect/hotspot/hotspot in world)
for(var/obj/fire/hotspot in world)
hotspots++
var/active_on_main_station = 0
var/inactive_on_main_station = 0
for(var/zone/zone in air_master.zones)
var/turf/simulated/turf = locate() in zone.contents
if(turf && turf.z == 1)
if(zone.status)
active_on_main_station++
else
inactive_on_main_station++
var/output = {"<B>AIR SYSTEMS REPORT</B><HR>
<B>General Processing Data</B><BR>
<B># of Groups:</B> [air_master.air_groups.len]<BR>
Cycle: [air_master.current_cycle]<br>
Groups: [air_master.zones.len]<BR>
---- <I>Active:</I> [active_groups]<BR>
---- <I>Inactive:</I> [inactive_groups]<BR>
-------- <I>Tiles:</I> [active_tiles]<BR>
<B># of Active Singletons:</B> [air_master.active_singletons.len]<BR>
---- <I>Inactive:</I> [inactive_groups]<BR><br>
---- <I>Active on station:</i> [active_on_main_station]<br>
---- <i>Inactive on station:</i> [inactive_on_main_station]<br>
<BR>
<B>Special Processing Data</B><BR>
<B>Hotspot Processing:</B> [hotspots]<BR>
<B>High Temperature Processing:</B> [air_master.active_super_conductivity.len]<BR>
<B>High Pressure Processing:</B> [air_master.high_pressure_delta.len] (not yet implemented)<BR>
<BR>
Hotspot Processing: [hotspots]<BR>
<br>
<B>Geometry Processing Data</B><BR>
<B>Group Rebuild:</B> [air_master.groups_to_rebuild.len]<BR>
<B>Tile Update:</B> [air_master.tiles_to_update.len]<BR>
Tile Update: [air_master.tiles_to_update.len]<BR>
"}
usr << browse(output,"window=airreport")
feedback_add_details("admin_verb","SAR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
*/
/client/proc/air_status(turf/target as turf)
set category = "Debug"
set name = "Display Air Status"