C++ Monstermos - Putting the 99% LAG FREE in 99% LAG FREE (#7981)

* c++ monstermos

fuck

Fixes the server hemorrhaging memory due to extools not decrementing ref counts

Increases defauilt tank pressure

make space cold or some shit

floor tile rips

Fixes code assuming that the heat capacity is nonzero

🤦

Fixes crash

fixes some bugs

fuck *facepalm*

the fastening

removes Del() in favor of an internal c++ hook

Fixes vent-pump math

* Fix the invisible gases bug

* Linux support

* fix the deploy.sh

* Uses newer BYOND 513 because older one is probably missing an important pattern (it segfaulted on pattern search)

* Updates windows dll to match linux version and cleans up unused BYOND code
This commit is contained in:
monster860
2020-04-24 10:29:51 -04:00
committed by GitHub
parent 8c819b972c
commit bf810f49c2
110 changed files with 779 additions and 1806 deletions

1
.gitignore vendored
View File

@@ -214,5 +214,4 @@ tools/MapAtmosFixer/MapAtmosFixer/bin/*
*.orig
#Debugging and other stuff
byond-extools.dll
extools.dll

View File

@@ -1,4 +1,4 @@
FROM tgstation/byond:513.1490 as base
FROM tgstation/byond:513.1519 as base
FROM base as build_base

BIN
byond-extools.dll Normal file

Binary file not shown.

BIN
byond-extools.pdb Normal file

Binary file not shown.

View File

@@ -140,7 +140,7 @@
#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold
#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3)
#define TANK_MIN_RELEASE_PRESSURE 0
#define TANK_DEFAULT_RELEASE_PRESSURE 16
#define TANK_DEFAULT_RELEASE_PRESSURE 17
//CANATMOSPASS
#define ATMOS_PASS_YES 1
@@ -275,20 +275,6 @@
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define ADD_GAS(gas_id, out_list)\
var/list/tmp_gaslist = GLOB.gaslist_cache[gas_id]; out_list[gas_id] = tmp_gaslist.Copy();
#define ASSERT_GAS(gas_id, gas_mixture) if (!gas_mixture.gases[gas_id]) { ADD_GAS(gas_id, gas_mixture.gases) };
//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][MOLES];\
}
#ifdef TESTING
GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 }
@@ -296,6 +282,17 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
#endif
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(world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")){\
var/result = call((world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so"),"init_monstermos")();\
if(result != "ok") {CRASH(result);}\
} else {\
CRASH("byond-extools.dll does not exist!");\
}\
}
GLOBAL_LIST_INIT(pipe_paint_colors, list(
"amethyst" = rgb(130,43,255), //supplymain
"blue" = rgb(0,0,255),

View File

@@ -24,7 +24,6 @@ SUBSYSTEM_DEF(air)
var/cost_atmos_machinery = 0
var/cost_equalize = 0
var/list/excited_groups = list()
var/list/active_turfs = list()
var/list/hotspots = list()
var/list/networks = list()
@@ -59,7 +58,7 @@ SUBSYSTEM_DEF(air)
msg += "AM:[round(cost_atmos_machinery,1)]"
msg += "} "
msg += "AT:[active_turfs.len]|"
msg += "EG:[excited_groups.len]|"
msg += "EG:[get_amt_excited_groups()]|"
msg += "HS:[hotspots.len]|"
msg += "PN:[networks.len]|"
msg += "HP:[high_pressure_delta.len]|"
@@ -67,8 +66,8 @@ SUBSYSTEM_DEF(air)
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
..(msg)
/datum/controller/subsystem/air/Initialize(timeofday)
extools_update_ssair()
map_loading = FALSE
setup_allturfs()
setup_atmos_machinery()
@@ -76,6 +75,7 @@ SUBSYSTEM_DEF(air)
gas_reactions = init_gas_reactions()
return ..()
/datum/controller/subsystem/air/proc/extools_update_ssair()
/datum/controller/subsystem/air/fire(resumed = 0)
var/timer = TICK_USAGE_REAL
@@ -233,7 +233,8 @@ SUBSYSTEM_DEF(air)
var/turf/open/T = currentrun[currentrun.len]
currentrun.len--
if (T)
equalize_pressure_in_zone(T, fire_count)
T.equalize_pressure_in_zone(fire_count)
//equalize_pressure_in_zone(T, fire_count)
if (MC_TICK_CHECK)
return
@@ -253,6 +254,9 @@ SUBSYSTEM_DEF(air)
return
/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)
src.currentrun = excited_groups.Copy()
//cache for sanic speed (lists are references anyways)
@@ -268,7 +272,10 @@ SUBSYSTEM_DEF(air)
EG.dismantle()
if (MC_TICK_CHECK)
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)
active_turfs -= T
@@ -278,21 +285,20 @@ SUBSYSTEM_DEF(air)
T.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#00ff00")
#endif
if(istype(T))
T.excited = 0
if(T.excited_group)
T.excited_group.garbage_collect()
T.set_excited(FALSE)
T.eg_garbage_collect()
/datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
if(istype(T) && T.air)
#ifdef VISUALIZE_ACTIVE_TURFS
T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY)
#endif
T.excited = 1
T.set_excited(TRUE)
active_turfs |= T
if(currentpart == SSAIR_ACTIVETURFS)
currentrun |= T
if(blockchanges && T.excited_group)
T.excited_group.garbage_collect()
if(blockchanges)
T.eg_garbage_collect()
else if(T.flags_1 & INITIALIZED_1)
for(var/turf/S in T.atmos_adjacent_turfs)
add_to_active(S)
@@ -350,11 +356,11 @@ SUBSYSTEM_DEF(air)
while (turfs_to_check.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
EG.self_breakdown(space_is_all_consuming = 1)
EG.dismantle()
CHECK_TICK
//EG.self_breakdown(space_is_all_consuming = 1)
//EG.dismantle()
CHECK_TICK*/
var/msg = "HEY! LISTEN! [DisplayTimeText(world.timeofday - timer)] were wasted processing [starting_ats] turf(s) (connected to [ending_ats] other turfs) with atmos differences at round start."
to_chat(world, "<span class='boldannounce'>[msg]</span>")
@@ -362,6 +368,7 @@ SUBSYSTEM_DEF(air)
/turf/open/proc/resolve_active_graph()
. = list()
/*
var/datum/excited_group/EG = excited_group
if (blocks_air || !air)
return
@@ -382,7 +389,8 @@ SUBSYSTEM_DEF(air)
EG.add_turf(ET)
if (!ET.excited)
ET.excited = 1
. += ET
. += ET*/
/turf/open/space/resolve_active_graph()
return list()

View File

@@ -18,22 +18,19 @@
return
var/datum/gas_mixture/turf_air = T.return_air()
var/datum/gas_mixture/stank_breath = T.remove_air(1 / turf_air.volume * turf_air.total_moles())
var/datum/gas_mixture/stank_breath = T.remove_air(1 / turf_air.return_volume() * turf_air.total_moles())
if(!stank_breath)
return
stank_breath.volume = 1
var/oxygen_pp = 0
if(stank_breath.gases[/datum/gas/oxygen])
oxygen_pp = stank_breath.gases[/datum/gas/oxygen][MOLES] * R_IDEAL_GAS_EQUATION * stank_breath.temperature / stank_breath.volume
stank_breath.set_volume(1)
var/oxygen_pp = stank_breath.get_moles(/datum/gas/oxygen) * R_IDEAL_GAS_EQUATION * stank_breath.return_temperature() / stank_breath.return_volume()
if(oxygen_pp > 18)
var/this_amount = min((oxygen_pp - 8) * stank_breath.volume / stank_breath.temperature / R_IDEAL_GAS_EQUATION, amount)
stank_breath.gases[/datum/gas/oxygen][MOLES] -= this_amount
var/this_amount = min((oxygen_pp - 8) * stank_breath.return_volume() / stank_breath.return_temperature() / R_IDEAL_GAS_EQUATION, amount)
stank_breath.adjust_moles(/datum/gas/oxygen, -this_amount)
var/datum/gas_mixture/stank = new
ADD_GAS(/datum/gas/miasma, stank.gases)
stank.gases[/datum/gas/miasma][MOLES] = this_amount
stank.temperature = BODYTEMP_NORMAL // otherwise we have gas below 2.7K which will break our lag generator
stank.set_moles(/datum/gas/miasma, this_amount)
stank.set_temperature(BODYTEMP_NORMAL) // otherwise we have gas below 2.7K which will break our lag generator
stank_breath.merge(stank)
T.assume_air(stank_breath)
T.air_update_turf()

View File

@@ -118,7 +118,7 @@
if(-INFINITY to T0C)
add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice!
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)
decrease = INFINITY
decrease = max(0, decrease)

View File

@@ -381,15 +381,13 @@
/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A)
var/mob/living/M = A.affected_mob
var/datum/gas_mixture/environment
var/list/gases
. = 0
if(M.loc)
environment = M.loc.return_air()
if(environment)
gases = environment.gases
if(gases["plasma"] && gases["plasma"][MOLES] > gases["plasma"][GAS_META][META_GAS_MOLES_VISIBLE]) //if there's enough plasma in the air to see
if(environment.get_moles(/datum/gas/plasma) > GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_MOLES_VISIBLE]) //if there's enough plasma in the air to see
. += power * 0.5
if(M.reagents.has_reagent(/datum/reagent/toxin/plasma, needs_metabolizing = TRUE))
. += power * 0.75

View File

@@ -116,9 +116,8 @@
continue
var/datum/gas_mixture/A = F.air
var/list/A_gases = A.gases
var/trace_gases
for(var/id in A_gases)
for(var/id in A.get_gases())
if(id in GLOB.hardcoded_gases)
continue
trace_gases = TRUE
@@ -127,15 +126,15 @@
// Can most things breathe?
if(trace_gases)
continue
if(!(A_gases[/datum/gas/oxygen] && A_gases[/datum/gas/oxygen][MOLES] >= 16))
if(A.get_moles(/datum/gas/oxygen) < 16)
continue
if(A_gases[/datum/gas/plasma])
if(A.get_moles(/datum/gas/plasma))
continue
if(A_gases[/datum/gas/carbon_dioxide] && A_gases[/datum/gas/carbon_dioxide][MOLES] >= 10)
if(A.get_moles(/datum/gas/carbon_dioxide) >= 10)
continue
// Aim for goldilocks temperatures and pressure
if((A.temperature <= 270) || (A.temperature >= 360))
if((A.return_temperature() <= 270) || (A.return_temperature() >= 360))
continue
var/pressure = A.return_pressure()
if((pressure <= 20) || (pressure >= 550))

View File

@@ -42,9 +42,7 @@
/obj/effect/proc_holder/spell/targeted/olfaction/cast(list/targets, mob/living/user = usr)
//can we sniff? is there miasma in the 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)
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

View File

@@ -134,7 +134,7 @@
if(!istype(o, /obj/item/tank))
continue
var/obj/item/tank/T = o
found_amount += T.air_contents.gases[/datum/gas/plasma] ? T.air_contents.gases[/datum/gas/plasma][MOLES] : 0
found_amount += T.air_contents.get_moles(/datum/gas/plasma)
return found_amount >= target_amount

View File

@@ -54,14 +54,14 @@
"id_tag" = id_tag,
"timestamp" = world.time,
"pressure" = air_sample.return_pressure(),
"temperature" = air_sample.temperature,
"temperature" = air_sample.return_temperature(),
"gases" = list()
))
var/total_moles = air_sample.total_moles()
if(total_moles)
for(var/gas_id in air_sample.gases)
var/gas_name = air_sample.gases[gas_id][GAS_META][META_GAS_NAME]
signal.data["gases"][gas_name] = air_sample.gases[gas_id][MOLES] / total_moles * 100
for(var/gas_id in air_sample.get_gases())
var/gas_name = GLOB.meta_gas_info[gas_id][META_GAS_NAME]
signal.data["gases"][gas_name] = air_sample.get_moles(gas_id) / total_moles * 100
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)

View File

@@ -205,11 +205,8 @@
if(!density)
return FALSE
// alrighty now we check for how much pressure we're holding back
var/min_moles
var/max_moles
var/list/our_gases = T.air.gases
TOTAL_MOLES(our_gases, min_moles)
max_moles = min_moles
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()
@@ -217,9 +214,7 @@
for(var/turf/open/T2 in T.atmos_adjacent_turfs)
if((flags_1 & ON_BORDER_1) && get_dir(src, T2) != dir)
continue
var/list/cached_gases = T2.air.gases
var/moles = cached_gases
TOTAL_MOLES(cached_gases, moles)
var/moles = T2.air.total_moles()
if(moles < min_moles)
min_moles = moles
if(moles > max_moles)

View File

@@ -82,9 +82,9 @@
var/datum/gas_mixture/env = L.return_air()
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
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
if(mode != newMode)
@@ -95,7 +95,7 @@
return
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)
if(requiredPower < 1)
@@ -105,7 +105,7 @@
if(mode == HEATER_MODE_COOL)
deltaTemperature *= -1
if(deltaTemperature)
env.temperature += deltaTemperature
env.set_temperature(env.return_temperature() + deltaTemperature)
air_update_turf()
cell.use(requiredPower / efficiency)
else
@@ -186,9 +186,9 @@
var/curTemp
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
curTemp = env.temperature
curTemp = env.return_temperature()
else if(isturf(L))
curTemp = L.temperature
curTemp = L.return_temperature()
if(isnull(curTemp))
data["currentTemp"] = "N/A"
else

View File

@@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(telecomms_list)
var/turf/T = get_turf(src) //yogs
var/speedloss = 0
var/datum/gas_mixture/env = T.return_air()
var/temperature = env.temperature
var/temperature = env.return_temperature()
if(temperature <= 150) // 150K optimal operating parameters
net_efective = 100
else
@@ -170,8 +170,8 @@ GLOBAL_LIST_EMPTY(telecomms_list)
traffic = 0
else
traffic -= deltaT
if(generates_heat)
env.temperature += deltaT * heatoutput / env.heat_capacity() //yogs end
if(generates_heat && env.heat_capacity())
env.set_temperature(env.return_temperature() + deltaT * heatoutput / env.heat_capacity()) //yogs end
/obj/machinery/telecomms/emp_act(severity)

View File

@@ -21,7 +21,7 @@
var/cell_charge = get_charge()
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_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/output = {"[report_internal_damage()]
[integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null]

View File

@@ -260,11 +260,10 @@
/obj/mecha/proc/add_cabin()
cabin_air = new
cabin_air.temperature = T20C
cabin_air.volume = 200
cabin_air.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
cabin_air.gases[/datum/gas/oxygen][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
cabin_air.gases[/datum/gas/nitrogen][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
cabin_air.set_temperature(T20C)
cabin_air.set_volume(200)
cabin_air.set_moles(/datum/gas/oxygen, O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.set_moles(/datum/gas/nitrogen, N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
return cabin_air
/obj/mecha/proc/add_radio()
@@ -330,9 +329,9 @@
if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH))
setInternalDamage(MECHA_INT_TANK_BREACH)
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)
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)
take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0)
@@ -357,8 +356,8 @@
if(internal_temp_regulation)
if(cabin_air && cabin_air.return_volume() > 0)
var/delta = cabin_air.temperature - T20C
cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1)))
var/delta = cabin_air.return_temperature() - T20C
cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1))))
if(internal_tank)
var/datum/gas_mixture/tank_air = internal_tank.return_air()

View File

@@ -78,7 +78,7 @@
if (internal_tank)
int_tank_air = internal_tank.return_air()
tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown"
tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown"
cabin_pressure = round(return_pressure(),0.01)
. = {"[report_internal_damage()]
[integrity<30?"<span class='userdanger'>DAMAGE LEVEL CRITICAL</span><br>":null]

View File

@@ -39,12 +39,11 @@
if(hotspot && istype(T) && T.air)
qdel(hotspot)
var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma][MOLES]) //Absorb some plasma
G.gases[/datum/gas/plasma][MOLES] -= plas_amt
var/plas_amt = min(30,G.get_moles(/datum/gas/plasma)) //Absorb some plasma
G.adjust_moles(/datum/gas/plasma, -plas_amt)
absorbed_plasma += plas_amt
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
G.garbage_collect()
if(G.return_temperature() > T20C)
G.set_temperature(max(G.return_temperature()/2,T20C))
T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam()
@@ -315,15 +314,13 @@
O.ClearWet()
if(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)
qdel(H)
var/list/G_gases = G.gases
for(var/I in G_gases)
for(var/I in G.get_gases())
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue
G_gases[I][MOLES] = 0
G.garbage_collect()
G.set_moles(I, 0)
O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded)

