Fixes almost all the bugs that I should have fixed six months ago (#18323)

* Fixes scanners properly this time

* Just some code cleanup

* Fixes HE pipes being fast

* Fixes a bug that, for once, was not my fault

* Bugs both my fault and otherwise

* Why didn't I just do this in the first place?

* Turns out I wasn't the one who did the last one

* Simplification

* This was just completely incorrect

* Just style, which should have been included in the last commit

* Use new proc

* Simplification. This is still fucked up by the way

* And fixes a bug with freezers. This behavior is still fucked up though

* Woah fuck I nearly missed this. Freezers no longer have the volume of an entire zone.

* This should really be based on partial pressure, but that's a problem for another day

* There was never a reason to remove the air since thermal energy change is scale-invariant, dummy

* I THINK this is as correct as it's going to get without a rewrite

* Reading this hurt me

* Forgot this one, long ago

* Fuck lifecode

* Various stuff

* Removing the air is still unnecessary

* Fixes these not updating the zones, but these should really adjust thermal energy rather than absolute temperature

* Fixes these to update and use pressure

* This one gets special mention for breaking any existing sleeping agent in the area

* Whoops. I really need to standardize this.

* For fuck's sake

* I was going to make it adjust the environment temperature directly but looking at the code hurt my skull

* Not really deserving of its own commit but R-UST is next

* Existence is pain

* Fixes compile errors and a trillion runtimes
The gas_mixture procs should probably never return null, but oh well

* You're solving for the wrong n
This commit is contained in:
Exxion
2018-05-22 05:39:19 -04:00
committed by jknpj
parent 1171796a43
commit e7c24c311c
58 changed files with 208 additions and 266 deletions

View File

@@ -319,7 +319,7 @@ Pipelines + Other Objects -> Pipe network
user.visible_message("[user] vents \the [src].",
"You have vented \the [src].",
"You hear a ratchet.")
var/datum/gas_mixture/internal_removed = int_air.remove(int_air.total_moles()*starting_volume/int_air.volume)
var/datum/gas_mixture/internal_removed = int_air.remove_volume(starting_volume)
env_air.merge(internal_removed)
else
to_chat(user, "<span class='warning'>You cannot unwrench this [src], it's too exerted due to internal pressure.</span>")

View File

@@ -86,7 +86,7 @@
if(pressure_delta > 0)
if(air1.temperature > 0)
var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles = pressure_delta * CELL_VOLUME / (air1.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
@@ -105,7 +105,7 @@
if(pressure_delta > 0)
if(environment.temperature > 0)
var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles = pressure_delta * air2.volume / (environment.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)

View File

@@ -41,7 +41,7 @@
var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2)
//Can not have a pressure delta that would cause output_pressure > input_pressure
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles = pressure_delta * air2.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles)

View File

@@ -59,7 +59,7 @@ Thus, the two variables affect pump operation are set in New():
//Calculate necessary moles to transfer using PV=nRT
if((air1.total_moles() > 0) && (air1.temperature>0))
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles = pressure_delta * air2.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles)

View File

@@ -71,7 +71,7 @@ obj/machinery/atmospherics/trinary/filter/process()
var/transfer_moles
if(air1.temperature > 0)
transfer_moles = pressure_delta*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * air3.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas

View File

@@ -56,10 +56,10 @@ obj/machinery/atmospherics/trinary/mixer/process()
var/transfer_moles2 = 0
if(air1.temperature > 0)
transfer_moles1 = (node1_concentration*pressure_delta)*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
transfer_moles1 = (node1_concentration * pressure_delta) * air3.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)
if(air2.temperature > 0)
transfer_moles2 = (node2_concentration*pressure_delta)*air3.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
transfer_moles2 = (node2_concentration * pressure_delta) * air3.volume / (air2.temperature * R_IDEAL_GAS_EQUATION)
var/air1_moles = air1.total_moles()
var/air2_moles = air2.total_moles()

View File

@@ -54,7 +54,7 @@
return
if(air_contents.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.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -72,7 +72,7 @@
injecting = 1
if(air_contents.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.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)

View File

@@ -19,12 +19,7 @@
//Get processable air sample and thermal info from environment
var/environment_moles = environment.total_moles()
var/transfer_moles = 0.25 * environment_moles
var/datum/gas_mixture/external_removed = environment.remove(transfer_moles)
if(!external_removed)
return radiate()
var/environment_moles = environment.molar_density() * CELL_VOLUME
if(environment_moles < NO_GAS)
return radiate()
@@ -33,15 +28,15 @@
//Get same info from connected gas
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
var/datum/gas_mixture/internal_removed = air_contents.remove_ratio(0.25)
if (!internal_removed)
environment.merge(external_removed)
return
var/datum/gas_mixture/external_removed = environment.remove(0.25 * environment_moles)
var/combined_heat_capacity = internal_removed.heat_capacity() + external_removed.heat_capacity()
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + external_removed.heat_capacity() * external_removed.temperature
var/combined_energy = internal_removed.thermal_energy() + external_removed.thermal_energy()
if(!combined_heat_capacity)
combined_heat_capacity = 1
@@ -70,14 +65,13 @@
air_contents.copy_from(network.radiate) //We can cut down on processing time by only calculating radiate() once and then applying the result
return
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
var/datum/gas_mixture/internal_removed = air_contents.remove_ratio(0.25)
if (!internal_removed)
return
var/combined_heat_capacity = internal_removed.heat_capacity() + RADIATION_CAPACITY
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + (RADIATION_CAPACITY * 6.4)
var/combined_energy = internal_removed.thermal_energy() + (RADIATION_CAPACITY * 6.4)
var/final_temperature = combined_energy / combined_heat_capacity

View File

@@ -120,7 +120,7 @@
if(pressure_delta > 0.1)
if(air_contents.temperature > 0)
var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles = pressure_delta * CELL_VOLUME / (air_contents.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -138,7 +138,7 @@
if(pressure_delta > 0.1)
if(environment.temperature > 0)
var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
if (isnull(removed)) //in space

View File

@@ -159,7 +159,7 @@
(scrub_N2O && environment.trace_gases.len > 0) ||\
(scrub_O2 && environment.oxygen > 0) ||\
(scrub_N2 && environment.nitrogen > 0))
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
var/transfer_moles = min(1, volume_rate / environment.volume) * environment.total_moles()
//Take a gas sample
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)

View File

