From f76f5ae53213255a04bd2246ff91539b5ff31bcd Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Sun, 8 Sep 2013 17:34:22 -0700 Subject: [PATCH 1/3] First pass on experimental change that allows zones to "Sleep" --- code/ZAS/Debug.dm | 13 +-- code/ZAS/FEA_system.dm | 73 +++++++++++++++-- code/ZAS/Functions.dm | 4 +- code/ZAS/ZAS_Turfs.dm | 24 +++--- code/ZAS/ZAS_Zones.dm | 104 +++++++++++++++++++++--- code/global.dm | 2 +- code/modules/admin/verbs/diagnostics.dm | 49 +++++------ 7 files changed, 205 insertions(+), 64 deletions(-) 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_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/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
General Processing Data
-# of Groups: [air_master.air_groups.len]
+ Cycle: [air_master.current_cycle]
+ Groups: [air_master.zones.len]
---- Active: [active_groups]
----- Inactive: [inactive_groups]
--------- Tiles: [active_tiles]
-# of Active Singletons: [air_master.active_singletons.len]
+---- Inactive: [inactive_groups]

+---- Active on station: [active_on_main_station]
+---- Inactive on station: [inactive_on_main_station]

Special Processing Data
-Hotspot Processing: [hotspots]
-High Temperature Processing: [air_master.active_super_conductivity.len]
-High Pressure Processing: [air_master.high_pressure_delta.len] (not yet implemented)
-
+ Hotspot Processing: [hotspots]
+
Geometry Processing Data
-Group Rebuild: [air_master.groups_to_rebuild.len]
-Tile Update: [air_master.tiles_to_update.len]
+ Tile Update: [air_master.tiles_to_update.len]
"} 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" From add3ed71c0892ea69e8dc22de0a74c60d0ffb27b Mon Sep 17 00:00:00 2001 From: SkyMarshal Date: Wed, 11 Sep 2013 11:39:55 -0700 Subject: [PATCH 2/3] Added new two-tile hazard door sprites, thanks to Ravensdale, and fixed a derp with the new ZAS sleeping stuff. --- code/ZAS/Connection.dm | 8 ++++++++ icons/obj/doors/DoorHazard2x1.dmi | Bin 804 -> 15200 bytes 2 files changed, 8 insertions(+) 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/icons/obj/doors/DoorHazard2x1.dmi b/icons/obj/doors/DoorHazard2x1.dmi index 102bcf081dd951828db33ac2ed1b9c7f72f4fc0e..081f44087cc3db591806a66a3fc1752290c1cf9e 100644 GIT binary patch literal 15200 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 delta 756 zcmViBL{Q4GJ0x0000DNk~Le0000$0000$2m=5B0G+pi>;M1&T~JI^ zMZmzoR8&+iFE5H)1Dj?9a!CQ(w*=+D1ONa4z>o#itOek^1f)*|vVR5Lxdebj2p%3D zDk>@fGXNbO9ROwk0GR-vh6#Q@2-<=O7Z(=|4Gs6u1JtS<1f698CnqP2mCtMd0004W zQchC}*EPTEZ0T@04z(8A98-UIyyBLarw4SLR)FVN0zk_H4qX^P z9E1RX1UNhcc1i#xhE+fY&?NxPfv^M*mAffkR$<=?fRIM-0Yg{;jsd_e!3rP@!LP!p z=X-$S59&eZ0R71We+Fp?D=|axfWZUK7YASoO%fk9a5;Ox70@)SmjCCY2H~0jyzuVp zIh+6%c^T@g5yCbCE?{}3;TqwAI0pk*=|DJ;*jQsM3<1zf0H50N2mm;a;{-tE zbYCAgS|+R$V7lGLP)<*Esl}B6P*#9A{+Ph_R6^1b4N~fsm(Pf4S z@x&;C#PH$|+#|e-C@~!UL6NQK4-^3M2TB063IMzXKs5*C543=z0zm#C9}xXPJ|Oyo zd_eRE`GD)2P5{(%pjid-2l;^L5Ap%gA1DCi50pL71Joyy=0KtAJs(iN0^n|U`2o5E m<@n+ctdviVP9oTs_=7(b5>=+(a^A}T0000 Date: Wed, 11 Sep 2013 12:09:23 -0700 Subject: [PATCH 3/3] Removes the gas mask filtering stuff from gas mixtures. Moved it into the relevant "life" code. --- baystation12.dme | 8 ++-- code/ZAS/FEA_gas_mixture.dm | 8 ++-- code/modules/mob/living/carbon/human/life.dm | 37 ++++++++++++------- code/modules/mob/living/carbon/monkey/life.dm | 26 ++++++++----- 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/baystation12.dme b/baystation12.dme index 1e82f65dd40..c7a0d7f95f4 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -739,10 +739,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/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/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 0164ca1227d..71621e49e37 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -322,6 +322,29 @@ // Not enough air around, take a percentage of what's there to model this properly breath_moles = environment.total_moles()*BREATH_PERCENTAGE + breath = loc.remove_air(breath_moles) + + if(istype(wear_mask, /obj/item/clothing/mask/gas)) + var/obj/item/clothing/mask/gas/G = wear_mask + var/datum/gas_mixture/filtered = new + + filtered.copy_from(breath) + filtered.toxins *= G.gas_filter_strength + for(var/datum/gas/gas in filtered.trace_gases) + gas.moles *= G.gas_filter_strength + filtered.update_values() + loc.assume_air(filtered) + + breath.toxins *= 1 - G.gas_filter_strength + for(var/datum/gas/gas in breath.trace_gases) + gas.moles *= 1 - G.gas_filter_strength + breath.update_values() + + if(!is_lung_ruptured()) + if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5) + if(prob(5)) + rupture_lung() + // Handle filtering var/block = 0 if(wear_mask) @@ -334,20 +357,6 @@ if(head.flags & BLOCK_GAS_SMOKE_EFFECT) block = 1 - if(block && wear_mask) - if(istype(wear_mask, /obj/item/clothing/mask/gas)) - var/obj/item/clothing/mask/gas/G = wear_mask - breath = loc.remove_air(breath_moles, G.gas_filter_strength) //Filters out harmful gases - else - breath = loc.remove_air(breath_moles, 0) - else - breath = loc.remove_air(breath_moles, 0) - - if(!is_lung_ruptured()) - if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5) - if(prob(5)) - rupture_lung() - if(!block) for(var/obj/effect/effect/chem_smoke/smoke in view(1, src)) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index be549e2c626..0a4348cd24c 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -225,6 +225,23 @@ breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME) else if(istype(loc, /turf/)) var/breath_moles = environment.total_moles()*BREATH_PERCENTAGE + breath = loc.remove_air(breath_moles) + + if(istype(wear_mask, /obj/item/clothing/mask/gas)) + var/obj/item/clothing/mask/gas/G = wear_mask + var/datum/gas_mixture/filtered = new + + filtered.copy_from(breath) + filtered.toxins *= G.gas_filter_strength + for(var/datum/gas/gas in filtered.trace_gases) + gas.moles *= G.gas_filter_strength + filtered.update_values() + loc.assume_air(filtered) + + breath.toxins *= 1 - G.gas_filter_strength + for(var/datum/gas/gas in breath.trace_gases) + gas.moles *= 1 - G.gas_filter_strength + breath.update_values() // Handle chem smoke effect -- Doohl var/block = 0 @@ -232,15 +249,6 @@ if(istype(wear_mask, /obj/item/clothing/mask/gas)) block = 1 - if(block && wear_mask) - if(istype(wear_mask, /obj/item/clothing/mask/gas)) - var/obj/item/clothing/mask/gas/G = wear_mask - breath = loc.remove_air(breath_moles, G.gas_filter_strength) //Filters out harmful gases - else - breath = loc.remove_air(breath_moles, 0) - else - breath = loc.remove_air(breath_moles, 0) - if(!block) for(var/obj/effect/effect/chem_smoke/smoke in view(1, src)) if(smoke.reagents.total_volume)