Merge pull request #13991 from Putnam3145/auxtools-atmos

Replaces extools with auxtools; atmos overhaul
This commit is contained in:
silicons
2021-06-27 11:01:32 -07:00
committed by GitHub
154 changed files with 2336 additions and 2232 deletions
+2 -38
View File
@@ -1,38 +1,2 @@
// _extools_api.dm - DM API for extools extension library
// (blatently stolen from rust_g)
//
// To configure, create a `extools.config.dm` and set what you care about from
// the following options:
//
// #define EXTOOLS "path/to/extools"
// Override the .dll/.so detection logic with a fixed path or with detection
// logic of your own.
#ifndef EXTOOLS
// Default automatic EXTOOLS detection.
// On Windows, looks in the standard places for `byond-extools.dll`.
// On Linux, looks in the standard places for`libbyond-extools.so`.
/* This comment bypasses grep checks */ /var/__extools
/proc/__detect_extools()
if (world.system_type == UNIX)
if (fexists("./libbyond-extools.so"))
// No need for LD_LIBRARY_PATH badness.
return __extools = "./libbyond-extools.so"
else
// It's not in the current directory, so try others
return __extools = "libbyond-extools.so"
else
return __extools = "byond-extools.dll"
#define EXTOOLS (__extools || __detect_extools())
#endif
#ifndef UNIT_TESTS // use default logging as extools is broken on travis
#define EXTOOLS_LOGGING // rust_g is used as a fallback if this is undefined
#endif
/proc/extools_log_write()
/proc/extools_finalize_logging()
#define EXTOOLS (world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")
#define AUXMOS (world.system_type == MS_WINDOWS ? "auxmos.dll" : "libauxmos.so")
+8 -1
View File
@@ -1,7 +1,11 @@
/// Percentage of tick to leave for master controller to run
#define MAPTICK_MC_MIN_RESERVE 70
/// internal_tick_usage is updated every tick by extools
#define MAPTICK_LAST_INTERNAL_TICK_USAGE ((GLOB.internal_tick_usage / world.tick_lag) * 100)
#if DM_VERSION > 513
#define MAPTICK_LAST_INTERNAL_TICK_USAGE world.map_cpu
#else
#define MAPTICK_LAST_INTERNAL_TICK_USAGE 50
#endif
/// Tick limit while running normally
#define TICK_BYOND_RESERVE 2
#define TICK_LIMIT_RUNNING (max(100 - TICK_BYOND_RESERVE - MAPTICK_LAST_INTERNAL_TICK_USAGE, MAPTICK_MC_MIN_RESERVE))
@@ -19,6 +23,9 @@
/// Returns true if tick_usage is above the limit
#define TICK_CHECK ( TICK_USAGE > Master.current_ticklimit )
#define TICK_REMAINING_MS ((Master.current_ticklimit - TICK_USAGE) * world.tick_lag)
/// runs stoplag if tick_usage is above the limit
#define CHECK_TICK ( TICK_CHECK ? stoplag() : 0 )
+20 -20
View File
@@ -1,12 +1,3 @@
//LISTMOS
//indices of values in gas lists.
#define META_GAS_SPECIFIC_HEAT 1
#define META_GAS_NAME 2
#define META_GAS_MOLES_VISIBLE 3
#define META_GAS_OVERLAY 4
#define META_GAS_DANGER 5
#define META_GAS_ID 6
#define META_GAS_FUSION_POWER 7
//ATMOS
//stuff you should probably leave well alone!
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
@@ -257,6 +248,26 @@
#define PIPING_DEFAULT_LAYER_ONLY (1<<2) //can only exist at PIPING_LAYER_DEFAULT
#define PIPING_CARDINAL_AUTONORMALIZE (1<<3) //north/south east/west doesn't matter, auto normalize on build.
// Gas defines because i hate typepaths
#define GAS_O2 "o2"
#define GAS_N2 "n2"
#define GAS_CO2 "co2"
#define GAS_PLASMA "plasma"
#define GAS_H2O "water_vapor"
#define GAS_HYPERNOB "nob"
#define GAS_NITROUS "n2o"
#define GAS_NITRYL "no2"
#define GAS_TRITIUM "tritium"
#define GAS_BZ "bz"
#define GAS_STIMULUM "stim"
#define GAS_PLUOXIUM "pluox"
#define GAS_MIASMA "miasma"
#define GAS_METHANE "methane"
#define GAS_METHYL_BROMIDE "methyl_bromide"
#define GAS_FLAG_DANGEROUS (1<<0)
#define GAS_FLAG_BREATH_PROC (1<<1)
//HELPERS
#define PIPING_LAYER_SHIFT(T, PipingLayer) \
if(T.dir & (NORTH|SOUTH)) { \
@@ -284,17 +295,6 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
//If you're doing spreading things related to atmos, DO NOT USE CANATMOSPASS, IT IS NOT CHEAP. use this instead, the info is cached after all. it's tweaked just a bit to allow for circular checks
#define TURFS_CAN_SHARE(T1, T2) (LAZYACCESS(T2.atmos_adjacent_turfs, T1) || LAZYLEN(T1.atmos_adjacent_turfs & T2.atmos_adjacent_turfs))
GLOBAL_VAR(atmos_extools_initialized) // this must be an uninitialized (null) one or init_monstermos will be called twice because reasons
#define ATMOS_EXTOOLS_CHECK if(!GLOB.atmos_extools_initialized){\
GLOB.atmos_extools_initialized=TRUE;\
if(fexists(EXTOOLS)){\
var/result = call(EXTOOLS,"init_monstermos")();\
if(result != "ok") {CRASH(result);}\
} else {\
CRASH("[EXTOOLS] does not exist!");\
}\
}
//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance.
#define GAS_GARBAGE_COLLECT(GASGASGAS)\
var/list/CACHE_GAS = GASGASGAS;\
+3
View File
@@ -254,6 +254,9 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list(
#define isshuttleturf(T) (length(T.baseturfs) && (/turf/baseturf_skipover/shuttle in T.baseturfs))
#define isProbablyWallMounted(O) (O.pixel_x > 20 || O.pixel_x < -20 || O.pixel_y > 20 || O.pixel_y < -20)
#define isfinite(n) (isnum(n) && n == n)
#define isbook(O) (is_type_in_typecache(O, GLOB.book_types))
GLOBAL_LIST_INIT(book_types, typecacheof(list(
+8 -3
View File
@@ -212,12 +212,17 @@
/// Like DT_PROB_RATE but easier to use, simply put `if(DT_PROB(10, 5))`
#define DT_PROB(prob_per_second_percent, delta_time) (prob(100*DT_PROB_RATE((prob_per_second_percent)/100, (delta_time))))
// )
/// Taxicab distance--gets you the **actual** time it takes to get from one turf to another due to how we calculate diagonal movement
#define MANHATTAN_DISTANCE(a, b) (abs(a.x - b.x) + abs(a.y - b.y))
// )
/// A function that exponentially approaches a maximum value of L
/// k is the rate at which is approaches L, x_0 is the point where the function = 0
#define LOGISTIC_FUNCTION(L,k,x,x_0) (L/(1+(NUM_E**(-k*(x-x_0)))))
// )
/// Make sure something is a boolean TRUE/FALSE 1/0 value, since things like bitfield & bitflag doesn't always give 1s and 0s.
#define FORCE_BOOLEAN(x) ((x)? TRUE : FALSE)
// )
/// Gives the number of pixels in an orthogonal line of tiles.
#define TILES_TO_PIXELS(tiles) (tiles * PIXELS)
// )
+4
View File
@@ -343,3 +343,7 @@
///Define for spawning megafauna instead of a mob for cave gen
#define SPAWN_MEGAFAUNA "bluh bluh huge boss"
// / Breathing types. Lungs can access either by these or by a string, which will be considered a gas ID.
#define BREATH_OXY /datum/breathing_class/oxygen
#define BREATH_PLASMA /datum/breathing_class/plasma
+2 -3
View File
@@ -28,6 +28,5 @@
#define VAR_PROTECTED var
#endif
/world/proc/enable_debugger()
if (fexists(EXTOOLS))
call(EXTOOLS, "debug_initialize")()
/proc/enable_debugging()
CRASH("Auxtools not found")
+15 -11
View File
@@ -185,6 +185,7 @@
#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_RUNECHAT 410
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_CALLBACKS 600
// #define FIRE_PRIORITY_EXPLOSIONS 666
#define FIRE_PRIORITY_TIMER 700
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
@@ -199,6 +200,20 @@
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
// SSair run section
#define SSAIR_PIPENETS 1
#define SSAIR_ATMOSMACHINERY 2
#define SSAIR_EXCITEDGROUPS 3
#define SSAIR_HIGHPRESSURE 4
#define SSAIR_HOTSPOTS 5
#define SSAIR_TURF_CONDUCTION 6
#define SSAIR_REBUILD_PIPENETS 7
#define SSAIR_EQUALIZE 8
#define SSAIR_ACTIVETURFS 9
#define SSAIR_TURF_POST_PROCESS 10
#define SSAIR_FINALIZE_TURFS 11
#define SSAIR_ATMOSMACHINERY_AIR 12
#define SSAIR_DEFERRED_AIRS 13
//! ## Overlays subsystem
@@ -228,14 +243,3 @@
* * flags flags for this timer, see: code\__DEFINES\subsystems.dm
*/
#define addtimer(args...) _addtimer(args, file = __FILE__, line = __LINE__)
// SSair run section
#define SSAIR_PIPENETS 1
#define SSAIR_ATMOSMACHINERY 2
#define SSAIR_EXCITEDGROUPS 3
#define SSAIR_HIGHPRESSURE 4
#define SSAIR_HOTSPOTS 5
#define SSAIR_SUPERCONDUCTIVITY 6
#define SSAIR_REBUILD_PIPENETS 7
#define SSAIR_EQUALIZE 8
#define SSAIR_ACTIVETURFS 9
+26
View File
@@ -0,0 +1,26 @@
//#define EXTOOLS_LOGGING // rust_g is used as a fallback if this is undefined
/proc/extools_log_write()
/proc/extools_finalize_logging()
/proc/auxtools_stack_trace(msg)
CRASH(msg)
GLOBAL_LIST_EMPTY(auxtools_initialized)
#define AUXTOOLS_CHECK(LIB)\
if (!GLOB.auxtools_initialized[LIB] && fexists(LIB)) {\
var/string = call(LIB,"auxtools_init")();\
if(findtext(string, "SUCCESS")) {\
GLOB.auxtools_initialized[LIB] = TRUE;\
} else {\
CRASH(string);\
}\
}\
#define AUXTOOLS_SHUTDOWN(LIB)\
if (GLOB.auxtools_initialized[LIB] && fexists(LIB)){\
call(LIB,"auxtools_shutdown")();\
GLOB.auxtools_initialized[LIB] = FALSE;\
}\
@@ -20,6 +20,9 @@ SUBSYSTEM_DEF(adjacent_air)
return ..()
/datum/controller/subsystem/adjacent_air/fire(resumed = FALSE, mc_check = TRUE)
if(SSair.thread_running())
pause()
return
var/list/queue = src.queue
+199 -183
View File
@@ -9,24 +9,36 @@ SUBSYSTEM_DEF(air)
var/cost_turfs = 0
var/cost_groups = 0
var/cost_highpressure = 0
var/cost_deferred_airs
var/cost_hotspots = 0
var/cost_post_process = 0
var/cost_superconductivity = 0
var/cost_pipenets = 0
var/cost_rebuilds = 0
var/cost_atmos_machinery = 0
var/cost_equalize = 0
var/thread_wait_ticks = 0
var/cur_thread_wait_ticks = 0
var/low_pressure_turfs = 0
var/high_pressure_turfs = 0
var/num_group_turfs_processed = 0
var/num_equalize_processed = 0
var/list/hotspots = list()
var/list/networks = list()
var/list/pipenets_needing_rebuilt = list()
var/list/deferred_airs = list()
var/max_deferred_airs = 0
var/list/obj/machinery/atmos_machinery = list()
var/list/obj/machinery/atmos_air_machinery = list()
var/list/pipe_init_dirs_cache = list()
//atmos singletons
var/list/gas_reactions = list()
//Special functions lists
var/list/turf/active_super_conductivity = list()
var/list/turf/open/high_pressure_delta = list()
@@ -34,54 +46,88 @@ SUBSYSTEM_DEF(air)
var/currentpart = SSAIR_REBUILD_PIPENETS
var/map_loading = TRUE
var/list/queued_for_activation
var/log_explosive_decompression = TRUE // If things get spammy, admemes can turn this off.
var/monstermos_turf_limit = 10
var/monstermos_hard_turf_limit = 2000
var/monstermos_enabled = TRUE
// Max number of turfs equalization will grab.
var/equalize_turf_limit = 10
// Max number of turfs to look for a space turf, and max number of turfs that will be decompressed.
var/equalize_hard_turf_limit = 2000
// Whether equalization should be enabled at all.
var/equalize_enabled = FALSE
// Whether turf-to-turf heat exchanging should be enabled.
var/heat_enabled = FALSE
// Max number of times process_turfs will share in a tick.
var/share_max_steps = 1
// Excited group processing will try to equalize groups with total pressure difference less than this amount.
var/excited_group_pressure_goal = 0.25
/datum/controller/subsystem/air/stat_entry(msg)
msg += "C:{"
msg += "EQ:[round(cost_equalize,1)]|"
msg += "AT:[round(cost_turfs,1)]|"
msg += "EG:[round(cost_groups,1)]|"
msg += "HP:[round(cost_highpressure,1)]|"
msg += "HS:[round(cost_hotspots,1)]|"
msg += "HE:[round(heat_process_time(),1)]|"
msg += "SC:[round(cost_superconductivity,1)]|"
msg += "PN:[round(cost_pipenets,1)]|"
msg += "AM:[round(cost_atmos_machinery,1)]"
msg += "} "
var/active_turfs_len = get_amt_active_turfs()
msg += "AT:[active_turfs_len]|"
msg += "EG:[get_amt_excited_groups()]|"
msg += "TC:{"
msg += "AT:[round(cost_turfs,1)]|"
msg += "EG:[round(cost_groups,1)]|"
msg += "EQ:[round(cost_equalize,1)]|"
msg += "PO:[round(cost_post_process,1)]"
msg += "}"
msg += "TH:[round(thread_wait_ticks,1)]|"
msg += "HS:[hotspots.len]|"
msg += "PN:[networks.len]|"
msg += "HP:[high_pressure_delta.len]|"
msg += "AS:[active_super_conductivity.len]|"
msg += "HT:[high_pressure_turfs]|"
msg += "LT:[low_pressure_turfs]|"
msg += "ET:[num_equalize_processed]|"
msg += "GT:[num_group_turfs_processed]|"
msg += "DF:[max_deferred_airs]|"
msg += "GA:[get_amt_gas_mixes()]|"
msg += "MG:[get_max_gas_mixes()]|"
msg += "AT/MS:[round((cost ? active_turfs_len/cost : 0),0.1)]"
msg += "MG:[get_max_gas_mixes()]"
return ..()
/datum/controller/subsystem/air/Initialize(timeofday)
extools_update_ssair()
map_loading = FALSE
setup_allturfs()
setup_atmos_machinery()
setup_pipenets()
gas_reactions = init_gas_reactions()
extools_update_reactions()
auxtools_update_reactions()
return ..()
/datum/controller/subsystem/air/proc/extools_update_ssair()
/datum/controller/subsystem/air/proc/extools_update_reactions()
/datum/controller/subsystem/air/proc/auxtools_update_reactions()
/proc/reset_all_air()
SSair.can_fire = 0
message_admins("Air reset begun.")
for(var/turf/open/T in world)
T.Initalize_Atmos(0)
CHECK_TICK
message_admins("Air reset done.")
SSair.can_fire = 1
/datum/controller/subsystem/air/proc/thread_running()
return FALSE
/proc/fix_corrupted_atmos()
/datum/admins/proc/fixcorruption()
set category = "Debug"
set desc="Fixes air that has weird NaNs (-1.#IND and such). Hopefully."
set name="Fix Infinite Air"
fix_corrupted_atmos()
/datum/controller/subsystem/air/fire(resumed = 0)
var/timer = TICK_USAGE_REAL
if(currentpart == SSAIR_REBUILD_PIPENETS)
timer = TICK_USAGE_REAL
var/list/pipenet_rebuilds = pipenets_needing_rebuilt
for(var/thing in pipenet_rebuilds)
var/obj/machinery/atmospherics/AT = thing
@@ -96,13 +142,14 @@ SUBSYSTEM_DEF(air)
currentpart = SSAIR_PIPENETS
if(currentpart == SSAIR_PIPENETS || !resumed)
timer = TICK_USAGE_REAL
process_pipenets(resumed)
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_ATMOSMACHINERY
// This is only machinery like filters, mixers that don't interact with air
if(currentpart == SSAIR_ATMOSMACHINERY)
timer = TICK_USAGE_REAL
process_atmos_machinery(resumed)
@@ -110,33 +157,6 @@ SUBSYSTEM_DEF(air)
if(state != SS_RUNNING)
return
resumed = 0
currentpart = monstermos_enabled ? SSAIR_EQUALIZE : SSAIR_ACTIVETURFS
if(currentpart == SSAIR_EQUALIZE)
timer = TICK_USAGE_REAL
process_turf_equalize(resumed)
cost_equalize = MC_AVERAGE(cost_equalize, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_ACTIVETURFS
if(currentpart == SSAIR_ACTIVETURFS)
timer = TICK_USAGE_REAL
process_active_turfs(resumed)
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_EXCITEDGROUPS
if(currentpart == SSAIR_EXCITEDGROUPS)
timer = TICK_USAGE_REAL
process_excited_groups(resumed)
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_HIGHPRESSURE
if(currentpart == SSAIR_HIGHPRESSURE)
@@ -146,6 +166,34 @@ SUBSYSTEM_DEF(air)
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_FINALIZE_TURFS
// This literally just waits for the turf processing thread to finish, doesn't do anything else.
// this is necessary cause the next step after this interacts with the air--we get consistency
// issues if we don't wait for it, disappearing gases etc.
if(currentpart == SSAIR_FINALIZE_TURFS)
finish_turf_processing(resumed)
if(state != SS_RUNNING)
cur_thread_wait_ticks++
return
resumed = 0
thread_wait_ticks = MC_AVERAGE(thread_wait_ticks, cur_thread_wait_ticks)
cur_thread_wait_ticks = 0
currentpart = SSAIR_DEFERRED_AIRS
if(currentpart == SSAIR_DEFERRED_AIRS)
timer = TICK_USAGE_REAL
process_deferred_airs(resumed)
cost_deferred_airs = MC_AVERAGE(cost_deferred_airs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_ATMOSMACHINERY_AIR
if(currentpart == SSAIR_ATMOSMACHINERY_AIR)
timer = TICK_USAGE_REAL
process_atmos_air_machinery(resumed)
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_HOTSPOTS
if(currentpart == SSAIR_HOTSPOTS)
@@ -155,19 +203,58 @@ SUBSYSTEM_DEF(air)
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_SUPERCONDUCTIVITY
if(currentpart == SSAIR_SUPERCONDUCTIVITY)
currentpart = heat_enabled ? SSAIR_TURF_CONDUCTION : SSAIR_ACTIVETURFS
// Heat -- slow and of questionable usefulness. Off by default for this reason. Pretty cool, though.
if(currentpart == SSAIR_TURF_CONDUCTION)
timer = TICK_USAGE_REAL
process_super_conductivity(resumed)
if(process_turf_heat(TICK_REMAINING_MS))
pause()
cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_ACTIVETURFS
// This simply starts the turf thread. It runs in the background until the FINALIZE_TURFS step, at which point it's waited for.
// This also happens to do all the commented out stuff below, all in a single separate thread. This is mostly so that the
// waiting is consistent.
if(currentpart == SSAIR_ACTIVETURFS)
timer = TICK_USAGE_REAL
process_turfs(resumed)
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
/*
// Monstermos and/or Putnamos--making large pressure deltas move faster
if(currentpart == SSAIR_EQUALIZE)
timer = TICK_USAGE_REAL
process_turf_equalize(resumed)
cost_equalize = MC_AVERAGE(cost_equalize, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_EXCITEDGROUPS
// Making small pressure deltas equalize immediately so they don't process anymore
if(currentpart == SSAIR_EXCITEDGROUPS)
timer = TICK_USAGE_REAL
process_excited_groups(resumed)
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_TURF_POST_PROCESS
// Quick multithreaded "should we display/react?" checks followed by finishing those up before the next step
if(currentpart == SSAIR_TURF_POST_PROCESS)
timer = TICK_USAGE_REAL
post_process_turfs(resumed)
cost_post_process = MC_AVERAGE(cost_post_process, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
if(state != SS_RUNNING)
return
resumed = 0
currentpart = SSAIR_HOTSPOTS
*/
currentpart = SSAIR_REBUILD_PIPENETS
/datum/controller/subsystem/air/proc/process_pipenets(resumed = 0)
if (!resumed)
src.currentrun = networks.Copy()
@@ -187,6 +274,31 @@ SUBSYSTEM_DEF(air)
if(istype(atmos_machine, /obj/machinery/atmospherics))
pipenets_needing_rebuilt += atmos_machine
/datum/controller/subsystem/air/proc/process_deferred_airs(resumed = 0)
max_deferred_airs = max(deferred_airs.len,max_deferred_airs)
while(deferred_airs.len)
var/list/cur_op = deferred_airs[deferred_airs.len]
deferred_airs.len--
var/datum/gas_mixture/air1
var/datum/gas_mixture/air2
if(isopenturf(cur_op[1]))
var/turf/open/T = cur_op[1]
air1 = T.return_air()
else
air1 = cur_op[1]
if(isopenturf(cur_op[2]))
var/turf/open/T = cur_op[2]
air2 = T.return_air()
else
air2 = cur_op[2]
if(istype(cur_op[3], /datum/callback))
var/datum/callback/cb = cur_op[3]
cb.Invoke(air1, air2)
else
air1.transfer_ratio_to(air2, cur_op[3])
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0)
var/seconds = wait * 0.1
if (!resumed)
@@ -201,19 +313,22 @@ SUBSYSTEM_DEF(air)
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0)
/datum/controller/subsystem/air/proc/process_atmos_air_machinery(resumed = 0)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = active_super_conductivity.Copy()
src.currentrun = atmos_air_machinery.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/turf/T = currentrun[currentrun.len]
var/obj/machinery/M = currentrun[currentrun.len]
currentrun.len--
T.super_conduct()
if(!M || (M.process_atmos(seconds) == PROCESS_KILL))
atmos_air_machinery.Remove(M)
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/process_turf_heat()
/datum/controller/subsystem/air/proc/process_hotspots(resumed = 0)
if (!resumed)
src.currentrun = hotspots.Copy()
@@ -241,7 +356,7 @@ SUBSYSTEM_DEF(air)
return
/datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0)
if(process_turf_equalize_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
if(process_turf_equalize_auxtools(resumed,TICK_REMAINING_MS))
pause()
/*
//cache for sanic speed
@@ -260,8 +375,8 @@ SUBSYSTEM_DEF(air)
return
*/
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
if(process_active_turfs_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
/datum/controller/subsystem/air/proc/process_turfs(resumed = 0)
if(process_turfs_auxtools(resumed,TICK_REMAINING_MS))
pause()
/*
//cache for sanic speed
@@ -280,75 +395,32 @@ SUBSYSTEM_DEF(air)
*/
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
if(process_excited_groups_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
if(process_excited_groups_auxtools(resumed,TICK_REMAINING_MS))
pause()
/*
if (!resumed)
src.currentrun = excited_groups.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/datum/excited_group/EG = currentrun[currentrun.len]
currentrun.len--
EG.breakdown_cooldown++
EG.dismantle_cooldown++
if(EG.breakdown_cooldown >= EXCITED_GROUP_BREAKDOWN_CYCLES)
EG.self_breakdown()
else if(EG.dismantle_cooldown >= EXCITED_GROUP_DISMANTLE_CYCLES)
EG.dismantle()
if (MC_TICK_CHECK)
return
*/
/datum/controller/subsystem/air/proc/process_active_turfs_extools()
/datum/controller/subsystem/air/proc/process_turf_equalize_extools()
/datum/controller/subsystem/air/proc/process_excited_groups_extools()
/datum/controller/subsystem/air/proc/get_amt_excited_groups()
/datum/controller/subsystem/air/proc/get_amt_active_turfs()
/datum/controller/subsystem/air/proc/finish_turf_processing(resumed = 0)
if(finish_turf_processing_auxtools(TICK_REMAINING_MS))
pause()
/datum/controller/subsystem/air/proc/post_process_turfs(resumed = 0)
if(post_process_turfs_auxtools(resumed,TICK_REMAINING_MS))
pause()
/datum/controller/subsystem/air/proc/finish_turf_processing_auxtools()
/datum/controller/subsystem/air/proc/process_turfs_auxtools()
/datum/controller/subsystem/air/proc/post_process_turfs_auxtools()
/datum/controller/subsystem/air/proc/process_turf_equalize_auxtools()
/datum/controller/subsystem/air/proc/process_excited_groups_auxtools()
/datum/controller/subsystem/air/proc/get_amt_gas_mixes()
/datum/controller/subsystem/air/proc/get_max_gas_mixes()
/datum/controller/subsystem/air/proc/add_to_active_extools()
/datum/controller/subsystem/air/proc/remove_from_active_extools()
/datum/controller/subsystem/air/proc/get_active_turfs()
/datum/controller/subsystem/air/proc/clear_active_turfs()
/datum/controller/subsystem/air/proc/remove_from_active(turf/open/T)
remove_from_active_extools(T)
#ifdef VISUALIZE_ACTIVE_TURFS
T.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#00ff00")
#endif
if(istype(T))
T.set_excited(FALSE)
T.eg_garbage_collect()
/datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
if(istype(T) && T.air)
#ifdef VISUALIZE_ACTIVE_TURFS
T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY)
#endif
T.set_excited(TRUE)
add_to_active_extools(T)
if(blockchanges)
T.eg_garbage_collect()
else if(T.flags_1 & INITIALIZED_1)
for(var/turf/S in T.atmos_adjacent_turfs)
add_to_active(S)
else if(map_loading)
if(queued_for_activation)
queued_for_activation[T] = T
return
else
T.requires_activation = TRUE
/datum/controller/subsystem/air/proc/turf_process_time()
/datum/controller/subsystem/air/proc/heat_process_time()
/datum/controller/subsystem/air/StartLoadingMap()
LAZYINITLIST(queued_for_activation)
map_loading = TRUE
/datum/controller/subsystem/air/StopLoadingMap()
map_loading = FALSE
for(var/T in queued_for_activation)
add_to_active(T)
queued_for_activation.Cut()
/datum/controller/subsystem/air/proc/setup_allturfs()
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
@@ -356,7 +428,6 @@ SUBSYSTEM_DEF(air)
// Clear active turfs - faster than removing every single turf in the world
// one-by-one, and Initalize_Atmos only ever adds `src` back in.
clear_active_turfs()
for(var/thing in turfs_to_init)
var/turf/T = thing
@@ -364,67 +435,9 @@ SUBSYSTEM_DEF(air)
continue
T.Initalize_Atmos(times_fired)
CHECK_TICK
var/starting_ats = get_amt_active_turfs()
if(starting_ats)
sleep(world.tick_lag)
var/timer = world.timeofday
log_mapping("There are [starting_ats] active turfs at roundstart caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required).")
var/list/turfs_to_check = get_active_turfs()
for(var/T in turfs_to_check)
GLOB.active_turfs_startlist += T
//now lets clear out these active turfs
do
var/list/new_turfs_to_check = list()
for(var/turf/open/T in turfs_to_check)
new_turfs_to_check += T.resolve_active_graph()
CHECK_TICK
for(var/T in new_turfs_to_check)
add_to_active_extools(T)
turfs_to_check = new_turfs_to_check
while (turfs_to_check.len)
var/ending_ats = get_amt_active_turfs()
/*for(var/thing in excited_groups)
var/datum/excited_group/EG = thing
//EG.self_breakdown(space_is_all_consuming = 1)
//EG.dismantle()
CHECK_TICK*/
var/msg = "HEY! LISTEN! [DisplayTimeText(world.timeofday - timer)] were wasted processing [starting_ats] turf(s) (connected to [ending_ats] other turfs) with atmos differences at round start."
to_chat(world, "<span class='boldannounce'>[msg]</span>")
warning(msg)
/turf/open/proc/resolve_active_graph()
. = list()
/*
var/datum/excited_group/EG = excited_group
if (blocks_air || !air)
return
if (!EG)
EG = new
EG.add_turf(src)
for (var/turf/open/ET in atmos_adjacent_turfs)
if ( ET.blocks_air || !ET.air)
continue
var/ET_EG = ET.excited_group
if (ET_EG)
if (ET_EG != EG)
EG.merge_groups(ET_EG)
EG = excited_group //merge_groups() may decide to replace our current EG
else
EG.add_turf(ET)
if (!ET.excited)
ET.excited = 1
. += ET*/
/turf/open/space/resolve_active_graph()
return list()
/datum/controller/subsystem/air/proc/setup_atmos_machinery()
for (var/obj/machinery/atmospherics/AM in atmos_machinery)
for (var/obj/machinery/atmospherics/AM in atmos_machinery + atmos_air_machinery)
AM.atmosinit()
CHECK_TICK
@@ -432,7 +445,7 @@ SUBSYSTEM_DEF(air)
// all atmos machinery has to initalize before the first
// pipenet can be built.
/datum/controller/subsystem/air/proc/setup_pipenets()
for (var/obj/machinery/atmospherics/AM in atmos_machinery)
for (var/obj/machinery/atmospherics/AM in atmos_machinery + atmos_air_machinery)
AM.build_network()
CHECK_TICK
@@ -460,12 +473,15 @@ SUBSYSTEM_DEF(air)
return pipe_init_dirs_cache[type]["[dir]"]
/proc/get_extools_benchmarks()
#undef SSAIR_PIPENETS
#undef SSAIR_ATMOSMACHINERY
#undef SSAIR_ACTIVETURFS
#undef SSAIR_EXCITEDGROUPS
#undef SSAIR_HIGHPRESSURE
#undef SSAIR_HOTSPOTS
#undef SSAIR_SUPERCONDUCTIVITY
#undef SSAIR_TURF_CONDUCTION
#undef SSAIR_REBUILD_PIPENETS
#undef SSAIR_EQUALIZE
#undef SSAIR_ACTIVETURFS
#undef SSAIR_TURF_POST_PROCESS
#undef SSAIR_FINALIZE_TURFS
#undef SSAIR_ATMOSMACHINERY_AIR
+14
View File
@@ -0,0 +1,14 @@
SUBSYSTEM_DEF(callbacks)
name = "Auxtools Callbacks"
flags = SS_TICKER | SS_NO_INIT
wait = 1
priority = FIRE_PRIORITY_CALLBACKS
/proc/process_atmos_callbacks()
SScallbacks.can_fire = 0
SScallbacks.flags |= SS_NO_FIRE
CRASH("Auxtools not found! Callback subsystem shutting itself off.")
/datum/controller/subsystem/callbacks/fire()
if(process_atmos_callbacks(TICK_REMAINING_MS))
pause()
+2
View File
@@ -726,6 +726,8 @@ SUBSYSTEM_DEF(shuttle)
preview_shuttle.register(replace)
preview_shuttle.reset_air()
// TODO indicate to the user that success happened, rather than just
// blanking the modification tab
preview_shuttle = null
+12 -8
View File
@@ -31,18 +31,20 @@ SUBSYSTEM_DEF(time_track)
"maptick",
"num_timers",
"air_turf_cost",
"air_turf_thread_time",
"air_equalize_cost",
"air_post_process_cost",
"air_eg_cost",
"air_highpressure_cost",
"air_hotspots_cost",
"air_superconductivity_cost",
"air_heat_spread_cost",
"air_pipenets_cost",
"air_rebuilds_cost",
"air_turf_count",
"air_eg_count",
"air_amt_gas_mixes",
"air_alloc_gas_mixes",
"air_hotspot_count",
"air_network_count",
"air_delta_count",
"air_superconductive_count"
)
)
@@ -81,17 +83,19 @@ SUBSYSTEM_DEF(time_track)
MAPTICK_LAST_INTERNAL_TICK_USAGE,
length(SStimer.timer_id_dict),
SSair.cost_turfs,
SSair.turf_process_time(),
SSair.cost_equalize,
SSair.cost_post_process,
SSair.cost_groups,
SSair.cost_highpressure,
SSair.cost_hotspots,
SSair.cost_superconductivity,
SSair.cost_pipenets,
SSair.cost_rebuilds,
SSair.get_active_turfs(), //does not return a list, which is what we want
SSair.get_amt_excited_groups(),
SSair.get_amt_gas_mixes(),
SSair.get_max_gas_mixes(),
length(SSair.hotspots),
length(SSair.networks),
length(SSair.high_pressure_delta),
length(SSair.active_super_conductivity)
length(SSair.high_pressure_delta)
)
)
@@ -404,8 +404,8 @@
if(M.loc)
environment = M.loc.return_air()
if(environment)
plasmamount = environment.get_moles(/datum/gas/plasma)
if(plasmamount && plasmamount > GLOB.meta_gas_visibility[/datum/gas/plasma]) //if there's enough plasma in the air to see
plasmamount = environment.get_moles(GAS_PLASMA)
if(plasmamount && plasmamount > GLOB.gas_data.visibility[GAS_PLASMA]) //if there's enough plasma in the air to see
. += power * 0.5
if(M.reagents.has_reagent(/datum/reagent/toxin/plasma))
. += power * 0.75
+26 -2
View File
@@ -184,7 +184,7 @@
return location.loc.assume_air(env)
return location.assume_air(env)
/obj/item/clothing/head/mob_holder/remove_air(amount)
/obj/item/clothing/head/mob_holder/proc/get_loc_for_air()
var/atom/location = loc
if(!loc)
return //null
@@ -192,9 +192,33 @@
while(location != T)
location = location.loc
if(ismob(location))
return location.loc.remove_air(amount)
return location.loc
return location
/obj/item/clothing/head/mob_holder/assume_air_moles(datum/gas_mixture/env, moles)
var/atom/location = get_loc_for_air()
return location.assume_air_moles(env, moles)
/obj/item/clothing/head/mob_holder/assume_air_ratio(datum/gas_mixture/env, ratio)
var/atom/location = get_loc_for_air()
return location.assume_air_ratio(env, ratio)
/obj/item/clothing/head/mob_holder/remove_air(amount)
var/atom/location = get_loc_for_air()
return location.remove_air(amount)
/obj/item/clothing/head/mob_holder/remove_air_ratio(ratio)
var/atom/location = get_loc_for_air()
return location.remove_air_ratio(ratio)
/obj/item/clothing/head/mob_holder/transfer_air(datum/gas_mixture/taker, amount)
var/atom/location = get_loc_for_air()
return location.transfer_air(taker, amount)
/obj/item/clothing/head/mob_holder/transfer_air_ratio(datum/gas_mixture/taker, ratio)
var/atom/location = get_loc_for_air()
return location.transfer_air(taker, ratio)
// escape when found if applicable
/obj/item/clothing/head/mob_holder/on_found(mob/living/finder)
if(escape_on_find)
+3 -3
View File
@@ -142,12 +142,12 @@
// Can most things breathe?
if(trace_gases)
continue
var/oxy_moles = A.get_moles(/datum/gas/oxygen)
var/oxy_moles = A.get_moles(GAS_O2)
if(oxy_moles < 16 || oxy_moles > 50)
continue
if(A.get_moles(/datum/gas/plasma))
if(A.get_moles(GAS_PLASMA))
continue
if(A.get_moles(/datum/gas/carbon_dioxide) >= 10)
if(A.get_moles(GAS_CO2) >= 10)
continue
// Aim for goldilocks temperatures and pressure
+1 -1
View File
@@ -227,7 +227,7 @@
//can we sniff? is there miasma in the air?
var/datum/gas_mixture/air = user.loc.return_air()
if(air.get_moles(/datum/gas/miasma))
if(air.get_moles(GAS_MIASMA))
user.adjust_disgust(sensitivity * 45)
to_chat(user, "<span class='warning'>With your overly sensitive nose, you get a whiff of stench and feel sick! Try moving to a cleaner area!</span>")
return
+15 -1
View File
@@ -378,12 +378,26 @@
return FALSE
/atom/proc/assume_air(datum/gas_mixture/giver)
qdel(giver)
return null
/atom/proc/assume_air_moles(datum/gas_mixture/giver, moles)
return null
/atom/proc/assume_air_ratio(datum/gas_mixture/giver, ratio)
return null
/atom/proc/remove_air(amount)
return null
/atom/proc/remove_air_ratio(ratio)
return null
/atom/proc/transfer_air(datum/gas_mixture/taker, amount)
return null
/atom/proc/transfer_air_ratio(datum/gas_mixture/taker, ratio)
return null
/atom/proc/return_air()
if(loc)
return loc.return_air()
+1 -1
View File
@@ -130,7 +130,7 @@
/datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T)
var/target_amount = text2num(name)
var/found_amount = 0
found_amount += T.air_contents.get_moles(/datum/gas/plasma)
found_amount += T.air_contents.get_moles(GAS_PLASMA)
return found_amount>=target_amount
@@ -60,7 +60,7 @@
var/total_moles = air_sample.total_moles()
if(total_moles)
for(var/gas_id in air_sample.get_gases())
var/gas_name = GLOB.meta_gas_names[gas_id]
var/gas_name = GLOB.gas_data.names[gas_id]
signal.data["gases"][gas_name] = air_sample.get_moles(gas_id) / total_moles * 100
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
@@ -73,11 +73,11 @@
/obj/machinery/air_sensor/Initialize()
. = ..()
SSair.atmos_machinery += src
SSair.atmos_air_machinery += src
set_frequency(frequency)
/obj/machinery/air_sensor/Destroy()
SSair.atmos_machinery -= src
SSair.atmos_air_machinery -= src
SSradio.remove_object(src, frequency)
return ..()
+1 -1
View File
@@ -254,7 +254,7 @@
DA.update_name()
qdel(src)
/obj/machinery/door/airlock/plasma/BlockSuperconductivity() //we don't stop the heat~
/obj/machinery/door/airlock/plasma/BlockThermalConductivity() //we don't stop the heat~
return 0
/obj/machinery/door/airlock/plasma/attackby(obj/item/C, mob/user, params)
+1 -1
View File
@@ -386,7 +386,7 @@
if(!glass && GLOB.cameranet)
GLOB.cameranet.updateVisibility(src, 0)
/obj/machinery/door/BlockSuperconductivity() // All non-glass airlocks block heat, this is intended.
/obj/machinery/door/BlockThermalConductivity() // All non-glass airlocks block heat, this is intended.
if(opacity || heat_proof)
return 1
return 0
@@ -28,7 +28,7 @@
pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
var/gas_type = /datum/gas/plasma
var/gas_type = GAS_PLASMA
var/efficiency_multiplier = 1
var/gas_capacity = 0
+2 -2
View File
@@ -66,7 +66,7 @@
if(panel_open)
. += "sheater-open"
/obj/machinery/space_heater/process()
/obj/machinery/space_heater/process_atmos()
if(!on || !is_operational())
if (on) // If it's broken, turn it off too
on = FALSE
@@ -220,7 +220,7 @@
usr.visible_message("<span class='notice'>[usr] switches [on ? "on" : "off"] \the [src].</span>", "<span class='notice'>You switch [on ? "on" : "off"] \the [src].</span>")
update_icon()
if (on)
START_PROCESSING(SSmachines, src)
SSair.atmos_air_machinery += src
. = TRUE
if("mode")
setMode = params["mode"]
@@ -422,12 +422,12 @@
return
var/datum/gas_mixture/GM = new
if(prob(10))
GM.adjust_moles(/datum/gas/plasma,100)
GM.adjust_moles(GAS_PLASMA,100)
GM.set_temperature(1500+T0C) //should be enough to start a fire
T.visible_message("[src] suddenly disgorges a cloud of heated plasma.")
qdel(src)
else
GM.adjust_moles(/datum/gas/plasma,5)
GM.adjust_moles(GAS_PLASMA,5)
GM.set_temperature(istype(T) ? T.air.return_temperature() : T20C)
T.visible_message("[src] suddenly disgorges a cloud of plasma.")
T.assume_air(GM)
+11 -21
View File
@@ -203,11 +203,7 @@
equipment.Cut()
cell = null
internal_tank = null
if(loc)
loc.assume_air(cabin_air)
air_update_turf()
else
qdel(cabin_air)
assume_air(cabin_air)
cabin_air = null
qdel(spark_system)
spark_system = null
@@ -257,8 +253,8 @@
/obj/mecha/proc/add_cabin()
cabin_air = new(200)
cabin_air.set_temperature(T20C)
cabin_air.set_moles(/datum/gas/oxygen,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.set_moles(/datum/gas/nitrogen,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.set_moles(GAS_O2,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.set_moles(GAS_N2,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
return cabin_air
/obj/mecha/proc/add_radio()
@@ -321,13 +317,7 @@
if(internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank
if(internal_tank)
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.1)
if(loc)
loc.assume_air(leaked_gas)
air_update_turf()
else
qdel(leaked_gas)
assume_air_ratio(internal_tank.return_air(), 0.1)
if(internal_damage & MECHA_INT_SHORT_CIRCUIT)
if(get_charge())
@@ -350,8 +340,7 @@
if(pressure_delta > 0) //cabin pressure lower than release pressure
if(tank_air.return_temperature() > 0)
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
cabin_air.merge(removed)
tank_air.transfer_to(cabin_air,transfer_moles)
else if(pressure_delta < 0) //cabin pressure higher than release pressure
var/datum/gas_mixture/t_air = return_air()
pressure_delta = cabin_pressure - release_pressure
@@ -359,11 +348,7 @@
pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
if(pressure_delta > 0) //if location pressure is lower than cabin pressure
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
if(t_air)
t_air.merge(removed)
else //just delete the cabin gas, we're in space or some shit
qdel(removed)
cabin_air.transfer_to(t_air, transfer_moles)
if(occupant)
if(cell)
@@ -809,6 +794,11 @@
return cabin_air.remove(amount)
return ..()
/obj/mecha/remove_air_ratio(ratio)
if(use_internal_tank)
return cabin_air.remove_ratio(ratio)
return ..()
/obj/mecha/return_air()
if(use_internal_tank)
return cabin_air
@@ -40,8 +40,8 @@
if(hotspot && istype(T) && T.air)
qdel(hotspot)
var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.get_moles(/datum/gas/plasma)) //Absorb some plasma
G.adjust_moles(/datum/gas/plasma,-plas_amt)
var/plas_amt = min(30,G.get_moles(GAS_PLASMA)) //Absorb some plasma
G.adjust_moles(GAS_PLASMA,-plas_amt)
absorbed_plasma += plas_amt
if(G.return_temperature() > T20C)
G.set_temperature(max(G.return_temperature()/2,T20C))
@@ -322,7 +322,7 @@
for(var/obj/effect/hotspot/H in O)
qdel(H)
for(var/I in G.get_gases())
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
if(I == GAS_O2 || I == GAS_N2)
continue
G.set_moles(I, 0)
O.air_update_turf()
@@ -341,7 +341,7 @@
return TRUE
. = ..()
/obj/structure/foamedmetal/resin/BlockSuperconductivity()
/obj/structure/foamedmetal/resin/BlockThermalConductivity()
return TRUE
#undef ALUMINUM_FOAM
@@ -170,9 +170,9 @@
T.air_update_turf()
for(var/obj/effect/hotspot/H in T)
qdel(H)
if(G.get_moles(/datum/gas/plasma))
G.adjust_moles(/datum/gas/nitrogen, G.get_moles(/datum/gas/plasma))
G.set_moles(/datum/gas/plasma, 0)
if(G.get_moles(GAS_PLASMA))
G.adjust_moles(GAS_N2, G.get_moles(GAS_PLASMA))
G.set_moles(GAS_PLASMA, 0)
if (weldvents)
for(var/obj/machinery/atmospherics/components/unary/U in T)
if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber.
@@ -1,6 +1,6 @@
#define CELSIUS_TO_KELVIN(T_K) ((T_K) + T0C)
#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.meta_gas_specific_heats[/datum/gas/plasma]) / (((PRESSURE_P) * GLOB.meta_gas_specific_heats[/datum/gas/plasma] + (PRESSURE_O) * GLOB.meta_gas_specific_heats[/datum/gas/oxygen]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.meta_gas_specific_heats[/datum/gas/oxygen] / CELSIUS_TO_KELVIN(TEMP_O)))
#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.gas_data.specific_heats[GAS_PLASMA]) / (((PRESSURE_P) * GLOB.gas_data.specific_heats[GAS_PLASMA] + (PRESSURE_O) * GLOB.gas_data.specific_heats[GAS_O2]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.gas_data.specific_heats[GAS_O2] / CELSIUS_TO_KELVIN(TEMP_O)))
#define OPTIMAL_TEMP_K_PLA_BURN_RATIO(PRESSURE_P,PRESSURE_O,TEMP_O) (CELSIUS_TO_KELVIN(TEMP_O) * PLASMA_OXYGEN_FULLBURN * (PRESSURE_P) / (PRESSURE_O))
/obj/effect/spawner/newbomb
@@ -19,10 +19,10 @@
var/obj/item/tank/internals/plasma/PT = new(V)
var/obj/item/tank/internals/oxygen/OT = new(V)
PT.air_contents.set_moles(/datum/gas/plasma, pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)))
PT.air_contents.set_moles(GAS_PLASMA, pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)))
PT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_p))
OT.air_contents.set_moles(/datum/gas/oxygen, pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)))
OT.air_contents.set_moles(GAS_O2, pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)))
OT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_o))
V.tank_one = PT
+9 -3
View File
@@ -242,12 +242,18 @@
return BULLET_ACT_HIT
/obj/effect/chrono_field/assume_air()
return 0
return null
/obj/effect/chrono_field/assume_air_moles()
return null
/obj/effect/chrono_field/assume_air_ratio()
return null
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
GM.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
GM.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
GM.set_moles(GAS_O2, MOLES_O2STANDARD)
GM.set_moles(GAS_N2, MOLES_N2STANDARD)
GM.set_temperature(T20C)
return GM
+1 -1
View File
@@ -447,7 +447,7 @@ GLOBAL_LIST_EMPTY(PDAs)
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0)
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100, 0.01)]%<br>"
dat += "[GLOB.gas_data.names[id]]: [round(gas_level*100, 0.01)]%<br>"
dat += "Temperature: [round(environment.return_temperature()-T0C)]&deg;C<br>"
dat += "<br>"
+15 -15
View File
@@ -708,7 +708,7 @@ GENETICS SCANNER
for(var/id in air_contents.get_gases())
if(air_contents.get_moles(id) >= 0.005)
var/gas_concentration = air_contents.get_moles(id)/total_moles
to_chat(user, "<span class='notice'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='notice'>[GLOB.gas_data.names[id]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='notice'>Temperature: [round(temperature - T0C,0.01)] &deg;C ([round(temperature, 0.01)] K)</span>")
else
@@ -721,7 +721,7 @@ GENETICS SCANNER
var/instability = round(cached_scan_results["fusion"], 0.01)
var/tier = instability2text(instability)
to_chat(user, "<span class='boldnotice'>Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.</span>")
to_chat(user, "<span class='notice'>Instability of the last fusion reaction: [instability]\n This indicates it was [tier].</span>")
to_chat(user, "<span class='notice'>Instability of the last fusion reaction: [instability]\n This indicates it was [tier]</span>")
return
/obj/item/analyzer/proc/scan_turf(mob/user, turf/location)
@@ -739,36 +739,36 @@ GENETICS SCANNER
to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>")
if(total_moles)
var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles
var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles
var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles
var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles
var/o2_concentration = environment.get_moles(GAS_O2)/total_moles
var/n2_concentration = environment.get_moles(GAS_N2)/total_moles
var/co2_concentration = environment.get_moles(GAS_CO2)/total_moles
var/plasma_concentration = environment.get_moles(GAS_PLASMA)/total_moles
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_N2), 0.01)] mol)</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_N2), 0.01)] mol)</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_O2), 0.01)] mol)</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_O2), 0.01)] mol)</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_CO2), 0.01)] mol)</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_CO2), 0.01)] mol)</span>")
if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_PLASMA), 0.01)] mol)</span>")
else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(GAS_PLASMA), 0.01)] mol)</span>")
for(var/id in environment.get_gases())
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = environment.get_moles(id)/total_moles
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>[GLOB.gas_data.names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.return_temperature()-T0C, 0.01)] &deg;C ([round(environment.return_temperature(), 0.01)] K)</span>")
if(cached_scan_results && cached_scan_results["fusion"]) //notify the user if a fusion reaction was detected
@@ -172,20 +172,15 @@
if(!target_self)
target.set_volume(target.return_volume() + tank_two.volume)
target.set_volume(target.return_volume() + tank_one.air_contents.return_volume())
var/datum/gas_mixture/temp
temp = tank_one.air_contents.remove_ratio(1)
target.merge(temp)
tank_one.air_contents.transfer_ratio_to(target, 1)
if(!target_self)
temp = tank_two.air_contents.remove_ratio(1)
target.merge(temp)
tank_two.air_contents.transfer_ratio_to(target, 1)
/obj/item/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two)
return
var/ratio1 = tank_one.air_contents.return_volume()/tank_two.air_contents.return_volume()
var/datum/gas_mixture/temp
temp = tank_two.air_contents.remove_ratio(ratio1)
tank_one.air_contents.merge(temp)
tank_two.air_contents.transfer_ratio_to(tank_one.air_contents, ratio1)
tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume())
/*
+1 -3
View File
@@ -210,13 +210,11 @@
//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(release_amount)
air_transfer.set_moles(/datum/gas/plasma, air_transfer.get_moles(/datum/gas/plasma) * 5)
air_transfer.set_moles(GAS_PLASMA, air_transfer.get_moles(GAS_PLASMA) * 5)
target.assume_air(air_transfer)
//Burn it based on transfered gas
target.hotspot_expose((ptank.air_contents.return_temperature()*2) + 380,500)
//location.hotspot_expose(1000,500,1)
SSair.add_to_active(target, 0)
/obj/item/flamethrower/Initialize(mapload)
. = ..()
+1 -1
View File
@@ -307,7 +307,7 @@
if(isanimal(occupant))
var/mob/living/simple_animal/animal = occupant
occupant_gas_supply[/datum/gas/oxygen] = 0.0064 //make sure it has some gas in so it isn't depressurized
occupant_gas_supply[GAS_O2] = 0.0064 //make sure it has some gas in so it isn't depressurized
occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature/pressure when their turf isnt a location
if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside
+5 -5
View File
@@ -79,27 +79,27 @@
var/weight = getweight(user, STAM_COST_ATTACK_MOB_MULT)
if(!user.UseStaminaBuffer(weight, warn = TRUE))
return FALSE
var/datum/gas_mixture/gasused = tank.air_contents.remove(gasperfist * fisto_setting)
var/turf/T = get_turf(src)
if(!T)
return FALSE
var/totalitemdamage = target.pre_attacked_by(src, user)
T.assume_air(gasused)
T.air_update_turf()
if(!gasused)
var/moles_used = gasperfist * fisto_setting
if(!moles_used)
to_chat(user, "<span class='warning'>\The [src]'s tank is empty!</span>")
target.apply_damage((totalitemdamage / 5), BRUTE)
playsound(loc, 'sound/weapons/punch1.ogg', 50, 1)
target.visible_message("<span class='danger'>[user]'s powerfist lets out a dull thunk as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
"<span class='userdanger'>[user]'s punches you!</span>")
return
if(gasused.total_moles() < gasperfist * fisto_setting)
if(tank.air_contents.total_moles() < moles_used)
to_chat(user, "<span class='warning'>\The [src]'s piston-ram lets out a weak hiss, it needs more gas!</span>")
playsound(loc, 'sound/weapons/punch4.ogg', 50, 1)
target.apply_damage((totalitemdamage / 2), BRUTE)
target.visible_message("<span class='danger'>[user]'s powerfist lets out a weak hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
"<span class='userdanger'>[user]'s punch strikes with force!</span>")
return
T.assume_air_moles(tank.air_contents, gasperfist * fisto_setting)
T.air_update_turf()
target.apply_damage(totalitemdamage * fisto_setting, BRUTE, wound_bonus = -25*fisto_setting**2)
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as [user.p_they()] punch[user.p_es()] [target.name]!</span>", \
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
+4 -16
View File
@@ -8,7 +8,7 @@
w_class = WEIGHT_CLASS_BULKY
distribute_pressure = ONE_ATMOSPHERE * O2STANDARD
actions_types = list(/datum/action/item_action/set_internals, /datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
var/gas_type = /datum/gas/oxygen
var/gas_type = GAS_O2
var/on = FALSE
var/stabilizers = FALSE
var/full_speed = TRUE // If the jetpack will have a speedboost in space/nograv or not
@@ -77,13 +77,7 @@
turn_off(user)
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
turn_off(user)
return
var/turf/T = get_turf(user)
T.assume_air(removed)
assume_air_moles(air_contents, num)
return TRUE
@@ -116,13 +110,7 @@
turn_off(user)
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
turn_off(user)
return
var/turf/T = get_turf(user)
T.assume_air(removed)
assume_air_moles(air_contents, num)
return TRUE
@@ -171,7 +159,7 @@
icon_state = "jetpack-black"
item_state = "jetpack-black"
distribute_pressure = 0
gas_type = /datum/gas/carbon_dioxide
gas_type = GAS_CO2
/obj/item/tank/jetpack/carbondioxide/eva
name = "surplus jetpack (carbon dioxide)"
+13 -13
View File
@@ -20,7 +20,7 @@
/obj/item/tank/internals/oxygen/populate_gas()
air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_O2, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
@@ -48,8 +48,8 @@
force = 10
/obj/item/tank/internals/anesthetic/populate_gas()
air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(/datum/gas/nitrous_oxide, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
air_contents.set_moles(GAS_O2, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(GAS_NITROUS, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
return
/*
@@ -63,8 +63,8 @@
dog_fashion = /datum/dog_fashion/back
/obj/item/tank/internals/air/populate_gas()
air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(/datum/gas/nitrogen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
air_contents.set_moles(GAS_O2, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(GAS_N2, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
return
@@ -81,7 +81,7 @@
/obj/item/tank/internals/plasma/populate_gas()
air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_PLASMA, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params)
@@ -98,14 +98,14 @@
return ..()
/obj/item/tank/internals/plasma/full/populate_gas()
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_PLASMA, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
//Makes empty oxygen tanks spawn without gas
/obj/item/tank/internals/plasma/empty/populate_gas()
return
/obj/item/tank/internals/plasma/full/populate_gas()
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_PLASMA, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/*
* Plasmaman Plasma Tank
@@ -120,11 +120,11 @@
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
/obj/item/tank/internals/plasmaman/populate_gas()
air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_PLASMA, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/plasmaman/full/populate_gas()
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_PLASMA, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
@@ -137,7 +137,7 @@
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/tank/internals/plasmaman/belt/full/populate_gas()
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_PLASMA, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
//makes empty plasma tanks spawn without gas.
@@ -160,7 +160,7 @@
/obj/item/tank/internals/emergency_oxygen/populate_gas()
air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_O2, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/emergency_oxygen/empty/populate_gas()
@@ -196,5 +196,5 @@
volume = 10
/obj/item/tank/internals/methyl_bromide/populate_gas()
air_contents.set_moles(/datum/gas/methyl_bromide, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
air_contents.set_moles(GAS_METHYL_BROMIDE, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
+15 -1
View File
@@ -83,7 +83,6 @@
if(istype(location))
location.assume_air(air_contents)
air_contents.clear()
SSair.add_to_active(location)
visible_message("<span class='warning'[src] leaks gas!")
/obj/item/tank/Destroy()
@@ -235,6 +234,9 @@
/obj/item/tank/remove_air(amount)
return air_contents.remove(amount)
/obj/item/tank/remove_air_ratio(ratio)
return air_contents.remove_ratio(ratio)
/obj/item/tank/return_air()
return air_contents
@@ -247,6 +249,18 @@
check_status()
return 1
/obj/item/tank/assume_air_moles(datum/gas_mixture/giver, moles)
giver.transfer_to(air_contents, moles)
check_status()
return 1
/obj/item/tank/assume_air_ratio(datum/gas_mixture/giver, ratio)
giver.transfer_ratio_to(air_contents, ratio)
check_status()
return 1
/obj/item/tank/proc/remove_air_volume(volume_to_return)
if(!air_contents)
return null
+32 -2
View File
@@ -96,12 +96,43 @@
else
return null
/obj/assume_air_moles(datum/gas_mixture/giver, moles)
if(loc)
return loc.assume_air_moles(giver, moles)
else
return null
/obj/assume_air_ratio(datum/gas_mixture/giver, ratio)
if(loc)
return loc.assume_air_ratio(giver, ratio)
else
return null
/obj/transfer_air(datum/gas_mixture/taker, moles)
if(loc)
return loc.transfer_air(taker, moles)
else
return null
/obj/transfer_air_ratio(datum/gas_mixture/taker, ratio)
if(loc)
return loc.transfer_air_ratio(taker, ratio)
else
return null
/obj/remove_air(amount)
if(loc)
return loc.remove_air(amount)
else
return null
/obj/remove_air_ratio(ratio)
if(loc)
return loc.remove_air_ratio(ratio)
else
return null
/obj/return_air()
if(loc)
return loc.return_air()
@@ -116,8 +147,7 @@
if(breath_request>0)
var/datum/gas_mixture/environment = return_air()
var/breath_percentage = BREATH_VOLUME / environment.return_volume()
return remove_air(environment.total_moles() * breath_percentage)
return remove_air_ratio(BREATH_VOLUME / environment.return_volume())
else
return null
+2 -2
View File
@@ -81,8 +81,8 @@
resintype = "wall"
canSmoothWith = list(/obj/structure/alien/resin/wall, /obj/structure/alien/resin/membrane)
/obj/structure/alien/resin/wall/BlockSuperconductivity()
return 1
/obj/structure/alien/resin/wall/BlockThermalConductivity()
return TRUE
/obj/structure/alien/resin/membrane
name = "resin membrane"
+2 -2
View File
@@ -95,7 +95,7 @@
alpha = 150
resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/firelock/BlockSuperconductivity()
/obj/structure/holosign/barrier/firelock/BlockThermalConductivity()
return TRUE
/obj/structure/holosign/barrier/firelock/Initialize()
@@ -115,7 +115,7 @@
CanAtmosPass = ATMOS_PASS_NO
resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/combifan/BlockSuperconductivity()
/obj/structure/holosign/barrier/combifan/BlockThermalConductivity()
return TRUE
/obj/structure/holosign/barrier/combifan/Initialize()
@@ -149,9 +149,7 @@
pod_moving = 0
if(!QDELETED(pod))
var/datum/gas_mixture/floor_mixture = loc.return_air()
floor_mixture.archive()
pod.air_contents.archive()
pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
equalize_all_gases_in_list(list(pod.air_contents,floor_mixture))
air_update_turf()
/obj/structure/transit_tube/station/init_tube_dirs()
@@ -10,8 +10,8 @@
/obj/structure/transit_tube_pod/Initialize()
. = ..()
air_contents.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
air_contents.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
air_contents.set_moles(GAS_O2, MOLES_O2STANDARD)
air_contents.set_moles(GAS_N2, MOLES_N2STANDARD)
air_contents.set_temperature(T20C)
@@ -153,9 +153,25 @@
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
/obj/structure/transit_tube_pod/assume_air_moles(datum/gas_mixture/giver, moles)
return giver.transfer_to(air_contents, moles)
/obj/structure/transit_tube_pod/assume_air_ratio(datum/gas_mixture/giver, ratio)
return giver.transfer_ratio_to(air_contents, ratio)
/obj/structure/transit_tube_pod/remove_air(amount)
return air_contents.remove(amount)
/obj/structure/transit_tube_pod/remove_air_ratio(ratio)
return air_contents.remove_ratio(ratio)
/obj/structure/transit_tube_pod/transfer_air(datum/gas_mixture/taker, moles)
return air_contents.transfer_to(taker, moles)
/obj/structure/transit_tube_pod/transfer_air_ratio(datum/gas_mixture/taker, ratio)
return air_contents.transfer_ratio_to(taker, ratio)
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(istype(mob) && mob.client)
if(!moving)
+1 -1
View File
@@ -674,7 +674,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
/obj/structure/window/plasma/reinforced/unanchored
anchored = FALSE
/obj/structure/window/plasma/reinforced/BlockSuperconductivity()
/obj/structure/window/plasma/reinforced/BlockThermalConductivity()
return TRUE
/obj/structure/window/reinforced/tinted
+16 -13
View File
@@ -15,9 +15,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
if(turf_type)
var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags)
SSair.remove_from_active(newT)
CALCULATE_ADJACENT_TURFS(newT)
SSair.add_to_active(newT,1)
/turf/proc/copyTurf(turf/T)
if(T.type != type)
@@ -54,6 +52,14 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/proc/TerraformTurf(path, new_baseturf, flags)
return ChangeTurf(path, new_baseturf, flags)
/turf/proc/get_z_base_turf()
. = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
if (!ispath(.))
. = text2path(.)
if (!ispath(.))
warning("Z-level [z] has invalid baseturf '[SSmapping.level_trait(z, ZTRAIT_BASETURF)]'")
. = /turf/open/space
// Creates a new turf
// new_baseturfs can be either a single type or list of types, formated the same as baseturfs. see turf.dm
/turf/proc/ChangeTurf(path, list/new_baseturfs, flags)
@@ -61,12 +67,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
if(null)
return
if(/turf/baseturf_bottom)
path = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
if (!ispath(path))
path = text2path(path)
if (!ispath(path))
warning("Z-level [z] has invalid baseturf '[SSmapping.level_trait(z, ZTRAIT_BASETURF)]'")
path = /turf/open/space
path = get_z_base_turf()
if(/turf/open/space/basic)
// basic doesn't initialize and this will cause issues
// no warning though because this can happen naturaly as a result of it being built on top of
@@ -142,22 +143,25 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/open/ChangeTurf(path, list/new_baseturfs, flags)
if ((flags & CHANGETURF_INHERIT_AIR) && ispath(path, /turf/open))
SSair.remove_from_active(src)
var/datum/gas_mixture/stashed_air = new()
stashed_air.copy_from(air)
. = ..()
if (!.) // changeturf failed or didn't do anything
QDEL_NULL(stashed_air)
update_air_ref()
return
var/turf/open/newTurf = .
newTurf.air.copy_from(stashed_air)
update_air_ref(planetary_atmos ? 1 : 2)
QDEL_NULL(stashed_air)
SSair.add_to_active(newTurf)
else
if(ispath(path,/turf/closed))
flags |= CHANGETURF_RECALC_ADJACENT
return ..()
update_air_ref(-1)
. = ..()
else
. = ..()
if(!istype(air,/datum/gas_mixture))
Initalize_Atmos(0)
// Take off the top layer turf and replace it with the next baseturf down
/turf/proc/ScrapeAway(amount=1, flags)
@@ -317,7 +321,6 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
total.merge(S.air)
air.copy_from(total.remove_ratio(1/turf_count))
SSair.add_to_active(src)
/turf/proc/ReplaceWithLattice()
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
+2 -4
View File
@@ -11,12 +11,10 @@
/turf/closed/Initialize()
. = ..()
update_air_ref()
/turf/closed/AfterChange()
. = ..()
SSair.high_pressure_delta -= src
update_air_ref()
/turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE
@@ -201,13 +199,13 @@
desc = "A wall made out of a strange metal. The squares on it pulse in a predictable pattern."
icon = 'icons/turf/walls/hierophant_wall.dmi'
icon_state = "wall"
/turf/closed/indestructible/rock/glacierrock
name = "unaturally hard ice wall"
desc = "Ice, hardened over thousands of years, you're not breaking through this."
icon = 'icons/turf/walls.dmi'
icon_state = "snow_rock"
/turf/closed/indestructible/rock/glacierrock/blue
name = "blue ice wall"
desc = "The incredible compressive forces that formed this sturdy ice wall gave it a blue color."
+11 -14
View File
@@ -218,18 +218,15 @@
flash_color(L, flash_color = "#C80000", flash_time = 10)
/turf/open/Initalize_Atmos(times_fired)
set_excited(FALSE)
if(!blocks_air)
if(!istype(air,/datum/gas_mixture/turf))
air = new(2500,src)
air.copy_from_turf(src)
update_air_ref(planetary_atmos ? 1 : 2)
update_visuals()
current_cycle = times_fired
ImmediateCalculateAdjacentTurfs()
for(var/i in atmos_adjacent_turfs)
var/turf/open/enemy_tile = i
var/datum/gas_mixture/enemy_air = enemy_tile.return_air()
if(!get_excited() && air.compare(enemy_air))
//testing("Active turf found. Return value of compare(): [is_active]")
set_excited(TRUE)
SSair.add_to_active_extools(src)
/turf/open/proc/GetHeatCapacity()
. = air.heat_capacity()
@@ -323,8 +320,8 @@
/turf/open/rad_act(pulse_strength)
. = ..()
if (air.get_moles(/datum/gas/carbon_dioxide) && air.get_moles(/datum/gas/oxygen))
pulse_strength = min(pulse_strength,air.get_moles(/datum/gas/carbon_dioxide)*1000,air.get_moles(/datum/gas/oxygen)*2000) //Ensures matter is conserved properly
air.set_moles(/datum/gas/carbon_dioxide, max(air.get_moles(/datum/gas/carbon_dioxide)-(pulse_strength/1000),0))
air.set_moles(/datum/gas/oxygen, max(air.get_moles(/datum/gas/oxygen)-(pulse_strength/2000),0))
air.adjust_moles(/datum/gas/pluoxium, pulse_strength/4000)
if (air.get_moles(GAS_CO2) && air.get_moles(GAS_O2))
pulse_strength = min(pulse_strength,air.get_moles(GAS_CO2)*1000,air.get_moles(GAS_O2)*2000) //Ensures matter is conserved properly
air.set_moles(GAS_CO2, max(air.get_moles(GAS_CO2)-(pulse_strength/1000),0))
air.set_moles(GAS_O2, max(air.get_moles(GAS_O2)-(pulse_strength/2000),0))
air.adjust_moles(GAS_PLUOXIUM, pulse_strength/4000)
+95
View File
@@ -0,0 +1,95 @@
/turf/open/transparent
baseturfs = /turf/open/transparent/openspace
intact = FALSE //this means wires go on top
/turf/open/transparent/Initialize() // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker
. = ..()
plane = OPENSPACE_PLANE
layer = OPENSPACE_LAYER
return INITIALIZE_HINT_LATELOAD
/turf/open/transparent/LateInitialize()
update_multiz(TRUE, TRUE)
/turf/open/transparent/Destroy()
vis_contents.len = 0
return ..()
/turf/open/transparent/update_multiz(prune_on_fail = FALSE, init = FALSE)
. = ..()
var/turf/T = below()
if(!T)
vis_contents.len = 0
if(!show_bottom_level() && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to plating as a fallback
ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
return FALSE
if(init)
vis_contents += T
return TRUE
/turf/open/transparent/multiz_turf_del(turf/T, dir)
if(dir != DOWN)
return
update_multiz()
/turf/open/transparent/multiz_turf_new(turf/T, dir)
if(dir != DOWN)
return
update_multiz()
///Called when there is no real turf below this turf
/turf/open/transparent/proc/show_bottom_level()
var/turf/path = get_z_base_turf()
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER, plane = PLANE_SPACE)
underlays += underlay_appearance
return TRUE
/turf/open/transparent/glass
name = "Glass floor"
desc = "Dont jump on it, or do, I'm not your mom."
icon = 'icons/turf/floors/glass.dmi'
icon_state = "floor_glass"
smooth = SMOOTH_MORE
var/floor_tile = /obj/item/stack/sheet/glass
canSmoothWith = list(/turf/open/transparent/glass, /turf/open/transparent/glass/reinforced)
footstep = FOOTSTEP_PLATING
barefootstep = FOOTSTEP_HARD_BAREFOOT
clawfootstep = FOOTSTEP_HARD_CLAW
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
/turf/open/transparent/glass/Initialize()
icon_state = "" //Prevent the normal icon from appearing behind the smooth overlays
..()
return INITIALIZE_HINT_LATELOAD
/turf/open/floor/glass/LateInitialize()
. = ..()
// AddElement(/datum/element/turf_z_transparency, TRUE)
/turf/open/transparent/glass/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You begin removing glass...</span>")
if(I.use_tool(src, user, 30, volume=80))
if(!istype(src, /turf/open/transparent/glass))
return TRUE
if(floor_tile)
new floor_tile(src, 2)
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
return TRUE
/turf/open/transparent/glass/reinforced
name = "Reinforced glass floor"
desc = "Do jump on it, it can take it."
icon = 'icons/turf/floors/reinf_glass.dmi'
floor_tile = /obj/item/stack/sheet/rglass
/turf/open/transparent/glass/reinforced/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You begin removing reinforced glass...</span>")
if(I.use_tool(src, user, 30, volume=80))
if(!istype(src, /turf/open/transparent/glass/reinforced))
return TRUE
if(floor_tile)
new floor_tile(src, 2)
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
return TRUE
+1 -1
View File
@@ -27,7 +27,7 @@
var/icon_regular_floor = "floor" //used to remember what icon the tile should have by default
var/icon_plating = "plating"
thermal_conductivity = 0.004
thermal_conductivity = 0.04
heat_capacity = 10000
intact = 1
var/broken = 0
@@ -69,7 +69,7 @@
ChangeTurf(/turf/open/floor/plating/rust)
/turf/open/floor/wood/cold
temperature = 255.37
initial_temperature = 255.37
/turf/open/floor/wood/airless
initial_gas_mix = AIRLESS_ATMOS
@@ -177,7 +177,7 @@
icon = 'icons/turf/floors/ice_turf.dmi'
icon_state = "unsmooth"
initial_gas_mix = FROZEN_ATMOS
temperature = 180
initial_temperature = 180
planetary_atmos = TRUE
baseturfs = /turf/open/floor/plating/ice
slowdown = 1
@@ -201,10 +201,10 @@
canSmoothWith = list(/turf/open/floor/plating/ice/smooth, /turf/open/floor/plating/ice, /turf/open/floor/plating/ice/colder)
/turf/open/floor/plating/ice/colder
temperature = 140
initial_temperature = 140
/turf/open/floor/plating/ice/temperate
temperature = 255.37
initial_temperature = 255.37
/turf/open/floor/plating/ice/break_tile()
return
@@ -221,7 +221,7 @@
icon = 'icons/turf/snow.dmi'
icon_state = "snowplating"
initial_gas_mix = FROZEN_ATMOS
temperature = 180
initial_temperature = 180
attachment_holes = FALSE
planetary_atmos = TRUE
footstep = FOOTSTEP_SAND
@@ -230,7 +230,7 @@
heavyfootstep = FOOTSTEP_GENERIC_HEAVY
/turf/open/floor/plating/snowed/cavern
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120"
initial_gas_mix = "n2=82;plasma=24;TEMP=120"
/turf/open/floor/plating/snowed/smoothed
smooth = SMOOTH_MORE | SMOOTH_BORDER
@@ -240,10 +240,10 @@
icon_state = "smooth"
/turf/open/floor/plating/snowed/colder
temperature = 140
initial_temperature = 140
/turf/open/floor/plating/snowed/temperatre
temperature = 255.37
initial_temperature = 255.37
/turf/open/floor/plating/snowed/smoothed/icemoon
initial_gas_mix = ICEMOON_DEFAULT_ATMOS
@@ -3,7 +3,7 @@
name = "reinforced floor"
desc = "Extremely sturdy."
icon_state = "engine"
thermal_conductivity = 0.0025
thermal_conductivity = 0.025
heat_capacity = INFINITY
floor_tile = /obj/item/stack/rods
footstep = FOOTSTEP_PLATING
+1 -1
View File
@@ -14,8 +14,8 @@
density = TRUE
blocks_air = TRUE
layer = EDGED_TURF_LAYER
initial_temperature = 293.15
// base_icon_state = "smoothrocks"
temperature = TCMB
var/smooth_icon = 'icons/turf/smoothrocks.dmi'
var/environment_type = "asteroid"
var/turf/open/floor/plating/turf_type = /turf/open/floor/plating/asteroid/airless
@@ -90,7 +90,7 @@
icon = 'icons/turf/walls/plasma_wall.dmi'
icon_state = "plasma"
sheet_type = /obj/item/stack/sheet/mineral/plasma
thermal_conductivity = 0.004
thermal_conductivity = 0.04
canSmoothWith = list(/turf/closed/wall/mineral/plasma, /obj/structure/falsewall/plasma)
/turf/closed/wall/mineral/plasma/attackby(obj/item/W, mob/user, params)
+10 -13
View File
@@ -5,8 +5,8 @@
intact = 0
dirt_buildup_allowed = FALSE
temperature = TCMB
thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
initial_temperature = TCMB
thermal_conductivity = 0
heat_capacity = 700000
wave_explosion_multiply = EXPLOSION_DAMPEN_SPACE
wave_explosion_block = EXPLOSION_BLOCK_SPACE
@@ -15,7 +15,7 @@
var/destination_x
var/destination_y
var/static/datum/gas_mixture/immutable/space/space_gas = new
var/static/datum/gas_mixture/immutable/space/space_gas
plane = PLANE_SPACE
layer = SPACE_LAYER
light_power = 0.25
@@ -36,8 +36,10 @@
/turf/open/space/Initialize()
SHOULD_CALL_PARENT(FALSE)
icon_state = SPACE_ICON_STATE
if(!space_gas)
space_gas = new
air = space_gas
update_air_ref()
update_air_ref(0)
vis_contents.Cut() //removes inherited overlays
visibilityChanged()
@@ -58,9 +60,6 @@
if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A))
add_overlay(/obj/effect/fullbright)
if(requires_activation)
SSair.add_to_active(src)
if (light_power && light_range)
update_light()
@@ -103,6 +102,9 @@
/turf/open/space/remove_air(amount)
return null
/turf/open/space/remove_air_ratio(amount)
return null
/turf/open/space/proc/update_starlight()
if(CONFIG_GET(flag/starlight))
for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
@@ -318,12 +320,7 @@
///Called when there is no real turf below this turf
/turf/open/space/transparent/proc/show_bottom_level()
var/turf/path = SSmapping.level_trait(z, ZTRAIT_BASETURF) || /turf/open/space
if(!ispath(path))
path = text2path(path)
if(!ispath(path))
warning("Z-level [z] has invalid baseturf '[SSmapping.level_trait(z, ZTRAIT_BASETURF)]'")
path = /turf/open/space
var/turf/path = get_z_base_turf()
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER, plane = PLANE_SPACE)
underlays += underlay_appearance
return TRUE
+13 -3
View File
@@ -16,7 +16,7 @@ GLOBAL_LIST_EMPTY(station_turfs)
// This shouldn't be modified directly, use the helper procs.
var/list/baseturfs = /turf/baseturf_bottom
var/temperature = T20C
var/initial_temperature = T20C
var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed
var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to
@@ -76,7 +76,6 @@ GLOBAL_LIST_EMPTY(station_turfs)
if(requires_activation)
CALCULATE_ADJACENT_TURFS(src)
SSair.add_to_active(src)
if (light_power && light_range)
update_light()
@@ -96,9 +95,21 @@ GLOBAL_LIST_EMPTY(station_turfs)
set_custom_materials(custom_materials)
ComponentInitialize()
if(isopenturf(src))
var/turf/open/O = src
__auxtools_update_turf_temp_info(isspaceturf(get_z_base_turf()) && !O.planetary_atmos)
else
update_air_ref(-1)
__auxtools_update_turf_temp_info(isspaceturf(get_z_base_turf()))
return INITIALIZE_HINT_NORMAL
/turf/proc/__auxtools_update_turf_temp_info()
/turf/return_temperature()
/turf/proc/set_temperature()
/turf/proc/Initalize_Atmos(times_fired)
CALCULATE_ADJACENT_TURFS(src)
@@ -120,7 +131,6 @@ GLOBAL_LIST_EMPTY(station_turfs)
for(var/A in B.contents)
qdel(A)
return
SSair.remove_from_active(src)
visibilityChanged()
QDEL_LIST(blueprint_data)
flags_1 &= ~INITIALIZED_1
+15 -36
View File
@@ -7,46 +7,20 @@ GLOBAL_VAR_INIT(tgs_initialized, FALSE)
GLOBAL_VAR(topic_status_lastcache)
GLOBAL_LIST(topic_status_cache)
/**
* World creation
*
* Here is where a round itself is actually begun and setup.
* * db connection setup
* * config loaded from files
* * loads admins
* * Sets up the dynamic menu system
* * and most importantly, calls initialize on the master subsystem, starting the game loop that causes the rest of the game to begin processing and setting up
*
*
* Nothing happens until something moves. ~Albert Einstein
*
* For clarity, this proc gets triggered later in the initialization pipeline, it is not the first thing to happen, as it might seem.
*
* Initialization Pipeline:
* Global vars are new()'ed, (including config, glob, and the master controller will also new and preinit all subsystems when it gets new()ed)
* Compiled in maps are loaded (mainly centcom). all areas/turfs/objs/mobs(ATOMs) in these maps will be new()ed
* world/New() (You are here)
* Once world/New() returns, client's can connect.
* 1 second sleep
* Master Controller initialization.
* Subsystem initialization.
* Non-compiled-in maps are maploaded, all atoms are new()ed
* All atoms in both compiled and uncompiled maps are initialized()
*/
//This happens after the Master subsystem new(s) (it's a global datum)
//So subsystems globals exist, but are not initialised
/world/New()
if (fexists(EXTOOLS))
call(EXTOOLS, "maptick_initialize")()
#ifdef EXTOOLS_LOGGING
call(EXTOOLS, "init_logging")()
else
CRASH("[EXTOOLS] does not exist!")
#endif
enable_debugger()
var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL")
if (debug_server)
call(debug_server, "auxtools_init")()
enable_debugging()
AUXTOOLS_CHECK(AUXMOS)
#ifdef REFERENCE_TRACKING
enable_reference_tracking()
#endif
world.Profile(PROFILE_START)
log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!")
GLOB.config_error_log = GLOB.world_manifest_log = GLOB.world_pda_log = GLOB.world_job_debug_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = "data/logs/config_error.[GUID()].log" //temporary file used to record errors with loading config, moved to log directory once logging is set bl
@@ -298,10 +272,15 @@ GLOBAL_LIST(topic_status_cache)
log_world("World rebooted at [TIME_STAMP("hh:mm:ss", FALSE)]")
shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss.
AUXTOOLS_SHUTDOWN(AUXMOS)
..()
/world/Del()
shutdown_logging() // makes sure the thread is closed before end, else we terminate
AUXTOOLS_SHUTDOWN(AUXMOS)
var/debug_server = world.GetConfig("env", "AUXTOOLS_DEBUG_DLL")
if (debug_server)
call(debug_server, "auxtools_shutdown")()
..()
/world/proc/update_status()
@@ -378,7 +357,7 @@ GLOBAL_LIST(topic_status_cache)
SSidlenpcpool.MaxZChanged()
world.refresh_atmos_grid()
/// Extools atmos
/// Auxtools atmos
/world/proc/refresh_atmos_grid()
/world/proc/change_fps(new_value = 20)
+1
View File
@@ -194,6 +194,7 @@ GLOBAL_PROTECT(admin_verbs_debug)
// /client/proc/check_missing_sprites,
// #endif
/datum/admins/proc/create_or_modify_area,
/datum/admins/proc/fixcorruption,
#ifdef REFERENCE_TRACKING
/datum/admins/proc/view_refs,
/datum/admins/proc/view_del_failures,
+1 -1
View File
@@ -581,7 +581,7 @@
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
Plasma.air_contents.set_moles(/datum/gas/plasma,70)
Plasma.air_contents.set_moles(GAS_PLASMA,70)
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.forceMove(Rad)
+1 -1
View File
@@ -10,7 +10,7 @@
for(var/id in env.get_gases())
var/moles = env.get_moles(id)
if (moles >= 0.00001)
lines += "[GLOB.meta_gas_names[id]]: [moles] mol"
lines += "[GLOB.gas_data.names[id]]: [moles] mol"
to_chat(usr, lines.Join("\n"))
/client/proc/air_status(turf/target)
@@ -4,7 +4,7 @@ GLOBAL_LIST_EMPTY(deletion_failures)
/world/proc/enable_reference_tracking()
if (fexists(EXTOOLS))
call(EXTOOLS, "ref_tracking_initialize")()
//call(EXTOOLS, "ref_tracking_initialize")()
/proc/get_back_references(datum/D)
CRASH("/proc/get_back_references not hooked by extools, reference tracking will not function!")
@@ -64,7 +64,7 @@
result++
. -= result - 1
/obj/structure/blob/BlockSuperconductivity()
/obj/structure/blob/BlockThermalConductivity()
return atmosblock
/obj/structure/blob/CanPass(atom/movable/mover, turf/target)
@@ -29,7 +29,7 @@
return
return TRUE
/obj/effect/clockwork/servant_blocker/BlockSuperconductivity()
/obj/effect/clockwork/servant_blocker/BlockThermalConductivity()
return TRUE
/obj/effect/clockwork/servant_blocker/singularity_act()
+1 -1
View File
@@ -647,7 +647,7 @@ structure_check() searches for nearby cultist structures required for the invoca
GLOB.wall_runes -= src
return ..()
/obj/effect/rune/wall/BlockSuperconductivity()
/obj/effect/rune/wall/BlockThermalConductivity()
return density
/obj/effect/rune/wall/invoke(var/list/invokers)
+2 -3
View File
@@ -146,7 +146,7 @@
return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
var/fuel_moles = air_contents.get_moles(GAS_PLASMA) + air_contents.get_moles(GAS_O2)/6
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1
@@ -196,9 +196,8 @@
ground_zero.air_update_turf()
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(removed)
T.assume_air(air_contents)
air_update_turf()
@@ -0,0 +1,37 @@
// Breathing classes are, yes, just a list of gases, associated with numbers.
// But they're very simple: pluoxium's status as O2 * 8 is represented here,
// with a single line of code, no hardcoding and special-casing across the codebase.
// Not only that, but they're very general: you could have a negative value
// to simulate asphyxiants, e.g. if I add krypton it could go into the oxygen
// breathing class at -7, simulating krypton narcosis.
/datum/breathing_class
var/list/gases = null
var/list/products = null
var/danger_reagent = null
var/low_alert_category = "not_enough_oxy"
var/low_alert_datum = /obj/screen/alert/not_enough_oxy
var/high_alert_category = "too_much_oxy"
var/high_alert_datum = /obj/screen/alert/too_much_oxy
/datum/breathing_class/oxygen
gases = list(
GAS_O2 = 1,
GAS_PLUOXIUM = 8,
GAS_CO2 = -0.7, // CO2 isn't actually toxic, just an asphyxiant
)
products = list(
GAS_CO2 = 1,
)
/datum/breathing_class/plasma
gases = list(
GAS_PLASMA = 1
)
products = list(
GAS_CO2 = 1
)
low_alert_category = "not_enough_tox"
low_alert_datum = /obj/screen/alert/not_enough_tox
high_alert_category = "too_much_tox"
high_alert_datum = /obj/screen/alert/too_much_tox
@@ -0,0 +1,169 @@
/datum/gas/oxygen
id = GAS_O2
specific_heat = 20
name = "Oxygen"
oxidation_temperature = T0C - 100 // it checks max of this and fire temperature, so rarely will things spontaneously combust
/datum/gas/nitrogen
id = GAS_N2
specific_heat = 20
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_nitro",
alert_type = /obj/screen/alert/not_enough_nitro
),
too_much_alert = list(
alert_category = "too_much_nitro",
alert_type = /obj/screen/alert/too_much_nitro
)
)
name = "Nitrogen"
/datum/gas/carbon_dioxide //what the fuck is this?
id = GAS_CO2
specific_heat = 30
name = "Carbon Dioxide"
breath_results = GAS_O2
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_co2",
alert_type = /obj/screen/alert/not_enough_co2
),
too_much_alert = list(
alert_category = "too_much_co2",
alert_type = /obj/screen/alert/too_much_co2
)
)
fusion_power = 3
/datum/gas/plasma
id = GAS_PLASMA
specific_heat = 200
name = "Plasma"
gas_overlay = "plasma"
moles_visible = MOLES_GAS_VISIBLE
flags = GAS_FLAG_DANGEROUS
// no fire info cause it has its own bespoke reaction for trit generation reasons
/datum/gas/water_vapor
id = GAS_H2O
specific_heat = 40
name = "Water Vapor"
gas_overlay = "water_vapor"
moles_visible = MOLES_GAS_VISIBLE
fusion_power = 8
breath_reagent = /datum/reagent/water
/datum/gas/hypernoblium
id = GAS_HYPERNOB
specific_heat = 2000
name = "Hyper-noblium"
gas_overlay = "freon"
moles_visible = MOLES_GAS_VISIBLE
/datum/gas/nitrous_oxide
id = GAS_NITROUS
specific_heat = 40
name = "Nitrous Oxide"
gas_overlay = "nitrous_oxide"
moles_visible = MOLES_GAS_VISIBLE * 2
flags = GAS_FLAG_DANGEROUS
fire_products = list(GAS_N2 = 1)
oxidation_rate = 0.5
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100
/datum/gas/nitryl
id = GAS_NITRYL
specific_heat = 20
name = "Nitryl"
gas_overlay = "nitryl"
moles_visible = MOLES_GAS_VISIBLE
flags = GAS_FLAG_DANGEROUS
fusion_power = 15
fire_products = list(GAS_N2 = 0.5)
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
/datum/gas/tritium
id = GAS_TRITIUM
specific_heat = 10
name = "Tritium"
gas_overlay = "tritium"
moles_visible = MOLES_GAS_VISIBLE
flags = GAS_FLAG_DANGEROUS
fusion_power = 1
/*
these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons
fire_provides = list(GAS_H2O = 2)
fire_burn_rate = 2
fire_energy_released = FIRE_HYDROGEN_ENERGY_RELEASED
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
*/
/datum/gas/bz
id = GAS_BZ
specific_heat = 20
name = "BZ"
flags = GAS_FLAG_DANGEROUS
fusion_power = 8
/datum/gas/stimulum
id = GAS_STIMULUM
specific_heat = 5
name = "Stimulum"
fusion_power = 7
/datum/gas/pluoxium
id = GAS_PLUOXIUM
specific_heat = 80
name = "Pluoxium"
fusion_power = 10
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 1000 // it is VERY stable
oxidation_rate = 8
/datum/gas/miasma
id = GAS_MIASMA
specific_heat = 20
fusion_power = 50
name = "Miasma"
gas_overlay = "miasma"
moles_visible = MOLES_GAS_VISIBLE * 60
/datum/gas/methane
id = GAS_METHANE
specific_heat = 30
name = "Methane"
breath_results = GAS_METHYL_BROMIDE
fire_products = list(GAS_CO2 = 1, GAS_H2O = 2)
fire_burn_rate = 0.5
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_ch4",
alert_type = /obj/screen/alert/not_enough_ch4
),
too_much_alert = list(
alert_category = "too_much_ch4",
alert_type = /obj/screen/alert/too_much_ch4
)
)
fire_energy_released = FIRE_CARBON_ENERGY_RELEASED
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
/datum/gas/methyl_bromide
id = GAS_METHYL_BROMIDE
specific_heat = 42
name = "Methyl Bromide"
flags = GAS_FLAG_DANGEROUS
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_ch3br",
alert_type = /obj/screen/alert/not_enough_ch3br
),
too_much_alert = list(
alert_category = "too_much_ch3br",
alert_type = /obj/screen/alert/too_much_ch3br
)
)
fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BZ = 0.5)
fire_energy_released = FIRE_CARBON_ENERGY_RELEASED
fire_burn_rate = 0.5
fire_temperature = 808 // its autoignition, it apparently doesn't spark readily, so i don't put it lower
@@ -13,28 +13,21 @@
if(!air)
return
var/oxy = air.get_moles(/datum/gas/oxygen)
if (oxy < 0.5)
if (air.get_oxidation_power(exposed_temperature) < 0.5)
return
var/tox = air.get_moles(/datum/gas/plasma)
var/trit = air.get_moles(/datum/gas/tritium)
var/has_fuel = air.get_moles(GAS_PLASMA) > 0.5 || air.get_moles(GAS_TRITIUM) > 0.5 || air.get_fuel_amount(exposed_temperature) > 0.5
if(active_hotspot)
if(soh)
if(tox > 0.5 || trit > 0.5)
if(has_fuel)
if(active_hotspot.temperature < exposed_temperature)
active_hotspot.temperature = exposed_temperature
if(active_hotspot.volume < exposed_volume)
active_hotspot.volume = exposed_volume
return
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (tox > 0.5 || trit > 0.5))
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && has_fuel)
active_hotspot = new /obj/effect/hotspot(src, exposed_volume*25, exposed_temperature)
active_hotspot.just_spawned = (current_cycle < SSair.times_fired)
//remove just_spawned protection if no longer processing this cell
SSair.add_to_active(src, 0)
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
/obj/effect/hotspot
anchored = TRUE
@@ -48,7 +41,6 @@
var/volume = 125
var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
var/just_spawned = TRUE
var/bypassing = FALSE
var/visual_update_tick = 0
@@ -70,7 +62,7 @@
location.active_hotspot = src
bypassing = !just_spawned && (volume > CELL_VOLUME*0.95)
bypassing = volume > CELL_VOLUME*0.95
if(bypassing)
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
@@ -150,10 +142,6 @@
#define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)
/obj/effect/hotspot/process()
if(just_spawned)
just_spawned = FALSE
return
var/turf/open/location = loc
if(!istype(location))
qdel(src)
@@ -164,13 +152,7 @@
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
qdel(src)
return
if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
qdel(src)
return
//Not enough to burn
// god damn it previous coder you made the INSUFFICIENT macro for a fucking reason why didn't you use it here smh
if((INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
if(!location.air || location.air.get_oxidation_power() < 0.5 || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM) && location.air.get_fuel_amount() < 0.5))
qdel(src)
return
@@ -19,57 +19,58 @@
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
var/opp = REVERSE_DIR(dir)
var/R = FALSE
. = TRUE
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
R = TRUE
. = FALSE
if(blocks_air || T.blocks_air)
R = TRUE
. = FALSE
if (T == src)
return !R
return .
for(var/obj/O in contents+T.contents)
var/turf/other = (O.loc == src ? T : src)
if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other))))
R = TRUE
if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
atmos_supeconductivity |= dir
T.atmos_supeconductivity |= opp
return FALSE //no need to keep going, we got all we asked
. = FALSE
if(O.BlockThermalConductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
conductivity_blocked_directions |= dir
T.conductivity_blocked_directions |= opp
if(!.)
return .
atmos_supeconductivity &= ~dir
T.atmos_supeconductivity &= ~opp
return !R
/atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm.
/atom/movable/proc/BlockThermalConductivity() // Objects that don't let heat through.
return FALSE
/turf/proc/ImmediateCalculateAdjacentTurfs()
if(SSair.thread_running())
CALCULATE_ADJACENT_TURFS(src)
return
var/canpass = CANATMOSPASS(src, src)
var/canvpass = CANVERTICALATMOSPASS(src, src)
for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction)
var/opp_dir = REVERSE_DIR(direction)
if(!isopenturf(T))
if(!istype(T))
continue
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
var/opp_dir = REVERSE_DIR(direction)
if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = direction
T.atmos_adjacent_turfs[src] = opp_dir
T.__update_extools_adjacent_turfs()
else
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= T
if (T.atmos_adjacent_turfs)
T.atmos_adjacent_turfs -= src
T.__update_extools_adjacent_turfs()
UNSETEMPTY(T.atmos_adjacent_turfs)
T.set_sleeping(T.blocks_air)
T.__update_auxtools_turf_adjacency_info(isspaceturf(T.get_z_base_turf()), -1)
UNSETEMPTY(atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs
__update_extools_adjacent_turfs()
set_sleeping(blocks_air)
__update_auxtools_turf_adjacency_info(isspaceturf(get_z_base_turf()))
/turf/proc/__update_extools_adjacent_turfs()
/turf/proc/set_sleeping(should_sleep)
/turf/proc/__update_auxtools_turf_adjacency_info()
//returns a list of adjacent turfs that can share air with this one.
//alldir includes adjacent diagonal tiles that can share
@@ -111,7 +112,6 @@
/turf/air_update_turf(command = 0)
if(command)
ImmediateCalculateAdjacentTurfs()
SSair.add_to_active(src,command)
/atom/movable/proc/move_update_air(turf/T)
if(isturf(T))
@@ -130,7 +130,4 @@
var/datum/gas_mixture/G = new
G.parse_gas_string(text)
air.merge(G)
archive()
SSair.add_to_active(src, 0)
assume_air(G)
@@ -1,18 +1,13 @@
/turf
//used for temperature calculations
var/thermal_conductivity = 0.005
//conductivity is divided by 10 when interacting with air for balance purposes
var/thermal_conductivity = 0.05
var/heat_capacity = 1
var/temperature_archived
//list of open turfs adjacent to us
var/list/atmos_adjacent_turfs
//bitfield of dirs in which we are superconducitng
var/atmos_supeconductivity = NONE
var/is_openturf = FALSE // used by extools shizz.
//used to determine whether we should archive
var/archived_cycle = 0
var/current_cycle = 0
//bitfield of dirs in which we thermal conductivity is blocked
var/conductivity_blocked_directions = NONE
//used for mapping and for breathing while in walls (because that's a thing that needs to be accounted for...)
//string parsed by /datum/gas/proc/copy_from_turf
@@ -32,21 +27,17 @@
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time
var/list/atmos_overlay_types //gas IDs of current active gas overlays
is_openturf = TRUE
/turf/open/Initialize()
if(!blocks_air)
air = new
air = new(2500,src)
air.copy_from_turf(src)
update_air_ref()
update_air_ref(planetary_atmos ? 1 : 2)
. = ..()
/turf/open/Destroy()
if(active_hotspot)
QDEL_NULL(active_hotspot)
// Adds the adjacent turfs to the current atmos processing
for(var/T in atmos_adjacent_turfs)
SSair.add_to_active(T)
return ..()
/// Function for Extools Atmos
@@ -55,10 +46,46 @@
/////////////////GAS MIXTURE PROCS///////////////////
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
return assume_air_ratio(giver, 1)
/turf/open/assume_air_moles(datum/gas_mixture/giver, moles)
if(!giver)
return FALSE
air.merge(giver)
update_visuals()
if(SSair.thread_running())
SSair.deferred_airs += list(list(giver, air, moles / giver.total_moles()))
else
giver.transfer_to(air, moles)
update_visuals()
return TRUE
/turf/open/assume_air_ratio(datum/gas_mixture/giver, ratio)
if(!giver)
return FALSE
if(SSair.thread_running())
SSair.deferred_airs += list(list(giver, air, ratio))
else
giver.transfer_ratio_to(air, ratio)
update_visuals()
return TRUE
/turf/open/transfer_air(datum/gas_mixture/taker, moles)
if(!taker || !return_air()) // shouldn't transfer from space
return FALSE
if(SSair.thread_running())
SSair.deferred_airs += list(list(air, taker, moles / air.total_moles()))
else
air.transfer_to(taker, moles)
update_visuals()
return TRUE
/turf/open/transfer_air_ratio(datum/gas_mixture/taker, ratio)
if(!taker || !return_air())
return FALSE
if(SSair.thread_running())
SSair.deferred_airs += list(list(air, taker, ratio))
else
air.transfer_ratio_to(taker, ratio)
update_visuals()
return TRUE
/turf/open/remove_air(amount)
@@ -67,6 +94,12 @@
update_visuals()
return removed
/turf/open/remove_air_ratio(ratio)
var/datum/gas_mixture/ours = return_air()
var/datum/gas_mixture/removed = ours.remove_ratio(ratio)
update_visuals()
return removed
/turf/open/proc/copy_air_with_tile(turf/open/T)
if(istype(T))
air.copy_from(T.air)
@@ -86,17 +119,9 @@
return air
/turf/temperature_expose()
if(temperature > heat_capacity)
if(return_temperature() > heat_capacity)
to_be_destroyed = TRUE
/turf/proc/archive()
temperature_archived = temperature
/turf/open/archive()
air.archive()
archived_cycle = SSair.times_fired
temperature_archived = temperature
/turf/open/proc/eg_reset_cooldowns()
/turf/open/proc/eg_garbage_collect()
/turf/open/proc/get_excited()
@@ -121,8 +146,8 @@
for(var/id in air.get_gases())
if (nonoverlaying_gases[id])
continue
var/gas_overlay = GLOB.meta_gas_overlays[id]
if(gas_overlay && air.get_moles(id) > GLOB.meta_gas_visibility[META_GAS_MOLES_VISIBLE])
var/gas_overlay = GLOB.gas_data.overlays[id]
if(gas_overlay && air.get_moles(id) > GLOB.gas_data.visibility[id])
new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(air.get_moles(id) / MOLES_GAS_VISIBLE_STEP, 1))]
if (atmos_overlay_types)
@@ -156,7 +181,7 @@
for (var/gastype in subtypesof(/datum/gas))
var/datum/gas/gasvar = gastype
if (!initial(gasvar.gas_overlay))
.[gastype] = TRUE
.[initial(gasvar.id)] = TRUE
/////////////////////////////SIMULATION///////////////////////////////////
@@ -171,7 +196,6 @@
}
*/
/turf/proc/process_cell(fire_count)
SSair.remove_from_active(src)
/turf/open/proc/equalize_pressure_in_zone(cyclenum)
/turf/open/proc/consider_firelocks(turf/T2)
@@ -198,7 +222,10 @@
//////////////////////////SPACEWIND/////////////////////////////
/turf/open/proc/consider_pressure_difference(turf/T, difference)
/turf/proc/consider_pressure_difference()
return
/turf/open/consider_pressure_difference(turf/T, difference)
if(difference > pressure_difference)
pressure_direction = get_dir(src, T)
pressure_difference = difference
@@ -236,117 +263,3 @@
if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO))))
step(src, direction)
////////////////////////SUPERCONDUCTIVITY/////////////////////////////
/turf/proc/conductivity_directions()
if(archived_cycle < SSair.times_fired)
archive()
return NORTH|SOUTH|EAST|WEST
/turf/open/conductivity_directions()
if(blocks_air)
return ..()
for(var/direction in GLOB.cardinals)
var/turf/T = get_step(src, direction)
if(!(T in atmos_adjacent_turfs) && !(atmos_supeconductivity & direction))
. |= direction
/turf/proc/neighbor_conduct_with_src(turf/open/other)
if(!other.blocks_air) //Open but neighbor is solid
other.temperature_share_open_to_solid(src)
else //Both tiles are solid
other.share_temperature_mutual_solid(src, thermal_conductivity)
temperature_expose(null, temperature, null)
/turf/open/neighbor_conduct_with_src(turf/other)
if(blocks_air)
..()
return
if(!other.blocks_air) //Both tiles are open
var/turf/open/T = other
T.air.temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else //Solid but neighbor is open
temperature_share_open_to_solid(other)
SSair.add_to_active(src, 0)
/turf/proc/super_conduct()
var/conductivity_directions = conductivity_directions()
archive()
if(conductivity_directions)
//Conduct with tiles around me
for(var/direction in GLOB.cardinals)
if(conductivity_directions & direction)
var/turf/neighbor = get_step(src,direction)
if(!neighbor.thermal_conductivity)
continue
if(neighbor.archived_cycle < SSair.times_fired)
neighbor.archive()
neighbor.neighbor_conduct_with_src(src)
neighbor.consider_superconductivity()
radiate_to_spess()
finish_superconduction()
/turf/proc/finish_superconduction(temp = temperature)
//Make sure still hot enough to continue conducting heat
if(temp < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
SSair.active_super_conductivity -= src
return FALSE
/turf/open/finish_superconduction()
//Conduct with air on my tile if I have it
if(!blocks_air)
temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity)
..((blocks_air ? temperature : air.return_temperature()))
/turf/proc/consider_superconductivity()
if(!thermal_conductivity)
return FALSE
SSair.active_super_conductivity[src] = TRUE
return TRUE
/turf/open/consider_superconductivity(starting)
if(planetary_atmos)
return FALSE
if(air.return_temperature() < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return FALSE
if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant.
return FALSE
return ..()
/turf/closed/consider_superconductivity(starting)
if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return FALSE
return ..()
/turf/proc/radiate_to_spess() //Radiate excess tile heat to space
if(temperature > T0C) //Considering 0 degC as te break even point for radiation in and out
var/delta_temperature = (temperature_archived - TCMB) //hardcoded space temperature
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
var/heat = thermal_conductivity*delta_temperature* \
(heat_capacity*HEAT_CAPACITY_VACUUM/(heat_capacity+HEAT_CAPACITY_VACUUM))
temperature -= heat/heat_capacity
temperature = max(temperature,T0C) //otherwise we just sorta get stuck at super cold temps forever
/turf/open/proc/temperature_share_open_to_solid(turf/sharer)
sharer.temperature = air.temperature_share(null, sharer.thermal_conductivity, sharer.temperature, sharer.heat_capacity)
/turf/proc/share_temperature_mutual_solid(turf/sharer, conduction_coefficient) //to be understood
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
var/heat = conduction_coefficient*delta_temperature* \
(heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
temperature -= heat/heat_capacity
sharer.temperature += heat/sharer.heat_capacity
temperature = max(temperature,T0C)
sharer.temperature = max(sharer.temperature,T0C)
@@ -0,0 +1,131 @@
GLOBAL_LIST_INIT(hardcoded_gases, list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLASMA)) //the main four gases, which were at one time hardcoded
GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLUOXIUM, GAS_STIMULUM, GAS_NITRYL))) //unable to react amongst themselves
// Auxgm
// It's a send-up of XGM, like what baystation got.
// It's got the same architecture as XGM, but it's structured
// differently to make it more convenient for auxmos.
// Most important compared to TG is that it does away with hardcoded typepaths,
// which lead to problems on the auxmos end anyway. We cache the string value
// references on the Rust end, so no performance is lost here.
// Also allows you to add new gases at runtime
/proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas
/datum/auxgm
var/list/datums = list()
var/list/specific_heats = list()
var/list/names = list()
var/list/visibility = list()
var/list/overlays = list()
var/list/flags = list()
var/list/ids = list()
var/list/typepaths = list()
var/list/fusion_powers = list()
var/list/breathing_classes = list()
var/list/breath_results = list()
var/list/breath_reagents = list()
var/list/breath_reagents_dangerous = list()
var/list/breath_alert_info = list()
var/list/oxidation_temperatures = list()
var/list/oxidation_rates = list()
var/list/fire_temperatures = list()
var/list/fire_enthalpies = list()
var/list/fire_products = list()
var/list/fire_burn_rates = list()
/datum/gas
var/id = ""
var/specific_heat = 0
var/name = ""
var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi
var/moles_visible = null
var/flags = NONE //currently used by canisters
var/fusion_power = 0 // How much the gas destabilizes a fusion reaction
var/breath_results = GAS_CO2 // what breathing this breathes out
var/breath_reagent = null // what breathing this adds to your reagents
var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something
var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none
var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material
var/fire_temperature = null // temperature above which gas may catch fire; null for none
var/list/fire_products = null // what results when this gas is burned (oxidizer or fuel); null for none
var/fire_energy_released = 0 // how much energy is released per mole of fuel burned
var/fire_burn_rate = 1 // how many moles are burned per product released
/datum/gas/proc/breath(partial_pressure, light_threshold, heavy_threshold, moles, mob/living/carbon/C, obj/item/organ/lungs/lungs)
// This is only called on gases with the GAS_FLAG_BREATH_PROC flag. When possible, do NOT use this--
// greatly prefer just adding a reagent. This is mostly around for legacy reasons.
return null
/datum/auxgm/proc/add_gas(datum/gas/gas)
var/g = gas.id
if(g)
datums[g] = gas
specific_heats[g] = gas.specific_heat
names[g] = gas.name
if(gas.moles_visible)
visibility[g] = gas.moles_visible
overlays[g] = new /list(FACTOR_GAS_VISIBLE_MAX)
for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
overlays[g][i] = new /obj/effect/overlay/gas(gas.gas_overlay, i * 255 / FACTOR_GAS_VISIBLE_MAX)
else
visibility[g] = 0
overlays[g] = 0
flags[g] = gas.flags
ids[g] = g
typepaths[g] = gas.type
fusion_powers[g] = gas.fusion_power
if(gas.breath_alert_info)
breath_alert_info[g] = gas.breath_alert_info
breath_results[g] = gas.breath_results
if(gas.breath_reagent)
breath_reagents[g] = gas.breath_reagent
if(gas.breath_reagent_dangerous)
breath_reagents_dangerous[g] = gas.breath_reagent_dangerous
if(gas.oxidation_temperature)
oxidation_temperatures[g] = gas.oxidation_temperature
oxidation_rates[g] = gas.oxidation_rate
if(gas.fire_products)
fire_products[g] = gas.fire_products
fire_enthalpies[g] = gas.fire_energy_released
else if(gas.fire_temperature)
fire_temperatures[g] = gas.fire_temperature
fire_burn_rates[g] = gas.fire_burn_rate
if(gas.fire_products)
fire_products[g] = gas.fire_products
fire_enthalpies[g] = gas.fire_energy_released
_auxtools_register_gas(gas)
/proc/finalize_gas_refs()
/datum/auxgm/New()
for(var/gas_path in subtypesof(/datum/gas))
var/datum/gas/gas = new gas_path
add_gas(gas)
for(var/breathing_class_path in subtypesof(/datum/breathing_class))
var/datum/breathing_class/class = new breathing_class_path
breathing_classes[breathing_class_path] = class
finalize_gas_refs()
GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new)
/obj/effect/overlay/gas
icon = 'icons/effects/atmospherics.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE // should only appear in vis_contents, but to be safe
layer = FLY_LAYER
appearance_flags = TILE_BOUND
vis_flags = NONE
/obj/effect/overlay/gas/New(state, alph)
. = ..()
icon_state = state
alpha = alph
@@ -6,27 +6,24 @@ What are the archived variables for?
#define MINIMUM_HEAT_CAPACITY 0.0003
#define MINIMUM_MOLE_COUNT 0.01
//Unomos - global list inits for all of the meta gas lists.
//This setup allows procs to only look at one list instead of trying to dig around in lists-within-lists
GLOBAL_LIST_INIT(meta_gas_specific_heats, meta_gas_heat_list())
GLOBAL_LIST_INIT(meta_gas_names, meta_gas_name_list())
GLOBAL_LIST_INIT(meta_gas_visibility, meta_gas_visibility_list())
GLOBAL_LIST_INIT(meta_gas_overlays, meta_gas_overlay_list())
GLOBAL_LIST_INIT(meta_gas_dangers, meta_gas_danger_list())
GLOBAL_LIST_INIT(meta_gas_ids, meta_gas_id_list())
GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture
/// Never ever set this variable, hooked into vv_get_var for view variables viewing.
var/gas_list_view_only
var/initial_volume = CELL_VOLUME //liters
var/list/reaction_results
var/list/analyzer_results //used for analyzer feedback - not initialized until its used
var/_extools_pointer_gasmixture = 0 // Contains the memory address of the shared_ptr object for this gas mixture in c++ land. Don't. Touch. This. Var.
var/_extools_pointer_gasmixture // Contains the index in the gas vector for this gas mixture in rust land. Don't. Touch. This. Var.
GLOBAL_LIST_INIT(auxtools_atmos_initialized,FALSE)
/proc/auxtools_atmos_init()
/datum/gas_mixture/New(volume)
if (!isnull(volume))
initial_volume = volume
ATMOS_EXTOOLS_CHECK
AUXTOOLS_CHECK(AUXMOS)
if(!GLOB.auxtools_atmos_initialized && auxtools_atmos_init())
GLOB.auxtools_atmos_initialized = TRUE
__gasmixture_register()
reaction_results = new
@@ -43,6 +40,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
var/list/dummy = get_gases()
for(var/gas in dummy)
dummy[gas] = get_moles(gas)
dummy["CAP [gas]"] = partial_heat_capacity(gas)
dummy["TEMP"] = return_temperature()
dummy["PRESSURE"] = return_pressure()
dummy["HEAT CAPACITY"] = heat_capacity()
@@ -79,16 +77,16 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
var/list/gases = get_gases()
for(var/gas in gases)
gases[gas] = get_moles(gas)
var/gastype = input(usr, "What kind of gas?", "Set Gas") as null|anything in subtypesof(/datum/gas)
if(!ispath(gastype, /datum/gas))
var/gasid = input(usr, "What kind of gas?", "Set Gas") as null|anything in GLOB.gas_data.ids
if(!gasid)
return
var/amount = input(usr, "Input amount", "Set Gas", gases[gastype] || 0) as num|null
var/amount = input(usr, "Input amount", "Set Gas", gases[gasid] || 0) as num|null
if(!isnum(amount))
return
amount = max(0, amount)
log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Set gas type [gastype] to [amount] moles.")
message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Set gas type [gastype] to [amount] moles.")
set_moles(gastype, amount)
log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Set gas [gasid] to [amount] moles.")
message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Set gas [gasid] to [amount] moles.")
set_moles(gasid, amount)
if(href_list[VV_HK_SET_TEMPERATURE])
var/temp = input(usr, "Set the temperature of this mixture to?", "Set Temperature", return_temperature()) as num|null
if(!isnum(temp))
@@ -107,9 +105,11 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
set_volume(volume)
/*
we use a hook instead
/datum/gas_mixture/Del()
__gasmixture_unregister()
. = ..()*/
. = ..()
*/
/datum/gas_mixture/proc/__gasmixture_unregister()
/datum/gas_mixture/proc/__gasmixture_register()
@@ -123,6 +123,8 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/heat_capacity() //joules per kelvin
/datum/gas_mixture/proc/partial_heat_capacity(gas_type)
/datum/gas_mixture/proc/total_moles()
/datum/gas_mixture/proc/return_pressure() //kilopascals
@@ -147,7 +149,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/vv_react(datum/holder)
return react(holder)
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, ratio, list/gases)
/datum/gas_mixture/proc/mark_immutable()
/datum/gas_mixture/proc/get_gases()
/datum/gas_mixture/proc/multiply(factor)
@@ -155,7 +157,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/clear()
/datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0)
set_moles(gas_type, get_moles(gas_type) + amt)
set_moles(gas_type, clamp(get_moles(gas_type) + amt,0,INFINITY))
/datum/gas_mixture/proc/return_volume() //liters
@@ -175,7 +177,9 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/transfer_to(datum/gas_mixture/target, amount)
//Transfers amount of gas to target. Equivalent to target.merge(remove(amount)) but faster.
//Removes amount of gas from the gas_mixture
/datum/gas_mixture/proc/transfer_ratio_to(datum/gas_mixture/target, ratio)
//Transfers ratio of gas to target. Equivalent to target.merge(remove_ratio(amount)) but faster.
/datum/gas_mixture/proc/remove_ratio(ratio)
//Proportionally removes amount of gas from the gas_mixture
@@ -213,6 +217,24 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
//Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise
/datum/gas_mixture/proc/adjust_heat(amt)
//Adjusts the thermal energy of the gas mixture, rather than having to do the full calculation.
//Returns: null
/datum/gas_mixture/proc/equalize_with(datum/gas_mixture/giver)
//Makes this mix have the same temperature and gas ratios as the giver, but with the same pressure, accounting for volume.
//Returns: null
/datum/gas_mixture/proc/get_oxidation_power(temp)
//Gets how much oxidation this gas can do, optionally at a given temperature.
/datum/gas_mixture/proc/get_fuel_amount(temp)
//Gets how much fuel for fires (not counting trit/plasma!) this gas has, optionally at a given temperature.
/proc/equalize_all_gases_in_list(list/L)
//Makes every gas in the given list have the same pressure, temperature and gas proportions.
//Returns: null
/datum/gas_mixture/proc/__remove()
/datum/gas_mixture/remove(amount)
var/datum/gas_mixture/removed = new type
@@ -234,26 +256,21 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
return copy
/datum/gas_mixture/copy_from_turf(turf/model)
set_temperature(initial(model.initial_temperature))
parse_gas_string(model.initial_gas_mix)
//acounts for changes in temperature
var/turf/model_parent = model.parent_type
if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
set_temperature(model.temperature)
return 1
/datum/gas_mixture/parse_gas_string(gas_string)
var/list/gas = params2list(gas_string)
if(gas["TEMP"])
set_temperature(text2num(gas["TEMP"]))
var/temp = text2num(gas["TEMP"])
gas -= "TEMP"
if(!isnum(temp) || temp < 2.7)
temp = 2.7
set_temperature(temp)
clear()
for(var/id in gas)
var/path = id
if(!ispath(path))
path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
set_moles(path, text2num(gas[id]))
set_moles(id, text2num(gas[id]))
archive()
return 1
/*
@@ -305,17 +322,11 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
if (. & STOP_REACTIONS)
break
*/
//Takes the amount of the gas you want to PP as an argument
//So I don't have to do some hacky switches/defines/magic strings
//eg:
//Tox_PP = get_partial_pressure(gas_mixture.toxins)
//O2_PP = get_partial_pressure(gas_mixture.oxygen)
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME
//inverse
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature())
/datum/gas_mixture/proc/set_analyzer_results(instability)
if(!analyzer_results)
analyzer_results = new
analyzer_results["fusion"] = instability
//Mathematical proofs:
/*
@@ -379,8 +390,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
var/transfer_moles = pressure_delta*output_air.return_volume()/(input_air.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = input_air.remove(transfer_moles)
output_air.merge(removed)
input_air.transfer_to(output_air, transfer_moles)
return TRUE
return FALSE
@@ -1,214 +0,0 @@
GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded
GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/pluoxium, /datum/gas/stimulum, /datum/gas/nitryl))) //unable to react amongst themselves
/proc/gas_id2path(id)
var/list/meta_gas = GLOB.meta_gas_ids
if(id in meta_gas)
return id
for(var/path in meta_gas)
if(meta_gas[path] == id)
return path
return ""
//Unomos - oh god oh fuck oh shit oh lord have mercy this is messy as fuck oh god
//my addiction to seeing better performance numbers isn't healthy, kids
//you see this shit, children?
//i am not a good idol. don't take after me.
//this is literally worse than my alcohol addiction
/proc/meta_gas_heat_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.specific_heat)
/proc/meta_gas_name_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.name)
/proc/meta_gas_visibility_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.moles_visible)
/proc/meta_gas_overlay_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = 0 //gotta make sure if(GLOB.meta_gas_overlays[gaspath]) doesn't break
if(initial(gas.moles_visible) != null)
.[gas_path] = new /list(FACTOR_GAS_VISIBLE_MAX)
for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
.[gas_path][i] = new /obj/effect/overlay/gas(initial(gas.gas_overlay), i * 255 / FACTOR_GAS_VISIBLE_MAX)
/proc/meta_gas_danger_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.dangerous)
/proc/meta_gas_id_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.id)
/proc/meta_gas_fusion_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.fusion_power)
/*||||||||||||||/----------\||||||||||||||*\
||||||||||||||||[GAS DATUMS]||||||||||||||||
||||||||||||||||\__________/||||||||||||||||
||||These should never be instantiated. ||||
||||They exist only to make it easier ||||
||||to add a new gas. They are accessed ||||
||||only by meta_gas_list(). ||||
\*||||||||||||||||||||||||||||||||||||||||*/
/datum/gas
var/id = ""
var/specific_heat = 0
var/name = ""
var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi
var/moles_visible = null
var/dangerous = FALSE //currently used by canisters
var/fusion_power = 0 //How much the gas accelerates a fusion reaction
var/rarity = 0 // relative rarity compared to other gases, used when setting up the reactions list.
/datum/gas/oxygen
id = "o2"
specific_heat = 20
name = "Oxygen"
rarity = 900
/datum/gas/nitrogen
id = "n2"
specific_heat = 20
name = "Nitrogen"
rarity = 1000
/datum/gas/carbon_dioxide //what the fuck is this?
id = "co2"
specific_heat = 30
name = "Carbon Dioxide"
fusion_power = 3
rarity = 700
/datum/gas/plasma
id = "plasma"
specific_heat = 200
name = "Plasma"
gas_overlay = "plasma"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
rarity = 800
/datum/gas/water_vapor
id = "water_vapor"
specific_heat = 40
name = "Water Vapor"
gas_overlay = "water_vapor"
moles_visible = MOLES_GAS_VISIBLE
fusion_power = 8
rarity = 500
/datum/gas/hypernoblium
id = "nob"
specific_heat = 2000
name = "Hyper-noblium"
gas_overlay = "freon"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
rarity = 50
/datum/gas/nitrous_oxide
id = "n2o"
specific_heat = 40
name = "Nitrous Oxide"
gas_overlay = "nitrous_oxide"
moles_visible = MOLES_GAS_VISIBLE * 2
dangerous = TRUE
rarity = 600
/datum/gas/nitryl
id = "no2"
specific_heat = 20
name = "Nitryl"
gas_overlay = "nitryl"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
fusion_power = 15
rarity = 100
/datum/gas/tritium
id = "tritium"
specific_heat = 10
name = "Tritium"
gas_overlay = "tritium"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
fusion_power = 1
rarity = 300
/datum/gas/bz
id = "bz"
specific_heat = 20
name = "BZ"
dangerous = TRUE
fusion_power = 8
rarity = 400
/datum/gas/stimulum
id = "stim"
specific_heat = 5
name = "Stimulum"
fusion_power = 7
rarity = 1
/datum/gas/pluoxium
id = "pluox"
specific_heat = 80
name = "Pluoxium"
fusion_power = 10
rarity = 200
/datum/gas/miasma
id = "miasma"
specific_heat = 20
fusion_power = 50
name = "Miasma"
gas_overlay = "miasma"
moles_visible = MOLES_GAS_VISIBLE * 60
rarity = 250
/datum/gas/methane
id = "methane"
specific_heat = 30
name = "Methane"
rarity = 320
/datum/gas/methyl_bromide
id = "methyl_bromide"
specific_heat = 42
name = "Methyl Bromide"
dangerous = TRUE
rarity = 310
/obj/effect/overlay/gas
icon = 'icons/effects/atmospherics.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE // should only appear in vis_contents, but to be safe
layer = FLY_LAYER
appearance_flags = TILE_BOUND
vis_flags = NONE
/obj/effect/overlay/gas/New(state, alph)
. = ..()
icon_state = state
alpha = alph
@@ -27,4 +27,4 @@
/datum/gas_mixture/immutable/cloner/populate()
..()
set_moles(/datum/gas/nitrogen, MOLES_O2STANDARD + MOLES_N2STANDARD)
set_moles(GAS_N2, MOLES_O2STANDARD + MOLES_N2STANDARD)
+218 -121
View File
@@ -8,13 +8,6 @@
if(initial(reaction.exclude))
continue
reaction = new r
var/datum/gas/reaction_key
for (var/req in reaction.min_requirements)
if (ispath(req))
var/datum/gas/req_gas = req
if (!reaction_key || initial(reaction_key.rarity) > initial(req_gas.rarity))
reaction_key = req_gas
reaction.major_gas = reaction_key
. += reaction
sortTim(., /proc/cmp_gas_reaction)
@@ -26,7 +19,6 @@
//when in doubt, use MINIMUM_MOLE_COUNT.
var/list/min_requirements
var/list/max_requirements
var/major_gas //the highest rarity gas used in the reaction.
var/exclude = FALSE //do it this way to allow for addition/removal of reactions midmatch in the future
var/priority = 100 //lower numbers are checked/react later than higher numbers. if two reactions have the same priority they may happen in either order
var/name = "reaction"
@@ -49,7 +41,7 @@
id = "nobstop"
/datum/gas_reaction/nobliumsupression/init_reqs()
min_requirements = list(/datum/gas/hypernoblium = REACTION_OPPRESSION_THRESHOLD)
min_requirements = list(GAS_HYPERNOB = REACTION_OPPRESSION_THRESHOLD)
/datum/gas_reaction/nobliumsupression/react()
return STOP_REACTIONS
@@ -61,7 +53,7 @@
id = "vapor"
/datum/gas_reaction/water_vapor/init_reqs()
min_requirements = list(/datum/gas/water_vapor = MOLES_GAS_VISIBLE)
min_requirements = list(GAS_H2O = MOLES_GAS_VISIBLE)
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
var/turf/open/location = isturf(holder) ? holder : null
@@ -70,7 +62,7 @@
if(location && location.freon_gas_act())
. = REACTING
else if(location && location.water_vapor_gas_act())
air.adjust_moles(/datum/gas/water_vapor,-MOLES_GAS_VISIBLE)
air.adjust_moles(GAS_H2O,-MOLES_GAS_VISIBLE)
. = REACTING
// no test cause it's entirely based on location
@@ -84,10 +76,22 @@
/datum/gas_reaction/tritfire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
/datum/gas/tritium = MINIMUM_MOLE_COUNT,
/datum/gas/oxygen = MINIMUM_MOLE_COUNT
GAS_TRITIUM = MINIMUM_MOLE_COUNT,
GAS_O2 = MINIMUM_MOLE_COUNT
)
/proc/fire_expose(turf/open/location, datum/gas_mixture/air, temperature)
if(istype(location) && temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location)
var/atom/movable/item = I
item.temperature_expose(air, temperature, CELL_VOLUME)
location.temperature_expose(air, temperature, CELL_VOLUME)
/proc/radiation_burn(turf/open/location, energy_released)
if(istype(location) && prob(10))
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
var/old_heat_capacity = air.heat_capacity()
@@ -97,20 +101,20 @@
var/turf/open/location = isturf(holder) ? holder : null
var/burned_fuel = 0
if(air.get_moles(/datum/gas/oxygen) < air.get_moles(/datum/gas/tritium))
burned_fuel = air.get_moles(/datum/gas/oxygen)/TRITIUM_BURN_OXY_FACTOR
air.adjust_moles(/datum/gas/tritium, -burned_fuel)
if(air.get_moles(GAS_O2) < air.get_moles(GAS_TRITIUM))
burned_fuel = air.get_moles(GAS_O2)/TRITIUM_BURN_OXY_FACTOR
air.adjust_moles(GAS_TRITIUM, -burned_fuel)
else
burned_fuel = air.get_moles(/datum/gas/tritium)*TRITIUM_BURN_TRIT_FACTOR
air.adjust_moles(/datum/gas/tritium, -air.get_moles(/datum/gas/tritium)/TRITIUM_BURN_TRIT_FACTOR)
air.adjust_moles(/datum/gas/oxygen,-air.get_moles(/datum/gas/tritium))
burned_fuel = air.get_moles(GAS_TRITIUM)*TRITIUM_BURN_TRIT_FACTOR
air.adjust_moles(GAS_TRITIUM, -air.get_moles(GAS_TRITIUM)/TRITIUM_BURN_TRIT_FACTOR)
air.adjust_moles(GAS_O2,-air.get_moles(GAS_TRITIUM))
if(burned_fuel)
energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel)
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
air.adjust_moles(/datum/gas/water_vapor, burned_fuel/TRITIUM_BURN_OXY_FACTOR)
air.adjust_moles(GAS_H2O, burned_fuel/TRITIUM_BURN_OXY_FACTOR)
cached_results["fire"] += burned_fuel
@@ -133,8 +137,8 @@
/datum/gas_reaction/tritfire/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/tritium,50)
G.set_moles(/datum/gas/oxygen,50)
G.set_moles(GAS_TRITIUM,50)
G.set_moles(GAS_O2,50)
G.set_temperature(500)
var/result = G.react()
if(result != REACTING)
@@ -152,8 +156,8 @@
/datum/gas_reaction/plasmafire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
/datum/gas/plasma = MINIMUM_MOLE_COUNT,
/datum/gas/oxygen = MINIMUM_MOLE_COUNT
GAS_PLASMA = MINIMUM_MOLE_COUNT,
GAS_O2 = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
@@ -178,21 +182,21 @@
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(air.get_moles(/datum/gas/oxygen) / air.get_moles(/datum/gas/plasma) > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
if(air.get_moles(GAS_O2) / air.get_moles(GAS_PLASMA) > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
super_saturation = TRUE
if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/plasma)*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (air.get_moles(/datum/gas/plasma)*temperature_scale)/PLASMA_BURN_RATE_DELTA
if(air.get_moles(GAS_O2) > air.get_moles(GAS_PLASMA)*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (air.get_moles(GAS_PLASMA)*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
plasma_burn_rate = (temperature_scale*(air.get_moles(/datum/gas/oxygen)/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
plasma_burn_rate = (temperature_scale*(air.get_moles(GAS_O2)/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
plasma_burn_rate = min(plasma_burn_rate,air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/oxygen)/oxygen_burn_rate) //Ensures matter is conserved properly
air.set_moles(/datum/gas/plasma, QUANTIZE(air.get_moles(/datum/gas/plasma) - plasma_burn_rate))
air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) - (plasma_burn_rate * oxygen_burn_rate)))
plasma_burn_rate = min(plasma_burn_rate,air.get_moles(GAS_PLASMA),air.get_moles(GAS_O2)/oxygen_burn_rate) //Ensures matter is conserved properly
air.set_moles(GAS_PLASMA, QUANTIZE(air.get_moles(GAS_PLASMA) - plasma_burn_rate))
air.set_moles(GAS_O2, QUANTIZE(air.get_moles(GAS_O2) - (plasma_burn_rate * oxygen_burn_rate)))
if (super_saturation)
air.adjust_moles(/datum/gas/tritium, plasma_burn_rate)
air.adjust_moles(GAS_TRITIUM, plasma_burn_rate)
else
air.adjust_moles(/datum/gas/carbon_dioxide, plasma_burn_rate)
air.adjust_moles(GAS_CO2, plasma_burn_rate)
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -217,8 +221,8 @@
/datum/gas_reaction/plasmafire/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/plasma,50)
G.set_moles(/datum/gas/oxygen,50)
G.set_moles(GAS_PLASMA,50)
G.set_moles(GAS_O2,50)
G.set_volume(1000)
G.set_temperature(500)
var/result = G.react()
@@ -226,21 +230,114 @@
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.reaction_results["fire"])
return list("success" = FALSE, "message" = "Plasma fires aren't setting fire results correctly!")
if(!G.get_moles(/datum/gas/carbon_dioxide))
if(!G.get_moles(GAS_CO2))
return list("success" = FALSE, "message" = "Plasma fires aren't making CO2!")
G.clear()
G.set_moles(/datum/gas/plasma,10)
G.set_moles(/datum/gas/oxygen,1000)
G.set_moles(GAS_PLASMA,10)
G.set_moles(GAS_O2,1000)
G.set_temperature(500)
result = G.react()
if(!G.get_moles(/datum/gas/tritium))
if(!G.get_moles(GAS_TRITIUM))
return list("success" = FALSE, "message" = "Plasma fires aren't making trit!")
return ..()
/datum/gas_reaction/genericfire
priority = -3 // very last reaction
name = "Combustion"
id = "genericfire"
/datum/gas_reaction/genericfire/init_reqs()
var/lowest_fire_temp = INFINITY
var/list/fire_temperatures = GLOB.gas_data.fire_temperatures
for(var/gas in fire_temperatures)
lowest_fire_temp = min(lowest_fire_temp, fire_temperatures[gas])
var/lowest_oxi_temp = INFINITY
var/list/oxidation_temperatures = GLOB.gas_data.oxidation_temperatures
for(var/gas in oxidation_temperatures)
lowest_oxi_temp = min(lowest_oxi_temp, oxidation_temperatures[gas])
min_requirements = list(
"TEMP" = max(lowest_oxi_temp, lowest_fire_temp),
"FIRE_REAGENTS" = MINIMUM_MOLE_COUNT
)
// no requirements, always runs
// bad idea? maybe
// this is overridden by auxmos but, hey, good idea to have it readable
/datum/gas_reaction/genericfire/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
var/list/oxidation_temps = GLOB.gas_data.oxidation_temperatures
var/list/oxidation_rates = GLOB.gas_data.oxidation_rates
var/oxidation_power = 0
var/list/burn_results = list()
var/list/fuels = list()
var/list/oxidizers = list()
var/list/fuel_rates = GLOB.gas_data.fire_burn_rates
var/list/fuel_temps = GLOB.gas_data.fire_temperatures
var/total_fuel = 0
var/energy_released = 0
for(var/G in air.get_gases())
var/oxidation_temp = oxidation_temps[G]
if(oxidation_temp && oxidation_temp > temperature)
var/temperature_scale = max(0, 1-(temperature / oxidation_temp))
var/amt = air.get_moles(G) * temperature_scale
oxidizers[G] = amt
oxidation_power += amt * oxidation_rates[G]
else
var/fuel_temp = fuel_temps[G]
if(fuel_temp && fuel_temp > temperature)
var/amt = (air.get_moles(G) / fuel_rates[G]) * max(0, 1-(temperature / fuel_temp))
fuels[G] = amt // we have to calculate the actual amount we're using after we get all oxidation together
total_fuel += amt
if(oxidation_power <= 0 || total_fuel <= 0)
return NO_REACTION
var/oxidation_ratio = oxidation_power / total_fuel
if(oxidation_ratio > 1)
for(var/oxidizer in oxidizers)
oxidizers[oxidizer] /= oxidation_ratio
else if(oxidation_ratio < 1)
for(var/fuel in fuels)
fuels[fuel] *= oxidation_ratio
fuels += oxidizers
var/list/fire_products = GLOB.gas_data.fire_products
var/list/fire_enthalpies = GLOB.gas_data.fire_enthalpies
for(var/fuel in fuels + oxidizers)
var/amt = fuels[fuel]
if(!burn_results[fuel])
burn_results[fuel] = 0
burn_results[fuel] -= amt
energy_released += amt * fire_enthalpies[fuel]
for(var/product in fire_products[fuel])
if(!burn_results[product])
burn_results[product] = 0
burn_results[product] += amt
var/final_energy = air.thermal_energy() + energy_released
for(var/result in burn_results)
air.adjust_moles(result, burn_results[result])
air.set_temperature(final_energy / air.heat_capacity())
var/list/cached_results = air.reaction_results
cached_results["fire"] = min(total_fuel, oxidation_power) * 2
return cached_results["fire"] ? REACTING : NO_REACTION
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again!
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
//6 reworks
/proc/fusion_ball(datum/holder, reaction_energy, instability)
var/turf/open/location
if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
var/datum/pipeline/fusion_pipenet = holder
location = get_turf(pick(fusion_pipenet.members))
else
location = get_turf(holder)
if(location)
var/particle_chance = ((PARTICLE_CHANCE_CONSTANT)/(reaction_energy-PARTICLE_CHANCE_CONSTANT)) + 1//Asymptopically approaches 100% as the energy of the reaction goes up.
if(prob(PERCENT(particle_chance)))
location.fire_nuclear_particle()
var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + FUSION_RAD_MAX,0)
radiation_pulse(location,rad_power)
/datum/gas_reaction/fusion
exclude = FALSE
priority = 2
@@ -250,9 +347,9 @@
/datum/gas_reaction/fusion/init_reqs()
min_requirements = list(
"TEMP" = FUSION_TEMPERATURE_THRESHOLD,
/datum/gas/tritium = FUSION_TRITIUM_MOLES_USED,
/datum/gas/plasma = FUSION_MOLE_THRESHOLD,
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
GAS_TRITIUM = FUSION_TRITIUM_MOLES_USED,
GAS_PLASMA = FUSION_MOLE_THRESHOLD,
GAS_CO2 = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
var/turf/open/location
@@ -268,12 +365,12 @@
var/list/cached_scan_results = air.analyzer_results
var/old_heat_capacity = air.heat_capacity()
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
var/initial_plasma = air.get_moles(/datum/gas/plasma)
var/initial_carbon = air.get_moles(/datum/gas/carbon_dioxide)
var/initial_plasma = air.get_moles(GAS_PLASMA)
var/initial_carbon = air.get_moles(GAS_CO2)
var/scale_factor = (air.return_volume())/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.return_volume()-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/gas_power = 0
var/list/gas_fusion_powers = GLOB.meta_gas_fusions
var/list/gas_fusion_powers = GLOB.gas_data.fusion_powers
for (var/gas_id in air.get_gases())
gas_power += (gas_fusion_powers[gas_id]*air.get_moles(gas_id))
var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
@@ -287,9 +384,9 @@
carbon = MODULUS(carbon - plasma, toroidal_size)
air.set_moles(/datum/gas/plasma, plasma*scale_factor + FUSION_MOLE_THRESHOLD) //Scales the gases back up
air.set_moles(/datum/gas/carbon_dioxide , carbon*scale_factor + FUSION_MOLE_THRESHOLD)
var/delta_plasma = initial_plasma - air.get_moles(/datum/gas/plasma)
air.set_moles(GAS_PLASMA, plasma*scale_factor + FUSION_MOLE_THRESHOLD) //Scales the gases back up
air.set_moles(GAS_CO2 , carbon*scale_factor + FUSION_MOLE_THRESHOLD)
var/delta_plasma = initial_plasma - air.get_moles(GAS_PLASMA)
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
@@ -298,17 +395,17 @@
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
air.set_moles(/datum/gas/plasma,initial_plasma)
air.set_moles(/datum/gas/carbon_dioxide, initial_carbon)
air.set_moles(GAS_PLASMA,initial_plasma)
air.set_moles(GAS_CO2, initial_carbon)
return NO_REACTION
air.adjust_moles(/datum/gas/tritium, -FUSION_TRITIUM_MOLES_USED)
air.adjust_moles(GAS_TRITIUM, -FUSION_TRITIUM_MOLES_USED)
//The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
if(reaction_energy > 0)
air.adjust_moles(/datum/gas/oxygen, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(/datum/gas/nitrous_oxide, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_O2, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_NITROUS, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
else
air.adjust_moles(/datum/gas/bz, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(/datum/gas/nitryl, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_BZ, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_NITRYL, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
if(reaction_energy)
if(location)
@@ -325,10 +422,10 @@
/datum/gas_reaction/fusion/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/carbon_dioxide,300)
G.set_moles(/datum/gas/plasma,1000)
G.set_moles(/datum/gas/tritium,100.61)
G.set_moles(/datum/gas/nitryl,1)
G.set_moles(GAS_CO2,300)
G.set_moles(GAS_PLASMA,1000)
G.set_moles(GAS_TRITIUM,100.61)
G.set_moles(GAS_NITRYL,1)
G.set_temperature(15000)
G.set_volume(1000)
var/result = G.react()
@@ -337,11 +434,11 @@
if(abs(G.analyzer_results["fusion"] - 3) > 0.0000001)
var/instability = G.analyzer_results["fusion"]
return list("success" = FALSE, "message" = "Fusion is not calculating analyzer results correctly, should be 3.000000045, is instead [instability]")
if(abs(G.get_moles(/datum/gas/plasma) - 850.616) > 0.5)
var/plas = G.get_moles(/datum/gas/plasma)
if(abs(G.get_moles(GAS_PLASMA) - 850.616) > 0.5)
var/plas = G.get_moles(GAS_PLASMA)
return list("success" = FALSE, "message" = "Fusion is not calculating plasma correctly, should be 850.616, is instead [plas]")
if(abs(G.get_moles(/datum/gas/carbon_dioxide) - 1699.384) > 0.5)
var/co2 = G.get_moles(/datum/gas/carbon_dioxide)
if(abs(G.get_moles(GAS_CO2) - 1699.384) > 0.5)
var/co2 = G.get_moles(GAS_CO2)
return list("success" = FALSE, "message" = "Fusion is not calculating co2 correctly, should be 1699.384, is instead [co2]")
if(abs(G.return_temperature() - 27600) > 200) // calculating this manually sucks dude
var/temp = G.return_temperature()
@@ -355,9 +452,9 @@
/datum/gas_reaction/nitrylformation/init_reqs()
min_requirements = list(
/datum/gas/oxygen = 20,
/datum/gas/nitrogen = 20,
/datum/gas/nitrous_oxide = 5,
GAS_O2 = 20,
GAS_N2 = 20,
GAS_NITROUS = 5,
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST*25
)
@@ -365,13 +462,13 @@
var/temperature = air.return_temperature()
var/old_heat_capacity = air.heat_capacity()
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),air.get_moles(/datum/gas/oxygen),air.get_moles(/datum/gas/nitrogen))
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),air.get_moles(GAS_O2),air.get_moles(GAS_N2))
var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
if ((air.get_moles(/datum/gas/oxygen) - heat_efficency < 0 )|| (air.get_moles(/datum/gas/nitrogen) - heat_efficency < 0)) //Shouldn't produce gas from nothing.
if ((air.get_moles(GAS_O2) - heat_efficency < 0 )|| (air.get_moles(GAS_N2) - heat_efficency < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
air.adjust_moles(/datum/gas/oxygen, -heat_efficency)
air.adjust_moles(/datum/gas/nitrogen, -heat_efficency)
air.adjust_moles(/datum/gas/nitryl, heat_efficency*2)
air.adjust_moles(GAS_O2, -heat_efficency)
air.adjust_moles(GAS_N2, -heat_efficency)
air.adjust_moles(GAS_NITRYL, heat_efficency*2)
if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity()
@@ -381,15 +478,15 @@
/datum/gas_reaction/nitrylformation/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/oxygen,30)
G.set_moles(/datum/gas/nitrogen,30)
G.set_moles(/datum/gas/nitrous_oxide,10)
G.set_moles(GAS_O2,30)
G.set_moles(GAS_N2,30)
G.set_moles(GAS_NITROUS,10)
G.set_volume(1000)
G.set_temperature(150000)
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.get_moles(/datum/gas/nitryl) < 0.8)
if(!G.get_moles(GAS_NITRYL) < 0.8)
return list("success" = FALSE, "message" = "Nitryl isn't being generated correctly!")
return ..()
@@ -400,8 +497,8 @@
/datum/gas_reaction/bzformation/init_reqs()
min_requirements = list(
/datum/gas/nitrous_oxide = 10,
/datum/gas/plasma = 10
GAS_NITROUS = 10,
GAS_PLASMA = 10
)
@@ -409,16 +506,16 @@
var/temperature = air.return_temperature()
var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(air.get_moles(/datum/gas/plasma)/air.get_moles(/datum/gas/nitrous_oxide),1))),air.get_moles(/datum/gas/nitrous_oxide),air.get_moles(/datum/gas/plasma)/2)
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(air.get_moles(GAS_PLASMA)/air.get_moles(GAS_NITROUS),1))),air.get_moles(GAS_NITROUS),air.get_moles(GAS_PLASMA)/2)
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
if ((air.get_moles(/datum/gas/nitrous_oxide) - reaction_efficency < 0 )|| (air.get_moles(/datum/gas/plasma) - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
if ((air.get_moles(GAS_NITROUS) - reaction_efficency < 0 )|| (air.get_moles(GAS_PLASMA) - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
return NO_REACTION
air.adjust_moles(/datum/gas/bz, reaction_efficency)
if(reaction_efficency == air.get_moles(/datum/gas/nitrous_oxide))
air.adjust_moles(/datum/gas/bz, -min(pressure,1))
air.adjust_moles(/datum/gas/oxygen, min(pressure,1))
air.adjust_moles(/datum/gas/nitrous_oxide, -reaction_efficency)
air.adjust_moles(/datum/gas/plasma, -2*reaction_efficency)
air.adjust_moles(GAS_BZ, reaction_efficency)
if(reaction_efficency == air.get_moles(GAS_NITROUS))
air.adjust_moles(GAS_BZ, -min(pressure,1))
air.adjust_moles(GAS_O2, min(pressure,1))
air.adjust_moles(GAS_NITROUS, -reaction_efficency)
air.adjust_moles(GAS_PLASMA, -2*reaction_efficency)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((reaction_efficency**2)*BZ_RESEARCH_SCALE),BZ_RESEARCH_MAX_AMOUNT)
@@ -430,14 +527,14 @@
/datum/gas_reaction/bzformation/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/plasma,15)
G.set_moles(/datum/gas/nitrous_oxide,15)
G.set_moles(GAS_PLASMA,15)
G.set_moles(GAS_NITROUS,15)
G.set_volume(1000)
G.set_temperature(10)
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.get_moles(/datum/gas/bz) < 4) // efficiency is 4.0643 and bz generation == efficiency
if(!G.get_moles(GAS_BZ) < 4) // efficiency is 4.0643 and bz generation == efficiency
return list("success" = FALSE, "message" = "Nitryl isn't being generated correctly!")
return ..()
@@ -448,23 +545,23 @@
/datum/gas_reaction/stimformation/init_reqs()
min_requirements = list(
/datum/gas/tritium = 30,
/datum/gas/plasma = 10,
/datum/gas/bz = 20,
/datum/gas/nitryl = 30,
GAS_TRITIUM = 30,
GAS_PLASMA = 10,
GAS_BZ = 20,
GAS_NITRYL = 30,
"TEMP" = STIMULUM_HEAT_SCALE/2)
/datum/gas_reaction/stimformation/react(datum/gas_mixture/air)
var/old_heat_capacity = air.heat_capacity()
var/heat_scale = min(air.return_temperature()/STIMULUM_HEAT_SCALE,air.get_moles(/datum/gas/tritium),air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/nitryl))
var/heat_scale = min(air.return_temperature()/STIMULUM_HEAT_SCALE,air.get_moles(GAS_TRITIUM),air.get_moles(GAS_PLASMA),air.get_moles(GAS_NITRYL))
var/stim_energy_change = heat_scale + STIMULUM_FIRST_RISE*(heat_scale**2) - STIMULUM_FIRST_DROP*(heat_scale**3) + STIMULUM_SECOND_RISE*(heat_scale**4) - STIMULUM_ABSOLUTE_DROP*(heat_scale**5)
if ((air.get_moles(/datum/gas/tritium) - heat_scale < 0 )|| (air.get_moles(/datum/gas/plasma) - heat_scale < 0) || (air.get_moles(/datum/gas/nitryl) - heat_scale < 0)) //Shouldn't produce gas from nothing.
if ((air.get_moles(GAS_TRITIUM) - heat_scale < 0 )|| (air.get_moles(GAS_PLASMA) - heat_scale < 0) || (air.get_moles(GAS_NITRYL) - heat_scale < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
air.adjust_moles(/datum/gas/stimulum, heat_scale/10)
air.adjust_moles(/datum/gas/tritium, -heat_scale)
air.adjust_moles(/datum/gas/plasma, -heat_scale)
air.adjust_moles(/datum/gas/nitryl, -heat_scale)
air.adjust_moles(GAS_STIMULUM, heat_scale/10)
air.adjust_moles(GAS_TRITIUM, -heat_scale)
air.adjust_moles(GAS_PLASMA, -heat_scale)
air.adjust_moles(GAS_NITRYL, -heat_scale)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0))
if(stim_energy_change)
@@ -476,17 +573,17 @@
/datum/gas_reaction/stimformation/test()
//above mentioned "strange pattern" is a basic quintic polynomial, it's fine, can calculate it manually
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/bz,30)
G.set_moles(/datum/gas/plasma,1000)
G.set_moles(/datum/gas/tritium,1000)
G.set_moles(/datum/gas/nitryl,1000)
G.set_moles(GAS_BZ,30)
G.set_moles(GAS_PLASMA,1000)
G.set_moles(GAS_TRITIUM,1000)
G.set_moles(GAS_NITRYL,1000)
G.set_volume(1000)
G.set_temperature(12998000) // yeah, really
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.get_moles(/datum/gas/stimulum) < 900)
if(!G.get_moles(GAS_STIMULUM) < 900)
return list("success" = FALSE, "message" = "Stimulum isn't being generated correctly!")
return ..()
@@ -497,19 +594,19 @@
/datum/gas_reaction/nobliumformation/init_reqs()
min_requirements = list(
/datum/gas/nitrogen = 10,
/datum/gas/tritium = 5,
GAS_N2 = 10,
GAS_TRITIUM = 5,
"ENER" = NOBLIUM_FORMATION_ENERGY)
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
var/old_heat_capacity = air.heat_capacity()
var/nob_formed = min((air.get_moles(/datum/gas/nitrogen)+air.get_moles(/datum/gas/tritium))/100,air.get_moles(/datum/gas/tritium)/10,air.get_moles(/datum/gas/nitrogen)/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(/datum/gas/bz),1)))
if ((air.get_moles(/datum/gas/tritium) - 10*nob_formed < 0) || (air.get_moles(/datum/gas/nitrogen) - 20*nob_formed < 0))
var/nob_formed = min((air.get_moles(GAS_N2)+air.get_moles(GAS_TRITIUM))/100,air.get_moles(GAS_TRITIUM)/10,air.get_moles(GAS_N2)/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(GAS_BZ),1)))
if ((air.get_moles(GAS_TRITIUM) - 10*nob_formed < 0) || (air.get_moles(GAS_N2) - 20*nob_formed < 0))
return NO_REACTION
air.adjust_moles(/datum/gas/tritium, -10*nob_formed)
air.adjust_moles(/datum/gas/nitrogen, -20*nob_formed)
air.adjust_moles(/datum/gas/hypernoblium,nob_formed)
air.adjust_moles(GAS_TRITIUM, -10*nob_formed)
air.adjust_moles(GAS_N2, -20*nob_formed)
air.adjust_moles(GAS_HYPERNOB,nob_formed)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
@@ -520,8 +617,8 @@
/datum/gas_reaction/nobliumformation/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/nitrogen,100)
G.set_moles(/datum/gas/tritium,500)
G.set_moles(GAS_N2,100)
G.set_moles(GAS_TRITIUM,500)
G.set_volume(1000)
G.set_temperature(5000000) // yeah, really
var/result = G.react()
@@ -540,18 +637,18 @@
/datum/gas_reaction/miaster/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST+70,
/datum/gas/miasma = MINIMUM_MOLE_COUNT
GAS_MIASMA = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
// As the name says it, it needs to be dry
if(air.get_moles(/datum/gas/water_vapor) && air.get_moles(/datum/gas/water_vapor)/air.total_moles() > 0.1)
if(air.get_moles(GAS_H2O) && air.get_moles(GAS_H2O)/air.total_moles() > 0.1)
return
//Replace miasma with oxygen
var/cleaned_air = min(air.get_moles(/datum/gas/miasma), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
air.adjust_moles(/datum/gas/miasma, -cleaned_air)
air.adjust_moles(/datum/gas/oxygen, cleaned_air)
var/cleaned_air = min(air.get_moles(GAS_MIASMA), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
air.adjust_moles(GAS_MIASMA, -cleaned_air)
air.adjust_moles(GAS_O2, cleaned_air)
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
air.set_temperature(air.return_temperature() + cleaned_air * 0.002)
@@ -559,16 +656,16 @@
/datum/gas_reaction/miaster/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/miasma,1)
G.set_moles(GAS_MIASMA,1)
G.set_volume(1000)
G.set_temperature(450)
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
G.clear()
G.set_moles(/datum/gas/miasma,1)
G.set_moles(GAS_MIASMA,1)
G.set_temperature(450)
G.set_moles(/datum/gas/water_vapor,0.5)
G.set_moles(GAS_H2O,0.5)
result = G.react()
if(result != NO_REACTION)
return list("success" = FALSE, "message" = "Miasma sterilization not stopping due to water vapor correctly!")
@@ -9,14 +9,14 @@
/datum/gas_mixture/heat_capacity() //joules per kelvin
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
var/list/cached_gasheats = GLOB.gas_data.specific_heats
. = 0
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
/datum/gas_mixture/turf/heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
var/list/cached_gasheats = GLOB.gas_data.specific_heats
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
if(!.)
@@ -56,20 +56,20 @@
return gases[gas_type]
/datum/gas_mixture/set_moles(gas_type, moles)
gases[gas_type] = moles
/datum/gas_mixture/scrub_into(datum/gas_mixture/target, list/gases)
/datum/gas_mixture/scrub_into(datum/gas_mixture/target, ratio, list/gases)
if(isnull(target))
return FALSE
var/list/removed_gases = target.gases
var/list/removed_gases = gases
//Filter it
var/datum/gas_mixture/filtered_out = new
var/list/filtered_gases = filtered_out.gases
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
filtered_gases[gas] = removed_gases[gas]
removed_gases[gas] = 0
merge(filtered_out)
filtered_gases[gas] = removed_gases[gas] * ratio
removed_gases[gas] = removed_gases[gas] * (1 - ratio)
target.merge(filtered_out)
/datum/gas_mixture/mark_immutable()
return
/datum/gas_mixture/get_gases()
@@ -208,7 +208,7 @@
var/delta
var/gas_heat_capacity
//and also cache this shit rq because that results in sanic speed for reasons byond explanation
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
var/list/cached_gasheats = GLOB.gas_data.specific_heats
//GAS TRANSFER
for(var/id in cached_gases | sharer_gases) // transfer gases
+63 -63
View File
@@ -94,63 +94,63 @@
var/list/TLV = list( // Breathable air.
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
/datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
/datum/gas/water_vapor = new/datum/tlv/dangerous,
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
GAS_O2 = new/datum/tlv(16, 19, 40, 50), // Partial pressure, kpa
GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000),
GAS_CO2 = new/datum/tlv(-1, -1, 5, 10),
GAS_MIASMA = new/datum/tlv(-1, -1, 2, 5),
GAS_PLASMA = new/datum/tlv/dangerous,
GAS_NITROUS = new/datum/tlv/dangerous,
GAS_BZ = new/datum/tlv/dangerous,
GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
GAS_H2O = new/datum/tlv/dangerous,
GAS_TRITIUM = new/datum/tlv/dangerous,
GAS_STIMULUM = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
GAS_METHANE = new/datum/tlv(-1, -1, 3, 6),
GAS_METHYL_BROMIDE = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/server // No checks here.
TLV = list(
"pressure" = new/datum/tlv/no_checks,
"temperature" = new/datum/tlv/no_checks,
/datum/gas/oxygen = new/datum/tlv/no_checks,
/datum/gas/nitrogen = new/datum/tlv/no_checks,
/datum/gas/carbon_dioxide = new/datum/tlv/no_checks,
/datum/gas/miasma = new/datum/tlv/no_checks,
/datum/gas/plasma = new/datum/tlv/no_checks,
/datum/gas/nitrous_oxide = new/datum/tlv/no_checks,
/datum/gas/bz = new/datum/tlv/no_checks,
/datum/gas/hypernoblium = new/datum/tlv/no_checks,
/datum/gas/water_vapor = new/datum/tlv/no_checks,
/datum/gas/tritium = new/datum/tlv/no_checks,
/datum/gas/stimulum = new/datum/tlv/no_checks,
/datum/gas/nitryl = new/datum/tlv/no_checks,
/datum/gas/pluoxium = new/datum/tlv/no_checks,
/datum/gas/methane = new/datum/tlv/no_checks,
/datum/gas/methyl_bromide = new/datum/tlv/no_checks
GAS_O2 = new/datum/tlv/no_checks,
GAS_N2 = new/datum/tlv/no_checks,
GAS_CO2 = new/datum/tlv/no_checks,
GAS_MIASMA = new/datum/tlv/no_checks,
GAS_PLASMA = new/datum/tlv/no_checks,
GAS_NITROUS = new/datum/tlv/no_checks,
GAS_BZ = new/datum/tlv/no_checks,
GAS_HYPERNOB = new/datum/tlv/no_checks,
GAS_H2O = new/datum/tlv/no_checks,
GAS_TRITIUM = new/datum/tlv/no_checks,
GAS_STIMULUM = new/datum/tlv/no_checks,
GAS_NITRYL = new/datum/tlv/no_checks,
GAS_PLUOXIUM = new/datum/tlv/no_checks,
GAS_METHANE = new/datum/tlv/no_checks,
GAS_METHYL_BROMIDE = new/datum/tlv/no_checks
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
TLV = list(
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(T0C-73.15, T0C-63.15, T0C, T0C+10),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
/datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
/datum/gas/water_vapor = new/datum/tlv/dangerous,
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
GAS_O2 = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000),
GAS_CO2 = new/datum/tlv(-1, -1, 5, 10),
GAS_MIASMA = new/datum/tlv/(-1, -1, 2, 5),
GAS_PLASMA = new/datum/tlv/dangerous,
GAS_NITROUS = new/datum/tlv/dangerous,
GAS_BZ = new/datum/tlv/dangerous,
GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
GAS_H2O = new/datum/tlv/dangerous,
GAS_TRITIUM = new/datum/tlv/dangerous,
GAS_STIMULUM = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
GAS_METHANE = new/datum/tlv(-1, -1, 3, 6),
GAS_METHYL_BROMIDE = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/unlocked
@@ -298,7 +298,7 @@
continue
cur_tlv = TLV[gas_id]
data["environment_data"] += list(list(
"name" = GLOB.meta_gas_names[gas_id],
"name" = GLOB.gas_data.names[gas_id],
"value" = environment.get_moles(gas_id) / total_moles * 100,
"unit" = "%",
"danger_level" = cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)
@@ -368,11 +368,11 @@
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1))
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2))
for(var/gas_id in GLOB.meta_gas_names)
for(var/gas_id in GLOB.gas_data.names)
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue
selected = TLV[gas_id]
thresholds += list(list("name" = GLOB.meta_gas_names[gas_id], "settings" = list()))
thresholds += list(list("name" = GLOB.gas_data.names[gas_id], "settings" = list()))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1))
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1))
@@ -532,7 +532,7 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
"set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma),
"set_filters" = list(GAS_CO2, GAS_MIASMA),
"scrubbing" = 1,
"widenet" = 0,
))
@@ -547,19 +547,19 @@
send_signal(device_id, list(
"power" = 1,
"set_filters" = list(
/datum/gas/carbon_dioxide,
/datum/gas/miasma,
/datum/gas/plasma,
/datum/gas/water_vapor,
/datum/gas/hypernoblium,
/datum/gas/nitrous_oxide,
/datum/gas/nitryl,
/datum/gas/tritium,
/datum/gas/bz,
/datum/gas/stimulum,
/datum/gas/pluoxium,
/datum/gas/methane,
/datum/gas/methyl_bromide
GAS_CO2,
GAS_MIASMA,
GAS_PLASMA,
GAS_H2O,
GAS_HYPERNOB,
GAS_NITROUS,
GAS_NITRYL,
GAS_TRITIUM,
GAS_BZ,
GAS_STIMULUM,
GAS_PLUOXIUM,
GAS_METHANE,
GAS_METHYL_BROMIDE
),
"scrubbing" = 1,
"widenet" = 1,
@@ -587,7 +587,7 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
"set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma),
"set_filters" = list(GAS_CO2, GAS_MIASMA),
"scrubbing" = 1,
"widenet" = 0,
))
@@ -39,6 +39,7 @@
var/construction_type
var/pipe_state //icon_state as a pipe item
var/on = FALSE
var/interacts_with_air = FALSE
/obj/machinery/atmospherics/examine(mob/user)
. = ..()
@@ -57,7 +58,10 @@
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70)
..()
if(process)
SSair.atmos_machinery += src
if(interacts_with_air)
SSair.atmos_air_machinery += src
else
SSair.atmos_machinery += src
SetInitDirections()
/obj/machinery/atmospherics/Destroy()
@@ -65,6 +69,7 @@
nullifyNode(i)
SSair.atmos_machinery -= src
SSair.atmos_air_machinery -= src
SSair.pipenets_needing_rebuilt -= src
dropContents()
@@ -15,6 +15,9 @@
desc = "Has a valve and pump attached to it. There are two ports."
level = 1
interacts_with_air = TRUE
var/frequency = 0
var/id = null
var/datum/radio_frequency/radio_connection
@@ -69,12 +72,7 @@
if(air1.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
//Removed can be null if there is no atmosphere in air1
if(!removed)
return
loc.assume_air(removed)
loc.assume_air_moles(air1, transfer_moles)
air_update_turf()
var/datum/pipeline/parent1 = parents[1]
@@ -90,11 +88,7 @@
moles_delta = min(moles_delta, (input_pressure_min - air2.return_pressure()) * our_multiplier)
if(moles_delta > 0)
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if (isnull(removed)) // in space
return
air2.merge(removed)
loc.transfer_air(air2, moles_delta)
air_update_turf()
var/datum/pipeline/parent2 = parents[2]
@@ -81,9 +81,7 @@
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
air2.merge(removed)
air1.transfer_to(air2,transfer_moles)
update_parents()
@@ -67,9 +67,7 @@
var/transfer_ratio = transfer_rate/air1.return_volume()
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
air2.merge(removed)
air1.transfer_ratio_to(air2,transfer_ratio)
update_parents()
@@ -120,14 +120,9 @@
times_lost++
var/shared_loss = lost/times_lost
var/datum/gas_mixture/to_release
for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i]
if(!to_release)
to_release = air.remove(shared_loss)
continue
to_release.merge(air.remove(shared_loss))
T.assume_air(to_release)
T.assume_air_moles(air, shared_loss)
air_update_turf(1)
/obj/machinery/atmospherics/components/proc/safe_input(var/title, var/text, var/default_set)
@@ -98,33 +98,11 @@
//Actually transfer the gas
if(transfer_ratio > 0)
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
if(!removed)
return
var/filtering = TRUE
if(!ispath(filter_type))
if(filter_type)
filter_type = gas_id2path(filter_type) //support for mappers so they don't need to type out paths
else
filtering = FALSE
if(filtering && removed.get_moles(filter_type))
var/datum/gas_mixture/filtered_out = new
filtered_out.set_temperature(removed.return_temperature())
filtered_out.set_moles(filter_type, removed.get_moles(filter_type))
removed.set_moles(filter_type, 0)
var/datum/gas_mixture/target = (air2.return_pressure() < 9000 ? air2 : air1)
target.merge(filtered_out)
if(filter_type && air2.return_pressure() <= 9000)
air1.scrub_into(air2, transfer_ratio, list(filter_type))
if(air3.return_pressure() <= 9000)
air3.merge(removed)
else
air1.merge(removed) // essentially just leaving it in
air1.transfer_ratio_to(air3, transfer_ratio)
update_parents()
@@ -145,9 +123,9 @@
data["max_rate"] = round(MAX_TRANSFER_RATE)
data["filter_types"] = list()
data["filter_types"] += list(list("name" = "Nothing", "path" = "", "selected" = !filter_type))
for(var/path in GLOB.meta_gas_ids)
data["filter_types"] += list(list("name" = GLOB.meta_gas_names[path], "id" = GLOB.meta_gas_ids[path], "selected" = (path == gas_id2path(filter_type))))
data["filter_types"] += list(list("name" = "Nothing", "id" = "", "selected" = !filter_type))
for(var/id in GLOB.gas_data.ids)
data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type)))
return data
@@ -177,10 +155,10 @@
if("filter")
filter_type = null
var/filter_name = "nothing"
var/gas = gas_id2path(params["mode"])
if(gas in GLOB.meta_gas_names)
var/gas = params["mode"]
if(gas in GLOB.gas_data.names)
filter_type = gas
filter_name = GLOB.meta_gas_names[gas]
filter_name = GLOB.gas_data.names[gas]
investigate_log("was set to filter [filter_name] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
update_icon()
@@ -110,14 +110,12 @@
//Actually transfer the gas
if(transfer_moles1)
var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
air3.merge(removed1)
air1.transfer_to(air3, transfer_moles1)
var/datum/pipeline/parent1 = parents[1]
parent1.update = TRUE
if(transfer_moles2)
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
air3.merge(removed2)
air2.transfer_to(air3, transfer_moles2)
var/datum/pipeline/parent2 = parents[2]
parent2.update = TRUE
@@ -210,7 +210,7 @@
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
air1.adjust_moles(/datum/gas/oxygen, -max(0,air1.get_moles(/datum/gas/oxygen) - 2 / efficiency)) //Let's use gas for this
air1.adjust_moles(GAS_O2, -max(0,air1.get_moles(GAS_O2) - 2 / efficiency)) //Let's use gas for this
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -224,7 +224,7 @@
var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || air1.get_moles(/datum/gas/oxygen) < 5) // Turn off if the machine won't work.
if(!nodes[1] || !airs[1] || air1.get_moles(GAS_O2) < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
@@ -16,6 +16,7 @@
var/datum/radio_frequency/radio_connection
level = 1
interacts_with_air = TRUE
layer = GAS_SCRUBBER_LAYER
pipe_state = "injector"
@@ -65,11 +66,7 @@
var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
air_update_turf()
update_parents()
@@ -84,9 +81,7 @@
injecting = 1
if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
update_parents()
flick("inje_inject", src)
@@ -6,6 +6,7 @@
can_unwrench = TRUE
level = 1
interacts_with_air = TRUE
layer = GAS_SCRUBBER_LAYER
pipe_state = "pvent"
@@ -29,23 +30,10 @@
var/pressure_delta = abs(external_pressure - internal_pressure)
if(pressure_delta > 0.5)
if(external_pressure < internal_pressure)
var/air_temperature = (external.return_temperature() > 0) ? external.return_temperature() : internal.return_temperature()
var/transfer_moles = (pressure_delta * external.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = internal.remove(transfer_moles)
external.merge(removed)
else
var/air_temperature = (internal.return_temperature() > 0) ? internal.return_temperature() : external.return_temperature()
var/transfer_moles = (pressure_delta * internal.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = min(transfer_moles, external.total_moles() * internal.return_volume() / external.return_volume())
var/datum/gas_mixture/removed = external.remove(transfer_moles)
if(isnull(removed))
return
internal.merge(removed)
equalize_all_gases_in_list(list(internal,external))
active = TRUE
active = internal.temperature_share(external, OPEN_HEAT_TRANSFER_COEFFICIENT) ? TRUE : active
active = internal.temperature_share(external, OPEN_HEAT_TRANSFER_COEFFICIENT) || active
if(active)
air_update_turf()
@@ -5,6 +5,7 @@
icon_state = "relief_valve-e-map"
can_unwrench = TRUE
interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
interacts_with_air = TRUE
var/opened = FALSE
var/open_pressure = ONE_ATMOSPHERE * 3
var/close_pressure = ONE_ATMOSPHERE
@@ -49,14 +50,11 @@
else if(!opened && our_pressure >= open_pressure)
opened = TRUE
update_icon_nopipes()
if(opened && air_contents.return_temperature() > 0)
if(opened)
var/datum/gas_mixture/environment = loc.return_air()
var/pressure_delta = our_pressure - environment.return_pressure()
var/transfer_moles = pressure_delta*200/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
if(transfer_moles > 0)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
var/pressure_delta = abs(our_pressure - environment.return_pressure())
if(pressure_delta > 0.1)
equalize_all_gases_in_list(list(air_contents,environment))
air_update_turf()
update_parents()
@@ -21,8 +21,8 @@
air_contents.set_volume(volume)
air_contents.set_temperature(T20C)
if(gas_type)
air_contents.set_moles(gas_type, AIR_CONTENTS)
name = "[name] ([GLOB.meta_gas_names[gas_type]])"
air_contents.set_moles(gas_type,AIR_CONTENTS)
name = "[name] ([GLOB.gas_data.names[gas_type]])"
setPipingLayer(piping_layer)
/obj/machinery/atmospherics/components/unary/tank/air
@@ -32,30 +32,30 @@
/obj/machinery/atmospherics/components/unary/tank/air/New()
..()
var/datum/gas_mixture/air_contents = airs[1]
air_contents.set_moles(/datum/gas/oxygen, AIR_CONTENTS * 0.21)
air_contents.set_moles(/datum/gas/nitrogen, AIR_CONTENTS * 0.79)
air_contents.set_moles(GAS_O2, AIR_CONTENTS * 0.21)
air_contents.set_moles(GAS_N2, AIR_CONTENTS * 0.79)
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
gas_type = /datum/gas/carbon_dioxide
gas_type = GAS_CO2
/obj/machinery/atmospherics/components/unary/tank/toxins
icon_state = "orange"
gas_type = /datum/gas/plasma
gas_type = GAS_PLASMA
/obj/machinery/atmospherics/components/unary/tank/nitrogen
icon_state = "red"
gas_type = /datum/gas/nitrogen
gas_type = GAS_N2
/obj/machinery/atmospherics/components/unary/tank/oxygen
icon_state = "blue"
gas_type = /datum/gas/oxygen
gas_type = GAS_O2
/obj/machinery/atmospherics/components/unary/tank/nitrous
icon_state = "red_white"
gas_type = /datum/gas/nitrous_oxide
gas_type = GAS_NITROUS
/obj/machinery/atmospherics/components/unary/tank/bz
gas_type = /datum/gas/bz
gas_type = GAS_BZ
// /obj/machinery/atmospherics/components/unary/tank/freon
// icon_state = "blue"
@@ -75,17 +75,17 @@
/obj/machinery/atmospherics/components/unary/tank/hypernoblium
icon_state = "blue"
gas_type = /datum/gas/hypernoblium
gas_type = GAS_HYPERNOB
/obj/machinery/atmospherics/components/unary/tank/miasma
gas_type = /datum/gas/miasma
gas_type = GAS_MIASMA
/obj/machinery/atmospherics/components/unary/tank/nitryl
gas_type = /datum/gas/nitryl
gas_type = GAS_NITRYL
/obj/machinery/atmospherics/components/unary/tank/pluoxium
icon_state = "blue"
gas_type = /datum/gas/pluoxium
gas_type = GAS_PLUOXIUM
// /obj/machinery/atmospherics/components/unary/tank/proto_nitrate
// icon_state = "red"
@@ -93,14 +93,14 @@
/obj/machinery/atmospherics/components/unary/tank/stimulum
icon_state = "red"
gas_type = /datum/gas/stimulum
gas_type = GAS_STIMULUM
/obj/machinery/atmospherics/components/unary/tank/tritium
gas_type = /datum/gas/tritium
gas_type = GAS_TRITIUM
/obj/machinery/atmospherics/components/unary/tank/water_vapor
icon_state = "grey"
gas_type = /datum/gas/water_vapor
gas_type = GAS_H2O
// /obj/machinery/atmospherics/components/unary/tank/zauker
// gas_type = /datum/gas/zauker
@@ -15,6 +15,8 @@
level = 1
layer = GAS_SCRUBBER_LAYER
interacts_with_air = TRUE
var/id_tag = null
var/pump_direction = RELEASING
@@ -107,9 +109,7 @@
if(air_contents.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.return_volume()/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
loc.assume_air_moles(air_contents, transfer_moles)
air_update_turf()
else // external -> internal
@@ -122,11 +122,7 @@
moles_delta = min(moles_delta, (internal_pressure_bound - air_contents.return_pressure()) * our_multiplier)
if(moles_delta > 0)
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if (isnull(removed)) // in space
return
air_contents.merge(removed)
loc.transfer_air(air_contents, moles_delta)
air_update_turf()
update_parents()
@@ -13,10 +13,12 @@
level = 1
layer = GAS_SCRUBBER_LAYER
interacts_with_air = TRUE
var/id_tag = null
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
var/filter_types = list(/datum/gas/carbon_dioxide)
var/filter_types = list(GAS_CO2)
var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
var/list/turf/adjacent_turfs = list()
@@ -33,11 +35,6 @@
if(!id_tag)
id_tag = assign_uid_vents()
for(var/f in filter_types)
if(istext(f))
filter_types -= f
filter_types += gas_id2path(f)
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
var/area/A = get_base_area(src)
if (A)
@@ -97,8 +94,8 @@
return FALSE
var/list/f_types = list()
for(var/path in GLOB.meta_gas_ids)
f_types += list(list("gas_id" = GLOB.meta_gas_ids[path], "gas_name" = GLOB.meta_gas_names[path], "enabled" = (path in filter_types)))
for(var/id in GLOB.gas_data.ids)
f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types)))
var/datum/signal/signal = new(list(
"tag" = id_tag,
@@ -150,32 +147,17 @@
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(filter_types))
return FALSE
if(scrubbing & SCRUBBING)
var/transfer_moles = min(1, volume_rate/environment.return_volume())*environment.total_moles()
environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types)
//Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile
if(isnull(removed))
return FALSE
removed.scrub_into(air_contents, filter_types)
//Remix the resulting gases
tile.assume_air(removed)
tile.air_update_turf()
else //Just siphoning all air
var/transfer_moles = environment.total_moles()*(volume_rate/environment.return_volume())
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
air_contents.merge(removed)
environment.transfer_ratio_to(air_contents, volume_rate/environment.return_volume())
tile.air_update_turf()
update_parents()
@@ -222,12 +204,12 @@
investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS)
if("toggle_filter" in signal.data)
filter_types ^= gas_id2path(signal.data["toggle_filter"])
filter_types ^= signal.data["toggle_filter"]
if("set_filters" in signal.data)
filter_types = list()
for(var/gas in signal.data["set_filters"])
filter_types += gas_id2path(gas)
filter_types += gas
if("init" in signal.data)
name = signal.data["init"]
@@ -241,25 +241,4 @@
/datum/pipeline/proc/reconcile_air()
var/list/datum/gas_mixture/GL = get_all_connected_airs()
var/total_thermal_energy = 0
var/total_heat_capacity = 0
var/datum/gas_mixture/total_gas_mixture = new(0)
for(var/i in GL)
var/datum/gas_mixture/G = i
total_gas_mixture.set_volume(total_gas_mixture.return_volume() + G.return_volume())
total_gas_mixture.merge(G)
total_thermal_energy += G.thermal_energy()
total_heat_capacity += G.heat_capacity()
total_gas_mixture.set_temperature(total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0)
if(total_gas_mixture.return_volume() > 0)
//Update individual gas_mixtures by volume ratio
for(var/i in GL)
var/datum/gas_mixture/G = i
G.copy_from(total_gas_mixture)
G.multiply(G.return_volume()/total_gas_mixture.return_volume())
equalize_all_gases_in_list(GL)
@@ -12,6 +12,7 @@
icon_state = "miner"
density = FALSE
resistance_flags = INDESTRUCTIBLE|ACID_PROOF|FIRE_PROOF
interacts_with_air = TRUE
var/spawn_id = null
var/spawn_temp = T20C
var/spawn_mol = MOLES_CELLSTANDARD * 10
@@ -117,7 +118,7 @@
on_overlay.color = overlay_color
add_overlay(on_overlay)
/obj/machinery/atmospherics/miner/process()
/obj/machinery/atmospherics/miner/process_atmos()
update_power()
check_operation()
if(active && !broken)
@@ -144,34 +145,34 @@
/obj/machinery/atmospherics/miner/n2o
name = "\improper N2O Gas Miner"
overlay_color = "#FFCCCC"
spawn_id = /datum/gas/nitrous_oxide
spawn_id = GAS_NITROUS
/obj/machinery/atmospherics/miner/nitrogen
name = "\improper N2 Gas Miner"
overlay_color = "#CCFFCC"
spawn_id = /datum/gas/nitrogen
spawn_id = GAS_N2
/obj/machinery/atmospherics/miner/oxygen
name = "\improper O2 Gas Miner"
overlay_color = "#007FFF"
spawn_id = /datum/gas/oxygen
spawn_id = GAS_O2
/obj/machinery/atmospherics/miner/toxins
name = "\improper Plasma Gas Miner"
overlay_color = "#FF0000"
spawn_id = /datum/gas/plasma
spawn_id = GAS_PLASMA
/obj/machinery/atmospherics/miner/carbon_dioxide
name = "\improper CO2 Gas Miner"
overlay_color = "#CDCDCD"
spawn_id = /datum/gas/carbon_dioxide
spawn_id = GAS_CO2
/obj/machinery/atmospherics/miner/bz
name = "\improper BZ Gas Miner"
overlay_color = "#FAFF00"
spawn_id = /datum/gas/bz
spawn_id = GAS_BZ
/obj/machinery/atmospherics/miner/water_vapor
name = "\improper Water Vapor Gas Miner"
overlay_color = "#99928E"
spawn_id = /datum/gas/water_vapor
spawn_id = GAS_H2O
@@ -6,6 +6,7 @@
buckle_lying = 1
var/icon_temperature = T20C //stop small changes in temperature causing icon refresh
resistance_flags = LAVA_PROOF | FIRE_PROOF
interacts_with_air = TRUE
/obj/machinery/atmospherics/pipe/heat_exchanging/Initialize()
. = ..()
@@ -54,6 +54,9 @@
/obj/machinery/atmospherics/pipe/remove_air(amount)
return parent.air.remove(amount)
/obj/machinery/atmospherics/pipe/remove_air_ratio(ratio)
return parent.air.remove_ratio(ratio)
/obj/machinery/atmospherics/pipe/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pipe_meter))
var/obj/item/pipe_meter/meter = W
@@ -28,7 +28,7 @@
// var/pressure_limit = 50000
var/temperature_resistance = 1000 + T0C
var/starter_temp
var/starter_temp = T20C
// Prototype vars
var/prototype = FALSE
var/valve_timer = null
@@ -74,37 +74,37 @@
name = "n2 canister"
desc = "Nitrogen. Reportedly useful for something."
icon_state = "red"
gas_type = /datum/gas/nitrogen
gas_type = GAS_N2
/obj/machinery/portable_atmospherics/canister/oxygen
name = "o2 canister"
desc = "Oxygen. Necessary for human life."
icon_state = "blue"
gas_type = /datum/gas/oxygen
gas_type = GAS_O2
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
name = "co2 canister"
desc = "Carbon dioxide. What the fuck is carbon dioxide?"
icon_state = "black"
gas_type = /datum/gas/carbon_dioxide
gas_type = GAS_CO2
/obj/machinery/portable_atmospherics/canister/toxins
name = "plasma canister"
desc = "Plasma. The reason YOU are here. Highly toxic."
icon_state = "orange"
gas_type = /datum/gas/plasma
gas_type = GAS_PLASMA
/obj/machinery/portable_atmospherics/canister/bz
name = "\improper BZ canister"
desc = "BZ. A powerful hallucinogenic nerve agent."
icon_state = "purple"
gas_type = /datum/gas/bz
gas_type = GAS_BZ
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
name = "n2o canister"
desc = "Nitrous oxide. Known to cause drowsiness."
icon_state = "redws"
gas_type = /datum/gas/nitrous_oxide
gas_type = GAS_NITROUS
/obj/machinery/portable_atmospherics/canister/air
name = "air canister"
@@ -115,57 +115,57 @@
name = "tritium canister"
desc = "Tritium. Inhalation might cause irradiation."
icon_state = "green"
gas_type = /datum/gas/tritium
gas_type = GAS_TRITIUM
/obj/machinery/portable_atmospherics/canister/nob
name = "hyper-noblium canister"
desc = "Hyper-Noblium. More noble than all other gases."
icon_state = "freon"
gas_type = /datum/gas/hypernoblium
gas_type = GAS_HYPERNOB
/obj/machinery/portable_atmospherics/canister/nitryl
name = "nitryl canister"
desc = "Nitryl. Feels great 'til the acid eats your lungs."
icon_state = "brown"
gas_type = /datum/gas/nitryl
gas_type = GAS_NITRYL
/obj/machinery/portable_atmospherics/canister/stimulum
name = "stimulum canister"
desc = "Stimulum. High energy gas, high energy people."
icon_state = "darkpurple"
gas_type = /datum/gas/stimulum
gas_type = GAS_STIMULUM
/obj/machinery/portable_atmospherics/canister/pluoxium
name = "pluoxium canister"
desc = "Pluoxium. Like oxygen, but more bang for your buck."
icon_state = "darkblue"
gas_type = /datum/gas/pluoxium
gas_type = GAS_PLUOXIUM
/obj/machinery/portable_atmospherics/canister/water_vapor
name = "water vapor canister"
desc = "Water vapor. We get it, you vape."
icon_state = "water_vapor"
gas_type = /datum/gas/water_vapor
gas_type = GAS_H2O
filled = 1
/obj/machinery/portable_atmospherics/canister/miasma
name = "miasma canister"
desc = "Miasma. Makes you wish your nose were blocked."
icon_state = "miasma"
gas_type = /datum/gas/miasma
gas_type = GAS_MIASMA
filled = 1
/obj/machinery/portable_atmospherics/canister/methane
name = "methane canister"
desc = "Methane. The simplest of hydrocarbons. Non-toxic but highly flammable."
icon_state = "greyblackred"
gas_type = /datum/gas/methane
gas_type = GAS_METHANE
/obj/machinery/portable_atmospherics/canister/methyl_bromide
name = "methyl bromide canister"
desc = "Methyl bromide. A potent toxin to most, essential for the Kharmaan to live."
icon_state = "purplecyan"
gas_type = /datum/gas/methyl_bromide
gas_type = GAS_METHYL_BROMIDE
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
if(timing)
@@ -198,7 +198,7 @@
name = "prototype canister"
desc = "A prototype canister for a prototype bike, what could go wrong?"
icon_state = "proto"
gas_type = /datum/gas/oxygen
gas_type = GAS_O2
filled = 1
release_pressure = ONE_ATMOSPHERE*2
@@ -217,13 +217,13 @@
// air_contents.add_gas(gas_type)
if(starter_temp)
air_contents.set_temperature(starter_temp)
if(!air_contents.return_volume())
CRASH("Auxtools is failing somehow! Gas with pointer [air_contents._extools_pointer_gasmixture] is not valid.")
air_contents.set_moles(gas_type,(maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
if(starter_temp)
air_contents.set_temperature(starter_temp)
/obj/machinery/portable_atmospherics/canister/air/create_gas()
air_contents.set_moles(/datum/gas/oxygen, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(GAS_O2, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(GAS_N2, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
/obj/machinery/portable_atmospherics/canister/update_icon_state()
if(stat & BROKEN)
@@ -287,9 +287,8 @@
/obj/machinery/portable_atmospherics/canister/proc/canister_break()
disconnect()
var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
T.assume_air(expelled_gas)
T.assume_air(air_contents)
air_update_turf()
obj_break()
@@ -434,10 +433,10 @@
var/list/danger = list()
for(var/id in air_contents.get_gases())
var/gas = air_contents.get_moles(id)
if(!GLOB.meta_gas_dangers[id])
if(!GLOB.gas_data.flags[id] & GAS_FLAG_DANGEROUS)
continue
if(gas > (GLOB.meta_gas_visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[GLOB.meta_gas_names[id]] = gas //ex. "plasma" = 20
if(gas > (GLOB.gas_data.visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[GLOB.gas_data.names[id]] = gas //ex. "plasma" = 20
if(danger.len)
message_admins("[ADMIN_LOOKUPFLW(usr)] opened a canister that contains the following at [ADMIN_VERBOSEJMP(src)]:")
@@ -16,7 +16,7 @@
/obj/machinery/portable_atmospherics/New()
..()
SSair.atmos_machinery += src
SSair.atmos_air_machinery += src
air_contents = new(volume)
air_contents.set_temperature(T20C)
@@ -24,7 +24,7 @@
return 1
/obj/machinery/portable_atmospherics/Destroy()
SSair.atmos_machinery -= src
SSair.atmos_air_machinery -= src
disconnect()
qdel(air_contents)
@@ -112,8 +112,8 @@
if("power")
on = !on
if(on && !holding)
var/plasma = air_contents.get_moles(/datum/gas/plasma)
var/n2o = air_contents.get_moles(/datum/gas/nitrous_oxide)
var/plasma = air_contents.get_moles(GAS_PLASMA)
var/n2o = air_contents.get_moles(GAS_NITROUS)
if(n2o || plasma)
message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [ADMIN_VERBOSEJMP(src)]")
log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [AREACOORD(src)]")

Some files were not shown because too many files have changed in this diff Show More