@@ -66,41 +66,29 @@
if(!parent)
. = ..()
// Get gas from pipenet
var/datum/gas_mixture/internal = return_air()
var/remove_ratio = volume/internal.volume
var/datum/gas_mixture/internal_removed = internal.remove_ratio(remove_ratio)
//Get processable air sample and thermal info from environment
var/datum/gas_mixture/environment = loc.return_air()
var/environment_moles = environment.total_moles()
var/transfer_moles = 0.25 * environment_moles
var/datum/gas_mixture/external_removed = environment.remove(transfer_moles)
var/environment_moles = environment.molar_density() * CELL_VOLUME //Moles per turf
// No environmental gas? We radiate it, then.
if(!external_removed)
if(internal_removed)
internal.merge(internal_removed)
return radiate()
// Not enough gas in the air around us to care about. Radiate. Less gas than airless tiles start with.
//Not enough gas in the air around us to care about. Radiate. Less gas than airless tiles start with.
if(environment_moles < NO_GAS)
if(internal_removed)
internal.merge(internal_removed)
environment.merge(external_removed)
return radiate()
// A tiny bit of air so this isn't really space, but its not worth activating exchange procs
//A tiny bit of air so this isn't really space, but it's not worth activating exchange procs
else if(environment_moles < SOME_GAS)
return 0
// No internal gas. Screw this, we're out.
if(!internal_removed)
environment.merge(external_removed)
//Get gas from pipenet
var/datum/gas_mixture/internal = return_air()
if(!internal.total_moles)
return
var/datum/gas_mixture/external_removed = environment.remove(0.25 * environment_moles)
var/datum/gas_mixture/internal_removed = internal.remove_volume(volume)
//Get same info from connected gas
var/combined_heat_capacity = internal_removed.heat_capacity() + external_removed.heat_capacity()
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + external_removed.heat_capacity() * external_removed.temperature
var/combined_energy = internal_removed.thermal_energy() + external_removed.thermal_energy()
if(!combined_heat_capacity)
combined_heat_capacity = 1
@@ -119,14 +107,13 @@
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/proc/radiate()
var/datum/gas_mixture/internal = return_air()
var/remove_ratio = volume/internal.volume
var/datum/gas_mixture/internal_removed = internal.remove_ratio(remove_ratio)
var/datum/gas_mixture/internal_removed = internal.remove_volume(volume)
if (!internal_removed)
return
var/combined_heat_capacity = internal_removed.heat_capacity() + RADIATION_CAPACITY
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + (RADIATION_CAPACITY * ENERGY_MULT)
var/combined_energy = internal_removed.thermal_energy() + (RADIATION_CAPACITY * ENERGY_MULT)
var/final_temperature = combined_energy / combined_heat_capacity

View File

@@ -93,8 +93,7 @@
var/turf/simulated/L = loc
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
var/transfer_moles = 0.25 * env.total_moles() / env.volume * CELL_VOLUME
var/datum/gas_mixture/removed = env.remove(transfer_moles)
var/datum/gas_mixture/removed = env.remove_volume(0.25 * CELL_VOLUME)
if(removed)
if(removed.temperature > (set_temperature + T0C))
var/air_heat_capacity = removed.heat_capacity()
@@ -102,8 +101,8 @@
//var/old_temperature = removed.temperature
if(combined_heat_capacity > 0)
var/combined_energy = set_temperature*cooling_power + air_heat_capacity*removed.temperature
removed.temperature = combined_energy/combined_heat_capacity
var/combined_energy = set_temperature * cooling_power + removed.thermal_energy()
removed.temperature = combined_energy / combined_heat_capacity
env.merge(removed)
return 1
env.merge(removed)

View File

@@ -127,7 +127,7 @@
..()
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
if(env.oxygen < 5)
if(env.molar_density("oxygen") < 5 / CELL_VOLUME)
to_chat(user, "<span class='notice'>You try to light \the [name], but it won't catch on fire!")
return
if(!on && cell.charge > 0)
@@ -282,9 +282,7 @@
var/datum/gas_mixture/env = L.return_air()
if(env.temperature != set_temperature + T0C)
var/transfer_moles = 0.25 * env.total_moles() / env.volume * CELL_VOLUME
var/datum/gas_mixture/removed = env.remove(transfer_moles)
var/datum/gas_mixture/removed = env.remove_volume(0.25 * CELL_VOLUME)
// to_chat(world, "got [transfer_moles] moles at [removed.temperature]")

View File

@@ -143,7 +143,12 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
var/moles_covered = environment.return_pressure()*volume_covered/(environment.temperature * R_IDEAL_GAS_EQUATION)
// to_chat(world, "<span class='notice'>moles_covered: [moles_covered]</span>")
//
var/datum/gas_mixture/gas_covered = environment.remove(moles_covered)
//Since nearly every mathematical expression in this file is wrong in some way, it actually relied on a bug in ZAS to not cause ridiculous nonsense.
//That bug got fixed, and ridiculous nonsense was caused.
//The min() in the following line of code simulates that bug, because god is dead.
//Obviously the correct solution would be to fix all the errors in here, but that would involve rebalancing every magic number in this file.
var/datum/gas_mixture/gas_covered = environment.remove(min(moles_covered, environment.molar_density() * CELL_VOLUME))
var/datum/gas_mixture/plasma_captured = new /datum/gas_mixture()
//
plasma_captured.toxins = round(gas_covered.toxins * transfer_ratio)

View File

