diff --git a/baystation12.dme b/baystation12.dme
index 5d6ebf9e675..a6af9b75351 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -741,10 +741,10 @@
#include "code\modules\customitems\item_defines.dm"
#include "code\modules\customitems\item_spawning.dm"
#include "code\modules\destilery\main.dm"
-#include "code\modules\DetectiveWork\detective_work.dm"
-#include "code\modules\DetectiveWork\evidence.dm"
-#include "code\modules\DetectiveWork\footprints_and_rag.dm"
-#include "code\modules\DetectiveWork\scanner.dm"
+#include "code\modules\detectivework\detective_work.dm"
+#include "code\modules\detectivework\evidence.dm"
+#include "code\modules\detectivework\footprints_and_rag.dm"
+#include "code\modules\detectivework\scanner.dm"
#include "code\modules\events\alien_infestation.dm"
#include "code\modules\events\blob.dm"
#include "code\modules\events\brand_intelligence.dm"
diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm
index 70b7f70e633..41dfd027f55 100644
--- a/code/ZAS/Connection.dm
+++ b/code/ZAS/Connection.dm
@@ -6,6 +6,9 @@ Indirect connections will not merge the two zones after they reach equilibrium.
#define CONNECTION_INDIRECT 1
#define CONNECTION_CLOSED 0
+#define ZONE_ACTIVE 1
+#define ZONE_SLEEPING 0
+
/connection
var/turf/simulated/A
var/turf/simulated/B
@@ -208,6 +211,11 @@ Indirect connections will not merge the two zones after they reach equilibrium.
zone_2.closed_connection_zones += zone_1
zone_2.closed_connection_zones[zone_1] = 1
+ if(zone_1.status == ZONE_SLEEPING)
+ zone_1.SetStatus(ZONE_ACTIVE)
+
+ if(zone_2.status == ZONE_SLEEPING)
+ zone_2.SetStatus(ZONE_ACTIVE)
/connection/proc/DisconnectZones(var/zone/zone_1, var/zone/zone_2)
//Sanity checking
diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm
index 762843d5b13..5ac704cf9fa 100644
--- a/code/ZAS/Debug.dm
+++ b/code/ZAS/Debug.dm
@@ -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
\ No newline at end of file
diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm
index 58ee345a033..89259c281b7 100644
--- a/code/ZAS/FEA_gas_mixture.dm
+++ b/code/ZAS/FEA_gas_mixture.dm
@@ -367,7 +367,7 @@ What are the archived variables for?
//del(giver)
return 1
-/datum/gas_mixture/proc/remove(amount, var/filtered = 0)
+/datum/gas_mixture/proc/remove(amount)
//Purpose: Removes a certain number of moles from the air.
//Called by: ?
//Inputs: How many moles to remove.
@@ -384,7 +384,7 @@ What are the archived variables for?
removed.oxygen = QUANTIZE((oxygen/sum)*amount)
removed.nitrogen = QUANTIZE((nitrogen/sum)*amount)
removed.carbon_dioxide = QUANTIZE((carbon_dioxide/sum)*amount)
- removed.toxins = QUANTIZE(((toxins/sum)*amount)*(1-filtered))
+ removed.toxins = QUANTIZE(((toxins/sum)*amount))
oxygen -= removed.oxygen/group_multiplier
nitrogen -= removed.nitrogen/group_multiplier
@@ -396,8 +396,8 @@ What are the archived variables for?
var/datum/gas/corresponding = new trace_gas.type()
removed.trace_gases += corresponding
- corresponding.moles = ((trace_gas.moles/sum)*amount)*(1-filtered)
- trace_gas.moles -= (corresponding.moles/group_multiplier)*(1-filtered)
+ corresponding.moles = ((trace_gas.moles/sum)*amount)
+ trace_gas.moles -= (corresponding.moles/group_multiplier)
removed.temperature = temperature
update_values()
diff --git a/code/ZAS/FEA_system.dm b/code/ZAS/FEA_system.dm
index 508cbb0125c..004de68358e 100644
--- a/code/ZAS/FEA_system.dm
+++ b/code/ZAS/FEA_system.dm
@@ -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)
\ No newline at end of file
diff --git a/code/ZAS/Functions.dm b/code/ZAS/Functions.dm
index 4a1ffaaea2a..3037e13f412 100644
--- a/code/ZAS/Functions.dm
+++ b/code/ZAS/Functions.dm
@@ -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)
diff --git a/code/ZAS/ZAS_Turfs.dm b/code/ZAS/ZAS_Turfs.dm
index d376d927f54..5280c572506 100644
--- a/code/ZAS/ZAS_Turfs.dm
+++ b/code/ZAS/ZAS_Turfs.dm
@@ -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
diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm
index 37aabee83ba..7bb8abd6b44 100644
--- a/code/ZAS/ZAS_Zones.dm
+++ b/code/ZAS/ZAS_Zones.dm
@@ -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
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 28f9bfe4126..bffdb4af2bf 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -265,6 +265,25 @@
if(!D.hidden[SCANNER])
dat += text("Warning: [D.form] Detected\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]
")
+ var/implnts = ""
+ for(var/obj/item/weapon/implant/I in occupant)
+ if(I in occupant)
+ if(I.implanted)
+ if(istype(I, /obj/item/weapon/implant/death_alarm))
+ implnts += "death alarm
"
+ if(istype(I, /obj/item/weapon/implant/loyalty))
+ implnts += "loyalty
"
+ if(istype(I, /obj/item/weapon/implant/chem))
+ implnts += "chemical
"
+ if(istype(I, /obj/item/weapon/implant/tracking))
+ implnts += "tracking
"
+
+ if(implnts)
+ dat += "
"
+ dat += "Detected implants:
"
+
+ dat += implnts
+
dat += "
| Organ | " diff --git a/code/global.dm b/code/global.dm index 69678943ab2..68d1fe6aee0 100644 --- a/code/global.dm +++ b/code/global.dm @@ -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 diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 1e328970fd8..f7a00256212 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -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 = {"AIR SYSTEMS REPORT
|---|