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
@@ -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)