@@ -441,7 +441,7 @@
var/transfer_moles = 0
if(pressure_delta > 0) //cabin pressure lower than release pressure
if(tank_air.return_temperature() > 0)
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * cabin_air.return_volume() / (cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
cabin_air.merge(removed)
else if(pressure_delta < 0) //cabin pressure higher than release pressure
@@ -450,7 +450,7 @@
if(t_air)
pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
if(pressure_delta > 0) //if location pressure is lower than cabin pressure
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * cabin_air.return_volume() / (cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
if(t_air)
t_air.merge(removed)

View File

@@ -169,9 +169,9 @@ Attach to transfer valve and open. BOOM.
//since the air is processed in fractions, we need to make sure not to have any minuscle residue or
//the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour
if(air_contents.oxygen < 0.1)
if(air_contents.molar_density("oxygen") < 0.1 / CELL_VOLUME)
air_contents.oxygen = 0
if(air_contents.toxins < 0.1)
if(air_contents.molar_density("toxins") < 0.1 / CELL_VOLUME)
air_contents.toxins = 0
if(fuel)
if(fuel.moles < 0.1)
@@ -240,7 +240,7 @@ Attach to transfer valve and open. BOOM.
//seperate part of the present gas
//this is done to prevent the fire burning all gases in a single pass
var/datum/gas_mixture/flow = air_contents.remove_ratio(zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate))
var/datum/gas_mixture/flow = air_contents.remove_volume(zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate) * CELL_VOLUME)
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
if(flow)
@@ -350,9 +350,9 @@ datum/gas_mixture/proc/zburn(var/turf/T, force_burn)
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
if(oxygen && (toxins || fuel))
if(QUANTIZE((toxins / volume * CELL_VOLUME) * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= MOLES_PLASMA_VISIBLE)
if(QUANTIZE(molar_density("toxins") * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= MOLES_PLASMA_VISIBLE / CELL_VOLUME)
return 1
if(fuel && QUANTIZE((fuel.moles / volume * CELL_VOLUME) * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ)
if(fuel && QUANTIZE((fuel.moles / volume) * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ / CELL_VOLUME) //Not bothering to make molar_density() support trace_gases since I'm removing those soon anyway
return 1
// Check if we're actually in a turf or not before trying to check object fires.
@@ -394,9 +394,9 @@ datum/gas_mixture/proc/check_combustability(var/turf/T, var/objects)
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
if(oxygen && (toxins || fuel))
if(QUANTIZE(toxins * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= MOLES_PLASMA_VISIBLE)
if(QUANTIZE(molar_density("toxins") * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= MOLES_PLASMA_VISIBLE / CELL_VOLUME)
return 1
if(fuel && QUANTIZE(fuel.moles * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ)
if(fuel && QUANTIZE((fuel.moles / volume) * zas_settings.Get(/datum/ZAS_Setting/fire_consumption_rate)) >= BASE_ZAS_FUEL_REQ / CELL_VOLUME)
return 1
if(objects && istype(T))

View File

@@ -203,7 +203,11 @@
/datum/gas_mixture/proc/thermal_energy()
return temperature*heat_capacity()
return temperature * heat_capacity()
/datum/gas_mixture/proc/molar_density(gas) //Per liter. You should probably be using pressure instead, but considering this had to be made, you wouldn't be the first not to.
return (gas ? vars[gas] : total_moles) / volume //Should verify if gas is actually a valid gas, but this shouldn't be in use for long anyway.
///////////////////////////////
//PV=nRT - related procedures//
@@ -364,7 +368,7 @@
//Inputs: Percentage to remove.
//Outputs: Removed air.
if(ratio <= 0)
if(ratio <= 0 || total_moles <= 0)
return null
ratio = min(ratio, 1)
@@ -399,8 +403,9 @@
//Removes a volume of gas from the mixture and returns a gas_mixture containing the removed air with the given volume.
/datum/gas_mixture/proc/remove_volume(removed_volume)
var/datum/gas_mixture/removed = remove_ratio(removed_volume/volume)
removed.volume = removed_volume
removed.update_values()
if(removed)
removed.volume = removed_volume
removed.update_values()
return removed

View File

@@ -217,7 +217,7 @@
if(target_temperature < T0C + MIN_TEMPERATURE)
target_temperature = T0C + MIN_TEMPERATURE
var/datum/gas_mixture/gas = location.remove_air(0.25 * environment.total_moles)
var/datum/gas_mixture/gas = environment.remove_volume(0.25 * CELL_VOLUME)
if(gas)
var/heat_capacity = gas.heat_capacity()
var/energy_used = min(abs(heat_capacity * (gas.temperature - target_temperature)), MAX_ENERGY_CHANGE)

View File

@@ -202,7 +202,7 @@
var/transfer_moles = 0
if((air_contents.temperature > 0) && (pressure_delta > 0))
transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * CELL_VOLUME / (air_contents.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)

View File

@@ -115,7 +115,7 @@
//pressure_delta = min(pressure_delta, (internal_pressure - environment_pressure))
if(pressure_delta > 0.1)
var/transfer_moles = pressure_delta*environment.volume/(pumping.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles = pressure_delta * CELL_VOLUME / (pumping.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = pumping.remove(transfer_moles)
@@ -128,35 +128,35 @@
AddAir()
var/datum/gas/sleeping_agent/trace_gas = new
air_contents.trace_gases += trace_gas
trace_gas.moles = internal_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
trace_gas.moles = internal_pressure * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
/obj/machinery/atmospherics/miner/nitrogen
name = "\improper N2 Gas Miner"
overlay_color = "#CCFFCC"
AddAir()
air_contents.nitrogen = internal_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.nitrogen = internal_pressure * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
/obj/machinery/atmospherics/miner/oxygen
name = "\improper O2 Gas Miner"
overlay_color = "#007FFF"
AddAir()
air_contents.oxygen = internal_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.oxygen = internal_pressure * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
/obj/machinery/atmospherics/miner/toxins
name = "\improper Plasma Gas Miner"
overlay_color = "#FF0000"
AddAir()
air_contents.toxins = internal_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.toxins = internal_pressure * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
/obj/machinery/atmospherics/miner/carbon_dioxide
name = "\improper CO2 Gas Miner"
overlay_color = "#CDCDCD"
AddAir()
air_contents.carbon_dioxide = internal_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.carbon_dioxide = internal_pressure * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
/obj/machinery/atmospherics/miner/air
@@ -167,5 +167,5 @@
on = 0
AddAir()
air_contents.oxygen = 0.2 * internal_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.nitrogen = 0.8 * internal_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
air_contents.oxygen = 0.2 * internal_pressure * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
air_contents.nitrogen = 0.8 * internal_pressure * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)

View File

@@ -61,7 +61,7 @@
var/transfer_moles = 0
if(air_contents.temperature > 0)
transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * CELL_VOLUME / (air_contents.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -76,7 +76,7 @@
var/transfer_moles = 0
if(environment.temperature > 0)
transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed

View File

@@ -116,7 +116,7 @@
if(on)
var/datum/gas_mixture/environment = get_environment()
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
var/transfer_moles = min(1, volume_rate / environment.volume) * environment.total_moles()
//Take a gas sample
var/datum/gas_mixture/removed = remove_sample(environment, transfer_moles)

View File

@@ -126,7 +126,7 @@
if(!colour2 && !T.density)
var/datum/gas_mixture/environment = T.return_air()
var/turf_total = environment.total_moles() / environment.volume * CELL_VOLUME
var/turf_total = environment.molar_density() * CELL_VOLUME
//var/turf_total = T.co2 + T.oxygen + T.poison + T.sl_gas + T.n2
@@ -214,7 +214,7 @@
if("/turf/simulated/floor", "/turf/simulated/floor/engine")
var/datum/gas_mixture/environment = T.return_air()
var/turf_total = environment.total_moles()
var/turf_total = environment.molar_density() * CELL_VOLUME
var/t1 = turf_total / MOLES_CELLSTANDARD * 175
if(t1<=100)

View File

@@ -2022,7 +2022,7 @@
var/transfer_moles = 0
if(pressure_delta > 0) //cabin pressure lower than release pressure
if(tank_air.return_temperature() > 0)
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * cabin_air.return_volume() / (cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = tank_air.remove(transfer_moles)
cabin_air.merge(removed)
else if(pressure_delta < 0) //cabin pressure higher than release pressure
@@ -2031,7 +2031,7 @@
if(t_air)
pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta)
if(pressure_delta > 0) //if location pressure is lower than cabin pressure
transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
transfer_moles = pressure_delta * cabin_air.return_volume() / (cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = cabin_air.remove(transfer_moles)
if(t_air)
t_air.merge(removed)

View File

@@ -748,8 +748,8 @@ steam.start() -- spawns the effect
var/datum/gas_mixture/old_air = T.return_air()
savedtemp = old_air.temperature
if(istype(T) && savedtemp > lowest_temperature)
var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() / T.air.volume * CELL_VOLUME )
lowertemp.temperature = max( min(lowertemp.temperature-500,lowertemp.temperature / 2) ,0)
var/datum/gas_mixture/lowertemp = old_air.remove_volume(CELL_VOLUME)
lowertemp.temperature = max(min(lowertemp.temperature - 500, lowertemp.temperature / 2), 0)
lowertemp.react()
T.assume_air(lowertemp)
spawn(3)
@@ -760,9 +760,9 @@ steam.start() -- spawns the effect
var/turf/simulated/T = get_turf(src)
var/datum/gas_mixture/local_air = T.return_air()
flick("[icon_state]-disolve", src)
if((local_air.temperature < lowest_temperature)&&(savedtemp > lowest_temperature)) //ie, we have over-chilled
if((local_air.temperature < lowest_temperature) && (savedtemp > lowest_temperature)) //ie, we have over-chilled
local_air.temperature = lowest_temperature
else if ((local_air.temperature < lowest_temperature)&&(savedtemp < lowest_temperature) && savedtemp) //ie it chilled when it shouldn't have
else if((local_air.temperature < lowest_temperature) && (savedtemp < lowest_temperature) && savedtemp) //ie it chilled when it shouldn't have
local_air.temperature = savedtemp
sleep(5)
qdel(src)

View File

@@ -41,7 +41,7 @@
wax--
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
if(env.oxygen / env.volume * CELL_VOLUME < 5)
if(env.molar_density("oxygen") < (5 / CELL_VOLUME))
src.lit = 0
set_light(0)
processing_objects.Remove(src)

View File

@@ -301,7 +301,7 @@ Subject's pulse: ??? BPM"})
var/datum/gas_mixture/environment = location.return_air()
to_chat(user, output_gas_scan(environment, location, 1))
to_chat(user, output_gas_scan(environment, location, 1, CELL_VOLUME))
src.add_fingerprint(user)
return
@@ -324,14 +324,20 @@ Subject's pulse: ??? BPM"})
return
var/turf/T = A
var/datum/gas_mixture/environment = T.return_air()
to_chat(user, output_gas_scan(environment, T, 1))
to_chat(user, output_gas_scan(environment, T, 1, CELL_VOLUME))
add_fingerprint(user)
//If human_standard is enabled, the message will be formatted to show which values are dangerous
/obj/item/device/analyzer/proc/output_gas_scan(var/datum/gas_mixture/scanned, var/atom/container, human_standard = 1)
//If unit_vol is specified, it will output the values for that volume of the scanned gas. Really for analyzing areas.
/obj/item/device/analyzer/proc/output_gas_scan(var/datum/gas_mixture/scanned, var/atom/container, human_standard = 1, unit_vol)
if(!scanned)
return "<span class='warning'>No gas mixture found.</span>"
scanned.update_values()
if(unit_vol)
var/datum/gas_mixture/unit = new() //Unless something goes horribly wrong, this will be cleaned up by the GC at the end of the proc.
unit.volume = unit_vol
unit.copy_from(scanned)
scanned = unit
var/pressure = scanned.return_pressure()
var/total_moles = scanned.total_moles()
var/message = ""
@@ -350,13 +356,13 @@ Subject's pulse: ??? BPM"})
var/unknown_concentration = 1 - (o2_concentration + n2_concentration + co2_concentration + plasma_concentration)
if(n2_concentration > 0.01)
message += "<br>[human_standard && abs(n2_concentration - N2STANDARD) > 20 ? "<span class='bad'>" : "<span class='notice'>"] Nitrogen: [round(scanned.nitrogen / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(n2_concentration*100)]%</span>"
message += "<br>[human_standard && abs(n2_concentration - N2STANDARD) > 20 ? "<span class='bad'>" : "<span class='notice'>"] Nitrogen: [round(scanned.nitrogen, 0.1)] mol, [round(n2_concentration*100)]%</span>"
if(o2_concentration > 0.01)
message += "<br>[human_standard && abs(o2_concentration - O2STANDARD) > 2 ? "<span class='bad'>" : "<span class='notice'>"] Oxygen: [round(scanned.oxygen / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(o2_concentration*100)]%</span>"
message += "<br>[human_standard && abs(o2_concentration - O2STANDARD) > 2 ? "<span class='bad'>" : "<span class='notice'>"] Oxygen: [round(scanned.oxygen, 0.1)] mol, [round(o2_concentration*100)]%</span>"
if(co2_concentration > 0.01)
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] CO2: [round(scanned.carbon_dioxide / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(co2_concentration*100)]%</span>"
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] CO2: [round(scanned.carbon_dioxide, 0.1)] mol, [round(co2_concentration*100)]%</span>"
if(plasma_concentration > 0.01)
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] Plasma: [round(scanned.toxins / scanned.volume * CELL_VOLUME, 0.1)] mol, [round(plasma_concentration*100)]%</span>"
message += "<br>[human_standard ? "<span class='bad'>" : "<span class='notice'>"] Plasma: [round(scanned.toxins, 0.1)] mol, [round(plasma_concentration*100)]%</span>"
if(unknown_concentration > 0.01)
message += "<br><span class='notice'>Unknown: [round(unknown_concentration*100)]%</span>"

View File

@@ -89,7 +89,7 @@ MATCHBOXES ARE ALSO IN FANCY.DM
lit = -1
update_brightness()
return
if(env.oxygen / env.volume * CELL_VOLUME < 5)
if(env.molar_density("oxygen") < (5 / CELL_VOLUME))
lit = -1
update_brightness()
if(M)
@@ -346,7 +346,7 @@ MATCHBOXES ARE ALSO IN FANCY.DM
M.IgniteMob()
smoketime--
var/datum/gas_mixture/env = location.return_air()
if(smoketime <= 0 | env.oxygen / env.volume * CELL_VOLUME < 5)
if(smoketime <= 0 | env.molar_density("oxygen") < (5 / CELL_VOLUME))
if(!inside_item)
var/atom/new_butt = new type_butt(location) //Spawn the cigarette butt
transfer_fingerprints_to(new_butt)
@@ -687,7 +687,7 @@ MATCHBOXES ARE ALSO IN FANCY.DM
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
user.delayNextAttack(5) //Hold on there cowboy
if(!fuel | env.oxygen / env.volume * CELL_VOLUME < 5)
if(!fuel | env.molar_density("oxygen") < (5 / CELL_VOLUME))
user.visible_message("<span class='rose'>[user] attempts to light \the [src] to no avail.</span>", \
"<span class='notice'>You try to light \the [src], but no flame appears.</span>")
return
@@ -744,7 +744,7 @@ MATCHBOXES ARE ALSO IN FANCY.DM
visible_message("<span class='warning'>Without warning, \the [src] suddenly shuts off.</span>")
fueltime = null
var/datum/gas_mixture/env = location.return_air()
if(env.oxygen / env.volume * CELL_VOLUME < 5)
if(env.molar_density("oxygen") < (5 / CELL_VOLUME))
lit = 0
update_brightness()
visible_message("<span class='warning'>Without warning, the flame on \the [src] suddenly goes out in a weak fashion.</span>")
@@ -767,7 +767,7 @@ MATCHBOXES ARE ALSO IN FANCY.DM
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
user.delayNextAttack(5) //Hold on there cowboy
if(!fuel | env.oxygen / env.volume * CELL_VOLUME < 5)
if(!fuel | env.molar_density("oxygen") < (5 / CELL_VOLUME))
user.visible_message("<span class='rose'>[user] attempts to light \the [src] to no avail.</span>", \
"<span class='notice'>You try to light \the [src], but no flame appears.</span>")
return

View File

@@ -122,12 +122,7 @@
if(!gas)
return null
var/datum/gas_mixture/newgas = new/datum/gas_mixture()
newgas.oxygen = gas.oxygen
newgas.carbon_dioxide = gas.carbon_dioxide
newgas.nitrogen = gas.nitrogen
newgas.toxins = gas.toxins
newgas.volume = gas.volume
newgas.temperature = gas.temperature
newgas.copy_from(gas)
if(newgas.temperature <= target_temp)
return
@@ -135,6 +130,7 @@
newgas.temperature -= cooling_power
else
newgas.temperature = target_temp
newgas.update_values()
return newgas
/obj/structure/closet/crate/freezer/surgery

View File

@@ -1,11 +1,11 @@
/datum/component/ai/atmos_checker
//Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
var/min_oxy = 5
var/min_oxy = 5 / CELL_VOLUME
var/max_oxy = 0 //Leaving something at 0 means it's off - has no maximum
var/min_tox = 0
var/max_tox = 1
var/max_tox = 1 / CELL_VOLUME
var/min_co2 = 0
var/max_co2 = 5
var/max_co2 = 5 / CELL_VOLUME
var/min_n2 = 0
var/max_n2 = 0
var/unsuitable_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
@@ -46,41 +46,41 @@
SendSignal(COMSIG_ADJUST_BODYTEMP, list("temp"=((Environment.temperature - controller.getBodyTemperature()) / 5)))
if(min_oxy)
if(Environment.oxygen < min_oxy)
if(Environment.molar_density("oxygen") < min_oxy)
atmos_suitable = 0
oxygen_alert = 1
else
oxygen_alert = 0
if(max_oxy)
if(Environment.oxygen > max_oxy)
if(Environment.molar_density("oxygen") > max_oxy)
atmos_suitable = 0
if(min_tox)
if(Environment.toxins < min_tox)
if(Environment.molar_density("toxins") < min_tox)
atmos_suitable = 0
if(max_tox)
if(Environment.toxins > max_tox)
if(Environment.molar_density("toxins") > max_tox)
atmos_suitable = 0
toxins_alert = 1
else
toxins_alert = 0
if(min_n2)
if(Environment.nitrogen < min_n2)
if(Environment.molar_density("nitrogen") < min_n2)
atmos_suitable = 0
if(max_n2)
if(Environment.nitrogen > max_n2)
if(Environment.molar_density("nitrogen") > max_n2)
atmos_suitable = 0
if(min_co2)
if(Environment.carbon_dioxide < min_co2)
if(Environment.molar_density("carbon_dioxide") < min_co2)
atmos_suitable = 0
if(max_co2)
if(Environment.carbon_dioxide > max_co2)
if(Environment.molar_density("carbon_dioxide") > max_co2)
atmos_suitable = 0
//Atmos effect

View File

@@ -229,28 +229,14 @@
if(istype(L) && heating_power)
var/datum/gas_mixture/env = L.return_air()
if(env.temperature != MAX_TEMP + T0C)
var/energy_to_add
var/transfer_moles = 0.25 * env.total_moles() / env.volume * CELL_VOLUME
if(env.temperature < MAX_TEMP + T0C)
energy_to_add = min(heating_power, env.get_thermal_energy_change(1000)) //Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE
else
energy_to_add = -heating_power //add_thermal_energy() automatically prevents the temperature from falling below TCMB, so a similar check here is unnecessary.
var/datum/gas_mixture/removed = env.remove(transfer_moles)
// to_chat(world, "got [transfer_moles] moles at [removed.temperature]")
if(removed)
var/heat_capacity = removed.heat_capacity()
// to_chat(world, "heating ([heat_capacity])")
if(heat_capacity) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE
if(removed.temperature < MAX_TEMP + T0C)
removed.temperature = min(removed.temperature + heating_power/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE
else
removed.temperature = max(removed.temperature - heating_power/heat_capacity, TCMB)
// to_chat(world, "now at [removed.temperature]")
env.merge(removed)
// to_chat(world, "turf now at [env.temperature]")
env.add_thermal_energy(energy_to_add)
// Checks heat from the environment and applies any integrity damage
var/datum/gas_mixture/environment = loc.return_air()

View File

@@ -683,7 +683,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='warning'>Unknown: [round(unknown_concentration * 100)]% ([round(unknown_concentration * total_moles / tiles, 0.01)] moles)</span>")
to_chat(src, "<span class='notice'>Temperature: [round(environment.temperature - T0C, 0.1)]&deg;C</span>")
to_chat(src, "<span class='notice'>Heat Capacity: [round(environment.heat_capacity(), 0.1)]</span>")
to_chat(src, "<span class='notice'>Heat Capacity: [round(environment.heat_capacity() / tiles, 0.1)]</span>")
/mob/dead/observer/verb/toggle_darkness()

View File

@@ -121,16 +121,13 @@
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = 0
/*if(environment.return_pressure() > ONE_ATMOSPHERE)
// Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
else
*/
// Not enough air around, take a percentage of what's there to model this properly
breath_moles = environment.total_moles()/environment.volume*CELL_VOLUME*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
breath = environment.remove_volume(CELL_VOLUME * BREATH_PERCENTAGE)
// Handle chem smoke effect -- Doohl
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
@@ -178,14 +175,15 @@
return 0
var/toxins_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
breath.volume = BREATH_VOLUME
breath.update_values()
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
var/Toxins_pp = (breath.toxins / breath.total_moles()) * breath.pressure
if(Toxins_pp) // Detect toxins in air
AdjustPlasma(breath.toxins*250)
AdjustPlasma(breath.toxins * 250)
toxins_alert = max(toxins_alert, 1)
toxins_used = breath.toxins
@@ -199,7 +197,7 @@
if(breath.temperature > (T0C+66) && !(M_RESIST_HEAT in mutations)) // Hot air hurts :(
if(prob(20))
to_chat(src, "<span class='warning'>You feel a searing heat in your lungs !</span>")
to_chat(src, "<span class='warning'>You feel a searing heat in your lungs!</span>")
fire_alert = max(fire_alert, 1)
else
fire_alert = 0

View File

@@ -101,16 +101,13 @@
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = 0
/*if(environment.return_pressure() > ONE_ATMOSPHERE)
// Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
else
*/
// Not enough air around, take a percentage of what's there to model this properly
breath_moles = environment.total_moles()/environment.volume*CELL_VOLUME*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
breath = environment.remove_volume(CELL_VOLUME * BREATH_PERCENTAGE)
// Handle chem smoke effect -- Doohl
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
@@ -159,14 +156,15 @@
return 0
var/toxins_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
breath.volume = BREATH_VOLUME
breath.update_values()
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
var/Toxins_pp = (breath.toxins / breath.total_moles()) * breath.pressure
if(Toxins_pp) // Detect toxins in air
AdjustPlasma(breath.toxins*250)
AdjustPlasma(breath.toxins * 250)
toxins_alert = max(toxins_alert, 1)
toxins_used = breath.toxins

View File

@@ -74,7 +74,7 @@
/mob/living/carbon/brain/proc/handle_environment(datum/gas_mixture/environment)
if(!environment || (flags & INVULNERABLE))
return
var/environment_heat_capacity = environment.heat_capacity()
var/environment_heat_capacity = environment.heat_capacity() / environment.volume * CELL_VOLUME
if(istype(get_turf(src), /turf/space))
var/turf/heat_turf = get_turf(src)
environment_heat_capacity = heat_turf.heat_capacity

View File

@@ -81,8 +81,7 @@
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = environment.total_moles()/environment.volume*CELL_VOLUME*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
breath = environment.remove_volume(CELL_VOLUME * BREATH_PERCENTAGE)
else //Still give containing object the chance to interact
if(istype(loc, /obj/))
@@ -115,14 +114,16 @@
var/SA_para_min = 0.5
var/SA_sleep_min = 5
var/oxygen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
breath.volume = BREATH_VOLUME
breath.update_values()
//Partial pressure of the O2 in our breath
var/O2_pp = (breath.oxygen/breath.total_moles())*breath_pressure
var/O2_pp = (breath.oxygen / breath.total_moles()) * breath.pressure
// Same, but for the toxins
var/Toxins_pp = (breath.toxins/breath.total_moles())*breath_pressure
var/Toxins_pp = (breath.toxins / breath.total_moles()) * breath.pressure
// And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun)
var/CO2_pp = (breath.carbon_dioxide/breath.total_moles())*breath_pressure
var/CO2_pp = (breath.carbon_dioxide / breath.total_moles()) * breath.pressure
if(O2_pp < safe_oxygen_min) // Too little oxygen
if(prob(20))
@@ -173,7 +174,7 @@
if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here.
for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
var/SA_pp = (SA.moles/breath.total_moles())*breath_pressure
var/SA_pp = (SA.moles / breath.total_moles()) * breath.pressure
if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit
Paralyse(3) // 3 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
@@ -200,7 +201,7 @@
return
var/loc_temp = get_loc_temp(environment)
var/spaceproof = is_spaceproof()
var/environment_heat_capacity = environment.heat_capacity()
var/environment_heat_capacity = environment.heat_capacity() / environment.volume * CELL_VOLUME
if(istype(get_turf(src), /turf/space))
var/turf/heat_turf = get_turf(src)
environment_heat_capacity = heat_turf.heat_capacity

View File

@@ -49,16 +49,13 @@
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_MOLES)
else if(isturf(loc))
var/breath_moles = 0
/*if(environment.return_pressure() > ONE_ATMOSPHERE)
//Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT)
breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature)
else
*/
//Not enough air around, take a percentage of what's there to model this properly
breath_moles = (environment.total_moles() / environment.volume * CELL_VOLUME) * BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
breath = environment.remove_volume(CELL_VOLUME * BREATH_PERCENTAGE)
if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5)
if(prob(15)) // 15% chance for lung damage if air intake is less of a fifth, or more than five times the threshold

View File

@@ -267,8 +267,7 @@
var/obj/location_as_object = loc
breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME)
else if(istype(loc, /turf/))
var/breath_moles = environment.total_moles()/environment.volume*CELL_VOLUME*BREATH_PERCENTAGE
breath = loc.remove_air(breath_moles)
breath = environment.remove_volume(CELL_VOLUME * BREATH_PERCENTAGE)
// Handle chem smoke effect -- Doohl
var/block = 0
@@ -458,7 +457,7 @@
if(hat && istype(hat, /obj/item/clothing/head/helmet/space) && uniform && istype(uniform, /obj/item/clothing/monkeyclothes/space))
spaceproof = 1 //quick and dirt cheap. no need for the Life() of monkeys to become as complicated as the Life() of humans. man that's deep.
var/loc_temp = get_loc_temp(environment)
var/environment_heat_capacity = environment.heat_capacity()
var/environment_heat_capacity = environment.heat_capacity() / environment.volume * CELL_VOLUME
if(istype(get_turf(src), /turf/space))
var/turf/heat_turf = get_turf(src)
environment_heat_capacity = heat_turf.heat_capacity

View File

@@ -1161,7 +1161,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/process()
var/turf/location = get_turf(src)
var/datum/gas_mixture/environment = location.return_air()
if ((environment.toxins / environment.volume * CELL_VOLUME) > MOLES_PLASMA_VISIBLE)//plasma exposure causes the egg to hatch
if (environment.molar_density("toxins") > MOLES_PLASMA_VISIBLE / CELL_VOLUME)//plasma exposure causes the egg to hatch
src.Hatch()
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob)

View File

@@ -301,8 +301,8 @@
if(istype(T))
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G)
oxy=G.oxygen/G.volume*CELL_VOLUME
if(oxy < 1 || fire_stacks <= 0)
oxy = G.molar_density("oxygen")
if(oxy < (1 / CELL_VOLUME) || fire_stacks <= 0)
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return 1
var/turf/location = get_turf(src)

View File

@@ -17,8 +17,8 @@
var/ping_cooldown = 50
var/list/required_mols=list(
"toxins"=MOLES_PLASMA_VISIBLE,
"oxygen"=5
"toxins" = MOLES_PLASMA_VISIBLE / CELL_VOLUME,
"oxygen" = 5 / CELL_VOLUME
)
/obj/item/weapon/reagent_containers/food/snacks/borer_egg/New()
@@ -93,7 +93,7 @@
//testing("[type]/PROCESS() - plasma: [environment.toxins]")
var/meets_conditions=1
for(var/gas_id in required_mols)
if((environment.vars[gas_id] / environment.volume * CELL_VOLUME) <= required_mols[gas_id])
if(environment.molar_density(gas_id) < required_mols[gas_id])
meets_conditions=0
if(meets_conditions)
src.Hatch()

View File

@@ -81,7 +81,7 @@
var/pressure=myenv.return_pressure()
for(var/dir in cardinal)
var/turf/simulated/T=get_turf(get_step(loc,dir))
var/turf/simulated/T = get_step(loc, dir)
if(T && istype(T) && T.zone)
var/datum/gas_mixture/environment = T.return_air()
var/pdiff = abs(pressure - environment.return_pressure())

View File

@@ -227,41 +227,41 @@ var/global/list/animal_count = list() //Stores types, and amount of animals of t
bodytemperature += ((Environment.temperature - bodytemperature) / 5)
if(min_oxy)
if(Environment.oxygen / Environment.volume * CELL_VOLUME < min_oxy)
if(Environment.molar_density("oxygen") < min_oxy / CELL_VOLUME)
atmos_suitable = 0
oxygen_alert = 1
else
oxygen_alert = 0
if(max_oxy)
if(Environment.oxygen / Environment.volume * CELL_VOLUME > max_oxy)
if(Environment.molar_density("oxygen") > max_oxy / CELL_VOLUME)
atmos_suitable = 0
if(min_tox)
if(Environment.toxins / Environment.volume * CELL_VOLUME < min_tox)
if(Environment.molar_density("toxins") < min_tox / CELL_VOLUME)
atmos_suitable = 0
if(max_tox)
if(Environment.toxins / Environment.volume * CELL_VOLUME > max_tox)
if(Environment.molar_density("toxins") > max_tox / CELL_VOLUME)
atmos_suitable = 0
toxins_alert = 1
else
toxins_alert = 0
if(min_n2)
if(Environment.nitrogen / Environment.volume * CELL_VOLUME < min_n2)
if(Environment.molar_density("nitrogen") < min_n2 / CELL_VOLUME)
atmos_suitable = 0
if(max_n2)
if(Environment.nitrogen / Environment.volume * CELL_VOLUME > max_n2)
if(Environment.molar_density("nitrogen") > max_n2 / CELL_VOLUME)
atmos_suitable = 0
if(min_co2)
if(Environment.carbon_dioxide / Environment.volume * CELL_VOLUME < min_co2)
if(Environment.molar_density("carbon_dioxide") < min_co2 / CELL_VOLUME)
atmos_suitable = 0
if(max_co2)
if(Environment.carbon_dioxide / Environment.volume * CELL_VOLUME > max_co2)
if(Environment.molar_density("carbon_dioxide") > max_co2 / CELL_VOLUME)
atmos_suitable = 0
//Atmos effect

View File

@@ -68,8 +68,8 @@
if(loc_temp < bodytemperature)
// We're going to try and just use exposed area(temperature difference)/cold divisor, and assume we're only conducting.
var/thermal_loss = (1-get_cold_protection()) // How much of your skin is exposed.
if(!isVentCrawling() && ((environment.total_moles / environment.volume * CELL_VOLUME) > MOLES_CELLSTANDARD || !IS_SPACE_COLD))
var/pressure_diff = (environment.total_moles / environment.volume * CELL_VOLUME) / MOLES_CELLSTANDARD // How many moles are in the environment over 103.934, the normal value of a station.
if(!isVentCrawling() && (environment.molar_density() > (MOLES_CELLSTANDARD / CELL_VOLUME) || !IS_SPACE_COLD))
var/pressure_diff = environment.molar_density() / (MOLES_CELLSTANDARD / CELL_VOLUME) // How many moles are in the environment over 103.934, the normal value of a station.
var/pressure_factor = (-COLD_PRESSUREFACTOR_MAX)/(pressure_diff) + COLD_PRESSUREFACTOR_MAX // non linear.
if(pressure_diff < PRESSUREFACTOR_NO_LINEAR)
pressure_factor = pressure_diff

View File

@@ -67,9 +67,7 @@
return
rpm = 0.9* rpm + 0.1 * rpmtarget
var/datum/gas_mixture/environment = inturf.return_air()
var/transfer_moles = environment.total_moles()/10
//var/transfer_moles = rpm/10000*capacity
var/datum/gas_mixture/removed = inturf.remove_air(transfer_moles)
var/datum/gas_mixture/removed = environment.remove_volume(CELL_VOLUME / 10)
gas_contained.merge(removed)
rpm = max(0, rpm - (rpm*rpm)/COMPFRICTION)

View File

@@ -146,9 +146,9 @@
range = min(range, MAX_EXPLOSION_RANGE)
var/turf/epicenter = get_turf(loc)
var/transfer_moles1 = (bomb.tank_one.air_contents.return_pressure() * bomb.tank_one.air_contents.volume)/(bomb.tank_one.air_contents.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles1 = (bomb.tank_one.air_contents.return_pressure() * bomb.tank_one.air_contents.volume) / (bomb.tank_one.air_contents.temperature * R_IDEAL_GAS_EQUATION)
bomb.tank_one.air_contents.remove(transfer_moles1)
var/transfer_moles2 = (bomb.tank_two.air_contents.return_pressure() * bomb.tank_two.air_contents.volume)/(bomb.tank_two.air_contents.temperature * R_IDEAL_GAS_EQUATION)
var/transfer_moles2 = (bomb.tank_two.air_contents.return_pressure() * bomb.tank_two.air_contents.volume) / (bomb.tank_two.air_contents.temperature * R_IDEAL_GAS_EQUATION)
bomb.tank_two.air_contents.remove(transfer_moles2)
bomb_air_contents_1 = null

View File

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

View File

@@ -112,20 +112,8 @@
var/turf/simulated/L = loc
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
if(env.temperature < (heat_amt+T0C))
var/transfer_moles = 0.25 * env.total_moles()
var/datum/gas_mixture/removed = env.remove(transfer_moles)
if(removed)
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.temperature = min((removed.temperature*heat_capacity + heating_power)/heat_capacity, 1000)
env.merge(removed)
if(env.temperature < (heat_amt + T0C))
env.add_thermal_energy(min(heating_power, env.get_thermal_energy_change(1000)))
/obj/machinery/r_n_d/server/attack_hand(mob/user as mob)
if (disabled)

View File

@@ -16,9 +16,11 @@
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.temperature = max(env.temperature - rand(5,50), 0)
env.update_values()
/datum/artifact_effect/cold/DoEffectAura()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.temperature > target_temp)
env.temperature -= pick(0, 0, 1)
env.update_values()

View File

@@ -14,10 +14,10 @@
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.carbon_dioxide += rand(2,15)
env.adjust_gas("carbon_dioxide", rand(2,15))
/datum/artifact_effect/gasco2/DoEffectAura()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.total_moles < max_pressure)
env.carbon_dioxide += pick(0, 0, 0.1, rand())
if(env && env.pressure < max_pressure)
env.adjust_gas("carbon_dioxide", pick(0, 0, 0.1, rand()))

View File

@@ -15,10 +15,10 @@
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.nitrogen += rand(2,15)
env.adjust_gas("nitrogen", rand(2,15))
/datum/artifact_effect/gasnitro/DoEffectAura()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.total_moles < max_pressure)
env.nitrogen += pick(0, 0, 0.1, rand())
if(env && env.pressure < max_pressure)
env.adjust_gas("nitrogen", pick(0, 0, 0.1, rand()))

View File

@@ -15,10 +15,10 @@
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.oxygen += rand(2,15)
env.adjust_gas("oxygen", rand(2,15))
/datum/artifact_effect/gasoxy/DoEffectAura()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.total_moles < max_pressure)
env.oxygen += pick(0, 0, 0.1, rand())
if(env && env.pressure < max_pressure)
env.adjust_gas("oxygen", pick(0, 0, 0.1, rand()))