View File

@@ -166,16 +166,13 @@
if(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
G.temperature = temperature
G.set_temperature(temperature)
T.air_update_turf()
for(var/obj/effect/hotspot/H in T)
qdel(H)
var/list/G_gases = G.gases
if(G_gases[/datum/gas/plasma])
G.assert_gas(/datum/gas/nitrogen)
G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES])
G_gases[/datum/gas/plasma][MOLES] = 0
G.garbage_collect()
if(G.get_moles(/datum/gas/plasma))
G.adjust_moles(/datum/gas/nitrogen, G.get_moles(/datum/gas/plasma))
G.set_moles(/datum/gas/plasma, 0)
if (weldvents)
for(var/obj/machinery/atmospherics/components/unary/U in T)
if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber.

View File

@@ -19,13 +19,11 @@
var/obj/item/tank/internals/plasma/PT = new(V)
var/obj/item/tank/internals/oxygen/OT = new(V)
PT.air_contents.assert_gas(/datum/gas/plasma)
PT.air_contents.gases[/datum/gas/plasma][MOLES] = 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_moles(/datum/gas/plasma, pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)))
PT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_p))
OT.air_contents.assert_gas(/datum/gas/oxygen)
OT.air_contents.gases[/datum/gas/oxygen][MOLES] = 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_moles(/datum/gas/oxygen, pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)))
OT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_o))
V.tank_one = PT
V.tank_two = OT

View File

@@ -252,10 +252,9 @@
/obj/structure/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
GM.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
GM.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD
GM.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD
GM.temperature = T20C
GM.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
GM.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
GM.set_temperature(T20C)
return GM
/obj/structure/chrono_field/singularity_act()

View File

@@ -376,7 +376,6 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "Unable to obtain a reading.<br>"
else
var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.gases
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
@@ -384,12 +383,12 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles)
for(var/id in env_gases)
var/gas_level = env_gases[id][MOLES]/total_moles
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0)
dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100, 0.01)]%<br>"
dat += "[GLOB.meta_gas_info[id][META_GAS_NAME]]: [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>"
if (666)

View File

@@ -479,42 +479,37 @@ GENE SCANNER
else
to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>")
if(total_moles)
var/list/env_gases = environment.gases
environment.assert_gases(arglist(GLOB.hardcoded_gases))
var/o2_concentration = env_gases[/datum/gas/oxygen][MOLES]/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen][MOLES]/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide][MOLES]/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma][MOLES]/total_moles
var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles
var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles
var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles
var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles
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][MOLES], 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
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen][MOLES], 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)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 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
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen][MOLES], 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)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 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
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide][MOLES], 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)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 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
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma][MOLES], 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>")
environment.garbage_collect()
for(var/id in env_gases)
for(var/id in environment.get_gases())
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = env_gases[id][MOLES]/total_moles
to_chat(user, "<span class='alert'>[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id][MOLES], 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>")
var/gas_concentration = environment.get_moles(id)/total_moles
to_chat(user, "<span class='alert'>[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.return_temperature()-T0C, 0.01)] &deg;C ([round(environment.return_temperature(), 0.01)] K)</span>")
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
..()
@@ -593,7 +588,7 @@ GENE SCANNER
var/total_moles = air_contents.total_moles()
var/pressure = air_contents.return_pressure()
var/volume = air_contents.return_volume() //could just do mixture.volume... but safety, I guess?
var/temperature = air_contents.temperature
var/temperature = air_contents.return_temperature()
var/cached_scan_results = air_contents.analyzer_results
if(total_moles > 0)
@@ -601,10 +596,9 @@ GENE SCANNER
to_chat(user, "<span class='notice'>Volume: [volume] L</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 cached_gases)
var/gas_concentration = cached_gases[id][MOLES]/total_moles
to_chat(user, "<span class='notice'>[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id][MOLES], 0.01)] mol)</span>")
for(var/id in air_contents.get_gases())
var/gas_concentration = air_contents.get_moles(id)/total_moles
to_chat(user, "<span class='notice'>[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='notice'>Temperature: [round(temperature - T0C,0.01)] &deg;C ([round(temperature, 0.01)] K)</span>")
else

View File

@@ -168,8 +168,8 @@
target_self = TRUE
if(change_volume)
if(!target_self)
target.volume += tank_two.volume
target.volume += tank_one.air_contents.volume
target.set_volume(target.return_volume() + tank_two.air_contents.return_volume())
target.set_volume(target.return_volume() + tank_one.air_contents.return_volume())
var/datum/gas_mixture/temp
temp = tank_one.air_contents.remove_ratio(1)
target.merge(temp)
@@ -180,11 +180,11 @@
/obj/item/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two)
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
temp = tank_two.air_contents.remove_ratio(ratio1)
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

View File

@@ -204,11 +204,10 @@
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
if(air_transfer.gases[/datum/gas/plasma])
air_transfer.gases[/datum/gas/plasma][MOLES] *= 5
air_transfer.set_moles(/datum/gas/plasma, air_transfer.get_moles(/datum/gas/plasma) * 5)
target.assume_air(air_transfer)
//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)
SSair.add_to_active(target, 0)

View File

@@ -21,8 +21,7 @@
/obj/item/tank/jetpack/populate_gas()
if(gas_type)
air_contents.assert_gas(gas_type)
air_contents.gases[gas_type][MOLES] = ((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)
if(istype(action, /datum/action/item_action/toggle_jetpack))

View File

@@ -20,8 +20,7 @@
/obj/item/tank/internals/oxygen/populate_gas()
air_contents.assert_gas(/datum/gas/oxygen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (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))
/obj/item/tank/internals/oxygen/yellow
@@ -48,9 +47,8 @@
force = 10
/obj/item/tank/internals/anesthetic/populate_gas()
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide)
air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(/datum/gas/nitrous_oxide, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
/*
* Air
@@ -64,9 +62,8 @@
dog_fashion = /datum/dog_fashion/back
/obj/item/tank/internals/air/populate_gas()
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrogen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(/datum/gas/nitrogen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
/*
* Plasma
@@ -81,8 +78,7 @@
/obj/item/tank/internals/plasma/populate_gas()
air_contents.assert_gas(/datum/gas/plasma)
air_contents.gases[/datum/gas/plasma][MOLES] = (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))
/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/flamethrower))
@@ -98,8 +94,7 @@
return ..()
/obj/item/tank/internals/plasma/full/populate_gas()
air_contents.assert_gas(/datum/gas/plasma)
air_contents.gases[/datum/gas/plasma][MOLES] = (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))
/obj/item/tank/internals/plasma/empty/populate_gas()
return
@@ -117,12 +112,10 @@
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
/obj/item/tank/internals/plasmaman/populate_gas()
air_contents.assert_gas(/datum/gas/plasma)
air_contents.gases[/datum/gas/plasma][MOLES] = (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))
/obj/item/tank/internals/plasmaman/full/populate_gas()
air_contents.assert_gas(/datum/gas/plasma)
air_contents.gases[/datum/gas/plasma][MOLES] = (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))
/obj/item/tank/internals/plasmaman/belt
@@ -134,8 +127,7 @@
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/tank/internals/plasmaman/belt/full/populate_gas()
air_contents.assert_gas(/datum/gas/plasma)
air_contents.gases[/datum/gas/plasma][MOLES] = (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))
/obj/item/tank/internals/plasmaman/belt/empty/populate_gas()
return
@@ -158,8 +150,7 @@
/obj/item/tank/internals/emergency_oxygen/populate_gas()
air_contents.assert_gas(/datum/gas/oxygen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/oxygen, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/obj/item/tank/internals/emergency_oxygen/empty/populate_gas()

View File

@@ -55,7 +55,7 @@
. = ..()
air_contents = new(volume) //liters
air_contents.temperature = T20C
air_contents.set_temperature(T20C)
populate_gas()
@@ -83,7 +83,7 @@
. += "<span class='notice'>The gauge reads [round(air_contents.total_moles(), 0.01)] mol at [round(src.air_contents.return_pressure(),0.01)] kPa.</span>" //yogs can read mols
var/celsius_temperature = src.air_contents.temperature-T0C
var/celsius_temperature = src.air_contents.return_temperature()-T0C
var/descriptive
if (celsius_temperature < 20)
@@ -222,7 +222,7 @@
if(tank_pressure < distribute_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)

View File

@@ -527,11 +527,11 @@
var/datum/gas_mixture/loc_air = loc?.return_air()
if(loc_air)
air_contents.copy_from(loc_air)
air_contents.remove_ratio((1 - (air_contents.volume / loc_air.volume))) // and thus we have just magically created new gases....
air_contents.remove_ratio((1 - (air_contents.return_volume() / loc_air.return_volume()))) // and thus we have just magically created new gases....
else if(!is_airtight && air_contents)
var/datum/gas_mixture/loc_air = loc?.return_air()
if(loc_air) // remember that air we created earlier? Now it's getting deleted! I mean it's still going on the turf....
var/remove_amount = (loc_air.total_moles() + air_contents.total_moles()) * air_contents.volume / (loc_air.volume + air_contents.volume)
var/remove_amount = (loc_air.total_moles() + air_contents.total_moles()) * air_contents.return_volume() / (loc_air.return_volume() + air_contents.return_volume())
loc.assume_air(air_contents)
loc.remove_air(remove_amount)
loc.air_update_turf()
@@ -554,5 +554,5 @@
/obj/structure/closet/return_temperature()
if(air_contents)
return air_contents.temperature
return air_contents.return_temperature()
return ..()

View File

@@ -10,10 +10,9 @@
/obj/structure/transit_tube_pod/Initialize()
. = ..()
air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD
air_contents.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD
air_contents.temperature = T20C
air_contents.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
air_contents.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
air_contents.set_temperature(T20C)
/obj/structure/transit_tube_pod/Destroy()
@@ -183,4 +182,4 @@
return
/obj/structure/transit_tube_pod/return_temperature()
return air_contents.temperature
return air_contents.return_temperature()

View File

@@ -149,6 +149,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
if (!istype(newTurf.air, /datum/gas_mixture/immutable/space))
QDEL_NULL(newTurf.air)
newTurf.air = stashed_air
update_air_ref()
SSair.add_to_active(newTurf)
else
if(ispath(path,/turf/closed))
@@ -305,25 +306,14 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
return
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)
var/turf/open/S = T
if(!S.air)
continue
var/list/S_gases = S.air.gases
for(var/id in S_gases)
ASSERT_GAS(id, total)
total_gases[id][MOLES] += S_gases[id][MOLES]
total.temperature += S.air.temperature
total.merge(S.air)
air.copy_from(total)
var/list/air_gases = air.gases
for(var/id in air_gases)
air_gases[id][MOLES] /= turf_count //Averages contents of the turfs, ignoring walls and the like
air.temperature /= turf_count
air.copy_from(total.remove_ratio(1/turf_count))
SSair.add_to_active(src)
/turf/proc/ReplaceWithLattice()

View File

@@ -6,9 +6,14 @@
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_MEDIUM_INSULATION
/turf/closed/Initialize()
. = ..()
update_air_ref()
/turf/closed/AfterChange()
. = ..()
SSair.high_pressure_delta -= src
update_air_ref()
/turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE

View File

@@ -174,7 +174,7 @@
flash_color(L, flash_color = "#C80000", flash_time = 10)
/turf/open/Initalize_Atmos(times_fired)
excited = 0
set_excited(FALSE)
update_visuals()
current_cycle = times_fired
@@ -182,19 +182,19 @@
for(var/i in atmos_adjacent_turfs)
var/turf/open/enemy_tile = i
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]")
excited = TRUE
set_excited(TRUE)
SSair.active_turfs |= src
/turf/open/proc/GetHeatCapacity()
. = air.heat_capacity()
/turf/open/proc/GetTemperature()
. = air.temperature
. = air.return_temperature()
/turf/open/proc/TakeTemperature(temp)
air.temperature += temp
air.set_temperature(air.return_temperature() + temp)
air_update_turf()
/turf/open/proc/freon_gas_act()
@@ -279,10 +279,8 @@
/turf/open/rad_act(pulse_strength)
. = ..()
if (air.gases[/datum/gas/carbon_dioxide] && air.gases[/datum/gas/oxygen])
pulse_strength = min(pulse_strength,air.gases[/datum/gas/carbon_dioxide][MOLES]*1000,air.gases[/datum/gas/oxygen][MOLES]*2000) //Ensures matter is conserved properly
air.gases[/datum/gas/carbon_dioxide][MOLES]=max(air.gases[/datum/gas/carbon_dioxide][MOLES]-(pulse_strength/1000),0)
air.gases[/datum/gas/oxygen][MOLES]=max(air.gases[/datum/gas/oxygen][MOLES]-(pulse_strength/2000),0)
air.assert_gas(/datum/gas/pluoxium)
air.gases[/datum/gas/pluoxium][MOLES]+=(pulse_strength/4000)
air.garbage_collect()
if (air.get_moles(/datum/gas/carbon_dioxide) && air.get_moles(/datum/gas/oxygen))
pulse_strength = min(pulse_strength,air.get_moles(/datum/gas/carbon_dioxide)*1000,air.get_moles(/datum/gas/oxygen)*2000) //Ensures matter is conserved properly
air.set_moles(/datum/gas/carbon_dioxide, max(air.get_moles(/datum/gas/carbon_dioxide)-(pulse_strength/1000),0))
air.set_moles(/datum/gas/oxygen, max(air.get_moles(/datum/gas/oxygen)-(pulse_strength/2000),0))
air.adjust_moles(/datum/gas/pluoxium, pulse_strength/4000)

View File

@@ -30,6 +30,7 @@
/turf/open/space/Initialize()
icon_state = SPACE_ICON_STATE
air = space_gas
update_air_ref()
vis_contents.Cut() //removes inherited overlays
visibilityChanged()

View File

@@ -268,7 +268,7 @@
/turf/open/Entered(atom/movable/AM)
..()
//melting
if(isobj(AM) && air && air.temperature > T0C)
if(isobj(AM) && air && air.return_temperature() > T0C)
var/obj/O = AM
if(O.obj_flags & FROZEN)
O.make_unfrozen()

View File

@@ -256,6 +256,15 @@ GLOBAL_VAR(restart_counter)
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() //yogs -- Mirrored in the Yogs folder in March 2019. Do not edit, swallow, or submerge in acid
var/list/features = list()
@@ -321,6 +330,7 @@ GLOBAL_VAR(restart_counter)
maxz++
SSmobs.MaxZChanged()
SSidlenpcpool.MaxZChanged()
world.refresh_atmos_grid()
/world/proc/change_fps(new_value = 20)
if(new_value <= 0)
@@ -344,3 +354,5 @@ GLOBAL_VAR(restart_counter)
/world/proc/on_tickrate_change()
SStimer?.reset_buckets()
/world/proc/refresh_atmos_grid()

View File

@@ -851,8 +851,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
Plasma.air_contents.assert_gas(/datum/gas/plasma)
Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70
Plasma.air_contents.set_moles(/datum/gas/plasma, 70)
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.forceMove(Rad)

View File

@@ -1,18 +1,16 @@
/proc/show_air_status_to(turf/target, mob/user)
var/datum/gas_mixture/env = target.return_air()
var/list/env_gases = env.gases
var/burning = FALSE
if(isopenturf(target))
var/turf/open/T = target
if(T.active_hotspot)
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>")
for(var/id in env_gases)
var/gas = env_gases[id]
var/moles = gas[MOLES]
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.get_gases())
var/moles = env.get_moles(id)
if (moles >= 0.00001)
lines += "[gas[GAS_META][META_GAS_NAME]]: [moles] mol"
lines += "[GLOB.meta_gas_info[id][META_GAS_NAME]]: [moles] mol"
to_chat(usr, lines.Join("\n"))
/client/proc/air_status(turf/target)

View File

@@ -51,7 +51,7 @@
return
if(I.use_tool(src, user, 0, volume=40))
status = TRUE
log_bomber(user, "welded a single tank bomb,", src, "| Temp: [bombtank.air_contents.temperature-T0C]")
log_bomber(user, "welded a single tank bomb,", src, "| 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>")
add_fingerprint(user)
return TRUE
@@ -142,9 +142,7 @@
return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6
air_contents.garbage_collect()
var/fuel_moles = air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1
@@ -154,7 +152,7 @@
qdel(master)
qdel(src)
if(bomb_mixture.temperature > (T0C + 400))
if(bomb_mixture.return_temperature() > (T0C + 400))
strength = (fuel_moles/15)
if(strength >=1)
@@ -167,7 +165,7 @@
ground_zero.assume_air(bomb_mixture)
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)
if(strength >=1)
@@ -178,7 +176,7 @@
ground_zero.assume_air(bomb_mixture)
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)
if (strength >=1)

View File

@@ -10,18 +10,14 @@
/turf/open/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/list/air_gases = air?.gases
if(!air_gases)
if(!air)
return
. = air_gases[/datum/gas/oxygen]
var/oxy = . ? .[MOLES] : 0
var/oxy = air.get_moles(/datum/gas/oxygen)
if (oxy < 0.5)
return
. = air_gases[/datum/gas/plasma]
var/tox = . ? .[MOLES] : 0
. = air_gases[/datum/gas/tritium]
var/trit = . ? .[MOLES] : 0
var/tox = air.get_moles(/datum/gas/plasma)
var/trit = air.get_moles(/datum/gas/tritium)
if(active_hotspot)
if(soh)
if(tox > 0.5 || trit > 0.5)
@@ -78,13 +74,13 @@
if(bypassing)
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
temperature = location.air.temperature
temperature = location.air.return_temperature()
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())
if(affected) //in case volume is 0
affected.temperature = temperature
affected.set_temperature(temperature)
affected.react(src)
temperature = affected.temperature
temperature = affected.return_temperature()
volume = affected.reaction_results["fire"]*FIRE_GROWTH_RATE
location.assume_air(affected)
@@ -152,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)
alpha = heat_a
#define INSUFFICIENT(path) (!location.air.gases[path] || location.air.gases[path][MOLES] < 0.5)
#define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)
/obj/effect/hotspot/process()
if(just_spawned)
just_spawned = FALSE
@@ -163,8 +159,7 @@
qdel(src)
return
if(location.excited_group)
location.excited_group.reset_cooldowns()
location.eg_reset_cooldowns()
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
qdel(src)
@@ -174,7 +169,8 @@
return
//Not enough to burn
if(((!location.air.gases[/datum/gas/plasma] || location.air.gases[/datum/gas/plasma][MOLES] < 0.5) && (!location.air.gases[/datum/gas/tritium] || location.air.gases[/datum/gas/tritium][MOLES] < 0.5)) || location.air.gases[/datum/gas/oxygen][MOLES] < 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)
return
@@ -185,8 +181,8 @@
location.burn_tile()
//Possible spread due to radiated heat
if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
if(location.air.return_temperature() > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
var/radiated_temperature = location.air.return_temperature()*FIRE_SPREAD_RADIOSITY_SCALE
for(var/t in location.atmos_adjacent_turfs)
var/turf/open/T = t
if(!T.active_hotspot)

View File

@@ -48,21 +48,28 @@
var/canvpass = CANVERTICALATMOSPASS(src, src)
for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction)
var/opp_dir = dir_inverse_multiz(direction)
if(!isopenturf(T))
continue
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = TRUE
T.atmos_adjacent_turfs[src] = TRUE
atmos_adjacent_turfs[T] = direction
T.atmos_adjacent_turfs[src] = opp_dir
T.__update_extools_adjacent_turfs()
else
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= T
if (T.atmos_adjacent_turfs)
T.atmos_adjacent_turfs -= src
T.__update_extools_adjacent_turfs()
UNSETEMPTY(T.atmos_adjacent_turfs)
UNSETEMPTY(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.
//alldir includes adjacent diagonal tiles that can share

View File

@@ -8,6 +8,7 @@
var/list/atmos_adjacent_turfs
//bitfield of dirs in which we are superconducitng
var/atmos_supeconductivity = NONE
var/is_openturf = FALSE // used by extools shizz.
//used to determine whether we should archive
var/archived_cycle = 0
@@ -25,20 +26,19 @@
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/obj/effect/hotspot/active_hotspot
var/atmos_cooldown = 0
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time
var/list/atmos_overlay_types //gas IDs of current active gas overlays
is_openturf = TRUE
/turf/open/Initialize()
if(!blocks_air)
air = new
air.copy_from_turf(src)
update_air_ref()
. = ..()
/turf/open/Destroy()
@@ -49,6 +49,8 @@
SSair.add_to_active(T)
return ..()
/turf/proc/update_air_ref()
/////////////////GAS MIXTURE PROCS///////////////////
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
@@ -94,6 +96,11 @@
archived_cycle = SSair.times_fired
temperature_archived = temperature
/turf/open/proc/eg_reset_cooldowns()
/turf/open/proc/eg_garbage_collect()
/turf/open/proc/get_excited()
/turf/open/proc/set_excited()
/////////////////////////GAS OVERLAYS//////////////////////////////
@@ -110,16 +117,13 @@
src.atmos_overlay_types = null
return
var/list/gases = air.gases
for(var/id in gases)
for(var/id in air.get_gases())
if (nonoverlaying_gases[id])
continue
var/gas = gases[id]
var/gas_meta = gas[GAS_META]
var/gas_meta = GLOB.meta_gas_info[id]
var/gas_overlay = gas_meta[META_GAS_OVERLAY]
if(gas_overlay && gas[MOLES] > gas_meta[META_GAS_MOLES_VISIBLE])
new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas[MOLES] / MOLES_GAS_VISIBLE_STEP, 1))]
if(gas_overlay && air.get_moles(id) > gas_meta[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)
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
@@ -134,6 +138,19 @@
UNSETEMPTY(new_overlay_types)
src.atmos_overlay_types = new_overlay_types
/turf/open/proc/set_visuals(list/new_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
vis_contents -= overlay
if (length(new_overlay_types))
if (atmos_overlay_types)
vis_contents += new_overlay_types - atmos_overlay_types //don't add overlays that already exist
else
vis_contents += new_overlay_types
UNSETEMPTY(new_overlay_types)
src.atmos_overlay_types = new_overlay_types
/proc/typecache_of_gases_with_no_overlays()
. = list()
for (var/gastype in subtypesof(/datum/gas))
@@ -143,8 +160,8 @@
/////////////////////////////SIMULATION///////////////////////////////////
#define LAST_SHARE_CHECK \
var/last_share = our_air.last_share;\
/*#define LAST_SHARE_CHECK \
var/last_share = our_air.get_last_share();\
if(last_share > MINIMUM_AIR_TO_SUSPEND){\
our_excited_group.reset_cooldowns();\
cached_atmos_cooldown = 0;\
@@ -152,95 +169,32 @@
our_excited_group.dismantle_cooldown = 0;\
cached_atmos_cooldown = 0;\
}
*/
/turf/proc/process_cell(fire_count)
SSair.remove_from_active(src)
/turf/open/process_cell(fire_count)
if(archived_cycle < fire_count) //archive self if not already done
archive()
current_cycle = fire_count
//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)
/turf/open/proc/equalize_pressure_in_zone(cyclenum)
/turf/open/proc/consider_firelocks(turf/T2)
var/reconsider_adj = FALSE
for(var/obj/machinery/door/firedoor/FD in T2)
if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, src) != FD.dir)
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
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)
G.archive()
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
our_air.react(src)
update_visuals()
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/process_cell(fire_count)
//////////////////////////SPACEWIND/////////////////////////////
@@ -289,87 +243,6 @@
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][MOLES] /= 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/////////////////////////////
/turf/proc/conductivity_directions()
if(archived_cycle < SSair.times_fired)
@@ -436,7 +309,7 @@
//Conduct with air on my tile if I have it
if(!blocks_air)
temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity)
..((blocks_air ? temperature : air.temperature))
..((blocks_air ? temperature : air.return_temperature()))
/turf/proc/consider_superconductivity()
if(!thermal_conductivity)
@@ -446,7 +319,7 @@
return TRUE
/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
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

