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:
@@ -61,7 +61,7 @@
|
||||
..()
|
||||
SSair.hotspots += src
|
||||
perform_exposure()
|
||||
setDir(pick(cardinal))
|
||||
setDir(pick(GLOB.cardinal))
|
||||
air_update_turf()
|
||||
|
||||
|
||||
@@ -79,14 +79,14 @@
|
||||
|
||||
if(bypassing)
|
||||
if(!just_spawned)
|
||||
volume = location.air.fuel_burnt*FIRE_GROWTH_RATE
|
||||
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
|
||||
temperature = location.air.temperature
|
||||
else
|
||||
var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.volume)
|
||||
affected.temperature = temperature
|
||||
affected.react()
|
||||
temperature = affected.temperature
|
||||
volume = affected.fuel_burnt*FIRE_GROWTH_RATE
|
||||
volume = affected.reaction_results["fire"]*FIRE_GROWTH_RATE
|
||||
location.assume_air(affected)
|
||||
|
||||
for(var/A in loc)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
/turf/proc/CalculateAdjacentTurfs()
|
||||
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
|
||||
for(var/direction in cardinal)
|
||||
for(var/direction in GLOB.cardinal)
|
||||
var/turf/T = get_step(src, direction)
|
||||
if(!T)
|
||||
continue
|
||||
@@ -72,11 +72,11 @@
|
||||
|
||||
var/turf/curloc = src
|
||||
|
||||
for (var/direction in diagonals)
|
||||
for (var/direction in GLOB.diagonals)
|
||||
var/matchingDirections = 0
|
||||
var/turf/S = get_step(curloc, direction)
|
||||
|
||||
for (var/checkDirection in cardinal)
|
||||
for (var/checkDirection in GLOB.cardinal)
|
||||
var/turf/checkTurf = get_step(S, checkDirection)
|
||||
if(!S.atmos_adjacent_turfs || !S.atmos_adjacent_turfs[checkTurf])
|
||||
continue
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
/turf/open/archive()
|
||||
air.archive()
|
||||
archived_cycle = SSair.times_fired
|
||||
..()
|
||||
temperature_archived = temperature
|
||||
|
||||
/////////////////////////GAS OVERLAYS//////////////////////////////
|
||||
|
||||
@@ -117,11 +117,23 @@
|
||||
var/list/gases = air.gases
|
||||
for(var/id in gases)
|
||||
var/gas = gases[id]
|
||||
if(gas[GAS_META][META_GAS_OVERLAY] && gas[MOLES] > gas[GAS_META][META_GAS_MOLES_VISIBLE])
|
||||
. += gas[GAS_META][META_GAS_OVERLAY]
|
||||
var/gas_meta = gas[GAS_META]
|
||||
var/gas_overlay = gas_meta[META_GAS_OVERLAY]
|
||||
if(gas_overlay && gas[MOLES] > gas_meta[META_GAS_MOLES_VISIBLE])
|
||||
. += gas_overlay
|
||||
|
||||
/////////////////////////////SIMULATION///////////////////////////////////
|
||||
|
||||
#define LAST_SHARE_CHECK \
|
||||
var/last_share = our_air.last_share;\
|
||||
if(last_share > MINIMUM_AIR_TO_SUSPEND){\
|
||||
our_excited_group.reset_cooldowns();\
|
||||
cached_atmos_cooldown = 0;\
|
||||
} else if(last_share > MINIMUM_MOLES_DELTA_TO_MOVE) {\
|
||||
our_excited_group.dismantle_cooldown = 0;\
|
||||
cached_atmos_cooldown = 0;\
|
||||
}
|
||||
|
||||
/turf/proc/process_cell(fire_count)
|
||||
SSair.remove_from_active(src)
|
||||
|
||||
@@ -130,16 +142,19 @@
|
||||
archive()
|
||||
|
||||
current_cycle = fire_count
|
||||
var/remove = 1 //set by non simulated turfs who are sharing with this turf
|
||||
|
||||
//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)
|
||||
atmos_cooldown++
|
||||
if (planetary_atmos)
|
||||
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
|
||||
|
||||
@@ -148,6 +163,8 @@
|
||||
|
||||
/******************* GROUP HANDLING START *****************************************************************/
|
||||
|
||||
var/should_share_air = FALSE
|
||||
var/datum/gas_mixture/enemy_air = enemy_tile.air
|
||||
if(enemy_tile.excited)
|
||||
//cache for sanic speed
|
||||
var/datum/excited_group/enemy_excited_group = enemy_tile.excited_group
|
||||
@@ -157,26 +174,26 @@
|
||||
//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
|
||||
share_air(enemy_tile, fire_count, adjacent_turfs_length) //share
|
||||
should_share_air = TRUE
|
||||
else
|
||||
if((recently_active == 1 && enemy_tile.recently_active == 1) || air.compare(enemy_tile.air))
|
||||
if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air))
|
||||
our_excited_group.add_turf(enemy_tile) //add enemy to our group
|
||||
share_air(enemy_tile, fire_count, adjacent_turfs_length) //share
|
||||
should_share_air = TRUE
|
||||
else
|
||||
if(enemy_excited_group)
|
||||
if((recently_active == 1 && enemy_tile.recently_active == 1) || air.compare(enemy_tile.air))
|
||||
if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air))
|
||||
enemy_excited_group.add_turf(src) //join self to enemy group
|
||||
our_excited_group = excited_group //update our cache
|
||||
share_air(enemy_tile, fire_count, adjacent_turfs_length) //share
|
||||
should_share_air = TRUE
|
||||
else
|
||||
if((recently_active == 1 && enemy_tile.recently_active == 1) || air.compare(enemy_tile.air))
|
||||
if((recently_active == 1 && enemy_tile.recently_active == 1) || our_air.compare(enemy_air))
|
||||
var/datum/excited_group/EG = new //generate new group
|
||||
EG.add_turf(src)
|
||||
EG.add_turf(enemy_tile)
|
||||
our_excited_group = excited_group //update our cache
|
||||
share_air(enemy_tile, fire_count, adjacent_turfs_length) //share
|
||||
should_share_air = TRUE
|
||||
else
|
||||
if(air.compare(enemy_tile.air)) //compare if
|
||||
if(our_air.compare(enemy_air)) //compare if
|
||||
SSair.add_to_active(enemy_tile) //excite enemy
|
||||
if(our_excited_group)
|
||||
our_excited_group.add_turf(enemy_tile) //add enemy to group
|
||||
@@ -185,51 +202,46 @@
|
||||
EG.add_turf(src)
|
||||
EG.add_turf(enemy_tile)
|
||||
our_excited_group = excited_group //update our cache
|
||||
share_air(enemy_tile, fire_count, adjacent_turfs_length) //share
|
||||
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 (planetary_atmos) //share our air with the "atmosphere" "above" the turf
|
||||
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(air.compare(G))
|
||||
if(our_air.compare(G))
|
||||
if(!our_excited_group)
|
||||
var/datum/excited_group/EG = new
|
||||
EG.add_turf(src)
|
||||
our_excited_group = excited_group
|
||||
air.share(G, adjacent_turfs_length)
|
||||
last_share_check()
|
||||
our_air.share(G, adjacent_turfs_length)
|
||||
LAST_SHARE_CHECK
|
||||
|
||||
air.react()
|
||||
our_air.react(src)
|
||||
|
||||
update_visuals()
|
||||
|
||||
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
hotspot_expose(air.temperature, CELL_VOLUME)
|
||||
for(var/atom/movable/item in src)
|
||||
item.temperature_expose(air, air.temperature, CELL_VOLUME)
|
||||
temperature_expose(air, air.temperature, CELL_VOLUME)
|
||||
var/remove = TRUE
|
||||
if(our_air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
|
||||
if(consider_superconductivity(starting = 1))
|
||||
remove = FALSE
|
||||
|
||||
if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
|
||||
if(consider_superconductivity(starting = 1))
|
||||
remove = 0
|
||||
|
||||
if (atmos_cooldown > EXCITED_GROUP_DISMANTLE_CYCLES*2)
|
||||
SSair.remove_from_active(src)
|
||||
if(!our_excited_group && remove == 1)
|
||||
if ((!our_excited_group && remove) || (cached_atmos_cooldown > (EXCITED_GROUP_DISMANTLE_CYCLES * 2)))
|
||||
SSair.remove_from_active(src)
|
||||
|
||||
|
||||
/turf/open/proc/share_air(turf/open/T, fire_count, adjacent_turfs_length)
|
||||
if(T.current_cycle < fire_count)
|
||||
var/difference = air.share(T.air, adjacent_turfs_length)
|
||||
if(difference)
|
||||
if(difference > 0)
|
||||
consider_pressure_difference(T, difference)
|
||||
else
|
||||
T.consider_pressure_difference(src, -difference)
|
||||
last_share_check()
|
||||
atmos_cooldown = cached_atmos_cooldown
|
||||
|
||||
//////////////////////////SPACEWIND/////////////////////////////
|
||||
|
||||
@@ -239,18 +251,7 @@
|
||||
pressure_direction = get_dir(src, T)
|
||||
pressure_difference = difference
|
||||
|
||||
/turf/open/proc/last_share_check()
|
||||
if(air.last_share > MINIMUM_AIR_TO_SUSPEND)
|
||||
excited_group.reset_cooldowns()
|
||||
atmos_cooldown = 0
|
||||
else if(air.last_share > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
excited_group.dismantle_cooldown = 0
|
||||
atmos_cooldown = 0
|
||||
|
||||
/turf/proc/high_pressure_movements()
|
||||
return
|
||||
|
||||
/turf/open/high_pressure_movements()
|
||||
/turf/open/proc/high_pressure_movements()
|
||||
for(var/atom/movable/M in src)
|
||||
M.experience_pressure_difference(pressure_difference, pressure_direction)
|
||||
|
||||
@@ -363,7 +364,7 @@
|
||||
/turf/open/conductivity_directions()
|
||||
if(blocks_air)
|
||||
return ..()
|
||||
for(var/direction in cardinal)
|
||||
for(var/direction in GLOB.cardinal)
|
||||
var/turf/T = get_step(src, direction)
|
||||
if(!(T in atmos_adjacent_turfs) && !(atmos_supeconductivity & direction))
|
||||
. |= direction
|
||||
@@ -392,7 +393,7 @@
|
||||
|
||||
if(conductivity_directions)
|
||||
//Conduct with tiles around me
|
||||
for(var/direction in cardinal)
|
||||
for(var/direction in GLOB.cardinal)
|
||||
if(conductivity_directions & direction)
|
||||
var/turf/neighbor = get_step(src,direction)
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
idle_power_usage = 4
|
||||
active_power_usage = 8
|
||||
power_channel = ENVIRON
|
||||
req_access = list(access_atmospherics)
|
||||
req_access = list(GLOB.access_atmospherics)
|
||||
obj_integrity = 250
|
||||
max_integrity = 250
|
||||
integrity_failure = 80
|
||||
@@ -158,7 +158,7 @@
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/airalarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "airalarm", name, 440, 650, master_ui, state)
|
||||
@@ -277,11 +277,11 @@
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max1", "selected" = selected.max1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = "max2", "selected" = selected.max2))
|
||||
|
||||
for(var/gas_id in meta_gas_info)
|
||||
for(var/gas_id in GLOB.meta_gas_info)
|
||||
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
|
||||
continue
|
||||
selected = TLV[gas_id]
|
||||
thresholds += list(list("name" = meta_gas_info[gas_id][META_GAS_NAME], "settings" = list()))
|
||||
thresholds += list(list("name" = GLOB.meta_gas_info[gas_id][META_GAS_NAME], "settings" = list()))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min2", "selected" = selected.min2))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "min1", "selected" = selected.min1))
|
||||
thresholds[thresholds.len]["settings"] += list(list("env" = gas_id, "val" = "max1", "selected" = selected.max1))
|
||||
@@ -389,7 +389,7 @@
|
||||
/obj/machinery/airalarm/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM)
|
||||
radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_TO_AIRALARM)
|
||||
|
||||
/obj/machinery/airalarm/proc/send_signal(target, list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise
|
||||
if(!radio_connection)
|
||||
@@ -403,7 +403,7 @@
|
||||
signal.data["tag"] = target
|
||||
signal.data["sigtype"] = "command"
|
||||
|
||||
radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM)
|
||||
radio_connection.post_signal(src, signal, GLOB.RADIO_FROM_AIRALARM)
|
||||
// to_chat(world, text("Signal [] Broadcasted to []", command, target))
|
||||
|
||||
return 1
|
||||
@@ -730,3 +730,14 @@
|
||||
I.obj_integrity = I.max_integrity * 0.5
|
||||
new /obj/item/stack/cable_coil(loc, 3)
|
||||
qdel(src)
|
||||
|
||||
#undef AALARM_MODE_SCRUBBING
|
||||
#undef AALARM_MODE_VENTING
|
||||
#undef AALARM_MODE_PANIC
|
||||
#undef AALARM_MODE_REPLACEMENT
|
||||
#undef AALARM_MODE_OFF
|
||||
#undef AALARM_MODE_FLOOD
|
||||
#undef AALARM_MODE_SIPHON
|
||||
#undef AALARM_MODE_CONTAMINATED
|
||||
#undef AALARM_MODE_REFILL
|
||||
#undef AALARM_REPORT_TIMEOUT
|
||||
@@ -67,7 +67,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
node_connects.len = device_type
|
||||
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
for(var/D in cardinal)
|
||||
for(var/D in GLOB.cardinal)
|
||||
if(D & GetInitDirections())
|
||||
if(D in node_connects)
|
||||
continue
|
||||
@@ -170,7 +170,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
var/fuck_you_dir = get_dir(src, user) // Because fuck you...
|
||||
if(!fuck_you_dir)
|
||||
fuck_you_dir = pick(cardinal)
|
||||
fuck_you_dir = pick(GLOB.cardinal)
|
||||
var/turf/target = get_edge_target_turf(user, fuck_you_dir)
|
||||
var/range = pressures/250
|
||||
var/speed = range/5
|
||||
@@ -212,7 +212,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
if(can_unwrench)
|
||||
add_atom_colour(obj_color, FIXED_COLOUR_PRIORITY)
|
||||
pipe_color = obj_color
|
||||
var/turf/T = loc
|
||||
var/turf/T = get_turf(src)
|
||||
level = T.intact ? 2 : 1
|
||||
atmosinit()
|
||||
var/list/nodes = pipeline_expansion()
|
||||
@@ -245,7 +245,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
var/obj/machinery/atmospherics/target_move = findConnecting(direction)
|
||||
if(target_move)
|
||||
if(target_move.can_crawl_through())
|
||||
if(is_type_in_list(target_move, ventcrawl_machinery))
|
||||
if(is_type_in_list(target_move, GLOB.ventcrawl_machinery))
|
||||
user.forceMove(target_move.loc) //handle entering and so on.
|
||||
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>","<span class='notice'>You climb out the ventilation system.")
|
||||
else
|
||||
@@ -258,7 +258,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
user.last_played_vent = world.time
|
||||
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
|
||||
else
|
||||
if((direction & initialize_directions) || is_type_in_list(src, ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
|
||||
if((direction & initialize_directions) || is_type_in_list(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
|
||||
user.forceMove(src.loc)
|
||||
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>","<span class='notice'>You climb out the ventilation system.")
|
||||
user.canmove = 0
|
||||
@@ -267,7 +267,7 @@ Pipelines + Other Objects -> Pipe network
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/AltClick(mob/living/L)
|
||||
if(is_type_in_list(src, ventcrawl_machinery))
|
||||
if(is_type_in_list(src, GLOB.ventcrawl_machinery))
|
||||
L.handle_ventcrawl(src)
|
||||
return
|
||||
..()
|
||||
|
||||
@@ -126,7 +126,7 @@ Acts like a normal vent, but has an input AND output.
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = GLOB.RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
@@ -147,7 +147,7 @@ Acts like a normal vent, but has an input AND output.
|
||||
"external" = external_pressure_bound,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ Passive gate is similar to the regular pump except:
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = GLOB.RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
@@ -88,12 +88,12 @@ Passive gate is similar to the regular pump except:
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 335, 115, master_ui, state)
|
||||
|
||||
@@ -77,7 +77,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = GLOB.RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
@@ -95,12 +95,12 @@ Thus, the two variables affect pump operation are set in New():
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 335, 115, master_ui, state)
|
||||
|
||||
@@ -95,7 +95,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 310, 115, master_ui, state)
|
||||
|
||||
@@ -31,7 +31,7 @@ Iconnery
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/icon_addbroken(var/connected = 0)
|
||||
var/unconnected = (~connected) & initialize_directions
|
||||
for(var/direction in cardinal)
|
||||
for(var/direction in GLOB.cardinal)
|
||||
if(unconnected & direction)
|
||||
underlays += getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_exposed", direction)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/Destroy()
|
||||
if(SSradio)
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/update_icon()
|
||||
cut_overlays()
|
||||
for(var/direction in cardinal)
|
||||
for(var/direction in GLOB.cardinal)
|
||||
if(direction & initialize_directions)
|
||||
var/obj/machinery/atmospherics/node = findConnecting(direction)
|
||||
if(node)
|
||||
@@ -113,7 +113,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_filter", name, 475, 155, master_ui, state)
|
||||
@@ -154,9 +154,9 @@
|
||||
filter_type = ""
|
||||
var/filter_name = "nothing"
|
||||
var/gas = params["mode"]
|
||||
if(gas in meta_gas_info)
|
||||
if(gas in GLOB.meta_gas_info)
|
||||
filter_type = gas
|
||||
filter_name = meta_gas_info[gas][META_GAS_NAME]
|
||||
filter_name = GLOB.meta_gas_info[gas][META_GAS_NAME]
|
||||
investigate_log("was set to filter [filter_name] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/update_icon()
|
||||
cut_overlays()
|
||||
for(var/direction in cardinal)
|
||||
for(var/direction in GLOB.cardinal)
|
||||
if(direction & initialize_directions)
|
||||
var/obj/machinery/atmospherics/node = findConnecting(direction)
|
||||
if(node)
|
||||
@@ -117,7 +117,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_mixer", name, 370, 165, master_ui, state)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
state_open = FALSE
|
||||
var/autoeject = FALSE
|
||||
var/volume = 100
|
||||
var/running_bob_animation = 0
|
||||
var/running_bob_animation = FALSE
|
||||
|
||||
var/efficiency = 1
|
||||
var/sleep_factor = 750
|
||||
@@ -106,7 +106,7 @@
|
||||
icon_state = "pod1"
|
||||
var/up = 0 //used to see if we are going up or down, 1 is down, 2 is up
|
||||
spawn(0) // Without this, the icon update will block. The new thread will die once the occupant leaves.
|
||||
running_bob_animation = 1
|
||||
running_bob_animation = TRUE
|
||||
while(occupant)
|
||||
overlays -= "lid1" //have to remove the overlays first, to force an update- remove cloning pod overlay
|
||||
overlays -= pickle //remove mob overlay
|
||||
@@ -134,7 +134,7 @@
|
||||
|
||||
sleep(7) //don't want to jiggle violently, just slowly bob
|
||||
return
|
||||
running_bob_animation = 0
|
||||
running_bob_animation = FALSE
|
||||
else
|
||||
icon_state = "pod1"
|
||||
overlays += "lid0" //have to remove the overlays first, to force an update- remove cloning pod overlay
|
||||
@@ -160,7 +160,7 @@
|
||||
playsound(T, 'sound/machines/cryo_warning.ogg', volume, 1) // Bug the doctors.
|
||||
radio.talk_into(src, "Patient fully restored", radio_channel)
|
||||
if(autoeject) // Eject if configured.
|
||||
radio.talk_into(src, "Auto ejecting patient now", radio_channel)
|
||||
radio.talk_into(src, "Auto ejecting patient now", radio_channel,get_spans(), get_default_language())
|
||||
open_machine()
|
||||
return
|
||||
else if(occupant.stat == DEAD) // We don't bother with dead people.
|
||||
@@ -280,7 +280,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = notcontained_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "cryo", name, 400, 550, master_ui, state)
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "thermomachine", name, 400, 240, master_ui, state)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump
|
||||
name = "air vent"
|
||||
desc = "Has a valve and pump attached to it"
|
||||
desc = "Has a valve and pump attached to it."
|
||||
icon_state = "vent_map"
|
||||
use_power = 1
|
||||
can_unwrench = 1
|
||||
@@ -178,8 +178,8 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/atmosinit()
|
||||
//some vents work his own spesial way
|
||||
radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null
|
||||
radio_filter_out = frequency==1439?(RADIO_TO_AIRALARM):null
|
||||
radio_filter_in = frequency==1439?(GLOB.RADIO_FROM_AIRALARM):null
|
||||
radio_filter_out = frequency==1439?(GLOB.RADIO_TO_AIRALARM):null
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
broadcast_status()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber
|
||||
name = "air scrubber"
|
||||
desc = "Has a valve and pump attached to it"
|
||||
desc = "Has a valve and pump attached to it."
|
||||
icon_state = "scrub_map"
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
@@ -142,8 +142,8 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit()
|
||||
radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null
|
||||
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
|
||||
radio_filter_in = frequency==initial(frequency)?(GLOB.RADIO_FROM_AIRALARM):null
|
||||
radio_filter_out = frequency==initial(frequency)?(GLOB.RADIO_TO_AIRALARM):null
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
broadcast_status()
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
reconcile_air()
|
||||
update = air.react()
|
||||
|
||||
var/pipenetwarnings = 10
|
||||
|
||||
/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base)
|
||||
var/volume = 0
|
||||
if(istype(base, /obj/machinery/atmospherics/pipe))
|
||||
@@ -44,7 +42,6 @@ var/pipenetwarnings = 10
|
||||
addMachineryMember(base)
|
||||
if(!air)
|
||||
air = new
|
||||
air.holder = src
|
||||
var/list/possible_expansions = list(base)
|
||||
while(possible_expansions.len>0)
|
||||
for(var/obj/machinery/atmospherics/borderline in possible_expansions)
|
||||
@@ -58,6 +55,7 @@ var/pipenetwarnings = 10
|
||||
if(!members.Find(item))
|
||||
|
||||
if(item.parent)
|
||||
var/static/pipenetwarnings = 10
|
||||
if(pipenetwarnings > 0)
|
||||
warning("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) Nearby: ([item.x], [item.y], [item.z])")
|
||||
pipenetwarnings -= 1
|
||||
@@ -246,4 +244,3 @@ var/pipenetwarnings = 10
|
||||
var/list/G_gases = G.gases
|
||||
for(var/id in G_gases)
|
||||
G_gases[id][MOLES] *= G.volume/total_gas_mixture.volume
|
||||
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
|
||||
#define GASMINER_POWER_NONE 0
|
||||
#define GASMINER_POWER_STATIC 1
|
||||
#define GASMINER_POWER_MOLES 2 //Scaled from here on down.
|
||||
#define GASMINER_POWER_KPA 3
|
||||
#define GASMINER_POWER_FULLSCALE 4
|
||||
|
||||
/obj/machinery/atmospherics/miner
|
||||
name = "gas miner"
|
||||
desc = "Gasses mined from the gas giant below (above?) flow out through this massive vent."
|
||||
icon = 'icons/obj/atmospherics/components/miners.dmi'
|
||||
icon_state = "miner"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
resistance_flags = INDESTRUCTIBLE|ACID_PROOF|FIRE_PROOF
|
||||
var/spawn_id = null
|
||||
var/spawn_temp = T20C
|
||||
var/spawn_mol = MOLES_CELLSTANDARD * 10
|
||||
var/max_ext_mol = INFINITY
|
||||
var/max_ext_kpa = 6500
|
||||
var/overlay_color = "#FFFFFF"
|
||||
var/active = TRUE
|
||||
var/power_draw = 0
|
||||
var/power_draw_static = 2000
|
||||
var/power_draw_dynamic_mol_coeff = 5 //DO NOT USE DYNAMIC SETTINGS UNTIL SOMEONE MAKES A USER INTERFACE/CONTROLLER FOR THIS!
|
||||
var/power_draw_dynamic_kpa_coeff = 0.5
|
||||
var/broken = FALSE
|
||||
var/broken_message = "ERROR"
|
||||
idle_power_usage = 150
|
||||
active_power_usage = 2000
|
||||
|
||||
/obj/machinery/atmospherics/miner/examine(mob/user)
|
||||
..()
|
||||
if(broken)
|
||||
to_chat(user, "Its debug output is printing \"[broken_message]\"")
|
||||
|
||||
/obj/machinery/atmospherics/miner/proc/check_operation()
|
||||
if(!active)
|
||||
return FALSE
|
||||
var/turf/T = get_turf(src)
|
||||
if(!isopenturf(T))
|
||||
broken_message = "<span class='boldnotice'>VENT BLOCKED</span>"
|
||||
broken = TRUE
|
||||
return FALSE
|
||||
var/turf/open/OT = T
|
||||
if(OT.planetary_atmos)
|
||||
broken_message = "<span class='boldwarning'>DEVICE NOT ENCLOSED IN A PRESSURIZED ENVIRONMENT</span>"
|
||||
broken = TRUE
|
||||
return FALSE
|
||||
if(isspaceturf(T))
|
||||
broken_message = "<span class='boldnotice'>AIR VENTING TO SPACE</span>"
|
||||
broken = TRUE
|
||||
return FALSE
|
||||
var/datum/gas_mixture/G = OT.return_air()
|
||||
if(G.return_pressure() > (max_ext_kpa - ((spawn_mol*spawn_temp*R_IDEAL_GAS_EQUATION)/(CELL_VOLUME))))
|
||||
broken_message = "<span class='boldwarning'>EXTERNAL PRESSURE OVER THRESHOLD</span>"
|
||||
broken = TRUE
|
||||
return FALSE
|
||||
if(G.total_moles() > max_ext_mol)
|
||||
broken_message = "<span class='boldwarning'>EXTERNAL AIR CONCENTRATION OVER THRESHOLD</span>"
|
||||
broken = TRUE
|
||||
return FALSE
|
||||
if(broken)
|
||||
broken = FALSE
|
||||
broken_message = ""
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/miner/proc/update_power()
|
||||
if(!active)
|
||||
active_power_usage = idle_power_usage
|
||||
var/turf/T = get_turf(src)
|
||||
var/datum/gas_mixture/G = T.return_air()
|
||||
var/P = G.return_pressure()
|
||||
switch(power_draw)
|
||||
if(GASMINER_POWER_NONE)
|
||||
active_power_usage = 0
|
||||
if(GASMINER_POWER_STATIC)
|
||||
active_power_usage = power_draw_static
|
||||
if(GASMINER_POWER_MOLES)
|
||||
active_power_usage = spawn_mol * power_draw_dynamic_mol_coeff
|
||||
if(GASMINER_POWER_KPA)
|
||||
active_power_usage = P * power_draw_dynamic_kpa_coeff
|
||||
if(GASMINER_POWER_FULLSCALE)
|
||||
active_power_usage = (spawn_mol * power_draw_dynamic_mol_coeff) + (P * power_draw_dynamic_kpa_coeff)
|
||||
|
||||
/obj/machinery/atmospherics/miner/proc/do_use_power(amount)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && istype(T))
|
||||
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
|
||||
if(C && C.powernet && (C.powernet.avail > amount))
|
||||
C.powernet.load += amount
|
||||
return TRUE
|
||||
if(powered())
|
||||
use_power(amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/atmospherics/miner/update_icon()
|
||||
overlays.Cut()
|
||||
if(broken)
|
||||
var/image/A = image(icon, "broken")
|
||||
add_overlay(A)
|
||||
else if(active)
|
||||
var/image/A = image(icon, "on")
|
||||
A.color = overlay_color
|
||||
add_overlay(A)
|
||||
|
||||
/obj/machinery/atmospherics/miner/process()
|
||||
update_power()
|
||||
update_icon()
|
||||
check_operation()
|
||||
if(active && !broken)
|
||||
if(isnull(spawn_id))
|
||||
return FALSE
|
||||
if(do_use_power(active_power_usage))
|
||||
mine_gas()
|
||||
|
||||
/obj/machinery/atmospherics/miner/proc/mine_gas()
|
||||
var/turf/open/O = get_turf(src)
|
||||
if(!isopenturf(O))
|
||||
return FALSE
|
||||
var/datum/gas_mixture/merger = new
|
||||
merger.assert_gas(spawn_id)
|
||||
merger.gases[spawn_id][MOLES] = (spawn_mol)
|
||||
merger.temperature = spawn_temp
|
||||
O.assume_air(merger)
|
||||
SSair.add_to_active(O)
|
||||
|
||||
/obj/machinery/atmospherics/miner/attack_ai(mob/living/silicon/user)
|
||||
if(broken)
|
||||
to_chat(user, "[src] seems to be broken. Its debug interface outputs: [broken_message]")
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/miner/n2o
|
||||
name = "\improper N2O Gas Miner"
|
||||
overlay_color = "#FFCCCC"
|
||||
spawn_id = "n2o"
|
||||
|
||||
/obj/machinery/atmospherics/miner/nitrogen
|
||||
name = "\improper N2 Gas Miner"
|
||||
overlay_color = "#CCFFCC"
|
||||
spawn_id = "n2"
|
||||
|
||||
/obj/machinery/atmospherics/miner/oxygen
|
||||
name = "\improper O2 Gas Miner"
|
||||
overlay_color = "#007FFF"
|
||||
spawn_id = "o2"
|
||||
|
||||
/obj/machinery/atmospherics/miner/toxins
|
||||
name = "\improper Plasma Gas Miner"
|
||||
overlay_color = "#FF0000"
|
||||
spawn_id = "plasma"
|
||||
|
||||
/obj/machinery/atmospherics/miner/carbon_dioxide
|
||||
name = "\improper CO2 Gas Miner"
|
||||
overlay_color = "#CDCDCD"
|
||||
spawn_id = "co2"
|
||||
|
||||
/obj/machinery/atmospherics/miner/bz
|
||||
name = "\improper BZ Gas Miner"
|
||||
overlay_color = "#FAFF00"
|
||||
spawn_id = "bz"
|
||||
|
||||
/obj/machinery/atmospherics/miner/freon
|
||||
name = "\improper Freon Gas Miner"
|
||||
overlay_color = "#00FFE5"
|
||||
spawn_id = "freon"
|
||||
|
||||
/obj/machinery/atmospherics/miner/volatile_fuel
|
||||
name = "\improper Volatile Fuel Gas Miner"
|
||||
overlay_color = "#564040"
|
||||
spawn_id = "v_fuel"
|
||||
|
||||
/obj/machinery/atmospherics/miner/agent_b
|
||||
name = "\improper Agent B Gas Miner"
|
||||
overlay_color = "#E81E24"
|
||||
spawn_id = "agent_b"
|
||||
|
||||
/obj/machinery/atmospherics/miner/water_vapor
|
||||
name = "\improper Water Vapor Gas Miner"
|
||||
overlay_color = "#99928E"
|
||||
spawn_id = "water_vapor"
|
||||
@@ -10,7 +10,7 @@
|
||||
device_type = BINARY
|
||||
|
||||
/obj/machinery/atmospherics/pipe/heat_exchanging/simple/SetInitDirections()
|
||||
if(dir in diagonals)
|
||||
if(dir in GLOB.diagonals)
|
||||
initialize_directions_he = dir
|
||||
switch(dir)
|
||||
if(NORTH,SOUTH)
|
||||
|
||||
@@ -8,7 +8,7 @@ The regular pipe you see everywhere, including bent ones.
|
||||
icon_state = "intact"
|
||||
|
||||
name = "pipe"
|
||||
desc = "A one meter section of regular pipe"
|
||||
desc = "A one meter section of regular pipe."
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH
|
||||
@@ -16,7 +16,7 @@ The regular pipe you see everywhere, including bent ones.
|
||||
device_type = BINARY
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/SetInitDirections()
|
||||
if(dir in diagonals)
|
||||
if(dir in GLOB.diagonals)
|
||||
initialize_directions = dir
|
||||
switch(dir)
|
||||
if(NORTH,SOUTH)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define CAN_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE * 10)
|
||||
#define CAN_MIN_RELEASE_PRESSURE (ONE_ATMOSPHERE / 10)
|
||||
#define CAN_DEFAULT_RELEASE_PRESSURE (ONE_ATMOSPHERE)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister
|
||||
@@ -16,6 +14,8 @@
|
||||
var/filled = 0.5
|
||||
var/gas_type = ""
|
||||
var/release_pressure = ONE_ATMOSPHERE
|
||||
var/can_max_release_pressure = (ONE_ATMOSPHERE * 10)
|
||||
var/can_min_release_pressure = (ONE_ATMOSPHERE / 10)
|
||||
|
||||
armor = list(melee = 50, bullet = 50, laser = 50, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 80, acid = 50)
|
||||
obj_integrity = 250
|
||||
@@ -24,6 +24,16 @@
|
||||
pressure_resistance = 7 * ONE_ATMOSPHERE
|
||||
var/temperature_resistance = 1000 + T0C
|
||||
var/starter_temp
|
||||
// Prototype vars
|
||||
var/prototype = FALSE
|
||||
var/valve_timer = null
|
||||
var/timer_set = 30
|
||||
var/default_timer_set = 30
|
||||
var/minimum_timer_set = 1
|
||||
var/maximum_timer_set = 300
|
||||
var/timing = FALSE
|
||||
var/restricted = FALSE
|
||||
req_access = list()
|
||||
|
||||
var/update = 0
|
||||
var/static/list/label2types = list(
|
||||
@@ -39,6 +49,13 @@
|
||||
"caution" = /obj/machinery/portable_atmospherics/canister,
|
||||
)
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/interact(mob/user)
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Error - Unauthorized User</span>")
|
||||
playsound(src, 'sound/misc/compiler-failure.ogg', 50, 1)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/nitrogen
|
||||
name = "n2 canister"
|
||||
desc = "Nitrogen gas. Reportedly useful for something."
|
||||
@@ -99,6 +116,46 @@
|
||||
gas_type = "water_vapor"
|
||||
filled = 1
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
|
||||
if(timing)
|
||||
. = round(max(0, valve_timer - world.time) / 10, 1)
|
||||
else
|
||||
. = timer_set
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/set_active()
|
||||
timing = !timing
|
||||
if(timing)
|
||||
valve_timer = world.time + (timer_set * 10)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proto
|
||||
name = "prototype canister"
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proto/default
|
||||
name = "prototype canister"
|
||||
desc = "The best way to fix an atmospheric emergency... or the best way to introduce one."
|
||||
icon_state = "proto"
|
||||
icon_state = "proto"
|
||||
volume = 5000
|
||||
obj_integrity = 300
|
||||
max_integrity = 300
|
||||
temperature_resistance = 2000 + T0C
|
||||
can_max_release_pressure = (ONE_ATMOSPHERE * 30)
|
||||
can_min_release_pressure = (ONE_ATMOSPHERE / 30)
|
||||
prototype = TRUE
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proto/default/oxygen
|
||||
name = "prototype canister"
|
||||
desc = "A prototype canister for a prototype bike, what could go wrong?"
|
||||
icon_state = "proto"
|
||||
gas_type = "o2"
|
||||
filled = 1
|
||||
release_pressure = ONE_ATMOSPHERE*2
|
||||
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture)
|
||||
..()
|
||||
if(existing_mixture)
|
||||
@@ -239,6 +296,9 @@
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
return PROCESS_KILL
|
||||
if(timing && valve_timer < world.time)
|
||||
valve_open = !valve_open
|
||||
timing = FALSE
|
||||
if(!valve_open)
|
||||
pump.AIR1 = null
|
||||
pump.AIR2 = null
|
||||
@@ -255,7 +315,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "canister", name, 420, 405, master_ui, state)
|
||||
@@ -267,10 +327,20 @@
|
||||
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
||||
data["releasePressure"] = round(release_pressure ? release_pressure : 0)
|
||||
data["defaultReleasePressure"] = round(CAN_DEFAULT_RELEASE_PRESSURE)
|
||||
data["minReleasePressure"] = round(CAN_MIN_RELEASE_PRESSURE)
|
||||
data["maxReleasePressure"] = round(CAN_MAX_RELEASE_PRESSURE)
|
||||
data["minReleasePressure"] = round(can_min_release_pressure)
|
||||
data["maxReleasePressure"] = round(can_max_release_pressure)
|
||||
data["valveOpen"] = valve_open ? 1 : 0
|
||||
|
||||
data["isPrototype"] = prototype ? 1 : 0
|
||||
if (prototype)
|
||||
data["restricted"] = restricted
|
||||
data["timing"] = timing
|
||||
data["time_left"] = get_time_left()
|
||||
data["timer_set"] = timer_set
|
||||
data["timer_is_not_default"] = timer_set != default_timer_set
|
||||
data["timer_is_not_min"] = timer_set != minimum_timer_set
|
||||
data["timer_is_not_max"] = timer_set != maximum_timer_set
|
||||
|
||||
data["hasHoldingTank"] = holding ? 1 : 0
|
||||
if (holding)
|
||||
data["holdingTank"] = list()
|
||||
@@ -287,32 +357,37 @@
|
||||
if(label && !..())
|
||||
var/newtype = label2types[label]
|
||||
if(newtype)
|
||||
var/obj/machinery/portable_atmospherics/canister/replacement = new newtype(loc, air_contents)
|
||||
if(connected_port)
|
||||
replacement.connected_port = connected_port
|
||||
replacement.connected_port.connected_device = replacement
|
||||
replacement.interact(usr)
|
||||
qdel(src)
|
||||
var/obj/machinery/portable_atmospherics/canister/replacement = newtype
|
||||
name = initial(replacement.name)
|
||||
desc = initial(replacement.name)
|
||||
icon_state = initial(replacement.icon_state)
|
||||
if("restricted")
|
||||
restricted = !restricted
|
||||
if(restricted)
|
||||
req_access = list(GLOB.access_engine)
|
||||
else
|
||||
req_access = list()
|
||||
. = TRUE
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "reset")
|
||||
pressure = CAN_DEFAULT_RELEASE_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "min")
|
||||
pressure = CAN_MIN_RELEASE_PRESSURE
|
||||
pressure = can_min_release_pressure
|
||||
. = TRUE
|
||||
else if(pressure == "max")
|
||||
pressure = CAN_MAX_RELEASE_PRESSURE
|
||||
pressure = can_max_release_pressure
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New release pressure ([CAN_MIN_RELEASE_PRESSURE]-[CAN_MAX_RELEASE_PRESSURE] kPa):", name, release_pressure) as num|null
|
||||
pressure = input("New release pressure ([can_min_release_pressure]-[can_max_release_pressure] kPa):", name, release_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
release_pressure = Clamp(round(pressure), CAN_MIN_RELEASE_PRESSURE, CAN_MAX_RELEASE_PRESSURE)
|
||||
release_pressure = Clamp(round(pressure), can_min_release_pressure, can_max_release_pressure)
|
||||
investigate_log("was set to [release_pressure] kPa by [key_name(usr)].", "atmos")
|
||||
if("valve")
|
||||
var/logmsg
|
||||
@@ -344,11 +419,34 @@
|
||||
investigate_log(logmsg, "atmos")
|
||||
release_log += logmsg
|
||||
. = TRUE
|
||||
if("timer")
|
||||
var/change = params["change"]
|
||||
switch(change)
|
||||
if("reset")
|
||||
timer_set = default_timer_set
|
||||
if("decrease")
|
||||
timer_set = max(minimum_timer_set, timer_set - 10)
|
||||
if("increase")
|
||||
timer_set = min(maximum_timer_set, timer_set + 10)
|
||||
if("input")
|
||||
var/user_input = input(usr, "Set time to valve toggle.", name) as null|num
|
||||
if(!user_input)
|
||||
return
|
||||
var/N = text2num(user_input)
|
||||
if(!N)
|
||||
return
|
||||
timer_set = Clamp(N,minimum_timer_set,maximum_timer_set)
|
||||
log_admin("[key_name(usr)] has activated a prototype valve timer")
|
||||
. = TRUE
|
||||
if("toggle_timer")
|
||||
set_active()
|
||||
if("eject")
|
||||
if(holding)
|
||||
if(valve_open)
|
||||
investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transfering into the <span class='boldannounce'>air</span><br>", "atmos")
|
||||
holding.loc = get_turf(src)
|
||||
holding.forceMove(get_turf(src))
|
||||
holding = null
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
air_contents = new
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
air_contents.holder = src
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "portable_pump", name, 420, 415, master_ui, state)
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "portable_scrubber", name, 420, 335, master_ui, state)
|
||||
|
||||
Reference in New Issue
Block a user