diff --git a/baystation12.dme b/baystation12.dme index 43e4dfcc446..a72955196df 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -3,222 +3,6 @@ // New source code should be placed in .dm files: choose File/New --> Code File. // BEGIN_INTERNALS // END_INTERNALS -// BEGIN_FILE_DIR -#define FILE_DIR . -#define FILE_DIR "code" -#define FILE_DIR "code/ATMOSPHERICS" -#define FILE_DIR "code/ATMOSPHERICS/components" -#define FILE_DIR "code/ATMOSPHERICS/components/binary_devices" -#define FILE_DIR "code/ATMOSPHERICS/components/trinary_devices" -#define FILE_DIR "code/ATMOSPHERICS/components/unary" -#define FILE_DIR "code/datums" -#define FILE_DIR "code/datums/diseases" -#define FILE_DIR "code/datums/helper_datums" -#define FILE_DIR "code/datums/spells" -#define FILE_DIR "code/defines" -#define FILE_DIR "code/defines/area" -#define FILE_DIR "code/defines/mob" -#define FILE_DIR "code/defines/mob/dead" -#define FILE_DIR "code/defines/mob/living" -#define FILE_DIR "code/defines/mob/living/carbon" -#define FILE_DIR "code/defines/mob/living/silicon" -#define FILE_DIR "code/defines/obj" -#define FILE_DIR "code/defines/procs" -#define FILE_DIR "code/defines/sd_procs" -#define FILE_DIR "code/FEA" -#define FILE_DIR "code/game" -#define FILE_DIR "code/game/area" -#define FILE_DIR "code/game/asteroid" -#define FILE_DIR "code/game/events" -#define FILE_DIR "code/game/events/EventProcs" -#define FILE_DIR "code/game/events/Events" -#define FILE_DIR "code/game/gamemodes" -#define FILE_DIR "code/game/gamemodes/autotraitor" -#define FILE_DIR "code/game/gamemodes/blob" -#define FILE_DIR "code/game/gamemodes/changeling" -#define FILE_DIR "code/game/gamemodes/cult" -#define FILE_DIR "code/game/gamemodes/epidemic" -#define FILE_DIR "code/game/gamemodes/extended" -#define FILE_DIR "code/game/gamemodes/malfunction" -#define FILE_DIR "code/game/gamemodes/meme" -#define FILE_DIR "code/game/gamemodes/meteor" -#define FILE_DIR "code/game/gamemodes/nuclear" -#define FILE_DIR "code/game/gamemodes/revolution" -#define FILE_DIR "code/game/gamemodes/sandbox" -#define FILE_DIR "code/game/gamemodes/traitor" -#define FILE_DIR "code/game/gamemodes/wizard" -#define FILE_DIR "code/game/jobs" -#define FILE_DIR "code/game/jobs/job" -#define FILE_DIR "code/game/machinery" -#define FILE_DIR "code/game/machinery/atmoalter" -#define FILE_DIR "code/game/machinery/bots" -#define FILE_DIR "code/game/machinery/computer" -#define FILE_DIR "code/game/machinery/doors" -#define FILE_DIR "code/game/machinery/embedded_controller" -#define FILE_DIR "code/game/machinery/kitchen" -#define FILE_DIR "code/game/machinery/pipe" -#define FILE_DIR "code/game/machinery/telecomms" -#define FILE_DIR "code/game/magic" -#define FILE_DIR "code/game/magic/cultist" -#define FILE_DIR "code/game/mecha" -#define FILE_DIR "code/game/mecha/combat" -#define FILE_DIR "code/game/mecha/equipment" -#define FILE_DIR "code/game/mecha/equipment/tools" -#define FILE_DIR "code/game/mecha/equipment/weapons" -#define FILE_DIR "code/game/mecha/medical" -#define FILE_DIR "code/game/mecha/working" -#define FILE_DIR "code/game/objects" -#define FILE_DIR "code/game/objects/alien" -#define FILE_DIR "code/game/objects/closets" -#define FILE_DIR "code/game/objects/closets/secure" -#define FILE_DIR "code/game/objects/devices" -#define FILE_DIR "code/game/objects/devices/PDA" -#define FILE_DIR "code/game/objects/items" -#define FILE_DIR "code/game/objects/items/weapons" -#define FILE_DIR "code/game/objects/items/weapons/implants" -#define FILE_DIR "code/game/objects/radio" -#define FILE_DIR "code/game/objects/secstorage" -#define FILE_DIR "code/game/objects/stacks" -#define FILE_DIR "code/game/objects/storage" -#define FILE_DIR "code/game/objects/tanks" -#define FILE_DIR "code/game/player" -#define FILE_DIR "code/game/vehicles" -#define FILE_DIR "code/game/vehicles/airtight" -#define FILE_DIR "code/game/verbs" -#define FILE_DIR "code/js" -#define FILE_DIR "code/modules" -#define FILE_DIR "code/modules/admin" -#define FILE_DIR "code/modules/admin/verbs" -#define FILE_DIR "code/modules/assembly" -#define FILE_DIR "code/modules/chemical" -#define FILE_DIR "code/modules/clothing" -#define FILE_DIR "code/modules/clothing/glasses" -#define FILE_DIR "code/modules/clothing/head" -#define FILE_DIR "code/modules/clothing/spacesuits" -#define FILE_DIR "code/modules/clothing/suits" -#define FILE_DIR "code/modules/clothing/uniforms" -#define FILE_DIR "code/modules/critters" -#define FILE_DIR "code/modules/critters/hivebots" -#define FILE_DIR "code/modules/customitems" -#define FILE_DIR "code/modules/DetectiveWork" -#define FILE_DIR "code/modules/flufftext" -#define FILE_DIR "code/modules/food" -#define FILE_DIR "code/modules/maps" -#define FILE_DIR "code/modules/mining" -#define FILE_DIR "code/modules/mob" -#define FILE_DIR "code/modules/mob/dead" -#define FILE_DIR "code/modules/mob/dead/observer" -#define FILE_DIR "code/modules/mob/living" -#define FILE_DIR "code/modules/mob/living/blob" -#define FILE_DIR "code/modules/mob/living/carbon" -#define FILE_DIR "code/modules/mob/living/carbon/alien" -#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid" -#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid/caste" -#define FILE_DIR "code/modules/mob/living/carbon/alien/larva" -#define FILE_DIR "code/modules/mob/living/carbon/alien/special" -#define FILE_DIR "code/modules/mob/living/carbon/brain" -#define FILE_DIR "code/modules/mob/living/carbon/human" -#define FILE_DIR "code/modules/mob/living/carbon/metroid" -#define FILE_DIR "code/modules/mob/living/carbon/monkey" -#define FILE_DIR "code/modules/mob/living/parasite" -#define FILE_DIR "code/modules/mob/living/silicon" -#define FILE_DIR "code/modules/mob/living/silicon/ai" -#define FILE_DIR "code/modules/mob/living/silicon/decoy" -#define FILE_DIR "code/modules/mob/living/silicon/pai" -#define FILE_DIR "code/modules/mob/living/silicon/robot" -#define FILE_DIR "code/modules/mob/new_player" -#define FILE_DIR "code/modules/mob/organ" -#define FILE_DIR "code/modules/mob/simple_animal" -#define FILE_DIR "code/modules/paperwork" -#define FILE_DIR "code/modules/power" -#define FILE_DIR "code/modules/power/antimatter" -#define FILE_DIR "code/modules/power/singularity" -#define FILE_DIR "code/modules/power/singularity/particle_accelerator" -#define FILE_DIR "code/modules/projectiles" -#define FILE_DIR "code/modules/projectiles/ammunition" -#define FILE_DIR "code/modules/projectiles/guns" -#define FILE_DIR "code/modules/projectiles/guns/energy" -#define FILE_DIR "code/modules/projectiles/guns/projectile" -#define FILE_DIR "code/modules/projectiles/projectile" -#define FILE_DIR "code/modules/recycling" -#define FILE_DIR "code/modules/research" -#define FILE_DIR "code/modules/scripting" -#define FILE_DIR "code/modules/scripting/AST" -#define FILE_DIR "code/modules/scripting/AST/Operators" -#define FILE_DIR "code/modules/scripting/Implementations" -#define FILE_DIR "code/modules/scripting/Interpreter" -#define FILE_DIR "code/modules/scripting/Parser" -#define FILE_DIR "code/modules/scripting/Scanner" -#define FILE_DIR "code/modules/security levels" -#define FILE_DIR "code/unused" -#define FILE_DIR "code/unused/beast" -#define FILE_DIR "code/unused/computer2" -#define FILE_DIR "code/unused/gamemodes" -#define FILE_DIR "code/unused/hivebot" -#define FILE_DIR "code/unused/mining" -#define FILE_DIR "code/unused/optics" -#define FILE_DIR "code/unused/pda2" -#define FILE_DIR "code/unused/powerarmor" -#define FILE_DIR "code/unused/spacecraft" -#define FILE_DIR "code/WorkInProgress" -#define FILE_DIR "code/WorkInProgress/AI_Visibility" -#define FILE_DIR "code/WorkInProgress/animusstation" -#define FILE_DIR "code/WorkInProgress/Apples" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/BirdMan" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Rust" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Supermatter" -#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Tajara" -#define FILE_DIR "code/WorkInProgress/Chinsky" -#define FILE_DIR "code/WorkInProgress/mapload" -#define FILE_DIR "code/WorkInProgress/Mini" -#define FILE_DIR "code/WorkInProgress/Mloc" -#define FILE_DIR "code/WorkInProgress/organs" -#define FILE_DIR "code/WorkInProgress/Ported" -#define FILE_DIR "code/WorkInProgress/Ported/Abi79" -#define FILE_DIR "code/WorkInProgress/Ported/Bureaucracy" -#define FILE_DIR "code/WorkInProgress/Ported/Spawners" -#define FILE_DIR "code/WorkInProgress/SkyMarshal" -#define FILE_DIR "code/WorkInProgress/Tastyfish" -#define FILE_DIR "code/WorkInProgress/virus2" -#define FILE_DIR "code/WorkInProgress/Wrongnumber" -#define FILE_DIR "code/ZAS" -#define FILE_DIR "html" -#define FILE_DIR "icons" -#define FILE_DIR "icons/48x48" -#define FILE_DIR "icons/effects" -#define FILE_DIR "icons/mecha" -#define FILE_DIR "icons/misc" -#define FILE_DIR "icons/mob" -#define FILE_DIR "icons/obj" -#define FILE_DIR "icons/obj/assemblies" -#define FILE_DIR "icons/obj/atmospherics" -#define FILE_DIR "icons/obj/clothing" -#define FILE_DIR "icons/obj/doors" -#define FILE_DIR "icons/obj/machines" -#define FILE_DIR "icons/obj/pipes" -#define FILE_DIR "icons/pda_icons" -#define FILE_DIR "icons/spideros_icons" -#define FILE_DIR "icons/Testing" -#define FILE_DIR "icons/turf" -#define FILE_DIR "icons/vending_icons" -#define FILE_DIR "interface" -#define FILE_DIR "maps" -#define FILE_DIR "maps/RandomZLevels" -#define FILE_DIR "sound" -#define FILE_DIR "sound/AI" -#define FILE_DIR "sound/ambience" -#define FILE_DIR "sound/announcer" -#define FILE_DIR "sound/effects" -#define FILE_DIR "sound/hallucinations" -#define FILE_DIR "sound/items" -#define FILE_DIR "sound/machines" -#define FILE_DIR "sound/mecha" -#define FILE_DIR "sound/misc" -#define FILE_DIR "sound/piano" -#define FILE_DIR "sound/voice" -#define FILE_DIR "sound/weapons" -// END_FILE_DIR // BEGIN_PREFERENCES #define DEBUG // END_PREFERENCES @@ -361,12 +145,6 @@ #include "code\defines\sd_procs\constants.dm" #include "code\defines\sd_procs\direction.dm" #include "code\defines\sd_procs\math.dm" -#include "code\FEA\FEA_airgroup.dm" -#include "code\FEA\FEA_fire.dm" -#include "code\FEA\FEA_gas_mixture.dm" -#include "code\FEA\FEA_group_helpers.dm" -#include "code\FEA\FEA_system.dm" -#include "code\FEA\FEA_turf_tile.dm" #include "code\game\algorithm.dm" #include "code\game\atom_procs.dm" #include "code\game\cellautomata.dm" @@ -1209,7 +987,235 @@ #include "code\WorkInProgress\virus2\monkeydispensor.dm" #include "code\WorkInProgress\virus2\Prob.dm" #include "code\WorkInProgress\Wrongnumber\weldbackpack.dm" +#include "code\ZAS\Airflow.dm" +#include "code\ZAS\Connection.dm" +#include "code\ZAS\Creation.dm" +#include "code\ZAS\Definition.dm" +#include "code\ZAS\FEA_gas_mixture.dm" +#include "code\ZAS\FEA_system.dm" +#include "code\ZAS\FEA_turf_tile.dm" +#include "code\ZAS\Fire.dm" +#include "code\ZAS\Functions.dm" +#include "code\ZAS\Plasma.dm" +#include "code\ZAS\Processing.dm" +#include "code\ZAS\Variable Settings.dm" #include "interface\interface.dm" #include "interface\skin.dmf" #include "maps\tgstation.2.0.8.dmm" // END_INCLUDE +// BEGIN_FILE_DIR +#define FILE_DIR . +#define FILE_DIR "code" +#define FILE_DIR "code/ATMOSPHERICS" +#define FILE_DIR "code/ATMOSPHERICS/components" +#define FILE_DIR "code/ATMOSPHERICS/components/binary_devices" +#define FILE_DIR "code/ATMOSPHERICS/components/trinary_devices" +#define FILE_DIR "code/ATMOSPHERICS/components/unary" +#define FILE_DIR "code/datums" +#define FILE_DIR "code/datums/diseases" +#define FILE_DIR "code/datums/helper_datums" +#define FILE_DIR "code/datums/spells" +#define FILE_DIR "code/defines" +#define FILE_DIR "code/defines/area" +#define FILE_DIR "code/defines/mob" +#define FILE_DIR "code/defines/mob/dead" +#define FILE_DIR "code/defines/mob/living" +#define FILE_DIR "code/defines/mob/living/carbon" +#define FILE_DIR "code/defines/mob/living/silicon" +#define FILE_DIR "code/defines/obj" +#define FILE_DIR "code/defines/procs" +#define FILE_DIR "code/defines/sd_procs" +#define FILE_DIR "code/FEA" +#define FILE_DIR "code/game" +#define FILE_DIR "code/game/area" +#define FILE_DIR "code/game/asteroid" +#define FILE_DIR "code/game/events" +#define FILE_DIR "code/game/events/EventProcs" +#define FILE_DIR "code/game/events/Events" +#define FILE_DIR "code/game/gamemodes" +#define FILE_DIR "code/game/gamemodes/autotraitor" +#define FILE_DIR "code/game/gamemodes/blob" +#define FILE_DIR "code/game/gamemodes/changeling" +#define FILE_DIR "code/game/gamemodes/cult" +#define FILE_DIR "code/game/gamemodes/epidemic" +#define FILE_DIR "code/game/gamemodes/extended" +#define FILE_DIR "code/game/gamemodes/malfunction" +#define FILE_DIR "code/game/gamemodes/meme" +#define FILE_DIR "code/game/gamemodes/meteor" +#define FILE_DIR "code/game/gamemodes/nuclear" +#define FILE_DIR "code/game/gamemodes/revolution" +#define FILE_DIR "code/game/gamemodes/sandbox" +#define FILE_DIR "code/game/gamemodes/traitor" +#define FILE_DIR "code/game/gamemodes/wizard" +#define FILE_DIR "code/game/jobs" +#define FILE_DIR "code/game/jobs/job" +#define FILE_DIR "code/game/machinery" +#define FILE_DIR "code/game/machinery/atmoalter" +#define FILE_DIR "code/game/machinery/bots" +#define FILE_DIR "code/game/machinery/computer" +#define FILE_DIR "code/game/machinery/doors" +#define FILE_DIR "code/game/machinery/embedded_controller" +#define FILE_DIR "code/game/machinery/kitchen" +#define FILE_DIR "code/game/machinery/pipe" +#define FILE_DIR "code/game/machinery/telecomms" +#define FILE_DIR "code/game/magic" +#define FILE_DIR "code/game/magic/cultist" +#define FILE_DIR "code/game/mecha" +#define FILE_DIR "code/game/mecha/combat" +#define FILE_DIR "code/game/mecha/equipment" +#define FILE_DIR "code/game/mecha/equipment/tools" +#define FILE_DIR "code/game/mecha/equipment/weapons" +#define FILE_DIR "code/game/mecha/medical" +#define FILE_DIR "code/game/mecha/working" +#define FILE_DIR "code/game/objects" +#define FILE_DIR "code/game/objects/alien" +#define FILE_DIR "code/game/objects/closets" +#define FILE_DIR "code/game/objects/closets/secure" +#define FILE_DIR "code/game/objects/devices" +#define FILE_DIR "code/game/objects/devices/PDA" +#define FILE_DIR "code/game/objects/items" +#define FILE_DIR "code/game/objects/items/weapons" +#define FILE_DIR "code/game/objects/items/weapons/implants" +#define FILE_DIR "code/game/objects/radio" +#define FILE_DIR "code/game/objects/secstorage" +#define FILE_DIR "code/game/objects/stacks" +#define FILE_DIR "code/game/objects/storage" +#define FILE_DIR "code/game/objects/tanks" +#define FILE_DIR "code/game/player" +#define FILE_DIR "code/game/vehicles" +#define FILE_DIR "code/game/vehicles/airtight" +#define FILE_DIR "code/game/verbs" +#define FILE_DIR "code/js" +#define FILE_DIR "code/modules" +#define FILE_DIR "code/modules/admin" +#define FILE_DIR "code/modules/admin/verbs" +#define FILE_DIR "code/modules/assembly" +#define FILE_DIR "code/modules/chemical" +#define FILE_DIR "code/modules/clothing" +#define FILE_DIR "code/modules/clothing/glasses" +#define FILE_DIR "code/modules/clothing/head" +#define FILE_DIR "code/modules/clothing/spacesuits" +#define FILE_DIR "code/modules/clothing/suits" +#define FILE_DIR "code/modules/clothing/uniforms" +#define FILE_DIR "code/modules/critters" +#define FILE_DIR "code/modules/critters/hivebots" +#define FILE_DIR "code/modules/customitems" +#define FILE_DIR "code/modules/DetectiveWork" +#define FILE_DIR "code/modules/flufftext" +#define FILE_DIR "code/modules/food" +#define FILE_DIR "code/modules/maps" +#define FILE_DIR "code/modules/mining" +#define FILE_DIR "code/modules/mob" +#define FILE_DIR "code/modules/mob/dead" +#define FILE_DIR "code/modules/mob/dead/observer" +#define FILE_DIR "code/modules/mob/living" +#define FILE_DIR "code/modules/mob/living/blob" +#define FILE_DIR "code/modules/mob/living/carbon" +#define FILE_DIR "code/modules/mob/living/carbon/alien" +#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid" +#define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid/caste" +#define FILE_DIR "code/modules/mob/living/carbon/alien/larva" +#define FILE_DIR "code/modules/mob/living/carbon/alien/special" +#define FILE_DIR "code/modules/mob/living/carbon/brain" +#define FILE_DIR "code/modules/mob/living/carbon/human" +#define FILE_DIR "code/modules/mob/living/carbon/metroid" +#define FILE_DIR "code/modules/mob/living/carbon/monkey" +#define FILE_DIR "code/modules/mob/living/parasite" +#define FILE_DIR "code/modules/mob/living/silicon" +#define FILE_DIR "code/modules/mob/living/silicon/ai" +#define FILE_DIR "code/modules/mob/living/silicon/decoy" +#define FILE_DIR "code/modules/mob/living/silicon/pai" +#define FILE_DIR "code/modules/mob/living/silicon/robot" +#define FILE_DIR "code/modules/mob/new_player" +#define FILE_DIR "code/modules/mob/organ" +#define FILE_DIR "code/modules/mob/simple_animal" +#define FILE_DIR "code/modules/paperwork" +#define FILE_DIR "code/modules/power" +#define FILE_DIR "code/modules/power/antimatter" +#define FILE_DIR "code/modules/power/singularity" +#define FILE_DIR "code/modules/power/singularity/particle_accelerator" +#define FILE_DIR "code/modules/projectiles" +#define FILE_DIR "code/modules/projectiles/ammunition" +#define FILE_DIR "code/modules/projectiles/guns" +#define FILE_DIR "code/modules/projectiles/guns/energy" +#define FILE_DIR "code/modules/projectiles/guns/projectile" +#define FILE_DIR "code/modules/projectiles/projectile" +#define FILE_DIR "code/modules/recycling" +#define FILE_DIR "code/modules/research" +#define FILE_DIR "code/modules/scripting" +#define FILE_DIR "code/modules/scripting/AST" +#define FILE_DIR "code/modules/scripting/AST/Operators" +#define FILE_DIR "code/modules/scripting/Implementations" +#define FILE_DIR "code/modules/scripting/Interpreter" +#define FILE_DIR "code/modules/scripting/Parser" +#define FILE_DIR "code/modules/scripting/Scanner" +#define FILE_DIR "code/modules/security levels" +#define FILE_DIR "code/unused" +#define FILE_DIR "code/unused/beast" +#define FILE_DIR "code/unused/computer2" +#define FILE_DIR "code/unused/gamemodes" +#define FILE_DIR "code/unused/hivebot" +#define FILE_DIR "code/unused/mining" +#define FILE_DIR "code/unused/optics" +#define FILE_DIR "code/unused/pda2" +#define FILE_DIR "code/unused/powerarmor" +#define FILE_DIR "code/unused/spacecraft" +#define FILE_DIR "code/WorkInProgress" +#define FILE_DIR "code/WorkInProgress/AI_Visibility" +#define FILE_DIR "code/WorkInProgress/animusstation" +#define FILE_DIR "code/WorkInProgress/Apples" +#define FILE_DIR "code/WorkInProgress/Cael_Aislinn" +#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/BirdMan" +#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Rust" +#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Supermatter" +#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Tajara" +#define FILE_DIR "code/WorkInProgress/Chinsky" +#define FILE_DIR "code/WorkInProgress/mapload" +#define FILE_DIR "code/WorkInProgress/Mini" +#define FILE_DIR "code/WorkInProgress/Mloc" +#define FILE_DIR "code/WorkInProgress/organs" +#define FILE_DIR "code/WorkInProgress/Ported" +#define FILE_DIR "code/WorkInProgress/Ported/Abi79" +#define FILE_DIR "code/WorkInProgress/Ported/Bureaucracy" +#define FILE_DIR "code/WorkInProgress/Ported/Spawners" +#define FILE_DIR "code/WorkInProgress/SkyMarshal" +#define FILE_DIR "code/WorkInProgress/Tastyfish" +#define FILE_DIR "code/WorkInProgress/virus2" +#define FILE_DIR "code/WorkInProgress/Wrongnumber" +#define FILE_DIR "code/ZAS" +#define FILE_DIR "html" +#define FILE_DIR "icons" +#define FILE_DIR "icons/48x48" +#define FILE_DIR "icons/effects" +#define FILE_DIR "icons/mecha" +#define FILE_DIR "icons/misc" +#define FILE_DIR "icons/mob" +#define FILE_DIR "icons/obj" +#define FILE_DIR "icons/obj/assemblies" +#define FILE_DIR "icons/obj/atmospherics" +#define FILE_DIR "icons/obj/clothing" +#define FILE_DIR "icons/obj/doors" +#define FILE_DIR "icons/obj/machines" +#define FILE_DIR "icons/obj/pipes" +#define FILE_DIR "icons/pda_icons" +#define FILE_DIR "icons/spideros_icons" +#define FILE_DIR "icons/Testing" +#define FILE_DIR "icons/turf" +#define FILE_DIR "icons/vending_icons" +#define FILE_DIR "interface" +#define FILE_DIR "maps" +#define FILE_DIR "maps/RandomZLevels" +#define FILE_DIR "sound" +#define FILE_DIR "sound/AI" +#define FILE_DIR "sound/ambience" +#define FILE_DIR "sound/announcer" +#define FILE_DIR "sound/effects" +#define FILE_DIR "sound/hallucinations" +#define FILE_DIR "sound/items" +#define FILE_DIR "sound/machines" +#define FILE_DIR "sound/mecha" +#define FILE_DIR "sound/misc" +#define FILE_DIR "sound/piano" +#define FILE_DIR "sound/voice" +#define FILE_DIR "sound/weapons" +// END_FILE_DIR diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index 1b63e605481..5ade345e08f 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -128,28 +128,19 @@ datum/pipeline var/datum/gas_mixture/air_sample = air.remove_ratio(mingle_volume/air.volume) air_sample.volume = mingle_volume - if(istype(target) && target.parent && target.parent.group_processing) + if(istype(target) && target.zone) //Have to consider preservation of group statuses var/datum/gas_mixture/turf_copy = new - turf_copy.copy_from(target.parent.air) - turf_copy.volume = target.parent.air.volume //Copy a good representation of the turf from parent group + turf_copy.copy_from(target.zone.air) + turf_copy.volume = target.zone.air.volume //Copy a good representation of the turf from parent group equalize_gases(list(air_sample, turf_copy)) air.merge(air_sample) - if(target.parent.air.compare(turf_copy)) - //The new turf would be an acceptable group member so permit the integration + turf_copy.subtract(target.zone.air) - turf_copy.subtract(target.parent.air) - - target.parent.air.merge(turf_copy) - - else - //Comparison failure so dissemble group and copy turf - - target.parent.suspend_group_processing() - target.air.copy_from(turf_copy) + target.zone.air.merge(turf_copy) else var/datum/gas_mixture/turf_air = target.return_air() @@ -187,9 +178,9 @@ datum/pipeline var/delta_temperature = 0 var/sharer_heat_capacity = 0 - if(modeled_location.parent && modeled_location.parent.group_processing) - delta_temperature = (air.temperature - modeled_location.parent.air.temperature) - sharer_heat_capacity = modeled_location.parent.air.heat_capacity() + if(modeled_location.zone) + delta_temperature = (air.temperature - modeled_location.zone.air.temperature) + sharer_heat_capacity = modeled_location.zone.air.heat_capacity() else delta_temperature = (air.temperature - modeled_location.air.temperature) sharer_heat_capacity = modeled_location.air.heat_capacity() @@ -208,14 +199,8 @@ datum/pipeline air.temperature += self_temperature_delta - if(modeled_location.parent && modeled_location.parent.group_processing) - if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*modeled_location.parent.air.temperature)) - modeled_location.parent.suspend_group_processing() - - modeled_location.air.temperature += sharer_temperature_delta - - else - modeled_location.parent.air.temperature += sharer_temperature_delta/modeled_location.parent.air.group_multiplier + if(modeled_location.zone) + modeled_location.zone.air.temperature += sharer_temperature_delta/modeled_location.zone.air.group_multiplier else modeled_location.air.temperature += sharer_temperature_delta diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index a3cb01eb7ee..50d8888c853 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -64,14 +64,13 @@ atom/movable/RepelAirflowDest(n) */ -var/tick_multiplier = 2 vs_control/var zone_update_delay = 10 zone_update_delay_NAME = "Zone Update Delay" zone_update_delay_DESC = "The delay in ticks between updates of zones. Increase if lag is bad seemingly because of air." - zone_share_percent = 2 + zone_share_percent = 5 zone_share_percent_NAME = "Zone Connection Transfer %" zone_share_percent_DESC = "Percent of gas per connected tile that is shared between zones." diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index bf43f90d1c0..022a714222e 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -5,6 +5,7 @@ connection B indirect = 0 //If the connection is purely indirect, the zones should not join. last_updated //The tick at which this was last updated. + no_zone_count = 0 New(turf/T,turf/O) A = T B = O @@ -31,6 +32,8 @@ connection B.zone.connected_zones[A.zone] = 1 else B.zone.connected_zones[A.zone]++ + else + world.log << "Attempted to create connection object for non-zone tiles: [T] -> [O]" Del() if(A.zone && A.zone.connections) A.zone.connections -= src @@ -57,5 +60,14 @@ connection . = ..() proc/Cleanup() - if(A.zone == B.zone) del src - if(!A.zone || !B.zone) del src \ No newline at end of file + if(!A || !B) + world.log << "Connection removed: [A] or [B] missing entirely." + del src + if(A.zone == B.zone) + world.log << "Connection removed: Zones now merged." + del src + if(!A.zone || !B.zone) + no_zone_count++ + if(no_zone_count >= 5) + world.log << "Connection removed: [A] or [B] missing a zone." + del src \ No newline at end of file diff --git a/code/ZAS/Creation.dm b/code/ZAS/Creation.dm index 5f256767fd3..1dba1d296ba 100644 --- a/code/ZAS/Creation.dm +++ b/code/ZAS/Creation.dm @@ -17,6 +17,7 @@ zone air.toxins += T.toxins / members air.temperature += T.temperature / members air.group_multiplier = contents.len + air.update_values() zones += src Del() zones -= src diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index 28fc3caef53..66c6a12ca33 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -1,5 +1,5 @@ -client/proc/Zone_Info(turf/T as null|turf) +client/verb/Zone_Info(turf/T as null|turf) set category = "Debug" if(T) if(T.zone) @@ -28,9 +28,10 @@ zone/proc M << "Plasma: [air.toxins]" M << "Carbon Dioxide: [air.carbon_dioxide]" M << "Temperature: [air.temperature]" - M << "Heat Energy: [air.thermal_energy()]" + M << "Heat Energy: [air.temperature * air.heat_capacity()]" M << "Pressure: [air.return_pressure()]" M << "" + M << "Space Tiles: [length(space_tiles)]" M << "Connections: [length(connections)]" for(var/connection/C in connections) @@ -40,6 +41,9 @@ zone/proc spawn(50) C.A.overlays -= 'debug_connect.dmi' C.B.overlays -= 'debug_connect.dmi' + for(var/C in connections) + if(!istype(C,/connection)) + M << "[C] (Not Connection!)" else dbg_output = 0 diff --git a/code/ZAS/Definition.dm b/code/ZAS/Definition.dm index 729d19841fc..b092dc304b7 100644 --- a/code/ZAS/Definition.dm +++ b/code/ZAS/Definition.dm @@ -1,25 +1,6 @@ turf/var/zone/zone var/list/zones = list() -var/zone_controller/zone_master = new - -zone_controller - var - current_tick = 0 - proc - start() - set background = 1 - while(1) - current_tick++ - for(var/zone/Z in zones) - if(Z.last_update < current_tick) - Z.process() - if(Z) Z.last_update = current_tick - for(var/obj/fire/F) - F.process() - //for(var/obj/z_hotspot/H in z_hotspots) - // H.process() - sleep(max(5,vsc.zone_update_delay*tick_multiplier)) zone var diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm new file mode 100644 index 00000000000..24a6682381b --- /dev/null +++ b/code/ZAS/FEA_gas_mixture.dm @@ -0,0 +1,1008 @@ +/* +What are the archived variables for? + Calculations are done using the archived variables with the results merged into the regular variables. + This prevents race conditions that arise based on the order of tile processing. +*/ + +datum + gas //These are used for the "Trace Gases" stuff, but is buggy. + sleeping_agent + specific_heat = 40 + + volatile_fuel + specific_heat = 30 + + var + moles = 0 + specific_heat = 0 + + moles_archived = 0 + + gas_mixture + var //Holds the "moles" of each of the four gases. + oxygen = 0 + carbon_dioxide = 0 + nitrogen = 0 + toxins = 0 + total_moles = 0 //Updated when a reaction occurs. + pressure = 0 + + volume = CELL_VOLUME + + temperature = 0 //in Kelvin, use calculate_temperature() to modify + + group_multiplier = 1 + //Size of the group this gas_mixture is representing. + //=1 for singletons + + graphic + + list/datum/gas/trace_gases = list() //Seemed to be a good idea that was abandoned + + tmp //These are variables for use with the archived data + oxygen_archived + carbon_dioxide_archived + nitrogen_archived + toxins_archived + + temperature_archived + + graphic_archived + fuel_burnt = 0 + +//FOR THE LOVE OF GOD PLEASE USE THIS PROC +//Call it with negative numbers to remove gases. + + proc/adjustGases(o2 = 0, co2 = 0, n2 = 0, tx = 0, list/datum/gas/traces = list()) + //Purpose: Adjusting the gases within a airmix + //Called by: Nothing, yet! + //Inputs: The values of the gases to adjust + //Outputs: null + + oxygen = max(0, oxygen + o2) + carbon_dioxide = max(0, carbon_dioxide + co2) + nitrogen = max(0, nitrogen + n2) + toxins = max(0, toxins + tx) + + //handle trace gasses + for(var/datum/gas/G in traces) + var/datum/gas/T = locate(G.type) in trace_gases + if(T) + T.moles = max(G.moles + T.moles, 0) + else if(G.moles > 0) + trace_gases |= G + update_values() + return + +/////////////////////////////// +//PV=nRT - related procedures// +/////////////////////////////// + + + proc/heat_capacity() + //Purpose: Returning the heat capacity of the gas mix + //Called by: UNKNOWN + //Inputs: None + //Outputs: Heat capacity + + var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + heat_capacity += trace_gas.moles*trace_gas.specific_heat + + return max(MINIMUM_HEAT_CAPACITY,heat_capacity) + + proc/heat_capacity_archived() + //Purpose: Returning the archived heat capacity of the gas mix + //Called by: UNKNOWN + //Inputs: None + //Outputs: Archived heat capacity + + var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,toxins_archived) + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat + + return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived) + + proc/return_pressure() + //Purpose: Calculating Current Pressure + //Called by: + //Inputs: None + //Outputs: Gas pressure. + + if(volume>0) + return total_moles*R_IDEAL_GAS_EQUATION*temperature/volume + return 0 + +// proc/return_temperature() + //Purpose: + //Inputs: + //Outputs: + +// return temperature + +// proc/return_volume() + //Purpose: + //Inputs: + //Outputs: + +// return max(0, volume) + +// proc/thermal_energy() + //Purpose: + //Inputs: + //Outputs: + +// return temperature*heat_capacity() + + proc/update_values() + //Purpose: Calculating and storing values which were normally called CONSTANTLY + //Called by: Anything that changes values within a gas mix. + //Inputs: None + //Outputs: None + + total_moles = oxygen + carbon_dioxide + nitrogen + toxins + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + total_moles += trace_gas.moles + + if(volume) + pressure = total_moles*R_IDEAL_GAS_EQUATION*temperature/volume + else + pressure = 0 + return + +//////////////////////////////////////////// +//Procedures used for very specific events// +//////////////////////////////////////////// + + + proc/check_tile_graphic() + //Purpose: Calculating the graphic for a tile + //Called by: Turfs updating + //Inputs: None + //Outputs: 1 if graphic changed, 0 if unchanged + + graphic = null + if(toxins > MOLES_PLASMA_VISIBLE) + graphic = "plasma" + else if(length(trace_gases)) + var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in trace_gases + if(sleeping_agent && (sleeping_agent.moles > 1)) + graphic = "sleeping_agent" + else + graphic = null + + return graphic != graphic_archived + + proc/react(atom/dump_location) + //Purpose: Calculating if it is possible for a fire to occur in the airmix + //Called by: Air mixes updating? + //Inputs: None + //Outputs: If a fire occured + + var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network) + + if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + if(fire() > 0) + reacting = 1 + + return reacting + + proc/fire() + //Purpose: Calculating any fire reactions. + //Called by: react() (See above) + //Inputs: None + //Outputs: How much fuel burned + + return zburn(null) + + /*var/energy_released = 0 + var/old_heat_capacity = heat_capacity() + + var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel) in trace_gases + if(fuel_store) //General volatile gas burn + var/burned_fuel = 0 + + if(oxygen < fuel_store.moles) + burned_fuel = oxygen + fuel_store.moles -= burned_fuel + oxygen = 0 + else + burned_fuel = fuel_store.moles + oxygen -= fuel_store.moles + del(fuel_store) + + energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel + carbon_dioxide += burned_fuel + fuel_burnt += burned_fuel + + //Handle plasma burning + if(toxins > MINIMUM_HEAT_CAPACITY) + var/plasma_burn_rate = 0 + var/oxygen_burn_rate = 0 + //more plasma released at higher temperatures + var/temperature_scale + if(temperature > PLASMA_UPPER_TEMPERATURE) + temperature_scale = 1 + else + temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) + if(temperature_scale > 0) + oxygen_burn_rate = 1.4 - temperature_scale + if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN) + plasma_burn_rate = (toxins*temperature_scale)/4 + else + plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4 + if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) + toxins -= plasma_burn_rate + oxygen -= plasma_burn_rate*oxygen_burn_rate + carbon_dioxide += plasma_burn_rate + + energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) + + fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate) + + if(energy_released > 0) + var/new_heat_capacity = heat_capacity() + if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) + temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity + update_values() + + return fuel_burnt*/ + +////////////////////////////////////////////// +//Procs for general gas spread calculations.// +////////////////////////////////////////////// + + + proc/archive() + //Purpose: Archives the current gas values + //Called by: UNKNOWN + //Inputs: None + //Outputs: 1 + + oxygen_archived = oxygen + carbon_dioxide_archived = carbon_dioxide + nitrogen_archived = nitrogen + toxins_archived = toxins + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + trace_gas.moles_archived = trace_gas.moles + + temperature_archived = temperature + + graphic_archived = graphic + + return 1 + + proc/check_then_merge(datum/gas_mixture/giver) + //Purpose: Similar to merge(...) but first checks to see if the amount of air assumed is small enough + // that group processing is still accurate for source (aborts if not) + //Called by: airgroups/machinery expelling air, ? + //Inputs: The gas to try and merge + //Outputs: 1 on successful merge. 0 otherwise. + + if(!giver) + return 0 + if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((giver.toxins > MINIMUM_AIR_TO_SUSPEND) && (giver.toxins >= toxins*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return 0 + if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) + return 0 + + if(giver.trace_gases.len) + for(var/datum/gas/trace_gas in giver.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return 0 + + return merge(giver) + + proc/merge(datum/gas_mixture/giver) + //Purpose: Merges all air from giver into self. Deletes giver. + //Called by: Machinery expelling air, check_then_merge, ? + //Inputs: The gas to merge. + //Outputs: 1 + + if(!giver) + return 0 + + if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity()*group_multiplier + var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier + var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity + if(combined_heat_capacity != 0) + temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity + + if((group_multiplier>1)||(giver.group_multiplier>1)) + oxygen += giver.oxygen*giver.group_multiplier/group_multiplier + carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier + nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier + toxins += giver.toxins*giver.group_multiplier/group_multiplier + else + oxygen += giver.oxygen + carbon_dioxide += giver.carbon_dioxide + nitrogen += giver.nitrogen + toxins += giver.toxins + + if(giver.trace_gases.len) + for(var/datum/gas/trace_gas in giver.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(!corresponding) + corresponding = new trace_gas.type() + trace_gases += corresponding + corresponding.moles += trace_gas.moles*giver.group_multiplier/group_multiplier + update_values() + + del(giver) + return 1 + + proc/remove(amount) + //Purpose: Removes a certain number of moles from the air. + //Called by: ? + //Inputs: How many moles to remove. + //Outputs: Removed air. + + var/sum = total_moles + amount = min(amount,sum) //Can not take more air than tile has! + if(amount <= 0) + return null + + var/datum/gas_mixture/removed = new + + + 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) + + oxygen -= removed.oxygen/group_multiplier + nitrogen -= removed.nitrogen/group_multiplier + carbon_dioxide -= removed.carbon_dioxide/group_multiplier + toxins -= removed.toxins/group_multiplier + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + var/datum/gas/corresponding = new trace_gas.type() + removed.trace_gases += corresponding + + corresponding.moles = (trace_gas.moles/sum)*amount + trace_gas.moles -= corresponding.moles/group_multiplier + + removed.temperature = temperature + update_values() + removed.update_values() + + return removed + + proc/remove_ratio(ratio) + //Purpose: Removes a certain ratio of the air. + //Called by: ? + //Inputs: Percentage to remove. + //Outputs: Removed air. + + if(ratio <= 0) + return null + + ratio = min(ratio, 1) + + var/datum/gas_mixture/removed = new + + removed.oxygen = QUANTIZE(oxygen*ratio) + removed.nitrogen = QUANTIZE(nitrogen*ratio) + removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio) + removed.toxins = QUANTIZE(toxins*ratio) + + oxygen -= removed.oxygen/group_multiplier + nitrogen -= removed.nitrogen/group_multiplier + carbon_dioxide -= removed.carbon_dioxide/group_multiplier + toxins -= removed.toxins/group_multiplier + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + var/datum/gas/corresponding = new trace_gas.type() + removed.trace_gases += corresponding + + corresponding.moles = trace_gas.moles*ratio + trace_gas.moles -= corresponding.moles/group_multiplier + + removed.temperature = temperature + update_values() + removed.update_values() + + return removed + + proc/check_then_remove(amount) + //Purpose: Similar to remove(...) but first checks to see if the amount of air removed is small enough + // that group processing is still accurate for source (aborts if not) + //Called by: ? + //Inputs: Number of moles to remove + //Outputs: Removed air or 0 if it can remove air or not. + + amount = min(amount,total_moles) //Can not take more air than tile has! + + if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > total_moles*MINIMUM_AIR_RATIO_TO_SUSPEND)) + return 0 + + return remove(amount) + + proc/copy_from(datum/gas_mixture/sample) + //Purpose: Duplicates the sample air mixture. + //Called by: airgroups splitting, ? + //Inputs: Gas to copy + //Outputs: 1 + + oxygen = sample.oxygen + carbon_dioxide = sample.carbon_dioxide + nitrogen = sample.nitrogen + toxins = sample.toxins + total_moles = sample.total_moles + + trace_gases.len=null + if(sample.trace_gases.len > 0) + for(var/datum/gas/trace_gas in sample.trace_gases) + var/datum/gas/corresponding = new trace_gas.type() + trace_gases += corresponding + + corresponding.moles = trace_gas.moles + + temperature = sample.temperature + + return 1 + + proc/check_gas_mixture(datum/gas_mixture/sharer) + //Purpose: Telling if one or both airgroups needs to disable group processing. + //Called by: Airgroups sharing air, checking if group processing needs disabled. + //Inputs: Gas to compare from other airgroup + //Outputs: 0 if the self-check failed (local airgroup breaks?) + // then -1 if sharer-check failed (sharing airgroup breaks?) + // then 1 if both checks pass (share succesful?) + if(!istype(sharer)) + return + + var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION + var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION + var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION + var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION + + var/delta_temperature = (temperature_archived - sharer.temperature_archived) + + if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return 0 + + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) + return 0 + + if(sharer.trace_gases.len) + for(var/datum/gas/trace_gas in sharer.trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(corresponding) + if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) + return 0 + else + return 0 + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + if(!locate(trace_gas.type) in sharer.trace_gases) + return 0 + + if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= sharer.toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return -1 + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases + if(corresponding) + if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) + return -1 + else + return -1 + + return 1 + + proc/check_turf(turf/model) + //Purpose: Used to compare the gases in an unsimulated turf with the gas in a simulated one. + //Called by: Sharing air (mimicing) with adjacent unsimulated turfs + //Inputs: Unsimulated turf + //Outputs: 1 if safe to mimic, 0 if needs to break airgroup. + + var/delta_oxygen = (oxygen_archived - model.oxygen)/TRANSFER_FRACTION + var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION + var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION + var/delta_toxins = (toxins_archived - model.toxins)/TRANSFER_FRACTION + + var/delta_temperature = (temperature_archived - model.temperature) + + if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ + || ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) + return 0 + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) + return 0 + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) + return 0 + + return 1 + + proc/share(datum/gas_mixture/sharer) + //Purpose: Used to transfer gas from a more pressurised tile to a less presurised tile + // (Two directional, if the other tile is more pressurised, air travels to current tile) + //Called by: Sharing air with adjacent simulated turfs + //Inputs: Air datum to share with + //Outputs: Amount of gas exchanged (Negative if lost air, positive if gained.) + + + if(!istype(sharer)) + return + + var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION + var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION + var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION + var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/TRANSFER_FRACTION + + var/delta_temperature = (temperature_archived - sharer.temperature_archived) + + var/old_self_heat_capacity = 0 + var/old_sharer_heat_capacity = 0 + + var/heat_self_to_sharer = 0 + var/heat_capacity_self_to_sharer = 0 + var/heat_sharer_to_self = 0 + var/heat_capacity_sharer_to_self = 0 + + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + + var/delta_air = delta_oxygen+delta_nitrogen + if(delta_air) + var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air + if(delta_air > 0) + heat_self_to_sharer += air_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += air_heat_capacity + else + heat_sharer_to_self -= air_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= air_heat_capacity + + if(delta_carbon_dioxide) + var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide + if(delta_carbon_dioxide > 0) + heat_self_to_sharer += carbon_dioxide_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity + else + heat_sharer_to_self -= carbon_dioxide_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity + + if(delta_toxins) + var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins + if(delta_toxins > 0) + heat_self_to_sharer += toxins_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += toxins_heat_capacity + else + heat_sharer_to_self -= toxins_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= toxins_heat_capacity + + old_self_heat_capacity = heat_capacity()*group_multiplier + old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier + + oxygen -= delta_oxygen/group_multiplier + sharer.oxygen += delta_oxygen/sharer.group_multiplier + + carbon_dioxide -= delta_carbon_dioxide/group_multiplier + sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier + + nitrogen -= delta_nitrogen/group_multiplier + sharer.nitrogen += delta_nitrogen/sharer.group_multiplier + + toxins -= delta_toxins/group_multiplier + sharer.toxins += delta_toxins/sharer.group_multiplier + + var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins) + + var/list/trace_types_considered = list() + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + + var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases + var/delta = 0 + + if(corresponding) + delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/TRANSFER_FRACTION + else + corresponding = new trace_gas.type() + sharer.trace_gases += corresponding + + delta = trace_gas.moles_archived/TRANSFER_FRACTION + + trace_gas.moles -= delta/group_multiplier + corresponding.moles += delta/sharer.group_multiplier + + if(delta) + var/individual_heat_capacity = trace_gas.specific_heat*delta + if(delta > 0) + heat_self_to_sharer += individual_heat_capacity*temperature_archived + heat_capacity_self_to_sharer += individual_heat_capacity + else + heat_sharer_to_self -= individual_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self -= individual_heat_capacity + + moved_moles += delta + + trace_types_considered += trace_gas.type + + + if(sharer.trace_gases.len) + for(var/datum/gas/trace_gas in sharer.trace_gases) + if(trace_gas.type in trace_types_considered) continue + else + var/datum/gas/corresponding + var/delta = 0 + + corresponding = new trace_gas.type() + trace_gases += corresponding + + delta = trace_gas.moles_archived/TRANSFER_FRACTION + + trace_gas.moles -= delta/sharer.group_multiplier + corresponding.moles += delta/group_multiplier + + //Guaranteed transfer from sharer to self + var/individual_heat_capacity = trace_gas.specific_heat*delta + heat_sharer_to_self += individual_heat_capacity*sharer.temperature_archived + heat_capacity_sharer_to_self += individual_heat_capacity + + moved_moles += -delta + update_values() + sharer.update_values() + + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer + var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self + + if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) + temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity + + if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) + sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity + + if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY) + if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity + temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT) + + if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) + var/delta_pressure = temperature_archived*(total_moles + moved_moles) - sharer.temperature_archived*(sharer.total_moles - moved_moles) + return delta_pressure*R_IDEAL_GAS_EQUATION/volume + + else + return 0 + + proc/mimic(turf/model, border_multiplier) + //Purpose: Used transfer gas from a more pressurised tile to a less presurised unsimulated tile. + //Called by: "sharing" from unsimulated to simulated turfs. + //Inputs: Unsimulated turf, Multiplier for gas transfer (optional) + //Outputs: Amount of gas exchanged + + var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/TRANSFER_FRACTION + var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION + var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION + var/delta_toxins = QUANTIZE(toxins_archived - model.toxins)/TRANSFER_FRACTION + + var/delta_temperature = (temperature_archived - model.temperature) + + var/heat_transferred = 0 + var/old_self_heat_capacity = 0 + var/heat_capacity_transferred = 0 + + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + + var/delta_air = delta_oxygen+delta_nitrogen + if(delta_air) + var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air + heat_transferred -= air_heat_capacity*model.temperature + heat_capacity_transferred -= air_heat_capacity + + if(delta_carbon_dioxide) + var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide + heat_transferred -= carbon_dioxide_heat_capacity*model.temperature + heat_capacity_transferred -= carbon_dioxide_heat_capacity + + if(delta_toxins) + var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins + heat_transferred -= toxins_heat_capacity*model.temperature + heat_capacity_transferred -= toxins_heat_capacity + + old_self_heat_capacity = heat_capacity()*group_multiplier + + if(border_multiplier) + oxygen -= delta_oxygen*border_multiplier/group_multiplier + carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier + nitrogen -= delta_nitrogen*border_multiplier/group_multiplier + toxins -= delta_toxins*border_multiplier/group_multiplier + else + oxygen -= delta_oxygen/group_multiplier + carbon_dioxide -= delta_carbon_dioxide/group_multiplier + nitrogen -= delta_nitrogen/group_multiplier + toxins -= delta_toxins/group_multiplier + + var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins) + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + var/delta = 0 + + delta = trace_gas.moles_archived/TRANSFER_FRACTION + + if(border_multiplier) + trace_gas.moles -= delta*border_multiplier/group_multiplier + else + trace_gas.moles -= delta/group_multiplier + + var/heat_cap_transferred = delta*trace_gas.specific_heat + heat_transferred += heat_cap_transferred*temperature_archived + heat_capacity_transferred += heat_cap_transferred + moved_moles += delta + update_values() + + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred + if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) + if(border_multiplier) + temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity + else + temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity + + temperature_mimic(model, model.thermal_conductivity, border_multiplier) + + if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) + var/delta_pressure = temperature_archived*(total_moles + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.toxins) + return delta_pressure*R_IDEAL_GAS_EQUATION/volume + else + return 0 + + proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) + var/delta_temperature = (temperature_archived - sharer.temperature_archived) + + var/self_heat_capacity = heat_capacity_archived() + var/sharer_heat_capacity = sharer.heat_capacity_archived() + + var/self_temperature_delta = 0 + var/sharer_temperature_delta = 0 + + if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) + + self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) + sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier) + else + return 1 + + if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ + && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) + return 0 + + if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ + && (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived)) + return -1 + + temperature += self_temperature_delta + sharer.temperature += sharer_temperature_delta + + return 1 + //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency + + proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) + var/delta_temperature = (temperature_archived - sharer.temperature_archived) + + var/self_heat_capacity = heat_capacity_archived() + var/sharer_heat_capacity = sharer.heat_capacity_archived() + + var/self_temperature_delta = 0 + var/sharer_temperature_delta = 0 + + if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) + + self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) + sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier) + else + return 1 + + if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ + && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) + return 0 + + temperature += self_temperature_delta + sharer.temperature += sharer_temperature_delta + + return 1 + //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency + + proc/check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient) + var/delta_temperature = (temperature_archived - sharer.temperature) + + var/self_temperature_delta = 0 + var/sharer_temperature_delta = 0 + + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity_archived() + + if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) + + self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) + sharer_temperature_delta = heat/sharer.heat_capacity + else + return 1 + + if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ + && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) + return 0 + + temperature += self_temperature_delta + sharer.temperature += sharer_temperature_delta + + return 1 + //Logic integrated from: temperature_turf_share(sharer, conduction_coefficient) for efficiency + + proc/check_me_then_temperature_mimic(turf/model, conduction_coefficient) + var/delta_temperature = (temperature_archived - model.temperature) + var/self_temperature_delta = 0 + + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity_archived() + + if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity)) + + self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) + + if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ + && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) + return 0 + + temperature += self_temperature_delta + + return 1 + //Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency + + proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient) + + var/delta_temperature = (temperature_archived - sharer.temperature_archived) + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity_archived() + var/sharer_heat_capacity = sharer.heat_capacity_archived() + if(!group_multiplier) + message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") + return + + if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) + + temperature -= heat/(self_heat_capacity*group_multiplier) + sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier) + + proc/temperature_mimic(turf/model, conduction_coefficient, border_multiplier) + var/delta_temperature = (temperature - model.temperature) + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity()//_archived() + if(!group_multiplier) + message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") + return + + if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity)) + + if(border_multiplier) + temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier) + else + temperature -= heat/(self_heat_capacity*group_multiplier) + + proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient) + var/delta_temperature = (temperature_archived - sharer.temperature) + if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) + var/self_heat_capacity = heat_capacity() + + if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) + var/heat = conduction_coefficient*delta_temperature* \ + (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) + + temperature -= heat/(self_heat_capacity*group_multiplier) + sharer.temperature += heat/sharer.heat_capacity + + proc/compare(datum/gas_mixture/sample) + //Purpose: Compares sample to self to see if within acceptable ranges that group processing may be enabled + //Called by: Airgroups trying to rebuild + //Inputs: Gas mix to compare + //Outputs: 1 if can rebuild, 0 if not. + if(!sample) return 0 + + if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \ + ((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen))) + return 0 + if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \ + ((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen))) + return 0 + if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \ + ((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide))) + return 0 + if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \ + ((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins))) + return 0 + + if(total_moles > MINIMUM_AIR_TO_SUSPEND) + if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \ + ((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature))) + //world << "temp fail [temperature] & [sample.temperature]" + return 0 + + if(sample.trace_gases.len) + for(var/datum/gas/trace_gas in sample.trace_gases) + if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(corresponding) + if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \ + ((corresponding.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (corresponding.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles))) + return 0 + else + return 0 + + if(trace_gases.len) + for(var/datum/gas/trace_gas in trace_gases) + if(trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) + var/datum/gas/corresponding = locate(trace_gas.type) in sample.trace_gases + if(corresponding) + if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \ + ((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles))) + return 0 + else + return 0 + return 1 + + + proc/subtract(datum/gas_mixture/right_side) + //Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle + //Called by: Pipelines ending in a break (or something) + //Inputs: Gas mix to remove + //Outputs: 1 + + oxygen -= right_side.oxygen + carbon_dioxide -= right_side.carbon_dioxide + nitrogen -= right_side.nitrogen + toxins -= right_side.toxins + + if((trace_gases.len > 0)||(right_side.trace_gases.len > 0)) + for(var/datum/gas/trace_gas in right_side.trace_gases) + var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases + if(!corresponding) + corresponding = new trace_gas.type() + trace_gases += corresponding + + corresponding.moles -= trace_gas.moles + update_values() + return 1 \ No newline at end of file diff --git a/code/ZAS/FEA_system.dm b/code/ZAS/FEA_system.dm new file mode 100644 index 00000000000..dd2fca6ef21 --- /dev/null +++ b/code/ZAS/FEA_system.dm @@ -0,0 +1,178 @@ +/* +Overview: + The air_master global variable is the workhorse for the system. + +Why are you archiving data before modifying it? + The general concept with archiving data and having each tile keep track of when they were last updated is to keep everything symmetric + and totally independent of the order they are read in an update cycle. + This prevents abnormalities like air/fire spreading rapidly in one direction and super slowly in the other. + +Why not just archive everything and then calculate? + Efficiency. While a for-loop that goes through all tils and groups to archive their information before doing any calculations seems simple, it is + slightly less efficient than the archive-before-modify/read method. + +Why is there a cycle check for calculating data as well? + This ensures that every connection between group-tile, tile-tile, and group-group is only evaluated once per loop. + + + + +Important variables: + air_master.groups_to_rebuild (list) + A list of air groups that have had their geometry occluded and thus may need to be split in half. + A set of adjacent groups put in here will join together if validly connected. + This is done before air system calculations for a cycle. + air_master.tiles_to_update (list) + Turfs that are in this list have their border data updated before the next air calculations for a cycle. + Place turfs in this list rather than call the proc directly to prevent race conditions + + turf/simulated.archive() and datum/air_group.archive() + This stores all data for. + If you modify, make sure to update the archived_cycle to prevent race conditions and maintain symmetry + + atom/CanPass(atom/movable/mover, turf/target, height, air_group) + returns 1 for allow pass and 0 for deny pass + Turfs automatically call this for all objects/mobs in its turf. + This is called both as source.CanPass(target, height, air_group) + and target.CanPass(source, height, air_group) + + Cases for the parameters + 1. This is called with args (mover, location, height>0, air_group=0) for normal objects. + 2. This is called with args (null, location, height=0, air_group=0) for flowing air. + 3. This is called with args (null, location, height=?, air_group=1) for determining group boundaries. + + Cases 2 and 3 would be different for doors or other objects open and close fairly often. + (Case 3 would return 0 always while Case 2 would return 0 only when the door is open) + This prevents the necessity of re-evaluating group geometry every time a door opens/closes. + + +Important Procedures + air_master.process() + This first processes the air_master update/rebuild lists then processes all groups and tiles for air calculations + + +*/ + +var/kill_air = 0 +var/tick_multiplier = 2 + +atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) + //Purpose: Determines if the object (or airflow) can pass this atom. + //Called by: Movement, airflow. + //Inputs: The moving atom (optional), target turf, "height" and air group + //Outputs: Boolean if can pass. + + return (!density || !height || air_group) + +turf + CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0) + if(!target) return 0 + + if(istype(mover)) // turf/Enter(...) will perform more advanced checks + return !density + + else // Now, doing more detailed checks for air movement and air group formation + if(target.blocks_air||blocks_air) + return 0 + + for(var/obj/obstacle in src) + if(!obstacle.CanPass(mover, target, height, air_group)) + return 0 + for(var/obj/obstacle in target) + if(!obstacle.CanPass(mover, src, height, air_group)) + return 0 + + return 1 + + +var/global/datum/controller/air_system/air_master + +datum + controller + air_system + //Geoemetry lists + var/list/turf/simulated/active_singletons = list() + + //Special functions lists + var/list/turf/simulated/active_super_conductivity = list() + var/list/turf/simulated/high_pressure_delta = list() + + //Geometry updates lists + var/list/turf/simulated/tiles_to_update = list() + var/list/turf/simulated/groups_to_rebuild = 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? + + +/* process() + //Call this to process air movements for a cycle + + process_rebuild_select_groups() + //Used by process() + //Warning: Do not call this + + rebuild_group(datum/air_group) + //Used by process_rebuild_select_groups() + //Warning: Do not call this, add the group to air_master.groups_to_rebuild instead + */ + + + proc/setup() + //Purpose: Call this at the start to setup air groups geometry + // (Warning: Very processor intensive but only must be done once per round) + //Called by: Gameticker/Master controller + //Inputs: None. + //Outputs: None. + + set background = 1 + world << "\red \b Processing Geometry..." + sleep(-1) + + var/start_time = world.timeofday + + for(var/turf/simulated/S in world) + if(S.z < 5) + if(!S.blocks_air && !S.zone && S.z < 5) // Added last check to force skipping asteroid z-levels -- TLE + new/zone(S) + + S.update_air_properties() + + world << "\red \b Geometry processed in [time2text(world.timeofday-start_time, "mm:ss")] minutes!" + spawn start() + + proc/start() + //Purpose: This is kicked off by the master controller, and controls the processing of all atmosphere. + //Called by: Master controller + //Inputs: None. + //Outputs: None. + + set background = 1 + while(1) + if(!kill_air) + current_cycle++ + var/success = tick() //Changed so that a runtime does not crash the ticker. + if(!success) //Runtimed. + failed_ticks++ + if(failed_ticks > 20) + world << "ERROR IN ATMOS TICKER. Killing air simulation!" + kill_air = 1 + sleep(max(5,update_delay*tick_multiplier)) + + proc/tick() + + if(tiles_to_update.len > 0) //If there are tiles to update, do so. + for(var/turf/simulated/T in tiles_to_update) + spawn T.update_air_properties() + tiles_to_update = list() + + for(var/zone/Z in zones) + if(Z.last_update < current_cycle) + Z.process() + if(Z) Z.last_update = current_cycle + + for(var/obj/fire/F) + F.process() + + return 1 \ No newline at end of file diff --git a/code/ZAS/FEA_turf_tile.dm b/code/ZAS/FEA_turf_tile.dm new file mode 100644 index 00000000000..d65d1d96650 --- /dev/null +++ b/code/ZAS/FEA_turf_tile.dm @@ -0,0 +1,205 @@ +atom/var/pressure_resistance = ONE_ATMOSPHERE +turf + assume_air(datum/gas_mixture/giver) //use this for machines to adjust air + del(giver) + return 0 + + return_air() + //Create gas mixture to hold data for passing + var/datum/gas_mixture/GM = new + + GM.oxygen = oxygen + GM.carbon_dioxide = carbon_dioxide + GM.nitrogen = nitrogen + GM.toxins = toxins + + GM.temperature = temperature + GM.update_values() + + return GM + + remove_air(amount as num) + var/datum/gas_mixture/GM = new + + 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 + + GM.temperature = temperature + GM.update_values() + + return GM + + +turf + simulated + + var/current_graphic = null + + var/tmp + datum/gas_mixture/air + + processing = 1 + group_border = 0 + length_space_border = 0 + + air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update + + archived_cycle = 0 + current_cycle = 0 + + obj/effect/hotspot/active_hotspot + + temperature_archived //USED ONLY FOR SOLIDS + being_superconductive = 0 + + + proc + process_cell() + update_air_properties() + archive() + + mimic_air_with_tile(turf/model) + share_air_with_tile(turf/simulated/sharer) + + mimic_temperature_with_tile(turf/model) + share_temperature_with_tile(turf/simulated/sharer) + + + super_conduct() + + update_visuals() + overlays = null + + var/siding_icon_state = return_siding_icon_state() + if(siding_icon_state) + overlays += image('floors.dmi',siding_icon_state) + var/datum/gas_mixture/model = return_air() + switch(model.graphic) + if("plasma") + overlays.Add(plmaster) + if("sleeping_agent") + overlays.Add(slmaster) + + + + New() + ..() + + if(!blocks_air) + air = new + + air.oxygen = oxygen + air.carbon_dioxide = carbon_dioxide + air.nitrogen = nitrogen + air.toxins = toxins + + air.temperature = temperature + air.update_values() + + if(air_master) + air_master.tiles_to_update.Add(src) + + find_zone() + +// air.parent = src //TODO DEBUG REMOVE + + else + if(air_master) + for(var/direction in cardinal) + var/turf/simulated/floor/target = get_step(src,direction) + if(istype(target)) + air_master.tiles_to_update.Add(target) + + Del() + if(active_hotspot) + del(active_hotspot) + if(blocks_air) + for(var/direction in list(NORTH, SOUTH, EAST, WEST)) + var/turf/simulated/tile = get_step(src,direction) + if(istype(tile) && !tile.blocks_air) + air_master.tiles_to_update.Add(tile) + ..() + + assume_air(datum/gas_mixture/giver) + if(!giver) return 0 + if(zone) + zone.air.merge(giver) + return 1 + else + return ..() + + archive() + if(air) //For open space like floors + air.archive() + + temperature_archived = temperature + archived_cycle = air_master.current_cycle + + share_air_with_tile(turf/simulated/T) + return air.share(T.air) + + mimic_air_with_tile(turf/T) + return air.mimic(T) + + return_air() + if(zone) + return zone.air + else if(air) + return air + + else + return ..() + + remove_air(amount as num) + if(zone) + var/datum/gas_mixture/removed = null + removed = zone.air.remove(amount) + return removed + else if(air) + var/datum/gas_mixture/removed = null + removed = air.remove(amount) + + if(air.check_tile_graphic()) + update_visuals(air) + return removed + + else + return ..() + + update_air_properties()//OPTIMIZE + air_check_directions = 0 + + for(var/direction in cardinal) + if(CanPass(null, get_step(src,direction), 0, 0)) + air_check_directions |= direction + + if(zone) + for(var/direction in cardinal) + if(air_check_directions&direction) + + var/turf/simulated/T = get_step(src,direction) + if(T) + ZConnect(src,T) + else + var/turf/simulated/T = get_step(src,direction) + if(T) + ZDisconnect(src,T) + else + + for(var/direction in cardinal) + if(air_check_directions&direction) + var/turf/simulated/T = get_step(src,direction) + if(T.zone) + T.zone.AddTurf(src) + break + if(!zone) + new/zone(src) + + if(air_check_directions) + processing = 1 + else + processing = 0 \ No newline at end of file diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index f265c45877a..24f98ccb02f 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -7,7 +7,7 @@ atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) - if(fire_protection) return + if(fire_protection > world.time-300) return var/datum/gas_mixture/air_contents = return_air(1) if(!air_contents) return 0 @@ -25,19 +25,11 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) return 1 var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases var/obj/liquid_fuel/liquid = locate() in src - var/fuel_level = 0 - var/liquid_level = 0 - if(fuel) fuel_level = fuel.moles - if(liquid) liquid_level = liquid.amount - var/total_fuel = air_contents.toxins + fuel_level + liquid_level - if((air_contents.oxygen + air_contents.toxins + fuel_level*1.5 + liquid_level*1.5) - (air_contents.carbon_dioxide*0.25) > vsc.IgnitionLevel && total_fuel > 0.5) + if(air_contents.calculate_firelevel(liquid) > vsc.IgnitionLevel && (fuel || liquid || air_contents.toxins > 0.5)) igniting = 1 if(air_contents.oxygen < 0.5) return 0 - if(parent&&parent.group_processing) - parent.suspend_group_processing() - if(! (locate(/obj/fire) in src)) var/obj/fire/F = new(src,1000) F.temperature = exposed_temperature @@ -180,31 +172,20 @@ obj var datum/gas_mixture/air_contents = S.return_air() datum/gas/volatile_fuel/fuel = locate(/datum/gas/volatile_fuel/) in air_contents.trace_gases - fuel_level = 0 obj/liquid_fuel/liquid = locate() in S - liquid_level = 0 - if(fuel) fuel_level = fuel.moles - if(liquid) - liquid_level = liquid.amount - if(liquid.amount <= 0) - del liquid - liquid_level = 0 + firelevel = air_contents.calculate_firelevel(liquid) - firelevel = (air_contents.oxygen + air_contents.toxins + fuel_level*1.5 + liquid_level*1.5) - (air_contents.carbon_dioxide*0.25) - - firelevel = min(firelevel,vsc.IgnitionLevel*5) - - if(firelevel > vsc.IgnitionLevel * 1.5 && (air_contents.toxins || fuel_level || liquid_level)) + if(firelevel > 25 && (air_contents.toxins || fuel || liquid)) for(var/direction in cardinal) if(S.air_check_directions&direction) //Grab all valid bordering tiles var/turf/simulated/enemy_tile = get_step(S, direction) if(istype(enemy_tile)) - if(enemy_tile.fire_protection) - firelevel -= vsc.IgnitionLevel + if(enemy_tile.fire_protection > world.time-30) + firelevel -= 150 continue if(!(locate(/obj/fire) in enemy_tile)) - if( prob( firelevel/(vsc.IgnitionLevel*0.1) ) ) + if( prob( firelevel/2.5 ) ) new/obj/fire(enemy_tile,firelevel) // else // world << "Spread Probability: [firelevel/(vsc.IgnitionLevel*0.1)]%." @@ -220,12 +201,12 @@ obj if(flow) - if(flow.oxygen > 0.3 && (flow.toxins || fuel_level || liquid)) + if(flow.oxygen > 0.3 && (flow.toxins || fuel || liquid)) icon_state = "1" - if(firelevel > vsc.IgnitionLevel * 2) + if(firelevel > 25) icon_state = "2" - if(firelevel > vsc.IgnitionLevel * 3.5) + if(firelevel > 100) icon_state = "3" flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature) flow.zburn(liquid) @@ -245,7 +226,7 @@ obj del src for(var/mob/living/carbon/human/M in loc) - M.FireBurn(firelevel/(vsc.IgnitionLevel*10)) + M.FireBurn(min(max(0.1,firelevel / 20),10)) New(newLoc,fl) @@ -254,7 +235,7 @@ obj sd_SetLuminosity(3) firelevel = fl for(var/mob/living/carbon/human/M in loc) - M.FireBurn(firelevel/(vsc.IgnitionLevel*10)) + M.FireBurn(min(max(0.1,firelevel / 20),10)) Del() if (istype(loc, /turf/simulated)) @@ -265,74 +246,135 @@ obj ..() obj/liquid_fuel - icon = 'effects.dmi' - icon_state = "slube" + icon = 'icons/effects/effects.dmi' + icon_state = "fuel" layer = TURF_LAYER+0.2 anchored = 1 var/amount = 1 - New(newLoc) + New(newLoc,amt=1) + src.amount = amt for(var/obj/liquid_fuel/other in newLoc) if(other != src) other.amount += src.amount + spawn other.Spread() del src + return + Spread() . = ..() + proc/Spread() + if(amount < 0.5) return + var/turf/simulated/S = loc + if(!istype(S)) return + for(var/d in cardinal) + if(S.air_check_directions & d) + if(rand(25)) + var/turf/simulated/O = get_step(src,d) + new/obj/liquid_fuel(O,amount*0.25) + amount *= 0.75 + + flamethrower_fuel + icon_state = "mustard" + anchored = 0 + New(newLoc, amt = 1, d = 0) + dir = d + . = ..() + Spread() + if(amount < 0.1) return + var/turf/simulated/S = loc + if(!istype(S)) return + for(var/d in list(turn(dir,90),turn(dir,-90))) + if(S.air_check_directions & d) + var/turf/simulated/O = get_step(S,d) + new/obj/liquid_fuel/flamethrower_fuel(O,amount*0.25,d) + O.hotspot_expose((T20C*2) + 380,500) + amount *= 0.5 vs_control/var/switch_fire = 1 turf/simulated/var/fire_protection = 0 -datum/gas_mixture/proc/zburn(obj/liquid_fuel/liquid) - if(vsc.switch_fire) - . = fire() - if(liquid && liquid.amount > 0) - oxygen -= fire_ratio_1 - liquid.amount = max(liquid.amount-fire_ratio_1,0) - carbon_dioxide += fire_ratio_1 - if(liquid.amount <= 0) - del liquid - return - if(temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) +turf/proc/apply_fire_protection() +turf/simulated/apply_fire_protection() + fire_protection = world.time + +datum/gas_mixture/proc + zburn(obj/liquid_fuel/liquid) + if(temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) + var + total_fuel = toxins + fuel_sources = 0 + datum/gas/volatile_fuel/fuel = locate() in trace_gases + if(fuel) + total_fuel += fuel.moles + fuel_sources++ + if(liquid) + if(liquid.amount <= 0) + del liquid + else + total_fuel += liquid.amount + fuel_sources++ + if(toxins > 0.3) fuel_sources++ + + if(!fuel_sources) return 0 + if(oxygen > 0.3 && total_fuel) + var/firelevel = calculate_firelevel(liquid) + //f(x) = 1000ln(0.01x + 1.45) + temperature = 1000*log(0.016*firelevel + 1.45) + var/consumed_gas = min(oxygen,0.002*firelevel,total_fuel) / fuel_sources + oxygen -= consumed_gas + toxins = max(0,toxins-consumed_gas) + if(fuel) + fuel.moles -= consumed_gas + if(fuel.moles <= 0) del fuel + if(liquid) + liquid.amount -= consumed_gas + if(liquid.amount <= 0) del liquid + update_values() + return consumed_gas*fuel_sources + return 0 + calculate_firelevel(obj/liquid_fuel/liquid) var - fuel_level = 0 datum/gas/volatile_fuel/fuel = locate() in trace_gases + fuel_level = 0 liquid_level = 0 if(fuel) fuel_level = fuel.moles if(liquid) liquid_level = liquid.amount - if(liquid && liquid_level <= 0) - del liquid - liquid_level = 0 - if(oxygen > 0.3 && (toxins || fuel_level || liquid_level)) - if(toxins && temperature < PLASMA_UPPER_TEMPERATURE) - temperature += (FIRE_PLASMA_ENERGY_RELEASED*fire_ratio_1) / heat_capacity() + return oxygen + toxins + liquid_level*15 + fuel_level*5 - if((fuel_level || liquid_level) && temperature < PLASMA_UPPER_TEMPERATURE) - temperature += (FIRE_CARBON_ENERGY_RELEASED*fire_ratio_1) / heat_capacity() +/mob/living/carbon/human/proc/FireBurn(mx as num) + //NO! NOT INTO THE PIT! IT BURRRRRNS! - if(toxins > fire_ratio_1) - oxygen -= vsc.plc.OXY_TO_PLASMA*fire_ratio_1 - toxins -= fire_ratio_1 - carbon_dioxide += fire_ratio_1 - else if(toxins) - oxygen -= toxins * vsc.plc.OXY_TO_PLASMA - carbon_dioxide += toxins - toxins = 0 + var + head_exposure = 1 + chest_exposure = 1 + groin_exposure = 1 + legs_exposure = 1 + arms_exposure = 1 - if(fuel_level > fire_ratio_1/1.5) - oxygen -= vsc.plc.OXY_TO_PLASMA*fire_ratio_1 - fuel.moles -= fire_ratio_1 - carbon_dioxide += fire_ratio_1 + for(var/obj/item/clothing/C in src) + if(l_hand == C || r_hand == C) continue + if(C.body_parts_covered & HEAD) + head_exposure *= C.heat_transfer_coefficient + if(C.body_parts_covered & UPPER_TORSO) + chest_exposure *= C.heat_transfer_coefficient + if(C.body_parts_covered & LOWER_TORSO) + groin_exposure *= C.heat_transfer_coefficient + if(C.body_parts_covered & LEGS) + legs_exposure *= C.heat_transfer_coefficient + if(C.body_parts_covered & ARMS) + arms_exposure *= C.heat_transfer_coefficient - else if(fuel_level) - oxygen -= fuel.moles * vsc.plc.OXY_TO_PLASMA - carbon_dioxide += fuel.moles - fuel.moles = 0 + mx *= 1 - if(liquid_level > 0) - oxygen -= fire_ratio_1 - liquid.amount = max(liquid.amount-fire_ratio_1,0) - carbon_dioxide += fire_ratio_1 - if(liquid.amount <= 0) - del liquid - return 1 - return 0 \ No newline at end of file + //Always check these damage procs first if fire damage isn't working. They're probably what's wrong. + + apply_damage(2.5*mx*head_exposure, BURN, "head", 0, 0, "Fire") + apply_damage(2.5*mx*chest_exposure, BURN, "chest", 0, 0, "Fire") + apply_damage(2.0*mx*groin_exposure, BURN, "groin", 0, 0, "Fire") + apply_damage(0.6*mx*legs_exposure, BURN, "l_leg", 0, 0, "Fire") + apply_damage(0.6*mx*legs_exposure, BURN, "r_leg", 0, 0, "Fire") + apply_damage(0.4*mx*arms_exposure, BURN, "l_arm", 0, 0, "Fire") + apply_damage(0.4*mx*arms_exposure, BURN, "r_arm", 0, 0, "Fire") + + flash_pain() \ No newline at end of file diff --git a/code/ZAS/Functions.dm b/code/ZAS/Functions.dm index ab52842dd1f..548289ade07 100644 --- a/code/ZAS/Functions.dm +++ b/code/ZAS/Functions.dm @@ -48,15 +48,29 @@ turf/proc/HasDoor(turf/O) return 1 turf/proc/find_zone() + if(world.time < 10) return for(var/d in cardinal) var/turf/T = get_step(src,d) - if(!T || !T.zone) continue + if(!T || !T.zone || !T.ZCanPass(src)) continue if(!zone) zone = T.zone zone.AddTurf(src) else if(T.zone != zone) ZConnect(src,T) +turf/proc/check_connections() + for(var/d in cardinal) + var/turf/T = get_step(src,d) + if(!T || !T.zone || !T.CanPass(0,src,0,0)) continue + if(T.zone != zone) + ZConnect(src,T) + +turf/proc/check_for_space() + for(var/d in cardinal) + var/turf/T = get_step(src,d) + if(istype(T,/turf/space) && T.CanPass(0,src,0,0)) + zone.AddSpace(T) + proc ZMerge(zone/A,zone/B) //world << "Merge occured." @@ -78,6 +92,7 @@ proc if((C.A in new_contents) && (C.B in new_contents)) del C continue + if(!A.connections) A.connections = list() A.connections += C A.space_tiles += B.space_tiles A.contents = new_contents @@ -93,7 +108,7 @@ proc return if(istype(A,/turf/space)) if(B.zone) - B.zone.AddSpace(B) + B.zone.AddSpace(A) //world << "Space added." return if(!A.zone || !B.zone) return @@ -124,7 +139,7 @@ proc A.overlays -= 'zone_connection_A.dmi' B.overlays -= 'zone_connection_B.dmi'*/ del C - /*else + else if(A == B) return if(A.CanPass(0,B,0,0)) return if(A.HasDoor(B) || B.HasDoor(A)) return @@ -137,6 +152,8 @@ proc if((A in Z.contents) || (B in Z.contents)) if(!Z.connections) Z.connections = list() Z.connections += C + for(var/turf/T in test) + T.check_for_space() var/datum/gas_mixture/Y_Air = new Y_Air.copy_from(oldzone.air) var/zone/Y = new(B,Y_Air) @@ -144,14 +161,11 @@ proc if((A in Y.contents) || (B in Y.contents)) if(!Y.connections) Y.connections = list() Y.connections += C + for(var/turf/space/T in oldzone.space_tiles) + if(!(T in Z.space_tiles)) + Y.AddSpace(T) oldzone.air = null del oldzone - world << "Zone Split: [A] / [B]" - A.overlays += 'zone_connection_A.dmi' - B.overlays += 'zone_connection_B.dmi' - spawn(10) - A.overlays -= 'zone_connection_A.dmi' - B.overlays -= 'zone_connection_B.dmi'*/ else if(istype(A,/turf/space) && B.zone) B.zone.RemoveSpace(A) diff --git a/code/ZAS/Plasma.dm b/code/ZAS/Plasma.dm index df25a974578..ab7f452fa9e 100644 --- a/code/ZAS/Plasma.dm +++ b/code/ZAS/Plasma.dm @@ -3,17 +3,12 @@ pl_control/var PLASMA_DMG_NAME = "Plasma Damage Multiplier" PLASMA_DMG_DESC = "Multiplier on how much damage inhaling plasma can do." - OXY_TO_PLASMA = 1 - OXY_TO_PLASMA_NAME = "O2/Plasma Ratio" - OXY_TO_PLASMA_DESC = "Multiplier for the ratio of oxygen to plasma required in fires." - - CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth. + CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth. CLOTH_CONTAMINATION_NAME = "Plasma - Cloth Contamination" CLOTH_CONTAMINATION_RANDOM = 60 CLOTH_CONTAMINATION_METHOD = "Toggle" CLOTH_CONTAMINATION_DESC = "If set to nonzero, plasma will contaminate cloth items (uniforms, backpacks, etc.)\ - and cause a small amount of damage over time to anyone carrying or wearing them. Contamination can be detected\ - with a Health Analyzer, and washed off in the washer." + and cause a small amount of damage over time to anyone carrying or wearing them. Contamination can be washed off in the washer." ALL_ITEM_CONTAMINATION = 0 //If this is on, any item can be contaminated, so suits and tools must be discarded or //decontaminated. @@ -48,7 +43,7 @@ pl_control/var //PLASMA_INJECTS_TOXINS_RANDOM = 30 //PLASMA_INJECTS_TOXINS_METHOD = "Toggle" - EYE_BURNS = 0 //Plasma burns the eyes of anyone not wearing eye protection. + EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection. EYE_BURNS_NAME = "Plasma - Eye Burns" EYE_BURNS_RANDOM = 30 EYE_BURNS_METHOD = "Toggle" @@ -66,8 +61,8 @@ pl_control/var //PLASMA_DMG_QUOTIENT = 10 //PLASMA_DMG_QUOTIENT_RANDOM = "1d10+4" - CONTAMINATION_LOSS = 0.1 - _NAME = "Plasma - Contamination Damage" + CONTAMINATION_LOSS = 0.01 + CONTAMINATION_LOSS_NAME = "Plasma - Contamination Damage" CONTAMINATION_LOSS_DESC = "A number representing the damage done per life cycle by contaminated items." PLASMA_HALLUCINATION = 1 @@ -93,160 +88,102 @@ obj/item/proc else if(istype(src,/obj/item/clothing)) return 1 else if(istype(src,/obj/item/weapon/storage/backpack)) return 1 -/mob/living/carbon/human/proc/contaminate() + contaminate() + if(!contaminated) + contaminated = 1 + overlays += 'icons/effects/contamination.dmi' + + decontaminate() + contaminated = 0 + overlays -= 'icons/effects/contamination.dmi' + +/mob/proc/contaminate() + +/mob/living/carbon/human/contaminate() if(!pl_suit_protected()) suit_contamination() - else if(vsc.plc.PLASMAGUARD_ONLY) - if(!wear_suit.flags & PLASMAGUARD) wear_suit.contaminated = 1 - - if(!pl_head_protected()) - if(wear_mask) wear_mask.contaminated = 1 if(prob(1)) suit_contamination() //Plasma can sometimes get through such an open suit. - else if(vsc.plc.PLASMAGUARD_ONLY) - if(!head.flags & PLASMAGUARD) head.contaminated = 1 - if(istype(back,/obj/item/weapon/storage/backpack) || vsc.plc.ALL_ITEM_CONTAMINATION) - back.contaminated = 1 + if(istype(back,/obj/item/weapon/storage/backpack)) + back.contaminate() - if(l_hand) - if(l_hand.can_contaminate()) l_hand.contaminated = 1 + /*if(l_hand) + if(l_hand.can_contaminate()) l_hand.contaminate() if(r_hand) - if(r_hand.can_contaminate()) r_hand.contaminated = 1 + if(r_hand.can_contaminate()) r_hand.contaminate() if(belt) - if(belt.can_contaminate()) belt.contaminated = 1 - if(wear_id && !pl_suit_protected()) - if(wear_id.can_contaminate()) wear_id.contaminated = 1 - if(l_ear && !pl_head_protected()) - if(l_ear.can_contaminate()) l_ear.contaminated = 1 - if(r_ear && !pl_head_protected()) - if(r_ear.can_contaminate()) r_ear.contaminated = 1 + if(belt.can_contaminate()) belt.contaminate()*/ -/mob/living/carbon/human/proc/pl_effects() +/mob/proc/pl_effects() + +/mob/living/carbon/human/pl_effects() + if(vsc.plc.CLOTH_CONTAMINATION) contaminate() if(stat >= 2) return if(vsc.plc.SKIN_BURNS) if(!pl_head_protected() || !pl_suit_protected()) burn_skin(0.75) - if (coughedtime != 1) - coughedtime = 1 - emote("gasp") - spawn (20) - coughedtime = 0 + if(prob(20)) src << "\red Your skin burns!" updatehealth() - if(vsc.plc.EYE_BURNS && !pl_head_protected()) - if(!wear_mask) - if(prob(20)) usr << "\red Your eyes burn!" - eye_stat += 2.5 - eye_blurry += 1.5 - if (eye_stat >= 20 && !(disabilities & 1)) - src << "\red Your eyes start to burn badly!" - disabilities |= 1 - if (prob(max(0,eye_stat - 20) + 1)) - src << "\red You are blinded!" - eye_blind += 20 - eye_stat = max(eye_stat-25,0) + + if(vsc.plc.EYE_BURNS) + if(!head) + if(!wear_mask) + burn_eyes() + else + if(!(wear_mask.flags & MASKCOVERSEYES)) + burn_eyes() else - if(!(wear_mask.flags & MASKCOVERSEYES)) - if(prob(20)) usr << "\red Your eyes burn!" - eye_stat += 2.5 - eye_blurry = min(eye_blurry+1.5,50) - if (eye_stat >= 20 && !(disabilities & 1)) - src << "\red Your eyes start to burn badly!" - disabilities |= 1 - if (prob(max(0,eye_stat - 20) + 1) &&!eye_blind) - src << "\red You are blinded!" - eye_blind += 20 - eye_stat = 0 + if(!(head.flags & MASKCOVERSEYES)) + if(!wear_mask) + burn_eyes() + else + if(!(wear_mask.flags & MASKCOVERSEYES)) + burn_eyes() + if(vsc.plc.GENETIC_CORRUPTION) - if(rand(1,1000) < vsc.plc.GENETIC_CORRUPTION) + if(rand(1,10000) < vsc.plc.GENETIC_CORRUPTION) randmutb(src) src << "\red High levels of toxins cause you to spontaneously mutate." domutcheck(src,null) -/mob/living/carbon/human/proc/FireBurn(mx as num) - //NO! NOT INTO THE PIT! IT BURRRRRNS! - mx *= vsc.BURN_DMG - - var - head_exposure = 1 - chest_exposure = 1 - groin_exposure = 1 - legs_exposure = 1 - feet_exposure = 1 - arms_exposure = 1 - hands_exposure = 1 - for(var/obj/item/clothing/C in src) - if(l_hand == C || r_hand == C) continue - if(C.body_parts_covered & HEAD) - head_exposure *= C.heat_transfer_coefficient - if(C.body_parts_covered & UPPER_TORSO) - chest_exposure *= C.heat_transfer_coefficient - if(C.body_parts_covered & LOWER_TORSO) - groin_exposure *= C.heat_transfer_coefficient - if(C.body_parts_covered & LEGS) - legs_exposure *= C.heat_transfer_coefficient - if(C.body_parts_covered & FEET) - feet_exposure *= C.heat_transfer_coefficient - if(C.body_parts_covered & ARMS) - arms_exposure *= C.heat_transfer_coefficient - if(C.body_parts_covered & HANDS) - arms_exposure *= C.heat_transfer_coefficient - - mx *= 10 - - apply_damage("head", 0, 2.5*mx*head_exposure) - apply_damage("chest", 0, 2.5*mx*chest_exposure) - apply_damage("groin", 0, 2.0*mx*groin_exposure) - apply_damage("l_leg", 0, 0.6*mx*legs_exposure) - apply_damage("r_leg", 0, 0.6*mx*legs_exposure) - apply_damage("l_arm", 0, 0.4*mx*arms_exposure) - apply_damage("r_arm", 0, 0.4*mx*arms_exposure) - apply_damage("l_foot", 0, 0.25*mx*feet_exposure) - apply_damage("r_foot", 0, 0.25*mx*feet_exposure) - apply_damage("l_hand", 0, 0.25*mx*hands_exposure) - apply_damage("r_hand", 0, 0.25*mx*hands_exposure) - -/mob/living/carbon/human/proc/suit_interior() - . = list() - if(!pl_suit_protected()) - for(var/obj/item/I in src) - . += I - return . - . += wear_mask - . += w_uniform - . += shoes - . += gloves - if(!pl_head_protected()) - . += head +/mob/living/carbon/human/proc/burn_eyes() + if(prob(20)) src << "\red Your eyes burn!" + eye_stat += 2.5 + eye_blurry = min(eye_blurry+1.5,50) + if (prob(max(0,eye_stat - 20) + 1) &&!eye_blind) + src << "\red You are blinded!" + eye_blind += 20 + eye_stat = 0 /mob/living/carbon/human/proc/pl_head_protected() if(head) - if(head.flags & PLASMAGUARD || head.flags & HEADSPACE) return 1 + if(vsc.plc.PLASMAGUARD_ONLY) + if(head.flags & PLASMAGUARD || head.flags & HEADSPACE) return 1 + else + if(head.flags & HEADCOVERSEYES) return 1 return 0 /mob/living/carbon/human/proc/pl_suit_protected() if(wear_suit) - if(wear_suit.flags & PLASMAGUARD || wear_suit.flags & SUITSPACE) return 1 + if(vsc.plc.PLASMAGUARD_ONLY) + if(wear_suit.flags & PLASMAGUARD || wear_suit.flags & SUITSPACE) return 1 + else + if(wear_suit.flags_inv & HIDEJUMPSUIT) return 1 return 0 /mob/living/carbon/human/proc/suit_contamination() - if(vsc.plc.ALL_ITEM_CONTAMINATION) - for(var/obj/item/I in src) - I.contaminated = 1 - else - if(wear_suit) wear_suit.contaminated = 1 - if(w_uniform) w_uniform.contaminated = 1 - if(shoes) shoes.contaminated = 1 - if(gloves) gloves.contaminated = 1 - if(wear_mask) wear_mask.contaminated = 1 + if(w_uniform) w_uniform.contaminate() + if(shoes) shoes.contaminate() + if(gloves) gloves.contaminate() turf/Entered(obj/item/I) . = ..() - if(istype(I)) + if(istype(I) && vsc.plc.CLOTH_CONTAMINATION) var/datum/gas_mixture/env = return_air(1) - if(env.toxins > 0.35) + if(env.toxins > MOLES_PLASMA_VISIBLE + 1) if(I.can_contaminate()) - I.contaminated = 1 \ No newline at end of file + I.contaminate() \ No newline at end of file diff --git a/code/ZAS/Processing.dm b/code/ZAS/Processing.dm index 4de6c939860..8423ae46af8 100644 --- a/code/ZAS/Processing.dm +++ b/code/ZAS/Processing.dm @@ -26,55 +26,39 @@ zone Z.air.copy_from(air) rebuild = 0 - var/total_space = 0 - var/turf/space/space + if(!air) + air = new() + air.adjustGases(MOLES_O2STANDARD, 0, MOLES_N2STANDARD, 0, list()) + world.log << "Air object lost in zone. Regenerating." - if(length(connected_zones)) - for(var/zone/Z in connected_zones) - total_space += length(Z.space_tiles) - if(length(Z.space_tiles)) - space = Z.space_tiles[1] + var/total_space = 0 if(space_tiles) for(var/T in space_tiles) if(!istype(T,/turf/space)) space_tiles -= T - total_space += length(space_tiles) - if(length(space_tiles)) - space = space_tiles[1] + total_space = length(space_tiles) - if(total_space && space) - var/old_pressure = air.return_pressure() - air.temperature_mimic(space,OPEN_HEAT_TRANSFER_COEFFICIENT,total_space) - air.remove(MOLES_CELLSTANDARD * (air.group_multiplier/40) * total_space) - if(dbg_output) world << "Space removed [MOLES_CELLSTANDARD*(air.group_multiplier/40)*total_space] moles of air." - var/p_diff = old_pressure - air.return_pressure() - if(p_diff > vsc.AF_TINY_MOVEMENT_THRESHOLD) AirflowSpace(src,p_diff) + if(total_space) // SPAAAAAAAAAACE + //var/old_pressure = air.pressure + ShareSpace(air,total_space*(vsc.zone_share_percent/100)) + //var/p_diff = old_pressure - air.pressure + //if(p_diff > vsc.AF_TINY_MOVEMENT_THRESHOLD) AirflowSpace(src,p_diff) air.react(null,0) var/check = air.check_tile_graphic() - for(var/turf/T in contents) - if(T.zone && T.zone != src) - RemoveTurf(T) - if(dbg_output) world << "Removed invalid turf." - if(air.group_multiplier <= 0) // No more turfs belong to this zone, so we can get rid of it - del(src) - else // Turf was valid, so we can handle it - if(!T.zone) - T.zone = src - if(istype(T,/turf/simulated)) - var/turf/simulated/S = T - if(S.fire_protection) S.fire_protection-- - if(check) - if(S.HasDoor(1)) - S.update_visuals() - else - S.update_visuals(air) + if(check || air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + for(var/turf/simulated/S in contents) + if(check) + if(S.HasDoor(1)) + S.update_visuals() + else + S.update_visuals(air) - if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) - for(var/atom/movable/item in S) - item.temperature_expose(air, air.temperature, CELL_VOLUME) - S.temperature_expose(air, air.temperature, CELL_VOLUME) + if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + for(var/atom/movable/item in S) + item.temperature_expose(air, air.temperature, CELL_VOLUME) + S.temperature_expose(air, air.temperature, CELL_VOLUME) air.graphic_archived = air.graphic @@ -83,13 +67,114 @@ zone if(length(connections)) for(var/connection/C in connections) C.Cleanup() - if(C && !C.indirect) - if(C.A.zone.air.compare(C.B.zone.air)) + if(C && !C.indirect && C.A.zone && C.B.zone) + if(C.A.zone.air.compare(C.B.zone.air) || total_space) ZMerge(C.A.zone,C.B.zone) for(var/zone/Z in connected_zones) - var/p_diff = (air.return_pressure()-Z.air.return_pressure())*connected_zones[Z]*(vsc.zone_share_percent/100) - if(p_diff > vsc.AF_TINY_MOVEMENT_THRESHOLD) Airflow(src,Z,p_diff) - air.share_ratio(Z.air,connected_zones[Z]*(vsc.zone_share_percent/100)) + //var/p_diff = (air.return_pressure()-Z.air.return_pressure())*connected_zones[Z]*(vsc.zone_share_percent/100) + //if(p_diff > vsc.AF_TINY_MOVEMENT_THRESHOLD) Airflow(src,Z,p_diff) + ShareRatio(air,Z.air,connected_zones[Z]*(vsc.zone_share_percent/100)) + +proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, ratio) + var + size = max(1,A.group_multiplier) + share_size = max(1,B.group_multiplier) + + full_oxy = A.oxygen * size + full_nitro = A.nitrogen * size + full_co2 = A.carbon_dioxide * size + full_plasma = A.toxins * size + + full_thermal = A.temperature * A.heat_capacity() * size + + s_full_oxy = B.oxygen * share_size + s_full_nitro = B.nitrogen * share_size + s_full_co2 = B.carbon_dioxide * share_size + s_full_plasma = B.toxins * share_size + + s_full_thermal = B.temperature * B.heat_capacity() * share_size + + oxy_avg = (full_oxy + s_full_oxy) / (size + share_size) + nit_avg = (full_nitro + s_full_nitro) / (size + share_size) + co2_avg = (full_co2 + s_full_co2) / (size + share_size) + plasma_avg = (full_plasma + s_full_plasma) / (size + share_size) + + thermal_avg = (full_thermal + s_full_thermal) / (size+share_size) + + A.oxygen = (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg + A.nitrogen = (A.nitrogen - nit_avg) * (1-ratio) + nit_avg + A.carbon_dioxide = (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg + A.toxins = (A.toxins - plasma_avg) * (1-ratio) + plasma_avg + + B.oxygen = (B.oxygen - oxy_avg) * (1-ratio) + oxy_avg + B.nitrogen = (B.nitrogen - nit_avg) * (1-ratio) + nit_avg + B.carbon_dioxide = (B.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg + B.toxins = (B.toxins - plasma_avg) * (1-ratio) + plasma_avg + + var + thermal = (full_thermal/size - thermal_avg) * (1-ratio) + thermal_avg + sharer_thermal = (s_full_thermal/share_size - thermal_avg) * (1-ratio) + thermal_avg + + A.temperature = thermal / (A.heat_capacity() == 0 ? MINIMUM_HEAT_CAPACITY : A.heat_capacity()) + + B.temperature = sharer_thermal / (B.heat_capacity() == 0 ? MINIMUM_HEAT_CAPACITY : B.heat_capacity()) + + for(var/datum/gas/G in A.trace_gases) + var/datum/gas/H = locate(G.type) in B.trace_gases + if(H) + var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + else + H = new G.type + B.trace_gases += H + var/G_avg = (G.moles*size) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + H.moles = (H.moles - G_avg) * (1-ratio) + G_avg + + A.update_values() + B.update_values() + + if(A.compare(B)) return 1 + else return 0 + + /* See? Now that's how it's done. */ + +proc/ShareSpace(datum/gas_mixture/A, ratio) + var + size = max(1,A.group_multiplier) + share_size = 2000 //A huge value because space is huge. + + full_oxy = A.oxygen * size + full_nitro = A.nitrogen * size + full_co2 = A.carbon_dioxide * size + full_plasma = A.toxins * size + + full_thermal = A.temperature * A.heat_capacity() * size + + oxy_avg = (full_oxy + 0) / (size + share_size) + nit_avg = (full_nitro + 0.2) / (size + share_size) + co2_avg = (full_co2 + 0) / (size + share_size) + plasma_avg = (full_plasma + 0) / (size + share_size) + + thermal_avg = (full_thermal + MINIMUM_HEAT_CAPACITY) / (size+share_size) + + A.oxygen = (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg + A.nitrogen = (A.nitrogen - nit_avg) * (1-ratio) + nit_avg + A.carbon_dioxide = (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg + A.toxins = (A.toxins - plasma_avg) * (1-ratio) + plasma_avg + + var/thermal = (full_thermal/size - thermal_avg) * (1-ratio) + thermal_avg + + A.temperature = thermal / (A.heat_capacity() == 0 ? MINIMUM_HEAT_CAPACITY : A.heat_capacity()) + + for(var/datum/gas/G in A.trace_gases) + var/G_avg = (G.moles*size + 0) / (size+share_size) + G.moles = (G.moles - G_avg) * (1-ratio) + G_avg + + A.update_values() + + return 1 zone/proc diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm index 188f885ae9b..226e38c1223 100644 --- a/code/ZAS/Variable Settings.dm +++ b/code/ZAS/Variable Settings.dm @@ -133,6 +133,8 @@ vs_control plc.EYE_BURNS = 0 //Plasma burns the eyes of anyone not wearing eye protection. + plc.PLASMA_HALLUCINATION = 0 + //plc.N2O_REACTION = 0 //Plasma can react with N2O, making sparks and starting a fire if levels are high. //plc.PLASMA_COLOR = "onturf" //Plasma can change colors yaaaay! @@ -141,8 +143,8 @@ vs_control //plc.PLASMA_DMG_QUOTIENT = 10 plc.CONTAMINATION_LOSS = 0 - if("Hazard-Low") - plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth. + if("Hazard - Low") + plc.CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth. plc.ALL_ITEM_CONTAMINATION = 0 //If this is on, any item can be contaminated, so suits and tools must be discarded or @@ -152,7 +154,7 @@ vs_control plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000. - plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited. + plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited. // plc.PLASMA_INJECTS_TOXINS = 0 //Plasma damage injects the toxins chemical to do damage over time. @@ -168,12 +170,9 @@ vs_control //plc.PLASMA_DMG_OFFSET = 1.5 //plc.PLASMA_DMG_QUOTIENT = 8 - plc.CONTAMINATION_LOSS = 0.01 + plc.CONTAMINATION_LOSS = 0 - var/s = pick(plc.settings) - plc.Randomize(s) - - if("Hazard-High") + if("Hazard - High") plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth. plc.ALL_ITEM_CONTAMINATION = 0 //If this is on, any item can be contaminated, so suits and tools must be discarded or @@ -184,11 +183,11 @@ vs_control plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000. - plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited. + plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited. // plc.PLASMA_INJECTS_TOXINS = 0 //Plasma damage injects the toxins chemical to do damage over time. - plc.EYE_BURNS = 0 //Plasma burns the eyes of anyone not wearing eye protection. + plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection. // plc.N2O_REACTION = 0 //Plasma can react with N2O, making sparks and starting a fire if levels are high. @@ -197,16 +196,10 @@ vs_control //plc.PLASMA_DMG_OFFSET = 3 //plc.PLASMA_DMG_QUOTIENT = 5 - plc.CONTAMINATION_LOSS = 0.05 - - for(var/i = rand(3,5),i>0,i--) - var/s = pick(plc.settings) - plc.Randomize(s) - - if("Everything") + if("Oh Shit!") plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth. - plc.ALL_ITEM_CONTAMINATION = 1 //If this is on, any item can be contaminated, so suits and tools must be discarded or ELSE + plc.ALL_ITEM_CONTAMINATION = 0 //If this is on, any item can be contaminated, so suits and tools must be discarded or ELSE plc.PLASMAGUARD_ONLY = 1 @@ -227,7 +220,6 @@ vs_control //plc.PLASMA_DMG_OFFSET = 3 //plc.PLASMA_DMG_QUOTIENT = 5 - plc.CONTAMINATION_LOSS = 0.02 /////world << "Plasma color updated." pl_control diff --git a/code/defines/atom.dm b/code/defines/atom.dm index d725f656503..1a1a79b94f8 100644 --- a/code/defines/atom.dm +++ b/code/defines/atom.dm @@ -17,7 +17,7 @@ // replaced by OPENCONTAINER flags and atom/proc/is_open_container() ///Chemistry. - proc/assume_air(datum/air_group/giver) + proc/assume_air(datum/gas_mixture/giver) del(giver) return null @@ -48,7 +48,7 @@ */ obj - assume_air(datum/air_group/giver) + assume_air(datum/gas_mixture/giver) if(loc) return loc.assume_air(giver) else diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index e128be4cf8c..c04bb4ca00e 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -1561,19 +1561,13 @@ proc/listclearnulls(list/list) for(var/turf/simulated/T1 in toupdate) for(var/obj/machinery/door/D2 in T1) doors += D2 - if(T1.parent) - air_master.groups_to_rebuild += T1.parent - else - air_master.tiles_to_update += T1 + air_master.tiles_to_update += T1 if(fromupdate.len) for(var/turf/simulated/T2 in fromupdate) for(var/obj/machinery/door/D2 in T2) doors += D2 - if(T2.parent) - air_master.groups_to_rebuild += T2.parent - else - air_master.tiles_to_update += T2 + air_master.tiles_to_update += T2 for(var/obj/O in doors) O:update_nearby_tiles(1) @@ -1728,10 +1722,7 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) for(var/turf/simulated/T1 in toupdate) for(var/obj/machinery/door/D2 in T1) doors += D2 - if(T1.parent) - air_master.groups_to_rebuild += T1.parent - else - air_master.tiles_to_update += T1 + air_master.tiles_to_update += T1 for(var/obj/O in doors) O:update_nearby_tiles(1) diff --git a/code/defines/turf.dm b/code/defines/turf.dm index 4fc3dfa963c..3eb764e5c6a 100644 --- a/code/defines/turf.dm +++ b/code/defines/turf.dm @@ -341,8 +341,6 @@ proc/TemperatureAct(temperature) for(var/turf/simulated/floor/target_tile in range(2,loc)) - if(target_tile.parent && target_tile.parent.group_processing) - target_tile.parent.suspend_group_processing() var/datum/gas_mixture/napalm = new diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index fb7b3c6a1b3..aa51784a615 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -267,12 +267,12 @@ if (src.operating) return src.operating = 1 - + var/X = src:x var/Y = src:y var/Z = src:z var/held = 1 - + if(src.holdopen && !forcecrush) while(held == 1 && holdopen && !forcecrush) //If it is no longer hold open, it should close. sleep(held? 10:40) @@ -288,25 +288,25 @@ spawn(4) if(!istype(src, /obj/machinery/door/window)) for(var/mob/living/L in src.loc) // Crush mobs and move them out of the way - + if(src.forcecrush) // Save an AI, crush a limb var/limbname = pick("l_arm", "r_arm", "l_hand","r_hand", "l_foot", "r_foot") var/limbdisplay - + for(var/organ in L:organs) var/datum/organ/external/temp = L:organs["[organ]"] if (istype(temp, /datum/organ/external) && temp.name == limbname) limbdisplay = temp.display_name // Take the name for down below temp.take_damage(rand(50,80), 0) //OH GOD IT HURTS break - + L << "\red The airlock crushes your [limbdisplay]!" for(var/mob/O in viewers(L, null)) if(O == L) continue O.show_message("\red The airlock crushes [L.name]'s [limbdisplay]!", 1) sleep(rand(2,8)) - + L << "\red The airlock forces you out of the way!" //Lucky you for(var/mob/O in viewers(L, null)) O.show_message("\red The airlock pushes [L.name] out of the way!", 1) @@ -314,7 +314,7 @@ var/turf/T = get_random_turf(L, lst) if(T) L.loc = T - + if(!src.forcecrush) for(var/obj/item/I in src.loc) // Move items out of the way if(!I.anchored) @@ -322,10 +322,10 @@ var/turf/T = get_random_turf(I, lst) if(T) I.loc = T - + sleep(6) update_icon() - + if(src.visible && (!src.glass)) src.sd_SetOpacity(1) if(operating == 1) @@ -343,38 +343,11 @@ var/turf/simulated/east = get_step(source,EAST) var/turf/simulated/west = get_step(source,WEST) - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(north)) - if(north.parent) - air_master.groups_to_rebuild += north.parent - else - air_master.tiles_to_update += north - if(istype(south)) - if(south.parent) - air_master.groups_to_rebuild += south.parent - else - air_master.tiles_to_update += south - if(istype(east)) - if(east.parent) - air_master.groups_to_rebuild += east.parent - else - air_master.tiles_to_update += east - if(istype(west)) - if(west.parent) - air_master.groups_to_rebuild += west.parent - else - air_master.tiles_to_update += west - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(north)) air_master.tiles_to_update += north - if(istype(south)) air_master.tiles_to_update += south - if(istype(east)) air_master.tiles_to_update += east - if(istype(west)) air_master.tiles_to_update += west + if(istype(source)) air_master.tiles_to_update += source + if(istype(north)) air_master.tiles_to_update += north + if(istype(south)) air_master.tiles_to_update += south + if(istype(east)) air_master.tiles_to_update += east + if(istype(west)) air_master.tiles_to_update += west return 1 diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 41462f0b0ce..efb86ae369e 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -110,18 +110,6 @@ var/turf/simulated/source = loc var/turf/simulated/destination = get_step(source,dir) - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(destination)) - if(destination.parent) - air_master.groups_to_rebuild += destination.parent - else - air_master.tiles_to_update += destination - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(destination)) air_master.tiles_to_update += destination + if(istype(source)) air_master.tiles_to_update += source + if(istype(destination)) air_master.tiles_to_update += destination return 1 \ No newline at end of file diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 50baa203d0d..27967591d0d 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -15,20 +15,8 @@ var/turf/simulated/source = loc var/turf/simulated/target = get_step(source,dir) - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(target)) - if(target.parent) - air_master.groups_to_rebuild += target.parent - else - air_master.tiles_to_update += target - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(target)) air_master.tiles_to_update += target + if(istype(source)) air_master.tiles_to_update += source + if(istype(target)) air_master.tiles_to_update += target return 1 diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 9bb05f46583..6050615cdcc 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -408,38 +408,11 @@ var/turf/simulated/east = get_step(source,EAST) var/turf/simulated/west = get_step(source,WEST) - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(north)) - if(north.parent) - air_master.groups_to_rebuild += north.parent - else - air_master.tiles_to_update += north - if(istype(south)) - if(south.parent) - air_master.groups_to_rebuild += south.parent - else - air_master.tiles_to_update += south - if(istype(east)) - if(east.parent) - air_master.groups_to_rebuild += east.parent - else - air_master.tiles_to_update += east - if(istype(west)) - if(west.parent) - air_master.groups_to_rebuild += west.parent - else - air_master.tiles_to_update += west - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(north)) air_master.tiles_to_update += north - if(istype(south)) air_master.tiles_to_update += south - if(istype(east)) air_master.tiles_to_update += east - if(istype(west)) air_master.tiles_to_update += west + if(istype(source)) air_master.tiles_to_update += source + if(istype(north)) air_master.tiles_to_update += north + if(istype(south)) air_master.tiles_to_update += south + if(istype(east)) air_master.tiles_to_update += east + if(istype(west)) air_master.tiles_to_update += west return 1 diff --git a/code/game/objects/closets/firecloset.dm b/code/game/objects/closets/firecloset.dm index be3571a83f1..c3a6ad2fbc5 100644 --- a/code/game/objects/closets/firecloset.dm +++ b/code/game/objects/closets/firecloset.dm @@ -8,7 +8,7 @@ new /obj/item/device/flashlight(src) new /obj/item/weapon/tank/oxygen/red(src) new /obj/item/weapon/extinguisher(src) - new /obj/item/clothing/head/helmet/hardhat/red(src) + new /obj/item/clothing/head/helmet/space/fire_helmet(src) /obj/structure/closet/firecloset/New() ..() @@ -17,7 +17,7 @@ new /obj/item/clothing/mask/gas(src) new /obj/item/weapon/tank/oxygen/red(src) new /obj/item/weapon/extinguisher(src) - new /obj/item/clothing/head/helmet/hardhat/red(src) + new /obj/item/clothing/head/helmet/space/fire_helmet(src) /*switch (pickweight(list("nothing" = 5, "bare-bones" = 35, "basic" = 40, "pickpocketed" = 10, "untouched" = 10))) if ("nothing") diff --git a/code/game/objects/effect_system.dm b/code/game/objects/effect_system.dm index c661ae8a725..1b449b6fc94 100644 --- a/code/game/objects/effect_system.dm +++ b/code/game/objects/effect_system.dm @@ -1050,38 +1050,11 @@ steam.start() -- spawns the effect var/turf/simulated/east = get_step(source,EAST) var/turf/simulated/west = get_step(source,WEST) - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(north)) - if(north.parent) - air_master.groups_to_rebuild += north.parent - else - air_master.tiles_to_update += north - if(istype(south)) - if(south.parent) - air_master.groups_to_rebuild += south.parent - else - air_master.tiles_to_update += south - if(istype(east)) - if(east.parent) - air_master.groups_to_rebuild += east.parent - else - air_master.tiles_to_update += east - if(istype(west)) - if(west.parent) - air_master.groups_to_rebuild += west.parent - else - air_master.tiles_to_update += west - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(north)) air_master.tiles_to_update += north - if(istype(south)) air_master.tiles_to_update += south - if(istype(east)) air_master.tiles_to_update += east - if(istype(west)) air_master.tiles_to_update += west + if(istype(source)) air_master.tiles_to_update += source + if(istype(north)) air_master.tiles_to_update += north + if(istype(south)) air_master.tiles_to_update += south + if(istype(east)) air_master.tiles_to_update += east + if(istype(west)) air_master.tiles_to_update += west return 1 diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 7ed926c801d..f976d3ee999 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -236,8 +236,10 @@ /obj/item/weapon/flamethrower/proc/ignite_turf(turf/target) //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... //Transfer 5% of current tank air contents to turf - var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.05*throw_amount/100) - air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE + var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.02*(throw_amount/100)) + //air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE + new/obj/liquid_fuel/flamethrower_fuel(target,air_transfer.toxins,get_dir(loc,target)) + air_transfer.toxins = 0 target.assume_air(air_transfer) //Burn it based on transfered gas //target.hotspot_expose(part4.air_contents.temperature*2,300) diff --git a/code/game/objects/mineral_doors.dm b/code/game/objects/mineral_doors.dm index 310cdfd8805..f99a8d395fe 100644 --- a/code/game/objects/mineral_doors.dm +++ b/code/game/objects/mineral_doors.dm @@ -145,38 +145,11 @@ var/turf/simulated/east = get_step(source,EAST) var/turf/simulated/west = get_step(source,WEST) - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(north)) - if(north.parent) - air_master.groups_to_rebuild += north.parent - else - air_master.tiles_to_update += north - if(istype(south)) - if(south.parent) - air_master.groups_to_rebuild += south.parent - else - air_master.tiles_to_update += south - if(istype(east)) - if(east.parent) - air_master.groups_to_rebuild += east.parent - else - air_master.tiles_to_update += east - if(istype(west)) - if(west.parent) - air_master.groups_to_rebuild += west.parent - else - air_master.tiles_to_update += west - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(north)) air_master.tiles_to_update += north - if(istype(south)) air_master.tiles_to_update += south - if(istype(east)) air_master.tiles_to_update += east - if(istype(west)) air_master.tiles_to_update += west + if(istype(source)) air_master.tiles_to_update += source + if(istype(north)) air_master.tiles_to_update += north + if(istype(south)) air_master.tiles_to_update += south + if(istype(east)) air_master.tiles_to_update += east + if(istype(west)) air_master.tiles_to_update += west return 1 @@ -225,8 +198,6 @@ proc/TemperatureAct(temperature) for(var/turf/simulated/floor/target_tile in range(2,loc)) - if(target_tile.parent && target_tile.parent.group_processing) - target_tile.parent.suspend_group_processing() var/datum/gas_mixture/napalm = new @@ -305,4 +276,4 @@ isSwitchingStates = 0 Dismantle(devastated = 0) - del(src) + del(src) diff --git a/code/game/objects/weapons.dm b/code/game/objects/weapons.dm index 6d04a7d4ea0..24be9eed502 100644 --- a/code/game/objects/weapons.dm +++ b/code/game/objects/weapons.dm @@ -30,8 +30,6 @@ for (var/turf/simulated/floor/target in range(1,src)) if(!target.blocks_air) - if(target.parent) - target.parent.suspend_group_processing() var/datum/gas_mixture/payload = new var/datum/gas/sleeping_agent/trace_gas = new @@ -48,8 +46,6 @@ /obj/effect/mine/proc/triggerplasma(obj) for (var/turf/simulated/floor/target in range(1,src)) if(!target.blocks_air) - if(target.parent) - target.parent.suspend_group_processing() var/datum/gas_mixture/payload = new diff --git a/code/game/objects/window.dm b/code/game/objects/window.dm index ee9871be0fc..f3e69130cf6 100644 --- a/code/game/objects/window.dm +++ b/code/game/objects/window.dm @@ -346,20 +346,8 @@ var/turf/simulated/source = loc var/turf/simulated/target = get_step(source,dir) - if(need_rebuild) - if(istype(source)) //Rebuild/update nearby group geometry - if(source.parent) - air_master.groups_to_rebuild += source.parent - else - air_master.tiles_to_update += source - if(istype(target)) - if(target.parent) - air_master.groups_to_rebuild += target.parent - else - air_master.tiles_to_update += target - else - if(istype(source)) air_master.tiles_to_update += source - if(istype(target)) air_master.tiles_to_update += target + if(istype(source)) air_master.tiles_to_update += source + if(istype(target)) air_master.tiles_to_update += target return 1 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 186fadd0ee8..8e8aceab534 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -144,7 +144,7 @@ verbs += /client/proc/voting verbs += /client/proc/hide_verbs verbs += /client/proc/general_report - verbs += /client/proc/air_report + //verbs += /client/proc/air_report verbs += /client/proc/deadmin_self //verbs += /client/proc/cmd_admin_prison --Merged with player panel //verbs += /obj/admins/proc/unprison --Merged with player panel @@ -248,7 +248,7 @@ // verbs += /client/proc/mapload verbs += /client/proc/check_words verbs += /client/proc/drop_bomb - verbs += /client/proc/kill_airgroup + //verbs += /client/proc/kill_airgroup //verbs += /client/proc/cmd_admin_drop_everything --Merged with view variables verbs += /client/proc/make_sound verbs += /client/proc/play_local_sound @@ -278,7 +278,7 @@ verbs += /client/proc/Force_Event_admin verbs += /client/proc/radioalert verbs += /client/proc/CarbonCopy - verbs += /client/proc/jump_to_dead_group + //verbs += /client/proc/jump_to_dead_group else return //Game Master @@ -403,7 +403,7 @@ verbs -= /client/proc/voting verbs -= /client/proc/hide_verbs verbs -= /client/proc/general_report - verbs -= /client/proc/air_report + //verbs -= /client/proc/air_report verbs -= /client/proc/cmd_admin_say verbs -= /client/proc/cmd_admin_gib_self verbs -= /client/proc/restartcontroller @@ -452,13 +452,13 @@ //verbs -= /obj/admins/proc/unprison --Merged with player panel //verbs -= /client/proc/cmd_switch_radio --removed because tcommsat is staying verbs -= /client/proc/togglebuildmodeself - verbs -= /client/proc/kill_airgroup + //verbs -= /client/proc/kill_airgroup verbs -= /client/proc/debug_master_controller verbs -= /client/proc/make_tajaran verbs -= /client/proc/admin_deny_shuttle verbs -= /client/proc/cmd_admin_christmas verbs -= /client/proc/editappear - verbs -= /client/proc/jump_to_dead_group + //verbs -= /client/proc/jump_to_dead_group verbs -= /client/proc/playernotes verbs -= /obj/admins/proc/show_skills verbs -= /client/proc/enable_debug_verbs diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index fa68b836d90..dc8c6371f53 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -22,7 +22,7 @@ usr << browse(output,"window=generalreport") //feedback_add_details("admin_verb","SGR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - air_report() +/* air_report() set category = "Debug" set name = "Show Air Report" @@ -83,7 +83,7 @@ for(var/datum/gas/trace_gas in GM.trace_gases) usr << "[trace_gas.type]: [trace_gas.moles]" //feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - +*/ fix_next_move() set category = "Debug" set name = "Unfreeze Everyone" @@ -183,7 +183,7 @@ //feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - jump_to_dead_group() + /*jump_to_dead_group() set name = "Jump to dead group" set category = "Debug" if(!holder) @@ -221,7 +221,7 @@ else usr << "Local airgroup is unsimulated!" //feedback_add_details("admin_verb","KLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - +*/ tension_report() set category = "Debug" diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index a899f823ddf..f319ebe5019 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -130,14 +130,14 @@ var/intercom_range_display_status = 0 src.verbs += /client/proc/camera_view //-errorage src.verbs += /client/proc/sec_camera_report //-errorage src.verbs += /client/proc/intercom_view //-errorage - src.verbs += /client/proc/air_status //Air things + //src.verbs += /client/proc/air_status //Air things src.verbs += /client/proc/Cell //More air things src.verbs += /client/proc/atmosscan //check plumbing src.verbs += /client/proc/powerdebug //check power src.verbs += /client/proc/count_objects_on_z_level src.verbs += /client/proc/count_objects_all src.verbs += /client/proc/cmd_assume_direct_control //-errorage - src.verbs += /client/proc/jump_to_dead_group + //src.verbs += /client/proc/jump_to_dead_group src.verbs += /client/proc/startSinglo src.verbs += /client/proc/ticklag //allows you to set the ticklag. src.verbs += /client/proc/cmd_admin_grantfullaccess diff --git a/code/modules/chemical/Chemistry-Recipes.dm b/code/modules/chemical/Chemistry-Recipes.dm index ad825ca068d..af599eced07 100644 --- a/code/modules/chemical/Chemistry-Recipes.dm +++ b/code/modules/chemical/Chemistry-Recipes.dm @@ -350,8 +350,6 @@ datum on_reaction(var/datum/reagents/holder, var/created_volume) var/turf/location = get_turf(holder.my_atom.loc) for(var/turf/simulated/floor/target_tile in range(0,location)) - if(target_tile.parent && target_tile.parent.group_processing) - target_tile.parent.suspend_group_processing() var/datum/gas_mixture/napalm = new diff --git a/code/modules/clothing/suits/fire.dm b/code/modules/clothing/suits/fire.dm index 42dc200379a..7f03617caa5 100644 --- a/code/modules/clothing/suits/fire.dm +++ b/code/modules/clothing/suits/fire.dm @@ -28,6 +28,18 @@ protective_temperature = 10000 slowdown = 1.5 +/obj/item/clothing/head/helmet/space/fire_helmet + name = "Fire Helmet" + desc = "A helmet designed to protect against fires in sealed areas, which often create extreme pressures." + flags = FPRINT | TABLEPASS | HEADSPACE | HEADCOVERSEYES | BLOCKHAIR + see_face = 0.0 + permeability_coefficient = 0.01 + heat_transfer_coefficient = 0.01 + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES + icon_state = "hazmat_firered" + item_state = "hazhat_firered" + /obj/item/clothing/head/radiation diff --git a/code/modules/mob/living/carbon/alien/humanoid/life.dm b/code/modules/mob/living/carbon/alien/humanoid/life.dm index edef1ab43a4..7a386ef417f 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/life.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/life.dm @@ -183,7 +183,7 @@ if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return var/datum/gas_mixture/environment = loc.return_air() - var/datum/air_group/breath + var/datum/gas_mixture/breath // HACK NEED CHANGING LATER if(src.health < 0) src.losebreath++ diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 23e9a6ca067..b35b9735434 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -158,7 +158,7 @@ if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return var/datum/gas_mixture/environment = loc.return_air() - var/datum/air_group/breath + var/datum/gas_mixture/breath // HACK NEED CHANGING LATER if(health < 0) losebreath++ diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b30bc302ceb..f091d8bf000 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -359,7 +359,7 @@ if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return var/datum/gas_mixture/environment = loc.return_air() - var/datum/air_group/breath + var/datum/gas_mixture/breath // HACK NEED CHANGING LATER if(isbreathing && health < config.health_threshold_crit) @@ -420,6 +420,14 @@ smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs? break // If they breathe in the nasty stuff once, no need to continue checking + if(istype(wear_mask, /obj/item/clothing/mask/gas)) + var/datum/gas_mixture/filtered = new() + filtered.toxins = breath.toxins + filtered.trace_gases = breath.trace_gases.Copy() + breath.toxins = 0 + breath.trace_gases = list() + loc.assume_air(filtered) + else //Still give containing object the chance to interact if(istype(loc, /obj/)) var/obj/location_as_object = loc @@ -469,7 +477,7 @@ var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa //var/safe_oxygen_max = 140 // Maximum safe partial pressure of O2, in kPa (Not used for now) var/safe_co2_max = 10 // Yes it's an arbitrary value who cares? - var/safe_toxins_max = 0.005 + var/safe_toxins_max = 0.0025 var/SA_para_min = 1 var/SA_sleep_min = 5 var/oxygen_used = 0 @@ -649,7 +657,7 @@ //Account for massive pressure differences. Done by Polymorph var/pressure = environment.return_pressure() - if(!istype(wear_suit, /obj/item/clothing/suit/space)) + if(!istype(wear_suit, /obj/item/clothing/suit/space) && !istype(wear_suit, /obj/item/clothing/suit/fire)) /*if(pressure < 20) if(prob(25)) src << "You feel the splittle on your lips and the fluid on your eyes boiling away, the capillteries in your skin breaking." @@ -658,6 +666,9 @@ if(pressure > HAZARD_HIGH_PRESSURE) adjustBruteLoss(min((10+(round(pressure/(HIGH_STEP_PRESSURE)-2)*5)),MAX_PRESSURE_DAMAGE)) + if(environment.toxins > MOLES_PLASMA_VISIBLE) + pl_effects() + return //TODO: DEFERRED adjust_body_temperature(current, loc_temp, boost) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 70489c1117a..e4baace6694 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -187,7 +187,7 @@ if(!loc) return //probably ought to make a proper fix for this, but :effort: --NeoFite var/datum/gas_mixture/environment = loc.return_air() - var/datum/air_group/breath + var/datum/gas_mixture/breath if(losebreath>0) //Suffocating so do not take a breath src.losebreath-- diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index aa829b0930e..c1067a0523a 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -40,14 +40,8 @@ return 0 var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part var/divided_damage = (burn_amount)/(H.organs.len) - var/extradam = 0 //added to when organ is at max dam for(var/name in H.organs) - var/datum/organ/external/affecting = H.organs[name] - if(!affecting) continue - if(affecting.take_damage(0, divided_damage+extradam, 0, used_weapon)) - extradam = 0 - else - extradam += divided_damage + apply_damage(divided_damage, BURN, name, 0, 0, "Skin Burns") H.UpdateDamageIcon() H.updatehealth() return 1 diff --git a/code/modules/mob/organ/organ.dm b/code/modules/mob/organ/organ.dm index 4070542e6c7..01155cbdbb8 100644 --- a/code/modules/mob/organ/organ.dm +++ b/code/modules/mob/organ/organ.dm @@ -104,7 +104,7 @@ burn *= 0.66 //~2/3 damage for ROBOLIMBS if(owner && !robot) - owner.pain(display_name, (brute+burn)*3, 1) + owner.pain(display_name, (brute+burn)*3, 1, burn > brute) if(sharp) var/nux = brute * rand(10,15) if(brute_dam >= max_damage) diff --git a/code/modules/mob/organ/pain.dm b/code/modules/mob/organ/pain.dm index 21825ce8eaa..3213b26ffae 100644 --- a/code/modules/mob/organ/pain.dm +++ b/code/modules/mob/organ/pain.dm @@ -7,7 +7,7 @@ mob/var/next_pain_time = 0 // partname is the name of a body part // amount is a num from 1 to 100 -mob/proc/pain(var/partname, var/amount, var/force) +mob/proc/pain(var/partname, var/amount, var/force, var/burning = 0) if(stat >= 2) return if(world.time < next_pain_time && !force) return @@ -17,15 +17,26 @@ mob/proc/pain(var/partname, var/amount, var/force) if(amount > 50 && prob(amount / 5)) src:drop_item() var/msg - switch(amount) - if(1 to 10) - msg = "Your [partname] hurts a bit." - if(11 to 90) - flash_weak_pain() - msg = "Ouch! Your [partname] hurts." - if(91 to 10000) - flash_pain() - msg = "OH GOD! Your [partname] is hurting terribly!" + if(burning) + switch(amount) + if(1 to 10) + msg = "\red Your [partname] burns." + if(11 to 90) + flash_weak_pain() + msg = "\red Your [partname] burns badly!" + if(91 to 10000) + flash_pain() + msg = "\red OH GOD! Your [partname] is on fire!" + else + switch(amount) + if(1 to 10) + msg = "Your [partname] hurts." + if(11 to 90) + flash_weak_pain() + msg = "Your [partname] hurts badly." + if(91 to 10000) + flash_pain() + msg = "OH GOD! Your [partname] is hurting terribly!" if(msg && (msg != last_pain_message || prob(10))) last_pain_message = msg src << msg diff --git a/code/setup.dm b/code/setup.dm index 05e8e837728..b701acb6118 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -14,6 +14,16 @@ #define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible +#define SPECIFIC_HEAT_TOXIN 200 +#define SPECIFIC_HEAT_AIR 20 +#define SPECIFIC_HEAT_CDO 30 +#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \ + (carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*SPECIFIC_HEAT_TOXIN) + +#define MINIMUM_HEAT_CAPACITY 0.0003 +#define QUANTIZE(variable) (round(variable,0.0001)) +#define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer + #define BREATH_VOLUME 0.5 //liters in a normal breath #define BREATH_PERCENTAGE BREATH_VOLUME/CELL_VOLUME //Amount of air to take a from a tile diff --git a/icons/effects/contamination.dmi b/icons/effects/contamination.dmi new file mode 100644 index 00000000000..e0f34e26469 Binary files /dev/null and b/icons/effects/contamination.dmi differ diff --git a/icons/effects/plasma.dmi b/icons/effects/plasma.dmi index bf287fde3ec..5f9137267d4 100644 Binary files a/icons/effects/plasma.dmi and b/icons/effects/plasma.dmi differ diff --git a/icons/effects/tile_effects.dmi b/icons/effects/tile_effects.dmi index 4c78f8f2e06..5ed60b7adcd 100644 Binary files a/icons/effects/tile_effects.dmi and b/icons/effects/tile_effects.dmi differ