View File

@@ -1,438 +0,0 @@
#define MONSTERMOS_TURF_LIMIT 75
/turf/open
var/last_eq_cycle
var/eq_mole_delta = 0
var/list/eq_transfer_dirs
var/turf/open/curr_eq_transfer_turf
var/curr_eq_transfer_amount
var/eq_fast_done = FALSE
var/eq_distance_score = 0
/turf/open/proc/adjust_eq_movement(turf/open/other, amount = 0)
if(!other)
return
if(!eq_transfer_dirs)
eq_transfer_dirs = list()
if(!eq_transfer_dirs[other])
eq_transfer_dirs[other] = amount
else
eq_transfer_dirs[other] += amount
if(other != src)
if(!other.eq_transfer_dirs)
other.eq_transfer_dirs = list()
if(!other.eq_transfer_dirs[src])
other.eq_transfer_dirs[src] = -amount
else
other.eq_transfer_dirs[src] -= amount
/turf/open/proc/finalize_eq()
var/list/transfer_dirs = eq_transfer_dirs
if(!transfer_dirs)
return
eq_transfer_dirs = null // null it out to prevent infinite recursion.
var/planet_transfer_amount = transfer_dirs[src] || 0
var/list/cached_gases = air.gases
var/sum
if(planet_transfer_amount > 0)
TOTAL_MOLES(cached_gases, sum)
if(sum < planet_transfer_amount)
finalize_eq_neighbors(transfer_dirs)
remove_air(planet_transfer_amount)
if(planet_transfer_amount < 0) // succ gases from above.
var/datum/gas_mixture/G = new
G.copy_from_turf(src)
var/list/planet_gases = G.gases
var/planet_sum
TOTAL_MOLES(planet_gases, planet_sum)
if(planet_sum > 0) // oi you cant just suck gases from turfs with no air.
var/multiplier = -planet_transfer_amount / planet_sum
for(var/id in planet_gases)
planet_gases[id][MOLES] *= multiplier
assume_air(G)
for(var/t in transfer_dirs)
if(t == src)
continue
var/amount = transfer_dirs[t]
var/turf/open/T = t
if(amount > 0)
// gas push time baby
// but first gotta make sure we got enough gas for that.
TOTAL_MOLES(cached_gases, sum)
if(sum < amount)
finalize_eq_neighbors(transfer_dirs)
if(T.eq_transfer_dirs)
T.eq_transfer_dirs -= src
// air.transfer_to(T.return_air(), amount) // push them gases.
//update_visuals()
//T.update_visuals()
T.assume_air(remove_air(amount))
consider_pressure_difference(T, amount)
/turf/open/proc/finalize_eq_neighbors(list/transfer_dirs)
for(var/t in transfer_dirs)
if(t == src)
continue
var/amount = transfer_dirs[t]
if(amount < 0)
var/turf/open/T = t
T.finalize_eq() // just a bit of recursion if necessary.
// This proc has a worst-case running time of about O(n^2), but this is
// is really rare. Otherwise you get more like O(n*log(n)) (there's a sort in there), or if you get lucky its faster.
/proc/equalize_pressure_in_zone(turf/open/starting_point, cyclenum)
// okay I lied in the proc name it equalizes moles not pressure. Pressure is impossible.
// wanna know why? well let's say you have two turfs. One of them is 101.375 kPA and the other is 101.375 kPa.
// When they mix what's the pressure gonna be, before any reactions occur? If you guessed 1483.62 kPa you'd be right,
// because one of them is 101.375 kPa of hyper-noblium at 1700K temperature, and the other is 101.375 kPa of nitrogen at 43.15K temperature,
// and that's just the way the math works out in SS13. And there's no reactions going on - hyper-noblium stops all reactions from happening.
// I'm pretty sure real gases don't work this way. Oh yeah this property can be used to make bombs too I guess so thats neat
if(!istype(starting_point) || starting_point.last_eq_cycle >= cyclenum)
return // if we've alrady done it then piss off.
// first gotta figure out if it's even necessary
var/starting_moles
var/list/starting_gases = starting_point.air.gases
var/run_monstermos = FALSE
TOTAL_MOLES(starting_gases, starting_moles)
for(var/t in starting_point.atmos_adjacent_turfs)
var/turf/open/T = t;
var/list/comparison_gases = T.air.gases
var/comparison_moles
TOTAL_MOLES(comparison_gases, comparison_moles)
if(abs(comparison_moles - starting_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
run_monstermos = TRUE
break
if(!run_monstermos) // if theres no need dont bother
starting_point.last_eq_cycle = cyclenum
return
if(starting_point.planetary_atmos)
return // nah, let's not lag the server trying to process lavaland please.
// it has been deemed necessary. Now to figure out which turfs are involved.
var/total_moles
var/list/turfs = list()
turfs[starting_point] = 1
var/list/planet_turfs = list()
for(var/i = 1; i <= turfs.len; i++) // turfs.len changes so this is necessary
var/turf/open/T = turfs[i]
T.eq_mole_delta = 0
T.eq_transfer_dirs = list()
T.eq_distance_score = i
if(i < MONSTERMOS_TURF_LIMIT)
var/turf_moles
var/list/cached_gases = T.air.gases
TOTAL_MOLES(cached_gases, turf_moles)
T.eq_mole_delta = turf_moles
T.eq_fast_done = FALSE
if(T.planetary_atmos)
planet_turfs += T
continue
total_moles += turf_moles
for(var/t2 in T.atmos_adjacent_turfs)
var/turf/open/T2 = t2
turfs[T2] = 1
if(istype(T2, /turf/open/space))
// Uh oh! looks like someone opened an airlock to space! TIME TO SUCK ALL THE AIR OUT!!!
// NOT ONE OF YOU IS GONNA SURVIVE THIS
// (I just made explosions less laggy, you're welcome)
explosively_depressurize(T, cyclenum)
return
CHECK_TICK
if(turfs.len >= MONSTERMOS_TURF_LIMIT)
turfs.Cut(MONSTERMOS_TURF_LIMIT)
var/average_moles = total_moles / (turfs.len - planet_turfs.len)
var/list/giver_turfs = list()
var/list/taker_turfs = list()
for(var/t in turfs)
var/turf/open/T = t
T.last_eq_cycle = cyclenum
T.eq_mole_delta -= average_moles
if(T.planetary_atmos)
continue
if(T.eq_mole_delta > 0)
giver_turfs += T
else if(T.eq_mole_delta < 0)
taker_turfs += T
var/log_n = log(2, turfs.len)
if(giver_turfs.len > log_n && taker_turfs.len > log_n) // optimization - try to spread gases using an O(nlogn) algorithm that has a chance of not working first to avoid O(n^2)
// even if it fails, it will speed up the next part
var/list/eligible_adj = list()
sortTim(turfs, /proc/cmp_monstermos_pushorder)
for(var/t in turfs)
var/turf/open/T = t
T.eq_fast_done = TRUE
if(T.eq_mole_delta > 0)
eligible_adj.Cut()
for(var/t2 in T.atmos_adjacent_turfs)
var/turf/open/T2 = t2
if(T2.eq_fast_done)
continue
eligible_adj += T2
if(eligible_adj.len <= 0)
continue // Oof we've painted ourselves into a corner. Bad luck. Next part will handle this.
var/moles_to_move = T.eq_mole_delta / eligible_adj.len
for(var/t2 in eligible_adj)
var/turf/open/T2 = t2
T.adjust_eq_movement(T2, moles_to_move)
T.eq_mole_delta -= moles_to_move
T2.eq_mole_delta += moles_to_move
CHECK_TICK
giver_turfs.Cut() // we need to recaclculate those now
taker_turfs.Cut()
for(var/t in turfs)
var/turf/open/T = t
if(T.planetary_atmos)
continue
if(T.eq_mole_delta > 0)
giver_turfs += T
else if(T.eq_mole_delta < 0)
taker_turfs += T
// alright this is the part that can become O(n^2).
if(giver_turfs.len < taker_turfs.len) // as an optimization, we choose one of two methods based on which list is smaller. We really want to avoid O(n^2) if we can.
for(var/g in giver_turfs)
var/turf/open/giver = g
giver.curr_eq_transfer_turf = giver
giver.curr_eq_transfer_amount = 0
var/list/queue = list()
queue[giver] = TRUE
for(var/i = 1; i <= queue.len; i++)
if(giver.eq_mole_delta <= 0)
break // we're done here now. Let's not do more work than we need.
var/turf/open/T = queue[i]
for(var/t2 in T.atmos_adjacent_turfs)
if(giver.eq_mole_delta <= 0)
break // we're done here now. Let's not do more work than we need.
var/turf/open/T2 = t2
if(T2.planetary_atmos)
continue
if(queue[T2])
continue
queue[T2] = 1
T2.curr_eq_transfer_turf = T
T2.curr_eq_transfer_amount = 0
if(T2.eq_mole_delta < 0)
// this turf needs gas. Let's give it to 'em.
if(-T2.eq_mole_delta > giver.eq_mole_delta)
// we don't have enough gas
T2.curr_eq_transfer_amount -= giver.eq_mole_delta
T2.eq_mole_delta += giver.eq_mole_delta
giver.eq_mole_delta = 0
else
// we have enough gas.
T2.curr_eq_transfer_amount += T2.eq_mole_delta
giver.eq_mole_delta += T2.eq_mole_delta
T2.eq_mole_delta = 0
for(var/i = queue.len; i > 0; i--) // putting this loop here helps make it O(n^2) over O(n^3) I nearly put this in the previous loop that would have been really really slow and bad.
var/turf/open/T = queue[i]
if(T.curr_eq_transfer_amount && T.curr_eq_transfer_turf != T)
T.adjust_eq_movement(T.curr_eq_transfer_turf, T.curr_eq_transfer_amount)
T.curr_eq_transfer_turf.curr_eq_transfer_amount += T.curr_eq_transfer_amount
T.curr_eq_transfer_amount = 0
CHECK_TICK
else
for(var/t in taker_turfs)
var/turf/open/taker = t
taker.curr_eq_transfer_turf = taker
taker.curr_eq_transfer_amount = 0
var/list/queue = list()
queue[taker] = TRUE
for(var/i = 1; i <= queue.len; i++)
if(taker.eq_mole_delta >= 0)
break // we're done here now. Let's not do more work than we need.
var/turf/open/T = queue[i]
for(var/t2 in T.atmos_adjacent_turfs)
if(taker.eq_mole_delta >= 0)
break // we're done here now. Let's not do more work than we need.
var/turf/open/T2 = t2
if(T2.planetary_atmos)
continue
if(queue[T2])
continue
queue[T2] = 1
T2.curr_eq_transfer_turf = T
T2.curr_eq_transfer_amount = 0
if(T2.eq_mole_delta > 0)
// this turf has gas we can succ. Time to succ.
if(T2.eq_mole_delta > -taker.eq_mole_delta)
// they have enough gas
T2.curr_eq_transfer_amount -= taker.eq_mole_delta
T2.eq_mole_delta += taker.eq_mole_delta
taker.eq_mole_delta = 0
else
// they don't have enough gas.
T2.curr_eq_transfer_amount += T2.eq_mole_delta
taker.eq_mole_delta += T2.eq_mole_delta
T2.eq_mole_delta = 0
for(var/i = queue.len; i > 0; i--)
var/turf/open/T = queue[i]
if(T.curr_eq_transfer_amount && T.curr_eq_transfer_turf != T)
T.adjust_eq_movement(T.curr_eq_transfer_turf, T.curr_eq_transfer_amount)
T.curr_eq_transfer_turf.curr_eq_transfer_amount += T.curr_eq_transfer_amount
T.curr_eq_transfer_amount = 0
CHECK_TICK
if(planet_turfs.len) // now handle planet turfs
var/turf/open/sample = planet_turfs[1] // we're gonna assume all the planet turfs are the same.
var/datum/gas_mixture/G = new
G.copy_from_turf(sample)
var/list/planet_gases = G.gases
var/planet_sum
TOTAL_MOLES(planet_gases, planet_sum)
var/target_delta = planet_sum - average_moles
var/list/progression_order = list()
for(var/t in planet_turfs)
var/turf/open/T = t
progression_order[T] = 1
T.curr_eq_transfer_turf = T
// now build a map of where the path to planet turf is for each tile.
for(var/i = 1; i <= progression_order.len; i++)
var/turf/open/T = progression_order[i]
for(var/t2 in T.atmos_adjacent_turfs)
if(!turfs[t2]) continue
if(progression_order[t2])
continue
var/turf/open/T2 = t2
if(T2.planetary_atmos)
continue
T2.curr_eq_transfer_turf = T
progression_order[T2] = 1
// apply airflow to turfs
for(var/i = progression_order.len; i > 0; i--)
var/turf/open/T = progression_order[i]
var/turf/open/T2 = T.curr_eq_transfer_turf
var/airflow = T.eq_mole_delta - target_delta
T.adjust_eq_movement(T2, airflow)
if(T != T2)
T2.eq_mole_delta += airflow
T.eq_mole_delta = target_delta
for(var/t in turfs)
var/turf/open/T = t
T.finalize_eq()
for(var/t in turfs)
var/turf/open/T = t
// make sure there's actually a difference - remember, we just equalized like all the pressure.
// it's very likely there's no significant difference in the gases, and we don't want to fuck around with
// expensive list operations afterwards.
for(var/t2 in T.atmos_adjacent_turfs)
var/turf/open/T2 = t2
if(T.air.compare(T2.air))
SSair.add_to_active(T)
break
/proc/cmp_monstermos_pushorder(turf/open/A, turf/open/B)
if(A.eq_mole_delta != B.eq_mole_delta)
return B.eq_mole_delta - A.eq_mole_delta
/*var/a_len = A.atmos_adjacent_turfs?.len || 0
var/b_len = B.atmos_adjacent_turfs?.len || 0
if(a_len != b_len)
if(A.eq_mole_delta > 0)
return a_len - b_len
else
return b_len - a_len*/ // hm I think this might actually be counterproductive
if(A.eq_mole_delta > 0)
return B.eq_distance_score - A.eq_distance_score
else
return A.eq_distance_score - B.eq_distance_score
/proc/explosively_depressurize(turf/open/starting_point, cyclenum)
var/total_gases_deleted = 0
// this is where all the air is immediately vented into space. Right now. Immediately.
var/list/turfs = list()
turfs[starting_point] = 1
var/list/space_turfs = list() // this is where we keep all the space turfs so that our wallslam hell is realistic
// start by figuring out which turfs are actually affected
var/warned_about_planet_atmos = FALSE
for(var/i = 1; i <= turfs.len; i++)
CHECK_TICK
var/turf/open/T = turfs[i]
T.last_eq_cycle = cyclenum
T.pressure_direction = 0
if(T.planetary_atmos)
// planet atmos > space
if(!warned_about_planet_atmos)
message_admins("Space turf(s) at [ADMIN_VERBOSEJMP(starting_point)] is connected to planetary turf(s) at [ADMIN_VERBOSEJMP(T)]!")
log_game("Space turf(s) at [AREACOORD(starting_point)] is connected to planetary turf(s) at [AREACOORD(T)]!")
warned_about_planet_atmos = TRUE
continue
if(istype(T, /turf/open/space))
space_turfs += T
T.pressure_specific_target = T
else
for(var/t2 in T.atmos_adjacent_turfs)
var/turf/open/T2 = t2
var/reconsider_adj = FALSE
for(var/obj/machinery/door/firedoor/FD in T2)
if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, T) != FD.dir)
continue
FD.emergency_pressure_stop()
reconsider_adj = TRUE
for(var/obj/machinery/door/firedoor/FD in T)
if((FD.flags_1 & ON_BORDER_1) && get_dir(T, T2) != FD.dir)
continue
FD.emergency_pressure_stop()
reconsider_adj = TRUE
if(reconsider_adj)
T2.ImmediateCalculateAdjacentTurfs() // We want those firelocks closed yesterday.
if(T2 in T.atmos_adjacent_turfs)
turfs[T2] = 1
else
turfs[T2] = 1
if(warned_about_planet_atmos)
return // planet atmos > space
var/list/progression_order = list()
for(var/T in space_turfs)
progression_order[T] = 1
// now build a map of where the path to space is for each tile.
for(var/i = 1; i <= progression_order.len; i++)
CHECK_TICK
var/turf/open/T = progression_order[i]
for(var/t2 in T.atmos_adjacent_turfs)
if(!turfs[t2]) continue
if(progression_order[t2])
continue
if(istype(t2, /turf/open/space))
continue
var/turf/open/T2 = t2
T2.pressure_direction = get_dir(T2, T)
T2.pressure_difference = 0
T2.pressure_specific_target = T.pressure_specific_target
progression_order[T2] = 1
// apply pressure differences to turfs
for(var/i = progression_order.len; i > 0; i--)
CHECK_TICK
var/turf/open/T = progression_order[i]
if(T.pressure_direction == 0)
continue
SSair.high_pressure_delta |= T
var/turf/open/T2 = get_step_multiz(T, T.pressure_direction)
if(!istype(T2))
continue
var/list/cached_gases = T.air.gases
var/sum
TOTAL_MOLES(cached_gases, sum)
total_gases_deleted += sum
T.pressure_difference += sum // our pressure gets applied to our tile
T2.pressure_difference += T.pressure_difference // then our tile gets propogated to the next tile.
if(!T2.pressure_direction)
T2.pressure_direction = T.pressure_direction // extend wallslam hell into space a bit, that way you're not totally safe from WALLSLAM HELL when in space.
cached_gases.Cut() // oh yeah its now vacuum I guess too, that's pretty important I think.
T.update_visuals() // yeah removing the plasma overlay is probably important.
if(istype(T, /turf/open/floor) && sum > 20 && prob(CLAMP(sum / 10, 0, 30)))
var/turf/open/floor/F = T
F.remove_tile()
if((total_gases_deleted / turfs.len) > 20 && turfs.len > 10) // logging I guess
if(SSticker.current_state != GAME_STATE_FINISHED && SSair.log_explosive_decompression)
message_admins("Explosive decompression occured at [ADMIN_VERBOSEJMP(starting_point)], sucking [total_gases_deleted] moles of air into space.")
log_game("Explosive decompression occured at [AREACOORD(starting_point)], sucking [total_gases_deleted] moles of air into space.")

