Merge pull request #12217 from Putnam3145/putnamos-for-real

The real fastmos: C++ monstermos port
This commit is contained in:
silicons
2020-07-09 20:37:18 -07:00
committed by GitHub
120 changed files with 1483 additions and 1377 deletions
BIN
View File
Binary file not shown.
+14 -12
View File
@@ -136,7 +136,7 @@
#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold #define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold
#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) #define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3)
#define TANK_MIN_RELEASE_PRESSURE 0 #define TANK_MIN_RELEASE_PRESSURE 0
#define TANK_DEFAULT_RELEASE_PRESSURE 16 #define TANK_DEFAULT_RELEASE_PRESSURE 17
//CANATMOSPASS //CANATMOSPASS
#define ATMOS_PASS_YES 1 #define ATMOS_PASS_YES 1
@@ -270,16 +270,9 @@
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\ T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y; T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that #define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
//prefer this to gas_mixture/total_moles in performance critical areas
#define TOTAL_MOLES(cached_gases, out_var)\
out_var = 0;\
for(var/total_moles_id in cached_gases){\
out_var += cached_gases[total_moles_id];\
}
#ifdef TESTING #ifdef TESTING
GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0)) GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
@@ -288,6 +281,19 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1 #define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
#endif #endif
#define EXTOOLS (world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")
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. //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)\ #define GAS_GARBAGE_COLLECT(GASGASGAS)\
var/list/CACHE_GAS = GASGASGAS;\ var/list/CACHE_GAS = GASGASGAS;\
@@ -296,10 +302,6 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
CACHE_GAS -= id;\ CACHE_GAS -= id;\
} }
#define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature
#define ARCHIVE(gas) gas.temperature_archived = gas.temperature; gas.gas_archive = gas.gases.Copy();
GLOBAL_LIST_INIT(pipe_paint_colors, list( GLOBAL_LIST_INIT(pipe_paint_colors, list(
"amethyst" = rgb(130,43,255), //supplymain "amethyst" = rgb(130,43,255), //supplymain
"blue" = rgb(0,0,255), "blue" = rgb(0,0,255),
+2 -3
View File
@@ -29,6 +29,5 @@
#endif #endif
/world/proc/enable_debugger() /world/proc/enable_debugger()
var/dll = world.GetConfig("env", "EXTOOLS_DLL") if (fexists(EXTOOLS))
if (dll) call(EXTOOLS, "debug_initialize")()
call(dll, "debug_initialize")()
+7 -6
View File
@@ -137,12 +137,13 @@
// SSair run section // SSair run section
#define SSAIR_PIPENETS 1 #define SSAIR_PIPENETS 1
#define SSAIR_ATMOSMACHINERY 2 #define SSAIR_ATMOSMACHINERY 2
#define SSAIR_REACTQUEUE 3 #define SSAIR_EXCITEDGROUPS 3
#define SSAIR_EXCITEDGROUPS 4 #define SSAIR_HIGHPRESSURE 4
#define SSAIR_HIGHPRESSURE 5 #define SSAIR_HOTSPOTS 5
#define SSAIR_HOTSPOTS 6 #define SSAIR_SUPERCONDUCTIVITY 6
#define SSAIR_SUPERCONDUCTIVITY 7 #define SSAIR_REBUILD_PIPENETS 7
#define SSAIR_REBUILD_PIPENETS 8 #define SSAIR_EQUALIZE 8
#define SSAIR_ACTIVETURFS 9
#define COMPILE_OVERLAYS(A)\ #define COMPILE_OVERLAYS(A)\
if (TRUE) {\ if (TRUE) {\
+87 -54
View File
@@ -6,7 +6,7 @@ SUBSYSTEM_DEF(air)
flags = SS_BACKGROUND flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/cost_turf_reactions = 0 var/cost_turfs = 0
var/cost_groups = 0 var/cost_groups = 0
var/cost_highpressure = 0 var/cost_highpressure = 0
var/cost_hotspots = 0 var/cost_hotspots = 0
@@ -14,10 +14,9 @@ SUBSYSTEM_DEF(air)
var/cost_pipenets = 0 var/cost_pipenets = 0
var/cost_rebuilds = 0 var/cost_rebuilds = 0
var/cost_atmos_machinery = 0 var/cost_atmos_machinery = 0
var/cost_equalize = 0
var/list/excited_groups = list()
var/list/active_turfs = list() var/list/active_turfs = list()
var/list/turf_react_queue = list()
var/list/hotspots = list() var/list/hotspots = list()
var/list/networks = list() var/list/networks = list()
var/list/pipenets_needing_rebuilt = list() var/list/pipenets_needing_rebuilt = list()
@@ -38,20 +37,25 @@ SUBSYSTEM_DEF(air)
var/map_loading = TRUE var/map_loading = TRUE
var/list/queued_for_activation 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
/datum/controller/subsystem/air/stat_entry(msg) /datum/controller/subsystem/air/stat_entry(msg)
msg += "C:{" msg += "C:{"
msg += "RQ:[round(cost_turf_reactions,1)]|" msg += "EQ:[round(cost_equalize,1)]|"
msg += "AT:[round(cost_turfs,1)]|"
msg += "EG:[round(cost_groups,1)]|" msg += "EG:[round(cost_groups,1)]|"
msg += "HP:[round(cost_highpressure,1)]|" msg += "HP:[round(cost_highpressure,1)]|"
msg += "HS:[round(cost_hotspots,1)]|" msg += "HS:[round(cost_hotspots,1)]|"
msg += "SC:[round(cost_superconductivity,1)]|" msg += "SC:[round(cost_superconductivity,1)]|"
msg += "PN:[round(cost_pipenets,1)]|" msg += "PN:[round(cost_pipenets,1)]|"
msg += "RB:[round(cost_rebuilds,1)]|"
msg += "AM:[round(cost_atmos_machinery,1)]" msg += "AM:[round(cost_atmos_machinery,1)]"
msg += "} " msg += "} "
msg += "AT:[active_turfs.len]|" msg += "AT:[active_turfs.len]|"
msg += "RQ:[turf_react_queue.len]|" msg += "EG:[get_amt_excited_groups()]|"
msg += "EG:[excited_groups.len]|"
msg += "HS:[hotspots.len]|" msg += "HS:[hotspots.len]|"
msg += "PN:[networks.len]|" msg += "PN:[networks.len]|"
msg += "HP:[high_pressure_delta.len]|" msg += "HP:[high_pressure_delta.len]|"
@@ -59,8 +63,8 @@ SUBSYSTEM_DEF(air)
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]" msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
..(msg) ..(msg)
/datum/controller/subsystem/air/Initialize(timeofday) /datum/controller/subsystem/air/Initialize(timeofday)
extools_update_ssair()
map_loading = FALSE map_loading = FALSE
setup_allturfs() setup_allturfs()
setup_atmos_machinery() setup_atmos_machinery()
@@ -68,6 +72,7 @@ SUBSYSTEM_DEF(air)
gas_reactions = init_gas_reactions() gas_reactions = init_gas_reactions()
return ..() return ..()
/datum/controller/subsystem/air/proc/extools_update_ssair()
/datum/controller/subsystem/air/fire(resumed = 0) /datum/controller/subsystem/air/fire(resumed = 0)
var/timer = TICK_USAGE_REAL var/timer = TICK_USAGE_REAL
@@ -101,12 +106,21 @@ SUBSYSTEM_DEF(air)
if(state != SS_RUNNING) if(state != SS_RUNNING)
return return
resumed = 0 resumed = 0
currentpart = SSAIR_REACTQUEUE currentpart = monstermos_enabled ? SSAIR_EQUALIZE : SSAIR_ACTIVETURFS
if(currentpart == SSAIR_REACTQUEUE) if(currentpart == SSAIR_EQUALIZE)
timer = TICK_USAGE_REAL timer = TICK_USAGE_REAL
process_react_queue(resumed) process_turf_equalize(resumed)
cost_turf_reactions = MC_AVERAGE(cost_turf_reactions, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer)) 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) if(state != SS_RUNNING)
return return
resumed = 0 resumed = 0
@@ -148,6 +162,8 @@ SUBSYSTEM_DEF(air)
resumed = 0 resumed = 0
currentpart = SSAIR_REBUILD_PIPENETS currentpart = SSAIR_REBUILD_PIPENETS
/datum/controller/subsystem/air/proc/process_pipenets(resumed = 0) /datum/controller/subsystem/air/proc/process_pipenets(resumed = 0)
if (!resumed) if (!resumed)
src.currentrun = networks.Copy() src.currentrun = networks.Copy()
@@ -182,19 +198,6 @@ SUBSYSTEM_DEF(air)
return return
/datum/controller/subsystem/air/proc/process_react_queue(resumed = 0)
if(!resumed)
src.currentrun = turf_react_queue.Copy()
var/list/currentrun = src.currentrun
while(currentrun.len)
var/turf/open/T = currentrun[currentrun.len]
currentrun.len--
if(T)
T.process_cell_reaction()
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0) /datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0)
if (!resumed) if (!resumed)
src.currentrun = active_super_conductivity.Copy() src.currentrun = active_super_conductivity.Copy()
@@ -229,10 +232,45 @@ SUBSYSTEM_DEF(air)
high_pressure_delta.len-- high_pressure_delta.len--
T.high_pressure_movements() T.high_pressure_movements()
T.pressure_difference = 0 T.pressure_difference = 0
T.pressure_specific_target = null
if(MC_TICK_CHECK) if(MC_TICK_CHECK)
return return
/datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0)
//cache for sanic speed
var/fire_count = times_fired
if (!resumed)
src.currentrun = active_turfs.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/turf/open/T = currentrun[currentrun.len]
currentrun.len--
if (T)
T.equalize_pressure_in_zone(fire_count)
//equalize_pressure_in_zone(T, fire_count)
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
//cache for sanic speed
var/fire_count = times_fired
if (!resumed)
src.currentrun = active_turfs.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/turf/open/T = currentrun[currentrun.len]
currentrun.len--
if (T)
T.process_cell(fire_count)
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0) /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))
sleep()
/*
if (!resumed) if (!resumed)
src.currentrun = excited_groups.Copy() src.currentrun = excited_groups.Copy()
//cache for sanic speed (lists are references anyways) //cache for sanic speed (lists are references anyways)
@@ -248,29 +286,33 @@ SUBSYSTEM_DEF(air)
EG.dismantle() EG.dismantle()
if (MC_TICK_CHECK) if (MC_TICK_CHECK)
return return
*/
/datum/controller/subsystem/air/proc/process_excited_groups_extools()
/datum/controller/subsystem/air/proc/get_amt_excited_groups()
/datum/controller/subsystem/air/proc/remove_from_active(turf/open/T) /datum/controller/subsystem/air/proc/remove_from_active(turf/open/T)
active_turfs -= T active_turfs -= T
SSair_turfs.currentrun -= T if(currentpart == SSAIR_ACTIVETURFS)
currentrun -= T
#ifdef VISUALIZE_ACTIVE_TURFS #ifdef VISUALIZE_ACTIVE_TURFS
T.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#00ff00") T.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#00ff00")
#endif #endif
if(istype(T)) if(istype(T))
T.excited = 0 T.set_excited(FALSE)
if(T.excited_group) T.eg_garbage_collect()
T.excited_group.garbage_collect()
remove_from_react_queue(T)
/datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1) /datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
if(istype(T) && T.air) if(istype(T) && T.air)
#ifdef VISUALIZE_ACTIVE_TURFS #ifdef VISUALIZE_ACTIVE_TURFS
T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY) T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY)
#endif #endif
T.excited = TRUE T.set_excited(TRUE)
active_turfs[T] = SSair_turfs.currentrun[T] = TRUE active_turfs |= T
if(blockchanges && T.excited_group) if(currentpart == SSAIR_ACTIVETURFS)
T.excited_group.garbage_collect() currentrun |= T
add_to_react_queue(T) if(blockchanges)
T.eg_garbage_collect()
else if(T.flags_1 & INITIALIZED_1) else if(T.flags_1 & INITIALIZED_1)
for(var/turf/S in T.atmos_adjacent_turfs) for(var/turf/S in T.atmos_adjacent_turfs)
add_to_active(S) add_to_active(S)
@@ -281,17 +323,6 @@ SUBSYSTEM_DEF(air)
else else
T.requires_activation = TRUE T.requires_activation = TRUE
/datum/controller/subsystem/air/proc/add_to_react_queue(turf/open/T)
if(istype(T) && T.air)
turf_react_queue[T] = TRUE
if(currentpart == SSAIR_REACTQUEUE)
currentrun[T] = TRUE
/datum/controller/subsystem/air/proc/remove_from_react_queue(turf/open/T)
turf_react_queue -= T
if(currentpart == SSAIR_REACTQUEUE)
currentrun -= T
/datum/controller/subsystem/air/StartLoadingMap() /datum/controller/subsystem/air/StartLoadingMap()
LAZYINITLIST(queued_for_activation) LAZYINITLIST(queued_for_activation)
map_loading = TRUE map_loading = TRUE
@@ -339,11 +370,11 @@ SUBSYSTEM_DEF(air)
while (turfs_to_check.len) while (turfs_to_check.len)
var/ending_ats = active_turfs.len var/ending_ats = active_turfs.len
for(var/thing in excited_groups) /*for(var/thing in excited_groups)
var/datum/excited_group/EG = thing var/datum/excited_group/EG = thing
EG.self_breakdown(space_is_all_consuming = 1) //EG.self_breakdown(space_is_all_consuming = 1)
EG.dismantle() //EG.dismantle()
CHECK_TICK 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." 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>") to_chat(world, "<span class='boldannounce'>[msg]</span>")
@@ -351,6 +382,7 @@ SUBSYSTEM_DEF(air)
/turf/open/proc/resolve_active_graph() /turf/open/proc/resolve_active_graph()
. = list() . = list()
/*
var/datum/excited_group/EG = excited_group var/datum/excited_group/EG = excited_group
if (blocks_air || !air) if (blocks_air || !air)
return return
@@ -371,7 +403,8 @@ SUBSYSTEM_DEF(air)
EG.add_turf(ET) EG.add_turf(ET)
if (!ET.excited) if (!ET.excited)
ET.excited = 1 ET.excited = 1
. += ET . += ET*/
/turf/open/space/resolve_active_graph() /turf/open/space/resolve_active_graph()
return list() return list()
@@ -389,9 +422,8 @@ SUBSYSTEM_DEF(air)
CHECK_TICK CHECK_TICK
/datum/controller/subsystem/air/proc/setup_template_machinery(list/atmos_machines) /datum/controller/subsystem/air/proc/setup_template_machinery(list/atmos_machines)
if(!initialized) if(!initialized) // yogs - fixes randomized bars
return return // yogs
for(var/A in atmos_machines) for(var/A in atmos_machines)
var/obj/machinery/atmospherics/AM = A var/obj/machinery/atmospherics/AM = A
AM.atmosinit() AM.atmosinit()
@@ -415,6 +447,7 @@ SUBSYSTEM_DEF(air)
#undef SSAIR_PIPENETS #undef SSAIR_PIPENETS
#undef SSAIR_ATMOSMACHINERY #undef SSAIR_ATMOSMACHINERY
#undef SSAIR_ACTIVETURFS
#undef SSAIR_EXCITEDGROUPS #undef SSAIR_EXCITEDGROUPS
#undef SSAIR_HIGHPRESSURE #undef SSAIR_HIGHPRESSURE
#undef SSAIR_HOTSPOTS #undef SSAIR_HOTSPOTS
+2 -1
View File
@@ -1,5 +1,5 @@
//WHAT IF WE TAKE THE ACTIVE TURF PROCESSING AND PUSH IT SOMEWHERE ELSE!!! //WHAT IF WE TAKE THE ACTIVE TURF PROCESSING AND PUSH IT SOMEWHERE ELSE!!!
/*
SUBSYSTEM_DEF(air_turfs) SUBSYSTEM_DEF(air_turfs)
name = "Atmospherics - Turfs" name = "Atmospherics - Turfs"
init_order = INIT_ORDER_AIR_TURFS init_order = INIT_ORDER_AIR_TURFS
@@ -24,3 +24,4 @@ SUBSYSTEM_DEF(air_turfs)
return return
resumed = 0 resumed = 0
return return
*/
+1 -1
View File
@@ -121,7 +121,7 @@
if(-INFINITY to T0C) if(-INFINITY to T0C)
add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice! add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice!
if(T0C to T0C + 100) if(T0C to T0C + 100)
decrease = ((T.air.temperature - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio) decrease = ((T.air.return_temperature() - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio)
if(T0C + 100 to INFINITY) if(T0C + 100 to INFINITY)
decrease = INFINITY decrease = INFINITY
decrease = max(0, decrease) decrease = max(0, decrease)
@@ -404,7 +404,7 @@
if(M.loc) if(M.loc)
environment = M.loc.return_air() environment = M.loc.return_air()
if(environment) if(environment)
plasmamount = environment.gases[/datum/gas/plasma] 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 if(plasmamount && plasmamount > GLOB.meta_gas_visibility[/datum/gas/plasma]) //if there's enough plasma in the air to see
. += power * 0.5 . += power * 0.5
if(M.reagents.has_reagent(/datum/reagent/toxin/plasma)) if(M.reagents.has_reagent(/datum/reagent/toxin/plasma))
+5 -6
View File
@@ -117,9 +117,8 @@
continue continue
var/datum/gas_mixture/A = F.air var/datum/gas_mixture/A = F.air
var/list/A_gases = A.gases
var/trace_gases var/trace_gases
for(var/id in A_gases) for(var/id in A.get_gases())
if(id in GLOB.hardcoded_gases) if(id in GLOB.hardcoded_gases)
continue continue
trace_gases = TRUE trace_gases = TRUE
@@ -128,15 +127,15 @@
// Can most things breathe? // Can most things breathe?
if(trace_gases) if(trace_gases)
continue continue
if(A_gases[/datum/gas/oxygen] <= 16) if(A.get_moles(/datum/gas/oxygen) < 16)
continue continue
if(A_gases[/datum/gas/plasma]) if(A.get_moles(/datum/gas/plasma))
continue continue
if(A_gases[/datum/gas/carbon_dioxide] >= 10) if(A.get_moles(/datum/gas/carbon_dioxide) >= 10)
continue continue
// Aim for goldilocks temperatures and pressure // Aim for goldilocks temperatures and pressure
if((A.temperature <= 270) || (A.temperature >= 360)) if((A.return_temperature() <= 270) || (A.return_temperature() >= 360))
continue continue
var/pressure = A.return_pressure() var/pressure = A.return_pressure()
if((pressure <= 20) || (pressure >= 550)) if((pressure <= 20) || (pressure >= 550))
+1 -2
View File
@@ -226,9 +226,8 @@
/obj/effect/proc_holder/spell/targeted/olfaction/cast(list/targets, mob/living/user = usr) /obj/effect/proc_holder/spell/targeted/olfaction/cast(list/targets, mob/living/user = usr)
//can we sniff? is there miasma in the air? //can we sniff? is there miasma in the air?
var/datum/gas_mixture/air = user.loc.return_air() var/datum/gas_mixture/air = user.loc.return_air()
var/list/cached_gases = air.gases
if(cached_gases[/datum/gas/miasma]) if(air.get_moles(/datum/gas/miasma))
user.adjust_disgust(sensitivity * 45) 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>") 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 return
+1 -1
View File
@@ -125,7 +125,7 @@
/datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T) /datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T)
var/target_amount = text2num(name) var/target_amount = text2num(name)
var/found_amount = 0 var/found_amount = 0
found_amount += T.air_contents.gases[/datum/gas/plasma] found_amount += T.air_contents.get_moles(/datum/gas/plasma)
return found_amount>=target_amount return found_amount>=target_amount
@@ -53,14 +53,14 @@
"id_tag" = id_tag, "id_tag" = id_tag,
"timestamp" = world.time, "timestamp" = world.time,
"pressure" = air_sample.return_pressure(), "pressure" = air_sample.return_pressure(),
"temperature" = air_sample.temperature, "temperature" = air_sample.return_temperature(),
"gases" = list() "gases" = list()
)) ))
var/total_moles = air_sample.total_moles() var/total_moles = air_sample.total_moles()
if(total_moles) if(total_moles)
for(var/gas_id in air_sample.gases) for(var/gas_id in air_sample.get_gases())
var/gas_name = GLOB.meta_gas_names[gas_id] var/gas_name = GLOB.meta_gas_names[gas_id]
signal.data["gases"][gas_name] = air_sample.gases[gas_id] / total_moles * 100 signal.data["gases"][gas_name] = air_sample.get_moles(gas_id) / total_moles * 100
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
+1 -1
View File
@@ -93,7 +93,7 @@
var/shuttledocked = 0 var/shuttledocked = 0
var/delayed_close_requested = FALSE // TRUE means the door will automatically close the next time it's opened. var/delayed_close_requested = FALSE // TRUE means the door will automatically close the next time it's opened.
var/air_tight = FALSE //TRUE means density will be set as soon as the door begins to close air_tight = FALSE
var/prying_so_hard = FALSE var/prying_so_hard = FALSE
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+36 -7
View File
@@ -17,6 +17,7 @@
interaction_flags_atom = INTERACT_ATOM_UI_INTERACT interaction_flags_atom = INTERACT_ATOM_UI_INTERACT
var/secondsElectrified = 0 var/secondsElectrified = 0
var/air_tight = FALSE //TRUE means density will be set as soon as the door begins to close
var/shockedby var/shockedby
var/visible = TRUE // To explain: Whether the door can block line of sight when closed or not. var/visible = TRUE // To explain: Whether the door can block line of sight when closed or not.
var/operating = FALSE var/operating = FALSE
@@ -161,7 +162,7 @@
open() open()
else else
close() close()
return return TRUE
if(density) if(density)
do_animate("deny") do_animate("deny")
@@ -181,11 +182,36 @@
/obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user) /obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user)
return return
/obj/machinery/door/proc/is_holding_pressure()
var/turf/open/T = loc
if(!T)
return FALSE
if(!density)
return FALSE
// alrighty now we check for how much pressure we're holding back
var/min_moles = T.air.total_moles()
var/max_moles = min_moles
// okay this is a bit hacky. First, we set density to 0 and recalculate our adjacent turfs
density = FALSE
T.ImmediateCalculateAdjacentTurfs()
// then we use those adjacent turfs to figure out what the difference between the lowest and highest pressures we'd be holding is
for(var/turf/open/T2 in T.atmos_adjacent_turfs)
if((flags_1 & ON_BORDER_1) && get_dir(src, T2) != dir)
continue
var/moles = T2.air.total_moles()
if(moles < min_moles)
min_moles = moles
if(moles > max_moles)
max_moles = moles
density = TRUE
T.ImmediateCalculateAdjacentTurfs() // alright lets put it back
return max_moles - min_moles > 20
/obj/machinery/door/attackby(obj/item/I, mob/user, params) /obj/machinery/door/attackby(obj/item/I, mob/user, params)
if(user.a_intent != INTENT_HARM && (istype(I, /obj/item/crowbar) || istype(I, /obj/item/fireaxe))) if(user.a_intent != INTENT_HARM && (I.tool_behaviour == TOOL_CROWBAR || istype(I, /obj/item/fireaxe)))
try_to_crowbar(I, user) try_to_crowbar(I, user)
return 1 return 1
else if(istype(I, /obj/item/weldingtool)) else if(I.tool_behaviour == TOOL_WELDER)
try_to_weld(I, user) try_to_weld(I, user)
return 1 return 1
else if(!(I.item_flags & NOBLUDGEON) && user.a_intent != INTENT_HARM) else if(!(I.item_flags & NOBLUDGEON) && user.a_intent != INTENT_HARM)
@@ -223,13 +249,13 @@
if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) ) if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
INVOKE_ASYNC(src, .proc/open) INVOKE_ASYNC(src, .proc/open)
if(prob(severity*10 - 20)) if(prob(severity*10 - 20))
if(secondsElectrified == 0) if(secondsElectrified == MACHINE_NOT_ELECTRIFIED)
secondsElectrified = -1 secondsElectrified = MACHINE_ELECTRIFIED_PERMANENT
LAZYADD(shockedby, "\[[TIME_STAMP("hh:mm:ss", FALSE)]\]EM Pulse") LAZYADD(shockedby, "\[[TIME_STAMP("hh:mm:ss", FALSE)]\]EM Pulse")
addtimer(CALLBACK(src, .proc/unelectrify), 300) addtimer(CALLBACK(src, .proc/unelectrify), 300)
/obj/machinery/door/proc/unelectrify() /obj/machinery/door/proc/unelectrify()
secondsElectrified = 0 secondsElectrified = MACHINE_NOT_ELECTRIFIED
/obj/machinery/door/update_icon_state() /obj/machinery/door/update_icon_state()
if(density) if(density)
@@ -289,8 +315,11 @@
return return
operating = TRUE operating = TRUE
do_animate("closing") do_animate("closing")
layer = closingLayer layer = closingLayer
if(air_tight)
density = TRUE
sleep(5) sleep(5)
density = TRUE density = TRUE
sleep(5) sleep(5)
@@ -302,7 +331,7 @@
update_freelook_sight() update_freelook_sight()
if(safe) if(safe)
CheckForMobs() CheckForMobs()
else else if(!(flags_1 & ON_BORDER_1))
crush() crush()
return 1 return 1
+170 -22
View File
@@ -23,6 +23,8 @@
assemblytype = /obj/structure/firelock_frame assemblytype = /obj/structure/firelock_frame
armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70)
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
air_tight = TRUE
var/emergency_close_timer = 0
var/nextstate = null var/nextstate = null
var/boltslocked = TRUE var/boltslocked = TRUE
var/list/affecting_areas var/list/affecting_areas
@@ -68,10 +70,14 @@
return ..() return ..()
/obj/machinery/door/firedoor/Bumped(atom/movable/AM) /obj/machinery/door/firedoor/Bumped(atom/movable/AM)
if(panel_open || operating) if(panel_open || operating || welded)
return return
if(!density) if(ismob(AM))
return ..() var/mob/user = AM
if(density && !welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user)))
add_fingerprint(user)
open()
return TRUE
return FALSE return FALSE
@@ -86,6 +92,15 @@
. = ..() . = ..()
if(.) if(.)
return return
if(!welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user)))
add_fingerprint(user)
if(density)
emergency_close_timer = world.time + 30 // prevent it from instaclosing again if in space
open()
else
close()
return TRUE
if(operating || !density) if(operating || !density)
return return
user.changeNext_move(CLICK_CD_MELEE) user.changeNext_move(CLICK_CD_MELEE)
@@ -100,7 +115,7 @@
return return
if(welded) if(welded)
if(istype(C, /obj/item/wrench)) if(C.tool_behaviour == TOOL_WRENCH)
if(boltslocked) if(boltslocked)
to_chat(user, "<span class='notice'>There are screws locking the bolts in place!</span>") to_chat(user, "<span class='notice'>There are screws locking the bolts in place!</span>")
return return
@@ -114,7 +129,7 @@
"<span class='notice'>You undo [src]'s floor bolts.</span>") "<span class='notice'>You undo [src]'s floor bolts.</span>")
deconstruct(TRUE) deconstruct(TRUE)
return return
if(istype(C, /obj/item/screwdriver)) if(C.tool_behaviour == TOOL_SCREWDRIVER)
user.visible_message("<span class='notice'>[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts.</span>", \ user.visible_message("<span class='notice'>[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts.</span>", \
"<span class='notice'>You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts.</span>") "<span class='notice'>You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts.</span>")
C.play_tool_sound(src) C.play_tool_sound(src)
@@ -140,10 +155,27 @@
return return
if(density) if(density)
if(is_holding_pressure())
// tell the user that this is a bad idea, and have a do_after as well
to_chat(user, "<span class='warning'>As you begin crowbarring \the [src] a gush of air blows in your face... maybe you should reconsider?</span>")
if(!do_after(user, 15, TRUE, src)) // give them a few seconds to reconsider their decision.
return
log_game("[key_name_admin(user)] has opened a firelock with a pressure difference at [AREACOORD(loc)]") // there bibby I made it logged just for you. Enjoy.
// since we have high-pressure-ness, close all other firedoors on the tile
whack_a_mole()
if(welded || operating || !density)
return // in case things changed during our do_after
emergency_close_timer = world.time + 60 // prevent it from instaclosing again if in space
open() open()
else else
close() close()
/obj/machinery/door/firedoor/proc/allow_hand_open(mob/user)
var/area/A = get_area(src)
if(A && A.fire)
return FALSE
return !is_holding_pressure()
/obj/machinery/door/firedoor/attack_ai(mob/user) /obj/machinery/door/firedoor/attack_ai(mob/user)
add_fingerprint(user) add_fingerprint(user)
if(welded || operating || stat & NOPOWER) if(welded || operating || stat & NOPOWER)
@@ -171,20 +203,16 @@
if("closing") if("closing")
flick("door_closing", src) flick("door_closing", src)
/obj/machinery/door/firedoor/update_icon_state() /obj/machinery/door/firedoor/update_icon()
cut_overlays()
if(density) if(density)
icon_state = "door_closed" icon_state = "door_closed"
if(welded)
add_overlay("welded")
else else
icon_state = "door_open" icon_state = "door_open"
if(welded)
/obj/machinery/door/firedoor/update_overlays() add_overlay("welded_open")
. = ..()
if(!welded)
return
if(density)
. += "welded"
else
. += "welded_open"
/obj/machinery/door/firedoor/open() /obj/machinery/door/firedoor/open()
. = ..() . = ..()
@@ -194,6 +222,61 @@
. = ..() . = ..()
latetoggle() latetoggle()
/obj/machinery/door/firedoor/proc/whack_a_mole(reconsider_immediately = FALSE)
set waitfor = 0
for(var/cdir in GLOB.cardinals)
if((flags_1 & ON_BORDER_1) && cdir != dir)
continue
whack_a_mole_part(get_step(src, cdir), reconsider_immediately)
if(flags_1 & ON_BORDER_1)
whack_a_mole_part(get_turf(src), reconsider_immediately)
/obj/machinery/door/firedoor/proc/whack_a_mole_part(turf/start_point, reconsider_immediately)
set waitfor = 0
var/list/doors_to_close = list()
var/list/turfs = list()
turfs[start_point] = 1
for(var/i = 1; (i <= turfs.len && i <= 11); i++) // check up to 11 turfs.
var/turf/open/T = turfs[i]
if(istype(T, /turf/open/space))
return -1
for(var/T2 in T.atmos_adjacent_turfs)
if(turfs[T2])
continue
var/is_cut_by_unopen_door = FALSE
for(var/obj/machinery/door/firedoor/FD in T2)
if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, T) != FD.dir)
continue
if(FD.operating || FD == src || FD.welded || FD.density)
continue
doors_to_close += FD
is_cut_by_unopen_door = TRUE
for(var/obj/machinery/door/firedoor/FD in T)
if((FD.flags_1 & ON_BORDER_1) && get_dir(T, T2) != FD.dir)
continue
if(FD.operating || FD == src || FD.welded || FD.density)
continue
doors_to_close += FD
is_cut_by_unopen_door= TRUE
if(!is_cut_by_unopen_door)
turfs[T2] = 1
if(turfs.len > 10)
return // too big, don't bother
for(var/obj/machinery/door/firedoor/FD in doors_to_close)
FD.emergency_pressure_stop(FALSE)
if(reconsider_immediately)
var/turf/open/T = FD.loc
if(istype(T))
T.ImmediateCalculateAdjacentTurfs()
/obj/machinery/door/firedoor/proc/emergency_pressure_stop(consider_timer = TRUE)
set waitfor = 0
if(density || operating || welded)
return
if(world.time >= emergency_close_timer || !consider_timer)
close()
/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE) /obj/machinery/door/firedoor/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1)) if(!(flags_1 & NODECONSTRUCT_1))
var/obj/structure/firelock_frame/F = new assemblytype(get_turf(src)) var/obj/structure/firelock_frame/F = new assemblytype(get_turf(src))
@@ -227,6 +310,59 @@
opacity = TRUE opacity = TRUE
density = TRUE density = TRUE
/obj/machinery/door/firedoor/border_only/close()
if(density)
return TRUE
if(operating || welded)
return
var/turf/T1 = get_turf(src)
var/turf/T2 = get_step(T1, dir)
for(var/mob/living/M in T1)
if(M.stat == CONSCIOUS && M.pulling && M.pulling.loc == T2 && !M.pulling.anchored && M.pulling.move_resist <= M.move_force)
var/mob/living/M2 = M.pulling
if(!istype(M2) || !M2.buckled || !M2.buckled.buckle_prevents_pull)
to_chat(M, "<span class='notice'>You pull [M.pulling] through [src] right as it closes</span>")
M.pulling.forceMove(T1)
M.start_pulling(M2)
for(var/mob/living/M in T2)
if(M.stat == CONSCIOUS && M.pulling && M.pulling.loc == T1 && !M.pulling.anchored && M.pulling.move_resist <= M.move_force)
var/mob/living/M2 = M.pulling
if(!istype(M2) || !M2.buckled || !M2.buckled.buckle_prevents_pull)
to_chat(M, "<span class='notice'>You pull [M.pulling] through [src] right as it closes</span>")
M.pulling.forceMove(T2)
M.start_pulling(M2)
. = ..()
/obj/machinery/door/firedoor/border_only/allow_hand_open(mob/user)
var/area/A = get_area(src)
if((!A || !A.fire) && !is_holding_pressure())
return TRUE
whack_a_mole(TRUE) // WOOP WOOP SIDE EFFECTS
var/turf/T = loc
var/turf/T2 = get_step(T, dir)
if(!T || !T2)
return
var/status1 = check_door_side(T)
var/status2 = check_door_side(T2)
if((status1 == 1 && status2 == -1) || (status1 == -1 && status2 == 1))
to_chat(user, "<span class='warning'>Access denied. Try closing another firedoor to minimize decompression, or using a crowbar.</span>")
return FALSE
return TRUE
/obj/machinery/door/firedoor/border_only/proc/check_door_side(turf/open/start_point)
var/list/turfs = list()
turfs[start_point] = 1
for(var/i = 1; (i <= turfs.len && i <= 11); i++) // check up to 11 turfs.
var/turf/open/T = turfs[i]
if(istype(T, /turf/open/space))
return -1
for(var/T2 in T.atmos_adjacent_turfs)
turfs[T2] = 1
if(turfs.len <= 10)
return 0 // not big enough to matter
return start_point.air.return_pressure() < 20 ? -1 : 1
/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target) /obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS)) if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE return TRUE
@@ -257,6 +393,18 @@
assemblytype = /obj/structure/firelock_frame/heavy assemblytype = /obj/structure/firelock_frame/heavy
max_integrity = 550 max_integrity = 550
/obj/machinery/door/firedoor/window
name = "window shutter"
icon = 'icons/obj/doors/doorfirewindow.dmi'
desc = "A second window that slides in when the original window is broken, designed to protect against hull breaches. Truly a work of genius by NT engineers."
glass = TRUE
explosion_block = 0
max_integrity = 50
resistance_flags = 0 // not fireproof
heat_proof = FALSE
/obj/machinery/door/firedoor/window/allow_hand_open()
return TRUE
/obj/item/electronics/firelock /obj/item/electronics/firelock
name = "firelock circuitry" name = "firelock circuitry"
@@ -294,7 +442,7 @@
/obj/structure/firelock_frame/attackby(obj/item/C, mob/user) /obj/structure/firelock_frame/attackby(obj/item/C, mob/user)
switch(constructionStep) switch(constructionStep)
if(CONSTRUCTION_PANEL_OPEN) if(CONSTRUCTION_PANEL_OPEN)
if(istype(C, /obj/item/crowbar)) if(C.tool_behaviour == TOOL_CROWBAR)
C.play_tool_sound(src) C.play_tool_sound(src)
user.visible_message("<span class='notice'>[user] starts prying something out from [src]...</span>", \ user.visible_message("<span class='notice'>[user] starts prying something out from [src]...</span>", \
"<span class='notice'>You begin prying out the wire cover...</span>") "<span class='notice'>You begin prying out the wire cover...</span>")
@@ -308,7 +456,7 @@
constructionStep = CONSTRUCTION_WIRES_EXPOSED constructionStep = CONSTRUCTION_WIRES_EXPOSED
update_icon() update_icon()
return return
if(istype(C, /obj/item/wrench)) if(C.tool_behaviour == TOOL_WRENCH)
if(locate(/obj/machinery/door/firedoor) in get_turf(src)) if(locate(/obj/machinery/door/firedoor) in get_turf(src))
to_chat(user, "<span class='warning'>There's already a firelock there.</span>") to_chat(user, "<span class='warning'>There's already a firelock there.</span>")
return return
@@ -350,7 +498,7 @@
return return
if(CONSTRUCTION_WIRES_EXPOSED) if(CONSTRUCTION_WIRES_EXPOSED)
if(istype(C, /obj/item/wirecutters)) if(C.tool_behaviour == TOOL_WIRECUTTER)
C.play_tool_sound(src) C.play_tool_sound(src)
user.visible_message("<span class='notice'>[user] starts cutting the wires from [src]...</span>", \ user.visible_message("<span class='notice'>[user] starts cutting the wires from [src]...</span>", \
"<span class='notice'>You begin removing [src]'s wires...</span>") "<span class='notice'>You begin removing [src]'s wires...</span>")
@@ -364,7 +512,7 @@
constructionStep = CONSTRUCTION_GUTTED constructionStep = CONSTRUCTION_GUTTED
update_icon() update_icon()
return return
if(istype(C, /obj/item/crowbar)) if(C.tool_behaviour == TOOL_CROWBAR)
C.play_tool_sound(src) C.play_tool_sound(src)
user.visible_message("<span class='notice'>[user] starts prying a metal plate into [src]...</span>", \ user.visible_message("<span class='notice'>[user] starts prying a metal plate into [src]...</span>", \
"<span class='notice'>You begin prying the cover plate back onto [src]...</span>") "<span class='notice'>You begin prying the cover plate back onto [src]...</span>")
@@ -379,7 +527,7 @@
update_icon() update_icon()
return return
if(CONSTRUCTION_GUTTED) if(CONSTRUCTION_GUTTED)
if(istype(C, /obj/item/crowbar)) if(C.tool_behaviour == TOOL_CROWBAR)
user.visible_message("<span class='notice'>[user] begins removing the circuit board from [src]...</span>", \ user.visible_message("<span class='notice'>[user] begins removing the circuit board from [src]...</span>", \
"<span class='notice'>You begin prying out the circuit board from [src]...</span>") "<span class='notice'>You begin prying out the circuit board from [src]...</span>")
if(!C.use_tool(src, user, 50, volume=50)) if(!C.use_tool(src, user, 50, volume=50))
@@ -401,7 +549,7 @@
"<span class='notice'>You begin adding wires to [src]...</span>") "<span class='notice'>You begin adding wires to [src]...</span>")
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 60, target = src)) if(do_after(user, 60, target = src))
if(constructionStep != CONSTRUCTION_GUTTED || !B.use_tool(src, user, 0, 5)) if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B)
return return
user.visible_message("<span class='notice'>[user] adds wires to [src].</span>", \ user.visible_message("<span class='notice'>[user] adds wires to [src].</span>", \
"<span class='notice'>You wire [src].</span>") "<span class='notice'>You wire [src].</span>")
@@ -410,7 +558,7 @@
update_icon() update_icon()
return return
if(CONSTRUCTION_NOCIRCUIT) if(CONSTRUCTION_NOCIRCUIT)
if(istype(C, /obj/item/weldingtool)) if(C.tool_behaviour == TOOL_WELDER)
if(!C.tool_start_check(user, amount=1)) if(!C.tool_start_check(user, amount=1))
return return
user.visible_message("<span class='notice'>[user] begins cutting apart [src]'s frame...</span>", \ user.visible_message("<span class='notice'>[user] begins cutting apart [src]'s frame...</span>", \
@@ -130,7 +130,7 @@
var/deltaTemperature = req_power / heat_cap var/deltaTemperature = req_power / heat_cap
if(deltaTemperature < 0) if(deltaTemperature < 0)
return return
env.temperature += deltaTemperature env.set_temperature(env.return_temperature(),deltaTemperature)
air_update_turf() air_update_turf()
/obj/machinery/shuttle/engine/default_change_direction_wrench(mob/user, obj/item/I) /obj/machinery/shuttle/engine/default_change_direction_wrench(mob/user, obj/item/I)
@@ -89,8 +89,8 @@
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
if(!air_contents) if(!air_contents)
return return
air_contents.volume = gas_capacity air_contents.set_volume(gas_capacity)
air_contents.temperature = T20C air_contents.set_temperature(T20C)
/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/hasFuel(var/required) /obj/machinery/atmospherics/components/unary/shuttle/heater/proc/hasFuel(var/required)
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
+6 -6
View File
@@ -83,9 +83,9 @@
var/datum/gas_mixture/env = L.return_air() var/datum/gas_mixture/env = L.return_air()
var/newMode = HEATER_MODE_STANDBY var/newMode = HEATER_MODE_STANDBY
if(setMode != HEATER_MODE_COOL && env.temperature < targetTemperature - temperatureTolerance) if(setMode != HEATER_MODE_COOL && env.return_temperature() < targetTemperature - temperatureTolerance)
newMode = HEATER_MODE_HEAT newMode = HEATER_MODE_HEAT
else if(setMode != HEATER_MODE_HEAT && env.temperature > targetTemperature + temperatureTolerance) else if(setMode != HEATER_MODE_HEAT && env.return_temperature() > targetTemperature + temperatureTolerance)
newMode = HEATER_MODE_COOL newMode = HEATER_MODE_COOL
if(mode != newMode) if(mode != newMode)
@@ -96,7 +96,7 @@
return return
var/heat_capacity = env.heat_capacity() var/heat_capacity = env.heat_capacity()
var/requiredPower = abs(env.temperature - targetTemperature) * heat_capacity var/requiredPower = abs(env.return_temperature() - targetTemperature) * heat_capacity
requiredPower = min(requiredPower, heatingPower) requiredPower = min(requiredPower, heatingPower)
if(requiredPower < 1) if(requiredPower < 1)
@@ -106,7 +106,7 @@
if(mode == HEATER_MODE_COOL) if(mode == HEATER_MODE_COOL)
deltaTemperature *= -1 deltaTemperature *= -1
if(deltaTemperature) if(deltaTemperature)
env.temperature += deltaTemperature env.set_temperature(env.return_temperature() + deltaTemperature)
air_update_turf() air_update_turf()
cell.use(requiredPower / efficiency) cell.use(requiredPower / efficiency)
else else
@@ -194,9 +194,9 @@
var/curTemp var/curTemp
if(istype(L)) if(istype(L))
var/datum/gas_mixture/env = L.return_air() var/datum/gas_mixture/env = L.return_air()
curTemp = env.temperature curTemp = env.return_temperature()
else if(isturf(L)) else if(isturf(L))
curTemp = L.temperature curTemp = L.return_temperature()
if(isnull(curTemp)) if(isnull(curTemp))
data["currentTemp"] = "N/A" data["currentTemp"] = "N/A"
else else
+1 -1
View File
@@ -21,7 +21,7 @@
var/cell_charge = get_charge() var/cell_charge = get_charge()
var/datum/gas_mixture/int_tank_air = internal_tank.return_air() var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None" var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown" var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01) var/cabin_pressure = round(return_pressure(),0.01)
var/output = {"[report_internal_damage()] var/output = {"[report_internal_damage()]
[integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null] [integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null]
@@ -422,13 +422,13 @@
return return
var/datum/gas_mixture/GM = new var/datum/gas_mixture/GM = new
if(prob(10)) if(prob(10))
GM.gases[/datum/gas/plasma] += 100 GM.adjust_moles(/datum/gas/plasma,100)
GM.temperature = 1500+T0C //should be enough to start a fire GM.set_temperature(1500+T0C) //should be enough to start a fire
T.visible_message("[src] suddenly disgorges a cloud of heated plasma.") T.visible_message("[src] suddenly disgorges a cloud of heated plasma.")
qdel(src) qdel(src)
else else
GM.gases[/datum/gas/plasma] += 5 GM.adjust_moles(/datum/gas/plasma,5)
GM.temperature = istype(T) ? T.air.return_temperature() : T20C GM.set_temperature(istype(T) ? T.air.return_temperature() : T20C)
T.visible_message("[src] suddenly disgorges a cloud of plasma.") T.visible_message("[src] suddenly disgorges a cloud of plasma.")
T.assume_air(GM) T.assume_air(GM)
return return
+8 -8
View File
@@ -247,10 +247,10 @@
/obj/mecha/proc/add_cabin() /obj/mecha/proc/add_cabin()
cabin_air = new cabin_air = new
cabin_air.temperature = T20C cabin_air.set_temperature(T20C)
cabin_air.volume = 200 cabin_air.set_volume(200)
cabin_air.gases[/datum/gas/oxygen] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) cabin_air.set_moles(/datum/gas/oxygen,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.gases[/datum/gas/nitrogen] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) cabin_air.set_moles(/datum/gas/nitrogen,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
return cabin_air return cabin_air
/obj/mecha/proc/add_radio() /obj/mecha/proc/add_radio()
@@ -302,9 +302,9 @@
if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH)) if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH))
setInternalDamage(MECHA_INT_TANK_BREACH) setInternalDamage(MECHA_INT_TANK_BREACH)
if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents
int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15)) int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15)))
if(cabin_air && cabin_air.return_volume()>0) if(cabin_air && cabin_air.return_volume()>0)
cabin_air.temperature = min(6000+T0C, cabin_air.return_temperature()+rand(10,15)) cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15)))
if(cabin_air.return_temperature() > max_temperature/2) if(cabin_air.return_temperature() > max_temperature/2)
take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0) take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0)
@@ -329,8 +329,8 @@
if(internal_temp_regulation) if(internal_temp_regulation)
if(cabin_air && cabin_air.return_volume() > 0) if(cabin_air && cabin_air.return_volume() > 0)
var/delta = cabin_air.temperature - T20C var/delta = cabin_air.return_temperature() - T20C
cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1))) cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1))))
if(internal_tank) if(internal_tank)
var/datum/gas_mixture/tank_air = internal_tank.return_air() var/datum/gas_mixture/tank_air = internal_tank.return_air()
+1 -1
View File
@@ -75,7 +75,7 @@
var/cell_charge = get_charge() var/cell_charge = get_charge()
var/datum/gas_mixture/int_tank_air = internal_tank.return_air() var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None" var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown" var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01) var/cabin_pressure = round(return_pressure(),0.01)
. = {"[report_internal_damage()] . = {"[report_internal_damage()]
[integrity<30?"<span class='userdanger'>DAMAGE LEVEL CRITICAL</span><br>":null] [integrity<30?"<span class='userdanger'>DAMAGE LEVEL CRITICAL</span><br>":null]
@@ -40,12 +40,11 @@
if(hotspot && istype(T) && T.air) if(hotspot && istype(T) && T.air)
qdel(hotspot) qdel(hotspot)
var/datum/gas_mixture/G = T.air var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma var/plas_amt = min(30,G.get_moles(/datum/gas/plasma)) //Absorb some plasma
G.gases[/datum/gas/plasma] -= plas_amt G.adjust_moles(/datum/gas/plasma,-plas_amt)
absorbed_plasma += plas_amt absorbed_plasma += plas_amt
if(G.temperature > T20C) if(G.return_temperature() > T20C)
G.temperature = max(G.temperature/2,T20C) G.set_temperature(max(G.return_temperature()/2,T20C))
GAS_GARBAGE_COLLECT(G.gases)
T.air_update_turf() T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam() /obj/effect/particle_effect/foam/firefighting/kill_foam()
@@ -317,15 +316,13 @@
O.ClearWet() O.ClearWet()
if(O.air) if(O.air)
var/datum/gas_mixture/G = O.air var/datum/gas_mixture/G = O.air
G.temperature = 293.15 G.set_temperature(293.15)
for(var/obj/effect/hotspot/H in O) for(var/obj/effect/hotspot/H in O)
qdel(H) qdel(H)
var/list/G_gases = G.gases for(var/I in G.get_gases())
for(var/I in G_gases)
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen) if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue continue
G_gases[I] = 0 G.set_moles(I, 0)
GAS_GARBAGE_COLLECT(G.gases)
O.air_update_turf() O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O) for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded) if(!U.welded)
@@ -166,15 +166,13 @@
if(T.air) if(T.air)
var/datum/gas_mixture/G = T.air var/datum/gas_mixture/G = T.air
if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air
G.temperature = temperature G.set_temperature(temperature)
T.air_update_turf() T.air_update_turf()
for(var/obj/effect/hotspot/H in T) for(var/obj/effect/hotspot/H in T)
qdel(H) qdel(H)
var/list/G_gases = G.gases if(G.get_moles(/datum/gas/plasma))
if(G_gases[/datum/gas/plasma]) G.adjust_moles(/datum/gas/nitrogen, G.get_moles(/datum/gas/plasma))
G_gases[/datum/gas/nitrogen] += (G_gases[/datum/gas/plasma]) G.set_moles(/datum/gas/plasma, 0)
G_gases[/datum/gas/plasma] = 0
GAS_GARBAGE_COLLECT(G.gases)
if (weldvents) if (weldvents)
for(var/obj/machinery/atmospherics/components/unary/U in T) 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. if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber.
@@ -19,11 +19,11 @@
var/obj/item/tank/internals/plasma/PT = new(V) var/obj/item/tank/internals/plasma/PT = new(V)
var/obj/item/tank/internals/oxygen/OT = new(V) var/obj/item/tank/internals/oxygen/OT = new(V)
PT.air_contents.gases[/datum/gas/plasma] = pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)) PT.air_contents.set_moles(/datum/gas/plasma, pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)))
PT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_p) PT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_p))
OT.air_contents.gases[/datum/gas/oxygen] = pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)) OT.air_contents.set_moles(/datum/gas/oxygen, pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)))
OT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_o) OT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_o))
V.tank_one = PT V.tank_one = PT
V.tank_two = OT V.tank_two = OT
@@ -487,3 +487,14 @@
/obj/effect/constructing_effect/proc/end() /obj/effect/constructing_effect/proc/end()
qdel(src) qdel(src)
/obj/effect/temp_visual/dir_setting/space_wind
icon = 'icons/effects/atmospherics.dmi'
icon_state = "space_wind"
layer = FLY_LAYER
duration = 20
mouse_opacity = 0
/obj/effect/temp_visual/dir_setting/space_wind/Initialize(mapload, set_dir, set_alpha = 255)
. = ..()
alpha = set_alpha
+3 -3
View File
@@ -246,9 +246,9 @@
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature /obj/effect/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new var/datum/gas_mixture/GM = new
GM.gases[/datum/gas/oxygen] = MOLES_O2STANDARD GM.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
GM.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD GM.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
GM.temperature = T20C GM.set_temperature(T20C)
return GM return GM
/obj/effect/chrono_field/Move() /obj/effect/chrono_field/Move()
+3 -4
View File
@@ -437,7 +437,6 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "Unable to obtain a reading.<br>" dat += "Unable to obtain a reading.<br>"
else else
var/datum/gas_mixture/environment = T.return_air() var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.gases
var/pressure = environment.return_pressure() var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles() var/total_moles = environment.total_moles()
@@ -445,12 +444,12 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>" dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles) if (total_moles)
for(var/id in env_gases) for(var/id in environment.get_gases())
var/gas_level = env_gases[id]/total_moles var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0) if(gas_level > 0)
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100, 0.01)]%<br>" dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100, 0.01)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>" dat += "Temperature: [round(environment.return_temperature()-T0C)]&deg;C<br>"
dat += "<br>" dat += "<br>"
else//Else it links to the cart menu proc. Although, it really uses menu hub 4--menu 4 doesn't really exist as it simply redirects to hub. else//Else it links to the cart menu proc. Although, it really uses menu hub 4--menu 4 doesn't really exist as it simply redirects to hub.
dat += cartridge.generate_menu() dat += cartridge.generate_menu()
+21 -25
View File
@@ -556,41 +556,38 @@ GENETICS SCANNER
else else
to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>") to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>")
if(total_moles) if(total_moles)
var/list/env_gases = environment.gases
var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles
if(abs(n2_concentration - N2STANDARD) < 20) if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)</span>") to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
else else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)</span>") to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
if(abs(o2_concentration - O2STANDARD) < 2) if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)</span>") to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
else else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)</span>") to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
if(co2_concentration > 0.01) if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/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(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
else else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/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(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
if(plasma_concentration > 0.005) if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)</span>") to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
else else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)</span>") to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
GAS_GARBAGE_COLLECT(environment.gases) for(var/id in environment.get_gases())
for(var/id in env_gases)
if(id in GLOB.hardcoded_gases) if(id in GLOB.hardcoded_gases)
continue continue
var/gas_concentration = env_gases[id]/total_moles 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(env_gases[id], 0.01)] mol)</span>") 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='info'>Temperature: [round(environment.temperature-T0C, 0.01)] &deg;C ([round(environment.temperature, 0.01)] K)</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>")
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens /obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
. = ..() . = ..()
@@ -669,8 +666,8 @@ GENETICS SCANNER
var/total_moles = air_contents.total_moles() var/total_moles = air_contents.total_moles()
var/pressure = air_contents.return_pressure() var/pressure = air_contents.return_pressure()
var/volume = air_contents.return_volume() //could just do mixture.volume... but safety, I guess? var/volume = air_contents.return_volume()
var/temperature = air_contents.temperature var/temperature = air_contents.return_temperature()
var/cached_scan_results = air_contents.analyzer_results var/cached_scan_results = air_contents.analyzer_results
if(total_moles > 0) if(total_moles > 0)
@@ -678,10 +675,9 @@ GENETICS SCANNER
to_chat(user, "<span class='notice'>Volume: [volume] L</span>") to_chat(user, "<span class='notice'>Volume: [volume] L</span>")
to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.01)] kPa</span>") to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.01)] kPa</span>")
var/list/cached_gases = air_contents.gases for(var/id in air_contents.get_gases())
for(var/id in cached_gases) var/gas_concentration = air_contents.get_moles(id)/total_moles
var/gas_concentration = cached_gases[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.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[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>") to_chat(user, "<span class='notice'>Temperature: [round(temperature - T0C,0.01)] &deg;C ([round(temperature, 0.01)] K)</span>")
else else
@@ -168,8 +168,8 @@
target_self = TRUE target_self = TRUE
if(change_volume) if(change_volume)
if(!target_self) if(!target_self)
target.volume += tank_two.volume target.set_volume(target.return_volume() + tank_two.volume)
target.volume += tank_one.air_contents.volume target.set_volume(target.return_volume() + tank_one.air_contents.return_volume())
var/datum/gas_mixture/temp var/datum/gas_mixture/temp
temp = tank_one.air_contents.remove_ratio(1) temp = tank_one.air_contents.remove_ratio(1)
target.merge(temp) target.merge(temp)
@@ -180,11 +180,11 @@
/obj/item/transfer_valve/proc/split_gases() /obj/item/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two) if (!valve_open || !tank_one || !tank_two)
return return
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume var/ratio1 = tank_one.air_contents.return_volume()/tank_two.air_contents.return_volume()
var/datum/gas_mixture/temp var/datum/gas_mixture/temp
temp = tank_two.air_contents.remove_ratio(ratio1) temp = tank_two.air_contents.remove_ratio(ratio1)
tank_one.air_contents.merge(temp) tank_one.air_contents.merge(temp)
tank_two.air_contents.volume -= tank_one.air_contents.volume tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume())
/* /*
Exadv1: I know this isn't how it's going to work, but this was just to check Exadv1: I know this isn't how it's going to work, but this was just to check
+2 -3
View File
@@ -204,11 +204,10 @@
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf //Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
if(air_transfer.gases[/datum/gas/plasma]) air_transfer.set_moles(/datum/gas/plasma, air_transfer.get_moles(/datum/gas/plasma) * 5)
air_transfer.gases[/datum/gas/plasma] *= 5
target.assume_air(air_transfer) target.assume_air(air_transfer)
//Burn it based on transfered gas //Burn it based on transfered gas
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) target.hotspot_expose((ptank.air_contents.return_temperature()*2) + 380,500)
//location.hotspot_expose(1000,500,1) //location.hotspot_expose(1000,500,1)
SSair.add_to_active(target, 0) SSair.add_to_active(target, 0)
+1 -1
View File
@@ -253,7 +253,7 @@
occupant_gas_supply = new occupant_gas_supply = new
if(isanimal(occupant)) if(isanimal(occupant))
var/mob/living/simple_animal/animal = occupant var/mob/living/simple_animal/animal = occupant
occupant_gas_supply.temperature = animal.minbodytemp //simple animals only care about temperature when their turf isnt a location occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature when their turf isnt a location
else else
if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside
ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist") ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
+1 -1
View File
@@ -21,7 +21,7 @@
/obj/item/tank/jetpack/populate_gas() /obj/item/tank/jetpack/populate_gas()
if(gas_type) if(gas_type)
air_contents.gases[gas_type] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) air_contents.set_moles(gas_type, ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)))
/obj/item/tank/jetpack/ui_action_click(mob/user, action) /obj/item/tank/jetpack/ui_action_click(mob/user, action)
+20 -11
View File
@@ -18,8 +18,9 @@
force = 10 force = 10
dog_fashion = /datum/dog_fashion/back dog_fashion = /datum/dog_fashion/back
/obj/item/tank/internals/oxygen/populate_gas() /obj/item/tank/internals/oxygen/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return return
@@ -47,8 +48,9 @@
force = 10 force = 10
/obj/item/tank/internals/anesthetic/populate_gas() /obj/item/tank/internals/anesthetic/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.gases[/datum/gas/nitrous_oxide] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD air_contents.set_moles(/datum/gas/nitrous_oxide, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
return
/* /*
* Air * Air
@@ -62,8 +64,9 @@
dog_fashion = /datum/dog_fashion/back dog_fashion = /datum/dog_fashion/back
/obj/item/tank/internals/air/populate_gas() /obj/item/tank/internals/air/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.gases[/datum/gas/nitrogen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD air_contents.set_moles(/datum/gas/nitrogen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
return
/* /*
@@ -79,7 +82,8 @@
/obj/item/tank/internals/plasma/populate_gas() /obj/item/tank/internals/plasma/populate_gas()
air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params) /obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/flamethrower)) if(istype(W, /obj/item/flamethrower))
@@ -93,12 +97,16 @@
F.update_icon() F.update_icon()
else else
return ..() 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))
//Makes empty oxygen tanks spawn without gas //Makes empty oxygen tanks spawn without gas
/obj/item/tank/internals/plasma/empty/populate_gas() /obj/item/tank/internals/plasma/empty/populate_gas()
return return
/obj/item/tank/internals/plasma/full/populate_gas() /obj/item/tank/internals/plasma/full/populate_gas()
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/* /*
* Plasmaman Plasma Tank * Plasmaman Plasma Tank
@@ -113,10 +121,11 @@
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
/obj/item/tank/internals/plasmaman/populate_gas() /obj/item/tank/internals/plasmaman/populate_gas()
air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/plasmaman/full/populate_gas() /obj/item/tank/internals/plasmaman/full/populate_gas()
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return return
@@ -129,7 +138,7 @@
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/tank/internals/plasmaman/belt/full/populate_gas() /obj/item/tank/internals/plasmaman/belt/full/populate_gas()
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return return
//makes empty plasma tanks spawn without gas. //makes empty plasma tanks spawn without gas.
@@ -152,7 +161,7 @@
/obj/item/tank/internals/emergency_oxygen/populate_gas() /obj/item/tank/internals/emergency_oxygen/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return return
/obj/item/tank/internals/emergency_oxygen/empty/populate_gas() /obj/item/tank/internals/emergency_oxygen/empty/populate_gas()
+3 -3
View File
@@ -64,7 +64,7 @@
. = ..() . = ..()
air_contents = new(volume) //liters air_contents = new(volume) //liters
air_contents.temperature = T20C air_contents.set_temperature(T20C)
populate_gas() populate_gas()
@@ -92,7 +92,7 @@
. += "<span class='notice'>The pressure gauge reads [round(src.air_contents.return_pressure(),0.01)] kPa.</span>" . += "<span class='notice'>The pressure gauge reads [round(src.air_contents.return_pressure(),0.01)] kPa.</span>"
var/celsius_temperature = src.air_contents.temperature-T0C var/celsius_temperature = src.air_contents.return_temperature()-T0C
var/descriptive var/descriptive
if (celsius_temperature < 20) if (celsius_temperature < 20)
@@ -235,7 +235,7 @@
if(tank_pressure < distribute_pressure) if(tank_pressure < distribute_pressure)
distribute_pressure = tank_pressure distribute_pressure = tank_pressure
var/moles_needed = distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.temperature) var/moles_needed = distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.return_temperature())
return remove_air(moles_needed) return remove_air(moles_needed)
+2 -2
View File
@@ -94,7 +94,7 @@
alpha = 150 alpha = 150
resistance_flags = FIRE_PROOF resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/firelock/blocksTemperature() /obj/structure/holosign/barrier/firelock/BlockSuperconductivity()
return TRUE return TRUE
/obj/structure/holosign/barrier/combifan /obj/structure/holosign/barrier/combifan
@@ -110,7 +110,7 @@
CanAtmosPass = ATMOS_PASS_NO CanAtmosPass = ATMOS_PASS_NO
resistance_flags = FIRE_PROOF resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/combifan/blocksTemperature() /obj/structure/holosign/barrier/combifan/BlockSuperconductivity()
return TRUE return TRUE
/obj/structure/holosign/barrier/combifan/Initialize() /obj/structure/holosign/barrier/combifan/Initialize()
@@ -152,8 +152,8 @@
pod_moving = 0 pod_moving = 0
if(!QDELETED(pod)) if(!QDELETED(pod))
var/datum/gas_mixture/floor_mixture = loc.return_air() var/datum/gas_mixture/floor_mixture = loc.return_air()
ARCHIVE(floor_mixture) floor_mixture.archive()
ARCHIVE(pod.air_contents) pod.air_contents.archive()
pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
air_update_turf() air_update_turf()
@@ -10,9 +10,9 @@
/obj/structure/transit_tube_pod/Initialize() /obj/structure/transit_tube_pod/Initialize()
. = ..() . = ..()
air_contents.gases[/datum/gas/oxygen] = MOLES_O2STANDARD air_contents.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
air_contents.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD air_contents.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
air_contents.temperature = T20C air_contents.set_temperature(T20C)
/obj/structure/transit_tube_pod/Destroy() /obj/structure/transit_tube_pod/Destroy()
@@ -181,4 +181,4 @@
return return
/obj/structure/transit_tube_pod/return_temperature() /obj/structure/transit_tube_pod/return_temperature()
return air_contents.temperature return air_contents.return_temperature()
+3 -12
View File
@@ -148,6 +148,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
. = ..() . = ..()
if (!.) // changeturf failed or didn't do anything if (!.) // changeturf failed or didn't do anything
QDEL_NULL(stashed_air) QDEL_NULL(stashed_air)
update_air_ref()
return return
var/turf/open/newTurf = . var/turf/open/newTurf = .
newTurf.air.copy_from(stashed_air) newTurf.air.copy_from(stashed_air)
@@ -308,24 +309,14 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
return return
var/datum/gas_mixture/total = new//Holders to assimilate air from nearby turfs var/datum/gas_mixture/total = new//Holders to assimilate air from nearby turfs
var/list/total_gases = total.gases
for(var/T in atmos_adjacent_turfs) for(var/T in atmos_adjacent_turfs)
var/turf/open/S = T var/turf/open/S = T
if(!S.air) if(!S.air)
continue continue
var/list/S_gases = S.air.gases total.merge(S.air)
for(var/id in S_gases)
total_gases[id] += S_gases[id]
total.temperature += S.air.temperature
air.copy_from(total) air.copy_from(total.remove_ratio(1/turf_count))
var/list/air_gases = air.gases
for(var/id in air_gases)
air_gases[id] /= turf_count //Averages contents of the turfs, ignoring walls and the like
air.temperature /= turf_count
SSair.add_to_active(src) SSair.add_to_active(src)
/turf/proc/ReplaceWithLattice() /turf/proc/ReplaceWithLattice()
+5
View File
@@ -7,9 +7,14 @@
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_MEDIUM_INSULATION rad_insulation = RAD_MEDIUM_INSULATION
/turf/closed/Initialize()
. = ..()
update_air_ref()
/turf/closed/AfterChange() /turf/closed/AfterChange()
. = ..() . = ..()
SSair.high_pressure_delta -= src SSair.high_pressure_delta -= src
update_air_ref()
/turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) /turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE return FALSE
+10 -11
View File
@@ -199,7 +199,7 @@
flash_color(L, flash_color = "#C80000", flash_time = 10) flash_color(L, flash_color = "#C80000", flash_time = 10)
/turf/open/Initalize_Atmos(times_fired) /turf/open/Initalize_Atmos(times_fired)
excited = 0 set_excited(FALSE)
update_visuals() update_visuals()
current_cycle = times_fired current_cycle = times_fired
@@ -207,19 +207,19 @@
for(var/i in atmos_adjacent_turfs) for(var/i in atmos_adjacent_turfs)
var/turf/open/enemy_tile = i var/turf/open/enemy_tile = i
var/datum/gas_mixture/enemy_air = enemy_tile.return_air() var/datum/gas_mixture/enemy_air = enemy_tile.return_air()
if(!excited && air.compare(enemy_air)) if(!get_excited() && air.compare(enemy_air))
//testing("Active turf found. Return value of compare(): [is_active]") //testing("Active turf found. Return value of compare(): [is_active]")
excited = TRUE set_excited(TRUE)
SSair.active_turfs |= src SSair.active_turfs |= src
/turf/open/proc/GetHeatCapacity() /turf/open/proc/GetHeatCapacity()
. = air.heat_capacity() . = air.heat_capacity()
/turf/open/proc/GetTemperature() /turf/open/proc/GetTemperature()
. = air.temperature . = air.return_temperature()
/turf/open/proc/TakeTemperature(temp) /turf/open/proc/TakeTemperature(temp)
air.temperature += temp air.set_temperature(air.return_temperature() + temp)
air_update_turf() air_update_turf()
/turf/open/proc/freon_gas_act() /turf/open/proc/freon_gas_act()
@@ -304,9 +304,8 @@
/turf/open/rad_act(pulse_strength) /turf/open/rad_act(pulse_strength)
. = ..() . = ..()
if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen]) if (air.get_moles(/datum/gas/carbon_dioxide) && air.get_moles(/datum/gas/oxygen))
pulse_strength = min(pulse_strength,air.gases[/datum/gas/carbon_dioxide]*1000,air.gases[/datum/gas/oxygen]*2000) //Ensures matter is conserved properly 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.gases[/datum/gas/carbon_dioxide]=max(air.gases[/datum/gas/carbon_dioxide]-(pulse_strength/1000),0) air.set_moles(/datum/gas/carbon_dioxide, max(air.get_moles(/datum/gas/carbon_dioxide)-(pulse_strength/1000),0))
air.gases[/datum/gas/oxygen]=max(air.gases[/datum/gas/oxygen]-(pulse_strength/2000),0) air.set_moles(/datum/gas/oxygen, max(air.get_moles(/datum/gas/oxygen)-(pulse_strength/2000),0))
air.gases[/datum/gas/pluoxium]+=(pulse_strength/4000) air.adjust_moles(/datum/gas/pluoxium, pulse_strength/4000)
GAS_GARBAGE_COLLECT(air.gases)
+1
View File
@@ -27,6 +27,7 @@
/turf/open/space/Initialize() /turf/open/space/Initialize()
icon_state = SPACE_ICON_STATE icon_state = SPACE_ICON_STATE
air = space_gas air = space_gas
update_air_ref()
vis_contents.Cut() //removes inherited overlays vis_contents.Cut() //removes inherited overlays
visibilityChanged() visibilityChanged()
+1 -1
View File
@@ -277,7 +277,7 @@
/turf/open/Entered(atom/movable/AM) /turf/open/Entered(atom/movable/AM)
..() ..()
//melting //melting
if(isobj(AM) && air && air.temperature > T0C) if(isobj(AM) && air && air.return_temperature() > T0C)
var/obj/O = AM var/obj/O = AM
if(O.obj_flags & FROZEN) if(O.obj_flags & FROZEN)
O.make_unfrozen() O.make_unfrozen()
+14 -3
View File
@@ -9,9 +9,8 @@ GLOBAL_LIST(topic_status_cache)
//This happens after the Master subsystem new(s) (it's a global datum) //This happens after the Master subsystem new(s) (it's a global datum)
//So subsystems globals exist, but are not initialised //So subsystems globals exist, but are not initialised
/world/New() /world/New()
var/extools = world.GetConfig("env", "EXTOOLS_DLL") || "./byond-extools.dll" if (fexists(EXTOOLS))
if (fexists(extools)) call(EXTOOLS, "maptick_initialize")()
call(extools, "maptick_initialize")()
enable_debugger() enable_debugger()
world.Profile(PROFILE_START) world.Profile(PROFILE_START)
@@ -276,6 +275,15 @@ GLOBAL_LIST(topic_status_cache)
shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss.
..() ..()
/world/Del()
// memory leaks bad
var/num_deleted = 0
for(var/datum/gas_mixture/GM)
GM.__gasmixture_unregister()
num_deleted++
log_world("Deallocated [num_deleted] gas mixtures")
..()
/world/proc/update_status() /world/proc/update_status()
var/list/features = list() var/list/features = list()
@@ -344,3 +352,6 @@ GLOBAL_LIST(topic_status_cache)
maxz++ maxz++
SSmobs.MaxZChanged() SSmobs.MaxZChanged()
SSidlenpcpool.MaxZChanged() SSidlenpcpool.MaxZChanged()
world.refresh_atmos_grid()
/world/proc/refresh_atmos_grid()
+1 -1
View File
@@ -573,7 +573,7 @@
if(Rad.anchored) if(Rad.anchored)
if(!Rad.loaded_tank) if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad) var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
Plasma.air_contents.gases[/datum/gas/plasma] = 70 Plasma.air_contents.set_moles(/datum/gas/plasma,70)
Rad.drainratio = 0 Rad.drainratio = 0
Rad.loaded_tank = Plasma Rad.loaded_tank = Plasma
Plasma.forceMove(Rad) Plasma.forceMove(Rad)
+3 -4
View File
@@ -1,15 +1,14 @@
/proc/show_air_status_to(turf/target, mob/user) /proc/show_air_status_to(turf/target, mob/user)
var/datum/gas_mixture/env = target.return_air() var/datum/gas_mixture/env = target.return_air()
var/list/env_gases = env.gases
var/burning = FALSE var/burning = FALSE
if(isopenturf(target)) if(isopenturf(target))
var/turf/open/T = target var/turf/open/T = target
if(T.active_hotspot) if(T.active_hotspot)
burning = TRUE burning = TRUE
var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.temperature] K ([env.temperature - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>") var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.return_temperature()] K ([env.return_temperature() - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>")
for(var/id in env_gases) for(var/id in env.get_gases())
var/moles = env_gases[id] var/moles = env.get_moles(id)
if (moles >= 0.00001) if (moles >= 0.00001)
lines += "[GLOB.meta_gas_names[id]]: [moles] mol" lines += "[GLOB.meta_gas_names[id]]: [moles] mol"
to_chat(usr, lines.Join("\n")) to_chat(usr, lines.Join("\n"))
+6 -7
View File
@@ -53,8 +53,8 @@
return return
if(I.use_tool(src, user, 0, volume=40)) if(I.use_tool(src, user, 0, volume=40))
status = TRUE status = TRUE
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.return_temperature()-T0C]"
message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]") message_admins("[ADMIN_LOOKUPFLW(user)] welded a single tank bomb. Temp: [bombtank.air_contents.return_temperature()-T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>") to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
add_fingerprint(user) add_fingerprint(user)
return TRUE return TRUE
@@ -145,8 +145,7 @@
return return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode /obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.gases[/datum/gas/plasma] + air_contents.gases[/datum/gas/oxygen]/6 var/fuel_moles = air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
GAS_GARBAGE_COLLECT(air_contents.gases)
var/datum/gas_mixture/bomb_mixture = air_contents.copy() var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1 var/strength = 1
@@ -156,7 +155,7 @@
qdel(master) qdel(master)
qdel(src) qdel(src)
if(bomb_mixture.temperature > (T0C + 400)) if(bomb_mixture.return_temperature() > (T0C + 400))
strength = (fuel_moles/15) strength = (fuel_moles/15)
if(strength >=1) if(strength >=1)
@@ -169,7 +168,7 @@
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 250)) else if(bomb_mixture.return_temperature() > (T0C + 250))
strength = (fuel_moles/20) strength = (fuel_moles/20)
if(strength >=1) if(strength >=1)
@@ -180,7 +179,7 @@
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 100)) else if(bomb_mixture.return_temperature() > (T0C + 100))
strength = (fuel_moles/25) strength = (fuel_moles/25)
if (strength >=1) if (strength >=1)
@@ -9,46 +9,31 @@
return return
/turf/open/hotspot_expose(exposed_temperature, exposed_volume, soh = FALSE, holo = FALSE) /turf/open/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/datum/gas_mixture/air_contents = return_air() if(!air)
if(!air_contents) return
return 0
var/oxy = air_contents.gases[/datum/gas/oxygen] var/oxy = air.get_moles(/datum/gas/oxygen)
var/tox = air_contents.gases[/datum/gas/plasma] if (oxy < 0.5)
var/trit = air_contents.gases[/datum/gas/tritium] return
var/tox = air.get_moles(/datum/gas/plasma)
var/trit = air.get_moles(/datum/gas/tritium)
if(active_hotspot) if(active_hotspot)
if(soh) if(soh)
if((tox > 0.5 || trit > 0.5) && oxy > 0.5) if(tox > 0.5 || trit > 0.5)
if(active_hotspot.temperature < exposed_temperature*50) if(active_hotspot.temperature < exposed_temperature)
active_hotspot.temperature = exposed_temperature*50 active_hotspot.temperature = exposed_temperature
if(active_hotspot.volume < exposed_volume) if(active_hotspot.volume < exposed_volume)
active_hotspot.volume = exposed_volume active_hotspot.volume = exposed_volume
return 1 return
var/igniting = 0
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (tox > 0.5 || trit > 0.5)) if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (tox > 0.5 || trit > 0.5))
igniting = 1
if(igniting) active_hotspot = new /obj/effect/hotspot(src, exposed_volume*25, exposed_temperature)
if(oxy < 0.5)
return 0
active_hotspot = new /obj/effect/hotspot(src, holo)
active_hotspot.temperature = exposed_temperature*50
active_hotspot.volume = exposed_volume*25
active_hotspot.just_spawned = (current_cycle < SSair.times_fired) active_hotspot.just_spawned = (current_cycle < SSair.times_fired)
//remove just_spawned protection if no longer processing this cell //remove just_spawned protection if no longer processing this cell
SSair.add_to_active(src, 0) SSair.add_to_active(src, 0)
else
var/datum/gas_mixture/heating = air_contents.remove_ratio(exposed_volume/air_contents.volume)
heating.temperature = exposed_temperature
heating.react()
assume_air(heating)
air_update_turf()
return igniting
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile //This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
/obj/effect/hotspot /obj/effect/hotspot
@@ -67,11 +52,13 @@
var/bypassing = FALSE var/bypassing = FALSE
var/visual_update_tick = 0 var/visual_update_tick = 0
/obj/effect/hotspot/Initialize(mapload, holo = FALSE) /obj/effect/hotspot/Initialize(mapload, starting_volume, starting_temperature)
. = ..() . = ..()
if(holo)
flags_1 |= HOLOGRAM_1
SSair.hotspots += src SSair.hotspots += src
if(!isnull(starting_volume))
volume = starting_volume
if(!isnull(starting_temperature))
temperature = starting_temperature
perform_exposure() perform_exposure()
setDir(pick(GLOB.cardinals)) setDir(pick(GLOB.cardinals))
air_update_turf() air_update_turf()
@@ -83,22 +70,19 @@
location.active_hotspot = src location.active_hotspot = src
if(volume > CELL_VOLUME*0.95) bypassing = !just_spawned && (volume > CELL_VOLUME*0.95)
bypassing = TRUE
else
bypassing = FALSE
if(bypassing) if(bypassing)
if(!just_spawned) volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE temperature = location.air.return_temperature()
temperature = location.air.temperature
else else
var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.volume) var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.return_volume())
affected.temperature = temperature if(affected) //in case volume is 0
affected.react(src) affected.set_temperature(temperature)
temperature = affected.temperature affected.react(src)
volume = affected.reaction_results["fire"]*FIRE_GROWTH_RATE temperature = affected.return_temperature()
location.assume_air(affected) volume = affected.reaction_results["fire"]*FIRE_GROWTH_RATE
location.assume_air(affected)
for(var/A in location) for(var/A in location)
var/atom/AT = A var/atom/AT = A
@@ -164,7 +148,7 @@
color = list(LERP(0.3, 1, 1-greyscale_fire) * heat_r,0.3 * heat_g * greyscale_fire,0.3 * heat_b * greyscale_fire, 0.59 * heat_r * greyscale_fire,LERP(0.59, 1, 1-greyscale_fire) * heat_g,0.59 * heat_b * greyscale_fire, 0.11 * heat_r * greyscale_fire,0.11 * heat_g * greyscale_fire,LERP(0.11, 1, 1-greyscale_fire) * heat_b, 0,0,0) color = list(LERP(0.3, 1, 1-greyscale_fire) * heat_r,0.3 * heat_g * greyscale_fire,0.3 * heat_b * greyscale_fire, 0.59 * heat_r * greyscale_fire,LERP(0.59, 1, 1-greyscale_fire) * heat_g,0.59 * heat_b * greyscale_fire, 0.11 * heat_r * greyscale_fire,0.11 * heat_g * greyscale_fire,LERP(0.11, 1, 1-greyscale_fire) * heat_b, 0,0,0)
alpha = heat_a alpha = heat_a
#define INSUFFICIENT(path) (location.air.gases[path] < 0.5) #define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)
/obj/effect/hotspot/process() /obj/effect/hotspot/process()
if(just_spawned) if(just_spawned)
just_spawned = FALSE just_spawned = FALSE
@@ -175,8 +159,7 @@
qdel(src) qdel(src)
return return
if(location.excited_group) location.eg_reset_cooldowns()
location.excited_group.reset_cooldowns()
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1)) if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
qdel(src) qdel(src)
@@ -186,7 +169,8 @@
return return
//Not enough to burn //Not enough to burn
if((location.air.gases[/datum/gas/plasma] < 0.5 && location.air.gases[/datum/gas/tritium] < 0.5) || location.air.gases[/datum/gas/oxygen] < 0.5) // 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))
qdel(src) qdel(src)
return return
@@ -194,16 +178,15 @@
if(bypassing) if(bypassing)
icon_state = "3" icon_state = "3"
if(!(flags_1 & HOLOGRAM_1)) location.burn_tile()
location.burn_tile()
//Possible spread due to radiated heat //Possible spread due to radiated heat
if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD) if(location.air.return_temperature() > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE var/radiated_temperature = location.air.return_temperature()*FIRE_SPREAD_RADIOSITY_SCALE
for(var/t in location.atmos_adjacent_turfs) for(var/t in location.atmos_adjacent_turfs)
var/turf/open/T = t var/turf/open/T = t
if(!T.active_hotspot) if(!T.active_hotspot)
T.hotspot_expose(radiated_temperature, CELL_VOLUME/4, flags_1 & HOLOGRAM_1) T.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
else else
if(volume > CELL_VOLUME*0.4) if(volume > CELL_VOLUME*0.4)
@@ -227,14 +210,13 @@
var/turf/open/T = loc var/turf/open/T = loc
if(istype(T) && T.active_hotspot == src) if(istype(T) && T.active_hotspot == src)
T.active_hotspot = null T.active_hotspot = null
if(!(flags_1 & HOLOGRAM_1)) DestroyTurf()
DestroyTurf()
return ..() return ..()
/obj/effect/hotspot/proc/DestroyTurf() /obj/effect/hotspot/proc/DestroyTurf()
if(isturf(loc)) if(isturf(loc))
var/turf/T = loc var/turf/T = loc
if(T.to_be_destroyed) if(T.to_be_destroyed && !T.changing_turf)
var/chance_of_deletion var/chance_of_deletion
if (T.heat_capacity) //beware of division by zero if (T.heat_capacity) //beware of division by zero
chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0 chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
@@ -18,7 +18,7 @@
/turf/open/CanAtmosPass(turf/T, vertical = FALSE) /turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T) var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
var/opp = dir_inverse_multiz(dir) var/opp = REVERSE_DIR(dir)
var/R = FALSE var/R = FALSE
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src))) if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
R = TRUE R = TRUE
@@ -48,21 +48,28 @@
var/canvpass = CANVERTICALATMOSPASS(src, src) var/canvpass = CANVERTICALATMOSPASS(src, src)
for(var/direction in GLOB.cardinals_multiz) for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction) var/turf/T = get_step_multiz(src, direction)
var/opp_dir = REVERSE_DIR(direction)
if(!isopenturf(T)) if(!isopenturf(T))
continue continue
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) ) if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs) LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = TRUE atmos_adjacent_turfs[T] = direction
T.atmos_adjacent_turfs[src] = TRUE T.atmos_adjacent_turfs[src] = opp_dir
T.__update_extools_adjacent_turfs()
else else
if (atmos_adjacent_turfs) if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= T atmos_adjacent_turfs -= T
if (T.atmos_adjacent_turfs) if (T.atmos_adjacent_turfs)
T.atmos_adjacent_turfs -= src T.atmos_adjacent_turfs -= src
T.__update_extools_adjacent_turfs()
UNSETEMPTY(T.atmos_adjacent_turfs) UNSETEMPTY(T.atmos_adjacent_turfs)
UNSETEMPTY(atmos_adjacent_turfs) UNSETEMPTY(atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs src.atmos_adjacent_turfs = atmos_adjacent_turfs
__update_extools_adjacent_turfs()
/turf/proc/__update_extools_adjacent_turfs()
//returns a list of adjacent turfs that can share air with this one. //returns a list of adjacent turfs that can share air with this one.
//alldir includes adjacent diagonal tiles that can share //alldir includes adjacent diagonal tiles that can share
@@ -111,9 +118,9 @@
SSair.add_to_active(src,command) SSair.add_to_active(src,command)
/atom/movable/proc/move_update_air(turf/T) /atom/movable/proc/move_update_air(turf/T)
if(isturf(T)) if(isturf(T))
T.air_update_turf(1) T.air_update_turf(1)
air_update_turf(1) air_update_turf(1)
/atom/proc/atmos_spawn_air(text) //because a lot of people loves to copy paste awful code lets just make an easy proc to spawn your plasma fires /atom/proc/atmos_spawn_air(text) //because a lot of people loves to copy paste awful code lets just make an easy proc to spawn your plasma fires
var/turf/open/T = get_turf(src) var/turf/open/T = get_turf(src)
@@ -8,6 +8,7 @@
var/list/atmos_adjacent_turfs var/list/atmos_adjacent_turfs
//bitfield of dirs in which we are superconducitng //bitfield of dirs in which we are superconducitng
var/atmos_supeconductivity = NONE var/atmos_supeconductivity = NONE
var/is_openturf = FALSE // used by extools shizz.
//used to determine whether we should archive //used to determine whether we should archive
var/archived_cycle = 0 var/archived_cycle = 0
@@ -23,21 +24,21 @@
//used for spacewind //used for spacewind
var/pressure_difference = 0 var/pressure_difference = 0
var/pressure_direction = 0 var/pressure_direction = 0
var/turf/pressure_specific_target
var/datum/excited_group/excited_group
var/excited = FALSE
var/datum/gas_mixture/turf/air var/datum/gas_mixture/turf/air
var/obj/effect/hotspot/active_hotspot var/obj/effect/hotspot/active_hotspot
var/atmos_cooldown = 0
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time 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 var/list/atmos_overlay_types //gas IDs of current active gas overlays
is_openturf = TRUE
/turf/open/Initialize() /turf/open/Initialize()
if(!blocks_air) if(!blocks_air)
air = new air = new
air.copy_from_turf(src) air.copy_from_turf(src)
update_air_ref()
. = ..() . = ..()
/turf/open/Destroy() /turf/open/Destroy()
@@ -48,6 +49,8 @@
SSair.add_to_active(T) SSair.add_to_active(T)
return ..() return ..()
/turf/proc/update_air_ref()
/////////////////GAS MIXTURE PROCS/////////////////// /////////////////GAS MIXTURE PROCS///////////////////
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air /turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
@@ -89,15 +92,37 @@
temperature_archived = temperature temperature_archived = temperature
/turf/open/archive() /turf/open/archive()
ARCHIVE(air) air.archive()
archived_cycle = SSair.times_fired archived_cycle = SSair.times_fired
temperature_archived = temperature temperature_archived = temperature
/turf/open/proc/eg_reset_cooldowns()
/turf/open/proc/eg_garbage_collect()
/turf/open/proc/get_excited()
/turf/open/proc/set_excited()
/////////////////////////GAS OVERLAYS////////////////////////////// /////////////////////////GAS OVERLAYS//////////////////////////////
/turf/open/proc/update_visuals() /turf/open/proc/update_visuals()
var/list/new_overlay_types = tile_graphic()
var/list/atmos_overlay_types = src.atmos_overlay_types // Cache for free performance var/list/atmos_overlay_types = src.atmos_overlay_types // Cache for free performance
var/list/new_overlay_types = list()
var/static/list/nonoverlaying_gases = typecache_of_gases_with_no_overlays()
if(!air) // 2019-05-14: was not able to get this path to fire in testing. Consider removing/looking at callers -Naksu
if (atmos_overlay_types)
for(var/overlay in atmos_overlay_types)
vis_contents -= overlay
src.atmos_overlay_types = null
return
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])
new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(air.get_moles(id) / MOLES_GAS_VISIBLE_STEP, 1))]
if (atmos_overlay_types) if (atmos_overlay_types)
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
@@ -112,19 +137,18 @@
UNSETEMPTY(new_overlay_types) UNSETEMPTY(new_overlay_types)
src.atmos_overlay_types = new_overlay_types src.atmos_overlay_types = new_overlay_types
/turf/open/proc/tile_graphic() /turf/open/proc/set_visuals(list/new_overlay_types)
var/static/list/nonoverlaying_gases = typecache_of_gases_with_no_overlays() if (atmos_overlay_types)
if(!air) for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
return vis_contents -= overlay
. = new /list
var/list/gases = air.gases if (length(new_overlay_types))
for(var/id in gases) if (atmos_overlay_types)
if (nonoverlaying_gases[id]) vis_contents += new_overlay_types - atmos_overlay_types //don't add overlays that already exist
continue else
var/gas = gases[id] vis_contents += new_overlay_types
var/gas_overlay = GLOB.meta_gas_overlays[id] UNSETEMPTY(new_overlay_types)
if(gas_overlay && gas > GLOB.meta_gas_visibility[id]) src.atmos_overlay_types = new_overlay_types
. += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas / MOLES_GAS_VISIBLE_STEP, 1))]
/proc/typecache_of_gases_with_no_overlays() /proc/typecache_of_gases_with_no_overlays()
. = list() . = list()
@@ -135,8 +159,8 @@
/////////////////////////////SIMULATION/////////////////////////////////// /////////////////////////////SIMULATION///////////////////////////////////
#define LAST_SHARE_CHECK \ /*#define LAST_SHARE_CHECK \
var/last_share = our_air.last_share;\ var/last_share = our_air.get_last_share();\
if(last_share > MINIMUM_AIR_TO_SUSPEND){\ if(last_share > MINIMUM_AIR_TO_SUSPEND){\
our_excited_group.reset_cooldowns();\ our_excited_group.reset_cooldowns();\
cached_atmos_cooldown = 0;\ cached_atmos_cooldown = 0;\
@@ -144,107 +168,32 @@
our_excited_group.dismantle_cooldown = 0;\ our_excited_group.dismantle_cooldown = 0;\
cached_atmos_cooldown = 0;\ cached_atmos_cooldown = 0;\
} }
*/
/turf/proc/process_cell(fire_count) /turf/proc/process_cell(fire_count)
SSair.remove_from_active(src) SSair.remove_from_active(src)
/turf/open/process_cell(fire_count) /turf/open/proc/equalize_pressure_in_zone(cyclenum)
if(archived_cycle < fire_count) //archive self if not already done /turf/open/proc/consider_firelocks(turf/T2)
archive() var/reconsider_adj = FALSE
for(var/obj/machinery/door/firedoor/FD in T2)
current_cycle = fire_count if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, src) != FD.dir)
//cache for sanic speed
var/list/adjacent_turfs = atmos_adjacent_turfs
var/datum/excited_group/our_excited_group = excited_group
var/adjacent_turfs_length = LAZYLEN(adjacent_turfs)
var/cached_atmos_cooldown = atmos_cooldown + 1
var/planet_atmos = planetary_atmos
if (planet_atmos)
adjacent_turfs_length++
var/datum/gas_mixture/our_air = air
for(var/t in adjacent_turfs)
var/turf/open/enemy_tile = t
if(fire_count <= enemy_tile.current_cycle)
continue continue
enemy_tile.archive() FD.emergency_pressure_stop()
reconsider_adj = TRUE
for(var/obj/machinery/door/firedoor/FD in src)
if((FD.flags_1 & ON_BORDER_1) && get_dir(src, T2) != FD.dir)
continue
FD.emergency_pressure_stop()
reconsider_adj = TRUE
if(reconsider_adj)
T2.ImmediateCalculateAdjacentTurfs() // We want those firelocks closed yesterday.
/******************* GROUP HANDLING START *****************************************************************/ /turf/proc/handle_decompression_floor_rip()
/turf/open/floor/handle_decompression_floor_rip(sum)
if(sum > 20 && prob(clamp(sum / 10, 0, 30)))
remove_tile()
var/should_share_air = FALSE /turf/open/process_cell(fire_count)
var/datum/gas_mixture/enemy_air = enemy_tile.air
//cache for sanic speed
var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group
if(our_excited_group && enemy_excited_group)
if(our_excited_group != enemy_excited_group)
//combine groups (this also handles updating the excited_group var of all involved turfs)
our_excited_group.merge_groups(enemy_excited_group)
our_excited_group = excited_group //update our cache
should_share_air = TRUE
else if(our_air.compare(enemy_air))
if(!enemy_tile.excited)
SSair.add_to_active(enemy_tile)
var/datum/excited_group/EG = our_excited_group || enemy_excited_group || new
if(!our_excited_group)
EG.add_turf(src)
if(!enemy_excited_group)
EG.add_turf(enemy_tile)
our_excited_group = excited_group
should_share_air = TRUE
//air sharing
if(should_share_air)
var/difference = our_air.share(enemy_air, adjacent_turfs_length)
if(difference)
if(difference > 0)
consider_pressure_difference(enemy_tile, difference)
else
enemy_tile.consider_pressure_difference(src, -difference)
LAST_SHARE_CHECK
/******************* GROUP HANDLING FINISH *********************************************************************/
if (planet_atmos) //share our air with the "atmosphere" "above" the turf
var/datum/gas_mixture/G = new
G.copy_from_turf(src)
ARCHIVE(G)
if(our_air.compare(G))
if(!our_excited_group)
var/datum/excited_group/EG = new
EG.add_turf(src)
our_excited_group = excited_group
our_air.share(G, adjacent_turfs_length)
LAST_SHARE_CHECK
SSair.add_to_react_queue(src)
if((!our_excited_group && !(our_air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION && consider_superconductivity(starting = TRUE))) \
|| (cached_atmos_cooldown > (EXCITED_GROUP_DISMANTLE_CYCLES * 2)))
SSair.remove_from_active(src)
atmos_cooldown = cached_atmos_cooldown
/turf/open/space/process_cell(fire_count) //dumb hack to prevent space pollution
. = ..()
var/datum/gas_mixture/immutable/I = space_gas
I.after_process_cell()
/turf/proc/process_cell_reaction()
SSair.remove_from_react_queue(src)
/turf/open/process_cell_reaction()
air.react(src)
update_visuals()
SSair.remove_from_react_queue(src)
return
//////////////////////////SPACEWIND///////////////////////////// //////////////////////////SPACEWIND/////////////////////////////
@@ -256,15 +205,22 @@
/turf/open/proc/high_pressure_movements() /turf/open/proc/high_pressure_movements()
var/atom/movable/M var/atom/movable/M
var/multiplier = 1
if(locate(/obj/structure/rack) in src)
multiplier *= 0.1
else if(locate(/obj/structure/table) in src)
multiplier *= 0.2
for(var/thing in src) for(var/thing in src)
M = thing M = thing
if (!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired) if (!M.anchored && !M.pulledby && M.last_high_pressure_movement_air_cycle < SSair.times_fired)
M.experience_pressure_difference(pressure_difference, pressure_direction) M.experience_pressure_difference(pressure_difference * multiplier, pressure_direction, 0, pressure_specific_target)
if(pressure_difference > 100)
new /obj/effect/temp_visual/dir_setting/space_wind(src, pressure_direction, clamp(round(sqrt(pressure_difference) * 2), 10, 255))
/atom/movable/var/pressure_resistance = 10 /atom/movable/var/pressure_resistance = 10
/atom/movable/var/last_high_pressure_movement_air_cycle = 0 /atom/movable/var/last_high_pressure_movement_air_cycle = 0
/atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0) /atom/movable/proc/experience_pressure_difference(pressure_difference, direction, pressure_resistance_prob_delta = 0, throw_target)
var/const/PROBABILITY_OFFSET = 25 var/const/PROBABILITY_OFFSET = 25
var/const/PROBABILITY_BASE_PRECENT = 75 var/const/PROBABILITY_BASE_PRECENT = 75
var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5) var/max_force = sqrt(pressure_difference)*(MOVE_FORCE_DEFAULT / 5)
@@ -275,93 +231,8 @@
move_prob += pressure_resistance_prob_delta move_prob += pressure_resistance_prob_delta
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)))) 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) step(src, direction)
last_high_pressure_movement_air_cycle = SSair.times_fired
///////////////////////////EXCITED GROUPS/////////////////////////////
/datum/excited_group
var/list/turf_list = list()
var/breakdown_cooldown = 0
var/dismantle_cooldown = 0
/datum/excited_group/New()
SSair.excited_groups += src
/datum/excited_group/proc/add_turf(turf/open/T)
turf_list += T
T.excited_group = src
reset_cooldowns()
/datum/excited_group/proc/merge_groups(datum/excited_group/E)
if(turf_list.len > E.turf_list.len)
SSair.excited_groups -= E
for(var/t in E.turf_list)
var/turf/open/T = t
T.excited_group = src
turf_list += T
reset_cooldowns()
else
SSair.excited_groups -= src
for(var/t in turf_list)
var/turf/open/T = t
T.excited_group = E
E.turf_list += T
E.reset_cooldowns()
/datum/excited_group/proc/reset_cooldowns()
breakdown_cooldown = 0
dismantle_cooldown = 0
//argument is so world start can clear out any turf differences quickly.
/datum/excited_group/proc/self_breakdown(space_is_all_consuming = FALSE)
var/datum/gas_mixture/A = new
//make local for sanic speed
var/list/A_gases = A.gases
var/list/turf_list = src.turf_list
var/turflen = turf_list.len
var/space_in_group = FALSE
for(var/t in turf_list)
var/turf/open/T = t
if (space_is_all_consuming && !space_in_group && istype(T.air, /datum/gas_mixture/immutable/space))
space_in_group = TRUE
qdel(A)
A = new /datum/gas_mixture/immutable/space()
A_gases = A.gases //update the cache
break
A.merge(T.air)
for(var/id in A_gases)
A_gases[id] /= turflen
for(var/t in turf_list)
var/turf/open/T = t
T.air.copy_from(A)
T.atmos_cooldown = 0
T.update_visuals()
breakdown_cooldown = 0
/datum/excited_group/proc/dismantle()
for(var/t in turf_list)
var/turf/open/T = t
T.excited = FALSE
T.excited_group = null
SSair.active_turfs -= T
garbage_collect()
/datum/excited_group/proc/garbage_collect()
for(var/t in turf_list)
var/turf/open/T = t
T.excited_group = null
turf_list.Cut()
SSair.excited_groups -= src
////////////////////////SUPERCONDUCTIVITY///////////////////////////// ////////////////////////SUPERCONDUCTIVITY/////////////////////////////
/atom/movable/proc/blocksTemperature()
return FALSE
/turf/proc/conductivity_directions() /turf/proc/conductivity_directions()
if(archived_cycle < SSair.times_fired) if(archived_cycle < SSair.times_fired)
archive() archive()
@@ -376,9 +247,6 @@
. |= direction . |= direction
/turf/proc/neighbor_conduct_with_src(turf/open/other) /turf/proc/neighbor_conduct_with_src(turf/open/other)
for (var/atom/movable/G in src)
if (G.blocksTemperature())
return
if(!other.blocks_air) //Open but neighbor is solid if(!other.blocks_air) //Open but neighbor is solid
other.temperature_share_open_to_solid(src) other.temperature_share_open_to_solid(src)
else //Both tiles are solid else //Both tiles are solid
@@ -389,9 +257,7 @@
if(blocks_air) if(blocks_air)
..() ..()
return return
for (var/atom/movable/G in src)
if (G.blocksTemperature())
return
if(!other.blocks_air) //Both tiles are open if(!other.blocks_air) //Both tiles are open
var/turf/open/T = other var/turf/open/T = other
T.air.temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT) T.air.temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
@@ -410,8 +276,10 @@
if(!neighbor.thermal_conductivity) if(!neighbor.thermal_conductivity)
continue continue
if(neighbor.archived_cycle < SSair.times_fired) if(neighbor.archived_cycle < SSair.times_fired)
neighbor.archive() neighbor.archive()
neighbor.neighbor_conduct_with_src(src) neighbor.neighbor_conduct_with_src(src)
neighbor.consider_superconductivity() neighbor.consider_superconductivity()
@@ -430,7 +298,7 @@
//Conduct with air on my tile if I have it //Conduct with air on my tile if I have it
if(!blocks_air) if(!blocks_air)
temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity) temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity)
..((blocks_air ? temperature : air.temperature)) ..((blocks_air ? temperature : air.return_temperature()))
/turf/proc/consider_superconductivity() /turf/proc/consider_superconductivity()
if(!thermal_conductivity) if(!thermal_conductivity)
@@ -440,7 +308,7 @@
return TRUE return TRUE
/turf/open/consider_superconductivity(starting) /turf/open/consider_superconductivity(starting)
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)) if(air.return_temperature() < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return FALSE 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. 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 FALSE
@@ -16,90 +16,80 @@ 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_ids, meta_gas_id_list())
GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list()) GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture /datum/gas_mixture
var/list/gases = list() var/initial_volume = CELL_VOLUME //liters
var/list/gas_archive = list() var/list/reaction_results
var/temperature = 0 //kelvins
var/tmp/temperature_archived = 0
var/volume = CELL_VOLUME //liters
var/last_share = 0
var/list/reaction_results = list()
var/list/analyzer_results //used for analyzer feedback - not initialized until its used var/list/analyzer_results //used for analyzer feedback - not initialized until its used
var/gc_share = FALSE // Whether to call garbage_collect() on the sharer during shares, used for immutable mixtures 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.
/datum/gas_mixture/New(volume) /datum/gas_mixture/New(volume)
if (!isnull(volume)) if (!isnull(volume))
src.volume = volume initial_volume = volume
ATMOS_EXTOOLS_CHECK
__gasmixture_register()
reaction_results = new
//PV = nRT /datum/gas_mixture/vv_edit_var(var_name, var_value)
if(var_name == "_extools_pointer_gasmixture")
return FALSE // please no. segfaults bad.
return ..()
/*
/datum/gas_mixture/Del()
__gasmixture_unregister()
. = ..()*/
/datum/gas_mixture/proc/heat_capacity() /datum/gas_mixture/proc/__gasmixture_unregister()
/datum/gas_mixture/proc/__gasmixture_register()
/datum/gas_mixture/proc/archived_heat_capacity() /proc/gas_types()
var/list/L = subtypesof(/datum/gas)
for(var/gt in L)
var/datum/gas/G = gt
L[gt] = initial(G.specific_heat)
return L
/datum/gas_mixture/heat_capacity() //joules per kelvin /datum/gas_mixture/proc/heat_capacity() //joules per kelvin
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
. = 0
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
/datum/gas_mixture/archived_heat_capacity()
// lots of copypasta but heat_capacity is the single proc called the most in a regular round, bar none, so performance loss adds up
var/list/cached_gases = gas_archive
var/list/cached_gasheats = GLOB.meta_gas_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
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
if(!.)
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
/datum/gas_mixture/turf/archived_heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM
var/list/cached_gases = gas_archive
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
if(!.)
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
/datum/gas_mixture/proc/total_moles() /datum/gas_mixture/proc/total_moles()
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
/datum/gas_mixture/proc/return_pressure() //kilopascals /datum/gas_mixture/proc/return_pressure() //kilopascals
if(volume > 0) // to prevent division by zero
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
. *= R_IDEAL_GAS_EQUATION * temperature / volume
return
return 0
/datum/gas_mixture/proc/return_temperature() //kelvins /datum/gas_mixture/proc/return_temperature() //kelvins
return temperature
/datum/gas_mixture/proc/set_min_heat_capacity(n)
/datum/gas_mixture/proc/set_temperature(new_temp)
/datum/gas_mixture/proc/set_volume(new_volume)
/datum/gas_mixture/proc/get_moles(gas_type)
/datum/gas_mixture/proc/set_moles(gas_type, moles)
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
/datum/gas_mixture/proc/mark_immutable()
/datum/gas_mixture/proc/get_gases()
/datum/gas_mixture/proc/multiply(factor)
/datum/gas_mixture/proc/get_last_share()
/datum/gas_mixture/proc/clear()
/datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0)
set_moles(gas_type, get_moles(gas_type) + amt)
/datum/gas_mixture/proc/return_volume() //liters /datum/gas_mixture/proc/return_volume() //liters
return max(0, volume)
/datum/gas_mixture/proc/thermal_energy() //joules /datum/gas_mixture/proc/thermal_energy() //joules
return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas
/datum/gas_mixture/proc/archive() /datum/gas_mixture/proc/archive()
//Update archived versions of variables //Update archived versions of variables
//Returns: 1 in all cases //Returns: 1 in all cases
/datum/gas_mixture/proc/merge(datum/gas_mixture/giver) /datum/gas_mixture/proc/merge(datum/gas_mixture/giver)
//Merges all air from giver into self. Deletes giver. //Merges all air from giver into self. giver is untouched.
//Returns: 1 if we are mutable, 0 otherwise //Returns: 1 if we are mutable, 0 otherwise
/datum/gas_mixture/proc/remove(amount) /datum/gas_mixture/proc/remove(amount)
//Proportionally removes amount of gas from the gas_mixture //Removes amount of gas from the gas_mixture
//Returns: gas_mixture with the gases removed //Returns: gas_mixture with the gases removed
/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/remove_ratio(ratio) /datum/gas_mixture/proc/remove_ratio(ratio)
//Proportionally removes amount of gas from the gas_mixture //Proportionally removes amount of gas from the gas_mixture
//Returns: gas_mixture with the gases removed //Returns: gas_mixture with the gases removed
@@ -136,245 +126,63 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
//Performs various reactions such as combustion or fusion (LOL) //Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise //Returns: 1 if any reaction took place; 0 otherwise
/datum/gas_mixture/archive() /datum/gas_mixture/proc/__remove()
temperature_archived = temperature
gas_archive = gases.Copy()
return 1
/datum/gas_mixture/merge(datum/gas_mixture/giver)
if(!giver)
return 0
//heat transfer
if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity()
var/giver_heat_capacity = giver.heat_capacity()
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
if(combined_heat_capacity)
temperature = (giver.temperature * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/giver_gases = giver.gases
//gas transfer
for(var/giver_id in giver_gases)
cached_gases[giver_id] += giver_gases[giver_id]
return 1
/datum/gas_mixture/remove(amount) /datum/gas_mixture/remove(amount)
var/sum
var/list/cached_gases = gases
TOTAL_MOLES(cached_gases, sum)
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
var/datum/gas_mixture/removed = new type var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars __remove(removed, amount)
removed.temperature = temperature
for(var/id in cached_gases)
removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount)
cached_gases[id] -= removed_gases[id]
GAS_GARBAGE_COLLECT(gases)
return removed return removed
/datum/gas_mixture/proc/__remove_ratio()
/datum/gas_mixture/remove_ratio(ratio) /datum/gas_mixture/remove_ratio(ratio)
if(ratio <= 0)
return null
ratio = min(ratio, 1)
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new type var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars __remove_ratio(removed, ratio)
removed.temperature = temperature
for(var/id in cached_gases)
removed_gases[id] = QUANTIZE(cached_gases[id] * ratio)
cached_gases[id] -= removed_gases[id]
GAS_GARBAGE_COLLECT(gases)
return removed return removed
/datum/gas_mixture/copy() /datum/gas_mixture/copy()
var/list/cached_gases = gases
var/datum/gas_mixture/copy = new type var/datum/gas_mixture/copy = new type
var/list/copy_gases = copy.gases copy.copy_from(src)
copy.temperature = temperature
for(var/id in cached_gases)
copy_gases[id] = cached_gases[id]
return copy return copy
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/sample_gases = sample.gases
temperature = sample.temperature
for(var/id in sample_gases)
cached_gases[id] = sample_gases[id]
//remove all gases not in the sample
cached_gases &= sample_gases
return 1
/datum/gas_mixture/copy_from_turf(turf/model) /datum/gas_mixture/copy_from_turf(turf/model)
parse_gas_string(model.initial_gas_mix) parse_gas_string(model.initial_gas_mix)
//acounts for changes in temperature //acounts for changes in temperature
var/turf/model_parent = model.parent_type var/turf/model_parent = model.parent_type
if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature)) if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
temperature = model.temperature set_temperature(model.temperature)
return 1 return 1
/datum/gas_mixture/parse_gas_string(gas_string) /datum/gas_mixture/parse_gas_string(gas_string)
var/list/gases = src.gases
var/list/gas = params2list(gas_string) var/list/gas = params2list(gas_string)
if(gas["TEMP"]) if(gas["TEMP"])
temperature = text2num(gas["TEMP"]) set_temperature(text2num(gas["TEMP"]))
gas -= "TEMP" gas -= "TEMP"
gases.Cut() clear()
for(var/id in gas) for(var/id in gas)
var/path = id var/path = id
if(!ispath(path)) 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 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
gases[path] = text2num(gas[id]) set_moles(path, text2num(gas[id]))
archive() archive()
return 1 return 1
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
var/list/cached_gases = gases
var/list/sharer_gases = sharer.gases
var/temperature_delta = temperature_archived - sharer.temperature_archived
var/abs_temperature_delta = abs(temperature_delta)
var/old_self_heat_capacity = 0
var/old_sharer_heat_capacity = 0
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
old_self_heat_capacity = heat_capacity()
old_sharer_heat_capacity = sharer.heat_capacity()
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
var/moved_moles = 0
var/abs_moved_moles = 0
//we're gonna define these vars outside of this for loop because as it turns out, var declaration is pricy
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
//GAS TRANSFER
for(var/id in cached_gases | sharer_gases) // transfer gases
delta = QUANTIZE(gas_archive[id] - sharer.gas_archive[id])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
gas_heat_capacity = delta * cached_gasheats[id]
if(delta > 0)
heat_capacity_self_to_sharer += gas_heat_capacity
else
heat_capacity_sharer_to_self -= gas_heat_capacity //subtract here instead of adding the absolute value because we know that delta is negative.
cached_gases[id] -= delta
sharer_gases[id] += delta
moved_moles += delta
abs_moved_moles += abs(delta)
last_share = abs_moved_moles
//THERMAL ENERGY TRANSFER
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
//transfer of thermal energy (via changed heat capacity) between self and sharer
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
//thermal energy of the system (self and sharer) is unchanged
if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
if (initial(sharer.gc_share))
GAS_GARBAGE_COLLECT(sharer.gases)
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
var/our_moles
TOTAL_MOLES(cached_gases,our_moles)
var/their_moles
TOTAL_MOLES(sharer_gases,their_moles)
return (temperature_archived*(our_moles + moved_moles) - sharer.temperature_archived*(their_moles - moved_moles)) * R_IDEAL_GAS_EQUATION / volume
/datum/gas_mixture/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity)
//transfer of thermal energy (via conduction) between self and sharer
if(sharer)
sharer_temperature = sharer.temperature_archived
var/temperature_delta = temperature_archived - sharer_temperature
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = archived_heat_capacity()
sharer_heat_capacity = sharer_heat_capacity || sharer.archived_heat_capacity()
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*temperature_delta* \
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
temperature = max(temperature - heat/self_heat_capacity, TCMB)
sharer_temperature = max(sharer_temperature + heat/sharer_heat_capacity, TCMB)
if(sharer)
sharer.temperature = sharer_temperature
return sharer_temperature
//thermal energy of the system (self and sharer) is unchanged
/datum/gas_mixture/compare(datum/gas_mixture/sample)
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
var/list/cached_gases = gases
for(var/id in cached_gases | sample_gases) // compare gases from either mixture
var/gas_moles = cached_gases[id]
var/sample_moles = sample_gases[id]
var/delta = abs(gas_moles - sample_moles)
if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \
delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE)
return id
var/our_moles
TOTAL_MOLES(cached_gases, our_moles)
if(our_moles > MINIMUM_MOLES_DELTA_TO_MOVE)
var/temp = temperature
var/sample_temp = sample.temperature
var/temperature_delta = abs(temp - sample_temp)
if(temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return "temp"
return ""
/datum/gas_mixture/react(datum/holder) /datum/gas_mixture/react(datum/holder)
. = NO_REACTION . = NO_REACTION
var/list/cached_gases = gases if(!total_moles())
if(!length(cached_gases))
return return
var/list/reactions = list() var/list/reactions = list()
for(var/datum/gas_reaction/G in SSair.gas_reactions) for(var/datum/gas_reaction/G in SSair.gas_reactions)
if(cached_gases[G.major_gas]) if(get_moles(G.major_gas))
reactions += G reactions += G
if(!length(reactions)) if(!length(reactions))
return return
reaction_results = new reaction_results = new
var/temp = temperature var/temp = return_temperature()
var/ener = THERMAL_ENERGY(src) var/ener = thermal_energy()
reaction_loop: reaction_loop:
for(var/r in reactions) for(var/r in reactions)
@@ -388,14 +196,13 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
for(var/id in min_reqs) for(var/id in min_reqs)
if (id == "TEMP" || id == "ENER") if (id == "TEMP" || id == "ENER")
continue continue
if(cached_gases[id] < min_reqs[id]) if(get_moles(id) < min_reqs[id])
continue reaction_loop continue reaction_loop
//at this point, all minimum requirements for the reaction are satisfied. //at this point, all minimum requirements for the reaction are satisfied.
/* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost /* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost
PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase. PLEASE DO NOT REMOVE THIS CODE. the commenting is here only for a performance increase.
enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible enabling these checks should be as easy as possible and the fact that they are disabled should be as clear as possible
var/list/max_reqs = reaction.max_requirements var/list/max_reqs = reaction.max_requirements
if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \ if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \
|| (max_reqs["ENER"] && ener > max_reqs["ENER"])) || (max_reqs["ENER"] && ener > max_reqs["ENER"]))
@@ -410,8 +217,6 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
. |= reaction.react(src, holder) . |= reaction.react(src, holder)
if (. & STOP_REACTIONS) if (. & STOP_REACTIONS)
break break
if(.)
GAS_GARBAGE_COLLECT(gases)
//Takes the amount of the gas you want to PP as an argument //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 //So I don't have to do some hacky switches/defines/magic strings
@@ -420,16 +225,50 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
//O2_PP = get_partial_pressure(gas_mixture.oxygen) //O2_PP = get_partial_pressure(gas_mixture.oxygen)
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure) /datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
return (gas_pressure * R_IDEAL_GAS_EQUATION * temperature) / BREATH_VOLUME return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME
//inverse //inverse
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure) /datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * temperature) return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature())
//Mathematical proofs: //Mathematical proofs:
/* /*
get_breath_partial_pressure(gas_pp) --> gas_pp/total_moles()*breath_pp = pp get_breath_partial_pressure(gas_pp) --> gas_pp/total_moles()*breath_pp = pp
get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles() get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
10/20*5 = 2.5 10/20*5 = 2.5
10 = 2.5/5*20 10 = 2.5/5*20
*/ */
/datum/gas_mixture/turf
/*
/mob/verb/profile_atmos()
/world{loop_checks = 0;}
var/datum/gas_mixture/A = new
var/datum/gas_mixture/B = new
A.parse_gas_string("o2=200;n2=800;TEMP=50")
B.parse_gas_string("co2=500;plasma=500;TEMP=5000")
var/pa
var/pb
pa = world.tick_usage
for(var/I in 1 to 100000)
B.transfer_to(A, 1)
A.transfer_to(B, 1)
pb = world.tick_usage
var/total_time = (pb-pa) * world.tick_lag
to_chat(src, "Total time (gas transfer): [total_time]ms")
to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
pa = world.tick_usage
for(var/I in 1 to 100000)
B.total_moles();
pb = world.tick_usage
total_time = (pb-pa) * world.tick_lag
to_chat(src, "Total time (total_moles): [total_time]ms")
to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
pa = world.tick_usage
for(var/I in 1 to 100000)
new /datum/gas_mixture
pb = world.tick_usage
total_time = (pb-pa) * world.tick_lag
to_chat(src, "Total time (new gas mixture): [total_time]ms")
to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
*/
@@ -2,73 +2,29 @@
//it can be changed, but any changes will ultimately be undone before they can have any effect //it can be changed, but any changes will ultimately be undone before they can have any effect
/datum/gas_mixture/immutable /datum/gas_mixture/immutable
var/initial_temperature var/initial_temperature = 0
gc_share = TRUE
/datum/gas_mixture/immutable/New() /datum/gas_mixture/immutable/New()
..() ..()
temperature = initial_temperature set_temperature(initial_temperature)
temperature_archived = initial_temperature populate()
gases.Cut() mark_immutable()
/datum/gas_mixture/immutable/merge() /datum/gas_mixture/immutable/proc/populate()
return 0 //we're immutable. return
/datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0)
temperature = initial_temperature
temperature_archived = initial_temperature
gases.Cut()
/datum/gas_mixture/immutable/react()
return 0 //we're immutable.
/datum/gas_mixture/immutable/copy()
return new type //we're immutable, so we can just return a new instance.
/datum/gas_mixture/immutable/copy_from()
return 0 //we're immutable.
/datum/gas_mixture/immutable/copy_from_turf()
return 0 //we're immutable.
/datum/gas_mixture/immutable/parse_gas_string()
return 0 //we're immutable.
/datum/gas_mixture/immutable/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity)
. = ..()
temperature = initial_temperature
/datum/gas_mixture/immutable/proc/after_process_cell()
temperature = initial_temperature
temperature_archived = initial_temperature
gases.Cut()
//used by space tiles //used by space tiles
/datum/gas_mixture/immutable/space /datum/gas_mixture/immutable/space
initial_temperature = TCMB initial_temperature = TCMB
/datum/gas_mixture/immutable/space/heat_capacity() /datum/gas_mixture/immutable/space/populate()
return HEAT_CAPACITY_VACUUM set_min_heat_capacity(HEAT_CAPACITY_VACUUM)
/datum/gas_mixture/immutable/space/remove()
return copy() //we're always empty, so we can just return a copy.
/datum/gas_mixture/immutable/space/remove_ratio()
return copy() //we're always empty, so we can just return a copy.
//used by cloners //used by cloners
/datum/gas_mixture/immutable/cloner /datum/gas_mixture/immutable/cloner
initial_temperature = T20C initial_temperature = T20C
/datum/gas_mixture/immutable/cloner/New() /datum/gas_mixture/immutable/cloner/populate()
..() ..()
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD set_moles(/datum/gas/nitrogen, MOLES_O2STANDARD + MOLES_N2STANDARD)
/datum/gas_mixture/immutable/cloner/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0)
gases[/datum/gas/nitrogen] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/cloner/heat_capacity()
return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20
@@ -63,11 +63,11 @@
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
var/turf/open/location = isturf(holder) ? holder : null var/turf/open/location = isturf(holder) ? holder : null
. = NO_REACTION . = NO_REACTION
if (air.temperature <= WATER_VAPOR_FREEZE) if (air.return_temperature() <= WATER_VAPOR_FREEZE)
if(location && location.freon_gas_act()) if(location && location.freon_gas_act())
. = REACTING . = REACTING
else if(location && location.water_vapor_gas_act()) else if(location && location.water_vapor_gas_act())
air.gases[/datum/gas/water_vapor] -= MOLES_GAS_VISIBLE air.adjust_moles(/datum/gas/water_vapor,-MOLES_GAS_VISIBLE)
. = REACTING . = REACTING
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic //tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
@@ -86,38 +86,37 @@
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0 var/energy_released = 0
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow var/temperature = air.return_temperature()
var/temperature = air.temperature
var/list/cached_results = air.reaction_results var/list/cached_results = air.reaction_results
cached_results["fire"] = 0 cached_results["fire"] = 0
var/turf/open/location = isturf(holder) ? holder : null var/turf/open/location = isturf(holder) ? holder : null
var/burned_fuel = 0 var/burned_fuel = 0
if(cached_gases[/datum/gas/oxygen] < cached_gases[/datum/gas/tritium]) if(air.get_moles(/datum/gas/oxygen) < air.get_moles(/datum/gas/tritium))
burned_fuel = cached_gases[/datum/gas/oxygen]/TRITIUM_BURN_OXY_FACTOR burned_fuel = air.get_moles(/datum/gas/oxygen)/TRITIUM_BURN_OXY_FACTOR
cached_gases[/datum/gas/tritium] -= burned_fuel air.adjust_moles(/datum/gas/tritium, -burned_fuel)
else else
burned_fuel = cached_gases[/datum/gas/tritium]*TRITIUM_BURN_TRIT_FACTOR burned_fuel = air.get_moles(/datum/gas/tritium)*TRITIUM_BURN_TRIT_FACTOR
cached_gases[/datum/gas/tritium] -= cached_gases[/datum/gas/tritium]/TRITIUM_BURN_TRIT_FACTOR air.adjust_moles(/datum/gas/tritium, -air.get_moles(/datum/gas/tritium)/TRITIUM_BURN_TRIT_FACTOR)
cached_gases[/datum/gas/oxygen] -= cached_gases[/datum/gas/tritium] air.adjust_moles(/datum/gas/oxygen,-air.get_moles(/datum/gas/tritium))
if(burned_fuel) if(burned_fuel)
energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * 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 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) radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
cached_gases[/datum/gas/water_vapor] += burned_fuel/TRITIUM_BURN_OXY_FACTOR air.adjust_moles(/datum/gas/water_vapor, burned_fuel/TRITIUM_BURN_OXY_FACTOR)
cached_results["fire"] += burned_fuel cached_results["fire"] += burned_fuel
if(energy_released > 0) if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
//let the floor know a fire is happening //let the floor know a fire is happening
if(istype(location)) if(istype(location))
temperature = air.temperature temperature = air.return_temperature()
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME) location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location) for(var/I in location)
@@ -143,8 +142,7 @@
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0 var/energy_released = 0
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow var/temperature = air.return_temperature()
var/temperature = air.temperature
var/list/cached_results = air.reaction_results var/list/cached_results = air.reaction_results
cached_results["fire"] = 0 cached_results["fire"] = 0
var/turf/open/location = isturf(holder) ? holder : null var/turf/open/location = isturf(holder) ? holder : null
@@ -163,21 +161,21 @@
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0) if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(cached_gases[/datum/gas/oxygen] / cached_gases[/datum/gas/plasma] > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium. if(air.get_moles(/datum/gas/oxygen) / air.get_moles(/datum/gas/plasma) > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
super_saturation = TRUE super_saturation = TRUE
if(cached_gases[/datum/gas/oxygen] > cached_gases[/datum/gas/plasma]*PLASMA_OXYGEN_FULLBURN) if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/plasma)*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases[/datum/gas/plasma]*temperature_scale)/PLASMA_BURN_RATE_DELTA plasma_burn_rate = (air.get_moles(/datum/gas/plasma)*temperature_scale)/PLASMA_BURN_RATE_DELTA
else else
plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA plasma_burn_rate = (temperature_scale*(air.get_moles(/datum/gas/oxygen)/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY) if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/oxygen]/oxygen_burn_rate) //Ensures matter is conserved properly 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
cached_gases[/datum/gas/plasma] = QUANTIZE(cached_gases[/datum/gas/plasma] - plasma_burn_rate) air.set_moles(/datum/gas/plasma, QUANTIZE(air.get_moles(/datum/gas/plasma) - plasma_burn_rate))
cached_gases[/datum/gas/oxygen] = QUANTIZE(cached_gases[/datum/gas/oxygen] - (plasma_burn_rate * oxygen_burn_rate)) air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) - (plasma_burn_rate * oxygen_burn_rate)))
if (super_saturation) if (super_saturation)
cached_gases[/datum/gas/tritium] += plasma_burn_rate air.adjust_moles(/datum/gas/tritium, plasma_burn_rate)
else else
cached_gases[/datum/gas/carbon_dioxide] += plasma_burn_rate air.adjust_moles(/datum/gas/carbon_dioxide, plasma_burn_rate)
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -186,11 +184,11 @@
if(energy_released > 0) if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
//let the floor know a fire is happening //let the floor know a fire is happening
if(istype(location)) if(istype(location))
temperature = air.temperature temperature = air.return_temperature()
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME) location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location) for(var/I in location)
@@ -218,7 +216,6 @@
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD) /datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
var/turf/open/location 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. 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 var/datum/pipeline/fusion_pipenet = holder
@@ -230,14 +227,14 @@
var/list/cached_scan_results = air.analyzer_results var/list/cached_scan_results = air.analyzer_results
var/old_heat_capacity = air.heat_capacity() 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/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
var/initial_plasma = cached_gases[/datum/gas/plasma] var/initial_plasma = air.get_moles(/datum/gas/plasma)
var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide] var/initial_carbon = air.get_moles(/datum/gas/carbon_dioxide)
var/scale_factor = (air.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/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.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus 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/gas_power = 0
var/list/gas_fusion_powers = GLOB.meta_gas_fusions var/list/gas_fusion_powers = GLOB.meta_gas_fusions
for (var/gas_id in cached_gases) for (var/gas_id in air.get_gases())
gas_power += (gas_fusion_powers[gas_id]*cached_gases[gas_id]) 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 var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
cached_scan_results[id] = instability//used for analyzer feedback cached_scan_results[id] = instability//used for analyzer feedback
@@ -249,9 +246,9 @@
carbon = MODULUS(carbon - plasma, toroidal_size) carbon = MODULUS(carbon - plasma, toroidal_size)
cached_gases[/datum/gas/plasma] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up air.set_moles(/datum/gas/plasma, plasma*scale_factor + FUSION_MOLE_THRESHOLD) //Scales the gases back up
cached_gases[/datum/gas/carbon_dioxide] = carbon*scale_factor + FUSION_MOLE_THRESHOLD air.set_moles(/datum/gas/carbon_dioxide , carbon*scale_factor + FUSION_MOLE_THRESHOLD)
var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma] var/delta_plasma = initial_plasma - air.get_moles(/datum/gas/plasma)
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass. 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) if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
@@ -260,17 +257,17 @@
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5 reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist. if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
cached_gases[/datum/gas/plasma] = initial_plasma air.set_moles(/datum/gas/plasma,initial_plasma)
cached_gases[/datum/gas/carbon_dioxide] = initial_carbon air.set_moles(/datum/gas/carbon_dioxide, initial_carbon)
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/tritium] -= FUSION_TRITIUM_MOLES_USED air.adjust_moles(/datum/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 //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) if(reaction_energy > 0)
cached_gases[/datum/gas/oxygen] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT) air.adjust_moles(/datum/gas/oxygen, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
cached_gases[/datum/gas/nitrous_oxide] += 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))
else else
cached_gases[/datum/gas/bz] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT) air.adjust_moles(/datum/gas/bz, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
cached_gases[/datum/gas/nitryl] += 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))
if(reaction_energy) if(reaction_energy)
if(location) if(location)
@@ -282,7 +279,7 @@
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = clamp(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY) air.set_temperature(clamp(((air.return_temperature()*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY))
return REACTING return REACTING
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst. /datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
@@ -299,22 +296,21 @@
) )
/datum/gas_reaction/nitrylformation/react(datum/gas_mixture/air) /datum/gas_reaction/nitrylformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases var/temperature = air.return_temperature()
var/temperature = air.temperature
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),cached_gases[/datum/gas/oxygen],cached_gases[/datum/gas/nitrogen]) var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),air.get_moles(/datum/gas/oxygen),air.get_moles(/datum/gas/nitrogen))
var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
if ((cached_gases[/datum/gas/oxygen] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen] - heat_efficency < 0)) //Shouldn't produce gas from nothing. 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.
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/oxygen] -= heat_efficency air.adjust_moles(/datum/gas/oxygen, heat_efficency)
cached_gases[/datum/gas/nitrogen] -= heat_efficency air.adjust_moles(/datum/gas/nitrogen, heat_efficency)
cached_gases[/datum/gas/nitryl] += heat_efficency*2 air.adjust_moles(/datum/gas/nitryl, heat_efficency*2)
if(energy_used > 0) if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((temperature*old_heat_capacity - energy_used)/new_heat_capacity),TCMB) air.set_temperature(max(((temperature*old_heat_capacity - energy_used)/new_heat_capacity),TCMB))
return REACTING return REACTING
/datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic. /datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic.
@@ -330,27 +326,26 @@
/datum/gas_reaction/bzformation/react(datum/gas_mixture/air) /datum/gas_reaction/bzformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases var/temperature = air.return_temperature()
var/temperature = air.temperature
var/pressure = air.return_pressure() var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma]/cached_gases[/datum/gas/nitrous_oxide],1))),cached_gases[/datum/gas/nitrous_oxide],cached_gases[/datum/gas/plasma]/2) 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/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
if ((cached_gases[/datum/gas/nitrous_oxide] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma] - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing. 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.
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/bz] += reaction_efficency air.adjust_moles(/datum/gas/bz, reaction_efficency)
if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide]) if(reaction_efficency == air.get_moles(/datum/gas/nitrous_oxide))
cached_gases[/datum/gas/bz] -= min(pressure,1) air.adjust_moles(/datum/gas/bz, -min(pressure,1))
cached_gases[/datum/gas/oxygen] += min(pressure,1) air.adjust_moles(/datum/gas/oxygen, min(pressure,1))
cached_gases[/datum/gas/nitrous_oxide] -= reaction_efficency air.adjust_moles(/datum/gas/nitrous_oxide, -reaction_efficency)
cached_gases[/datum/gas/plasma] -= 2*reaction_efficency air.adjust_moles(/datum/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) SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((reaction_efficency**2)*BZ_RESEARCH_SCALE),BZ_RESEARCH_MAX_AMOUNT)
if(energy_released > 0) if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB) air.set_temperature(max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB))
return REACTING return REACTING
/datum/gas_reaction/stimformation //Stimulum formation follows a strange pattern of how effective it will be at a given temperature, having some multiple peaks and some large dropoffs. Exo and endo thermic. /datum/gas_reaction/stimformation //Stimulum formation follows a strange pattern of how effective it will be at a given temperature, having some multiple peaks and some large dropoffs. Exo and endo thermic.
@@ -367,24 +362,22 @@
"TEMP" = STIMULUM_HEAT_SCALE/2) "TEMP" = STIMULUM_HEAT_SCALE/2)
/datum/gas_reaction/stimformation/react(datum/gas_mixture/air) /datum/gas_reaction/stimformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/tritium],cached_gases[/datum/gas/plasma],cached_gases[/datum/gas/nitryl]) 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/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) 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 ((cached_gases[/datum/gas/tritium] - heat_scale < 0 )|| (cached_gases[/datum/gas/plasma] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl] - heat_scale < 0)) //Shouldn't produce gas from nothing. 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.
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/stimulum]+= heat_scale/10 air.adjust_moles(/datum/gas/stimulum, heat_scale/10)
cached_gases[/datum/gas/tritium] -= heat_scale air.adjust_moles(/datum/gas/tritium, -heat_scale)
cached_gases[/datum/gas/plasma] -= heat_scale air.adjust_moles(/datum/gas/plasma, -heat_scale)
cached_gases[/datum/gas/nitryl] -= heat_scale air.adjust_moles(/datum/gas/nitryl, -heat_scale)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0)) SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0))
if(stim_energy_change) if(stim_energy_change)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((air.temperature*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB) air.set_temperature(max(((air.return_temperature()*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB))
return REACTING return REACTING
/datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic. /datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic.
@@ -399,22 +392,21 @@
"TEMP" = 5000000) "TEMP" = 5000000)
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air) /datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/nob_formed = min((cached_gases[/datum/gas/nitrogen]+cached_gases[/datum/gas/tritium])/100,cached_gases[/datum/gas/tritium]/10,cached_gases[/datum/gas/nitrogen]/20) 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(cached_gases[/datum/gas/bz],1))) var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(/datum/gas/bz),1)))
if ((cached_gases[/datum/gas/tritium] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen] - 20*nob_formed < 0)) if ((air.get_moles(/datum/gas/tritium) - 10*nob_formed < 0) || (air.get_moles(/datum/gas/nitrogen) - 20*nob_formed < 0))
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/tritium] -= 10*nob_formed air.adjust_moles(/datum/gas/tritium, -10*nob_formed)
cached_gases[/datum/gas/nitrogen] -= 20*nob_formed air.adjust_moles(/datum/gas/nitrogen, -20*nob_formed)
cached_gases[/datum/gas/hypernoblium]+= nob_formed air.adjust_moles(/datum/gas/hypernoblium,nob_formed)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT) SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
if (nob_formed) if (nob_formed)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((air.temperature*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB) air.set_temperature(max(((air.return_temperature()*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB))
/datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air /datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air
@@ -429,16 +421,15 @@
) )
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
// As the name says it, it needs to be dry // As the name says it, it needs to be dry
if(cached_gases[/datum/gas/water_vapor] && cached_gases[/datum/gas/water_vapor]/air.total_moles() > 0.1) if(air.get_moles(/datum/gas/water_vapor) && air.get_moles(/datum/gas/water_vapor)/air.total_moles() > 0.1)
return return
//Replace miasma with oxygen //Replace miasma with oxygen
var/cleaned_air = min(cached_gases[/datum/gas/miasma], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20) var/cleaned_air = min(air.get_moles(/datum/gas/miasma), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
cached_gases[/datum/gas/miasma] -= cleaned_air air.adjust_moles(/datum/gas/miasma, -cleaned_air)
cached_gases[/datum/gas/oxygen] += cleaned_air air.adjust_moles(/datum/gas/oxygen, cleaned_air)
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable //Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
air.temperature += cleaned_air * 0.002 air.set_temperature(air.return_temperature() + cleaned_air * 0.002)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists
@@ -0,0 +1,304 @@
#ifdef EXTOOLS_BROKE
/datum/gas_mixture
var/list/gases = list()
var/temperature = 0 //kelvins
var/tmp/temperature_archived = 0
var/volume = CELL_VOLUME //liters
var/last_share = 0
/datum/gas_mixture/heat_capacity() //joules per kelvin
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_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
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
if(!.)
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
//prefer this to gas_mixture/total_moles in performance critical areas
#define TOTAL_MOLES(cached_gases, out_var)\
out_var = 0;\
for(var/total_moles_id in cached_gases){\
out_var += cached_gases[total_moles_id];\
}
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
/datum/gas_mixture/total_moles()
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
/datum/gas_mixture/return_pressure() //kilopascals
if(volume > 0) // to prevent division by zero
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
. *= R_IDEAL_GAS_EQUATION * temperature / volume
return
return 0
/datum/gas_mixture/return_temperature() //kelvins
return temperature
/datum/gas_mixture/set_min_heat_capacity(n)
return
/datum/gas_mixture/set_temperature(new_temp)
temperature = new_temp
/datum/gas_mixture/set_volume(new_volume)
volume = new_volume
/datum/gas_mixture/get_moles(gas_type)
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)
if(isnull(target))
return FALSE
var/list/removed_gases = target.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)
/datum/gas_mixture/mark_immutable()
return
/datum/gas_mixture/get_gases()
return gases
/datum/gas_mixture/multiply(factor)
for(var/id in gases)
gases[id] *= factor
/datum/gas_mixture/get_last_share()
return last_share
/datum/gas_mixture/clear()
gases.Cut()
/datum/gas_mixture/return_volume()
return volume // wow!
/datum/gas_mixture/thermal_energy()
return THERMAL_ENERGY(src)
/datum/gas_mixture/archive()
temperature_archived = temperature
gas_archive = gases.Copy()
return 1
/datum/gas_mixture/merge(datum/gas_mixture/giver)
if(!giver)
return 0
//heat transfer
if(abs(temperature - giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity()
var/giver_heat_capacity = giver.heat_capacity()
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
if(combined_heat_capacity)
temperature = (giver.temperature * giver_heat_capacity + temperature * self_heat_capacity) / combined_heat_capacity
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/giver_gases = giver.gases
//gas transfer
for(var/giver_id in giver_gases)
cached_gases[giver_id] += giver_gases[giver_id]
return 1
/datum/gas_mixture/remove(amount)
var/sum
var/list/cached_gases = gases
TOTAL_MOLES(cached_gases, sum)
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
removed.temperature = temperature
for(var/id in cached_gases)
removed_gases[id] = QUANTIZE((cached_gases[id] / sum) * amount)
cached_gases[id] -= removed_gases[id]
GAS_GARBAGE_COLLECT(gases)
return removed
/datum/gas_mixture/remove_ratio(ratio)
if(ratio <= 0)
return null
ratio = min(ratio, 1)
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
removed.temperature = temperature
for(var/id in cached_gases)
removed_gases[id] = QUANTIZE(cached_gases[id] * ratio)
cached_gases[id] -= removed_gases[id]
GAS_GARBAGE_COLLECT(gases)
return removed
/datum/gas_mixture/copy()
var/list/cached_gases = gases
var/datum/gas_mixture/copy = new type
var/list/copy_gases = copy.gases
copy.temperature = temperature
for(var/id in cached_gases)
copy_gases[id] = cached_gases[id]
return copy
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/sample_gases = sample.gases
temperature = sample.temperature
for(var/id in sample_gases)
cached_gases[id] = sample_gases[id]
//remove all gases not in the sample
cached_gases &= sample_gases
return 1
/datum/gas_mixture/copy_from_turf(turf/model)
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))
temperature = model.temperature
return 1
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
var/list/cached_gases = gases
var/list/sharer_gases = sharer.gases
var/temperature_delta = temperature_archived - sharer.temperature_archived
var/abs_temperature_delta = abs(temperature_delta)
var/old_self_heat_capacity = 0
var/old_sharer_heat_capacity = 0
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
old_self_heat_capacity = heat_capacity()
old_sharer_heat_capacity = sharer.heat_capacity()
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
var/moved_moles = 0
var/abs_moved_moles = 0
//we're gonna define these vars outside of this for loop because as it turns out, var declaration is pricy
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
//GAS TRANSFER
for(var/id in cached_gases | sharer_gases) // transfer gases
delta = QUANTIZE(gas_archive[id] - sharer.gas_archive[id])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
gas_heat_capacity = delta * cached_gasheats[id]
if(delta > 0)
heat_capacity_self_to_sharer += gas_heat_capacity
else
heat_capacity_sharer_to_self -= gas_heat_capacity //subtract here instead of adding the absolute value because we know that delta is negative.
cached_gases[id] -= delta
sharer_gases[id] += delta
moved_moles += delta
abs_moved_moles += abs(delta)
last_share = abs_moved_moles
//THERMAL ENERGY TRANSFER
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
//transfer of thermal energy (via changed heat capacity) between self and sharer
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
//thermal energy of the system (self and sharer) is unchanged
if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.1) // <10% change in sharer heat capacity
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
if (initial(sharer.gc_share))
GAS_GARBAGE_COLLECT(sharer.gases)
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
var/our_moles
TOTAL_MOLES(cached_gases,our_moles)
var/their_moles
TOTAL_MOLES(sharer_gases,their_moles)
return (temperature_archived*(our_moles + moved_moles) - sharer.temperature_archived*(their_moles - moved_moles)) * R_IDEAL_GAS_EQUATION / volume
/datum/gas_mixture/temperature_share(datum/gas_mixture/sharer, conduction_coefficient, sharer_temperature, sharer_heat_capacity)
//transfer of thermal energy (via conduction) between self and sharer
if(sharer)
sharer_temperature = sharer.temperature_archived
var/temperature_delta = temperature_archived - sharer_temperature
if(abs(temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = archived_heat_capacity()
sharer_heat_capacity = sharer_heat_capacity || sharer.archived_heat_capacity()
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
var/heat = conduction_coefficient*temperature_delta* \
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
temperature = max(temperature - heat/self_heat_capacity, TCMB)
sharer_temperature = max(sharer_temperature + heat/sharer_heat_capacity, TCMB)
if(sharer)
sharer.temperature = sharer_temperature
return sharer_temperature
//thermal energy of the system (self and sharer) is unchanged
/datum/gas_mixture/compare(datum/gas_mixture/sample)
var/list/sample_gases = sample.gases //accessing datum vars is slower than proc vars
var/list/cached_gases = gases
for(var/id in cached_gases | sample_gases) // compare gases from either mixture
var/gas_moles = cached_gases[id]
var/sample_moles = sample_gases[id]
var/delta = abs(gas_moles - sample_moles)
if(delta > MINIMUM_MOLES_DELTA_TO_MOVE && \
delta > gas_moles * MINIMUM_AIR_RATIO_TO_MOVE)
return id
var/our_moles
TOTAL_MOLES(cached_gases, our_moles)
if(our_moles > MINIMUM_MOLES_DELTA_TO_MOVE)
var/temp = temperature
var/sample_temp = sample.temperature
var/temperature_delta = abs(temp - sample_temp)
if(temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return "temp"
return ""
/datum/gas_mixture/transfer_to(datum/gas_mixture/target, amount)
return merge(target.remove(amount))
#endif
@@ -269,7 +269,7 @@
"unit" = "kPa", "unit" = "kPa",
"danger_level" = cur_tlv.get_danger_level(pressure) "danger_level" = cur_tlv.get_danger_level(pressure)
)) ))
var/temperature = environment.temperature var/temperature = environment.return_temperature()
cur_tlv = TLV["temperature"] cur_tlv = TLV["temperature"]
data["environment_data"] += list(list( data["environment_data"] += list(list(
"name" = "Temperature", "name" = "Temperature",
@@ -278,16 +278,16 @@
"danger_level" = cur_tlv.get_danger_level(temperature) "danger_level" = cur_tlv.get_danger_level(temperature)
)) ))
var/total_moles = environment.total_moles() var/total_moles = environment.total_moles()
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
for(var/gas_id in environment.gases) for(var/gas_id in environment.get_gases())
if(!(gas_id in TLV)) // We're not interested in this gas, it seems. if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue continue
cur_tlv = TLV[gas_id] cur_tlv = TLV[gas_id]
data["environment_data"] += list(list( data["environment_data"] += list(list(
"name" = GLOB.meta_gas_names[gas_id], "name" = GLOB.meta_gas_names[gas_id],
"value" = environment.gases[gas_id] / total_moles * 100, "value" = environment.get_moles(gas_id) / total_moles * 100,
"unit" = "%", "unit" = "%",
"danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id] * partial_pressure) "danger_level" = cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)
)) ))
if(!locked || hasSiliconAccessInArea(user, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE)) if(!locked || hasSiliconAccessInArea(user, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE))
@@ -684,24 +684,21 @@
var/datum/tlv/cur_tlv var/datum/tlv/cur_tlv
var/datum/gas_mixture/environment = location.return_air() var/datum/gas_mixture/environment = location.return_air()
var/list/env_gases = environment.gases var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
cur_tlv = TLV["pressure"] cur_tlv = TLV["pressure"]
var/environment_pressure = environment.return_pressure() var/environment_pressure = environment.return_pressure()
var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure) var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure)
cur_tlv = TLV["temperature"] cur_tlv = TLV["temperature"]
var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature) var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.return_temperature())
var/gas_dangerlevel = 0 var/gas_dangerlevel = 0
for(var/gas_id in env_gases) for(var/gas_id in environment.get_gases())
if(!(gas_id in TLV)) // We're not interested in this gas, it seems. if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue continue
cur_tlv = TLV[gas_id] cur_tlv = TLV[gas_id]
gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id] * partial_pressure)) gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure))
GAS_GARBAGE_COLLECT(environment.gases)
var/old_danger_level = danger_level var/old_danger_level = danger_level
danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel) danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel)
@@ -52,10 +52,10 @@
return null return null
//Calculate necessary moles to transfer using PV = nRT //Calculate necessary moles to transfer using PV = nRT
if(air2.temperature>0) if(air2.return_temperature()>0)
var/pressure_delta = (input_starting_pressure - output_starting_pressure)/2 var/pressure_delta = (input_starting_pressure - output_starting_pressure)/2
var/transfer_moles = pressure_delta*air1.volume/(air2.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*air1.return_volume()/(air2.return_temperature() * R_IDEAL_GAS_EQUATION)
last_pressure_delta = pressure_delta last_pressure_delta = pressure_delta
@@ -66,8 +66,8 @@
pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min)) pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min))
if(pressure_delta > 0) if(pressure_delta > 0)
if(air1.temperature > 0) if(air1.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*environment.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air1.remove(transfer_moles) var/datum/gas_mixture/removed = air1.remove(transfer_moles)
//Removed can be null if there is no atmosphere in air1 //Removed can be null if there is no atmosphere in air1
@@ -81,20 +81,17 @@
parent1.update = 1 parent1.update = 1
else //external -> output else //external -> output
var/pressure_delta = 10000 if(environment.return_pressure() > 0)
var/our_multiplier = air2.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION)
var/moles_delta = 10000 * our_multiplier
if(pressure_checks&EXT_BOUND)
moles_delta = min(moles_delta, (environment_pressure - output_pressure_max) * environment.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION))
if(pressure_checks&INPUT_MIN)
moles_delta = min(moles_delta, (input_pressure_min - air2.return_pressure()) * our_multiplier)
if(pressure_checks&EXT_BOUND) if(moles_delta > 0)
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound)) var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if(pressure_checks&INPUT_MIN) if (isnull(removed)) // in space
pressure_delta = min(pressure_delta, (output_pressure_max - air2.return_pressure()))
if(pressure_delta > 0)
if(environment.temperature > 0)
var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
//removed can be null if there is no air in the location
if(!removed)
return return
air2.merge(removed) air2.merge(removed)
@@ -182,8 +179,8 @@
..() ..()
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2] var/datum/gas_mixture/air2 = airs[2]
air1.volume = 1000 air1.set_volume(1000)
air2.volume = 1000 air2.set_volume(1000)
// Mapping // Mapping
@@ -53,11 +53,11 @@ Passive gate is similar to the regular pump except:
return return
//Calculate necessary moles to transfer using PV = nRT //Calculate necessary moles to transfer using PV = nRT
if((air1.total_moles() > 0) && (air1.temperature>0)) if((air1.total_moles() > 0) && (air1.return_temperature()>0))
var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2) var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2)
//Can not have a pressure delta that would cause output_pressure > input_pressure //Can not have a pressure delta that would cause output_pressure > input_pressure
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas //Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles) var/datum/gas_mixture/removed = air1.remove(transfer_moles)
@@ -77,9 +77,9 @@
return return
//Calculate necessary moles to transfer using PV=nRT //Calculate necessary moles to transfer using PV=nRT
if((air1.total_moles() > 0) && (air1.temperature>0)) if((air1.total_moles() > 0) && (air1.return_temperature()>0))
var/pressure_delta = target_pressure - output_starting_pressure var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas //Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles) var/datum/gas_mixture/removed = air1.remove(transfer_moles)
@@ -65,7 +65,7 @@
if((input_starting_pressure < 0.01) || (output_starting_pressure > 9000)) if((input_starting_pressure < 0.01) || (output_starting_pressure > 9000))
return return
var/transfer_ratio = transfer_rate/air1.volume var/transfer_ratio = transfer_rate/air1.return_volume()
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio) var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
@@ -153,7 +153,7 @@
if("set_transfer_rate" in signal.data) if("set_transfer_rate" in signal.data)
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
transfer_rate = clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume) transfer_rate = clamp(text2num(signal.data["set_transfer_rate"]),0,air1.return_volume())
if(on != old_on) if(on != old_on)
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)
@@ -15,8 +15,7 @@
..() ..()
for(var/i in 1 to device_type) for(var/i in 1 to device_type)
var/datum/gas_mixture/A = new var/datum/gas_mixture/A = new(200)
A.volume = 200
airs[i] = A airs[i] = A
// Iconnery // Iconnery
@@ -117,7 +116,7 @@
var/times_lost = 0 var/times_lost = 0
for(var/i in 1 to device_type) for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i] var/datum/gas_mixture/air = airs[i]
lost += pressures*environment.volume/(air.temperature * R_IDEAL_GAS_EQUATION) lost += pressures*environment.return_volume()/(air.return_temperature() * R_IDEAL_GAS_EQUATION)
times_lost++ times_lost++
var/shared_loss = lost/times_lost var/shared_loss = lost/times_lost
@@ -94,7 +94,7 @@
//Calculate necessary moles to transfer using PV=nRT //Calculate necessary moles to transfer using PV=nRT
var/transfer_ratio = transfer_rate/air1.volume var/transfer_ratio = transfer_rate/air1.return_volume()
//Actually transfer the gas //Actually transfer the gas
@@ -111,14 +111,13 @@
else else
filtering = FALSE filtering = FALSE
if(filtering && removed.gases[filter_type]) if(filtering && removed.get_moles(filter_type))
var/datum/gas_mixture/filtered_out = new var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature filtered_out.set_temperature(removed.return_temperature())
filtered_out.gases[filter_type] = removed.gases[filter_type] filtered_out.set_moles(filter_type, removed.get_moles(filter_type))
removed.gases[filter_type] = 0 removed.set_moles(filter_type, 0)
GAS_GARBAGE_COLLECT(removed.gases)
var/datum/gas_mixture/target = (air2.return_pressure() < 9000 ? air2 : air1) var/datum/gas_mixture/target = (air2.return_pressure() < 9000 ? air2 : air1)
target.merge(filtered_out) target.merge(filtered_out)
@@ -57,7 +57,7 @@
/obj/machinery/atmospherics/components/trinary/mixer/New() /obj/machinery/atmospherics/components/trinary/mixer/New()
..() ..()
var/datum/gas_mixture/air3 = airs[3] var/datum/gas_mixture/air3 = airs[3]
air3.volume = 300 air3.set_volume(300)
airs[3] = air3 airs[3] = air3
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos() /obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
@@ -81,26 +81,26 @@
return return
//Calculate necessary moles to transfer using PV=nRT //Calculate necessary moles to transfer using PV=nRT
var/general_transfer = (target_pressure - output_starting_pressure) * air3.volume / R_IDEAL_GAS_EQUATION var/general_transfer = (target_pressure - output_starting_pressure) * air3.return_volume() / R_IDEAL_GAS_EQUATION
var/transfer_moles1 = air1.temperature ? node1_concentration * general_transfer / air1.temperature : 0 var/transfer_moles1 = air1.return_temperature() ? node1_concentration * general_transfer / air1.return_temperature() : 0
var/transfer_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0 var/transfer_moles2 = air2.return_temperature() ? node2_concentration * general_transfer / air2.return_temperature() : 0
var/air1_moles = air1.total_moles() var/air1_moles = air1.total_moles()
var/air2_moles = air2.total_moles() var/air2_moles = air2.total_moles()
if(!node2_concentration) if(!node2_concentration)
if(air1.temperature <= 0) if(air1.return_temperature() <= 0)
return return
transfer_moles1 = min(transfer_moles1, air1_moles) transfer_moles1 = min(transfer_moles1, air1_moles)
transfer_moles2 = 0 transfer_moles2 = 0
else if(!node1_concentration) else if(!node1_concentration)
if(air2.temperature <= 0) if(air2.return_temperature() <= 0)
return return
transfer_moles2 = min(transfer_moles2, air2_moles) transfer_moles2 = min(transfer_moles2, air2_moles)
transfer_moles1 = 0 transfer_moles1 = 0
else else
if(air1.temperature <= 0 || air2.temperature <= 0) if(air1.return_temperature() <= 0 || air2.return_temperature() <= 0)
return return
if((transfer_moles2 <= 0) || (transfer_moles1 <= 0)) if((transfer_moles2 <= 0) || (transfer_moles1 <= 0))
return return
@@ -186,7 +186,7 @@
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
if(air1.gases.len) if(air1.total_moles())
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic. if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
// temperature factor goes from 1 to about 2.5 // temperature factor goes from 1 to about 2.5
var/amount = max(1, (4 * log(T0C - mob_occupant.bodytemperature)) - 20) * knockout_factor * base_knockout var/amount = max(1, (4 * log(T0C - mob_occupant.bodytemperature)) - 20) * knockout_factor * base_knockout
@@ -196,8 +196,7 @@
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents. beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR) beaker.reagents.reaction(occupant, VAPOR)
air1.gases[/datum/gas/oxygen] -= max(0,air1.gases[/datum/gas/oxygen] - 2 / efficiency) //Let's use gas for this air1.adjust_moles(/datum/gas/oxygen, -max(0,air1.get_moles(/datum/gas/oxygen) - 2 / efficiency)) //Let's use gas for this
GAS_GARBAGE_COLLECT(air1.gases)
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0 reagent_transfer = 0
@@ -211,7 +210,7 @@
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen] < 5) // Turn off if the machine won't work. if(!nodes[1] || !airs[1] || air1.get_moles(/datum/gas/oxygen) < 5) // Turn off if the machine won't work.
on = FALSE on = FALSE
update_icon() update_icon()
return return
@@ -219,22 +218,21 @@
if(occupant) if(occupant)
var/mob/living/mob_occupant = occupant var/mob/living/mob_occupant = occupant
var/cold_protection = 0 var/cold_protection = 0
var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant. var/temperature_delta = air1.return_temperature() - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant.
if(ishuman(occupant)) if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant var/mob/living/carbon/human/H = occupant
cold_protection = H.get_thermal_protection(air1.temperature, TRUE) cold_protection = H.get_thermal_protection(air1.return_temperature(), TRUE)
if(abs(temperature_delta) > 1) if(abs(temperature_delta) > 1)
var/air_heat_capacity = air1.heat_capacity() var/air_heat_capacity = air1.heat_capacity()
var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity)) var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity))
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB) air1.set_temperature(max(air1.return_temperature() - heat / air_heat_capacity, TCMB))
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB) mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
air1.gases[/datum/gas/oxygen] = max(0,air1.gases[/datum/gas/oxygen] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic. air1.set_temperature(max(air1.return_temperature() - 0.5 / efficiency)) // Magically consume gas? Why not, we run on cryo magic.
GAS_GARBAGE_COLLECT(air1.gases)
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change() /obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..() ..()
@@ -369,7 +367,7 @@
data["occupant"]["temperaturestatus"] = "bad" data["occupant"]["temperaturestatus"] = "bad"
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
data["cellTemperature"] = round(air1.temperature, 1) data["cellTemperature"] = round(air1.return_temperature(), 1)
data["isBeakerLoaded"] = beaker ? TRUE : FALSE data["isBeakerLoaded"] = beaker ? TRUE : FALSE
var/beakerContents = list() var/beakerContents = list()
@@ -439,7 +437,7 @@
var/datum/gas_mixture/G = airs[1] var/datum/gas_mixture/G = airs[1]
if(G.total_moles() > 10) if(G.total_moles() > 10)
return G.temperature return G.return_temperature()
return ..() return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W) /obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)
@@ -59,18 +59,18 @@
var/other_air_heat_capacity = partner_air_contents.heat_capacity() var/other_air_heat_capacity = partner_air_contents.heat_capacity()
var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature var/old_temperature = air_contents.return_temperature()
var/other_old_temperature = partner_air_contents.temperature var/other_old_temperature = partner_air_contents.return_temperature()
if(combined_heat_capacity > 0) if(combined_heat_capacity > 0)
var/combined_energy = partner_air_contents.temperature*other_air_heat_capacity + air_heat_capacity*air_contents.temperature var/combined_energy = partner_air_contents.return_temperature()*other_air_heat_capacity + air_heat_capacity*air_contents.return_temperature()
var/new_temperature = combined_energy/combined_heat_capacity var/new_temperature = combined_energy/combined_heat_capacity
air_contents.temperature = new_temperature air_contents.set_temperature(new_temperature)
partner_air_contents.temperature = new_temperature partner_air_contents.set_temperature(new_temperature)
if(abs(old_temperature-air_contents.temperature) > 1) if(abs(old_temperature-air_contents.return_temperature()) > 1)
update_parents() update_parents()
if(abs(other_old_temperature-partner_air_contents.temperature) > 1) if(abs(other_old_temperature-partner_air_contents.return_temperature()) > 1)
partner.update_parents() partner.update_parents()
@@ -52,8 +52,8 @@
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.temperature > 0) if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) 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) var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -71,8 +71,8 @@
injecting = 1 injecting = 1
if(air_contents.temperature > 0) if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) 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) var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed) loc.assume_air(removed)
update_parents() update_parents()
@@ -123,7 +123,7 @@
if("set_volume_rate" in signal.data) if("set_volume_rate" in signal.data)
var/number = text2num(signal.data["set_volume_rate"]) var/number = text2num(signal.data["set_volume_rate"])
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
volume_rate = clamp(number, 0, air_contents.volume) volume_rate = clamp(number, 0, air_contents.return_volume())
if("status" in signal.data) if("status" in signal.data)
spawn(2) spawn(2)
@@ -30,14 +30,14 @@
if(pressure_delta > 0.5) if(pressure_delta > 0.5)
if(external_pressure < internal_pressure) if(external_pressure < internal_pressure)
var/air_temperature = (external.temperature > 0) ? external.temperature : internal.temperature var/air_temperature = (external.return_temperature() > 0) ? external.return_temperature() : internal.return_temperature()
var/transfer_moles = (pressure_delta * external.volume) / (air_temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = (pressure_delta * external.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = internal.remove(transfer_moles) var/datum/gas_mixture/removed = internal.remove(transfer_moles)
external.merge(removed) external.merge(removed)
else else
var/air_temperature = (internal.temperature > 0) ? internal.temperature : external.temperature var/air_temperature = (internal.return_temperature() > 0) ? internal.return_temperature() : external.return_temperature()
var/transfer_moles = (pressure_delta * internal.volume) / (air_temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = (pressure_delta * internal.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = min(transfer_moles, external.total_moles() * internal.volume / external.volume) transfer_moles = min(transfer_moles, external.total_moles() * internal.return_volume() / external.return_volume())
var/datum/gas_mixture/removed = external.remove(transfer_moles) var/datum/gas_mixture/removed = external.remove(transfer_moles)
if(isnull(removed)) if(isnull(removed))
return return
@@ -16,7 +16,7 @@
..() ..()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 0 air_contents.set_volume(0)
/obj/machinery/atmospherics/components/unary/portables_connector/Destroy() /obj/machinery/atmospherics/components/unary/portables_connector/Destroy()
if(connected_device) if(connected_device)
@@ -49,10 +49,10 @@
else if(!opened && our_pressure >= open_pressure) else if(!opened && our_pressure >= open_pressure)
opened = TRUE opened = TRUE
update_icon_nopipes() update_icon_nopipes()
if(opened && air_contents.temperature > 0) if(opened && air_contents.return_temperature() > 0)
var/datum/gas_mixture/environment = loc.return_air() var/datum/gas_mixture/environment = loc.return_air()
var/pressure_delta = our_pressure - environment.return_pressure() var/pressure_delta = our_pressure - environment.return_pressure()
var/transfer_moles = pressure_delta*200/(air_contents.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*200/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
if(transfer_moles > 0) if(transfer_moles > 0)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -1,4 +1,4 @@
#define AIR_CONTENTS ((25*ONE_ATMOSPHERE)*(air_contents.volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature)) #define AIR_CONTENTS ((25*ONE_ATMOSPHERE)*(air_contents.return_volume())/(R_IDEAL_GAS_EQUATION*air_contents.return_temperature()))
/obj/machinery/atmospherics/components/unary/tank /obj/machinery/atmospherics/components/unary/tank
icon = 'icons/obj/atmospherics/pipes/pressure_tank.dmi' icon = 'icons/obj/atmospherics/pipes/pressure_tank.dmi'
icon_state = "generic" icon_state = "generic"
@@ -15,10 +15,10 @@
/obj/machinery/atmospherics/components/unary/tank/New() /obj/machinery/atmospherics/components/unary/tank/New()
..() ..()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = volume air_contents.set_volume(volume)
air_contents.temperature = T20C air_contents.set_temperature(T20C)
if(gas_type) if(gas_type)
air_contents.gases[gas_type] = AIR_CONTENTS air_contents.set_moles(AIR_CONTENTS)
name = "[name] ([GLOB.meta_gas_names[gas_type]])" name = "[name] ([GLOB.meta_gas_names[gas_type]])"
/obj/machinery/atmospherics/components/unary/tank/air /obj/machinery/atmospherics/components/unary/tank/air
@@ -28,8 +28,8 @@
/obj/machinery/atmospherics/components/unary/tank/air/New() /obj/machinery/atmospherics/components/unary/tank/air/New()
..() ..()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
air_contents.gases[/datum/gas/oxygen] = AIR_CONTENTS * 0.2 air_contents.set_moles(/datum/gas/oxygen, AIR_CONTENTS * 0.2)
air_contents.gases[/datum/gas/nitrogen] = AIR_CONTENTS * 0.8 air_contents.set_moles(/datum/gas/nitrogen, AIR_CONTENTS * 0.8)
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide /obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
gas_type = /datum/gas/carbon_dioxide gas_type = /datum/gas/carbon_dioxide
@@ -74,13 +74,13 @@
var/air_heat_capacity = air_contents.heat_capacity() var/air_heat_capacity = air_contents.heat_capacity()
var/combined_heat_capacity = heat_capacity + air_heat_capacity var/combined_heat_capacity = heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature var/old_temperature = air_contents.return_temperature()
if(combined_heat_capacity > 0) if(combined_heat_capacity > 0)
var/combined_energy = heat_capacity * target_temperature + air_heat_capacity * air_contents.temperature var/combined_energy = heat_capacity * target_temperature + air_heat_capacity * air_contents.return_temperature()
air_contents.temperature = combined_energy/combined_heat_capacity air_contents.set_temperature(combined_energy/combined_heat_capacity)
var/temperature_delta= abs(old_temperature - air_contents.temperature) var/temperature_delta= abs(old_temperature - air_contents.return_temperature())
if(temperature_delta > 1) if(temperature_delta > 1)
active_power_usage = (heat_capacity * temperature_delta) / 10 + idle_power_usage active_power_usage = (heat_capacity * temperature_delta) / 10 + idle_power_usage
update_parents() update_parents()
@@ -142,7 +142,7 @@
data["initial"] = initial(target_temperature) data["initial"] = initial(target_temperature)
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
data["temperature"] = air1.temperature data["temperature"] = air1.return_temperature()
data["pressure"] = air1.return_pressure() data["pressure"] = air1.return_pressure()
return data return data
@@ -104,8 +104,8 @@
pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound)) pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound))
if(pressure_delta > 0) if(pressure_delta > 0)
if(air_contents.temperature > 0) if(air_contents.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION) 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) var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -113,21 +113,21 @@
air_update_turf() air_update_turf()
else // external -> internal else // external -> internal
var/pressure_delta = 10000 if(environment.return_pressure() > 0)
if(pressure_checks&EXT_BOUND) var/our_multiplier = air_contents.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION)
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound)) var/moles_delta = 10000 * our_multiplier
if(pressure_checks&INT_BOUND) if(pressure_checks&EXT_BOUND)
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure())) moles_delta = min(moles_delta, (environment_pressure - external_pressure_bound) * environment.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION))
if(pressure_checks&INT_BOUND)
moles_delta = min(moles_delta, (internal_pressure_bound - air_contents.return_pressure()) * our_multiplier)
if(pressure_delta > 0 && environment.temperature > 0) if(moles_delta > 0)
var/transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if (isnull(removed)) // in space
return
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) air_contents.merge(removed)
if (isnull(removed)) // in space air_update_turf()
return
air_contents.merge(removed)
air_update_turf()
update_parents() update_parents()
//Radio remote control //Radio remote control
@@ -295,7 +295,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New() /obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New()
..() ..()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 1000 air_contents.set_volume(1000)
// mapping // mapping
@@ -149,43 +149,29 @@
return FALSE return FALSE
var/datum/gas_mixture/environment = tile.return_air() var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE) if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
return FALSE return FALSE
if(scrubbing & SCRUBBING) if(scrubbing & SCRUBBING)
if(length(env_gases & filter_types)) var/transfer_moles = min(1, volume_rate/environment.return_volume())*environment.total_moles()
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
//Take a gas sample //Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile //Nothing left to remove from the tile
if(isnull(removed)) if(isnull(removed))
return FALSE return FALSE
var/list/removed_gases = removed.gases removed.scrub_into(air_contents, filter_types)
//Filter it //Remix the resulting gases
var/datum/gas_mixture/filtered_out = new tile.assume_air(removed)
var/list/filtered_gases = filtered_out.gases tile.air_update_turf()
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
filtered_gases[gas] = removed_gases[gas]
removed_gases[gas] = 0
GAS_GARBAGE_COLLECT(removed.gases)
//Remix the resulting gases
air_contents.merge(filtered_out)
tile.assume_air(removed)
tile.air_update_turf()
else //Just siphoning all air else //Just siphoning all air
var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) var/transfer_moles = environment.total_moles()*(volume_rate/environment.return_volume())
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
@@ -15,7 +15,7 @@
/datum/pipeline/Destroy() /datum/pipeline/Destroy()
SSair.networks -= src SSair.networks -= src
if(air && air.volume) if(air && air.return_volume())
temporarily_store_air() temporarily_store_air()
for(var/obj/machinery/atmospherics/pipe/P in members) for(var/obj/machinery/atmospherics/pipe/P in members)
P.parent = null P.parent = null
@@ -76,7 +76,7 @@
possible_expansions -= borderline possible_expansions -= borderline
air.volume = volume air.set_volume(volume)
/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/components/C) /datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/components/C)
other_atmosmch |= C other_atmosmch |= C
@@ -99,7 +99,7 @@
merge(E) merge(E)
if(!members.Find(P)) if(!members.Find(P))
members += P members += P
air.volume += P.volume air.set_volume(air.return_volume() + P.volume)
else else
A.setPipenet(src, N) A.setPipenet(src, N)
addMachineryMember(A) addMachineryMember(A)
@@ -107,7 +107,7 @@
/datum/pipeline/proc/merge(datum/pipeline/E) /datum/pipeline/proc/merge(datum/pipeline/E)
if(E == src) if(E == src)
return return
air.volume += E.air.volume air.set_volume(air.return_volume() + E.air.return_volume())
members.Add(E.members) members.Add(E.members)
for(var/obj/machinery/atmospherics/pipe/S in E.members) for(var/obj/machinery/atmospherics/pipe/S in E.members)
S.parent = src S.parent = src
@@ -139,18 +139,16 @@
for(var/obj/machinery/atmospherics/pipe/member in members) for(var/obj/machinery/atmospherics/pipe/member in members)
member.air_temporary = new member.air_temporary = new
member.air_temporary.volume = member.volume member.air_temporary.set_volume(member.volume)
member.air_temporary.copy_from(air) member.air_temporary.copy_from(air)
var/member_gases = member.air_temporary.gases
for(var/id in member_gases) member.air_temporary.multiply(member.volume/air.return_volume())
member_gases[id] *= member.volume/air.volume
member.air_temporary.temperature = air.temperature member.air_temporary.set_temperature(air.return_temperature())
/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity) /datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
var/total_heat_capacity = air.heat_capacity() var/total_heat_capacity = air.heat_capacity()
var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume) var/partial_heat_capacity = total_heat_capacity*(share_volume/air.return_volume())
var/target_temperature var/target_temperature
var/target_heat_capacity var/target_heat_capacity
@@ -163,19 +161,19 @@
if(modeled_location.blocks_air) if(modeled_location.blocks_air)
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0)) if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
var/delta_temperature = air.temperature - target_temperature var/delta_temperature = air.return_temperature() - target_temperature
var/heat = thermal_conductivity*delta_temperature* \ var/heat = thermal_conductivity*delta_temperature* \
(partial_heat_capacity*target_heat_capacity/(partial_heat_capacity+target_heat_capacity)) (partial_heat_capacity*target_heat_capacity/(partial_heat_capacity+target_heat_capacity))
air.temperature -= heat/total_heat_capacity air.set_temperature(air.return_temperature() - heat/total_heat_capacity)
modeled_location.TakeTemperature(heat/target_heat_capacity) modeled_location.TakeTemperature(heat/target_heat_capacity)
else else
var/delta_temperature = 0 var/delta_temperature = 0
var/sharer_heat_capacity = 0 var/sharer_heat_capacity = 0
delta_temperature = (air.temperature - target_temperature) delta_temperature = (air.return_temperature() - target_temperature)
sharer_heat_capacity = target_heat_capacity sharer_heat_capacity = target_heat_capacity
var/self_temperature_delta = 0 var/self_temperature_delta = 0
@@ -190,18 +188,18 @@
else else
return 1 return 1
air.temperature += self_temperature_delta air.set_temperature(air.return_temperature() + self_temperature_delta)
modeled_location.TakeTemperature(sharer_temperature_delta) modeled_location.TakeTemperature(sharer_temperature_delta)
else else
if((target.heat_capacity>0) && (partial_heat_capacity>0)) if((target.heat_capacity>0) && (partial_heat_capacity>0))
var/delta_temperature = air.temperature - target.temperature var/delta_temperature = air.return_temperature() - target.return_temperature()
var/heat = thermal_conductivity*delta_temperature* \ var/heat = thermal_conductivity*delta_temperature* \
(partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity)) (partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
air.temperature -= heat/total_heat_capacity air.set_temperature(air.return_temperature() - heat/total_heat_capacity)
update = TRUE update = TRUE
/datum/pipeline/proc/return_air() /datum/pipeline/proc/return_air()
@@ -242,20 +240,18 @@
for(var/i in GL) for(var/i in GL)
var/datum/gas_mixture/G = i var/datum/gas_mixture/G = i
total_gas_mixture.volume += G.volume total_gas_mixture.set_volume(total_gas_mixture.return_volume() + G.return_volume())
total_gas_mixture.merge(G) total_gas_mixture.merge(G)
total_thermal_energy += THERMAL_ENERGY(G) total_thermal_energy += G.thermal_energy()
total_heat_capacity += G.heat_capacity() total_heat_capacity += G.heat_capacity()
total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0 total_gas_mixture.set_temperature(total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0)
if(total_gas_mixture.volume > 0) if(total_gas_mixture.return_volume() > 0)
//Update individual gas_mixtures by volume ratio //Update individual gas_mixtures by volume ratio
for(var/i in GL) for(var/i in GL)
var/datum/gas_mixture/G = i var/datum/gas_mixture/G = i
G.copy_from(total_gas_mixture) G.copy_from(total_gas_mixture)
var/list/G_gases = G.gases G.multiply(G.return_volume()/total_gas_mixture.return_volume())
for(var/id in G_gases)
G_gases[id] *= G.volume/total_gas_mixture.volume
@@ -103,7 +103,7 @@
if (target) if (target)
var/datum/gas_mixture/environment = target.return_air() var/datum/gas_mixture/environment = target.return_air()
if(environment) if(environment)
. = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)] K ([round(environment.temperature-T0C,0.01)]&deg;C)." . = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.return_temperature(),0.01)] K ([round(environment.return_temperature()-T0C,0.01)]&deg;C)."
else else
. = "The sensor error light is blinking." . = "The sensor error light is blinking."
else else
@@ -131,8 +131,8 @@
if(!isopenturf(O)) if(!isopenturf(O))
return FALSE return FALSE
var/datum/gas_mixture/merger = new var/datum/gas_mixture/merger = new
merger.gases[spawn_id] = (spawn_mol) merger.set_moles(spawn_id, spawn_mol)
merger.temperature = spawn_temp merger.set_temperature(spawn_temp)
O.assume_air(merger) O.assume_air(merger)
O.air_update_turf(TRUE) O.air_update_turf(TRUE)
@@ -28,14 +28,14 @@
if(islava(T)) if(islava(T))
environment_temperature = 5000 environment_temperature = 5000
else if(T.blocks_air) else if(T.blocks_air)
environment_temperature = T.temperature environment_temperature = T.return_temperature()
else else
var/turf/open/OT = T var/turf/open/OT = T
environment_temperature = OT.GetTemperature() environment_temperature = OT.GetTemperature()
else else
environment_temperature = T.temperature environment_temperature = T.return_temperature()
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) if(abs(environment_temperature-pipe_air.return_temperature()) > minimum_temperature_difference)
parent.temperature_interact(T, volume, thermal_conductivity) parent.temperature_interact(T, volume, thermal_conductivity)
@@ -44,11 +44,11 @@
var/hc = pipe_air.heat_capacity() var/hc = pipe_air.heat_capacity()
var/mob/living/heat_source = buckled_mobs[1] var/mob/living/heat_source = buckled_mobs[1]
//Best guess-estimate of the total bodytemperature of all the mobs, since they share the same environment it's ~ok~ to guess like this //Best guess-estimate of the total bodytemperature of all the mobs, since they share the same environment it's ~ok~ to guess like this
var/avg_temp = (pipe_air.temperature * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs ? buckled_mobs.len * 3500 : 0)) var/avg_temp = (pipe_air.return_temperature() * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs ? buckled_mobs.len * 3500 : 0))
for(var/m in buckled_mobs) for(var/m in buckled_mobs)
var/mob/living/L = m var/mob/living/L = m
L.bodytemperature = avg_temp L.bodytemperature = avg_temp
pipe_air.temperature = avg_temp pipe_air.set_temperature(avg_temp)
/obj/machinery/atmospherics/pipe/heat_exchanging/process() /obj/machinery/atmospherics/pipe/heat_exchanging/process()
if(!parent) if(!parent)
@@ -57,9 +57,9 @@
var/datum/gas_mixture/pipe_air = return_air() var/datum/gas_mixture/pipe_air = return_air()
//Heat causes pipe to glow //Heat causes pipe to glow
if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //glow starts at 500K if(pipe_air.return_temperature() && (icon_temperature > 500 || pipe_air.return_temperature() > 500)) //glow starts at 500K
if(abs(pipe_air.temperature - icon_temperature) > 10) if(abs(pipe_air.return_temperature() - icon_temperature) > 10)
icon_temperature = pipe_air.temperature icon_temperature = pipe_air.return_temperature()
var/h_r = heat2colour_r(icon_temperature) var/h_r = heat2colour_r(icon_temperature)
var/h_g = heat2colour_g(icon_temperature) var/h_g = heat2colour_g(icon_temperature)
@@ -76,7 +76,7 @@
//burn any mobs buckled based on temperature //burn any mobs buckled based on temperature
if(has_buckled_mobs()) if(has_buckled_mobs())
var/heat_limit = 1000 var/heat_limit = 1000
if(pipe_air.temperature > heat_limit + 1) if(pipe_air.return_temperature() > heat_limit + 1)
for(var/m in buckled_mobs) for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m var/mob/living/buckled_mob = m
buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BODY_ZONE_CHEST) buckled_mob.apply_damage(4 * log(pipe_air.return_temperature() - heat_limit), BURN, BODY_ZONE_CHEST)
@@ -200,14 +200,14 @@
/obj/machinery/portable_atmospherics/canister/proc/create_gas() /obj/machinery/portable_atmospherics/canister/proc/create_gas()
if(gas_type) if(gas_type)
if(starter_temp) if(starter_temp)
air_contents.temperature = starter_temp air_contents.set_temperature(starter_temp)
air_contents.gases[gas_type] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) air_contents.set_moles(gas_type,(maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
if(starter_temp) if(starter_temp)
air_contents.temperature = starter_temp air_contents.set_temperature(starter_temp)
/obj/machinery/portable_atmospherics/canister/air/create_gas() /obj/machinery/portable_atmospherics/canister/air/create_gas()
air_contents.gases[/datum/gas/oxygen] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) 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.gases[/datum/gas/nitrogen] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) air_contents.set_moles(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
/obj/machinery/portable_atmospherics/canister/update_icon_state() /obj/machinery/portable_atmospherics/canister/update_icon_state()
if(stat & BROKEN) if(stat & BROKEN)
@@ -397,8 +397,8 @@
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting a transfer into \the [holding || "air"].<br>" logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting a transfer into \the [holding || "air"].<br>"
if(!holding) if(!holding)
var/list/danger = list() var/list/danger = list()
for(var/id in air_contents.gases) for(var/id in air_contents.get_gases())
var/gas = air_contents.gases[id] var/gas = air_contents.get_moles(id)
if(!GLOB.meta_gas_dangers[id]) if(!GLOB.meta_gas_dangers[id])
continue continue
if(gas > (GLOB.meta_gas_visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility if(gas > (GLOB.meta_gas_visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
@@ -18,9 +18,8 @@
..() ..()
SSair.atmos_machinery += src SSair.atmos_machinery += src
air_contents = new air_contents = new(volume)
air_contents.volume = volume air_contents.set_temperature(T20C)
air_contents.temperature = T20C
return 1 return 1
@@ -115,8 +115,8 @@
if("power") if("power")
on = !on on = !on
if(on && !holding) if(on && !holding)
var/plasma = air_contents.gases[/datum/gas/plasma] var/plasma = air_contents.get_moles(/datum/gas/plasma)
var/n2o = air_contents.gases[/datum/gas/nitrous_oxide] var/n2o = air_contents.get_moles(/datum/gas/nitrous_oxide)
if(n2o || plasma) if(n2o || plasma)
message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [ADMIN_VERBOSEJMP(src)]") 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)]") log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [AREACOORD(src)]")
@@ -40,20 +40,13 @@
scrub(T.return_air()) scrub(T.return_air())
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture) /obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
var/transfer_moles = min(1, volume_rate / mixture.volume) * mixture.total_moles() var/transfer_moles = min(1, volume_rate / mixture.return_volume()) * mixture.total_moles()
var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter. var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
var/datum/gas_mixture/filtered = new
if(!filtering) if(!filtering)
return return
filtered.temperature = filtering.temperature filtering.scrub_into(air_contents,scrubbing)
for(var/gas in filtering.gases & scrubbing)
filtered.gases[gas] = filtering.gases[gas] // Shuffle the "bad" gasses to the filtered mixture.
filtering.gases[gas] = 0
GAS_GARBAGE_COLLECT(filtering.gases)
air_contents.merge(filtered) // Store filtered out gasses.
mixture.merge(filtering) // Returned the cleaned gas. mixture.merge(filtering) // Returned the cleaned gas.
if(!holding) if(!holding)
air_update_turf() air_update_turf()
+1 -3
View File
@@ -10,9 +10,7 @@
if(!..()) if(!..())
return FALSE return FALSE
var/obj/item/tank/T = O var/obj/item/tank/T = O
if(!T.air_contents.gases[gas_type]) return T.air_contents.get_moles(gas_type) >= moles_required
return FALSE
return T.air_contents.gases[gas_type] >= moles_required
//datum/bounty/item/engineering/gas/nitryl_tank //datum/bounty/item/engineering/gas/nitryl_tank
// name = "Full Tank of Nitryl" // name = "Full Tank of Nitryl"
+7 -9
View File
@@ -169,15 +169,13 @@
/datum/export/large/gas_canister/get_cost(obj/O) /datum/export/large/gas_canister/get_cost(obj/O)
var/obj/machinery/portable_atmospherics/canister/C = O var/obj/machinery/portable_atmospherics/canister/C = O
var/worth = 10 var/worth = 10
var/gases = C.air_contents.gases worth += C.air_contents.get_moles(/datum/gas/bz)*3
worth += C.air_contents.get_moles(/datum/gas/stimulum)*25
worth += gases[/datum/gas/bz]*3 worth += C.air_contents.get_moles(/datum/gas/hypernoblium)*1000
worth += gases[/datum/gas/stimulum]*25 worth += C.air_contents.get_moles(/datum/gas/miasma)*2
worth += gases[/datum/gas/hypernoblium]*1000 worth += C.air_contents.get_moles(/datum/gas/tritium)*7
worth += gases[/datum/gas/miasma]*2 worth += C.air_contents.get_moles(/datum/gas/pluoxium)*6
worth += gases[/datum/gas/tritium]*7 worth += C.air_contents.get_moles(/datum/gas/nitryl)*30
worth += gases[/datum/gas/pluoxium]*6
worth += gases[/datum/gas/nitryl]*30
return worth return worth
+4 -16
View File
@@ -171,10 +171,7 @@
var/turf/open/floor/T = holder.loc var/turf/open/floor/T = holder.loc
if(istype(T)) if(istype(T))
var/datum/gas_mixture/GM = T.air var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/oxygen]) GM.set_moles(/datum/gas/oxygen, max(GM.get_moles(/datum/gas/oxygen) - severity * holder.energy, 0))
return
GM.gases[/datum/gas/oxygen] = max(GM.gases[/datum/gas/oxygen] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/nitro_eater /datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming" name = "nitrogen consuming"
@@ -186,10 +183,7 @@
var/turf/open/floor/T = holder.loc var/turf/open/floor/T = holder.loc
if(istype(T)) if(istype(T))
var/datum/gas_mixture/GM = T.air var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/nitrogen]) GM.set_moles(/datum/gas/nitrogen, max(GM.get_moles(/datum/gas/nitrogen) - severity * holder.energy, 0))
return
GM.gases[/datum/gas/nitrogen] = max(GM.gases[/datum/gas/nitrogen] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/carbondioxide_eater /datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming" name = "CO2 consuming"
@@ -201,10 +195,7 @@
var/turf/open/floor/T = holder.loc var/turf/open/floor/T = holder.loc
if(istype(T)) if(istype(T))
var/datum/gas_mixture/GM = T.air var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/carbon_dioxide]) GM.set_moles(/datum/gas/carbon_dioxide, max(GM.get_moles(/datum/gas/carbon_dioxide) - severity * holder.energy, 0))
return
GM.gases[/datum/gas/carbon_dioxide] = max(GM.gases[/datum/gas/carbon_dioxide] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/plasma_eater /datum/spacevine_mutation/plasma_eater
name = "toxins consuming" name = "toxins consuming"
@@ -216,10 +207,7 @@
var/turf/open/floor/T = holder.loc var/turf/open/floor/T = holder.loc
if(istype(T)) if(istype(T))
var/datum/gas_mixture/GM = T.air var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/plasma]) GM.set_moles(/datum/gas/plasma, max(GM.get_moles(/datum/gas/plasma) - severity * holder.energy, 0))
return
GM.gases[/datum/gas/plasma] = max(GM.gases[/datum/gas/plasma] - severity * holder.energy, 0)
GAS_GARBAGE_COLLECT(GM.gases)
/datum/spacevine_mutation/thorns /datum/spacevine_mutation/thorns
name = "thorny" name = "thorny"
+2 -2
View File
@@ -57,8 +57,8 @@
return return
var/datum/gas_mixture/stank = new var/datum/gas_mixture/stank = new
stank.gases[/datum/gas/miasma] = (yield + 6)*7*0.02 // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses stank.adjust_moles(/datum/gas/miasma,(yield + 6)*7*0.02) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
stank.temperature = T20C // without this the room would eventually freeze and miasma mining would be easier stank.set_temperature(T20C) // without this the room would eventually freeze and miasma mining would be easier
T.assume_air(stank) T.assume_air(stank)
T.air_update_turf() T.air_update_turf()
+2 -2
View File
@@ -226,8 +226,8 @@
if(isopenturf(loc)) if(isopenturf(loc))
var/turf/open/O = loc var/turf/open/O = loc
if(O.air) if(O.air)
var/loc_gases = O.air.gases var/datum/gas_mixture/loc_air = O.air
if(loc_gases[/datum/gas/oxygen] > 13) if(loc_air.get_moles(/datum/gas/oxygen) > 13)
return TRUE return TRUE
return FALSE return FALSE
@@ -125,12 +125,12 @@
return return
// Negative Kelvin temperatures should never happen and if they do, normalize them // Negative Kelvin temperatures should never happen and if they do, normalize them
if(source_air.temperature < TCMB) if(source_air.return_temperature() < TCMB)
source_air.temperature = TCMB source_air.set_temperature(TCMB)
var/pressure_delta = target_pressure - target_air.return_pressure() var/pressure_delta = target_pressure - target_air.return_pressure()
if(pressure_delta > 0.1) if(pressure_delta > 0.1)
var/transfer_moles = (pressure_delta*target_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY var/transfer_moles = (pressure_delta*target_air.return_volume()/(source_air.return_temperature() * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
var/datum/gas_mixture/removed = source_air.remove(transfer_moles) var/datum/gas_mixture/removed = source_air.remove(transfer_moles)
target_air.merge(removed) target_air.merge(removed)
@@ -171,14 +171,14 @@
return return
// Negative Kelvin temperatures should never happen and if they do, normalize them // Negative Kelvin temperatures should never happen and if they do, normalize them
if(source_air.temperature < TCMB) if(source_air.return_temperature() < TCMB)
source_air.temperature = TCMB source_air.set_temperature(TCMB)
if((source_air.return_pressure() < 0.01) || (target_air.return_pressure() >= PUMP_MAX_PRESSURE)) if((source_air.return_pressure() < 0.01) || (target_air.return_pressure() >= PUMP_MAX_PRESSURE))
return return
//The second part of the min caps the pressure built by the volume pumps to the max pump pressure //The second part of the min caps the pressure built by the volume pumps to the max pump pressure
var/transfer_ratio = min(transfer_rate,target_air.volume*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.volume var/transfer_ratio = min(transfer_rate,target_air.return_volume()*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.return_volume()
var/datum/gas_mixture/removed = source_air.remove_ratio(transfer_ratio * PUMP_EFFICIENCY) var/datum/gas_mixture/removed = source_air.remove_ratio(transfer_ratio * PUMP_EFFICIENCY)
@@ -351,10 +351,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
var/transfer_moles var/transfer_moles
//Negative Kelvins are an anomaly and should be normalized if encountered //Negative Kelvins are an anomaly and should be normalized if encountered
if(source_air.temperature < TCMB) if(source_air.return_temperature(TCMB))
source_air.temperature = TCMB source_air.set_temperature(TCMB)
transfer_moles = (pressure_delta*contaminated_air.volume/(source_air.temperature * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY transfer_moles = (pressure_delta*contaminated_air.return_volume()/(source_air.return_temperature() * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
//If there is nothing to transfer, just return //If there is nothing to transfer, just return
if(transfer_moles <= 0) if(transfer_moles <= 0)
@@ -368,16 +368,15 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
//This is the gas that will be moved from source to filtered //This is the gas that will be moved from source to filtered
var/datum/gas_mixture/filtered_out = new var/datum/gas_mixture/filtered_out = new
for(var/filtered_gas in removed.gases) for(var/filtered_gas in removed.get_gases())
//Get the name of the gas and see if it is in the list //Get the name of the gas and see if it is in the list
if(GLOB.meta_gas_names[filtered_gas] in wanted) if(GLOB.meta_gas_names[filtered_gas] in wanted)
//The gas that is put in all the filtered out gases //The gas that is put in all the filtered out gases
filtered_out.temperature = removed.temperature filtered_out.set_temperature(removed.return_temperature())
filtered_out.gases[filtered_gas] = removed.gases[filtered_gas] filtered_out.set_moles(filtered_gas, removed.get_moles(filtered_gas))
//The filtered out gas is entirely removed from the currently filtered gases //The filtered out gas is entirely removed from the currently filtered gases
removed.gases[filtered_gas] = 0 removed.set_moles(filtered_gas, 0)
GAS_GARBAGE_COLLECT(removed.gases)
//Check if the pressure is high enough to put stuff in filtered, or else just put it back in the source //Check if the pressure is high enough to put stuff in filtered, or else just put it back in the source
var/datum/gas_mixture/target = (filtered_air.return_pressure() < target_pressure ? filtered_air : source_air) var/datum/gas_mixture/target = (filtered_air.return_pressure() < target_pressure ? filtered_air : source_air)
@@ -444,7 +443,7 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
var/gas_percentage = round(max(min(get_pin_data(IC_INPUT, 4),100),0) / 100) var/gas_percentage = round(max(min(get_pin_data(IC_INPUT, 4),100),0) / 100)
//Basically: number of moles = percentage of pressure filled up * efficiency coefficient * (pressure from both gases * volume of output) / (R * Temperature) //Basically: number of moles = percentage of pressure filled up * efficiency coefficient * (pressure from both gases * volume of output) / (R * Temperature)
var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.volume/ (R_IDEAL_GAS_EQUATION * max(output_gases.temperature,TCMB)) var/transfer_moles = (get_pin_data(IC_INPUT, 5) / max(1,output_gases.return_pressure())) * PUMP_EFFICIENCY * (source_1_gases.return_pressure() * gas_percentage + source_2_gases.return_pressure() * (1 - gas_percentage)) * output_gases.return_volume()/ (R_IDEAL_GAS_EQUATION * max(output_gases.return_temperature(),TCMB))
if(transfer_moles <= 0) if(transfer_moles <= 0)
@@ -544,10 +543,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
push_data() push_data()
//Cool the tank if the power is on and the temp is above //Cool the tank if the power is on and the temp is above
if(!power_draw_idle || air_contents.temperature < temperature) if(!power_draw_idle || air_contents.return_temperature() < temperature)
return return
air_contents.temperature = max(73.15,air_contents.temperature - (air_contents.temperature - temperature) * heater_coefficient) air_contents.set_temperature(max(73.15,air_contents.return_temperature() - (air_contents.return_temperature() - temperature) * heater_coefficient))
// - heater tank - // **works** // - heater tank - // **works**
@@ -574,10 +573,10 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
push_data() push_data()
//Heat the tank if the power is on or its temperature is below what is set //Heat the tank if the power is on or its temperature is below what is set
if(!power_draw_idle || air_contents.temperature > temperature) if(!power_draw_idle || air_contents.return_temperature() > temperature)
return return
air_contents.temperature = min(573.15,air_contents.temperature + (temperature - air_contents.temperature) * heater_coefficient) air_contents.set_temperature(min(573.15,air_contents.return_temperature() + (temperature - air_contents.return_temperature()) * heater_coefficient))
// - atmospheric cooler - // **works** // - atmospheric cooler - // **works**
@@ -621,11 +620,11 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
return return
var/datum/gas_mixture/turf_air = current_turf.return_air() var/datum/gas_mixture/turf_air = current_turf.return_air()
if(!power_draw_idle || turf_air.temperature < temperature) if(!power_draw_idle || turf_air.return_temperature() < temperature)
return return
//Cool the gas //Cool the gas
turf_air.temperature = max(243.15,turf_air.temperature - (turf_air.temperature - temperature) * heater_coefficient) turf_air.set_temperature(max(243.15,turf_air.return_temperature() - (turf_air.return_temperature() - temperature) * heater_coefficient))
// - atmospheric heater - // **works** // - atmospheric heater - // **works**
@@ -650,11 +649,11 @@ obj/item/integrated_circuit/atmospherics/connector/portableConnectorReturnAir()
return return
var/datum/gas_mixture/turf_air = current_turf.return_air() var/datum/gas_mixture/turf_air = current_turf.return_air()
if(!power_draw_idle || turf_air.temperature > temperature) if(!power_draw_idle || turf_air.return_temperature() > temperature)
return return
//Heat the gas //Heat the gas
turf_air.temperature = min(323.15,turf_air.temperature + (temperature - turf_air.temperature) * heater_coefficient) turf_air.set_temperature(min(323.15,turf_air.return_temperature() + (temperature - turf_air.return_temperature()) * heater_coefficient))
// - tank slot - // **works** // - tank slot - // **works**
@@ -1162,12 +1162,11 @@
activate_pin(3) activate_pin(3)
return return
var/list/gases = air_contents.gases
var/list/gas_names = list() var/list/gas_names = list()
var/list/gas_amounts = list() var/list/gas_amounts = list()
for(var/id in gases) for(var/id in air_contents.get_gases())
var/name = GLOB.meta_gas_names[id] var/name = GLOB.meta_gas_names[id]
var/amt = round(gases[id], 0.001) var/amt = round(air_contents.get_moles(id), 0.001)
gas_names.Add(name) gas_names.Add(name)
gas_amounts.Add(amt) gas_amounts.Add(amt)
@@ -1175,7 +1174,7 @@
set_pin_data(IC_OUTPUT, 2, gas_amounts) set_pin_data(IC_OUTPUT, 2, gas_amounts)
set_pin_data(IC_OUTPUT, 3, round(air_contents.total_moles(), 0.001)) set_pin_data(IC_OUTPUT, 3, round(air_contents.total_moles(), 0.001))
set_pin_data(IC_OUTPUT, 4, round(air_contents.return_pressure(), 0.001)) set_pin_data(IC_OUTPUT, 4, round(air_contents.return_pressure(), 0.001))
set_pin_data(IC_OUTPUT, 5, round(air_contents.temperature, 0.001)) set_pin_data(IC_OUTPUT, 5, round(air_contents.return_temperature(), 0.001))
set_pin_data(IC_OUTPUT, 6, round(air_contents.return_volume(), 0.001)) set_pin_data(IC_OUTPUT, 6, round(air_contents.return_volume(), 0.001))
push_data() push_data()
activate_pin(2) activate_pin(2)
+7
View File
@@ -213,6 +213,7 @@
var/list/modelCache = build_cache(no_changeturf) var/list/modelCache = build_cache(no_changeturf)
var/space_key = modelCache[SPACE_KEY] var/space_key = modelCache[SPACE_KEY]
var/list/bounds var/list/bounds
var/did_expand = FALSE
src.bounds = bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) src.bounds = bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
var/datum/map_orientation_pattern/mode = forced_pattern || GLOB.map_orientation_patterns["[orientation]"] || GLOB.map_orientation_patterns["[SOUTH]"] var/datum/map_orientation_pattern/mode = forced_pattern || GLOB.map_orientation_patterns["[orientation]"] || GLOB.map_orientation_patterns["[SOUTH]"]
var/invert_y = mode.invert_y var/invert_y = mode.invert_y
@@ -235,6 +236,7 @@
else else
while(parsed_z > world.maxz) while(parsed_z > world.maxz)
world.incrementMaxZ() world.incrementMaxZ()
did_expand = TRUE
if(!no_changeturf) if(!no_changeturf)
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called") WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
//these values are the same until a new gridset is reached. //these values are the same until a new gridset is reached.
@@ -256,11 +258,13 @@
continue continue
else else
world.maxx = placement_x world.maxx = placement_x
did_expand = TRUE
if(placement_y > world.maxy) if(placement_y > world.maxy)
if(cropMap) if(cropMap)
break break
else else
world.maxy = placement_y world.maxy = placement_y
did_expand = TRUE
if(placement_x < 1) if(placement_x < 1)
actual_x += xi actual_x += xi
continue continue
@@ -301,6 +305,9 @@
testing("Skipped loading [turfsSkipped] default turfs") testing("Skipped loading [turfsSkipped] default turfs")
#endif #endif
if(did_expand)
world.refresh_atmos_grid()
return TRUE return TRUE
/datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null) /datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null)
@@ -7,6 +7,20 @@
return get_step(SSmapping.get_turf_below(get_turf(ref)), dir) return get_step(SSmapping.get_turf_below(get_turf(ref)), dir)
return get_step(ref, dir) return get_step(ref, dir)
/proc/get_multiz_accessible_levels(center_z)
. = list(center_z)
var/other_z = center_z
var/offset
while((offset = SSmapping.level_trait(other_z, ZTRAIT_DOWN)))
other_z += offset
. += other_z
other_z = center_z
while((offset = SSmapping.level_trait(other_z, ZTRAIT_UP)))
other_z += offset
. += other_z
return .
/proc/get_dir_multiz(turf/us, turf/them) /proc/get_dir_multiz(turf/us, turf/them)
us = get_turf(us) us = get_turf(us)
them = get_turf(them) them = get_turf(them)
@@ -33,15 +47,3 @@
/turf/proc/below() /turf/proc/below()
return get_step_multiz(src, DOWN) return get_step_multiz(src, DOWN)
/proc/dir_inverse_multiz(dir)
var/holder = dir & (UP|DOWN)
if((holder == NONE) || (holder == (UP|DOWN)))
return turn(dir, 180)
dir &= ~(UP|DOWN)
dir = turn(dir, 180)
if(holder == UP)
holder = DOWN
else
holder = UP
dir |= holder
return dir
+6 -9
View File
@@ -13,26 +13,23 @@
var/toxins_used = 0 var/toxins_used = 0
var/tox_detect_threshold = 0.02 var/tox_detect_threshold = 0.02
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
var/list/breath_gases = breath.gases
//Partial pressure of the toxins in our breath //Partial pressure of the toxins in our breath
var/Toxins_pp = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure var/Toxins_pp = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
adjustPlasma(breath_gases[/datum/gas/plasma]*250) adjustPlasma(breath.get_moles(/datum/gas/plasma)*250)
throw_alert("alien_tox", /obj/screen/alert/alien_tox) throw_alert("alien_tox", /obj/screen/alert/alien_tox)
toxins_used = breath_gases[/datum/gas/plasma] toxins_used = breath.get_moles(/datum/gas/plasma)
else else
clear_alert("alien_tox") clear_alert("alien_tox")
//Breathe in toxins and out oxygen //Breathe in toxins and out oxygen
breath_gases[/datum/gas/plasma] -= toxins_used breath.adjust_moles(/datum/gas/plasma, -toxins_used)
breath_gases[/datum/gas/oxygen] += toxins_used breath.adjust_moles(/datum/gas/oxygen, toxins_used)
GAS_GARBAGE_COLLECT(breath.gases)
//BREATH TEMPERATURE //BREATH TEMPERATURE
handle_breath_temperature(breath) handle_breath_temperature(breath)
@@ -33,7 +33,7 @@
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed) if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment) if(environment)
if(environment.total_moles()) if(environment.total_moles())
if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen]) >= 1) //Same threshhold that extinguishes fire if(environment.get_moles(/datum/gas/oxygen) >= 1) //Same threshhold that extinguishes fire
H.adjust_fire_stacks(0.5) H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0) if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>") H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
+21 -27
View File
@@ -162,12 +162,11 @@
var/SA_para_min = 1 var/SA_para_min = 1
var/SA_sleep_min = 5 var/SA_sleep_min = 5
var/oxygen_used = 0 var/oxygen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
var/list/breath_gases = breath.gases var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
var/O2_partialpressure = (breath_gases[/datum/gas/oxygen]/breath.total_moles())*breath_pressure var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide]/breath.total_moles())*breath_pressure
//OXYGEN //OXYGEN
@@ -191,7 +190,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3)) adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1 failed_last_breath = 1
oxygen_used = breath_gases[/datum/gas/oxygen]*ratio oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
else else
adjustOxyLoss(3) adjustOxyLoss(3)
failed_last_breath = 1 failed_last_breath = 1
@@ -203,12 +202,12 @@
o2overloadtime = 0 //reset our counter for this too o2overloadtime = 0 //reset our counter for this too
if(health >= crit_threshold) if(health >= crit_threshold)
adjustOxyLoss(-5) adjustOxyLoss(-5)
oxygen_used = breath_gases[/datum/gas/oxygen] oxygen_used = breath.get_moles(/datum/gas/oxygen)
clear_alert("not_enough_oxy") clear_alert("not_enough_oxy")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
breath_gases[/datum/gas/oxygen] -= oxygen_used breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
breath_gases[/datum/gas/carbon_dioxide] += oxygen_used breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
//CARBON DIOXIDE //CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max) if(CO2_partialpressure > safe_co2_max)
@@ -227,15 +226,15 @@
//TOXINS/PLASMA //TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max) if(Toxins_partialpressure > safe_tox_max)
var/ratio = (breath_gases[/datum/gas/plasma]/safe_tox_max) * 10 var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_tox_max) * 10
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE)) adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else else
clear_alert("too_much_tox") clear_alert("too_much_tox")
//NITROUS OXIDE //NITROUS OXIDE
if(breath_gases[/datum/gas/nitrous_oxide]) if(breath.get_moles(/datum/gas/nitrous_oxide))
var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide]/breath.total_moles())*breath_pressure var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min) if(SA_partialpressure > SA_para_min)
Unconscious(60) Unconscious(60)
if(SA_partialpressure > SA_sleep_min) if(SA_partialpressure > SA_sleep_min)
@@ -248,26 +247,26 @@
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria")
//BZ (Facepunch port of their Agent B) //BZ (Facepunch port of their Agent B)
if(breath_gases[/datum/gas/bz]) if(breath.get_moles(/datum/gas/bz))
var/bz_partialpressure = (breath_gases[/datum/gas/bz]/breath.total_moles())*breath_pressure var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
if(bz_partialpressure > 1) if(bz_partialpressure > 1)
hallucination += 10 hallucination += 10
else if(bz_partialpressure > 0.01) else if(bz_partialpressure > 0.01)
hallucination += 5 hallucination += 5
//TRITIUM //TRITIUM
if(breath_gases[/datum/gas/tritium]) if(breath.get_moles(/datum/gas/tritium))
var/tritium_partialpressure = (breath_gases[/datum/gas/tritium]/breath.total_moles())*breath_pressure var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
radiation += tritium_partialpressure/10 radiation += tritium_partialpressure/10
//NITRYL //NITRYL
if(breath_gases[/datum/gas/nitryl]) if(breath.get_moles(/datum/gas/nitryl))
var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl]/breath.total_moles())*breath_pressure var/nitryl_partialpressure = (breath.get_moles(/datum/gas/nitryl)/breath.total_moles())*breath_pressure
adjustFireLoss(nitryl_partialpressure/4) adjustFireLoss(nitryl_partialpressure/4)
//MIASMA //MIASMA
if(breath_gases[/datum/gas/miasma]) if(breath.get_moles(/datum/gas/miasma))
var/miasma_partialpressure = (breath_gases[/datum/gas/miasma]/breath.total_moles())*breath_pressure var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE) if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE)
if(prob(0.05 * miasma_partialpressure)) if(prob(0.05 * miasma_partialpressure))
@@ -307,11 +306,6 @@
else else
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
GAS_GARBAGE_COLLECT(breath.gases)
//BREATH TEMPERATURE //BREATH TEMPERATURE
handle_breath_temperature(breath) handle_breath_temperature(breath)
@@ -370,9 +364,9 @@
var/datum/gas_mixture/stank = new var/datum/gas_mixture/stank = new
stank.gases[/datum/gas/miasma] = 0.1 stank.set_moles(/datum/gas/miasma,0.1)
stank.temperature = BODYTEMP_NORMAL stank.set_temperature(BODYTEMP_NORMAL)
miasma_turf.assume_air(stank) miasma_turf.assume_air(stank)
@@ -46,8 +46,8 @@
return ..() return ..()
/mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath) /mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath)
if(abs(BODYTEMP_NORMAL - breath.temperature) > 50) if(abs(BODYTEMP_NORMAL - breath.return_temperature()) > 50)
switch(breath.temperature) switch(breath.return_temperature())
if(-INFINITY to 120) if(-INFINITY to 120)
adjustFireLoss(3) adjustFireLoss(3)
if(120 to 200) if(120 to 200)
+1 -1
View File
@@ -134,7 +134,7 @@
ExtinguishMob() ExtinguishMob()
return return
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G.gases[/datum/gas/oxygen] < 1) if(G.get_moles(/datum/gas/oxygen, 1))
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return return
var/turf/location = get_turf(src) var/turf/location = get_turf(src)
+1 -1
View File
@@ -914,7 +914,7 @@
floating_need_update = TRUE floating_need_update = TRUE
/mob/living/proc/get_temperature(datum/gas_mixture/environment) /mob/living/proc/get_temperature(datum/gas_mixture/environment)
var/loc_temp = environment ? environment.temperature : T0C var/loc_temp = environment ? environment.return_temperature() : T0C
if(isobj(loc)) if(isobj(loc))
var/obj/oloc = loc var/obj/oloc = loc
var/obj_temp = oloc.return_temperature() var/obj_temp = oloc.return_temperature()
@@ -565,7 +565,6 @@
dat += "Unable to obtain a reading.<br>" dat += "Unable to obtain a reading.<br>"
else else
var/datum/gas_mixture/environment = T.return_air() var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.gases
var/pressure = environment.return_pressure() var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles() var/total_moles = environment.total_moles()
@@ -573,11 +572,11 @@
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>" dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles) if (total_moles)
for(var/id in env_gases) for(var/id in environment.get_gases())
var/gas_level = env_gases[id]/total_moles var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0.01) if(gas_level > 0.01)
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%<br>" dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>" dat += "Temperature: [round(environment.return_temperature()-T0C)]&deg;C<br>"
dat += "<a href='byond://?src=[REF(src)];software=atmosensor;sub=0'>Refresh Reading</a> <br>" dat += "<a href='byond://?src=[REF(src)];software=atmosensor;sub=0'>Refresh Reading</a> <br>"
dat += "<br>" dat += "<br>"
return dat return dat
@@ -49,12 +49,12 @@
return return
if(isopenturf(loc)) if(isopenturf(loc))
var/turf/open/T = src.loc var/turf/open/T = src.loc
if(T.air && T.air.gases[/datum/gas/carbon_dioxide]) if(T.air)
var/co2 = T.air.gases[/datum/gas/carbon_dioxide] var/co2 = T.air.get_moles(/datum/gas/carbon_dioxide)
if(co2 > 0) if(co2 > 0)
if(prob(25)) if(prob(25))
var/amt = min(co2, 9) var/amt = min(co2, 9)
T.air.gases[/datum/gas/carbon_dioxide] -= amt T.air.adjust_moles(/datum/gas/carbon_dioxide, -amt)
T.atmos_spawn_air("o2=[amt]") T.atmos_spawn_air("o2=[amt]")
/mob/living/simple_animal/hostile/tree/AttackingTarget() /mob/living/simple_animal/hostile/tree/AttackingTarget()
@@ -252,14 +252,11 @@
if(isturf(src.loc) && isopenturf(src.loc)) if(isturf(src.loc) && isopenturf(src.loc))
var/turf/open/ST = src.loc var/turf/open/ST = src.loc
if(ST.air) if(ST.air)
var/ST_gases = ST.air.gases
var/tox = ST_gases[/datum/gas/plasma] var/tox = ST.air.get_moles(/datum/gas/plasma)
var/oxy = ST_gases[/datum/gas/oxygen] var/oxy = ST.air.get_moles(/datum/gas/oxygen)
var/n2 = ST_gases[/datum/gas/nitrogen] var/n2 = ST.air.get_moles(/datum/gas/nitrogen)
var/co2 = ST_gases[/datum/gas/carbon_dioxide] var/co2 = ST.air.get_moles(/datum/gas/carbon_dioxide)
GAS_GARBAGE_COLLECT(ST.air.gases)
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"]) if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
. = FALSE . = FALSE
@@ -128,9 +128,7 @@
Tempstun = 0 Tempstun = 0
if(stat != DEAD) if(stat != DEAD)
var/bz_percentage =0 var/bz_percentage = environment.total_moles() ? (environment.get_moles(/datum/gas/bz) / environment.total_moles()) : 0
if(environment.gases[/datum/gas/bz])
bz_percentage = environment.gases[/datum/gas/bz] / environment.total_moles()
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
if(stat == CONSCIOUS && stasis) if(stat == CONSCIOUS && stasis)

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