April sync (#360)

* Maps and things no code/icons

* helpers defines globalvars

* Onclick world.dm orphaned_procs

* subsystems

Round vote and shuttle autocall done here too

* datums

* Game folder

* Admin - chatter modules

* clothing - mining

* modular computers - zambies

* client

* mob level 1

* mob stage 2 + simple_animal

* silicons n brains

* mob stage 3 + Alien/Monkey

* human mobs

* icons updated

* some sounds

* emitter y u no commit

* update tgstation.dme

* compile fixes

* travis fixes

Also removes Fast digest mode, because reasons.

* tweaks for travis Mentors are broke again

Also fixes Sizeray guns

* oxygen loss fix for vore code.

* removes unused code

* some code updates

* bulk fixes

* further fixes

* outside things

* whoops.

* Maint bar ported

* GLOBs.
This commit is contained in:
Poojawa
2017-04-13 23:37:00 -05:00
committed by GitHub
parent cdc32c98fa
commit 7e9b96a00f
1322 changed files with 174827 additions and 23888 deletions
@@ -6,30 +6,24 @@ What are the archived variables for?
#define MINIMUM_HEAT_CAPACITY 0.0003
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
var/list/meta_gas_info = meta_gas_list() //see ATMOSPHERICS/gas_types.dm
var/list/gaslist_cache = null
/proc/gaslist(id)
var/list/cached_gas
GLOBAL_LIST_INIT(meta_gas_info, meta_gas_list()) //see ATMOSPHERICS/gas_types.dm
GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache())
//only instantiate the first time it's needed
if(!gaslist_cache)
gaslist_cache = new(meta_gas_info.len)
/proc/init_gaslist_cache()
. = list()
for(var/id in GLOB.meta_gas_info)
var/list/cached_gas = new(3)
//only setup the individual lists the first time they're needed
if(!gaslist_cache[id])
if(!meta_gas_info[id])
CRASH("Gas [id] does not exist!")
cached_gas = new(3)
gaslist_cache[id] = cached_gas
.[id] = cached_gas
cached_gas[MOLES] = 0
cached_gas[ARCHIVE] = 0
cached_gas[GAS_META] = meta_gas_info[id]
else
cached_gas = gaslist_cache[id]
//Copy() it because only GAS_META is static
return cached_gas.Copy()
cached_gas[GAS_META] = GLOB.meta_gas_info[id]
#define GASLIST(id, out_list)\
var/list/tmp_gaslist = GLOB.gaslist_cache[id];\
out_list = tmp_gaslist.Copy();
/datum/gas_mixture
var/list/gases
@@ -37,17 +31,15 @@ var/list/gaslist_cache = null
var/tmp/temperature_archived
var/volume //liters
var/last_share
var/tmp/fuel_burnt
var/datum/holder
var/list/reaction_results
/datum/gas_mixture/New(volume = CELL_VOLUME)
..()
gases = new
temperature = 0
temperature_archived = 0
src.volume = volume
last_share = 0
fuel_burnt = 0
reaction_results = new
//listmos procs
@@ -57,7 +49,7 @@ var/list/gaslist_cache = null
var/cached_gases = gases
if(cached_gases[gas_id])
return
cached_gases[gas_id] = gaslist(gas_id)
GASLIST(gas_id, cached_gases[gas_id])
//assert_gases(args) - shorthand for calling assert_gas() once for each gas type.
/datum/gas_mixture/proc/assert_gases()
@@ -68,12 +60,13 @@ var/list/gaslist_cache = null
//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)
gases[gas_id] = gaslist(gas_id)
GASLIST(gas_id, gases[gas_id])
//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)
GASLIST(id, cached_gases[id])
//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.
@@ -91,23 +84,33 @@ var/list/gaslist_cache = null
var/list/cached_gases = gases
. = 0
for(var/id in cached_gases)
. += cached_gases[id][MOLES] * cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT]
var/gas_data = cached_gases[id]
. += gas_data[MOLES] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
/datum/gas_mixture/proc/heat_capacity_archived() //joules per kelvin
var/list/cached_gases = gases
. = 0
for(var/id in cached_gases)
. += cached_gases[id][ARCHIVE] * cached_gases[id][GAS_META][META_GAS_SPECIFIC_HEAT]
var/gas_data = cached_gases[id]
. += gas_data[ARCHIVE] * gas_data[GAS_META][META_GAS_SPECIFIC_HEAT]
/datum/gas_mixture/proc/total_moles() //moles
var/list/cached_gases = gases
. = 0
for(var/id in cached_gases)
. += cached_gases[id][MOLES]
//prefer this 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];\
}
/datum/gas_mixture/proc/total_moles()
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
/datum/gas_mixture/proc/return_pressure() //kilopascals
if(volume > 0) // to prevent division by zero
return total_moles() * R_IDEAL_GAS_EQUATION * temperature / volume
var/cached_gases = gases
TOTAL_MOLES(cached_gases, .)
. *= R_IDEAL_GAS_EQUATION * temperature / volume
return
return 0
/datum/gas_mixture/proc/return_temperature() //kelvins
@@ -119,149 +122,6 @@ var/list/gaslist_cache = null
/datum/gas_mixture/proc/thermal_energy() //joules
return temperature * heat_capacity()
//Procedures used for very specific events
/datum/gas_mixture/proc/react(atom/dump_location)
var/list/cached_gases = gases //this speeds things up because >byond
var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network)
if(temperature < TCMB)
temperature = TCMB
if(cached_gases["agent_b"] && temperature > 900 && cached_gases["plasma"] && cached_gases["co2"])
//agent b converts hot co2 to o2 (endothermic)
if(cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && cached_gases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY)
var/reaction_rate = min(cached_gases["co2"][MOLES]*0.75, cached_gases["plasma"][MOLES]*0.25, cached_gases["agent_b"][MOLES]*0.05)
cached_gases["co2"][MOLES] -= reaction_rate
assert_gas("o2") //only need to assert oxygen, as this reaction doesn't occur without the other gases existing
cached_gases["o2"][MOLES] += reaction_rate
cached_gases["agent_b"][MOLES] -= reaction_rate*0.05
temperature -= (reaction_rate*20000)/heat_capacity()
garbage_collect()
reacting = 1
/*
if(thermal_energy() > (PLASMA_BINDING_ENERGY*10))
if(cached_gases["plasma"] && cached_gases["co2"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY && cached_gases["co2"][MOLES] > MINIMUM_HEAT_CAPACITY && (cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])/total_moles() >= FUSION_PURITY_THRESHOLD)//Fusion wont occur if the level of impurities is too high.
//fusion converts plasma and co2 to o2 and n2 (exothermic)
//to_chat(world, "pre [temperature, [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]])
var/old_heat_capacity = heat_capacity()
var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY)
var/reaction_energy = thermal_energy()
var/moles_impurities = total_moles()-(cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])
var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
var/oxygen_added = carbon_catalyzed
var/nitrogen_added = (plasma_fused-oxygen_added)-(thermal_energy()/PLASMA_BINDING_ENERGY)
reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0)
assert_gases("o2", "n2")
cached_gases["plasma"][MOLES] -= plasma_fused
cached_gases["co2"][MOLES] -= carbon_catalyzed
cached_gases["o2"][MOLES] += oxygen_added
cached_gases["n2"][MOLES] += nitrogen_added
garbage_collect()
if(reaction_energy > 0)
reacting = 1
var/new_heat_capacity = heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB)
//Prevents whatever mechanism is causing it to hit negative temperatures.
//to_chat(world, "post [temperature], [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]])
*/
if(holder)
if(cached_gases["freon"])
if(cached_gases["freon"][MOLES] >= MOLES_PLASMA_VISIBLE)
if(holder.freon_gas_act())
cached_gases["freon"][MOLES] -= MOLES_PLASMA_VISIBLE
if(cached_gases["water_vapor"])
if(cached_gases["water_vapor"][MOLES] >= MOLES_PLASMA_VISIBLE)
if(holder.water_vapor_gas_act())
cached_gases["water_vapor"][MOLES] -= MOLES_PLASMA_VISIBLE
fuel_burnt = 0
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
//to_chat(world, "pre [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]")
if(fire())
reacting = 1
//to_chat(world, "post [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]")
return reacting
/datum/gas_mixture/proc/fire()
//combustion of plasma and volatile fuel, which both act as hydrocarbons (exothermic)
var/energy_released = 0
var/old_heat_capacity = heat_capacity()
var/list/cached_gases = gases //this speeds things up because accessing datum vars is slow
//General volatile gas burn
if(cached_gases["v_fuel"] && cached_gases["v_fuel"][MOLES])
var/burned_fuel
if(!cached_gases["o2"])
burned_fuel = 0
else if(cached_gases["o2"][MOLES] < cached_gases["v_fuel"][MOLES])
burned_fuel = cached_gases["o2"][MOLES]
cached_gases["v_fuel"][MOLES] -= burned_fuel
cached_gases["o2"][MOLES] = 0
else
burned_fuel = cached_gases["v_fuel"][MOLES]
cached_gases["o2"][MOLES] -= cached_gases["v_fuel"][MOLES]
if(burned_fuel)
energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
assert_gas("co2")
cached_gases["co2"][MOLES] += burned_fuel
fuel_burnt += burned_fuel
//Handle plasma burning
if(cached_gases["plasma"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY)
var/plasma_burn_rate = 0
var/oxygen_burn_rate = 0
//more plasma released at higher temperatures
var/temperature_scale
if(temperature > PLASMA_UPPER_TEMPERATURE)
temperature_scale = 1
else
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
assert_gas("o2")
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(cached_gases["o2"][MOLES] > cached_gases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
plasma_burn_rate = (temperature_scale*(cached_gases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
assert_gas("co2")
cached_gases["plasma"][MOLES] = QUANTIZE(cached_gases["plasma"][MOLES] - plasma_burn_rate)
cached_gases["o2"][MOLES] = QUANTIZE(cached_gases["o2"][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
cached_gases["co2"][MOLES] += plasma_burn_rate
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate)
garbage_collect()
if(energy_released > 0)
var/new_heat_capacity = heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
return fuel_burnt
/datum/gas_mixture/proc/archive()
//Update archived versions of variables
//Returns: 1 in all cases
@@ -309,6 +169,10 @@ var/list/gaslist_cache = null
//Compares sample to self to see if within acceptable ranges that group processing may be enabled
//Returns: a string indicating what check failed, or "" if check passes
/datum/gas_mixture/proc/react(turf/open/dump_location)
//Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise
/datum/gas_mixture/archive()
var/list/cached_gases = gases
@@ -340,11 +204,12 @@ var/list/gaslist_cache = null
return 1
/datum/gas_mixture/remove(amount)
var/sum = total_moles()
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/list/cached_gases = gases
var/datum/gas_mixture/removed = new
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
@@ -495,7 +360,11 @@ var/list/gaslist_cache = null
sharer.garbage_collect(sharer_gases - cached_gases) //the reverse is equally true
sharer.after_share(src, atmos_adjacent_turfs)
if(temperature_delta > MINIMUM_TEMPERATURE_TO_MOVE || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles)
var/our_moles
TOTAL_MOLES(cached_gases,our_moles)
var/their_moles
TOTAL_MOLES(sharer_gases,their_moles)
var/delta_pressure = temperature_archived*(our_moles + moved_moles) - sharer.temperature_archived*(their_moles - moved_moles)
return delta_pressure * R_IDEAL_GAS_EQUATION / volume
/datum/gas_mixture/after_share(datum/gas_mixture/sharer, atmos_adjacent_turfs = 4)
@@ -521,43 +390,82 @@ var/list/gaslist_cache = null
return sharer_temperature
//thermal energy of the system (self and sharer) is unchanged
/datum/gas_mixture/compare(datum/gas_mixture/sample, datatype = MOLES, adjacents = 0)
/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] ? cached_gases[id][datatype] : 0
var/sample_moles = sample_gases[id] ? sample_gases[id][datatype] : 0
var/delta = abs(gas_moles - sample_moles)/(adjacents+1)
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
if(total_moles() > MINIMUM_MOLES_DELTA_TO_MOVE)
var/temp
var/sample_temp
switch(datatype)
if(MOLES)
temp = temperature
sample_temp = sample.temperature
if(ARCHIVE)
temp = temperature_archived
sample_temp = sample.temperature_archived
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) && \
temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND * temp)
if(temperature_delta > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return "temp"
return ""
/datum/gas_mixture/react(turf/open/dump_location)
. = 0
if(temperature < TCMB) //just for safety
temperature = TCMB
reaction_results = new
var/list/cached_gases = gases
var/temp = temperature
var/ener = thermal_energy()
reaction_loop:
for(var/r in SSair.gas_reactions)
var/datum/gas_reaction/reaction = r
var/list/min_reqs = reaction.min_requirements.Copy()
if((min_reqs["TEMP"] && temp < min_reqs["TEMP"]) \
|| (min_reqs["ENER"] && ener < min_reqs["ENER"]))
continue
min_reqs -= "TEMP"
min_reqs -= "ENER"
for(var/id in min_reqs)
if(!cached_gases[id] || cached_gases[id][MOLES] < min_reqs[id])
continue reaction_loop
//at this point, all minimum requirements for the reaction are satisfied.
/* currently no reactions have maximum requirements, so we can leave the checks commented out for a slight performance boost
var/list/max_reqs = reaction.max_requirements.Copy()
if((max_reqs["TEMP"] && temp > max_reqs["TEMP"]) \
|| (max_reqs["ENER"] && ener > max_reqs["ENER"]))
continue
max_reqs -= "TEMP"
max_reqs -= "ENER"
for(var/id in max_reqs)
if(cached_gases[id] && cached_gases[id][MOLES] > max_reqs[id])
continue reaction_loop
//at this point, all requirements for the reaction are satisfied. we can now react()
*/
. |= reaction.react(src, dump_location)
if(.)
garbage_collect()
//Takes the amount of the gas you want to PP as an argument
//So I don't have to do some hacky switches/defines/magic strings
//eg:
//Tox_PP = get_partial_pressure(gas_mixture.toxins)
//O2_PP = get_partial_pressure(gas_mixture.oxygen)
//Does handle trace gases!
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
return (gas_pressure * R_IDEAL_GAS_EQUATION * temperature) / BREATH_VOLUME
//inverse
@@ -1,4 +1,4 @@
var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases, which were at one time hardcoded
GLOBAL_LIST_INIT(hardcoded_gases, list("o2","n2","co2","plasma")) //the main four gases, which were at one time hardcoded
/proc/meta_gas_list()
. = new /list
@@ -0,0 +1,234 @@
#define NO_REACTION 0
#define REACTING 1
/datum/controller/subsystem/air/var/list/gas_reactions //this is our singleton of all reactions
/proc/init_gas_reactions()
var/list/reaction_types = list()
for(var/r in subtypesof(/datum/gas_reaction))
var/datum/gas_reaction/reaction = r
if(!initial(reaction.exclude))
reaction_types += reaction
reaction_types = sortList(reaction_types, /proc/cmp_gas_reactions)
. = list()
for(var/path in reaction_types)
. += new path
/proc/cmp_gas_reactions(datum/gas_reaction/a, datum/gas_reaction/b) //sorts in descending order of priority
return initial(b.priority) - initial(a.priority)
/datum/gas_reaction
//regarding the requirements lists: the minimum or maximum requirements must be non-zero.
//when in doubt, use MINIMUM_HEAT_CAPACITY.
var/list/min_requirements
var/list/max_requirements
var/exclude = FALSE //do it this way to allow for addition/removal of reactions midmatch in the future
var/priority = 100 //lower numbers are checked/react later than higher numbers. if two reactions have the same priority they may happen in either order
var/name = "reaction"
var/id = "r"
/datum/gas_reaction/New()
init_reqs()
/datum/gas_reaction/proc/init_reqs()
/datum/gas_reaction/proc/react(datum/gas_mixture/air, atom/location)
return NO_REACTION
//agent b: converts hot co2 and agent b to oxygen. requires plasma as a catalyst. endothermic
/datum/gas_reaction/agent_b
priority = 2
name = "Agent B"
id = "agent_b"
/datum/gas_reaction/agent_b/init_reqs()
min_requirements = list(
"TEMP" = 900,
"agent_b" = MINIMUM_HEAT_CAPACITY,
"plasma" = MINIMUM_HEAT_CAPACITY,
"co2" = MINIMUM_HEAT_CAPACITY
)
/datum/gas_reaction/agent_b/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/reaction_rate = min(cached_gases["co2"][MOLES]*0.75, cached_gases["plasma"][MOLES]*0.25, cached_gases["agent_b"][MOLES]*0.05)
cached_gases["co2"][MOLES] -= reaction_rate
cached_gases["agent_b"][MOLES] -= reaction_rate*0.05
air.assert_gas("o2") //only need to assert oxygen, as this reaction doesn't occur without the other gases existing
cached_gases["o2"][MOLES] += reaction_rate
air.temperature -= (reaction_rate*20000)/air.heat_capacity()
return REACTING
//freon: does a freezy thing?
/datum/gas_reaction/freon
priority = 1
name = "Freon"
id = "freon"
/datum/gas_reaction/freon/init_reqs()
min_requirements = list("freon" = MOLES_PLASMA_VISIBLE)
/datum/gas_reaction/freon/react(datum/gas_mixture/air, turf/open/location)
. = NO_REACTION
if(location && location.freon_gas_act())
air.gases["freon"][MOLES] -= MOLES_PLASMA_VISIBLE
. = REACTING
//water vapor: puts out fires?
/datum/gas_reaction/water_vapor
priority = 1
name = "Water Vapor"
id = "vapor"
/datum/gas_reaction/water_vapor/init_reqs()
min_requirements = list("water_vapor" = MOLES_PLASMA_VISIBLE)
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, turf/open/location)
. = NO_REACTION
if(location && location.water_vapor_gas_act())
air.gases["water_vapor"][MOLES] -= MOLES_PLASMA_VISIBLE
. = REACTING
//fire: combustion of plasma and volatile fuel (treated as hydrocarbons). creates hotspots. exothermic
/datum/gas_reaction/fire
priority = -1 //fire should ALWAYS be last
name = "Hydrocarbon Combustion"
id = "fire"
/datum/gas_reaction/fire/init_reqs()
min_requirements = list("TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST) //doesn't include plasma reqs b/c of volatile fuel stuff - consider finally axing volatile fuel
/datum/gas_reaction/fire/react(datum/gas_mixture/air, turf/open/location)
var/energy_released = 0
var/old_heat_capacity = air.heat_capacity()
var/list/cached_gases = air.gases //this speeds things up because accessing datum vars is slow
var/temperature = air.temperature
var/list/cached_results = air.reaction_results
//to_chat(world, "pre [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]")
cached_results[id] = 0
//General volatile gas burn
if(cached_gases["v_fuel"] && cached_gases["v_fuel"][MOLES])
var/burned_fuel
if(!cached_gases["o2"])
burned_fuel = 0
else if(cached_gases["o2"][MOLES] < cached_gases["v_fuel"][MOLES])
burned_fuel = cached_gases["o2"][MOLES]
cached_gases["v_fuel"][MOLES] -= burned_fuel
cached_gases["o2"][MOLES] = 0
else
burned_fuel = cached_gases["v_fuel"][MOLES]
cached_gases["o2"][MOLES] -= cached_gases["v_fuel"][MOLES]
if(burned_fuel)
energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
air.assert_gas("co2")
cached_gases["co2"][MOLES] += burned_fuel
cached_results[id] += burned_fuel
//Handle plasma burning
if(cached_gases["plasma"] && cached_gases["plasma"][MOLES] > MINIMUM_HEAT_CAPACITY)
var/plasma_burn_rate = 0
var/oxygen_burn_rate = 0
//more plasma released at higher temperatures
var/temperature_scale
if(temperature > PLASMA_UPPER_TEMPERATURE)
temperature_scale = 1
else
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
air.assert_gas("o2")
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(cached_gases["o2"][MOLES] > cached_gases["plasma"][MOLES]*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (cached_gases["plasma"][MOLES]*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
plasma_burn_rate = (temperature_scale*(cached_gases["o2"][MOLES]/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
air.assert_gas("co2")
cached_gases["plasma"][MOLES] = QUANTIZE(cached_gases["plasma"][MOLES] - plasma_burn_rate)
cached_gases["o2"][MOLES] = QUANTIZE(cached_gases["o2"][MOLES] - (plasma_burn_rate * oxygen_burn_rate))
cached_gases["co2"][MOLES] += plasma_burn_rate
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
cached_results[id] += (plasma_burn_rate)*(1+oxygen_burn_rate)
if(energy_released > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
//to_chat(world, "post [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]")
//let the floor know a fire is happening
if(istype(location))
temperature = air.temperature
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
location.hotspot_expose(temperature, CELL_VOLUME)
for(var/I in location)
var/atom/movable/item = I
item.temperature_expose(air, temperature, CELL_VOLUME)
location.temperature_expose(air, temperature, CELL_VOLUME)
return cached_results[id] ? REACTING : NO_REACTION
//fusion: a terrible idea that was fun to try. turns co2 and plasma into REALLY HOT oxygen and nitrogen. super exothermic lol
/datum/gas_reaction/fusion
exclude = TRUE
priority = 2
name = "Plasmic Fusion"
id = "fusion"
/datum/gas_reaction/fusion/init_reqs()
min_requirements = list(
"ENER" = PLASMA_BINDING_ENERGY * 10,
"plasma" = MINIMUM_HEAT_CAPACITY,
"co2" = MINIMUM_HEAT_CAPACITY
)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air)
var/list/cached_gases = air.gases
var/temperature = air.temperature
if((cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])/air.total_moles() < FUSION_PURITY_THRESHOLD)
//Fusion wont occur if the level of impurities is too high.
return NO_REACTION
//to_chat(world, "pre [temperature, [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]])
var/old_heat_capacity = air.heat_capacity()
var/carbon_efficency = min(cached_gases["plasma"][MOLES]/cached_gases["co2"][MOLES],MAX_CARBON_EFFICENCY)
var/reaction_energy = air.thermal_energy()
var/moles_impurities = air.total_moles()-(cached_gases["plasma"][MOLES]+cached_gases["co2"][MOLES])
var/plasma_fused = (PLASMA_FUSED_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
var/carbon_catalyzed = (CARBON_CATALYST_COEFFICENT*carbon_efficency)*(temperature/PLASMA_BINDING_ENERGY)
var/oxygen_added = carbon_catalyzed
var/nitrogen_added = (plasma_fused-oxygen_added)-(air.thermal_energy()/PLASMA_BINDING_ENERGY)
reaction_energy = max(reaction_energy+((carbon_efficency*cached_gases["plasma"][MOLES])/((moles_impurities/carbon_efficency)+2)*10)+((plasma_fused/(moles_impurities/carbon_efficency))*PLASMA_BINDING_ENERGY),0)
air.assert_gases("o2", "n2")
cached_gases["plasma"][MOLES] -= plasma_fused
cached_gases["co2"][MOLES] -= carbon_catalyzed
cached_gases["o2"][MOLES] += oxygen_added
cached_gases["n2"][MOLES] += nitrogen_added
if(reaction_energy > 0)
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
air.temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB)
//Prevents whatever mechanism is causing it to hit negative temperatures.
//to_chat(world, "post [temperature], [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]])
return REACTING
#undef REACTING
#undef NO_REACTION
@@ -41,9 +41,6 @@
/datum/gas_mixture/space/react()
return 0 //we're immutable.
/datum/gas_mixture/space/fire()
return 0 //we're immutable.
/datum/gas_mixture/space/copy()
return new /datum/gas_mixture/space //we're immutable, so we can just return a new instance.