View File

@@ -22,95 +22,63 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
cached_gas[GAS_META] = GLOB.meta_gas_info[id]
/datum/gas_mixture
var/list/gases
var/temperature = 0 //kelvins
var/tmp/temperature_archived = 0
var/volume = CELL_VOLUME //liters
var/last_share = 0
var/initial_volume = CELL_VOLUME //liters
var/list/reaction_results
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)
gases = new
if (!isnull(volume))
src.volume = volume
initial_volume = volume
ATMOS_EXTOOLS_CHECK
__gasmixture_register()
reaction_results = new
//listmos procs
//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm
/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()
. = ..()*/
//assert_gas(gas_id) - used to guarantee that the gas list for this id exists in gas_mixture.gases.
//Must be used before adding to a gas. May be used before reading from a gas.
/datum/gas_mixture/proc/assert_gas(gas_id)
ASSERT_GAS(gas_id, src)
/datum/gas_mixture/proc/__gasmixture_unregister()
/datum/gas_mixture/proc/__gasmixture_register()
//assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type.
/datum/gas_mixture/proc/assert_gases(...)
for(var/id in args)
ASSERT_GAS(id, src)
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing
//gas list for this id. This can clobber existing gases.
//Used instead of assert_gas() when you know the gas does not exist. Faster than assert_gas().
/datum/gas_mixture/proc/add_gas(gas_id)
ADD_GAS(gas_id, gases)
//add_gases(args) - shorthand for calling add_gas() once for each gas_type.
/datum/gas_mixture/proc/add_gases(...)
var/cached_gases = gases
for(var/id in args)
ADD_GAS(id, cached_gases)
//garbage_collect() - removes any gas list which is empty.
//If called with a list as an argument, only removes gas lists with IDs from that list.
//Must be used after subtracting from a gas. Must be used after assert_gas()
//if assert_gas() was called only to read from the gas.
//By removing empty gases, processing speed is increased.
/datum/gas_mixture/proc/garbage_collect(list/tocheck)
var/list/cached_gases = gases
for(var/id in (tocheck || cached_gases))
if(QUANTIZE(cached_gases[id][MOLES]) <= 0 && QUANTIZE(cached_gases[id][ARCHIVE]) <= 0)
cached_gases -= id
//PV = nRT
/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/proc/heat_capacity(data = MOLES) //joules per kelvin
var/list/cached_gases = gases
. = 0
for(var/id in cached_gases)
var/gas_data = cached_gases[id]
. += gas_data[data] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
/datum/gas_mixture/turf/heat_capacity(data = MOLES) // Same as above except vacuums return HEAT_CAPACITY_VACUUM
var/list/cached_gases = gases
. = 0
for(var/id in cached_gases)
var/gas_data = cached_gases[id]
. += gas_data[data] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
if(!.)
. += HEAT_CAPACITY_VACUUM //we want vacuums in turfs to have the same heat capacity as space
/datum/gas_mixture/proc/total_moles()
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
/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
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
return max(0, volume)
/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()
//Update archived versions of variables
@@ -164,282 +132,60 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise
/datum/gas_mixture/archive()
var/list/cached_gases = gases
temperature_archived = temperature
for(var/id in cached_gases)
cached_gases[id][ARCHIVE] = cached_gases[id][MOLES]
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)
ASSERT_GAS(giver_id, src)
cached_gases[giver_id][MOLES] += giver_gases[giver_id][MOLES]
return 1
/datum/gas_mixture/transfer_to(datum/gas_mixture/target, amount) // Transfer gases
var/list/cached_gases = gases
var/sum
TOTAL_MOLES(cached_gases, sum)
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
var/list/target_gases = target.gases
var/heat_capacity_transferred = 0
for(var/id in cached_gases)
ASSERT_GAS(id, target)
var/list/cached_gas = cached_gases[id]
var/moles_to_transfer = QUANTIZE((cached_gases[id][MOLES] / sum) * amount)
target_gases[id][MOLES] += moles_to_transfer
cached_gas[MOLES] -= moles_to_transfer
heat_capacity_transferred += cached_gas[GAS_META][META_GAS_SPECIFIC_HEAT] * moles_to_transfer
if(abs(temperature - target.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/target_heat_capacity = target.heat_capacity()
var/target_heat_capacity_before = heat_capacity_transferred
target.temperature = (temperature * heat_capacity_transferred + target.temperature * target_heat_capacity_before) / target_heat_capacity
garbage_collect()
/datum/gas_mixture/proc/__remove()
/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)
ADD_GAS(id, removed_gases)
removed_gases[id][MOLES] = QUANTIZE((cached_gases[id][MOLES] / sum) * amount)
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
garbage_collect()
__remove(removed, amount)
return removed
/datum/gas_mixture/proc/__remove_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/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
removed.temperature = temperature
for(var/id in cached_gases)
ADD_GAS(id, removed_gases)
removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio)
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
garbage_collect()
__remove_ratio(removed, ratio)
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)
ADD_GAS(id, copy.gases)
copy_gases[id][MOLES] = cached_gases[id][MOLES]
copy.copy_from(src)
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)
ASSERT_GAS(id,src)
cached_gases[id][MOLES] = sample_gases[id][MOLES]
//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
set_temperature(model.temperature)
return 1
/datum/gas_mixture/parse_gas_string(gas_string)
var/list/gases = src.gases
var/list/gas = params2list(gas_string)
if(gas["TEMP"])
temperature = text2num(gas["TEMP"])
set_temperature(text2num(gas["TEMP"]))
gas -= "TEMP"
gases.Cut()
clear()
for(var/id in gas)
var/path = id
if(!ispath(path))
path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
ADD_GAS(path, gases)
gases[path][MOLES] = text2num(gas[id])
set_moles(path, text2num(gas[id]))
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
//GAS TRANSFER
for(var/id in sharer_gases - cached_gases) // create gases not in our cache
ADD_GAS(id, gases)
for(var/id in cached_gases) // transfer gases
ASSERT_GAS(id, sharer)
var/gas = cached_gases[id]
var/sharergas = sharer_gases[id]
var/delta = QUANTIZE(gas[ARCHIVE] - sharergas[ARCHIVE])/(atmos_adjacent_turfs+1) //the amount of gas that gets moved between the mixtures
if(delta && abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/gas_heat_capacity = delta * gas[GAS_META][META_GAS_SPECIFIC_HEAT]
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.
gas[MOLES] -= delta
sharergas[MOLES] += 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(length(cached_gases ^ sharer_gases)) //if all gases were present in both mixtures, we know that no gases are 0
garbage_collect(cached_gases - sharer_gases) //any gases the sharer had, we are guaranteed to have. gases that it didn't have we are not.
sharer.garbage_collect(sharer_gases - cached_gases) //the reverse is equally true
if (initial(sharer.gc_share))
sharer.garbage_collect()
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 = heat_capacity(ARCHIVE)
sharer_heat_capacity = sharer_heat_capacity || sharer.heat_capacity(ARCHIVE)
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]
gas_moles = gas_moles ? gas_moles[MOLES] : 0
var/sample_moles = sample_gases[id]
sample_moles = sample_moles ? sample_moles[MOLES] : 0
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)
. = NO_REACTION
var/list/cached_gases = gases
if(!length(cached_gases))
return
var/list/reactions = list()
for(var/I in cached_gases)
for(var/I in get_gases())
reactions += SSair.gas_reactions[I]
if(!length(reactions))
return
reaction_results = new
var/temp = temperature
var/ener = THERMAL_ENERGY(src)
var/temp = return_temperature()
var/ener = thermal_energy()
reaction_loop:
for(var/r in reactions)
@@ -453,7 +199,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
for(var/id in min_reqs)
if (id == "TEMP" || id == "ENER")
continue
if(!cached_gases[id] || cached_gases[id][MOLES] < min_reqs[id])
if(get_moles(id) < min_reqs[id])
continue reaction_loop
//at this point, all requirements for the reaction are satisfied. we can now react()
@@ -461,8 +207,6 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
. |= reaction.react(src, holder)
if (. & STOP_REACTIONS)
break
if(.)
garbage_collect()
//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
@@ -471,10 +215,10 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//O2_PP = get_partial_pressure(gas_mixture.oxygen)
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
return (gas_pressure * R_IDEAL_GAS_EQUATION * temperature) / BREATH_VOLUME
return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME
//inverse
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * temperature)
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature())
//Mathematical proofs:
/*
@@ -485,6 +229,8 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
10 = 2.5/5*20
*/
/datum/gas_mixture/turf
/*
/mob/verb/profile_atmos()
/world{loop_checks = 0;}
@@ -511,7 +257,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
pa = world.tick_usage
for(var/I in 1 to 100000)
var/datum/gas_mixture/GM = new
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")

View File

@@ -49,6 +49,9 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/g
var/fusion_power = 0 //How much the gas accelerates a fusion reaction
var/rarity = 0 // relative rarity compared to other gases, used when setting up the reactions list.
// If you add or remove gases, update TOTAL_NUM_GASES in the extools code to match!
// (dont forget to count shizz in the yogstation folder)
/datum/gas/oxygen
id = "o2"
specific_heat = 20

View File

@@ -2,69 +2,27 @@
//it can be changed, but any changes will ultimately be undone before they can have any effect
/datum/gas_mixture/immutable
var/initial_temperature
gc_share = TRUE
var/initial_temperature = 0
/datum/gas_mixture/immutable/New()
..()
garbage_collect()
set_temperature(initial_temperature)
populate()
mark_immutable()
/datum/gas_mixture/immutable/garbage_collect()
temperature = initial_temperature
temperature_archived = initial_temperature
gases.Cut()
/datum/gas_mixture/immutable/archive()
return 1 //nothing changes, so we do nothing and the archive is successful
/datum/gas_mixture/immutable/merge()
return 0 //we're immutable.
/datum/gas_mixture/immutable/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
. = ..(sharer, 0)
garbage_collect()
/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/populate()
return
//used by space tiles
/datum/gas_mixture/immutable/space
initial_temperature = TCMB
/datum/gas_mixture/immutable/space/heat_capacity()
return 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.
/datum/gas_mixture/immutable/space/populate()
set_min_heat_capacity(HEAT_CAPACITY_VACUUM)
//used by cloners
/datum/gas_mixture/immutable/cloner
initial_temperature = T20C
/datum/gas_mixture/immutable/cloner/garbage_collect()
..()
ADD_GAS(/datum/gas/nitrogen, gases)
gases[/datum/gas/nitrogen][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/cloner/heat_capacity()
return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20
/datum/gas_mixture/immutable/cloner/populate()
set_moles(/datum/gas/nitrogen, MOLES_O2STANDARD + MOLES_N2STANDARD)

View File

@@ -72,11 +72,11 @@
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
var/turf/open/location = isturf(holder) ? holder : null
. = NO_REACTION
if (air.temperature <= WATER_VAPOR_FREEZE)
if (air.return_temperature() <= WATER_VAPOR_FREEZE)
if(location && location.freon_gas_act())
. = REACTING
else if(location && location.water_vapor_gas_act())
air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_GAS_VISIBLE
air.adjust_moles(/datum/gas/water_vapor, -MOLES_GAS_VISIBLE)
. = REACTING
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
@@ -95,21 +95,20 @@
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
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.temperature
var/temperature = air.return_temperature()
var/list/cached_results = air.reaction_results
cached_results["fire"] = 0
var/turf/open/location = isturf(holder) ? holder : null
var/burned_fuel = 0
var/initial_trit = cached_gases[/datum/gas/tritium][MOLES]// Yogs
if(cached_gases[/datum/gas/oxygen][MOLES] < initial_trit || MINIMUM_TRIT_OXYBURN_ENERGY > (temperature * old_heat_capacity))// Yogs -- Maybe a tiny performance boost? I'unno
burned_fuel = cached_gases[/datum/gas/oxygen][MOLES]/TRITIUM_BURN_OXY_FACTOR
var/initial_trit = air.get_moles(/datum/gas/tritium)// Yogs
if(air.get_moles(/datum/gas/oxygen) < initial_trit || MINIMUM_TRIT_OXYBURN_ENERGY > (temperature * old_heat_capacity))// Yogs -- Maybe a tiny performance boost? I'unno
burned_fuel = air.get_moles(/datum/gas/oxygen)/TRITIUM_BURN_OXY_FACTOR
if(burned_fuel > initial_trit) burned_fuel = initial_trit //Yogs -- prevents negative moles of Tritium
cached_gases[/datum/gas/tritium][MOLES] -= burned_fuel
air.adjust_moles(/datum/gas/tritium, -burned_fuel)
else
burned_fuel = initial_trit // Yogs -- Conservation of Mass fix
cached_gases[/datum/gas/tritium][MOLES] *= (1 - 1/TRITIUM_BURN_TRIT_FACTOR) // Yogs -- Maybe a tiny performance boost? I'unno
cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/tritium][MOLES]
air.set_moles(/datum/gas/tritium, air.get_moles(/datum/gas/tritium) * (1 - 1/TRITIUM_BURN_TRIT_FACTOR)) // Yogs -- Maybe a tiny performance boost? I'unno
air.adjust_moles(/datum/gas/oxygen, -air.get_moles(/datum/gas/tritium))
energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel * (TRITIUM_BURN_TRIT_FACTOR - 1)) // Yogs -- Fixes low-energy tritium fires
if(burned_fuel)
@@ -117,19 +116,19 @@
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)
ASSERT_GAS(/datum/gas/water_vapor, air) //oxygen+more-or-less hydrogen=H2O
cached_gases[/datum/gas/water_vapor][MOLES] += burned_fuel // Yogs -- Conservation of Mass
//oxygen+more-or-less hydrogen=H2O
air.adjust_moles(/datum/gas/water_vapor, burned_fuel )// Yogs -- Conservation of Mass
cached_results["fire"] += burned_fuel
if(energy_released > 0)
var/new_heat_capacity = air.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
if(istype(location))
temperature = air.temperature
temperature = air.return_temperature()
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location)
@@ -155,8 +154,7 @@
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
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.temperature
var/temperature = air.return_temperature()
var/list/cached_results = air.reaction_results
cached_results["fire"] = 0
var/turf/open/location = isturf(holder) ? holder : null
@@ -175,23 +173,21 @@
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(cached_gases[/datum/gas/oxygen][MOLES] / cached_gases[/datum/gas/plasma][MOLES] > 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
if(cached_gases[/datum/gas/oxygen][MOLES] > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/plasma)*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (air.get_moles(/datum/gas/plasma)*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen][MOLES]/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)
plasma_burn_rate = min(plasma_burn_rate,cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/oxygen][MOLES]/oxygen_burn_rate) //Ensures matter is conserved properly
cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate)
cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
plasma_burn_rate = min(plasma_burn_rate,air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/oxygen)/oxygen_burn_rate) //Ensures matter is conserved properly
air.set_moles(/datum/gas/plasma, QUANTIZE(air.get_moles(/datum/gas/plasma) - plasma_burn_rate))
air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) - (plasma_burn_rate * oxygen_burn_rate)))
if (super_saturation)
ASSERT_GAS(/datum/gas/tritium,air)
cached_gases[/datum/gas/tritium][MOLES] += plasma_burn_rate
air.adjust_moles(/datum/gas/tritium, plasma_burn_rate)
else
ASSERT_GAS(/datum/gas/carbon_dioxide,air)
cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate
air.adjust_moles(/datum/gas/carbon_dioxide, plasma_burn_rate)
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -200,11 +196,11 @@
if(energy_released > 0)
var/new_heat_capacity = air.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
if(istype(location))
temperature = air.temperature
temperature = air.return_temperature()
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location)
@@ -232,12 +228,11 @@
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
//Yogs start -- Cold Fusion
if(air.temperature < FUSION_TEMPERATURE_THRESHOLD)
if(!air.gases[/datum/gas/dilithium] || QUANTIZE(air.gases[/datum/gas/dilithium][MOLES]) <= 0)
if(air.return_temperature() < FUSION_TEMPERATURE_THRESHOLD)
if(!air.get_moles(/datum/gas/dilithium))
return
if(air.temperature < (FUSION_TEMPERATURE_THRESHOLD - FUSION_TEMPERATURE_THRESHOLD_MINIMUM) * NUM_E**( - air.gases[/datum/gas/dilithium][MOLES] * DILITHIUM_LAMBDA) + FUSION_TEMPERATURE_THRESHOLD_MINIMUM)
if(air.return_temperature() < (FUSION_TEMPERATURE_THRESHOLD - FUSION_TEMPERATURE_THRESHOLD_MINIMUM) * NUM_E**( - air.get_moles(/datum/gas/dilithium) * DILITHIUM_LAMBDA) + FUSION_TEMPERATURE_THRESHOLD_MINIMUM)
// This is an exponential decay equation, actually. Horizontal Asymptote is FUSION_TEMPERATURE_THRESHOLD_MINIMUM.
return
//Yogs End
@@ -252,13 +247,13 @@
var/list/cached_scan_results = air.analyzer_results
var/old_heat_capacity = air.heat_capacity()
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
var/initial_plasma = cached_gases[/datum/gas/plasma][MOLES]
var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide][MOLES]
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/toroidal_size = (2*PI)+TORADIANS(arctan((air.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/initial_plasma = air.get_moles(/datum/gas/plasma)
var/initial_carbon = air.get_moles(/datum/gas/carbon_dioxide)
var/scale_factor = (air.return_volume())/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.return_volume()-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/gas_power = 0
for (var/gas_id in cached_gases)
gas_power += (cached_gases[gas_id][GAS_META][META_GAS_FUSION_POWER]*cached_gases[gas_id][MOLES])
for (var/gas_id in air.get_gases())
gas_power += (GLOB.meta_gas_info[gas_id][META_GAS_FUSION_POWER]*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
cached_scan_results[id] = instability//used for analyzer feedback
@@ -270,9 +265,9 @@
carbon = MODULUS(carbon - plasma, toroidal_size)
cached_gases[/datum/gas/plasma][MOLES] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up
cached_gases[/datum/gas/carbon_dioxide][MOLES] = carbon*scale_factor + FUSION_MOLE_THRESHOLD
var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma][MOLES]
air.set_moles(/datum/gas/plasma, plasma*scale_factor + FUSION_MOLE_THRESHOLD )//Scales the gases back up
air.set_moles(/datum/gas/carbon_dioxide, carbon*scale_factor + FUSION_MOLE_THRESHOLD)
var/delta_plasma = initial_plasma - air.get_moles(/datum/gas/plasma)
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)
@@ -281,19 +276,17 @@
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
cached_gases[/datum/gas/plasma][MOLES] = initial_plasma
cached_gases[/datum/gas/carbon_dioxide][MOLES] = initial_carbon
air.set_moles(/datum/gas/plasma, initial_plasma)
air.set_moles(/datum/gas/carbon_dioxide, initial_carbon)
return NO_REACTION
cached_gases[/datum/gas/tritium][MOLES] -= 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
if(reaction_energy > 0)
air.assert_gases(/datum/gas/oxygen,/datum/gas/nitrous_oxide)
cached_gases[/datum/gas/oxygen][MOLES] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
cached_gases[/datum/gas/nitrous_oxide][MOLES] += 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))
air.adjust_moles(/datum/gas/nitrous_oxide, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
else
air.assert_gases(/datum/gas/bz,/datum/gas/nitryl)
cached_gases[/datum/gas/bz][MOLES] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
cached_gases[/datum/gas/nitryl][MOLES] += 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))
air.adjust_moles(/datum/gas/nitryl, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
if(reaction_energy)
if(location)
@@ -305,7 +298,7 @@
var/new_heat_capacity = air.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
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
@@ -322,23 +315,21 @@
)
/datum/gas_reaction/nitrylformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/temperature = air.temperature
var/temperature = air.return_temperature()
var/old_heat_capacity = air.heat_capacity()
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*60),cached_gases[/datum/gas/oxygen][MOLES],cached_gases[/datum/gas/nitrogen][MOLES])
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*60),air.get_moles(/datum/gas/oxygen),air.get_moles(/datum/gas/nitrogen))
var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
ASSERT_GAS(/datum/gas/nitryl,air)
if ((cached_gases[/datum/gas/oxygen][MOLES] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen][MOLES] - 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
cached_gases[/datum/gas/oxygen][MOLES] -= heat_efficency
cached_gases[/datum/gas/nitrogen][MOLES] -= heat_efficency
cached_gases[/datum/gas/nitryl][MOLES] += heat_efficency*2
air.adjust_moles(/datum/gas/oxygen, -heat_efficency)
air.adjust_moles(/datum/gas/nitrogen, -heat_efficency)
air.adjust_moles(/datum/gas/nitryl, heat_efficency*2)
if(energy_used > 0)
var/new_heat_capacity = air.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
/datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic.
@@ -354,29 +345,26 @@
/datum/gas_reaction/bzformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/temperature = air.temperature
var/temperature = air.return_temperature()
var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.5*ONE_ATMOSPHERE))*(max(cached_gases[/datum/gas/plasma][MOLES]/cached_gases[/datum/gas/nitrous_oxide][MOLES],1))),cached_gases[/datum/gas/nitrous_oxide][MOLES],cached_gases[/datum/gas/plasma][MOLES]/2)
var/reaction_efficency = min(1/((pressure/(0.5*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
if ((cached_gases[/datum/gas/nitrous_oxide][MOLES] - reaction_efficency < 0 )|| (cached_gases[/datum/gas/plasma][MOLES] - (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
ASSERT_GAS(/datum/gas/bz,air)
cached_gases[/datum/gas/bz][MOLES] += reaction_efficency
if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide][MOLES])
ASSERT_GAS(/datum/gas/oxygen,air)
cached_gases[/datum/gas/bz][MOLES] -= min(pressure,1)
cached_gases[/datum/gas/oxygen][MOLES] += min(pressure,1)
cached_gases[/datum/gas/nitrous_oxide][MOLES] -= reaction_efficency
cached_gases[/datum/gas/plasma][MOLES] -= 2*reaction_efficency
air.adjust_moles(/datum/gas/bz, reaction_efficency)
if(reaction_efficency == air.get_moles(/datum/gas/nitrous_oxide))
air.adjust_moles(/datum/gas/bz, -min(pressure,1))
air.adjust_moles(/datum/gas/oxygen, min(pressure,1))
air.adjust_moles(/datum/gas/nitrous_oxide, -reaction_efficency)
air.adjust_moles(/datum/gas/plasma, -2*reaction_efficency)
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)
var/new_heat_capacity = air.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
/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.
@@ -392,23 +380,21 @@
"TEMP" = STIMULUM_HEAT_SCALE/2)
/datum/gas_reaction/stimformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/old_heat_capacity = air.heat_capacity()
var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/plasma][MOLES],cached_gases[/datum/gas/nitryl][MOLES])
var/heat_scale = min(air.return_temperature()/STIMULUM_HEAT_SCALE,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)
ASSERT_GAS(/datum/gas/stimulum,air)
if ((cached_gases[/datum/gas/plasma][MOLES] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl][MOLES] - heat_scale < 0)) //Shouldn't produce gas from nothing.
if ((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
cached_gases[/datum/gas/stimulum][MOLES]+= heat_scale/10
cached_gases[/datum/gas/plasma][MOLES] -= heat_scale
cached_gases[/datum/gas/nitryl][MOLES] -= heat_scale
air.adjust_moles(/datum/gas/stimulum, heat_scale/10)
air.adjust_moles(/datum/gas/plasma, -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))
if(stim_energy_change)
var/new_heat_capacity = air.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
/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.
@@ -423,22 +409,20 @@
"TEMP" = 5000000)
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
air.assert_gases(/datum/gas/hypernoblium,/datum/gas/bz)
var/old_heat_capacity = air.heat_capacity()
var/nob_formed = min((cached_gases[/datum/gas/nitrogen][MOLES]+cached_gases[/datum/gas/tritium][MOLES])/100,cached_gases[/datum/gas/tritium][MOLES]/10,cached_gases[/datum/gas/nitrogen][MOLES]/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz][MOLES],1)))
if ((cached_gases[/datum/gas/tritium][MOLES] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen][MOLES] - 20*nob_formed < 0))
var/nob_formed = min((air.get_moles(/datum/gas/nitrogen)+air.get_moles(/datum/gas/tritium))/100,air.get_moles(/datum/gas/tritium)/10,air.get_moles(/datum/gas/nitrogen)/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(/datum/gas/bz),1)))
if ((air.get_moles(/datum/gas/tritium) - 10*nob_formed < 0) || (air.get_moles(/datum/gas/nitrogen) - 20*nob_formed < 0))
return NO_REACTION
cached_gases[/datum/gas/tritium][MOLES] -= 10*nob_formed
cached_gases[/datum/gas/nitrogen][MOLES] -= 20*nob_formed
cached_gases[/datum/gas/hypernoblium][MOLES]+= nob_formed
air.adjust_moles(/datum/gas/tritium, -10*nob_formed)
air.adjust_moles(/datum/gas/nitrogen, -20*nob_formed)
air.adjust_moles(/datum/gas/hypernoblium, nob_formed)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
if (nob_formed)
var/new_heat_capacity = air.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
@@ -453,18 +437,15 @@
)
/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
if(/datum/gas/water_vapor in cached_gases)
if(cached_gases[/datum/gas/water_vapor][MOLES]/air.total_moles() > 0.1) // Yogs --Fixes runtime in Sterilization
if(air.get_moles(/datum/gas/water_vapor)/air.total_moles() > 0.1) // Yogs --Fixes runtime in Sterilization
return
//Replace miasma with oxygen
var/cleaned_air = min(cached_gases[/datum/gas/miasma][MOLES], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
cached_gases[/datum/gas/miasma][MOLES] -= cleaned_air
ASSERT_GAS(/datum/gas/oxygen,air)
cached_gases[/datum/gas/oxygen][MOLES] += cleaned_air
var/cleaned_air = min(air.get_moles(/datum/gas/miasma), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
air.adjust_moles(/datum/gas/miasma, -cleaned_air)
air.adjust_moles(/datum/gas/oxygen, cleaned_air)
//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

View File

@@ -277,7 +277,7 @@
"unit" = "kPa",
"danger_level" = cur_tlv.get_danger_level(pressure)
))
var/temperature = environment.temperature
var/temperature = environment.return_temperature()
cur_tlv = TLV["temperature"]
data["environment_data"] += list(list(
"name" = "Temperature",
@@ -286,16 +286,16 @@
"danger_level" = cur_tlv.get_danger_level(temperature)
))
var/total_moles = environment.total_moles()
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
for(var/gas_id in environment.gases)
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
for(var/gas_id in environment.get_gases())
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue
cur_tlv = TLV[gas_id]
data["environment_data"] += list(list(
"name" = environment.gases[gas_id][GAS_META][META_GAS_NAME],
"value" = environment.gases[gas_id][MOLES] / total_moles * 100,
"name" = GLOB.meta_gas_info[gas_id][META_GAS_NAME],
"value" = environment.get_moles(gas_id) / total_moles * 100,
"unit" = "%",
"danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id][MOLES] * partial_pressure)
"danger_level" = cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)
))
if(!locked || user.has_unlimited_silicon_privilege)
@@ -639,24 +639,22 @@
var/datum/tlv/cur_tlv
var/datum/gas_mixture/environment = location.return_air()
var/list/env_gases = environment.gases
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.temperature / environment.volume
var/partial_pressure = R_IDEAL_GAS_EQUATION * environment.return_temperature() / environment.return_volume()
cur_tlv = TLV["pressure"]
var/environment_pressure = environment.return_pressure()
var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure)
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
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.
continue
cur_tlv = TLV[gas_id]
gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(env_gases[gas_id][MOLES] * partial_pressure))
gas_dangerlevel = max(gas_dangerlevel, cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure))
environment.garbage_collect()
var/old_danger_level = danger_level
danger_level = max(pressure_dangerlevel, temperature_dangerlevel, gas_dangerlevel)

View File

@@ -51,10 +51,10 @@
return null
//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/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

View File

@@ -70,8 +70,8 @@
pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min))
if(pressure_delta > 0)
if(air1.temperature > 0)
var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
if(air1.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
//Removed can be null if there is no atmosphere in air1
@@ -85,20 +85,18 @@
parent1.update = 1
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)
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_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)
pressure_delta = min(pressure_delta, (output_pressure_max - air2.return_pressure()))
moles_delta = min(moles_delta, (input_pressure_min - air2.return_pressure()) * our_multiplier)
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)
if(moles_delta > 0)
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if (isnull(removed)) // in space
return
air2.merge(removed)
@@ -186,8 +184,8 @@
..()
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
air1.volume = 1000
air2.volume = 1000
air1.set_volume(1000)
air2.set_volume(1000)
// Mapping

View File

@@ -53,11 +53,11 @@ Passive gate is similar to the regular pump except:
return
//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)
//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
var/datum/gas_mixture/removed = air1.remove(transfer_moles)

View File

@@ -63,9 +63,9 @@
return
//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/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
var/datum/gas_mixture/removed = air1.remove(transfer_moles)

View File

@@ -67,7 +67,7 @@
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)
@@ -166,7 +166,7 @@
if("set_transfer_rate" in signal.data)
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)
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)

View File

@@ -16,8 +16,7 @@
..()
for(var/i in 1 to device_type)
var/datum/gas_mixture/A = new
A.volume = 200
var/datum/gas_mixture/A = new(200)
airs[i] = A
// Iconnery
@@ -119,7 +118,7 @@
var/times_lost = 0
for(var/i in 1 to device_type)
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++
var/shared_loss = lost/times_lost

View File

@@ -70,7 +70,7 @@
//Early return
var/datum/gas_mixture/air1 = airs[1]
if(!air1 || air1.temperature <= 0)
if(!air1 || air1.return_temperature() <= 0)
return
var/datum/gas_mixture/air2 = airs[2]
@@ -82,7 +82,7 @@
//No need to transfer if target is already full!
return
var/transfer_ratio = transfer_rate/air1.volume
var/transfer_ratio = transfer_rate/air1.return_volume()
//Actually transfer the gas
@@ -101,15 +101,13 @@
else
filtering = FALSE
if(filtering && removed.gases[filter_type])
if(filtering && removed.get_moles(filter_type))
var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature
filtered_out.add_gas(filter_type)
filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES]
filtered_out.set_temperature(removed.return_temperature())
filtered_out.set_moles(filter_type, removed.get_moles(filter_type))
removed.gases[filter_type][MOLES] = 0
removed.garbage_collect()
removed.set_moles(filter_type, 0)
var/datum/gas_mixture/target = (air2.return_pressure() < MAX_OUTPUT_PRESSURE ? air2 : air1) //if there's no room for the filtered gas; just leave it in air1
target.merge(filtered_out)

View File

@@ -58,7 +58,7 @@
/obj/machinery/atmospherics/components/trinary/mixer/New()
..()
var/datum/gas_mixture/air3 = airs[3]
air3.volume = 300
air3.set_volume(300)
airs[3] = air3
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
@@ -82,26 +82,26 @@
return
//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_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0
var/transfer_moles1 = air1.return_temperature() ? node1_concentration * general_transfer / air1.return_temperature() : 0
var/transfer_moles2 = air2.return_temperature() ? node2_concentration * general_transfer / air2.return_temperature() : 0
var/air1_moles = air1.total_moles()
var/air2_moles = air2.total_moles()
if(!node2_concentration)
if(air1.temperature <= 0)
if(air1.return_temperature() <= 0)
return
transfer_moles1 = min(transfer_moles1, air1_moles)
transfer_moles2 = 0
else if(!node1_concentration)
if(air2.temperature <= 0)
if(air2.return_temperature() <= 0)
return
transfer_moles2 = min(transfer_moles2, air2_moles)
transfer_moles1 = 0
else
if(air1.temperature <= 0 || air2.temperature <= 0)
if(air1.return_temperature() <= 0 || air2.return_temperature() <= 0)
return
if((transfer_moles2 <= 0) || (transfer_moles1 <= 0))
return

View File

@@ -194,7 +194,7 @@
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.
mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000)
mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000)
@@ -202,8 +202,7 @@
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
air1.gases[/datum/gas/oxygen][MOLES] -= max(0,air1.gases[/datum/gas/oxygen][MOLES] - 2 / efficiency) //Let's use gas for this
air1.garbage_collect()
air1.adjust_moles(/datum/gas/oxygen, -max(0,air1.get_moles(/datum/gas/oxygen) - 2 / efficiency)) //Let's use gas for this
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -217,7 +216,7 @@
var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 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
update_icon()
return
@@ -225,22 +224,21 @@
if(occupant)
var/mob/living/mob_occupant = occupant
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))
var/mob/living/carbon/human/H = occupant
cold_protection = H.get_cold_protection(air1.temperature)
cold_protection = H.get_cold_protection(air1.return_temperature())
if(abs(temperature_delta) > 1)
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))
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)
air1.gases[/datum/gas/oxygen][MOLES] = max(0,air1.gases[/datum/gas/oxygen][MOLES] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic.
air1.garbage_collect()
air1.set_moles(/datum/gas/oxygen, max(0,air1.get_moles(/datum/gas/oxygen) - 0.5 / efficiency)) // Magically consume gas? Why not, we run on cryo magic.
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..()
@@ -376,7 +374,7 @@
data["occupant"]["temperaturestatus"] = "bad"
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
var/beakerContents = list()
@@ -431,7 +429,7 @@
var/datum/gas_mixture/G = airs[1]
if(G.total_moles() > 10)
return G.temperature
return G.return_temperature()
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)

View File

@@ -59,18 +59,18 @@
var/other_air_heat_capacity = partner_air_contents.heat_capacity()
var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature
var/other_old_temperature = partner_air_contents.temperature
var/old_temperature = air_contents.return_temperature()
var/other_old_temperature = partner_air_contents.return_temperature()
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
air_contents.temperature = new_temperature
partner_air_contents.temperature = new_temperature
air_contents.set_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()
if(abs(other_old_temperature-partner_air_contents.temperature) > 1)
if(abs(other_old_temperature-partner_air_contents.return_temperature()) > 1)
partner.update_parents()

View File

@@ -54,8 +54,8 @@
var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.temperature > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -73,8 +73,8 @@
injecting = 1
if(air_contents.temperature > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
update_parents()
@@ -125,7 +125,7 @@
if("set_volume_rate" in signal.data)
var/number = text2num(signal.data["set_volume_rate"])
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)
spawn(2)

View File

@@ -18,7 +18,7 @@
/obj/machinery/atmospherics/components/unary/portables_connector/New()
..()
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()
if(connected_device)

View File

@@ -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
icon = 'icons/obj/atmospherics/pipes/pressure_tank.dmi'
icon_state = "generic"
@@ -17,12 +17,11 @@
/obj/machinery/atmospherics/components/unary/tank/New()
..()
var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = volume
air_contents.temperature = T20C
air_contents.set_volume(volume)
air_contents.set_temperature(T20C)
if(gas_type)
air_contents.assert_gas(gas_type)
air_contents.gases[gas_type][MOLES] = AIR_CONTENTS
name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])"
air_contents.set_moles(AIR_CONTENTS)
name = "[name] ([GLOB.meta_gas_info[gas_type][META_GAS_NAME]])"
setPipingLayer(piping_layer)
@@ -33,9 +32,8 @@
/obj/machinery/atmospherics/components/unary/tank/air/New()
..()
var/datum/gas_mixture/air_contents = airs[1]
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = AIR_CONTENTS * 0.2
air_contents.gases[/datum/gas/nitrogen][MOLES] = AIR_CONTENTS * 0.8
air_contents.set_moles(/datum/gas/oxygen, AIR_CONTENTS * 0.2)
air_contents.set_moles(/datum/gas/nitrogen, AIR_CONTENTS * 0.8)
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
gas_type = /datum/gas/carbon_dioxide

View File

@@ -64,13 +64,13 @@
var/air_heat_capacity = air_contents.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)
var/combined_energy = heat_capacity * target_temperature + air_heat_capacity * air_contents.temperature
air_contents.temperature = combined_energy/combined_heat_capacity
var/combined_energy = heat_capacity * target_temperature + air_heat_capacity * air_contents.return_temperature()
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)
active_power_usage = (heat_capacity * temperature_delta) / 10 + idle_power_usage
update_parents()
@@ -132,7 +132,7 @@
data["initial"] = initial(target_temperature)
var/datum/gas_mixture/air1 = airs[1]
data["temperature"] = air1.temperature
data["temperature"] = air1.return_temperature()
data["pressure"] = air1.return_pressure()
return data

View File

@@ -47,7 +47,7 @@
if(!id_tag)
id_tag = assign_uid_vents()
var/datum/gas_mixture/N = airs[1]
N.volume = 1000 // Increase the volume of the air vent's node.
N.set_volume(1000) // Increase the volume of the air vent's node.
// Allows it to pump much faster.
/obj/machinery/atmospherics/components/unary/vent_pump/Destroy()
@@ -152,9 +152,9 @@
pressure_delta = min(pressure_delta, 10)
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)
last_moles_added = transfer_moles
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -164,16 +164,16 @@
else // external -> internal
last_moles_added = 0
var/pressure_delta = 10000
if(environment.return_pressure() > 0)
var/our_multiplier = air_contents.return_volume() / (environment.return_temperature() * R_IDEAL_GAS_EQUATION)
var/moles_delta = 10000 * our_multiplier
if(pressure_checks&EXT_BOUND)
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
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)
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure()))
moles_delta = min(moles_delta, (internal_pressure_bound - air_contents.return_pressure()) * our_multiplier)
if(pressure_delta > 0 && environment.temperature > 0)
var/transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
if(moles_delta > 0)
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if (isnull(removed)) // in space
return
@@ -352,7 +352,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New()
..()
var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 1000
air_contents.set_volume(1000)
// mapping

View File

@@ -151,14 +151,12 @@
return FALSE
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
return FALSE
if(scrubbing & SCRUBBING)
if(length(env_gases & filter_types))
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
var/transfer_moles = min(1, volume_rate/environment.return_volume())*environment.total_moles()
//Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
@@ -167,28 +165,15 @@
if(isnull(removed))
return FALSE
var/list/removed_gases = removed.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_out.add_gas(gas)
filtered_gases[gas][MOLES] = removed_gases[gas][MOLES]
removed_gases[gas][MOLES] = 0
removed.garbage_collect()
removed.scrub_into(air_contents, filter_types)
//Remix the resulting gases
air_contents.merge(filtered_out)
tile.assume_air(removed)
tile.air_update_turf()
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)

View File

@@ -15,7 +15,7 @@
/datum/pipeline/Destroy()
SSair.networks -= src
if(air && air.volume)
if(air && air.return_volume())
temporarily_store_air()
for(var/obj/machinery/atmospherics/pipe/P in members)
P.parent = null
@@ -74,7 +74,7 @@
possible_expansions -= borderline
air.volume = volume
air.set_volume(volume)
/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/components/C)
other_atmosmch |= C
@@ -97,7 +97,7 @@
merge(E)
if(!members.Find(P))
members += P
air.volume += P.volume
air.set_volume(air.return_volume() + P.volume)
else
A.setPipenet(src, N)
addMachineryMember(A)
@@ -105,7 +105,7 @@
/datum/pipeline/proc/merge(datum/pipeline/E)
if(E == src)
return
air.volume += E.air.volume
air.set_volume(air.return_volume() + E.air.return_volume())
members.Add(E.members)
for(var/obj/machinery/atmospherics/pipe/S in E.members)
S.parent = src
@@ -138,18 +138,16 @@
for(var/obj/machinery/atmospherics/pipe/member in members)
member.air_temporary = new
member.air_temporary.volume = member.volume
member.air_temporary.set_volume(member.volume)
member.air_temporary.copy_from(air)
var/member_gases = member.air_temporary.gases
for(var/id in member_gases)
member_gases[id][MOLES] *= member.volume/air.volume
member.air_temporary.multiply(member.volume/air.return_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)
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_heat_capacity
@@ -162,19 +160,19 @@
if(modeled_location.blocks_air)
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* \
(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)
else
var/delta_temperature = 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
var/self_temperature_delta = 0
@@ -189,18 +187,18 @@
else
return 1
air.temperature += self_temperature_delta
air.set_temperature(air.return_temperature() + self_temperature_delta);
modeled_location.TakeTemperature(sharer_temperature_delta)
else
if((target.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* \
(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
/datum/pipeline/proc/return_air()
@@ -231,35 +229,17 @@
if(C.connected_device)
GL += C.connected_device.air_contents
var/total_thermal_energy = 0
var/total_heat_capacity = 0
var/datum/gas_mixture/total_gas_mixture = new(0)
var/list/total_gases = total_gas_mixture.gases
var/total_volume = 0
for(var/i in GL)
var/datum/gas_mixture/G = i
total_gas_mixture.volume += G.volume
total_gas_mixture.merge(G)
total_volume += G.return_volume()
// This is sort of a combined merge + heat_capacity calculation
var/list/giver_gases = G.gases
//gas transfer
for(var/giver_id in giver_gases)
var/giver_gas_data = giver_gases[giver_id]
ASSERT_GAS(giver_id, total_gas_mixture)
total_gases[giver_id][MOLES] += giver_gas_data[MOLES]
total_heat_capacity += giver_gas_data[MOLES] * giver_gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
total_thermal_energy += THERMAL_ENERGY(G)
total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0
if(total_gas_mixture.volume > 0)
if(total_volume > 0)
//Update individual gas_mixtures by volume ratio
for(var/i in GL)
var/datum/gas_mixture/G = i
G.copy_from(total_gas_mixture)
var/list/G_gases = G.gases
for(var/id in G_gases)
G_gases[id][MOLES] *= G.volume/total_gas_mixture.volume
G.multiply(G.return_volume()/total_volume)

View File

@@ -103,7 +103,7 @@
if (target)
var/datum/gas_mixture/environment = target.return_air()
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
. = "The sensor error light is blinking."
else

View File

@@ -131,9 +131,8 @@
if(!isopenturf(O))
return FALSE
var/datum/gas_mixture/merger = new
merger.assert_gas(spawn_id)
merger.gases[spawn_id][MOLES] = (spawn_mol)
merger.temperature = spawn_temp
merger.set_moles(spawn_id, spawn_mol)
merger.set_temperature(spawn_temp)
O.assume_air(merger)
O.air_update_turf(TRUE)

View File

@@ -28,14 +28,14 @@
if(islava(T))
environment_temperature = 5000
else if(T.blocks_air)
environment_temperature = T.temperature
environment_temperature = T.return_temperature()
else
var/turf/open/OT = T
environment_temperature = OT.GetTemperature()
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)
@@ -44,11 +44,11 @@
var/hc = pipe_air.heat_capacity()
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
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)
var/mob/living/L = m
L.bodytemperature = avg_temp
pipe_air.temperature = avg_temp
pipe_air.set_temperature(avg_temp)
/obj/machinery/atmospherics/pipe/heat_exchanging/process()
if(!parent)
@@ -57,9 +57,9 @@
var/datum/gas_mixture/pipe_air = return_air()
//Heat causes pipe to glow
if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //glow starts at 500K
if(abs(pipe_air.temperature - icon_temperature) > 10)
icon_temperature = pipe_air.temperature
if(pipe_air.return_temperature() && (icon_temperature > 500 || pipe_air.return_temperature() > 500)) //glow starts at 500K
if(abs(pipe_air.return_temperature() - icon_temperature) > 10)
icon_temperature = pipe_air.return_temperature()
var/h_r = heat2colour_r(icon_temperature)
var/h_g = heat2colour_g(icon_temperature)
@@ -76,7 +76,7 @@
//burn any mobs buckled based on temperature
if(has_buckled_mobs())
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)
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)

View File

@@ -212,16 +212,15 @@
/obj/machinery/portable_atmospherics/canister/proc/create_gas()
if(gas_type)
air_contents.add_gas(gas_type)
if(starter_temp)
air_contents.temperature = starter_temp
air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
if(starter_temp)
air_contents.temperature = starter_temp
air_contents.set_temperature(starter_temp)
air_contents.set_moles(gas_type, (maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
/obj/machinery/portable_atmospherics/canister/air/create_gas()
air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
air_contents.gases[/datum/gas/nitrogen][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
if(starter_temp)
air_contents.set_temperature(starter_temp)
air_contents.set_moles(/datum/gas/oxygen, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
#define CANISTER_UPDATE_HOLDING (1<<0)
#define CANISTER_UPDATE_CONNECTED (1<<1)
@@ -445,12 +444,11 @@
logmsg = "Valve was <b>opened</b> by [key_name(usr)], starting a transfer into \the [holding || "air"].<br>"
if(!holding)
var/list/danger = list()
for(var/id in air_contents.gases)
var/gas = air_contents.gases[id]
if(!gas[GAS_META][META_GAS_DANGER])
for(var/id in air_contents.get_gases())
if(!GLOB.meta_gas_info[id][META_GAS_DANGER])
continue
if(gas[MOLES] > (gas[GAS_META][META_GAS_MOLES_VISIBLE] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[gas[GAS_META][META_GAS_NAME]] = gas[MOLES] //ex. "plasma" = 20
if(air_contents.get_moles(id) > (GLOB.meta_gas_info[id][META_GAS_MOLES_VISIBLE] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[GLOB.meta_gas_info[id][META_GAS_NAME]] = air_contents.get_moles(id) //ex. "plasma" = 20
if(danger.len)
message_admins("[ADMIN_LOOKUPFLW(usr)] opened a canister that contains the following at [ADMIN_VERBOSEJMP(src)]:")

View File

@@ -18,9 +18,8 @@
..()
SSair.atmos_machinery += src
air_contents = new
air_contents.volume = volume
air_contents.temperature = T20C
air_contents = new(volume)
air_contents.set_temperature(T20C)
return 1

View File

@@ -113,8 +113,8 @@
if("power")
on = !on
if(on && !holding)
var/plasma = air_contents.gases[/datum/gas/plasma]
var/n2o = air_contents.gases[/datum/gas/nitrous_oxide]
var/plasma = air_contents.get_moles(/datum/gas/plasma)
var/n2o = air_contents.get_moles(/datum/gas/nitrous_oxide)
if(n2o || plasma)
message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [ADMIN_VERBOSEJMP(src)]")
log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [AREACOORD(src)]")

View File

@@ -40,21 +40,14 @@
if(air_contents.return_pressure() >= overpressure_m * ONE_ATMOSPHERE)
return
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/filtered = new
if(!filtering)
return
filtered.temperature = filtering.temperature
for(var/gas in filtering.gases & scrubbing)
filtered.add_gas(gas)
filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture.
filtering.gases[gas][MOLES] = 0
filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture.
filtering.scrub_into(air_contents, scrubbing)
air_contents.merge(filtered) // Store filtered out gasses.
mixture.merge(filtering) // Returned the cleaned gas.
if(!holding)
air_update_turf()

View File

@@ -10,9 +10,7 @@
if(!..())
return FALSE
var/obj/item/tank/T = O
if(!T.air_contents.gases[gas_type])
return FALSE
return T.air_contents.gases[gas_type][MOLES] >= moles_required
return T.air_contents.get_moles(gas_type) >= moles_required
/datum/bounty/item/engineering/gas/nitryl_tank
name = "Full Tank of Nitryl"

View File

@@ -129,13 +129,11 @@
/datum/export/large/gas_canister/get_cost(obj/O)
var/obj/machinery/portable_atmospherics/canister/C = O
var/worth = 10
var/gases = C.air_contents.gases
C.air_contents.assert_gases(/datum/gas/bz,/datum/gas/stimulum,/datum/gas/hypernoblium,/datum/gas/miasma,/datum/gas/tritium,/datum/gas/pluoxium)
worth += gases[/datum/gas/bz][MOLES]*4
worth += gases[/datum/gas/stimulum][MOLES]*100
worth += gases[/datum/gas/hypernoblium][MOLES]*1000
worth += gases[/datum/gas/miasma][MOLES]*10
worth += gases[/datum/gas/tritium][MOLES]*5
worth += gases[/datum/gas/pluoxium][MOLES]*5
worth += C.air_contents.get_moles(/datum/gas/bz)*4
worth += C.air_contents.get_moles(/datum/gas/stimulum)*100
worth += C.air_contents.get_moles(/datum/gas/hypernoblium)*1000
worth += C.air_contents.get_moles(/datum/gas/miasma)*10
worth += C.air_contents.get_moles(/datum/gas/tritium)*5
worth += C.air_contents.get_moles(/datum/gas/pluoxium)*5
return worth

View File

@@ -170,10 +170,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/oxygen])
return
GM.gases[/datum/gas/oxygen][MOLES] = max(GM.gases[/datum/gas/oxygen][MOLES] - severity * holder.energy, 0)
GM.garbage_collect()
GM.set_moles(/datum/gas/oxygen, max(GM.get_moles(/datum/gas/oxygen) - severity * holder.energy, 0))
/datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming"
@@ -185,10 +182,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/nitrogen])
return
GM.gases[/datum/gas/nitrogen][MOLES] = max(GM.gases[/datum/gas/nitrogen][MOLES] - severity * holder.energy, 0)
GM.garbage_collect()
GM.set_moles(/datum/gas/nitrogen, max(GM.get_moles(/datum/gas/nitrogen) - severity * holder.energy, 0))
/datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming"
@@ -200,10 +194,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/carbon_dioxide])
return
GM.gases[/datum/gas/carbon_dioxide][MOLES] = max(GM.gases[/datum/gas/carbon_dioxide][MOLES] - severity * holder.energy, 0)
GM.garbage_collect()
GM.set_moles(/datum/gas/carbon_dioxide, max(GM.get_moles(/datum/gas/carbon_dioxide) - severity * holder.energy, 0))
/datum/spacevine_mutation/plasma_eater
name = "toxins consuming"
@@ -215,10 +206,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
if(!GM.gases[/datum/gas/plasma])
return
GM.gases[/datum/gas/plasma][MOLES] = max(GM.gases[/datum/gas/plasma][MOLES] - severity * holder.energy, 0)
GM.garbage_collect()
GM.set_moles(/datum/gas/plasma, max(GM.get_moles(/datum/gas/plasma) - severity * holder.energy, 0))
/datum/spacevine_mutation/thorns
name = "thorny"

View File

@@ -56,9 +56,8 @@
return
var/datum/gas_mixture/stank = new
ADD_GAS(/datum/gas/miasma, stank.gases)
stank.gases[/datum/gas/miasma][MOLES] = (yield + 6)*7*MIASMA_CORPSE_MOLES // 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_moles(/datum/gas/miasma, (yield + 6)*7*MIASMA_CORPSE_MOLES) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
stank.set_temperature(T20C) // without this the room would eventually freeze and miasma mining would be easier
T.assume_air(stank)
T.air_update_turf()

View File

@@ -229,8 +229,7 @@
if(isopenturf(loc))
var/turf/open/O = loc
if(O.air)
var/loc_gases = O.air.gases
if(loc_gases[/datum/gas/oxygen][MOLES] > 13)
if(O.air.get_moles(/datum/gas/oxygen) > 13)
return TRUE
return FALSE

View File

@@ -142,6 +142,7 @@
var/list/modelCache = build_cache(no_changeturf)
var/space_key = modelCache[SPACE_KEY]
var/list/bounds
var/did_expand = FALSE
src.bounds = bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
for(var/I in gridSets)
@@ -150,6 +151,7 @@
var/zcrd = gset.zcrd + z_offset - 1
if(!cropMap && ycrd > world.maxy)
world.maxy = ycrd // Expand Y here. X is expanded in the loop below
did_expand = TRUE
var/zexpansion = zcrd > world.maxz
if(zexpansion)
if(cropMap)
@@ -157,6 +159,7 @@
else
while (zcrd > world.maxz) //create a new z_level if needed
world.incrementMaxZ()
did_expand = FALSE
if(!no_changeturf)
WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/AfterChange is called")
@@ -175,6 +178,7 @@
break
else
world.maxx = xcrd
did_expand = TRUE
if(xcrd >= 1)
var/model_key = copytext(line, tpos, tpos + key_len)
@@ -213,6 +217,9 @@
testing("Skipped loading [turfsSkipped] default turfs")
#endif
if(did_expand)
world.refresh_atmos_grid()
return TRUE
/datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null)

View File

@@ -12,28 +12,23 @@
var/toxins_used = 0
var/tox_detect_threshold = 0.02
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/list/breath_gases = breath.gases
breath.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath_gases[/datum/gas/plasma][MOLES]/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
adjustPlasma(breath_gases[/datum/gas/plasma][MOLES]*250)
adjustPlasma(breath.get_moles(/datum/gas/plasma)*250)
throw_alert("alien_tox", /obj/screen/alert/alien_tox)
toxins_used = breath_gases[/datum/gas/plasma][MOLES]
toxins_used = breath.get_moles(/datum/gas/plasma)
else
clear_alert("alien_tox")
//Breathe in toxins and out oxygen
breath_gases[/datum/gas/plasma][MOLES] -= toxins_used
breath_gases[/datum/gas/oxygen][MOLES] += toxins_used
breath.garbage_collect()
breath.adjust_moles(/datum/gas/plasma, -toxins_used)
breath.adjust_moles(/datum/gas/oxygen, toxins_used)
//BREATH TEMPERATURE
handle_breath_temperature(breath)

View File

@@ -32,7 +32,7 @@
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.total_moles())
if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 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)
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>")

View File

@@ -162,13 +162,11 @@
var/SA_para_min = 1
var/SA_sleep_min = 5
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
breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz)
var/O2_partialpressure = (breath_gases[/datum/gas/oxygen][MOLES]/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide][MOLES]/breath.total_moles())*breath_pressure
var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/breath.total_moles())*breath_pressure
//OXYGEN
@@ -179,7 +177,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1
oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]*ratio
oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
else
adjustOxyLoss(3)
failed_last_breath = 1
@@ -189,11 +187,11 @@
failed_last_breath = 0
if(health >= crit_threshold)
adjustOxyLoss(-5)
oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]
oxygen_used = breath.get_moles(/datum/gas/oxygen)
clear_alert("not_enough_oxy")
breath_gases[/datum/gas/oxygen][MOLES] -= oxygen_used
breath_gases[/datum/gas/carbon_dioxide][MOLES] += oxygen_used
breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
//CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max)
@@ -212,15 +210,15 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/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))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
//NITROUS OXIDE
if(breath_gases[/datum/gas/nitrous_oxide])
var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide][MOLES]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/nitrous_oxide))
var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
Unconscious(60)
if(SA_partialpressure > SA_sleep_min)
@@ -234,8 +232,8 @@
//yogs start -- Adds Nitrogen Narcosis https://en.wikipedia.org/wiki/Nitrogen_narcosis
//NITROGEN
if(breath_gases[/datum/gas/nitrogen])
var/SA_partialpressure = (breath_gases[/datum/gas/nitrogen][MOLES]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/nitrogen))
var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrogen)/breath.total_moles())*breath_pressure
if(SA_partialpressure > NITROGEN_NARCOSIS_PRESSURE_LOW) // Giggles
if(prob(20))
emote(pick("giggle","laugh"))
@@ -246,8 +244,8 @@
hallucination += 5
//yogs end
//BZ (Facepunch port of their Agent B)
if(breath_gases[/datum/gas/bz])
var/bz_partialpressure = (breath_gases[/datum/gas/bz][MOLES]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/bz))
var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
/* Yogs comment-out: Smoothed BZ hallucination levels
if(bz_partialpressure > 1)
hallucination += 10
@@ -257,18 +255,18 @@
hallucination += round(BZ_MAX_HALLUCINATION * (1 - NUM_E ** (-BZ_LAMBDA * bz_partialpressure))) // Yogs -- Better BZ hallucination values. Keep in mind that hallucination has to be an integer value, due to how it's handled in handle_hallucination()
//TRITIUM
if(breath_gases[/datum/gas/tritium])
var/tritium_partialpressure = (breath_gases[/datum/gas/tritium][MOLES]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/tritium))
var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
radiation += tritium_partialpressure/10
//NITRYL
if(breath_gases[/datum/gas/nitryl])
var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl][MOLES]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/nitryl))
var/nitryl_partialpressure = (breath.get_moles(/datum/gas/nitryl)/breath.total_moles())*breath_pressure
adjustFireLoss(nitryl_partialpressure/4)
//MIASMA
if(breath_gases[/datum/gas/miasma])
var/miasma_partialpressure = (breath_gases[/datum/gas/miasma][MOLES]/breath.total_moles())*breath_pressure
if(breath.get_moles(/datum/gas/miasma))
var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
if(prob(1 * miasma_partialpressure))
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3)
@@ -308,10 +306,6 @@
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
breath.garbage_collect()
//BREATH TEMPERATURE
handle_breath_temperature(breath)

View File

@@ -50,8 +50,8 @@
return ..()
/mob/living/carbon/monkey/handle_breath_temperature(datum/gas_mixture/breath)
if(abs(BODYTEMP_NORMAL - breath.temperature) > 50)
switch(breath.temperature)
if(abs(BODYTEMP_NORMAL - breath.return_temperature()) > 50)
switch(breath.return_temperature())
if(-INFINITY to 120)
adjustFireLoss(3)
if(120 to 200)

View File

@@ -112,7 +112,7 @@
ExtinguishMob()
return TRUE //mob was put out, on_fire = FALSE via ExtinguishMob(), no need to update everything down the chain.
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(!G.gases[/datum/gas/oxygen] || G.gases[/datum/gas/oxygen][MOLES] < 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
return TRUE
var/turf/location = get_turf(src)

View File

@@ -848,7 +848,7 @@
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
/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))
var/obj/oloc = loc
var/obj_temp = oloc.return_temperature()

View File

@@ -557,7 +557,6 @@
dat += "Unable to obtain a reading.<br>"
else
var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.gases
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
@@ -565,11 +564,11 @@
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles)
for(var/id in env_gases)
var/gas_level = env_gases[id][MOLES]/total_moles
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0.01)
dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "[GLOB.meta_gas_info[id][META_GAS_NAME]]: [round(gas_level*100)]%<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 += "<br>"
return dat

View File

@@ -44,12 +44,12 @@
..()
if(isopenturf(loc))
var/turf/open/T = src.loc
if(T.air && T.air.gases[/datum/gas/carbon_dioxide])
var/co2 = T.air.gases[/datum/gas/carbon_dioxide][MOLES]
if(T.air)
var/co2 = T.air.get_moles(/datum/gas/carbon_dioxide)
if(co2 > 0)
if(prob(25))
var/amt = min(co2, 9)
T.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt
T.air.adjust_moles(/datum/gas/carbon_dioxide, -amt)
T.atmos_spawn_air("o2=[amt]")
/mob/living/simple_animal/hostile/tree/AttackingTarget()

View File

@@ -213,15 +213,11 @@
if(isturf(src.loc) && isopenturf(src.loc))
var/turf/open/ST = src.loc
if(ST.air)
var/ST_gases = ST.air.gases
ST.air.assert_gases(arglist(GLOB.hardcoded_gases))
var/tox = ST_gases[/datum/gas/plasma][MOLES]
var/oxy = ST_gases[/datum/gas/oxygen][MOLES]
var/n2 = ST_gases[/datum/gas/nitrogen][MOLES]
var/co2 = ST_gases[/datum/gas/carbon_dioxide][MOLES]
ST.air.garbage_collect()
var/tox = ST.air.get_moles(/datum/gas/plasma)
var/oxy = ST.air.get_moles(/datum/gas/oxygen)
var/n2 = ST.air.get_moles(/datum/gas/nitrogen)
var/co2 = ST.air.get_moles(/datum/gas/carbon_dioxide)
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
. = FALSE

View File

@@ -133,9 +133,7 @@
Tempstun = 0
if(stat != DEAD)
var/bz_percentage =0
if(environment.gases[/datum/gas/bz])
bz_percentage = environment.gases[/datum/gas/bz][MOLES] / environment.total_moles()
var/bz_percentage = environment.total_moles() ? (environment.get_moles(/datum/gas/bz) / environment.total_moles()) : 0
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
if(stat == CONSCIOUS && stasis)

View File

@@ -64,11 +64,10 @@
var/datum/gas_mixture/environment = loc.return_air()
var/t = "<span class='notice'>Coordinates: [x],[y] \n</span>"
t += "<span class='danger'>Temperature: [environment.temperature] \n</span>"
for(var/id in environment.gases)
var/gas = environment.gases[id]
if(gas[MOLES])
t+="<span class='notice'>[gas[GAS_META][META_GAS_NAME]]: [gas[MOLES]] \n</span>"
t += "<span class='danger'>Temperature: [environment.return_temperature()] \n</span>"
for(var/id in environment.get_gases())
if(environment.get_moles(id))
t+="<span class='notice'>[GLOB.meta_gas_info[id][META_GAS_NAME]]: [environment.get_moles(id)] \n</span>"
to_chat(usr, t)

View File

@@ -72,22 +72,22 @@
data["active"] = TRUE
data["SM_integrity"] = active.get_integrity()
data["SM_power"] = active.power
data["SM_ambienttemp"] = air.temperature
data["SM_ambienttemp"] = air.return_temperature()
data["SM_ambientpressure"] = air.return_pressure()
//data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01)
var/list/gasdata = list()
if(air.total_moles())
for(var/gasid in air.gases)
for(var/gasid in air.get_gases())
gasdata.Add(list(list(
"name"= air.gases[gasid][GAS_META][META_GAS_NAME],
"amount" = round(100*air.gases[gasid][MOLES]/air.total_moles(),0.01))))
"name"= GLOB.meta_gas_info[gasid][META_GAS_NAME],
"amount" = round(100*air.get_moles(gasid)/air.total_moles(),0.01))))
else
for(var/gasid in air.gases)
for(var/gasid in air.get_gases())
gasdata.Add(list(list(
"name"= air.gases[gasid][GAS_META][META_GAS_NAME],
"name"= GLOB.meta_gas_info[gasid][META_GAS_NAME],
"amount" = 0)))
data["gases"] = gasdata

View File

@@ -61,7 +61,7 @@
var/cold_air_heat_capacity = cold_air.heat_capacity()
var/hot_air_heat_capacity = hot_air.heat_capacity()
var/delta_temperature = hot_air.temperature - cold_air.temperature
var/delta_temperature = hot_air.return_temperature() - cold_air.return_temperature()
if(delta_temperature > 0 && cold_air_heat_capacity > 0 && hot_air_heat_capacity > 0)
@@ -72,8 +72,8 @@
var/heat = energy_transfer*(1-efficiency)
lastgen += energy_transfer*efficiency
hot_air.temperature = hot_air.temperature - energy_transfer/hot_air_heat_capacity
cold_air.temperature = cold_air.temperature + heat/cold_air_heat_capacity
hot_air.set_temperature(hot_air.return_temperature() - energy_transfer/hot_air_heat_capacity)
cold_air.set_temperature(cold_air.return_temperature() + heat/cold_air_heat_capacity)
//add_avail(lastgen) This is done in process now
// update icon overlays only if displayed level has changed
@@ -120,11 +120,11 @@
t += "<BR>"
t += "<B><font color='blue'>Cold loop</font></B><BR>"
t += "Temperature Inlet: [round(cold_circ_air2.temperature, 0.1)] K / Outlet: [round(cold_circ_air1.temperature, 0.1)] K<BR>"
t += "Temperature Inlet: [round(cold_circ_air2.return_temperature(), 0.1)] K / Outlet: [round(cold_circ_air1.return_temperature(), 0.1)] K<BR>"
t += "Pressure Inlet: [round(cold_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(cold_circ_air1.return_pressure(), 0.1)] kPa<BR>"
t += "<B><font color='red'>Hot loop</font></B><BR>"
t += "Temperature Inlet: [round(hot_circ_air2.temperature, 0.1)] K / Outlet: [round(hot_circ_air1.temperature, 0.1)] K<BR>"
t += "Temperature Inlet: [round(hot_circ_air2.return_temperature(), 0.1)] K / Outlet: [round(hot_circ_air1.return_temperature(), 0.1)] K<BR>"
t += "Pressure Inlet: [round(hot_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(hot_circ_air1.return_pressure(), 0.1)] kPa<BR>"
t += "</div>"

View File

@@ -39,32 +39,28 @@
if(!loaded_tank)
return
if(!bitcoinmining)
if(!loaded_tank.air_contents.gases[/datum/gas/plasma])
if(loaded_tank.air_contents.get_moles(/datum/gas/plasma) < 0.0001)
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SUPERMATTER) // yogs - so supermatter investigate is useful
playsound(src, 'sound/machines/ding.ogg', 50, 1)
eject()
else
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES])
loaded_tank.air_contents.gases[/datum/gas/plasma][MOLES] -= gasdrained
loaded_tank.air_contents.assert_gas(/datum/gas/tritium)
loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] += gasdrained
loaded_tank.air_contents.garbage_collect()
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.get_moles(/datum/gas/plasma))
loaded_tank.air_contents.adjust_moles(/datum/gas/plasma, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, gasdrained)
var/power_produced = RAD_COLLECTOR_OUTPUT
add_avail(power_produced)
stored_power-=power_produced
else if(is_station_level(z) && SSresearch.science_tech)
if(!loaded_tank.air_contents.gases[/datum/gas/tritium] || !loaded_tank.air_contents.gases[/datum/gas/oxygen])
if(!loaded_tank.air_contents.get_moles(/datum/gas/tritium) || !loaded_tank.air_contents.get_moles(/datum/gas/oxygen))
playsound(src, 'sound/machines/ding.ogg', 50, 1)
eject()
else
var/gasdrained = bitcoinproduction_drain*drainratio
loaded_tank.air_contents.gases[/datum/gas/tritium][MOLES] -= gasdrained
loaded_tank.air_contents.gases[/datum/gas/oxygen][MOLES] -= gasdrained
loaded_tank.air_contents.assert_gas(/datum/gas/carbon_dioxide)
loaded_tank.air_contents.gases[/datum/gas/carbon_dioxide][MOLES] += gasdrained*2
loaded_tank.air_contents.garbage_collect()
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/oxygen, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/carbon_dioxide, gasdrained*2)
var/bitcoins_mined = RAD_COLLECTOR_OUTPUT
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
if(D)
@@ -78,10 +74,7 @@
toggle_power()
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
var/fuel
if(loaded_tank)
fuel = loaded_tank.air_contents.gases[/datum/gas/plasma]
fuel = fuel ? fuel[MOLES] : 0
var/fuel = loaded_tank.air_contents.get_moles(/datum/gas/plasma)
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SUPERMATTER) // yogs - so supermatter investigate is useful
return

View File

@@ -201,10 +201,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(get_integrity() < SUPERMATTER_DANGER_PERCENT)
return SUPERMATTER_DANGER
if((get_integrity() < SUPERMATTER_WARNING_PERCENT) || (air.temperature > CRITICAL_TEMPERATURE))
if((get_integrity() < SUPERMATTER_WARNING_PERCENT) || (air.return_temperature() > CRITICAL_TEMPERATURE))
return SUPERMATTER_WARNING
if(air.temperature > (CRITICAL_TEMPERATURE * 0.8))
if(air.return_temperature() > (CRITICAL_TEMPERATURE * 0.8))
return SUPERMATTER_NOTIFY
if(power > 5)
@@ -338,29 +338,29 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
else
if(takes_damage)
//causing damage
damage = max(damage + (max(CLAMP(removed.total_moles() / 200, 0.5, 1) * removed.temperature - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
damage = max(damage + (max(CLAMP(removed.total_moles() / 200, 0.5, 1) * removed.return_temperature() - ((T0C + HEAT_PENALTY_THRESHOLD)*dynamic_heat_resistance), 0) * mole_heat_penalty / 150 ) * DAMAGE_INCREASE_MULTIPLIER, 0)
damage = max(damage + (max(power - POWER_PENALTY_THRESHOLD, 0)/500) * DAMAGE_INCREASE_MULTIPLIER, 0)
damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0)
//healing damage
if(combined_gas < MOLE_PENALTY_THRESHOLD)
damage = max(damage + (min(removed.temperature - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0)
damage = max(damage + (min(removed.return_temperature() - (T0C + HEAT_PENALTY_THRESHOLD), 0) / 150 ), 0)
//capping damage
damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage)
if(damage > damage_archived && prob(10))
playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1)
removed.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/nitrogen)
//calculating gas related values
combined_gas = max(removed.total_moles(), 0)
plasmacomp = max(removed.gases[/datum/gas/plasma][MOLES]/combined_gas, 0)
o2comp = max(removed.gases[/datum/gas/oxygen][MOLES]/combined_gas, 0)
co2comp = max(removed.gases[/datum/gas/carbon_dioxide][MOLES]/combined_gas, 0)
plasmacomp = max(removed.get_moles(/datum/gas/plasma)/combined_gas, 0)
o2comp = max(removed.get_moles(/datum/gas/oxygen)/combined_gas, 0)
co2comp = max(removed.get_moles(/datum/gas/carbon_dioxide)/combined_gas, 0)
n2ocomp = max(removed.gases[/datum/gas/nitrous_oxide][MOLES]/combined_gas, 0)
n2comp = max(removed.gases[/datum/gas/nitrogen][MOLES]/combined_gas, 0)
n2ocomp = max(removed.get_moles(/datum/gas/nitrous_oxide)/combined_gas, 0)
n2comp = max(removed.get_moles(/datum/gas/nitrogen)/combined_gas, 0)
gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp, 0), 1)
@@ -393,7 +393,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
temp_factor = 30
icon_state = base_icon_state
power = CLAMP( (removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0, SUPERMATTER_MAXIMUM_ENERGY) //Total laser power plus an overload
power = CLAMP( (removed.return_temperature() * temp_factor / T0C) * gasmix_power_ratio + power, 0, SUPERMATTER_MAXIMUM_ENERGY) //Total laser power plus an overload
if(prob(50))
radiation_pulse(src, power * (1 + power_transmission_bonus/10))
@@ -407,14 +407,14 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock
//is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall.
removed.temperature += ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER)
removed.set_temperature(removed.return_temperature() + ((device_energy * dynamic_heat_modifier) / THERMAL_RELEASE_MODIFIER))
removed.temperature = max(0, min(removed.temperature, 2500 * dynamic_heat_modifier))
removed.set_temperature(max(0, min(removed.return_temperature(), 2500 * dynamic_heat_modifier)))
//Calculate how much gas to release
removed.gases[/datum/gas/plasma][MOLES] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)
removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
removed.gases[/datum/gas/oxygen][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
removed.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0))
if(produces_gas)
env.merge(removed)

View File

@@ -226,7 +226,7 @@
// Weird function but it works. Should be something else...
var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles())/4
var/newrpm = ((compressor.gas_contained.return_temperature()) * compressor.gas_contained.total_moles())/4
newrpm = max(0, newrpm)
@@ -347,7 +347,7 @@
data["power"] = DisplayPower(compressor?.turbine?.lastgen)
data["rpm"] = compressor?.rpm
data["temp"] = compressor?.gas_contained.temperature
data["temp"] = compressor?.gas_contained.return_temperature()
return data

View File

@@ -268,7 +268,7 @@
if(isopenturf(T))
var/turf/open/OT = T
OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=100, wet_time_to_add=reac_volume SECONDS) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit.
OT.air.set_temperature(OT.air.return_temperature() - MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity()) // reduces environment temperature by 5K per unit.
/datum/reagent/consumable/condensedcapsaicin
name = "Condensed Capsaicin"
@@ -443,7 +443,7 @@
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles())
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,0))
lowertemp.react(src)
T.assume_air(lowertemp)
qdel(hotspot)

View File

@@ -136,7 +136,7 @@
if(hotspot && !isspaceturf(T))
if(T.air)
var/datum/gas_mixture/G = T.air
G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),TCMB)
G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB))
G.react(src)
qdel(hotspot)
var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)

View File

@@ -259,8 +259,8 @@
if(hotspot && !isspaceturf(T))
if(T.air)
var/datum/gas_mixture/G = T.air
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
if(G.return_temperature() > T20C)
G.set_temperature(max(G.return_temperature()/2,T20C))
G.react(src)
qdel(hotspot)

View File

@@ -414,8 +414,8 @@
var/datum/gas_mixture/env = L.return_air()
var/pressure_delta = (SEND_PRESSURE*1.01) - air_contents.return_pressure()
if(env.temperature > 0)
var/transfer_moles = 0.1 * pressure_delta*air_contents.volume/(env.temperature * R_IDEAL_GAS_EQUATION)
if(env.return_temperature() > 0)
var/transfer_moles = 0.1 * pressure_delta*air_contents.return_volume()/(env.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = env.remove(transfer_moles)

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