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

3
.gitignore vendored
View File

@@ -214,5 +214,4 @@ tools/MapAtmosFixer/MapAtmosFixer/bin/*
*.orig *.orig
#Debugging and other stuff #Debugging and other stuff
byond-extools.dll 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 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_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold
#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) #define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3)
#define TANK_MIN_RELEASE_PRESSURE 0 #define TANK_MIN_RELEASE_PRESSURE 0
#define TANK_DEFAULT_RELEASE_PRESSURE 16 #define TANK_DEFAULT_RELEASE_PRESSURE 17
//CANATMOSPASS //CANATMOSPASS
#define ATMOS_PASS_YES 1 #define ATMOS_PASS_YES 1
@@ -275,20 +275,6 @@
T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\ T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\
T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y; T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;
#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity())
#define 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 #ifdef TESTING
GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0)) 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 } #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 #define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
#endif #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( GLOBAL_LIST_INIT(pipe_paint_colors, list(
"amethyst" = rgb(130,43,255), //supplymain "amethyst" = rgb(130,43,255), //supplymain
"blue" = rgb(0,0,255), "blue" = rgb(0,0,255),

View File

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

View File

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

View File

@@ -118,7 +118,7 @@
if(-INFINITY to T0C) if(-INFINITY to T0C)
add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice! add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice!
if(T0C to T0C + 100) if(T0C to T0C + 100)
decrease = ((T.air.temperature - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio) decrease = ((T.air.return_temperature() - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio)
if(T0C + 100 to INFINITY) if(T0C + 100 to INFINITY)
decrease = INFINITY decrease = INFINITY
decrease = max(0, decrease) decrease = max(0, decrease)

View File

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

View File

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

View File

@@ -42,9 +42,7 @@
/obj/effect/proc_holder/spell/targeted/olfaction/cast(list/targets, mob/living/user = usr) /obj/effect/proc_holder/spell/targeted/olfaction/cast(list/targets, mob/living/user = usr)
//can we sniff? is there miasma in the air? //can we sniff? is there miasma in the air?
var/datum/gas_mixture/air = user.loc.return_air() var/datum/gas_mixture/air = user.loc.return_air()
var/list/cached_gases = air.gases if(air.get_moles(/datum/gas/miasma))
if(cached_gases[/datum/gas/miasma])
user.adjust_disgust(sensitivity * 45) user.adjust_disgust(sensitivity * 45)
to_chat(user, "<span class='warning'>With your overly sensitive nose, you get a whiff of stench and feel sick! Try moving to a cleaner area!</span>") to_chat(user, "<span class='warning'>With your overly sensitive nose, you get a whiff of stench and feel sick! Try moving to a cleaner area!</span>")
return return

View File

@@ -134,7 +134,7 @@
if(!istype(o, /obj/item/tank)) if(!istype(o, /obj/item/tank))
continue continue
var/obj/item/tank/T = o 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 return found_amount >= target_amount

View File

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

View File

@@ -205,11 +205,8 @@
if(!density) if(!density)
return FALSE return FALSE
// alrighty now we check for how much pressure we're holding back // alrighty now we check for how much pressure we're holding back
var/min_moles var/min_moles = T.air.total_moles()
var/max_moles var/max_moles = min_moles
var/list/our_gases = T.air.gases
TOTAL_MOLES(our_gases, min_moles)
max_moles = min_moles
// okay this is a bit hacky. First, we set density to 0 and recalculate our adjacent turfs // okay this is a bit hacky. First, we set density to 0 and recalculate our adjacent turfs
density = FALSE density = FALSE
T.ImmediateCalculateAdjacentTurfs() T.ImmediateCalculateAdjacentTurfs()
@@ -217,9 +214,7 @@
for(var/turf/open/T2 in T.atmos_adjacent_turfs) for(var/turf/open/T2 in T.atmos_adjacent_turfs)
if((flags_1 & ON_BORDER_1) && get_dir(src, T2) != dir) if((flags_1 & ON_BORDER_1) && get_dir(src, T2) != dir)
continue continue
var/list/cached_gases = T2.air.gases var/moles = T2.air.total_moles()
var/moles = cached_gases
TOTAL_MOLES(cached_gases, moles)
if(moles < min_moles) if(moles < min_moles)
min_moles = moles min_moles = moles
if(moles > max_moles) if(moles > max_moles)

View File

@@ -82,9 +82,9 @@
var/datum/gas_mixture/env = L.return_air() var/datum/gas_mixture/env = L.return_air()
var/newMode = HEATER_MODE_STANDBY var/newMode = HEATER_MODE_STANDBY
if(setMode != HEATER_MODE_COOL && env.temperature < targetTemperature - temperatureTolerance) if(setMode != HEATER_MODE_COOL && env.return_temperature() < targetTemperature - temperatureTolerance)
newMode = HEATER_MODE_HEAT newMode = HEATER_MODE_HEAT
else if(setMode != HEATER_MODE_HEAT && env.temperature > targetTemperature + temperatureTolerance) else if(setMode != HEATER_MODE_HEAT && env.return_temperature() > targetTemperature + temperatureTolerance)
newMode = HEATER_MODE_COOL newMode = HEATER_MODE_COOL
if(mode != newMode) if(mode != newMode)
@@ -95,7 +95,7 @@
return return
var/heat_capacity = env.heat_capacity() var/heat_capacity = env.heat_capacity()
var/requiredPower = abs(env.temperature - targetTemperature) * heat_capacity var/requiredPower = abs(env.return_temperature() - targetTemperature) * heat_capacity
requiredPower = min(requiredPower, heatingPower) requiredPower = min(requiredPower, heatingPower)
if(requiredPower < 1) if(requiredPower < 1)
@@ -105,7 +105,7 @@
if(mode == HEATER_MODE_COOL) if(mode == HEATER_MODE_COOL)
deltaTemperature *= -1 deltaTemperature *= -1
if(deltaTemperature) if(deltaTemperature)
env.temperature += deltaTemperature env.set_temperature(env.return_temperature() + deltaTemperature)
air_update_turf() air_update_turf()
cell.use(requiredPower / efficiency) cell.use(requiredPower / efficiency)
else else
@@ -186,9 +186,9 @@
var/curTemp var/curTemp
if(istype(L)) if(istype(L))
var/datum/gas_mixture/env = L.return_air() var/datum/gas_mixture/env = L.return_air()
curTemp = env.temperature curTemp = env.return_temperature()
else if(isturf(L)) else if(isturf(L))
curTemp = L.temperature curTemp = L.return_temperature()
if(isnull(curTemp)) if(isnull(curTemp))
data["currentTemp"] = "N/A" data["currentTemp"] = "N/A"
else else

View File

@@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(telecomms_list)
var/turf/T = get_turf(src) //yogs var/turf/T = get_turf(src) //yogs
var/speedloss = 0 var/speedloss = 0
var/datum/gas_mixture/env = T.return_air() var/datum/gas_mixture/env = T.return_air()
var/temperature = env.temperature var/temperature = env.return_temperature()
if(temperature <= 150) // 150K optimal operating parameters if(temperature <= 150) // 150K optimal operating parameters
net_efective = 100 net_efective = 100
else else
@@ -170,8 +170,8 @@ GLOBAL_LIST_EMPTY(telecomms_list)
traffic = 0 traffic = 0
else else
traffic -= deltaT traffic -= deltaT
if(generates_heat) if(generates_heat && env.heat_capacity())
env.temperature += deltaT * heatoutput / env.heat_capacity() //yogs end env.set_temperature(env.return_temperature() + deltaT * heatoutput / env.heat_capacity()) //yogs end
/obj/machinery/telecomms/emp_act(severity) /obj/machinery/telecomms/emp_act(severity)
@@ -189,4 +189,4 @@ GLOBAL_LIST_EMPTY(telecomms_list)
/obj/machinery/telecomms/emag_act() /obj/machinery/telecomms/emag_act()
obj_flags |= EMAGGED obj_flags |= EMAGGED
visible_message("<span class='notice'>Sparks fly out of the[src]!</span>") visible_message("<span class='notice'>Sparks fly out of the[src]!</span>")
traffic += 50 traffic += 50

View File

@@ -21,7 +21,7 @@
var/cell_charge = get_charge() var/cell_charge = get_charge()
var/datum/gas_mixture/int_tank_air = internal_tank.return_air() var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None" var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown" var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01) var/cabin_pressure = round(return_pressure(),0.01)
var/output = {"[report_internal_damage()] var/output = {"[report_internal_damage()]
[integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null] [integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null]

View File

@@ -260,11 +260,10 @@
/obj/mecha/proc/add_cabin() /obj/mecha/proc/add_cabin()
cabin_air = new cabin_air = new
cabin_air.temperature = T20C cabin_air.set_temperature(T20C)
cabin_air.volume = 200 cabin_air.set_volume(200)
cabin_air.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) cabin_air.set_moles(/datum/gas/oxygen, O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.gases[/datum/gas/oxygen][MOLES] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature) cabin_air.set_moles(/datum/gas/nitrogen, N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.gases[/datum/gas/nitrogen][MOLES] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
return cabin_air return cabin_air
/obj/mecha/proc/add_radio() /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)) if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH))
setInternalDamage(MECHA_INT_TANK_BREACH) setInternalDamage(MECHA_INT_TANK_BREACH)
if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents
int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15)) int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15)))
if(cabin_air && cabin_air.return_volume()>0) if(cabin_air && cabin_air.return_volume()>0)
cabin_air.temperature = min(6000+T0C, cabin_air.return_temperature()+rand(10,15)) cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15)))
if(cabin_air.return_temperature() > max_temperature/2) if(cabin_air.return_temperature() > max_temperature/2)
take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0) take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0)
@@ -357,8 +356,8 @@
if(internal_temp_regulation) if(internal_temp_regulation)
if(cabin_air && cabin_air.return_volume() > 0) if(cabin_air && cabin_air.return_volume() > 0)
var/delta = cabin_air.temperature - T20C var/delta = cabin_air.return_temperature() - T20C
cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1))) cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1))))
if(internal_tank) if(internal_tank)
var/datum/gas_mixture/tank_air = internal_tank.return_air() var/datum/gas_mixture/tank_air = internal_tank.return_air()
@@ -1172,4 +1171,4 @@ GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
to_chat(user, "<span class='notice'>You can't fit any more ammo of this type!</span>") to_chat(user, "<span class='notice'>You can't fit any more ammo of this type!</span>")
else else
to_chat(user, "<span class='notice'>None of the equipment on this exosuit can use this ammo!</span>") to_chat(user, "<span class='notice'>None of the equipment on this exosuit can use this ammo!</span>")
return FALSE return FALSE

View File

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

View File

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

View File

@@ -166,16 +166,13 @@
if(T.air) if(T.air)
var/datum/gas_mixture/G = T.air var/datum/gas_mixture/G = T.air
if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air
G.temperature = temperature G.set_temperature(temperature)
T.air_update_turf() T.air_update_turf()
for(var/obj/effect/hotspot/H in T) for(var/obj/effect/hotspot/H in T)
qdel(H) qdel(H)
var/list/G_gases = G.gases if(G.get_moles(/datum/gas/plasma))
if(G_gases[/datum/gas/plasma]) G.adjust_moles(/datum/gas/nitrogen, G.get_moles(/datum/gas/plasma))
G.assert_gas(/datum/gas/nitrogen) G.set_moles(/datum/gas/plasma, 0)
G_gases[/datum/gas/nitrogen][MOLES] += (G_gases[/datum/gas/plasma][MOLES])
G_gases[/datum/gas/plasma][MOLES] = 0
G.garbage_collect()
if (weldvents) if (weldvents)
for(var/obj/machinery/atmospherics/components/unary/U in T) for(var/obj/machinery/atmospherics/components/unary/U in T)
if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber. if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber.

View File

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

View File

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

View File

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

View File

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

View File

@@ -168,8 +168,8 @@
target_self = TRUE target_self = TRUE
if(change_volume) if(change_volume)
if(!target_self) if(!target_self)
target.volume += tank_two.volume target.set_volume(target.return_volume() + tank_two.air_contents.return_volume())
target.volume += tank_one.air_contents.volume target.set_volume(target.return_volume() + tank_one.air_contents.return_volume())
var/datum/gas_mixture/temp var/datum/gas_mixture/temp
temp = tank_one.air_contents.remove_ratio(1) temp = tank_one.air_contents.remove_ratio(1)
target.merge(temp) target.merge(temp)
@@ -180,11 +180,11 @@
/obj/item/transfer_valve/proc/split_gases() /obj/item/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two) if (!valve_open || !tank_one || !tank_two)
return return
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume var/ratio1 = tank_one.air_contents.return_volume()/tank_two.air_contents.return_volume()
var/datum/gas_mixture/temp var/datum/gas_mixture/temp
temp = tank_two.air_contents.remove_ratio(ratio1) temp = tank_two.air_contents.remove_ratio(ratio1)
tank_one.air_contents.merge(temp) tank_one.air_contents.merge(temp)
tank_two.air_contents.volume -= tank_one.air_contents.volume tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume())
/* /*
Exadv1: I know this isn't how it's going to work, but this was just to check Exadv1: I know this isn't how it's going to work, but this was just to check

View File

@@ -204,11 +204,10 @@
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf //Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
if(air_transfer.gases[/datum/gas/plasma]) air_transfer.set_moles(/datum/gas/plasma, air_transfer.get_moles(/datum/gas/plasma) * 5)
air_transfer.gases[/datum/gas/plasma][MOLES] *= 5
target.assume_air(air_transfer) target.assume_air(air_transfer)
//Burn it based on transfered gas //Burn it based on transfered gas
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) target.hotspot_expose((ptank.air_contents.return_temperature()*2) + 380,500)
//location.hotspot_expose(1000,500,1) //location.hotspot_expose(1000,500,1)
SSair.add_to_active(target, 0) SSair.add_to_active(target, 0)

View File

@@ -21,8 +21,7 @@
/obj/item/tank/jetpack/populate_gas() /obj/item/tank/jetpack/populate_gas()
if(gas_type) if(gas_type)
air_contents.assert_gas(gas_type) air_contents.set_moles(gas_type, ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)))
air_contents.gases[gas_type][MOLES] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))
/obj/item/tank/jetpack/ui_action_click(mob/user, action) /obj/item/tank/jetpack/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_jetpack)) if(istype(action, /datum/action/item_action/toggle_jetpack))

View File

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

View File

@@ -55,7 +55,7 @@
. = ..() . = ..()
air_contents = new(volume) //liters air_contents = new(volume) //liters
air_contents.temperature = T20C air_contents.set_temperature(T20C)
populate_gas() 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 . += "<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 var/descriptive
if (celsius_temperature < 20) if (celsius_temperature < 20)
@@ -222,7 +222,7 @@
if(tank_pressure < distribute_pressure) if(tank_pressure < distribute_pressure)
distribute_pressure = tank_pressure distribute_pressure = tank_pressure
var/moles_needed = distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.temperature) var/moles_needed = distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.return_temperature())
return remove_air(moles_needed) return remove_air(moles_needed)

View File

@@ -527,11 +527,11 @@
var/datum/gas_mixture/loc_air = loc?.return_air() var/datum/gas_mixture/loc_air = loc?.return_air()
if(loc_air) if(loc_air)
air_contents.copy_from(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) else if(!is_airtight && air_contents)
var/datum/gas_mixture/loc_air = loc?.return_air() 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.... 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.assume_air(air_contents)
loc.remove_air(remove_amount) loc.remove_air(remove_amount)
loc.air_update_turf() loc.air_update_turf()
@@ -554,5 +554,5 @@
/obj/structure/closet/return_temperature() /obj/structure/closet/return_temperature()
if(air_contents) if(air_contents)
return air_contents.temperature return air_contents.return_temperature()
return ..() return ..()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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. 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 /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() var/list/features = list()
@@ -321,6 +330,7 @@ GLOBAL_VAR(restart_counter)
maxz++ maxz++
SSmobs.MaxZChanged() SSmobs.MaxZChanged()
SSidlenpcpool.MaxZChanged() SSidlenpcpool.MaxZChanged()
world.refresh_atmos_grid()
/world/proc/change_fps(new_value = 20) /world/proc/change_fps(new_value = 20)
if(new_value <= 0) if(new_value <= 0)
@@ -344,3 +354,5 @@ GLOBAL_VAR(restart_counter)
/world/proc/on_tickrate_change() /world/proc/on_tickrate_change()
SStimer?.reset_buckets() SStimer?.reset_buckets()
/world/proc/refresh_atmos_grid()

View File

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

View File

@@ -1,18 +1,16 @@
/proc/show_air_status_to(turf/target, mob/user) /proc/show_air_status_to(turf/target, mob/user)
var/datum/gas_mixture/env = target.return_air() var/datum/gas_mixture/env = target.return_air()
var/list/env_gases = env.gases
var/burning = FALSE var/burning = FALSE
if(isopenturf(target)) if(isopenturf(target))
var/turf/open/T = target var/turf/open/T = target
if(T.active_hotspot) if(T.active_hotspot)
burning = TRUE burning = TRUE
var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.temperature] K ([env.temperature - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>") var/list/lines = list("<span class='adminnotice'>[AREACOORD(target)]: [env.return_temperature()] K ([env.return_temperature() - T0C] C), [env.return_pressure()] kPa[(burning)?(", <font color='red'>burning</font>"):(null)]</span>")
for(var/id in env_gases) for(var/id in env.get_gases())
var/gas = env_gases[id] var/moles = env.get_moles(id)
var/moles = gas[MOLES]
if (moles >= 0.00001) 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")) to_chat(usr, lines.Join("\n"))
/client/proc/air_status(turf/target) /client/proc/air_status(turf/target)

View File

@@ -51,7 +51,7 @@
return return
if(I.use_tool(src, user, 0, volume=40)) if(I.use_tool(src, user, 0, volume=40))
status = TRUE 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>") to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
add_fingerprint(user) add_fingerprint(user)
return TRUE return TRUE
@@ -142,9 +142,7 @@
return return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode /obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen) var/fuel_moles = air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6
air_contents.garbage_collect()
var/datum/gas_mixture/bomb_mixture = air_contents.copy() var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1 var/strength = 1
@@ -154,7 +152,7 @@
qdel(master) qdel(master)
qdel(src) qdel(src)
if(bomb_mixture.temperature > (T0C + 400)) if(bomb_mixture.return_temperature() > (T0C + 400))
strength = (fuel_moles/15) strength = (fuel_moles/15)
if(strength >=1) if(strength >=1)
@@ -167,7 +165,7 @@
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 250)) else if(bomb_mixture.return_temperature() > (T0C + 250))
strength = (fuel_moles/20) strength = (fuel_moles/20)
if(strength >=1) if(strength >=1)
@@ -178,7 +176,7 @@
ground_zero.assume_air(bomb_mixture) ground_zero.assume_air(bomb_mixture)
ground_zero.hotspot_expose(1000, 125) ground_zero.hotspot_expose(1000, 125)
else if(bomb_mixture.temperature > (T0C + 100)) else if(bomb_mixture.return_temperature() > (T0C + 100))
strength = (fuel_moles/25) strength = (fuel_moles/25)
if (strength >=1) if (strength >=1)

View File

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

View File

@@ -48,21 +48,28 @@
var/canvpass = CANVERTICALATMOSPASS(src, src) var/canvpass = CANVERTICALATMOSPASS(src, src)
for(var/direction in GLOB.cardinals_multiz) for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction) var/turf/T = get_step_multiz(src, direction)
var/opp_dir = dir_inverse_multiz(direction)
if(!isopenturf(T)) if(!isopenturf(T))
continue continue
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) ) if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs) LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs) LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = TRUE atmos_adjacent_turfs[T] = direction
T.atmos_adjacent_turfs[src] = TRUE T.atmos_adjacent_turfs[src] = opp_dir
T.__update_extools_adjacent_turfs()
else else
if (atmos_adjacent_turfs) if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= T atmos_adjacent_turfs -= T
if (T.atmos_adjacent_turfs) if (T.atmos_adjacent_turfs)
T.atmos_adjacent_turfs -= src T.atmos_adjacent_turfs -= src
T.__update_extools_adjacent_turfs()
UNSETEMPTY(T.atmos_adjacent_turfs) UNSETEMPTY(T.atmos_adjacent_turfs)
UNSETEMPTY(atmos_adjacent_turfs) UNSETEMPTY(atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs src.atmos_adjacent_turfs = atmos_adjacent_turfs
__update_extools_adjacent_turfs()
/turf/proc/__update_extools_adjacent_turfs()
//returns a list of adjacent turfs that can share air with this one. //returns a list of adjacent turfs that can share air with this one.
//alldir includes adjacent diagonal tiles that can share //alldir includes adjacent diagonal tiles that can share

View File

@@ -8,6 +8,7 @@
var/list/atmos_adjacent_turfs var/list/atmos_adjacent_turfs
//bitfield of dirs in which we are superconducitng //bitfield of dirs in which we are superconducitng
var/atmos_supeconductivity = NONE var/atmos_supeconductivity = NONE
var/is_openturf = FALSE // used by extools shizz.
//used to determine whether we should archive //used to determine whether we should archive
var/archived_cycle = 0 var/archived_cycle = 0
@@ -25,20 +26,19 @@
var/pressure_direction = 0 var/pressure_direction = 0
var/turf/pressure_specific_target var/turf/pressure_specific_target
var/datum/excited_group/excited_group
var/excited = FALSE
var/datum/gas_mixture/turf/air var/datum/gas_mixture/turf/air
var/obj/effect/hotspot/active_hotspot var/obj/effect/hotspot/active_hotspot
var/atmos_cooldown = 0
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time
var/list/atmos_overlay_types //gas IDs of current active gas overlays var/list/atmos_overlay_types //gas IDs of current active gas overlays
is_openturf = TRUE
/turf/open/Initialize() /turf/open/Initialize()
if(!blocks_air) if(!blocks_air)
air = new air = new
air.copy_from_turf(src) air.copy_from_turf(src)
update_air_ref()
. = ..() . = ..()
/turf/open/Destroy() /turf/open/Destroy()
@@ -49,6 +49,8 @@
SSair.add_to_active(T) SSair.add_to_active(T)
return ..() return ..()
/turf/proc/update_air_ref()
/////////////////GAS MIXTURE PROCS/////////////////// /////////////////GAS MIXTURE PROCS///////////////////
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air /turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
@@ -94,6 +96,11 @@
archived_cycle = SSair.times_fired archived_cycle = SSair.times_fired
temperature_archived = temperature temperature_archived = temperature
/turf/open/proc/eg_reset_cooldowns()
/turf/open/proc/eg_garbage_collect()
/turf/open/proc/get_excited()
/turf/open/proc/set_excited()
/////////////////////////GAS OVERLAYS////////////////////////////// /////////////////////////GAS OVERLAYS//////////////////////////////
@@ -110,16 +117,13 @@
src.atmos_overlay_types = null src.atmos_overlay_types = null
return return
var/list/gases = air.gases for(var/id in air.get_gases())
for(var/id in gases)
if (nonoverlaying_gases[id]) if (nonoverlaying_gases[id])
continue continue
var/gas = gases[id] var/gas_meta = GLOB.meta_gas_info[id]
var/gas_meta = gas[GAS_META]
var/gas_overlay = gas_meta[META_GAS_OVERLAY] var/gas_overlay = gas_meta[META_GAS_OVERLAY]
if(gas_overlay && gas[MOLES] > gas_meta[META_GAS_MOLES_VISIBLE]) if(gas_overlay && air.get_moles(id) > gas_meta[META_GAS_MOLES_VISIBLE])
new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(gas[MOLES] / MOLES_GAS_VISIBLE_STEP, 1))] new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(air.get_moles(id) / MOLES_GAS_VISIBLE_STEP, 1))]
if (atmos_overlay_types) if (atmos_overlay_types)
for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added for(var/overlay in atmos_overlay_types-new_overlay_types) //doesn't remove overlays that would only be added
@@ -134,6 +138,19 @@
UNSETEMPTY(new_overlay_types) UNSETEMPTY(new_overlay_types)
src.atmos_overlay_types = new_overlay_types src.atmos_overlay_types = new_overlay_types
/turf/open/proc/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() /proc/typecache_of_gases_with_no_overlays()
. = list() . = list()
for (var/gastype in subtypesof(/datum/gas)) for (var/gastype in subtypesof(/datum/gas))
@@ -143,8 +160,8 @@
/////////////////////////////SIMULATION/////////////////////////////////// /////////////////////////////SIMULATION///////////////////////////////////
#define LAST_SHARE_CHECK \ /*#define LAST_SHARE_CHECK \
var/last_share = our_air.last_share;\ var/last_share = our_air.get_last_share();\
if(last_share > MINIMUM_AIR_TO_SUSPEND){\ if(last_share > MINIMUM_AIR_TO_SUSPEND){\
our_excited_group.reset_cooldowns();\ our_excited_group.reset_cooldowns();\
cached_atmos_cooldown = 0;\ cached_atmos_cooldown = 0;\
@@ -152,95 +169,32 @@
our_excited_group.dismantle_cooldown = 0;\ our_excited_group.dismantle_cooldown = 0;\
cached_atmos_cooldown = 0;\ cached_atmos_cooldown = 0;\
} }
*/
/turf/proc/process_cell(fire_count) /turf/proc/process_cell(fire_count)
SSair.remove_from_active(src) SSair.remove_from_active(src)
/turf/open/process_cell(fire_count) /turf/open/proc/equalize_pressure_in_zone(cyclenum)
if(archived_cycle < fire_count) //archive self if not already done /turf/open/proc/consider_firelocks(turf/T2)
archive() var/reconsider_adj = FALSE
for(var/obj/machinery/door/firedoor/FD in T2)
current_cycle = fire_count if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, src) != FD.dir)
//cache for sanic speed
var/list/adjacent_turfs = atmos_adjacent_turfs
var/datum/excited_group/our_excited_group = excited_group
var/adjacent_turfs_length = LAZYLEN(adjacent_turfs)
var/cached_atmos_cooldown = atmos_cooldown + 1
var/planet_atmos = planetary_atmos
if (planet_atmos)
adjacent_turfs_length++
var/datum/gas_mixture/our_air = air
for(var/t in adjacent_turfs)
var/turf/open/enemy_tile = t
if(fire_count <= enemy_tile.current_cycle)
continue continue
enemy_tile.archive() FD.emergency_pressure_stop()
reconsider_adj = TRUE
for(var/obj/machinery/door/firedoor/FD in src)
if((FD.flags_1 & ON_BORDER_1) && get_dir(src, T2) != FD.dir)
continue
FD.emergency_pressure_stop()
reconsider_adj = TRUE
if(reconsider_adj)
T2.ImmediateCalculateAdjacentTurfs() // We want those firelocks closed yesterday.
/******************* GROUP HANDLING START *****************************************************************/ /turf/proc/handle_decompression_floor_rip()
/turf/open/floor/handle_decompression_floor_rip(sum)
if(sum > 20 && prob(CLAMP(sum / 10, 0, 30)))
remove_tile()
var/should_share_air = FALSE /turf/open/process_cell(fire_count)
var/datum/gas_mixture/enemy_air = enemy_tile.air
//cache for sanic speed
var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group
if(our_excited_group && enemy_excited_group)
if(our_excited_group != enemy_excited_group)
//combine groups (this also handles updating the excited_group var of all involved turfs)
our_excited_group.merge_groups(enemy_excited_group)
our_excited_group = excited_group //update our cache
should_share_air = TRUE
else if(our_air.compare(enemy_air))
if(!enemy_tile.excited)
SSair.add_to_active(enemy_tile)
var/datum/excited_group/EG = our_excited_group || enemy_excited_group || new
if(!our_excited_group)
EG.add_turf(src)
if(!enemy_excited_group)
EG.add_turf(enemy_tile)
our_excited_group = excited_group
should_share_air = TRUE
//air sharing
if(should_share_air)
var/difference = our_air.share(enemy_air, adjacent_turfs_length)
if(difference)
if(difference > 0)
consider_pressure_difference(enemy_tile, difference)
else
enemy_tile.consider_pressure_difference(src, -difference)
LAST_SHARE_CHECK
/******************* GROUP HANDLING FINISH *********************************************************************/
if (planet_atmos) //share our air with the "atmosphere" "above" the turf
var/datum/gas_mixture/G = new
G.copy_from_turf(src)
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
//////////////////////////SPACEWIND///////////////////////////// //////////////////////////SPACEWIND/////////////////////////////
@@ -289,87 +243,6 @@
step(src, direction) step(src, direction)
last_high_pressure_movement_air_cycle = SSair.times_fired 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///////////////////////////// ////////////////////////SUPERCONDUCTIVITY/////////////////////////////
/turf/proc/conductivity_directions() /turf/proc/conductivity_directions()
if(archived_cycle < SSair.times_fired) if(archived_cycle < SSair.times_fired)
@@ -436,7 +309,7 @@
//Conduct with air on my tile if I have it //Conduct with air on my tile if I have it
if(!blocks_air) if(!blocks_air)
temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity) temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity)
..((blocks_air ? temperature : air.temperature)) ..((blocks_air ? temperature : air.return_temperature()))
/turf/proc/consider_superconductivity() /turf/proc/consider_superconductivity()
if(!thermal_conductivity) if(!thermal_conductivity)
@@ -446,7 +319,7 @@
return TRUE return TRUE
/turf/open/consider_superconductivity(starting) /turf/open/consider_superconductivity(starting)
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)) if(air.return_temperature() < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return FALSE return FALSE
if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant. if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant.
return FALSE return FALSE

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] cached_gas[GAS_META] = GLOB.meta_gas_info[id]
/datum/gas_mixture /datum/gas_mixture
var/list/gases var/initial_volume = CELL_VOLUME //liters
var/temperature = 0 //kelvins
var/tmp/temperature_archived = 0
var/volume = CELL_VOLUME //liters
var/last_share = 0
var/list/reaction_results var/list/reaction_results
var/list/analyzer_results //used for analyzer feedback - not initialized until its used var/list/analyzer_results //used for analyzer feedback - not initialized until its used
var/gc_share = FALSE // Whether to call garbage_collect() on the sharer during shares, used for immutable mixtures var/_extools_pointer_gasmixture = 0 // Contains the memory address of the shared_ptr object for this gas mixture in c++ land. Don't. Touch. This. Var.
/datum/gas_mixture/New(volume) /datum/gas_mixture/New(volume)
gases = new
if (!isnull(volume)) if (!isnull(volume))
src.volume = volume initial_volume = volume
ATMOS_EXTOOLS_CHECK
__gasmixture_register()
reaction_results = new reaction_results = new
//listmos procs /datum/gas_mixture/vv_edit_var(var_name, var_value)
//use the macros in performance intensive areas. for their definitions, refer to code/__DEFINES/atmospherics.dm 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. /datum/gas_mixture/proc/__gasmixture_unregister()
//Must be used before adding to a gas. May be used before reading from a gas. /datum/gas_mixture/proc/__gasmixture_register()
/datum/gas_mixture/proc/assert_gas(gas_id)
ASSERT_GAS(gas_id, src)
//assert_gases(args) - shorthand for calling ASSERT_GAS() once for each gas type. /proc/gas_types()
/datum/gas_mixture/proc/assert_gases(...) var/list/L = subtypesof(/datum/gas)
for(var/id in args) for(var/gt in L)
ASSERT_GAS(id, src) var/datum/gas/G = gt
L[gt] = initial(G.specific_heat)
//add_gas(gas_id) - similar to assert_gas(), but does not check for an existing return L
//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
/datum/gas_mixture/proc/heat_capacity(data = MOLES) //joules per kelvin /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() /datum/gas_mixture/proc/total_moles()
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
/datum/gas_mixture/proc/return_pressure() //kilopascals /datum/gas_mixture/proc/return_pressure() //kilopascals
if(volume > 0) // to prevent division by zero
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
. *= R_IDEAL_GAS_EQUATION * temperature / volume
return
return 0
/datum/gas_mixture/proc/return_temperature() //kelvins /datum/gas_mixture/proc/return_temperature() //kelvins
return temperature
/datum/gas_mixture/proc/set_min_heat_capacity(n)
/datum/gas_mixture/proc/set_temperature(new_temp)
/datum/gas_mixture/proc/set_volume(new_volume)
/datum/gas_mixture/proc/get_moles(gas_type)
/datum/gas_mixture/proc/set_moles(gas_type, moles)
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
/datum/gas_mixture/proc/mark_immutable()
/datum/gas_mixture/proc/get_gases()
/datum/gas_mixture/proc/multiply(factor)
/datum/gas_mixture/proc/get_last_share()
/datum/gas_mixture/proc/clear()
/datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0)
set_moles(gas_type, get_moles(gas_type) + amt)
/datum/gas_mixture/proc/return_volume() //liters /datum/gas_mixture/proc/return_volume() //liters
return max(0, volume)
/datum/gas_mixture/proc/thermal_energy() //joules /datum/gas_mixture/proc/thermal_energy() //joules
return THERMAL_ENERGY(src) //see code/__DEFINES/atmospherics.dm; use the define in performance critical areas
/datum/gas_mixture/proc/archive() /datum/gas_mixture/proc/archive()
//Update archived versions of variables //Update archived versions of variables
@@ -164,282 +132,60 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//Performs various reactions such as combustion or fusion (LOL) //Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise //Returns: 1 if any reaction took place; 0 otherwise
/datum/gas_mixture/archive()
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) /datum/gas_mixture/remove(amount)
var/sum
var/list/cached_gases = gases
TOTAL_MOLES(cached_gases, sum)
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
var/datum/gas_mixture/removed = new type var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars __remove(removed, amount)
removed.temperature = temperature
for(var/id in cached_gases)
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()
return removed return removed
/datum/gas_mixture/proc/__remove_ratio()
/datum/gas_mixture/remove_ratio(ratio) /datum/gas_mixture/remove_ratio(ratio)
if(ratio <= 0)
return null
ratio = min(ratio, 1)
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new type var/datum/gas_mixture/removed = new type
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars __remove_ratio(removed, ratio)
removed.temperature = temperature
for(var/id in cached_gases)
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()
return removed return removed
/datum/gas_mixture/copy() /datum/gas_mixture/copy()
var/list/cached_gases = gases
var/datum/gas_mixture/copy = new type var/datum/gas_mixture/copy = new type
var/list/copy_gases = copy.gases copy.copy_from(src)
copy.temperature = temperature
for(var/id in cached_gases)
ADD_GAS(id, copy.gases)
copy_gases[id][MOLES] = cached_gases[id][MOLES]
return copy return copy
/datum/gas_mixture/copy_from(datum/gas_mixture/sample)
var/list/cached_gases = gases //accessing datum vars is slower than proc vars
var/list/sample_gases = sample.gases
temperature = sample.temperature
for(var/id in sample_gases)
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) /datum/gas_mixture/copy_from_turf(turf/model)
parse_gas_string(model.initial_gas_mix) parse_gas_string(model.initial_gas_mix)
//acounts for changes in temperature //acounts for changes in temperature
var/turf/model_parent = model.parent_type var/turf/model_parent = model.parent_type
if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature)) if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
temperature = model.temperature set_temperature(model.temperature)
return 1 return 1
/datum/gas_mixture/parse_gas_string(gas_string) /datum/gas_mixture/parse_gas_string(gas_string)
var/list/gases = src.gases
var/list/gas = params2list(gas_string) var/list/gas = params2list(gas_string)
if(gas["TEMP"]) if(gas["TEMP"])
temperature = text2num(gas["TEMP"]) set_temperature(text2num(gas["TEMP"]))
gas -= "TEMP" gas -= "TEMP"
gases.Cut() clear()
for(var/id in gas) for(var/id in gas)
var/path = id var/path = id
if(!ispath(path)) if(!ispath(path))
path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
ADD_GAS(path, gases) set_moles(path, text2num(gas[id]))
gases[path][MOLES] = text2num(gas[id])
return 1 return 1
/datum/gas_mixture/share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
var/list/cached_gases = gases
var/list/sharer_gases = sharer.gases
var/temperature_delta = temperature_archived - sharer.temperature_archived
var/abs_temperature_delta = abs(temperature_delta)
var/old_self_heat_capacity = 0
var/old_sharer_heat_capacity = 0
if(abs_temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
old_self_heat_capacity = heat_capacity()
old_sharer_heat_capacity = sharer.heat_capacity()
var/heat_capacity_self_to_sharer = 0 //heat capacity of the moles transferred from us to the sharer
var/heat_capacity_sharer_to_self = 0 //heat capacity of the moles transferred from the sharer to us
var/moved_moles = 0
var/abs_moved_moles = 0
//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) /datum/gas_mixture/react(datum/holder)
. = NO_REACTION . = NO_REACTION
var/list/cached_gases = gases
if(!length(cached_gases))
return
var/list/reactions = list() var/list/reactions = list()
for(var/I in cached_gases) for(var/I in get_gases())
reactions += SSair.gas_reactions[I] reactions += SSair.gas_reactions[I]
if(!length(reactions)) if(!length(reactions))
return return
reaction_results = new reaction_results = new
var/temp = temperature var/temp = return_temperature()
var/ener = THERMAL_ENERGY(src) var/ener = thermal_energy()
reaction_loop: reaction_loop:
for(var/r in reactions) for(var/r in reactions)
@@ -453,7 +199,7 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
for(var/id in min_reqs) for(var/id in min_reqs)
if (id == "TEMP" || id == "ENER") if (id == "TEMP" || id == "ENER")
continue continue
if(!cached_gases[id] || cached_gases[id][MOLES] < min_reqs[id]) if(get_moles(id) < min_reqs[id])
continue reaction_loop continue reaction_loop
//at this point, all requirements for the reaction are satisfied. we can now react() //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) . |= reaction.react(src, holder)
if (. & STOP_REACTIONS) if (. & STOP_REACTIONS)
break break
if(.)
garbage_collect()
//Takes the amount of the gas you want to PP as an argument //Takes the amount of the gas you want to PP as an argument
//So I don't have to do some hacky switches/defines/magic strings //So I don't have to do some hacky switches/defines/magic strings
@@ -471,10 +215,10 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//O2_PP = get_partial_pressure(gas_mixture.oxygen) //O2_PP = get_partial_pressure(gas_mixture.oxygen)
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure) /datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
return (gas_pressure * R_IDEAL_GAS_EQUATION * temperature) / BREATH_VOLUME return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME
//inverse //inverse
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure) /datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * temperature) return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature())
//Mathematical proofs: //Mathematical proofs:
/* /*
@@ -485,6 +229,8 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
10 = 2.5/5*20 10 = 2.5/5*20
*/ */
/datum/gas_mixture/turf
/* /*
/mob/verb/profile_atmos() /mob/verb/profile_atmos()
/world{loop_checks = 0;} /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)]") to_chat(src, "Operations per second: [100000 / (total_time/1000)]")
pa = world.tick_usage pa = world.tick_usage
for(var/I in 1 to 100000) for(var/I in 1 to 100000)
var/datum/gas_mixture/GM = new new /datum/gas_mixture
pb = world.tick_usage pb = world.tick_usage
total_time = (pb-pa) * world.tick_lag total_time = (pb-pa) * world.tick_lag
to_chat(src, "Total time (new gas mixture): [total_time]ms") 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/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. 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 /datum/gas/oxygen
id = "o2" id = "o2"
specific_heat = 20 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 //it can be changed, but any changes will ultimately be undone before they can have any effect
/datum/gas_mixture/immutable /datum/gas_mixture/immutable
var/initial_temperature var/initial_temperature = 0
gc_share = TRUE
/datum/gas_mixture/immutable/New() /datum/gas_mixture/immutable/New()
..() ..()
garbage_collect() set_temperature(initial_temperature)
populate()
mark_immutable()
/datum/gas_mixture/immutable/garbage_collect() /datum/gas_mixture/immutable/proc/populate()
temperature = initial_temperature return
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
//used by space tiles //used by space tiles
/datum/gas_mixture/immutable/space /datum/gas_mixture/immutable/space
initial_temperature = TCMB initial_temperature = TCMB
/datum/gas_mixture/immutable/space/heat_capacity() /datum/gas_mixture/immutable/space/populate()
return HEAT_CAPACITY_VACUUM set_min_heat_capacity(HEAT_CAPACITY_VACUUM)
/datum/gas_mixture/immutable/space/remove()
return copy() //we're always empty, so we can just return a copy.
/datum/gas_mixture/immutable/space/remove_ratio()
return copy() //we're always empty, so we can just return a copy.
//used by cloners //used by cloners
/datum/gas_mixture/immutable/cloner /datum/gas_mixture/immutable/cloner
initial_temperature = T20C initial_temperature = T20C
/datum/gas_mixture/immutable/cloner/garbage_collect() /datum/gas_mixture/immutable/cloner/populate()
..() set_moles(/datum/gas/nitrogen, MOLES_O2STANDARD + MOLES_N2STANDARD)
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

View File

@@ -72,11 +72,11 @@
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
var/turf/open/location = isturf(holder) ? holder : null var/turf/open/location = isturf(holder) ? holder : null
. = NO_REACTION . = NO_REACTION
if (air.temperature <= WATER_VAPOR_FREEZE) if (air.return_temperature() <= WATER_VAPOR_FREEZE)
if(location && location.freon_gas_act()) if(location && location.freon_gas_act())
. = REACTING . = REACTING
else if(location && location.water_vapor_gas_act()) else if(location && location.water_vapor_gas_act())
air.gases[/datum/gas/water_vapor][MOLES] -= MOLES_GAS_VISIBLE air.adjust_moles(/datum/gas/water_vapor, -MOLES_GAS_VISIBLE)
. = REACTING . = REACTING
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic //tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
@@ -95,21 +95,20 @@
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0 var/energy_released = 0
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow var/temperature = air.return_temperature()
var/temperature = air.temperature
var/list/cached_results = air.reaction_results var/list/cached_results = air.reaction_results
cached_results["fire"] = 0 cached_results["fire"] = 0
var/turf/open/location = isturf(holder) ? holder : null var/turf/open/location = isturf(holder) ? holder : null
var/burned_fuel = 0 var/burned_fuel = 0
var/initial_trit = cached_gases[/datum/gas/tritium][MOLES]// Yogs var/initial_trit = air.get_moles(/datum/gas/tritium)// 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 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 = cached_gases[/datum/gas/oxygen][MOLES]/TRITIUM_BURN_OXY_FACTOR 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 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 else
burned_fuel = initial_trit // Yogs -- Conservation of Mass fix 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 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
cached_gases[/datum/gas/oxygen][MOLES] -= cached_gases[/datum/gas/tritium][MOLES] 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 energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel * (TRITIUM_BURN_TRIT_FACTOR - 1)) // Yogs -- Fixes low-energy tritium fires
if(burned_fuel) 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 if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR) radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
ASSERT_GAS(/datum/gas/water_vapor, air) //oxygen+more-or-less hydrogen=H2O //oxygen+more-or-less hydrogen=H2O
cached_gases[/datum/gas/water_vapor][MOLES] += burned_fuel // Yogs -- Conservation of Mass air.adjust_moles(/datum/gas/water_vapor, burned_fuel )// Yogs -- Conservation of Mass
cached_results["fire"] += burned_fuel cached_results["fire"] += burned_fuel
if(energy_released > 0) if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
//let the floor know a fire is happening //let the floor know a fire is happening
if(istype(location)) if(istype(location))
temperature = air.temperature temperature = air.return_temperature()
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME) location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location) for(var/I in location)
@@ -155,8 +154,7 @@
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0 var/energy_released = 0
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow var/temperature = air.return_temperature()
var/temperature = air.temperature
var/list/cached_results = air.reaction_results var/list/cached_results = air.reaction_results
cached_results["fire"] = 0 cached_results["fire"] = 0
var/turf/open/location = isturf(holder) ? holder : null var/turf/open/location = isturf(holder) ? holder : null
@@ -175,23 +173,21 @@
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0) if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(cached_gases[/datum/gas/oxygen][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 super_saturation = TRUE
if(cached_gases[/datum/gas/oxygen][MOLES] > cached_gases[/datum/gas/plasma][MOLES]*PLASMA_OXYGEN_FULLBURN) if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/plasma)*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases[/datum/gas/plasma][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA plasma_burn_rate = (air.get_moles(/datum/gas/plasma)*temperature_scale)/PLASMA_BURN_RATE_DELTA
else else
plasma_burn_rate = (temperature_scale*(cached_gases[/datum/gas/oxygen][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) 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 plasma_burn_rate = min(plasma_burn_rate,air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/oxygen)/oxygen_burn_rate) //Ensures matter is conserved properly
cached_gases[/datum/gas/plasma][MOLES] = QUANTIZE(cached_gases[/datum/gas/plasma][MOLES] - plasma_burn_rate) air.set_moles(/datum/gas/plasma, QUANTIZE(air.get_moles(/datum/gas/plasma) - plasma_burn_rate))
cached_gases[/datum/gas/oxygen][MOLES] = QUANTIZE(cached_gases[/datum/gas/oxygen][MOLES] - (plasma_burn_rate * oxygen_burn_rate)) air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) - (plasma_burn_rate * oxygen_burn_rate)))
if (super_saturation) if (super_saturation)
ASSERT_GAS(/datum/gas/tritium,air) air.adjust_moles(/datum/gas/tritium, plasma_burn_rate)
cached_gases[/datum/gas/tritium][MOLES] += plasma_burn_rate
else else
ASSERT_GAS(/datum/gas/carbon_dioxide,air) air.adjust_moles(/datum/gas/carbon_dioxide, plasma_burn_rate)
cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate) energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -200,11 +196,11 @@
if(energy_released > 0) if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity)
//let the floor know a fire is happening //let the floor know a fire is happening
if(istype(location)) if(istype(location))
temperature = air.temperature temperature = air.return_temperature()
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME) location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location) for(var/I in location)
@@ -232,12 +228,11 @@
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD) /datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
//Yogs start -- Cold Fusion //Yogs start -- Cold Fusion
if(air.temperature < FUSION_TEMPERATURE_THRESHOLD) if(air.return_temperature() < FUSION_TEMPERATURE_THRESHOLD)
if(!air.gases[/datum/gas/dilithium] || QUANTIZE(air.gases[/datum/gas/dilithium][MOLES]) <= 0) if(!air.get_moles(/datum/gas/dilithium))
return 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. // This is an exponential decay equation, actually. Horizontal Asymptote is FUSION_TEMPERATURE_THRESHOLD_MINIMUM.
return return
//Yogs End //Yogs End
@@ -252,13 +247,13 @@
var/list/cached_scan_results = air.analyzer_results var/list/cached_scan_results = air.analyzer_results
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions. var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
var/initial_plasma = cached_gases[/datum/gas/plasma][MOLES] var/initial_plasma = air.get_moles(/datum/gas/plasma)
var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide][MOLES] var/initial_carbon = air.get_moles(/datum/gas/carbon_dioxide)
var/scale_factor = (air.volume)/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions. var/scale_factor = (air.return_volume())/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus var/toroidal_size = (2*PI)+TORADIANS(arctan((air.return_volume()-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/gas_power = 0 var/gas_power = 0
for (var/gas_id in cached_gases) for (var/gas_id in air.get_gases())
gas_power += (cached_gases[gas_id][GAS_META][META_GAS_FUSION_POWER]*cached_gases[gas_id][MOLES]) 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 var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
cached_scan_results[id] = instability//used for analyzer feedback cached_scan_results[id] = instability//used for analyzer feedback
@@ -270,9 +265,9 @@
carbon = MODULUS(carbon - plasma, toroidal_size) carbon = MODULUS(carbon - plasma, toroidal_size)
cached_gases[/datum/gas/plasma][MOLES] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up air.set_moles(/datum/gas/plasma, plasma*scale_factor + FUSION_MOLE_THRESHOLD )//Scales the gases back up
cached_gases[/datum/gas/carbon_dioxide][MOLES] = carbon*scale_factor + FUSION_MOLE_THRESHOLD air.set_moles(/datum/gas/carbon_dioxide, carbon*scale_factor + FUSION_MOLE_THRESHOLD)
var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma][MOLES] var/delta_plasma = initial_plasma - air.get_moles(/datum/gas/plasma)
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass. reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
if(instability < FUSION_INSTABILITY_ENDOTHERMALITY) if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
@@ -281,19 +276,17 @@
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5 reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist. if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
cached_gases[/datum/gas/plasma][MOLES] = initial_plasma air.set_moles(/datum/gas/plasma, initial_plasma)
cached_gases[/datum/gas/carbon_dioxide][MOLES] = initial_carbon air.set_moles(/datum/gas/carbon_dioxide, initial_carbon)
return NO_REACTION 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 //The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
if(reaction_energy > 0) if(reaction_energy > 0)
air.assert_gases(/datum/gas/oxygen,/datum/gas/nitrous_oxide) air.adjust_moles(/datum/gas/oxygen, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
cached_gases[/datum/gas/oxygen][MOLES] += 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))
cached_gases[/datum/gas/nitrous_oxide][MOLES] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
else else
air.assert_gases(/datum/gas/bz,/datum/gas/nitryl) air.adjust_moles(/datum/gas/bz, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
cached_gases[/datum/gas/bz][MOLES] += 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))
cached_gases[/datum/gas/nitryl][MOLES] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
if(reaction_energy) if(reaction_energy)
if(location) if(location)
@@ -305,7 +298,7 @@
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = CLAMP(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY) air.set_temperature(CLAMP(((air.return_temperature()*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY))
return REACTING return REACTING
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst. /datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
@@ -322,23 +315,21 @@
) )
/datum/gas_reaction/nitrylformation/react(datum/gas_mixture/air) /datum/gas_reaction/nitrylformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases var/temperature = air.return_temperature()
var/temperature = air.temperature
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*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 var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
ASSERT_GAS(/datum/gas/nitryl,air) if ((air.get_moles(/datum/gas/oxygen) - heat_efficency < 0 )|| (air.get_moles(/datum/gas/nitrogen) - heat_efficency < 0)) //Shouldn't produce gas from nothing.
if ((cached_gases[/datum/gas/oxygen][MOLES] - heat_efficency < 0 )|| (cached_gases[/datum/gas/nitrogen][MOLES] - heat_efficency < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/oxygen][MOLES] -= heat_efficency air.adjust_moles(/datum/gas/oxygen, -heat_efficency)
cached_gases[/datum/gas/nitrogen][MOLES] -= heat_efficency air.adjust_moles(/datum/gas/nitrogen, -heat_efficency)
cached_gases[/datum/gas/nitryl][MOLES] += heat_efficency*2 air.adjust_moles(/datum/gas/nitryl, heat_efficency*2)
if(energy_used > 0) if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((temperature*old_heat_capacity - energy_used)/new_heat_capacity),TCMB) air.set_temperature(max(((temperature*old_heat_capacity - energy_used)/new_heat_capacity),TCMB))
return REACTING return REACTING
/datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic. /datum/gas_reaction/bzformation //Formation of BZ by combining plasma and tritium at low pressures. Exothermic.
@@ -354,29 +345,26 @@
/datum/gas_reaction/bzformation/react(datum/gas_mixture/air) /datum/gas_reaction/bzformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases var/temperature = air.return_temperature()
var/temperature = air.temperature
var/pressure = air.return_pressure() var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.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 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 return NO_REACTION
ASSERT_GAS(/datum/gas/bz,air) air.adjust_moles(/datum/gas/bz, reaction_efficency)
cached_gases[/datum/gas/bz][MOLES] += reaction_efficency if(reaction_efficency == air.get_moles(/datum/gas/nitrous_oxide))
if(reaction_efficency == cached_gases[/datum/gas/nitrous_oxide][MOLES]) air.adjust_moles(/datum/gas/bz, -min(pressure,1))
ASSERT_GAS(/datum/gas/oxygen,air) air.adjust_moles(/datum/gas/oxygen, min(pressure,1))
cached_gases[/datum/gas/bz][MOLES] -= min(pressure,1) air.adjust_moles(/datum/gas/nitrous_oxide, -reaction_efficency)
cached_gases[/datum/gas/oxygen][MOLES] += min(pressure,1) air.adjust_moles(/datum/gas/plasma, -2*reaction_efficency)
cached_gases[/datum/gas/nitrous_oxide][MOLES] -= reaction_efficency
cached_gases[/datum/gas/plasma][MOLES] -= 2*reaction_efficency
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((reaction_efficency**2)*BZ_RESEARCH_SCALE),BZ_RESEARCH_MAX_AMOUNT) SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((reaction_efficency**2)*BZ_RESEARCH_SCALE),BZ_RESEARCH_MAX_AMOUNT)
if(energy_released > 0) if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB) air.set_temperature(max(((temperature*old_heat_capacity + energy_released)/new_heat_capacity),TCMB))
return REACTING return REACTING
/datum/gas_reaction/stimformation //Stimulum formation follows a strange pattern of how effective it will be at a given temperature, having some multiple peaks and some large dropoffs. Exo and endo thermic. /datum/gas_reaction/stimformation //Stimulum formation follows a strange pattern of how effective it will be at a given temperature, having some multiple peaks and some large dropoffs. Exo and endo thermic.
@@ -392,23 +380,21 @@
"TEMP" = STIMULUM_HEAT_SCALE/2) "TEMP" = STIMULUM_HEAT_SCALE/2)
/datum/gas_reaction/stimformation/react(datum/gas_mixture/air) /datum/gas_reaction/stimformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/old_heat_capacity = air.heat_capacity() var/old_heat_capacity = air.heat_capacity()
var/heat_scale = min(air.temperature/STIMULUM_HEAT_SCALE,cached_gases[/datum/gas/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) 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 ((air.get_moles(/datum/gas/plasma) - heat_scale < 0) || (air.get_moles(/datum/gas/nitryl) - heat_scale < 0)) //Shouldn't produce gas from nothing.
if ((cached_gases[/datum/gas/plasma][MOLES] - heat_scale < 0) || (cached_gases[/datum/gas/nitryl][MOLES] - heat_scale < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/stimulum][MOLES]+= heat_scale/10 air.adjust_moles(/datum/gas/stimulum, heat_scale/10)
cached_gases[/datum/gas/plasma][MOLES] -= heat_scale air.adjust_moles(/datum/gas/plasma, -heat_scale)
cached_gases[/datum/gas/nitryl][MOLES] -= heat_scale air.adjust_moles(/datum/gas/nitryl, -heat_scale)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0)) SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0))
if(stim_energy_change) if(stim_energy_change)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((air.temperature*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB) air.set_temperature(max(((air.return_temperature()*old_heat_capacity + stim_energy_change)/new_heat_capacity),TCMB))
return REACTING return REACTING
/datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic. /datum/gas_reaction/nobliumformation //Hyper-Noblium formation is extrememly endothermic, but requires high temperatures to start. Due to its high mass, hyper-nobelium uses large amounts of nitrogen and tritium. BZ can be used as a catalyst to make it less endothermic.
@@ -423,22 +409,20 @@
"TEMP" = 5000000) "TEMP" = 5000000)
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air) /datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
air.assert_gases(/datum/gas/hypernoblium,/datum/gas/bz)
var/old_heat_capacity = air.heat_capacity() 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/nob_formed = min((air.get_moles(/datum/gas/nitrogen)+air.get_moles(/datum/gas/tritium))/100,air.get_moles(/datum/gas/tritium)/10,air.get_moles(/datum/gas/nitrogen)/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(cached_gases[/datum/gas/bz][MOLES],1))) var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(/datum/gas/bz),1)))
if ((cached_gases[/datum/gas/tritium][MOLES] - 10*nob_formed < 0) || (cached_gases[/datum/gas/nitrogen][MOLES] - 20*nob_formed < 0)) if ((air.get_moles(/datum/gas/tritium) - 10*nob_formed < 0) || (air.get_moles(/datum/gas/nitrogen) - 20*nob_formed < 0))
return NO_REACTION return NO_REACTION
cached_gases[/datum/gas/tritium][MOLES] -= 10*nob_formed air.adjust_moles(/datum/gas/tritium, -10*nob_formed)
cached_gases[/datum/gas/nitrogen][MOLES] -= 20*nob_formed air.adjust_moles(/datum/gas/nitrogen, -20*nob_formed)
cached_gases[/datum/gas/hypernoblium][MOLES]+= nob_formed air.adjust_moles(/datum/gas/hypernoblium, nob_formed)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT) SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
if (nob_formed) if (nob_formed)
var/new_heat_capacity = air.heat_capacity() var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((air.temperature*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB) air.set_temperature(max(((air.return_temperature()*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB))
/datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air /datum/gas_reaction/miaster //dry heat sterilization: clears out pathogens in the air
@@ -453,18 +437,15 @@
) )
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder) /datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
// As the name says it, it needs to be dry // As the name says it, it needs to be dry
if(/datum/gas/water_vapor in cached_gases) if(air.get_moles(/datum/gas/water_vapor)/air.total_moles() > 0.1) // Yogs --Fixes runtime in Sterilization
if(cached_gases[/datum/gas/water_vapor][MOLES]/air.total_moles() > 0.1) // Yogs --Fixes runtime in Sterilization return
return
//Replace miasma with oxygen //Replace miasma with oxygen
var/cleaned_air = min(cached_gases[/datum/gas/miasma][MOLES], 20 + (air.temperature - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20) var/cleaned_air = min(air.get_moles(/datum/gas/miasma), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
cached_gases[/datum/gas/miasma][MOLES] -= cleaned_air air.adjust_moles(/datum/gas/miasma, -cleaned_air)
ASSERT_GAS(/datum/gas/oxygen,air) air.adjust_moles(/datum/gas/oxygen, cleaned_air)
cached_gases[/datum/gas/oxygen][MOLES] += cleaned_air
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable //Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
air.temperature += cleaned_air * 0.002 air.set_temperature(air.return_temperature() + cleaned_air * 0.002)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, cleaned_air*MIASMA_RESEARCH_AMOUNT)//Turns out the burning of miasma is kinda interesting to scientists

View File

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

View File

@@ -51,10 +51,10 @@
return null return null
//Calculate necessary moles to transfer using PV = nRT //Calculate necessary moles to transfer using PV = nRT
if(air2.temperature>0) if(air2.return_temperature()>0)
var/pressure_delta = (input_starting_pressure - output_starting_pressure)/2 var/pressure_delta = (input_starting_pressure - output_starting_pressure)/2
var/transfer_moles = pressure_delta*air1.volume/(air2.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*air1.return_volume()/(air2.return_temperature() * R_IDEAL_GAS_EQUATION)
last_pressure_delta = pressure_delta last_pressure_delta = pressure_delta

View File

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

View File

@@ -53,11 +53,11 @@ Passive gate is similar to the regular pump except:
return return
//Calculate necessary moles to transfer using PV = nRT //Calculate necessary moles to transfer using PV = nRT
if((air1.total_moles() > 0) && (air1.temperature>0)) if((air1.total_moles() > 0) && (air1.return_temperature()>0))
var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2) var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2)
//Can not have a pressure delta that would cause output_pressure > input_pressure //Can not have a pressure delta that would cause output_pressure > input_pressure
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas //Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles) var/datum/gas_mixture/removed = air1.remove(transfer_moles)

View File

@@ -63,9 +63,9 @@
return return
//Calculate necessary moles to transfer using PV=nRT //Calculate necessary moles to transfer using PV=nRT
if((air1.total_moles() > 0) && (air1.temperature>0)) if((air1.total_moles() > 0) && (air1.return_temperature()>0))
var/pressure_delta = target_pressure - output_starting_pressure var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas //Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles) var/datum/gas_mixture/removed = air1.remove(transfer_moles)

View File

@@ -67,7 +67,7 @@
return return
var/transfer_ratio = transfer_rate/air1.volume var/transfer_ratio = transfer_rate/air1.return_volume()
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio) var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
@@ -166,7 +166,7 @@
if("set_transfer_rate" in signal.data) if("set_transfer_rate" in signal.data)
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume) transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.return_volume())
if(on != old_on) if(on != old_on)
investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS)

View File

@@ -16,8 +16,7 @@
..() ..()
for(var/i in 1 to device_type) for(var/i in 1 to device_type)
var/datum/gas_mixture/A = new var/datum/gas_mixture/A = new(200)
A.volume = 200
airs[i] = A airs[i] = A
// Iconnery // Iconnery
@@ -119,7 +118,7 @@
var/times_lost = 0 var/times_lost = 0
for(var/i in 1 to device_type) for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i] var/datum/gas_mixture/air = airs[i]
lost += pressures*environment.volume/(air.temperature * R_IDEAL_GAS_EQUATION) lost += pressures*environment.return_volume()/(air.return_temperature() * R_IDEAL_GAS_EQUATION)
times_lost++ times_lost++
var/shared_loss = lost/times_lost var/shared_loss = lost/times_lost

View File

@@ -70,7 +70,7 @@
//Early return //Early return
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
if(!air1 || air1.temperature <= 0) if(!air1 || air1.return_temperature() <= 0)
return return
var/datum/gas_mixture/air2 = airs[2] var/datum/gas_mixture/air2 = airs[2]
@@ -82,7 +82,7 @@
//No need to transfer if target is already full! //No need to transfer if target is already full!
return return
var/transfer_ratio = transfer_rate/air1.volume var/transfer_ratio = transfer_rate/air1.return_volume()
//Actually transfer the gas //Actually transfer the gas
@@ -101,15 +101,13 @@
else else
filtering = FALSE filtering = FALSE
if(filtering && removed.gases[filter_type]) if(filtering && removed.get_moles(filter_type))
var/datum/gas_mixture/filtered_out = new var/datum/gas_mixture/filtered_out = new
filtered_out.temperature = removed.temperature filtered_out.set_temperature(removed.return_temperature())
filtered_out.add_gas(filter_type) filtered_out.set_moles(filter_type, removed.get_moles(filter_type))
filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES]
removed.gases[filter_type][MOLES] = 0 removed.set_moles(filter_type, 0)
removed.garbage_collect()
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 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) target.merge(filtered_out)

View File

@@ -58,7 +58,7 @@
/obj/machinery/atmospherics/components/trinary/mixer/New() /obj/machinery/atmospherics/components/trinary/mixer/New()
..() ..()
var/datum/gas_mixture/air3 = airs[3] var/datum/gas_mixture/air3 = airs[3]
air3.volume = 300 air3.set_volume(300)
airs[3] = air3 airs[3] = air3
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos() /obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
@@ -82,26 +82,26 @@
return return
//Calculate necessary moles to transfer using PV=nRT //Calculate necessary moles to transfer using PV=nRT
var/general_transfer = (target_pressure - output_starting_pressure) * air3.volume / R_IDEAL_GAS_EQUATION var/general_transfer = (target_pressure - output_starting_pressure) * air3.return_volume() / R_IDEAL_GAS_EQUATION
var/transfer_moles1 = air1.temperature ? node1_concentration * general_transfer / air1.temperature : 0 var/transfer_moles1 = air1.return_temperature() ? node1_concentration * general_transfer / air1.return_temperature() : 0
var/transfer_moles2 = air2.temperature ? node2_concentration * general_transfer / air2.temperature : 0 var/transfer_moles2 = air2.return_temperature() ? node2_concentration * general_transfer / air2.return_temperature() : 0
var/air1_moles = air1.total_moles() var/air1_moles = air1.total_moles()
var/air2_moles = air2.total_moles() var/air2_moles = air2.total_moles()
if(!node2_concentration) if(!node2_concentration)
if(air1.temperature <= 0) if(air1.return_temperature() <= 0)
return return
transfer_moles1 = min(transfer_moles1, air1_moles) transfer_moles1 = min(transfer_moles1, air1_moles)
transfer_moles2 = 0 transfer_moles2 = 0
else if(!node1_concentration) else if(!node1_concentration)
if(air2.temperature <= 0) if(air2.return_temperature() <= 0)
return return
transfer_moles2 = min(transfer_moles2, air2_moles) transfer_moles2 = min(transfer_moles2, air2_moles)
transfer_moles1 = 0 transfer_moles1 = 0
else else
if(air1.temperature <= 0 || air2.temperature <= 0) if(air1.return_temperature() <= 0 || air2.return_temperature() <= 0)
return return
if((transfer_moles2 <= 0) || (transfer_moles1 <= 0)) if((transfer_moles2 <= 0) || (transfer_moles1 <= 0))
return return

View File

@@ -194,7 +194,7 @@
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
if(air1.gases.len) if(air1.total_moles())
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic. if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000) mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000)
mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_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. if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents. beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR) beaker.reagents.reaction(occupant, VAPOR)
air1.gases[/datum/gas/oxygen][MOLES] -= max(0,air1.gases[/datum/gas/oxygen][MOLES] - 2 / efficiency) //Let's use gas for this air1.adjust_moles(/datum/gas/oxygen, -max(0,air1.get_moles(/datum/gas/oxygen) - 2 / efficiency)) //Let's use gas for this
air1.garbage_collect()
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0 reagent_transfer = 0
@@ -217,7 +216,7 @@
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen][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 on = FALSE
update_icon() update_icon()
return return
@@ -225,22 +224,21 @@
if(occupant) if(occupant)
var/mob/living/mob_occupant = occupant var/mob/living/mob_occupant = occupant
var/cold_protection = 0 var/cold_protection = 0
var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant. var/temperature_delta = air1.return_temperature() - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant.
if(ishuman(occupant)) if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant var/mob/living/carbon/human/H = occupant
cold_protection = H.get_cold_protection(air1.temperature) cold_protection = H.get_cold_protection(air1.return_temperature())
if(abs(temperature_delta) > 1) if(abs(temperature_delta) > 1)
var/air_heat_capacity = air1.heat_capacity() var/air_heat_capacity = air1.heat_capacity()
var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity)) var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity))
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB) air1.set_temperature(max(air1.return_temperature() - heat / air_heat_capacity, TCMB))
mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB) mob_occupant.adjust_bodytemperature(heat / heat_capacity, TCMB)
air1.gases[/datum/gas/oxygen][MOLES] = max(0,air1.gases[/datum/gas/oxygen][MOLES] - 0.5 / efficiency) // Magically consume gas? Why not, we run on cryo magic. 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.
air1.garbage_collect()
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change() /obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
..() ..()
@@ -376,7 +374,7 @@
data["occupant"]["temperaturestatus"] = "bad" data["occupant"]["temperaturestatus"] = "bad"
var/datum/gas_mixture/air1 = airs[1] var/datum/gas_mixture/air1 = airs[1]
data["cellTemperature"] = round(air1.temperature, 1) data["cellTemperature"] = round(air1.return_temperature(), 1)
data["isBeakerLoaded"] = beaker ? TRUE : FALSE data["isBeakerLoaded"] = beaker ? TRUE : FALSE
var/beakerContents = list() var/beakerContents = list()
@@ -431,7 +429,7 @@
var/datum/gas_mixture/G = airs[1] var/datum/gas_mixture/G = airs[1]
if(G.total_moles() > 10) if(G.total_moles() > 10)
return G.temperature return G.return_temperature()
return ..() return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W) /obj/machinery/atmospherics/components/unary/cryo_cell/default_change_direction_wrench(mob/user, obj/item/wrench/W)

View File

@@ -59,18 +59,18 @@
var/other_air_heat_capacity = partner_air_contents.heat_capacity() var/other_air_heat_capacity = partner_air_contents.heat_capacity()
var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature var/old_temperature = air_contents.return_temperature()
var/other_old_temperature = partner_air_contents.temperature var/other_old_temperature = partner_air_contents.return_temperature()
if(combined_heat_capacity > 0) if(combined_heat_capacity > 0)
var/combined_energy = partner_air_contents.temperature*other_air_heat_capacity + air_heat_capacity*air_contents.temperature var/combined_energy = partner_air_contents.return_temperature()*other_air_heat_capacity + air_heat_capacity*air_contents.return_temperature()
var/new_temperature = combined_energy/combined_heat_capacity var/new_temperature = combined_energy/combined_heat_capacity
air_contents.temperature = new_temperature air_contents.set_temperature(new_temperature)
partner_air_contents.temperature = new_temperature partner_air_contents.set_temperature(new_temperature)
if(abs(old_temperature-air_contents.temperature) > 1) if(abs(old_temperature-air_contents.return_temperature()) > 1)
update_parents() update_parents()
if(abs(other_old_temperature-partner_air_contents.temperature) > 1) if(abs(other_old_temperature-partner_air_contents.return_temperature()) > 1)
partner.update_parents() partner.update_parents()

View File

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

View File

@@ -18,7 +18,7 @@
/obj/machinery/atmospherics/components/unary/portables_connector/New() /obj/machinery/atmospherics/components/unary/portables_connector/New()
..() ..()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 0 air_contents.set_volume(0)
/obj/machinery/atmospherics/components/unary/portables_connector/Destroy() /obj/machinery/atmospherics/components/unary/portables_connector/Destroy()
if(connected_device) if(connected_device)

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

View File

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

View File

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

View File

@@ -151,44 +151,29 @@
return FALSE return FALSE
var/datum/gas_mixture/environment = tile.return_air() var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE) if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
return FALSE return FALSE
if(scrubbing & SCRUBBING) if(scrubbing & SCRUBBING)
if(length(env_gases & filter_types)) var/transfer_moles = min(1, volume_rate/environment.return_volume())*environment.total_moles()
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
//Take a gas sample //Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile //Nothing left to remove from the tile
if(isnull(removed)) if(isnull(removed))
return FALSE return FALSE
var/list/removed_gases = removed.gases removed.scrub_into(air_contents, filter_types)
//Filter it //Remix the resulting gases
var/datum/gas_mixture/filtered_out = new tile.assume_air(removed)
var/list/filtered_gases = filtered_out.gases tile.air_update_turf()
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
filtered_out.add_gas(gas)
filtered_gases[gas][MOLES] = removed_gases[gas][MOLES]
removed_gases[gas][MOLES] = 0
removed.garbage_collect()
//Remix the resulting gases
air_contents.merge(filtered_out)
tile.assume_air(removed)
tile.air_update_turf()
else //Just siphoning all air else //Just siphoning all air
var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) var/transfer_moles = environment.total_moles()*(volume_rate/environment.return_volume())
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles) var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)

View File

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

View File

@@ -103,7 +103,7 @@
if (target) if (target)
var/datum/gas_mixture/environment = target.return_air() var/datum/gas_mixture/environment = target.return_air()
if(environment) if(environment)
. = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)] K ([round(environment.temperature-T0C,0.01)]&deg;C)." . = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.return_temperature(),0.01)] K ([round(environment.return_temperature()-T0C,0.01)]&deg;C)."
else else
. = "The sensor error light is blinking." . = "The sensor error light is blinking."
else else

View File

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

View File

@@ -28,14 +28,14 @@
if(islava(T)) if(islava(T))
environment_temperature = 5000 environment_temperature = 5000
else if(T.blocks_air) else if(T.blocks_air)
environment_temperature = T.temperature environment_temperature = T.return_temperature()
else else
var/turf/open/OT = T var/turf/open/OT = T
environment_temperature = OT.GetTemperature() environment_temperature = OT.GetTemperature()
else else
environment_temperature = T.temperature environment_temperature = T.return_temperature()
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) if(abs(environment_temperature-pipe_air.return_temperature()) > minimum_temperature_difference)
parent.temperature_interact(T, volume, thermal_conductivity) parent.temperature_interact(T, volume, thermal_conductivity)
@@ -44,11 +44,11 @@
var/hc = pipe_air.heat_capacity() var/hc = pipe_air.heat_capacity()
var/mob/living/heat_source = buckled_mobs[1] var/mob/living/heat_source = buckled_mobs[1]
//Best guess-estimate of the total bodytemperature of all the mobs, since they share the same environment it's ~ok~ to guess like this //Best guess-estimate of the total bodytemperature of all the mobs, since they share the same environment it's ~ok~ to guess like this
var/avg_temp = (pipe_air.temperature * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs ? buckled_mobs.len * 3500 : 0)) var/avg_temp = (pipe_air.return_temperature() * hc + (heat_source.bodytemperature * buckled_mobs.len) * 3500) / (hc + (buckled_mobs ? buckled_mobs.len * 3500 : 0))
for(var/m in buckled_mobs) for(var/m in buckled_mobs)
var/mob/living/L = m var/mob/living/L = m
L.bodytemperature = avg_temp L.bodytemperature = avg_temp
pipe_air.temperature = avg_temp pipe_air.set_temperature(avg_temp)
/obj/machinery/atmospherics/pipe/heat_exchanging/process() /obj/machinery/atmospherics/pipe/heat_exchanging/process()
if(!parent) if(!parent)
@@ -57,9 +57,9 @@
var/datum/gas_mixture/pipe_air = return_air() var/datum/gas_mixture/pipe_air = return_air()
//Heat causes pipe to glow //Heat causes pipe to glow
if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //glow starts at 500K if(pipe_air.return_temperature() && (icon_temperature > 500 || pipe_air.return_temperature() > 500)) //glow starts at 500K
if(abs(pipe_air.temperature - icon_temperature) > 10) if(abs(pipe_air.return_temperature() - icon_temperature) > 10)
icon_temperature = pipe_air.temperature icon_temperature = pipe_air.return_temperature()
var/h_r = heat2colour_r(icon_temperature) var/h_r = heat2colour_r(icon_temperature)
var/h_g = heat2colour_g(icon_temperature) var/h_g = heat2colour_g(icon_temperature)
@@ -76,7 +76,7 @@
//burn any mobs buckled based on temperature //burn any mobs buckled based on temperature
if(has_buckled_mobs()) if(has_buckled_mobs())
var/heat_limit = 1000 var/heat_limit = 1000
if(pipe_air.temperature > heat_limit + 1) if(pipe_air.return_temperature() > heat_limit + 1)
for(var/m in buckled_mobs) for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m var/mob/living/buckled_mob = m
buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BODY_ZONE_CHEST) buckled_mob.apply_damage(4 * log(pipe_air.return_temperature() - heat_limit), BURN, BODY_ZONE_CHEST)

View File

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

View File

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

View File

@@ -40,21 +40,14 @@
if(air_contents.return_pressure() >= overpressure_m * ONE_ATMOSPHERE) if(air_contents.return_pressure() >= overpressure_m * ONE_ATMOSPHERE)
return 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/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
var/datum/gas_mixture/filtered = new
if(!filtering) if(!filtering)
return return
filtered.temperature = filtering.temperature filtering.scrub_into(air_contents, scrubbing)
for(var/gas in filtering.gases & scrubbing)
filtered.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.
air_contents.merge(filtered) // Store filtered out gasses.
mixture.merge(filtering) // Returned the cleaned gas. mixture.merge(filtering) // Returned the cleaned gas.
if(!holding) if(!holding)
air_update_turf() air_update_turf()

View File

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

View File

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

View File

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

View File

@@ -56,9 +56,8 @@
return return
var/datum/gas_mixture/stank = new var/datum/gas_mixture/stank = new
ADD_GAS(/datum/gas/miasma, stank.gases) 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.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.set_temperature(T20C) // without this the room would eventually freeze and miasma mining would be easier
stank.temperature = T20C // without this the room would eventually freeze and miasma mining would be easier
T.assume_air(stank) T.assume_air(stank)
T.air_update_turf() T.air_update_turf()

View File

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

View File

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

View File

@@ -12,28 +12,23 @@
var/toxins_used = 0 var/toxins_used = 0
var/tox_detect_threshold = 0.02 var/tox_detect_threshold = 0.02
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
var/list/breath_gases = breath.gases
breath.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
//Partial pressure of the toxins in our breath //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 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) 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 else
clear_alert("alien_tox") clear_alert("alien_tox")
//Breathe in toxins and out oxygen //Breathe in toxins and out oxygen
breath_gases[/datum/gas/plasma][MOLES] -= toxins_used breath.adjust_moles(/datum/gas/plasma, -toxins_used)
breath_gases[/datum/gas/oxygen][MOLES] += toxins_used breath.adjust_moles(/datum/gas/oxygen, toxins_used)
breath.garbage_collect()
//BREATH TEMPERATURE //BREATH TEMPERATURE
handle_breath_temperature(breath) 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((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment) if(environment)
if(environment.total_moles()) if(environment.total_moles())
if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][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) H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0) if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>") H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")

View File

@@ -162,13 +162,11 @@
var/SA_para_min = 1 var/SA_para_min = 1
var/SA_sleep_min = 5 var/SA_sleep_min = 5
var/oxygen_used = 0 var/oxygen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
var/list/breath_gases = breath.gases var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz) var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
var/O2_partialpressure = (breath_gases[/datum/gas/oxygen][MOLES]/breath.total_moles())*breath_pressure var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/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
//OXYGEN //OXYGEN
@@ -179,7 +177,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3)) adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1 failed_last_breath = 1
oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]*ratio oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
else else
adjustOxyLoss(3) adjustOxyLoss(3)
failed_last_breath = 1 failed_last_breath = 1
@@ -189,11 +187,11 @@
failed_last_breath = 0 failed_last_breath = 0
if(health >= crit_threshold) if(health >= crit_threshold)
adjustOxyLoss(-5) adjustOxyLoss(-5)
oxygen_used = breath_gases[/datum/gas/oxygen][MOLES] oxygen_used = breath.get_moles(/datum/gas/oxygen)
clear_alert("not_enough_oxy") clear_alert("not_enough_oxy")
breath_gases[/datum/gas/oxygen][MOLES] -= oxygen_used breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
breath_gases[/datum/gas/carbon_dioxide][MOLES] += oxygen_used breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
//CARBON DIOXIDE //CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max) if(CO2_partialpressure > safe_co2_max)
@@ -212,15 +210,15 @@
//TOXINS/PLASMA //TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max) 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)) adjustToxLoss(CLAMP(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox) throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else else
clear_alert("too_much_tox") clear_alert("too_much_tox")
//NITROUS OXIDE //NITROUS OXIDE
if(breath_gases[/datum/gas/nitrous_oxide]) if(breath.get_moles(/datum/gas/nitrous_oxide))
var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide][MOLES]/breath.total_moles())*breath_pressure var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min) if(SA_partialpressure > SA_para_min)
Unconscious(60) Unconscious(60)
if(SA_partialpressure > SA_sleep_min) if(SA_partialpressure > SA_sleep_min)
@@ -234,8 +232,8 @@
//yogs start -- Adds Nitrogen Narcosis https://en.wikipedia.org/wiki/Nitrogen_narcosis //yogs start -- Adds Nitrogen Narcosis https://en.wikipedia.org/wiki/Nitrogen_narcosis
//NITROGEN //NITROGEN
if(breath_gases[/datum/gas/nitrogen]) if(breath.get_moles(/datum/gas/nitrogen))
var/SA_partialpressure = (breath_gases[/datum/gas/nitrogen][MOLES]/breath.total_moles())*breath_pressure var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrogen)/breath.total_moles())*breath_pressure
if(SA_partialpressure > NITROGEN_NARCOSIS_PRESSURE_LOW) // Giggles if(SA_partialpressure > NITROGEN_NARCOSIS_PRESSURE_LOW) // Giggles
if(prob(20)) if(prob(20))
emote(pick("giggle","laugh")) emote(pick("giggle","laugh"))
@@ -246,8 +244,8 @@
hallucination += 5 hallucination += 5
//yogs end //yogs end
//BZ (Facepunch port of their Agent B) //BZ (Facepunch port of their Agent B)
if(breath_gases[/datum/gas/bz]) if(breath.get_moles(/datum/gas/bz))
var/bz_partialpressure = (breath_gases[/datum/gas/bz][MOLES]/breath.total_moles())*breath_pressure var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
/* Yogs comment-out: Smoothed BZ hallucination levels /* Yogs comment-out: Smoothed BZ hallucination levels
if(bz_partialpressure > 1) if(bz_partialpressure > 1)
hallucination += 10 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() 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 //TRITIUM
if(breath_gases[/datum/gas/tritium]) if(breath.get_moles(/datum/gas/tritium))
var/tritium_partialpressure = (breath_gases[/datum/gas/tritium][MOLES]/breath.total_moles())*breath_pressure var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
radiation += tritium_partialpressure/10 radiation += tritium_partialpressure/10
//NITRYL //NITRYL
if(breath_gases[/datum/gas/nitryl]) if(breath.get_moles(/datum/gas/nitryl))
var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl][MOLES]/breath.total_moles())*breath_pressure var/nitryl_partialpressure = (breath.get_moles(/datum/gas/nitryl)/breath.total_moles())*breath_pressure
adjustFireLoss(nitryl_partialpressure/4) adjustFireLoss(nitryl_partialpressure/4)
//MIASMA //MIASMA
if(breath_gases[/datum/gas/miasma]) if(breath.get_moles(/datum/gas/miasma))
var/miasma_partialpressure = (breath_gases[/datum/gas/miasma][MOLES]/breath.total_moles())*breath_pressure var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
if(prob(1 * miasma_partialpressure)) if(prob(1 * miasma_partialpressure))
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3) 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") SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
breath.garbage_collect()
//BREATH TEMPERATURE //BREATH TEMPERATURE
handle_breath_temperature(breath) handle_breath_temperature(breath)

View File

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

View File

@@ -112,7 +112,7 @@
ExtinguishMob() ExtinguishMob()
return TRUE //mob was put out, on_fire = FALSE via ExtinguishMob(), no need to update everything down the chain. 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 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 ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return TRUE return TRUE
var/turf/location = get_turf(src) 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(). 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) /mob/living/proc/get_temperature(datum/gas_mixture/environment)
var/loc_temp = environment ? environment.temperature : T0C var/loc_temp = environment ? environment.return_temperature() : T0C
if(isobj(loc)) if(isobj(loc))
var/obj/oloc = loc var/obj/oloc = loc
var/obj_temp = oloc.return_temperature() var/obj_temp = oloc.return_temperature()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -201,10 +201,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(get_integrity() < SUPERMATTER_DANGER_PERCENT) if(get_integrity() < SUPERMATTER_DANGER_PERCENT)
return SUPERMATTER_DANGER 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 return SUPERMATTER_WARNING
if(air.temperature > (CRITICAL_TEMPERATURE * 0.8)) if(air.return_temperature() > (CRITICAL_TEMPERATURE * 0.8))
return SUPERMATTER_NOTIFY return SUPERMATTER_NOTIFY
if(power > 5) if(power > 5)
@@ -338,29 +338,29 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
else else
if(takes_damage) if(takes_damage)
//causing 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(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) damage = max(damage + (max(combined_gas - MOLE_PENALTY_THRESHOLD, 0)/80) * DAMAGE_INCREASE_MULTIPLIER, 0)
//healing damage //healing damage
if(combined_gas < MOLE_PENALTY_THRESHOLD) 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 //capping damage
damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage) damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage)
if(damage > damage_archived && prob(10)) if(damage > damage_archived && prob(10))
playsound(get_turf(src), 'sound/effects/empulse.ogg', 50, 1) 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 //calculating gas related values
combined_gas = max(removed.total_moles(), 0) combined_gas = max(removed.total_moles(), 0)
plasmacomp = max(removed.gases[/datum/gas/plasma][MOLES]/combined_gas, 0) plasmacomp = max(removed.get_moles(/datum/gas/plasma)/combined_gas, 0)
o2comp = max(removed.gases[/datum/gas/oxygen][MOLES]/combined_gas, 0) o2comp = max(removed.get_moles(/datum/gas/oxygen)/combined_gas, 0)
co2comp = max(removed.gases[/datum/gas/carbon_dioxide][MOLES]/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) n2ocomp = max(removed.get_moles(/datum/gas/nitrous_oxide)/combined_gas, 0)
n2comp = max(removed.gases[/datum/gas/nitrogen][MOLES]/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) 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 temp_factor = 30
icon_state = base_icon_state 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)) if(prob(50))
radiation_pulse(src, power * (1 + power_transmission_bonus/10)) 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 //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. //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 //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) if(produces_gas)
env.merge(removed) env.merge(removed)

View File

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

View File

@@ -268,7 +268,7 @@
if(isopenturf(T)) if(isopenturf(T))
var/turf/open/OT = 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.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 /datum/reagent/consumable/condensedcapsaicin
name = "Condensed Capsaicin" name = "Condensed Capsaicin"
@@ -443,7 +443,7 @@
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot) if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles()) 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) lowertemp.react(src)
T.assume_air(lowertemp) T.assume_air(lowertemp)
qdel(hotspot) qdel(hotspot)

View File

@@ -136,7 +136,7 @@
if(hotspot && !isspaceturf(T)) if(hotspot && !isspaceturf(T))
if(T.air) if(T.air)
var/datum/gas_mixture/G = 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) G.react(src)
qdel(hotspot) qdel(hotspot)
var/obj/effect/acid/A = (locate(/obj/effect/acid) in T) var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)

View File

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

View File

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