View File

@@ -15,10 +15,10 @@
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.toxins += rand(2,15)
env.adjust_gas("plasma", rand(2,15))
/datum/artifact_effect/gasplasma/DoEffectAura()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.total_moles < max_pressure)
env.toxins += pick(0, 0, 0.1, rand())
if(env && env.pressure < max_pressure)
env.adjust_gas("plasma", pick(0, 0, 0.1, rand()))

View File

@@ -16,17 +16,15 @@
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
var/datum/gas/sleeping_agent/trace_gas = new
env.trace_gases += trace_gas
trace_gas.moles = rand(2,15)
env.update_values()
env.adjust(traces = list(trace_gas))
/datum/artifact_effect/gassleeping/DoEffectAura()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.total_moles < max_pressure)
if(env && env.pressure < max_pressure)
var/datum/gas/sleeping_agent/trace_gas = new
env.trace_gases += trace_gas
trace_gas.moles = pick(0, 0, 0.1, rand())
env.update_values()
env.adjust(traces = list(trace_gas))

View File

@@ -16,9 +16,11 @@
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.temperature += rand(5,50)
env.update_values()
/datum/artifact_effect/heat/DoEffectAura()
if(holder)
var/datum/gas_mixture/env = holder.loc.return_air()
if(env && env.temperature < target_temp)
env.temperature += pick(0, 0, 1)
env.update_values()

View File

@@ -1,4 +1,4 @@
#define MOLE_TRIGGER 10
#define MOLE_TRIGGER (10 / CELL_VOLUME)
/datum/artifact_trigger/gas
triggertype = TRIGGER_GAS
@@ -7,7 +7,7 @@
/datum/artifact_trigger/gas/New()
..()
trigger_gas = pick("TOXINS","CARBON_DIOXIDE","NITROGEN","OXYGEN")
trigger_gas = pick("TOXINS", "CARBON_DIOXIDE", "NITROGEN", "OXYGEN")
/datum/artifact_trigger/gas/CheckTrigger()
@@ -15,24 +15,9 @@
var/datum/gas_mixture/env = T.return_air()
if(env)
if(!my_effect.activated)
if(trigger_gas == "TOXINS" && env.toxins >= MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
if(trigger_gas == "CARBON_DIOXIDE" && env.carbon_dioxide >= MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
if(trigger_gas == "NITROGEN" && env.nitrogen >= MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
if(trigger_gas == "OXYGEN" && env.oxygen >= MOLE_TRIGGER)
if(env.molar_density(lowertext(trigger_gas)) >= MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
else
if(trigger_gas == "TOXINS" && env.toxins < MOLE_TRIGGER)
if(env.molar_density(lowertext(trigger_gas)) < MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
if(trigger_gas == "CARBON_DIOXIDE" && env.carbon_dioxide < MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
if(trigger_gas == "NITROGEN" && env.nitrogen < MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
if(trigger_gas == "OXYGEN" && env.oxygen < MOLE_TRIGGER)
Triggered(0, trigger_gas, 0)
/datum/artifact_trigger/gas/Destroy()
..()

View File

@@ -84,32 +84,32 @@
//Add 3000 joules when active. This is about 0.6 degrees per tick.
//May need adjustment
if(use_power == 1)
var/heat_added = active_power_usage *XENOARCH_HEAT_COEFFICIENT
var/heat_added = active_power_usage * XENOARCH_HEAT_COEFFICIENT
if(temperature < XENOARCH_MAX_HEAT_INCREASE_TEMP)
temperature += heat_added/XENOARCH_HEAT_CAPACITY
temperature += heat_added / XENOARCH_HEAT_CAPACITY
var/temperature_difference = abs(environmental_temp-temperature)
var/datum/gas_mixture/removed = loc.remove_air(env.total_moles / env.volume * CELL_VOLUME * 0.25)
var/temperature_difference = abs(environmental_temp - temperature)
var/datum/gas_mixture/removed = env.remove_volume(0.25 * CELL_VOLUME)
var/heat_capacity = removed.heat_capacity()
heat_added = min(temperature_difference*heat_capacity, XENOARCH_MAX_ENERGY_TRANSFER)
heat_added = min(temperature_difference * heat_capacity, XENOARCH_MAX_ENERGY_TRANSFER)
if(temperature > environmental_temp)
//cool down to match the air
temperature = max(TCMB, temperature - heat_added/XENOARCH_HEAT_CAPACITY)
removed.temperature = max(TCMB, removed.temperature + heat_added/heat_capacity)
temperature = max(TCMB, temperature - heat_added / XENOARCH_HEAT_CAPACITY)
removed.temperature = max(TCMB, removed.temperature + heat_added / heat_capacity)
if(temperature_difference > 10 && prob(5))
visible_message("<span class='notice'>[bicon(src)] hisses softly.</span>", "You hear a soft hiss.")
else
//heat up to match the air
temperature = max(TCMB, temperature + heat_added/XENOARCH_HEAT_CAPACITY)
removed.temperature = max(TCMB, removed.temperature - heat_added/heat_capacity)
temperature = max(TCMB, temperature + heat_added / XENOARCH_HEAT_CAPACITY)
removed.temperature = max(TCMB, removed.temperature - heat_added / heat_capacity)
if(temperature_difference > 10 && prob(5))
visible_message("<span class='notice'>[bicon(src)] plinks quietly.</span>", "You hear a soft hiss.")
visible_message("<span class='notice'>[bicon(src)] plinks quietly.</span>", "You hear a quiet plink.")
env.merge(removed)

View File

@@ -100,7 +100,7 @@
if(held_container && heating == BUNSEN_ON)
var/turf/T = get_turf(src)
var/datum/gas_mixture/G = T.return_air()
if(!G || G.oxygen / G.volume * CELL_VOLUME < 0.1)
if(!G || G.molar_density("oxygen") < 0.1 / CELL_VOLUME)
visible_message("<span class = 'warning'>\The [src] splutters out from lack of oxygen.</span>","<span class = 'warning'>You hear something cough.</span>")
toggle()
return