Merge pull request #13991 from Putnam3145/auxtools-atmos

Replaces extools with auxtools; atmos overhaul
This commit is contained in:
silicons
2021-06-27 11:01:32 -07:00
committed by GitHub
154 changed files with 2336 additions and 2232 deletions
+1
View File
@@ -194,6 +194,7 @@ GLOBAL_PROTECT(admin_verbs_debug)
// /client/proc/check_missing_sprites,
// #endif
/datum/admins/proc/create_or_modify_area,
/datum/admins/proc/fixcorruption,
#ifdef REFERENCE_TRACKING
/datum/admins/proc/view_refs,
/datum/admins/proc/view_del_failures,
+1 -1
View File
@@ -581,7 +581,7 @@
if(Rad.anchored)
if(!Rad.loaded_tank)
var/obj/item/tank/internals/plasma/Plasma = new/obj/item/tank/internals/plasma(Rad)
Plasma.air_contents.set_moles(/datum/gas/plasma,70)
Plasma.air_contents.set_moles(GAS_PLASMA,70)
Rad.drainratio = 0
Rad.loaded_tank = Plasma
Plasma.forceMove(Rad)
+1 -1
View File
@@ -10,7 +10,7 @@
for(var/id in env.get_gases())
var/moles = env.get_moles(id)
if (moles >= 0.00001)
lines += "[GLOB.meta_gas_names[id]]: [moles] mol"
lines += "[GLOB.gas_data.names[id]]: [moles] mol"
to_chat(usr, lines.Join("\n"))
/client/proc/air_status(turf/target)
@@ -4,7 +4,7 @@ GLOBAL_LIST_EMPTY(deletion_failures)
/world/proc/enable_reference_tracking()
if (fexists(EXTOOLS))
call(EXTOOLS, "ref_tracking_initialize")()
//call(EXTOOLS, "ref_tracking_initialize")()
/proc/get_back_references(datum/D)
CRASH("/proc/get_back_references not hooked by extools, reference tracking will not function!")
@@ -64,7 +64,7 @@
result++
. -= result - 1
/obj/structure/blob/BlockSuperconductivity()
/obj/structure/blob/BlockThermalConductivity()
return atmosblock
/obj/structure/blob/CanPass(atom/movable/mover, turf/target)
@@ -29,7 +29,7 @@
return
return TRUE
/obj/effect/clockwork/servant_blocker/BlockSuperconductivity()
/obj/effect/clockwork/servant_blocker/BlockThermalConductivity()
return TRUE
/obj/effect/clockwork/servant_blocker/singularity_act()
+1 -1
View File
@@ -647,7 +647,7 @@ structure_check() searches for nearby cultist structures required for the invoca
GLOB.wall_runes -= src
return ..()
/obj/effect/rune/wall/BlockSuperconductivity()
/obj/effect/rune/wall/BlockThermalConductivity()
return density
/obj/effect/rune/wall/invoke(var/list/invokers)
+2 -3
View File
@@ -146,7 +146,7 @@
return
/obj/item/tank/proc/ignite() //This happens when a bomb is told to explode
var/fuel_moles = air_contents.get_moles(/datum/gas/plasma) + air_contents.get_moles(/datum/gas/oxygen)/6
var/fuel_moles = air_contents.get_moles(GAS_PLASMA) + air_contents.get_moles(GAS_O2)/6
var/datum/gas_mixture/bomb_mixture = air_contents.copy()
var/strength = 1
@@ -196,9 +196,8 @@
ground_zero.air_update_turf()
/obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out.
var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(removed)
T.assume_air(air_contents)
air_update_turf()
@@ -0,0 +1,37 @@
// Breathing classes are, yes, just a list of gases, associated with numbers.
// But they're very simple: pluoxium's status as O2 * 8 is represented here,
// with a single line of code, no hardcoding and special-casing across the codebase.
// Not only that, but they're very general: you could have a negative value
// to simulate asphyxiants, e.g. if I add krypton it could go into the oxygen
// breathing class at -7, simulating krypton narcosis.
/datum/breathing_class
var/list/gases = null
var/list/products = null
var/danger_reagent = null
var/low_alert_category = "not_enough_oxy"
var/low_alert_datum = /obj/screen/alert/not_enough_oxy
var/high_alert_category = "too_much_oxy"
var/high_alert_datum = /obj/screen/alert/too_much_oxy
/datum/breathing_class/oxygen
gases = list(
GAS_O2 = 1,
GAS_PLUOXIUM = 8,
GAS_CO2 = -0.7, // CO2 isn't actually toxic, just an asphyxiant
)
products = list(
GAS_CO2 = 1,
)
/datum/breathing_class/plasma
gases = list(
GAS_PLASMA = 1
)
products = list(
GAS_CO2 = 1
)
low_alert_category = "not_enough_tox"
low_alert_datum = /obj/screen/alert/not_enough_tox
high_alert_category = "too_much_tox"
high_alert_datum = /obj/screen/alert/too_much_tox
@@ -0,0 +1,169 @@
/datum/gas/oxygen
id = GAS_O2
specific_heat = 20
name = "Oxygen"
oxidation_temperature = T0C - 100 // it checks max of this and fire temperature, so rarely will things spontaneously combust
/datum/gas/nitrogen
id = GAS_N2
specific_heat = 20
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_nitro",
alert_type = /obj/screen/alert/not_enough_nitro
),
too_much_alert = list(
alert_category = "too_much_nitro",
alert_type = /obj/screen/alert/too_much_nitro
)
)
name = "Nitrogen"
/datum/gas/carbon_dioxide //what the fuck is this?
id = GAS_CO2
specific_heat = 30
name = "Carbon Dioxide"
breath_results = GAS_O2
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_co2",
alert_type = /obj/screen/alert/not_enough_co2
),
too_much_alert = list(
alert_category = "too_much_co2",
alert_type = /obj/screen/alert/too_much_co2
)
)
fusion_power = 3
/datum/gas/plasma
id = GAS_PLASMA
specific_heat = 200
name = "Plasma"
gas_overlay = "plasma"
moles_visible = MOLES_GAS_VISIBLE
flags = GAS_FLAG_DANGEROUS
// no fire info cause it has its own bespoke reaction for trit generation reasons
/datum/gas/water_vapor
id = GAS_H2O
specific_heat = 40
name = "Water Vapor"
gas_overlay = "water_vapor"
moles_visible = MOLES_GAS_VISIBLE
fusion_power = 8
breath_reagent = /datum/reagent/water
/datum/gas/hypernoblium
id = GAS_HYPERNOB
specific_heat = 2000
name = "Hyper-noblium"
gas_overlay = "freon"
moles_visible = MOLES_GAS_VISIBLE
/datum/gas/nitrous_oxide
id = GAS_NITROUS
specific_heat = 40
name = "Nitrous Oxide"
gas_overlay = "nitrous_oxide"
moles_visible = MOLES_GAS_VISIBLE * 2
flags = GAS_FLAG_DANGEROUS
fire_products = list(GAS_N2 = 1)
oxidation_rate = 0.5
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 100
/datum/gas/nitryl
id = GAS_NITRYL
specific_heat = 20
name = "Nitryl"
gas_overlay = "nitryl"
moles_visible = MOLES_GAS_VISIBLE
flags = GAS_FLAG_DANGEROUS
fusion_power = 15
fire_products = list(GAS_N2 = 0.5)
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
/datum/gas/tritium
id = GAS_TRITIUM
specific_heat = 10
name = "Tritium"
gas_overlay = "tritium"
moles_visible = MOLES_GAS_VISIBLE
flags = GAS_FLAG_DANGEROUS
fusion_power = 1
/*
these are for when we add hydrogen, trit gets to keep its hardcoded fire for legacy reasons
fire_provides = list(GAS_H2O = 2)
fire_burn_rate = 2
fire_energy_released = FIRE_HYDROGEN_ENERGY_RELEASED
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 50
*/
/datum/gas/bz
id = GAS_BZ
specific_heat = 20
name = "BZ"
flags = GAS_FLAG_DANGEROUS
fusion_power = 8
/datum/gas/stimulum
id = GAS_STIMULUM
specific_heat = 5
name = "Stimulum"
fusion_power = 7
/datum/gas/pluoxium
id = GAS_PLUOXIUM
specific_heat = 80
name = "Pluoxium"
fusion_power = 10
oxidation_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST * 1000 // it is VERY stable
oxidation_rate = 8
/datum/gas/miasma
id = GAS_MIASMA
specific_heat = 20
fusion_power = 50
name = "Miasma"
gas_overlay = "miasma"
moles_visible = MOLES_GAS_VISIBLE * 60
/datum/gas/methane
id = GAS_METHANE
specific_heat = 30
name = "Methane"
breath_results = GAS_METHYL_BROMIDE
fire_products = list(GAS_CO2 = 1, GAS_H2O = 2)
fire_burn_rate = 0.5
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_ch4",
alert_type = /obj/screen/alert/not_enough_ch4
),
too_much_alert = list(
alert_category = "too_much_ch4",
alert_type = /obj/screen/alert/too_much_ch4
)
)
fire_energy_released = FIRE_CARBON_ENERGY_RELEASED
fire_temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
/datum/gas/methyl_bromide
id = GAS_METHYL_BROMIDE
specific_heat = 42
name = "Methyl Bromide"
flags = GAS_FLAG_DANGEROUS
breath_alert_info = list(
not_enough_alert = list(
alert_category = "not_enough_ch3br",
alert_type = /obj/screen/alert/not_enough_ch3br
),
too_much_alert = list(
alert_category = "too_much_ch3br",
alert_type = /obj/screen/alert/too_much_ch3br
)
)
fire_products = list(GAS_CO2 = 1, GAS_H2O = 1.5, GAS_BZ = 0.5)
fire_energy_released = FIRE_CARBON_ENERGY_RELEASED
fire_burn_rate = 0.5
fire_temperature = 808 // its autoignition, it apparently doesn't spark readily, so i don't put it lower
@@ -13,28 +13,21 @@
if(!air)
return
var/oxy = air.get_moles(/datum/gas/oxygen)
if (oxy < 0.5)
if (air.get_oxidation_power(exposed_temperature) < 0.5)
return
var/tox = air.get_moles(/datum/gas/plasma)
var/trit = air.get_moles(/datum/gas/tritium)
var/has_fuel = air.get_moles(GAS_PLASMA) > 0.5 || air.get_moles(GAS_TRITIUM) > 0.5 || air.get_fuel_amount(exposed_temperature) > 0.5
if(active_hotspot)
if(soh)
if(tox > 0.5 || trit > 0.5)
if(has_fuel)
if(active_hotspot.temperature < exposed_temperature)
active_hotspot.temperature = exposed_temperature
if(active_hotspot.volume < exposed_volume)
active_hotspot.volume = exposed_volume
return
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (tox > 0.5 || trit > 0.5))
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && has_fuel)
active_hotspot = new /obj/effect/hotspot(src, exposed_volume*25, exposed_temperature)
active_hotspot.just_spawned = (current_cycle < SSair.times_fired)
//remove just_spawned protection if no longer processing this cell
SSair.add_to_active(src, 0)
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
/obj/effect/hotspot
anchored = TRUE
@@ -48,7 +41,6 @@
var/volume = 125
var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
var/just_spawned = TRUE
var/bypassing = FALSE
var/visual_update_tick = 0
@@ -70,7 +62,7 @@
location.active_hotspot = src
bypassing = !just_spawned && (volume > CELL_VOLUME*0.95)
bypassing = volume > CELL_VOLUME*0.95
if(bypassing)
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
@@ -150,10 +142,6 @@
#define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)
/obj/effect/hotspot/process()
if(just_spawned)
just_spawned = FALSE
return
var/turf/open/location = loc
if(!istype(location))
qdel(src)
@@ -164,13 +152,7 @@
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
qdel(src)
return
if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
qdel(src)
return
//Not enough to burn
// god damn it previous coder you made the INSUFFICIENT macro for a fucking reason why didn't you use it here smh
if((INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
if(!location.air || location.air.get_oxidation_power() < 0.5 || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM) && location.air.get_fuel_amount() < 0.5))
qdel(src)
return
@@ -19,57 +19,58 @@
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
var/opp = REVERSE_DIR(dir)
var/R = FALSE
. = TRUE
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
R = TRUE
. = FALSE
if(blocks_air || T.blocks_air)
R = TRUE
. = FALSE
if (T == src)
return !R
return .
for(var/obj/O in contents+T.contents)
var/turf/other = (O.loc == src ? T : src)
if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other))))
R = TRUE
if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
atmos_supeconductivity |= dir
T.atmos_supeconductivity |= opp
return FALSE //no need to keep going, we got all we asked
. = FALSE
if(O.BlockThermalConductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
conductivity_blocked_directions |= dir
T.conductivity_blocked_directions |= opp
if(!.)
return .
atmos_supeconductivity &= ~dir
T.atmos_supeconductivity &= ~opp
return !R
/atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm.
/atom/movable/proc/BlockThermalConductivity() // Objects that don't let heat through.
return FALSE
/turf/proc/ImmediateCalculateAdjacentTurfs()
if(SSair.thread_running())
CALCULATE_ADJACENT_TURFS(src)
return
var/canpass = CANATMOSPASS(src, src)
var/canvpass = CANVERTICALATMOSPASS(src, src)
for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction)
var/opp_dir = REVERSE_DIR(direction)
if(!isopenturf(T))
if(!istype(T))
continue
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
var/opp_dir = REVERSE_DIR(direction)
if(isopenturf(T) && !(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = direction
T.atmos_adjacent_turfs[src] = opp_dir
T.__update_extools_adjacent_turfs()
else
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= T
if (T.atmos_adjacent_turfs)
T.atmos_adjacent_turfs -= src
T.__update_extools_adjacent_turfs()
UNSETEMPTY(T.atmos_adjacent_turfs)
T.set_sleeping(T.blocks_air)
T.__update_auxtools_turf_adjacency_info(isspaceturf(T.get_z_base_turf()), -1)
UNSETEMPTY(atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs
__update_extools_adjacent_turfs()
set_sleeping(blocks_air)
__update_auxtools_turf_adjacency_info(isspaceturf(get_z_base_turf()))
/turf/proc/__update_extools_adjacent_turfs()
/turf/proc/set_sleeping(should_sleep)
/turf/proc/__update_auxtools_turf_adjacency_info()
//returns a list of adjacent turfs that can share air with this one.
//alldir includes adjacent diagonal tiles that can share
@@ -111,7 +112,6 @@
/turf/air_update_turf(command = 0)
if(command)
ImmediateCalculateAdjacentTurfs()
SSair.add_to_active(src,command)
/atom/movable/proc/move_update_air(turf/T)
if(isturf(T))
@@ -130,7 +130,4 @@
var/datum/gas_mixture/G = new
G.parse_gas_string(text)
air.merge(G)
archive()
SSair.add_to_active(src, 0)
assume_air(G)
@@ -1,18 +1,13 @@
/turf
//used for temperature calculations
var/thermal_conductivity = 0.005
//conductivity is divided by 10 when interacting with air for balance purposes
var/thermal_conductivity = 0.05
var/heat_capacity = 1
var/temperature_archived
//list of open turfs adjacent to us
var/list/atmos_adjacent_turfs
//bitfield of dirs in which we are superconducitng
var/atmos_supeconductivity = NONE
var/is_openturf = FALSE // used by extools shizz.
//used to determine whether we should archive
var/archived_cycle = 0
var/current_cycle = 0
//bitfield of dirs in which we thermal conductivity is blocked
var/conductivity_blocked_directions = NONE
//used for mapping and for breathing while in walls (because that's a thing that needs to be accounted for...)
//string parsed by /datum/gas/proc/copy_from_turf
@@ -32,21 +27,17 @@
var/planetary_atmos = FALSE //air will revert to initial_gas_mix over time
var/list/atmos_overlay_types //gas IDs of current active gas overlays
is_openturf = TRUE
/turf/open/Initialize()
if(!blocks_air)
air = new
air = new(2500,src)
air.copy_from_turf(src)
update_air_ref()
update_air_ref(planetary_atmos ? 1 : 2)
. = ..()
/turf/open/Destroy()
if(active_hotspot)
QDEL_NULL(active_hotspot)
// Adds the adjacent turfs to the current atmos processing
for(var/T in atmos_adjacent_turfs)
SSair.add_to_active(T)
return ..()
/// Function for Extools Atmos
@@ -55,10 +46,46 @@
/////////////////GAS MIXTURE PROCS///////////////////
/turf/open/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
return assume_air_ratio(giver, 1)
/turf/open/assume_air_moles(datum/gas_mixture/giver, moles)
if(!giver)
return FALSE
air.merge(giver)
update_visuals()
if(SSair.thread_running())
SSair.deferred_airs += list(list(giver, air, moles / giver.total_moles()))
else
giver.transfer_to(air, moles)
update_visuals()
return TRUE
/turf/open/assume_air_ratio(datum/gas_mixture/giver, ratio)
if(!giver)
return FALSE
if(SSair.thread_running())
SSair.deferred_airs += list(list(giver, air, ratio))
else
giver.transfer_ratio_to(air, ratio)
update_visuals()
return TRUE
/turf/open/transfer_air(datum/gas_mixture/taker, moles)
if(!taker || !return_air()) // shouldn't transfer from space
return FALSE
if(SSair.thread_running())
SSair.deferred_airs += list(list(air, taker, moles / air.total_moles()))
else
air.transfer_to(taker, moles)
update_visuals()
return TRUE
/turf/open/transfer_air_ratio(datum/gas_mixture/taker, ratio)
if(!taker || !return_air())
return FALSE
if(SSair.thread_running())
SSair.deferred_airs += list(list(air, taker, ratio))
else
air.transfer_ratio_to(taker, ratio)
update_visuals()
return TRUE
/turf/open/remove_air(amount)
@@ -67,6 +94,12 @@
update_visuals()
return removed
/turf/open/remove_air_ratio(ratio)
var/datum/gas_mixture/ours = return_air()
var/datum/gas_mixture/removed = ours.remove_ratio(ratio)
update_visuals()
return removed
/turf/open/proc/copy_air_with_tile(turf/open/T)
if(istype(T))
air.copy_from(T.air)
@@ -86,17 +119,9 @@
return air
/turf/temperature_expose()
if(temperature > heat_capacity)
if(return_temperature() > heat_capacity)
to_be_destroyed = TRUE
/turf/proc/archive()
temperature_archived = temperature
/turf/open/archive()
air.archive()
archived_cycle = SSair.times_fired
temperature_archived = temperature
/turf/open/proc/eg_reset_cooldowns()
/turf/open/proc/eg_garbage_collect()
/turf/open/proc/get_excited()
@@ -121,8 +146,8 @@
for(var/id in air.get_gases())
if (nonoverlaying_gases[id])
continue
var/gas_overlay = GLOB.meta_gas_overlays[id]
if(gas_overlay && air.get_moles(id) > GLOB.meta_gas_visibility[META_GAS_MOLES_VISIBLE])
var/gas_overlay = GLOB.gas_data.overlays[id]
if(gas_overlay && air.get_moles(id) > GLOB.gas_data.visibility[id])
new_overlay_types += gas_overlay[min(FACTOR_GAS_VISIBLE_MAX, CEILING(air.get_moles(id) / MOLES_GAS_VISIBLE_STEP, 1))]
if (atmos_overlay_types)
@@ -156,7 +181,7 @@
for (var/gastype in subtypesof(/datum/gas))
var/datum/gas/gasvar = gastype
if (!initial(gasvar.gas_overlay))
.[gastype] = TRUE
.[initial(gasvar.id)] = TRUE
/////////////////////////////SIMULATION///////////////////////////////////
@@ -171,7 +196,6 @@
}
*/
/turf/proc/process_cell(fire_count)
SSair.remove_from_active(src)
/turf/open/proc/equalize_pressure_in_zone(cyclenum)
/turf/open/proc/consider_firelocks(turf/T2)
@@ -198,7 +222,10 @@
//////////////////////////SPACEWIND/////////////////////////////
/turf/open/proc/consider_pressure_difference(turf/T, difference)
/turf/proc/consider_pressure_difference()
return
/turf/open/consider_pressure_difference(turf/T, difference)
if(difference > pressure_difference)
pressure_direction = get_dir(src, T)
pressure_difference = difference
@@ -236,117 +263,3 @@
if (move_prob > PROBABILITY_OFFSET && prob(move_prob) && (move_resist != INFINITY) && (!anchored && (max_force >= (move_resist * MOVE_FORCE_PUSH_RATIO))) || (anchored && (max_force >= (move_resist * MOVE_FORCE_FORCEPUSH_RATIO))))
step(src, direction)
////////////////////////SUPERCONDUCTIVITY/////////////////////////////
/turf/proc/conductivity_directions()
if(archived_cycle < SSair.times_fired)
archive()
return NORTH|SOUTH|EAST|WEST
/turf/open/conductivity_directions()
if(blocks_air)
return ..()
for(var/direction in GLOB.cardinals)
var/turf/T = get_step(src, direction)
if(!(T in atmos_adjacent_turfs) && !(atmos_supeconductivity & direction))
. |= direction
/turf/proc/neighbor_conduct_with_src(turf/open/other)
if(!other.blocks_air) //Open but neighbor is solid
other.temperature_share_open_to_solid(src)
else //Both tiles are solid
other.share_temperature_mutual_solid(src, thermal_conductivity)
temperature_expose(null, temperature, null)
/turf/open/neighbor_conduct_with_src(turf/other)
if(blocks_air)
..()
return
if(!other.blocks_air) //Both tiles are open
var/turf/open/T = other
T.air.temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
else //Solid but neighbor is open
temperature_share_open_to_solid(other)
SSair.add_to_active(src, 0)
/turf/proc/super_conduct()
var/conductivity_directions = conductivity_directions()
archive()
if(conductivity_directions)
//Conduct with tiles around me
for(var/direction in GLOB.cardinals)
if(conductivity_directions & direction)
var/turf/neighbor = get_step(src,direction)
if(!neighbor.thermal_conductivity)
continue
if(neighbor.archived_cycle < SSair.times_fired)
neighbor.archive()
neighbor.neighbor_conduct_with_src(src)
neighbor.consider_superconductivity()
radiate_to_spess()
finish_superconduction()
/turf/proc/finish_superconduction(temp = temperature)
//Make sure still hot enough to continue conducting heat
if(temp < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
SSair.active_super_conductivity -= src
return FALSE
/turf/open/finish_superconduction()
//Conduct with air on my tile if I have it
if(!blocks_air)
temperature = air.temperature_share(null, thermal_conductivity, temperature, heat_capacity)
..((blocks_air ? temperature : air.return_temperature()))
/turf/proc/consider_superconductivity()
if(!thermal_conductivity)
return FALSE
SSair.active_super_conductivity[src] = TRUE
return TRUE
/turf/open/consider_superconductivity(starting)
if(planetary_atmos)
return FALSE
if(air.return_temperature() < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return FALSE
if(air.heat_capacity() < M_CELL_WITH_RATIO) // Was: MOLES_CELLSTANDARD*0.1*0.05 Since there are no variables here we can make this a constant.
return FALSE
return ..()
/turf/closed/consider_superconductivity(starting)
if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
return FALSE
return ..()
/turf/proc/radiate_to_spess() //Radiate excess tile heat to space
if(temperature > T0C) //Considering 0 degC as te break even point for radiation in and out
var/delta_temperature = (temperature_archived - TCMB) //hardcoded space temperature
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
var/heat = thermal_conductivity*delta_temperature* \
(heat_capacity*HEAT_CAPACITY_VACUUM/(heat_capacity+HEAT_CAPACITY_VACUUM))
temperature -= heat/heat_capacity
temperature = max(temperature,T0C) //otherwise we just sorta get stuck at super cold temps forever
/turf/open/proc/temperature_share_open_to_solid(turf/sharer)
sharer.temperature = air.temperature_share(null, sharer.thermal_conductivity, sharer.temperature, sharer.heat_capacity)
/turf/proc/share_temperature_mutual_solid(turf/sharer, conduction_coefficient) //to be understood
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
var/heat = conduction_coefficient*delta_temperature* \
(heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
temperature -= heat/heat_capacity
sharer.temperature += heat/sharer.heat_capacity
temperature = max(temperature,T0C)
sharer.temperature = max(sharer.temperature,T0C)
@@ -0,0 +1,131 @@
GLOBAL_LIST_INIT(hardcoded_gases, list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLASMA)) //the main four gases, which were at one time hardcoded
GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GAS_PLUOXIUM, GAS_STIMULUM, GAS_NITRYL))) //unable to react amongst themselves
// Auxgm
// It's a send-up of XGM, like what baystation got.
// It's got the same architecture as XGM, but it's structured
// differently to make it more convenient for auxmos.
// Most important compared to TG is that it does away with hardcoded typepaths,
// which lead to problems on the auxmos end anyway. We cache the string value
// references on the Rust end, so no performance is lost here.
// Also allows you to add new gases at runtime
/proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas
/datum/auxgm
var/list/datums = list()
var/list/specific_heats = list()
var/list/names = list()
var/list/visibility = list()
var/list/overlays = list()
var/list/flags = list()
var/list/ids = list()
var/list/typepaths = list()
var/list/fusion_powers = list()
var/list/breathing_classes = list()
var/list/breath_results = list()
var/list/breath_reagents = list()
var/list/breath_reagents_dangerous = list()
var/list/breath_alert_info = list()
var/list/oxidation_temperatures = list()
var/list/oxidation_rates = list()
var/list/fire_temperatures = list()
var/list/fire_enthalpies = list()
var/list/fire_products = list()
var/list/fire_burn_rates = list()
/datum/gas
var/id = ""
var/specific_heat = 0
var/name = ""
var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi
var/moles_visible = null
var/flags = NONE //currently used by canisters
var/fusion_power = 0 // How much the gas destabilizes a fusion reaction
var/breath_results = GAS_CO2 // what breathing this breathes out
var/breath_reagent = null // what breathing this adds to your reagents
var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something
var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none
var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material
var/fire_temperature = null // temperature above which gas may catch fire; null for none
var/list/fire_products = null // what results when this gas is burned (oxidizer or fuel); null for none
var/fire_energy_released = 0 // how much energy is released per mole of fuel burned
var/fire_burn_rate = 1 // how many moles are burned per product released
/datum/gas/proc/breath(partial_pressure, light_threshold, heavy_threshold, moles, mob/living/carbon/C, obj/item/organ/lungs/lungs)
// This is only called on gases with the GAS_FLAG_BREATH_PROC flag. When possible, do NOT use this--
// greatly prefer just adding a reagent. This is mostly around for legacy reasons.
return null
/datum/auxgm/proc/add_gas(datum/gas/gas)
var/g = gas.id
if(g)
datums[g] = gas
specific_heats[g] = gas.specific_heat
names[g] = gas.name
if(gas.moles_visible)
visibility[g] = gas.moles_visible
overlays[g] = new /list(FACTOR_GAS_VISIBLE_MAX)
for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
overlays[g][i] = new /obj/effect/overlay/gas(gas.gas_overlay, i * 255 / FACTOR_GAS_VISIBLE_MAX)
else
visibility[g] = 0
overlays[g] = 0
flags[g] = gas.flags
ids[g] = g
typepaths[g] = gas.type
fusion_powers[g] = gas.fusion_power
if(gas.breath_alert_info)
breath_alert_info[g] = gas.breath_alert_info
breath_results[g] = gas.breath_results
if(gas.breath_reagent)
breath_reagents[g] = gas.breath_reagent
if(gas.breath_reagent_dangerous)
breath_reagents_dangerous[g] = gas.breath_reagent_dangerous
if(gas.oxidation_temperature)
oxidation_temperatures[g] = gas.oxidation_temperature
oxidation_rates[g] = gas.oxidation_rate
if(gas.fire_products)
fire_products[g] = gas.fire_products
fire_enthalpies[g] = gas.fire_energy_released
else if(gas.fire_temperature)
fire_temperatures[g] = gas.fire_temperature
fire_burn_rates[g] = gas.fire_burn_rate
if(gas.fire_products)
fire_products[g] = gas.fire_products
fire_enthalpies[g] = gas.fire_energy_released
_auxtools_register_gas(gas)
/proc/finalize_gas_refs()
/datum/auxgm/New()
for(var/gas_path in subtypesof(/datum/gas))
var/datum/gas/gas = new gas_path
add_gas(gas)
for(var/breathing_class_path in subtypesof(/datum/breathing_class))
var/datum/breathing_class/class = new breathing_class_path
breathing_classes[breathing_class_path] = class
finalize_gas_refs()
GLOBAL_DATUM_INIT(gas_data, /datum/auxgm, new)
/obj/effect/overlay/gas
icon = 'icons/effects/atmospherics.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE // should only appear in vis_contents, but to be safe
layer = FLY_LAYER
appearance_flags = TILE_BOUND
vis_flags = NONE
/obj/effect/overlay/gas/New(state, alph)
. = ..()
icon_state = state
alpha = alph
@@ -6,27 +6,24 @@ What are the archived variables for?
#define MINIMUM_HEAT_CAPACITY 0.0003
#define MINIMUM_MOLE_COUNT 0.01
//Unomos - global list inits for all of the meta gas lists.
//This setup allows procs to only look at one list instead of trying to dig around in lists-within-lists
GLOBAL_LIST_INIT(meta_gas_specific_heats, meta_gas_heat_list())
GLOBAL_LIST_INIT(meta_gas_names, meta_gas_name_list())
GLOBAL_LIST_INIT(meta_gas_visibility, meta_gas_visibility_list())
GLOBAL_LIST_INIT(meta_gas_overlays, meta_gas_overlay_list())
GLOBAL_LIST_INIT(meta_gas_dangers, meta_gas_danger_list())
GLOBAL_LIST_INIT(meta_gas_ids, meta_gas_id_list())
GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture
/// Never ever set this variable, hooked into vv_get_var for view variables viewing.
var/gas_list_view_only
var/initial_volume = CELL_VOLUME //liters
var/list/reaction_results
var/list/analyzer_results //used for analyzer feedback - not initialized until its used
var/_extools_pointer_gasmixture = 0 // Contains the memory address of the shared_ptr object for this gas mixture in c++ land. Don't. Touch. This. Var.
var/_extools_pointer_gasmixture // Contains the index in the gas vector for this gas mixture in rust land. Don't. Touch. This. Var.
GLOBAL_LIST_INIT(auxtools_atmos_initialized,FALSE)
/proc/auxtools_atmos_init()
/datum/gas_mixture/New(volume)
if (!isnull(volume))
initial_volume = volume
ATMOS_EXTOOLS_CHECK
AUXTOOLS_CHECK(AUXMOS)
if(!GLOB.auxtools_atmos_initialized && auxtools_atmos_init())
GLOB.auxtools_atmos_initialized = TRUE
__gasmixture_register()
reaction_results = new
@@ -43,6 +40,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
var/list/dummy = get_gases()
for(var/gas in dummy)
dummy[gas] = get_moles(gas)
dummy["CAP [gas]"] = partial_heat_capacity(gas)
dummy["TEMP"] = return_temperature()
dummy["PRESSURE"] = return_pressure()
dummy["HEAT CAPACITY"] = heat_capacity()
@@ -79,16 +77,16 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
var/list/gases = get_gases()
for(var/gas in gases)
gases[gas] = get_moles(gas)
var/gastype = input(usr, "What kind of gas?", "Set Gas") as null|anything in subtypesof(/datum/gas)
if(!ispath(gastype, /datum/gas))
var/gasid = input(usr, "What kind of gas?", "Set Gas") as null|anything in GLOB.gas_data.ids
if(!gasid)
return
var/amount = input(usr, "Input amount", "Set Gas", gases[gastype] || 0) as num|null
var/amount = input(usr, "Input amount", "Set Gas", gases[gasid] || 0) as num|null
if(!isnum(amount))
return
amount = max(0, amount)
log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Set gas type [gastype] to [amount] moles.")
message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Set gas type [gastype] to [amount] moles.")
set_moles(gastype, amount)
log_admin("[key_name(usr)] modified gas mixture [REF(src)]: Set gas [gasid] to [amount] moles.")
message_admins("[key_name(usr)] modified gas mixture [REF(src)]: Set gas [gasid] to [amount] moles.")
set_moles(gasid, amount)
if(href_list[VV_HK_SET_TEMPERATURE])
var/temp = input(usr, "Set the temperature of this mixture to?", "Set Temperature", return_temperature()) as num|null
if(!isnum(temp))
@@ -107,9 +105,11 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
set_volume(volume)
/*
we use a hook instead
/datum/gas_mixture/Del()
__gasmixture_unregister()
. = ..()*/
. = ..()
*/
/datum/gas_mixture/proc/__gasmixture_unregister()
/datum/gas_mixture/proc/__gasmixture_register()
@@ -123,6 +123,8 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/heat_capacity() //joules per kelvin
/datum/gas_mixture/proc/partial_heat_capacity(gas_type)
/datum/gas_mixture/proc/total_moles()
/datum/gas_mixture/proc/return_pressure() //kilopascals
@@ -147,7 +149,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/vv_react(datum/holder)
return react(holder)
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, list/gases)
/datum/gas_mixture/proc/scrub_into(datum/gas_mixture/target, ratio, list/gases)
/datum/gas_mixture/proc/mark_immutable()
/datum/gas_mixture/proc/get_gases()
/datum/gas_mixture/proc/multiply(factor)
@@ -155,7 +157,7 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/clear()
/datum/gas_mixture/proc/adjust_moles(gas_type, amt = 0)
set_moles(gas_type, get_moles(gas_type) + amt)
set_moles(gas_type, clamp(get_moles(gas_type) + amt,0,INFINITY))
/datum/gas_mixture/proc/return_volume() //liters
@@ -175,7 +177,9 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
/datum/gas_mixture/proc/transfer_to(datum/gas_mixture/target, amount)
//Transfers amount of gas to target. Equivalent to target.merge(remove(amount)) but faster.
//Removes amount of gas from the gas_mixture
/datum/gas_mixture/proc/transfer_ratio_to(datum/gas_mixture/target, ratio)
//Transfers ratio of gas to target. Equivalent to target.merge(remove_ratio(amount)) but faster.
/datum/gas_mixture/proc/remove_ratio(ratio)
//Proportionally removes amount of gas from the gas_mixture
@@ -213,6 +217,24 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
//Performs various reactions such as combustion or fusion (LOL)
//Returns: 1 if any reaction took place; 0 otherwise
/datum/gas_mixture/proc/adjust_heat(amt)
//Adjusts the thermal energy of the gas mixture, rather than having to do the full calculation.
//Returns: null
/datum/gas_mixture/proc/equalize_with(datum/gas_mixture/giver)
//Makes this mix have the same temperature and gas ratios as the giver, but with the same pressure, accounting for volume.
//Returns: null
/datum/gas_mixture/proc/get_oxidation_power(temp)
//Gets how much oxidation this gas can do, optionally at a given temperature.
/datum/gas_mixture/proc/get_fuel_amount(temp)
//Gets how much fuel for fires (not counting trit/plasma!) this gas has, optionally at a given temperature.
/proc/equalize_all_gases_in_list(list/L)
//Makes every gas in the given list have the same pressure, temperature and gas proportions.
//Returns: null
/datum/gas_mixture/proc/__remove()
/datum/gas_mixture/remove(amount)
var/datum/gas_mixture/removed = new type
@@ -234,26 +256,21 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
return copy
/datum/gas_mixture/copy_from_turf(turf/model)
set_temperature(initial(model.initial_temperature))
parse_gas_string(model.initial_gas_mix)
//acounts for changes in temperature
var/turf/model_parent = model.parent_type
if(model.temperature != initial(model.temperature) || model.temperature != initial(model_parent.temperature))
set_temperature(model.temperature)
return 1
/datum/gas_mixture/parse_gas_string(gas_string)
var/list/gas = params2list(gas_string)
if(gas["TEMP"])
set_temperature(text2num(gas["TEMP"]))
var/temp = text2num(gas["TEMP"])
gas -= "TEMP"
if(!isnum(temp) || temp < 2.7)
temp = 2.7
set_temperature(temp)
clear()
for(var/id in gas)
var/path = id
if(!ispath(path))
path = gas_id2path(path) //a lot of these strings can't have embedded expressions (especially for mappers), so support for IDs needs to stick around
set_moles(path, text2num(gas[id]))
set_moles(id, text2num(gas[id]))
archive()
return 1
/*
@@ -305,17 +322,11 @@ GLOBAL_LIST_INIT(meta_gas_fusions, meta_gas_fusion_list())
if (. & STOP_REACTIONS)
break
*/
//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)
/datum/gas_mixture/proc/get_breath_partial_pressure(gas_pressure)
return (gas_pressure * R_IDEAL_GAS_EQUATION * return_temperature()) / BREATH_VOLUME
//inverse
/datum/gas_mixture/proc/get_true_breath_pressure(partial_pressure)
return (partial_pressure * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * return_temperature())
/datum/gas_mixture/proc/set_analyzer_results(instability)
if(!analyzer_results)
analyzer_results = new
analyzer_results["fusion"] = instability
//Mathematical proofs:
/*
@@ -379,8 +390,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles()
var/transfer_moles = pressure_delta*output_air.return_volume()/(input_air.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = input_air.remove(transfer_moles)
output_air.merge(removed)
input_air.transfer_to(output_air, transfer_moles)
return TRUE
return FALSE
@@ -1,214 +0,0 @@
GLOBAL_LIST_INIT(hardcoded_gases, list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/plasma)) //the main four gases, which were at one time hardcoded
GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(/datum/gas/oxygen, /datum/gas/nitrogen, /datum/gas/carbon_dioxide, /datum/gas/pluoxium, /datum/gas/stimulum, /datum/gas/nitryl))) //unable to react amongst themselves
/proc/gas_id2path(id)
var/list/meta_gas = GLOB.meta_gas_ids
if(id in meta_gas)
return id
for(var/path in meta_gas)
if(meta_gas[path] == id)
return path
return ""
//Unomos - oh god oh fuck oh shit oh lord have mercy this is messy as fuck oh god
//my addiction to seeing better performance numbers isn't healthy, kids
//you see this shit, children?
//i am not a good idol. don't take after me.
//this is literally worse than my alcohol addiction
/proc/meta_gas_heat_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.specific_heat)
/proc/meta_gas_name_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.name)
/proc/meta_gas_visibility_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.moles_visible)
/proc/meta_gas_overlay_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = 0 //gotta make sure if(GLOB.meta_gas_overlays[gaspath]) doesn't break
if(initial(gas.moles_visible) != null)
.[gas_path] = new /list(FACTOR_GAS_VISIBLE_MAX)
for(var/i in 1 to FACTOR_GAS_VISIBLE_MAX)
.[gas_path][i] = new /obj/effect/overlay/gas(initial(gas.gas_overlay), i * 255 / FACTOR_GAS_VISIBLE_MAX)
/proc/meta_gas_danger_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.dangerous)
/proc/meta_gas_id_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.id)
/proc/meta_gas_fusion_list()
. = subtypesof(/datum/gas)
for(var/gas_path in .)
var/datum/gas/gas = gas_path
.[gas_path] = initial(gas.fusion_power)
/*||||||||||||||/----------\||||||||||||||*\
||||||||||||||||[GAS DATUMS]||||||||||||||||
||||||||||||||||\__________/||||||||||||||||
||||These should never be instantiated. ||||
||||They exist only to make it easier ||||
||||to add a new gas. They are accessed ||||
||||only by meta_gas_list(). ||||
\*||||||||||||||||||||||||||||||||||||||||*/
/datum/gas
var/id = ""
var/specific_heat = 0
var/name = ""
var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi
var/moles_visible = null
var/dangerous = FALSE //currently used by canisters
var/fusion_power = 0 //How much the gas accelerates a fusion reaction
var/rarity = 0 // relative rarity compared to other gases, used when setting up the reactions list.
/datum/gas/oxygen
id = "o2"
specific_heat = 20
name = "Oxygen"
rarity = 900
/datum/gas/nitrogen
id = "n2"
specific_heat = 20
name = "Nitrogen"
rarity = 1000
/datum/gas/carbon_dioxide //what the fuck is this?
id = "co2"
specific_heat = 30
name = "Carbon Dioxide"
fusion_power = 3
rarity = 700
/datum/gas/plasma
id = "plasma"
specific_heat = 200
name = "Plasma"
gas_overlay = "plasma"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
rarity = 800
/datum/gas/water_vapor
id = "water_vapor"
specific_heat = 40
name = "Water Vapor"
gas_overlay = "water_vapor"
moles_visible = MOLES_GAS_VISIBLE
fusion_power = 8
rarity = 500
/datum/gas/hypernoblium
id = "nob"
specific_heat = 2000
name = "Hyper-noblium"
gas_overlay = "freon"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
rarity = 50
/datum/gas/nitrous_oxide
id = "n2o"
specific_heat = 40
name = "Nitrous Oxide"
gas_overlay = "nitrous_oxide"
moles_visible = MOLES_GAS_VISIBLE * 2
dangerous = TRUE
rarity = 600
/datum/gas/nitryl
id = "no2"
specific_heat = 20
name = "Nitryl"
gas_overlay = "nitryl"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
fusion_power = 15
rarity = 100
/datum/gas/tritium
id = "tritium"
specific_heat = 10
name = "Tritium"
gas_overlay = "tritium"
moles_visible = MOLES_GAS_VISIBLE
dangerous = TRUE
fusion_power = 1
rarity = 300
/datum/gas/bz
id = "bz"
specific_heat = 20
name = "BZ"
dangerous = TRUE
fusion_power = 8
rarity = 400
/datum/gas/stimulum
id = "stim"
specific_heat = 5
name = "Stimulum"
fusion_power = 7
rarity = 1
/datum/gas/pluoxium
id = "pluox"
specific_heat = 80
name = "Pluoxium"
fusion_power = 10
rarity = 200
/datum/gas/miasma
id = "miasma"
specific_heat = 20
fusion_power = 50
name = "Miasma"
gas_overlay = "miasma"
moles_visible = MOLES_GAS_VISIBLE * 60
rarity = 250
/datum/gas/methane
id = "methane"
specific_heat = 30
name = "Methane"
rarity = 320
/datum/gas/methyl_bromide
id = "methyl_bromide"
specific_heat = 42
name = "Methyl Bromide"
dangerous = TRUE
rarity = 310
/obj/effect/overlay/gas
icon = 'icons/effects/atmospherics.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE // should only appear in vis_contents, but to be safe
layer = FLY_LAYER
appearance_flags = TILE_BOUND
vis_flags = NONE
/obj/effect/overlay/gas/New(state, alph)
. = ..()
icon_state = state
alpha = alph
@@ -27,4 +27,4 @@
/datum/gas_mixture/immutable/cloner/populate()
..()
set_moles(/datum/gas/nitrogen, MOLES_O2STANDARD + MOLES_N2STANDARD)
set_moles(GAS_N2, MOLES_O2STANDARD + MOLES_N2STANDARD)
+218 -121
View File
@@ -8,13 +8,6 @@
if(initial(reaction.exclude))
continue
reaction = new r
var/datum/gas/reaction_key
for (var/req in reaction.min_requirements)
if (ispath(req))
var/datum/gas/req_gas = req
if (!reaction_key || initial(reaction_key.rarity) > initial(req_gas.rarity))
reaction_key = req_gas
reaction.major_gas = reaction_key
. += reaction
sortTim(., /proc/cmp_gas_reaction)
@@ -26,7 +19,6 @@
//when in doubt, use MINIMUM_MOLE_COUNT.
var/list/min_requirements
var/list/max_requirements
var/major_gas //the highest rarity gas used in the reaction.
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"
@@ -49,7 +41,7 @@
id = "nobstop"
/datum/gas_reaction/nobliumsupression/init_reqs()
min_requirements = list(/datum/gas/hypernoblium = REACTION_OPPRESSION_THRESHOLD)
min_requirements = list(GAS_HYPERNOB = REACTION_OPPRESSION_THRESHOLD)
/datum/gas_reaction/nobliumsupression/react()
return STOP_REACTIONS
@@ -61,7 +53,7 @@
id = "vapor"
/datum/gas_reaction/water_vapor/init_reqs()
min_requirements = list(/datum/gas/water_vapor = MOLES_GAS_VISIBLE)
min_requirements = list(GAS_H2O = MOLES_GAS_VISIBLE)
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
var/turf/open/location = isturf(holder) ? holder : null
@@ -70,7 +62,7 @@
if(location && location.freon_gas_act())
. = REACTING
else if(location && location.water_vapor_gas_act())
air.adjust_moles(/datum/gas/water_vapor,-MOLES_GAS_VISIBLE)
air.adjust_moles(GAS_H2O,-MOLES_GAS_VISIBLE)
. = REACTING
// no test cause it's entirely based on location
@@ -84,10 +76,22 @@
/datum/gas_reaction/tritfire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
/datum/gas/tritium = MINIMUM_MOLE_COUNT,
/datum/gas/oxygen = MINIMUM_MOLE_COUNT
GAS_TRITIUM = MINIMUM_MOLE_COUNT,
GAS_O2 = MINIMUM_MOLE_COUNT
)
/proc/fire_expose(turf/open/location, datum/gas_mixture/air, temperature)
if(istype(location) && 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)
/proc/radiation_burn(turf/open/location, energy_released)
if(istype(location) && prob(10))
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
/datum/gas_reaction/tritfire/react(datum/gas_mixture/air, datum/holder)
var/energy_released = 0
var/old_heat_capacity = air.heat_capacity()
@@ -97,20 +101,20 @@
var/turf/open/location = isturf(holder) ? holder : null
var/burned_fuel = 0
if(air.get_moles(/datum/gas/oxygen) < air.get_moles(/datum/gas/tritium))
burned_fuel = air.get_moles(/datum/gas/oxygen)/TRITIUM_BURN_OXY_FACTOR
air.adjust_moles(/datum/gas/tritium, -burned_fuel)
if(air.get_moles(GAS_O2) < air.get_moles(GAS_TRITIUM))
burned_fuel = air.get_moles(GAS_O2)/TRITIUM_BURN_OXY_FACTOR
air.adjust_moles(GAS_TRITIUM, -burned_fuel)
else
burned_fuel = air.get_moles(/datum/gas/tritium)*TRITIUM_BURN_TRIT_FACTOR
air.adjust_moles(/datum/gas/tritium, -air.get_moles(/datum/gas/tritium)/TRITIUM_BURN_TRIT_FACTOR)
air.adjust_moles(/datum/gas/oxygen,-air.get_moles(/datum/gas/tritium))
burned_fuel = air.get_moles(GAS_TRITIUM)*TRITIUM_BURN_TRIT_FACTOR
air.adjust_moles(GAS_TRITIUM, -air.get_moles(GAS_TRITIUM)/TRITIUM_BURN_TRIT_FACTOR)
air.adjust_moles(GAS_O2,-air.get_moles(GAS_TRITIUM))
if(burned_fuel)
energy_released += (FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel)
if(location && prob(10) && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) //woah there let's not crash the server
radiation_pulse(location, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR)
air.adjust_moles(/datum/gas/water_vapor, burned_fuel/TRITIUM_BURN_OXY_FACTOR)
air.adjust_moles(GAS_H2O, burned_fuel/TRITIUM_BURN_OXY_FACTOR)
cached_results["fire"] += burned_fuel
@@ -133,8 +137,8 @@
/datum/gas_reaction/tritfire/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/tritium,50)
G.set_moles(/datum/gas/oxygen,50)
G.set_moles(GAS_TRITIUM,50)
G.set_moles(GAS_O2,50)
G.set_temperature(500)
var/result = G.react()
if(result != REACTING)
@@ -152,8 +156,8 @@
/datum/gas_reaction/plasmafire/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST,
/datum/gas/plasma = MINIMUM_MOLE_COUNT,
/datum/gas/oxygen = MINIMUM_MOLE_COUNT
GAS_PLASMA = MINIMUM_MOLE_COUNT,
GAS_O2 = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/plasmafire/react(datum/gas_mixture/air, datum/holder)
@@ -178,21 +182,21 @@
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
if(temperature_scale > 0)
oxygen_burn_rate = OXYGEN_BURN_RATE_BASE - temperature_scale
if(air.get_moles(/datum/gas/oxygen) / air.get_moles(/datum/gas/plasma) > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
if(air.get_moles(GAS_O2) / air.get_moles(GAS_PLASMA) > SUPER_SATURATION_THRESHOLD) //supersaturation. Form Tritium.
super_saturation = TRUE
if(air.get_moles(/datum/gas/oxygen) > air.get_moles(/datum/gas/plasma)*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (air.get_moles(/datum/gas/plasma)*temperature_scale)/PLASMA_BURN_RATE_DELTA
if(air.get_moles(GAS_O2) > air.get_moles(GAS_PLASMA)*PLASMA_OXYGEN_FULLBURN)
plasma_burn_rate = (air.get_moles(GAS_PLASMA)*temperature_scale)/PLASMA_BURN_RATE_DELTA
else
plasma_burn_rate = (temperature_scale*(air.get_moles(/datum/gas/oxygen)/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
plasma_burn_rate = (temperature_scale*(air.get_moles(GAS_O2)/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
plasma_burn_rate = min(plasma_burn_rate,air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/oxygen)/oxygen_burn_rate) //Ensures matter is conserved properly
air.set_moles(/datum/gas/plasma, QUANTIZE(air.get_moles(/datum/gas/plasma) - plasma_burn_rate))
air.set_moles(/datum/gas/oxygen, QUANTIZE(air.get_moles(/datum/gas/oxygen) - (plasma_burn_rate * oxygen_burn_rate)))
plasma_burn_rate = min(plasma_burn_rate,air.get_moles(GAS_PLASMA),air.get_moles(GAS_O2)/oxygen_burn_rate) //Ensures matter is conserved properly
air.set_moles(GAS_PLASMA, QUANTIZE(air.get_moles(GAS_PLASMA) - plasma_burn_rate))
air.set_moles(GAS_O2, QUANTIZE(air.get_moles(GAS_O2) - (plasma_burn_rate * oxygen_burn_rate)))
if (super_saturation)
air.adjust_moles(/datum/gas/tritium, plasma_burn_rate)
air.adjust_moles(GAS_TRITIUM, plasma_burn_rate)
else
air.adjust_moles(/datum/gas/carbon_dioxide, plasma_burn_rate)
air.adjust_moles(GAS_CO2, plasma_burn_rate)
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
@@ -217,8 +221,8 @@
/datum/gas_reaction/plasmafire/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/plasma,50)
G.set_moles(/datum/gas/oxygen,50)
G.set_moles(GAS_PLASMA,50)
G.set_moles(GAS_O2,50)
G.set_volume(1000)
G.set_temperature(500)
var/result = G.react()
@@ -226,21 +230,114 @@
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.reaction_results["fire"])
return list("success" = FALSE, "message" = "Plasma fires aren't setting fire results correctly!")
if(!G.get_moles(/datum/gas/carbon_dioxide))
if(!G.get_moles(GAS_CO2))
return list("success" = FALSE, "message" = "Plasma fires aren't making CO2!")
G.clear()
G.set_moles(/datum/gas/plasma,10)
G.set_moles(/datum/gas/oxygen,1000)
G.set_moles(GAS_PLASMA,10)
G.set_moles(GAS_O2,1000)
G.set_temperature(500)
result = G.react()
if(!G.get_moles(/datum/gas/tritium))
if(!G.get_moles(GAS_TRITIUM))
return list("success" = FALSE, "message" = "Plasma fires aren't making trit!")
return ..()
/datum/gas_reaction/genericfire
priority = -3 // very last reaction
name = "Combustion"
id = "genericfire"
/datum/gas_reaction/genericfire/init_reqs()
var/lowest_fire_temp = INFINITY
var/list/fire_temperatures = GLOB.gas_data.fire_temperatures
for(var/gas in fire_temperatures)
lowest_fire_temp = min(lowest_fire_temp, fire_temperatures[gas])
var/lowest_oxi_temp = INFINITY
var/list/oxidation_temperatures = GLOB.gas_data.oxidation_temperatures
for(var/gas in oxidation_temperatures)
lowest_oxi_temp = min(lowest_oxi_temp, oxidation_temperatures[gas])
min_requirements = list(
"TEMP" = max(lowest_oxi_temp, lowest_fire_temp),
"FIRE_REAGENTS" = MINIMUM_MOLE_COUNT
)
// no requirements, always runs
// bad idea? maybe
// this is overridden by auxmos but, hey, good idea to have it readable
/datum/gas_reaction/genericfire/react(datum/gas_mixture/air, datum/holder)
var/temperature = air.return_temperature()
var/list/oxidation_temps = GLOB.gas_data.oxidation_temperatures
var/list/oxidation_rates = GLOB.gas_data.oxidation_rates
var/oxidation_power = 0
var/list/burn_results = list()
var/list/fuels = list()
var/list/oxidizers = list()
var/list/fuel_rates = GLOB.gas_data.fire_burn_rates
var/list/fuel_temps = GLOB.gas_data.fire_temperatures
var/total_fuel = 0
var/energy_released = 0
for(var/G in air.get_gases())
var/oxidation_temp = oxidation_temps[G]
if(oxidation_temp && oxidation_temp > temperature)
var/temperature_scale = max(0, 1-(temperature / oxidation_temp))
var/amt = air.get_moles(G) * temperature_scale
oxidizers[G] = amt
oxidation_power += amt * oxidation_rates[G]
else
var/fuel_temp = fuel_temps[G]
if(fuel_temp && fuel_temp > temperature)
var/amt = (air.get_moles(G) / fuel_rates[G]) * max(0, 1-(temperature / fuel_temp))
fuels[G] = amt // we have to calculate the actual amount we're using after we get all oxidation together
total_fuel += amt
if(oxidation_power <= 0 || total_fuel <= 0)
return NO_REACTION
var/oxidation_ratio = oxidation_power / total_fuel
if(oxidation_ratio > 1)
for(var/oxidizer in oxidizers)
oxidizers[oxidizer] /= oxidation_ratio
else if(oxidation_ratio < 1)
for(var/fuel in fuels)
fuels[fuel] *= oxidation_ratio
fuels += oxidizers
var/list/fire_products = GLOB.gas_data.fire_products
var/list/fire_enthalpies = GLOB.gas_data.fire_enthalpies
for(var/fuel in fuels + oxidizers)
var/amt = fuels[fuel]
if(!burn_results[fuel])
burn_results[fuel] = 0
burn_results[fuel] -= amt
energy_released += amt * fire_enthalpies[fuel]
for(var/product in fire_products[fuel])
if(!burn_results[product])
burn_results[product] = 0
burn_results[product] += amt
var/final_energy = air.thermal_energy() + energy_released
for(var/result in burn_results)
air.adjust_moles(result, burn_results[result])
air.set_temperature(final_energy / air.heat_capacity())
var/list/cached_results = air.reaction_results
cached_results["fire"] = min(total_fuel, oxidation_power) * 2
return cached_results["fire"] ? REACTING : NO_REACTION
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again!
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
//6 reworks
/proc/fusion_ball(datum/holder, reaction_energy, instability)
var/turf/open/location
if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
var/datum/pipeline/fusion_pipenet = holder
location = get_turf(pick(fusion_pipenet.members))
else
location = get_turf(holder)
if(location)
var/particle_chance = ((PARTICLE_CHANCE_CONSTANT)/(reaction_energy-PARTICLE_CHANCE_CONSTANT)) + 1//Asymptopically approaches 100% as the energy of the reaction goes up.
if(prob(PERCENT(particle_chance)))
location.fire_nuclear_particle()
var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + FUSION_RAD_MAX,0)
radiation_pulse(location,rad_power)
/datum/gas_reaction/fusion
exclude = FALSE
priority = 2
@@ -250,9 +347,9 @@
/datum/gas_reaction/fusion/init_reqs()
min_requirements = list(
"TEMP" = FUSION_TEMPERATURE_THRESHOLD,
/datum/gas/tritium = FUSION_TRITIUM_MOLES_USED,
/datum/gas/plasma = FUSION_MOLE_THRESHOLD,
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
GAS_TRITIUM = FUSION_TRITIUM_MOLES_USED,
GAS_PLASMA = FUSION_MOLE_THRESHOLD,
GAS_CO2 = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
var/turf/open/location
@@ -268,12 +365,12 @@
var/list/cached_scan_results = air.analyzer_results
var/old_heat_capacity = air.heat_capacity()
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
var/initial_plasma = air.get_moles(/datum/gas/plasma)
var/initial_carbon = air.get_moles(/datum/gas/carbon_dioxide)
var/initial_plasma = air.get_moles(GAS_PLASMA)
var/initial_carbon = air.get_moles(GAS_CO2)
var/scale_factor = (air.return_volume())/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.return_volume()-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/gas_power = 0
var/list/gas_fusion_powers = GLOB.meta_gas_fusions
var/list/gas_fusion_powers = GLOB.gas_data.fusion_powers
for (var/gas_id in air.get_gases())
gas_power += (gas_fusion_powers[gas_id]*air.get_moles(gas_id))
var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
@@ -287,9 +384,9 @@
carbon = MODULUS(carbon - plasma, toroidal_size)
air.set_moles(/datum/gas/plasma, plasma*scale_factor + FUSION_MOLE_THRESHOLD) //Scales the gases back up
air.set_moles(/datum/gas/carbon_dioxide , carbon*scale_factor + FUSION_MOLE_THRESHOLD)
var/delta_plasma = initial_plasma - air.get_moles(/datum/gas/plasma)
air.set_moles(GAS_PLASMA, plasma*scale_factor + FUSION_MOLE_THRESHOLD) //Scales the gases back up
air.set_moles(GAS_CO2 , carbon*scale_factor + FUSION_MOLE_THRESHOLD)
var/delta_plasma = initial_plasma - air.get_moles(GAS_PLASMA)
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
@@ -298,17 +395,17 @@
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
air.set_moles(/datum/gas/plasma,initial_plasma)
air.set_moles(/datum/gas/carbon_dioxide, initial_carbon)
air.set_moles(GAS_PLASMA,initial_plasma)
air.set_moles(GAS_CO2, initial_carbon)
return NO_REACTION
air.adjust_moles(/datum/gas/tritium, -FUSION_TRITIUM_MOLES_USED)
air.adjust_moles(GAS_TRITIUM, -FUSION_TRITIUM_MOLES_USED)
//The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
if(reaction_energy > 0)
air.adjust_moles(/datum/gas/oxygen, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(/datum/gas/nitrous_oxide, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_O2, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_NITROUS, FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT))
else
air.adjust_moles(/datum/gas/bz, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(/datum/gas/nitryl, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_BZ, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
air.adjust_moles(GAS_NITRYL, FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT))
if(reaction_energy)
if(location)
@@ -325,10 +422,10 @@
/datum/gas_reaction/fusion/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/carbon_dioxide,300)
G.set_moles(/datum/gas/plasma,1000)
G.set_moles(/datum/gas/tritium,100.61)
G.set_moles(/datum/gas/nitryl,1)
G.set_moles(GAS_CO2,300)
G.set_moles(GAS_PLASMA,1000)
G.set_moles(GAS_TRITIUM,100.61)
G.set_moles(GAS_NITRYL,1)
G.set_temperature(15000)
G.set_volume(1000)
var/result = G.react()
@@ -337,11 +434,11 @@
if(abs(G.analyzer_results["fusion"] - 3) > 0.0000001)
var/instability = G.analyzer_results["fusion"]
return list("success" = FALSE, "message" = "Fusion is not calculating analyzer results correctly, should be 3.000000045, is instead [instability]")
if(abs(G.get_moles(/datum/gas/plasma) - 850.616) > 0.5)
var/plas = G.get_moles(/datum/gas/plasma)
if(abs(G.get_moles(GAS_PLASMA) - 850.616) > 0.5)
var/plas = G.get_moles(GAS_PLASMA)
return list("success" = FALSE, "message" = "Fusion is not calculating plasma correctly, should be 850.616, is instead [plas]")
if(abs(G.get_moles(/datum/gas/carbon_dioxide) - 1699.384) > 0.5)
var/co2 = G.get_moles(/datum/gas/carbon_dioxide)
if(abs(G.get_moles(GAS_CO2) - 1699.384) > 0.5)
var/co2 = G.get_moles(GAS_CO2)
return list("success" = FALSE, "message" = "Fusion is not calculating co2 correctly, should be 1699.384, is instead [co2]")
if(abs(G.return_temperature() - 27600) > 200) // calculating this manually sucks dude
var/temp = G.return_temperature()
@@ -355,9 +452,9 @@
/datum/gas_reaction/nitrylformation/init_reqs()
min_requirements = list(
/datum/gas/oxygen = 20,
/datum/gas/nitrogen = 20,
/datum/gas/nitrous_oxide = 5,
GAS_O2 = 20,
GAS_N2 = 20,
GAS_NITROUS = 5,
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST*25
)
@@ -365,13 +462,13 @@
var/temperature = air.return_temperature()
var/old_heat_capacity = air.heat_capacity()
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),air.get_moles(/datum/gas/oxygen),air.get_moles(/datum/gas/nitrogen))
var/heat_efficency = min(temperature/(FIRE_MINIMUM_TEMPERATURE_TO_EXIST*100),air.get_moles(GAS_O2),air.get_moles(GAS_N2))
var/energy_used = heat_efficency*NITRYL_FORMATION_ENERGY
if ((air.get_moles(/datum/gas/oxygen) - heat_efficency < 0 )|| (air.get_moles(/datum/gas/nitrogen) - heat_efficency < 0)) //Shouldn't produce gas from nothing.
if ((air.get_moles(GAS_O2) - heat_efficency < 0 )|| (air.get_moles(GAS_N2) - heat_efficency < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
air.adjust_moles(/datum/gas/oxygen, -heat_efficency)
air.adjust_moles(/datum/gas/nitrogen, -heat_efficency)
air.adjust_moles(/datum/gas/nitryl, heat_efficency*2)
air.adjust_moles(GAS_O2, -heat_efficency)
air.adjust_moles(GAS_N2, -heat_efficency)
air.adjust_moles(GAS_NITRYL, heat_efficency*2)
if(energy_used > 0)
var/new_heat_capacity = air.heat_capacity()
@@ -381,15 +478,15 @@
/datum/gas_reaction/nitrylformation/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/oxygen,30)
G.set_moles(/datum/gas/nitrogen,30)
G.set_moles(/datum/gas/nitrous_oxide,10)
G.set_moles(GAS_O2,30)
G.set_moles(GAS_N2,30)
G.set_moles(GAS_NITROUS,10)
G.set_volume(1000)
G.set_temperature(150000)
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.get_moles(/datum/gas/nitryl) < 0.8)
if(!G.get_moles(GAS_NITRYL) < 0.8)
return list("success" = FALSE, "message" = "Nitryl isn't being generated correctly!")
return ..()
@@ -400,8 +497,8 @@
/datum/gas_reaction/bzformation/init_reqs()
min_requirements = list(
/datum/gas/nitrous_oxide = 10,
/datum/gas/plasma = 10
GAS_NITROUS = 10,
GAS_PLASMA = 10
)
@@ -409,16 +506,16 @@
var/temperature = air.return_temperature()
var/pressure = air.return_pressure()
var/old_heat_capacity = air.heat_capacity()
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(air.get_moles(/datum/gas/plasma)/air.get_moles(/datum/gas/nitrous_oxide),1))),air.get_moles(/datum/gas/nitrous_oxide),air.get_moles(/datum/gas/plasma)/2)
var/reaction_efficency = min(1/((pressure/(0.1*ONE_ATMOSPHERE))*(max(air.get_moles(GAS_PLASMA)/air.get_moles(GAS_NITROUS),1))),air.get_moles(GAS_NITROUS),air.get_moles(GAS_PLASMA)/2)
var/energy_released = 2*reaction_efficency*FIRE_CARBON_ENERGY_RELEASED
if ((air.get_moles(/datum/gas/nitrous_oxide) - reaction_efficency < 0 )|| (air.get_moles(/datum/gas/plasma) - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
if ((air.get_moles(GAS_NITROUS) - reaction_efficency < 0 )|| (air.get_moles(GAS_PLASMA) - (2*reaction_efficency) < 0) || energy_released <= 0) //Shouldn't produce gas from nothing.
return NO_REACTION
air.adjust_moles(/datum/gas/bz, reaction_efficency)
if(reaction_efficency == air.get_moles(/datum/gas/nitrous_oxide))
air.adjust_moles(/datum/gas/bz, -min(pressure,1))
air.adjust_moles(/datum/gas/oxygen, min(pressure,1))
air.adjust_moles(/datum/gas/nitrous_oxide, -reaction_efficency)
air.adjust_moles(/datum/gas/plasma, -2*reaction_efficency)
air.adjust_moles(GAS_BZ, reaction_efficency)
if(reaction_efficency == air.get_moles(GAS_NITROUS))
air.adjust_moles(GAS_BZ, -min(pressure,1))
air.adjust_moles(GAS_O2, min(pressure,1))
air.adjust_moles(GAS_NITROUS, -reaction_efficency)
air.adjust_moles(GAS_PLASMA, -2*reaction_efficency)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min((reaction_efficency**2)*BZ_RESEARCH_SCALE),BZ_RESEARCH_MAX_AMOUNT)
@@ -430,14 +527,14 @@
/datum/gas_reaction/bzformation/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/plasma,15)
G.set_moles(/datum/gas/nitrous_oxide,15)
G.set_moles(GAS_PLASMA,15)
G.set_moles(GAS_NITROUS,15)
G.set_volume(1000)
G.set_temperature(10)
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.get_moles(/datum/gas/bz) < 4) // efficiency is 4.0643 and bz generation == efficiency
if(!G.get_moles(GAS_BZ) < 4) // efficiency is 4.0643 and bz generation == efficiency
return list("success" = FALSE, "message" = "Nitryl isn't being generated correctly!")
return ..()
@@ -448,23 +545,23 @@
/datum/gas_reaction/stimformation/init_reqs()
min_requirements = list(
/datum/gas/tritium = 30,
/datum/gas/plasma = 10,
/datum/gas/bz = 20,
/datum/gas/nitryl = 30,
GAS_TRITIUM = 30,
GAS_PLASMA = 10,
GAS_BZ = 20,
GAS_NITRYL = 30,
"TEMP" = STIMULUM_HEAT_SCALE/2)
/datum/gas_reaction/stimformation/react(datum/gas_mixture/air)
var/old_heat_capacity = air.heat_capacity()
var/heat_scale = min(air.return_temperature()/STIMULUM_HEAT_SCALE,air.get_moles(/datum/gas/tritium),air.get_moles(/datum/gas/plasma),air.get_moles(/datum/gas/nitryl))
var/heat_scale = min(air.return_temperature()/STIMULUM_HEAT_SCALE,air.get_moles(GAS_TRITIUM),air.get_moles(GAS_PLASMA),air.get_moles(GAS_NITRYL))
var/stim_energy_change = heat_scale + STIMULUM_FIRST_RISE*(heat_scale**2) - STIMULUM_FIRST_DROP*(heat_scale**3) + STIMULUM_SECOND_RISE*(heat_scale**4) - STIMULUM_ABSOLUTE_DROP*(heat_scale**5)
if ((air.get_moles(/datum/gas/tritium) - heat_scale < 0 )|| (air.get_moles(/datum/gas/plasma) - heat_scale < 0) || (air.get_moles(/datum/gas/nitryl) - heat_scale < 0)) //Shouldn't produce gas from nothing.
if ((air.get_moles(GAS_TRITIUM) - heat_scale < 0 )|| (air.get_moles(GAS_PLASMA) - heat_scale < 0) || (air.get_moles(GAS_NITRYL) - heat_scale < 0)) //Shouldn't produce gas from nothing.
return NO_REACTION
air.adjust_moles(/datum/gas/stimulum, heat_scale/10)
air.adjust_moles(/datum/gas/tritium, -heat_scale)
air.adjust_moles(/datum/gas/plasma, -heat_scale)
air.adjust_moles(/datum/gas/nitryl, -heat_scale)
air.adjust_moles(GAS_STIMULUM, heat_scale/10)
air.adjust_moles(GAS_TRITIUM, -heat_scale)
air.adjust_moles(GAS_PLASMA, -heat_scale)
air.adjust_moles(GAS_NITRYL, -heat_scale)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, STIMULUM_RESEARCH_AMOUNT*max(stim_energy_change,0))
if(stim_energy_change)
@@ -476,17 +573,17 @@
/datum/gas_reaction/stimformation/test()
//above mentioned "strange pattern" is a basic quintic polynomial, it's fine, can calculate it manually
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/bz,30)
G.set_moles(/datum/gas/plasma,1000)
G.set_moles(/datum/gas/tritium,1000)
G.set_moles(/datum/gas/nitryl,1000)
G.set_moles(GAS_BZ,30)
G.set_moles(GAS_PLASMA,1000)
G.set_moles(GAS_TRITIUM,1000)
G.set_moles(GAS_NITRYL,1000)
G.set_volume(1000)
G.set_temperature(12998000) // yeah, really
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
if(!G.get_moles(/datum/gas/stimulum) < 900)
if(!G.get_moles(GAS_STIMULUM) < 900)
return list("success" = FALSE, "message" = "Stimulum isn't being generated correctly!")
return ..()
@@ -497,19 +594,19 @@
/datum/gas_reaction/nobliumformation/init_reqs()
min_requirements = list(
/datum/gas/nitrogen = 10,
/datum/gas/tritium = 5,
GAS_N2 = 10,
GAS_TRITIUM = 5,
"ENER" = NOBLIUM_FORMATION_ENERGY)
/datum/gas_reaction/nobliumformation/react(datum/gas_mixture/air)
var/old_heat_capacity = air.heat_capacity()
var/nob_formed = min((air.get_moles(/datum/gas/nitrogen)+air.get_moles(/datum/gas/tritium))/100,air.get_moles(/datum/gas/tritium)/10,air.get_moles(/datum/gas/nitrogen)/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(/datum/gas/bz),1)))
if ((air.get_moles(/datum/gas/tritium) - 10*nob_formed < 0) || (air.get_moles(/datum/gas/nitrogen) - 20*nob_formed < 0))
var/nob_formed = min((air.get_moles(GAS_N2)+air.get_moles(GAS_TRITIUM))/100,air.get_moles(GAS_TRITIUM)/10,air.get_moles(GAS_N2)/20)
var/energy_taken = nob_formed*(NOBLIUM_FORMATION_ENERGY/(max(air.get_moles(GAS_BZ),1)))
if ((air.get_moles(GAS_TRITIUM) - 10*nob_formed < 0) || (air.get_moles(GAS_N2) - 20*nob_formed < 0))
return NO_REACTION
air.adjust_moles(/datum/gas/tritium, -10*nob_formed)
air.adjust_moles(/datum/gas/nitrogen, -20*nob_formed)
air.adjust_moles(/datum/gas/hypernoblium,nob_formed)
air.adjust_moles(GAS_TRITIUM, -10*nob_formed)
air.adjust_moles(GAS_N2, -20*nob_formed)
air.adjust_moles(GAS_HYPERNOB,nob_formed)
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, nob_formed*NOBLIUM_RESEARCH_AMOUNT)
@@ -520,8 +617,8 @@
/datum/gas_reaction/nobliumformation/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/nitrogen,100)
G.set_moles(/datum/gas/tritium,500)
G.set_moles(GAS_N2,100)
G.set_moles(GAS_TRITIUM,500)
G.set_volume(1000)
G.set_temperature(5000000) // yeah, really
var/result = G.react()
@@ -540,18 +637,18 @@
/datum/gas_reaction/miaster/init_reqs()
min_requirements = list(
"TEMP" = FIRE_MINIMUM_TEMPERATURE_TO_EXIST+70,
/datum/gas/miasma = MINIMUM_MOLE_COUNT
GAS_MIASMA = MINIMUM_MOLE_COUNT
)
/datum/gas_reaction/miaster/react(datum/gas_mixture/air, datum/holder)
// As the name says it, it needs to be dry
if(air.get_moles(/datum/gas/water_vapor) && air.get_moles(/datum/gas/water_vapor)/air.total_moles() > 0.1)
if(air.get_moles(GAS_H2O) && air.get_moles(GAS_H2O)/air.total_moles() > 0.1)
return
//Replace miasma with oxygen
var/cleaned_air = min(air.get_moles(/datum/gas/miasma), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
air.adjust_moles(/datum/gas/miasma, -cleaned_air)
air.adjust_moles(/datum/gas/oxygen, cleaned_air)
var/cleaned_air = min(air.get_moles(GAS_MIASMA), 20 + (air.return_temperature() - FIRE_MINIMUM_TEMPERATURE_TO_EXIST - 70) / 20)
air.adjust_moles(GAS_MIASMA, -cleaned_air)
air.adjust_moles(GAS_O2, cleaned_air)
//Possibly burning a bit of organic matter through maillard reaction, so a *tiny* bit more heat would be understandable
air.set_temperature(air.return_temperature() + cleaned_air * 0.002)
@@ -559,16 +656,16 @@
/datum/gas_reaction/miaster/test()
var/datum/gas_mixture/G = new
G.set_moles(/datum/gas/miasma,1)
G.set_moles(GAS_MIASMA,1)
G.set_volume(1000)
G.set_temperature(450)
var/result = G.react()
if(result != REACTING)
return list("success" = FALSE, "message" = "Reaction didn't go at all!")
G.clear()
G.set_moles(/datum/gas/miasma,1)
G.set_moles(GAS_MIASMA,1)
G.set_temperature(450)
G.set_moles(/datum/gas/water_vapor,0.5)
G.set_moles(GAS_H2O,0.5)
result = G.react()
if(result != NO_REACTION)
return list("success" = FALSE, "message" = "Miasma sterilization not stopping due to water vapor correctly!")
@@ -9,14 +9,14 @@
/datum/gas_mixture/heat_capacity() //joules per kelvin
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
var/list/cached_gasheats = GLOB.gas_data.specific_heats
. = 0
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
/datum/gas_mixture/turf/heat_capacity() // Same as above except vacuums return HEAT_CAPACITY_VACUUM
var/list/cached_gases = gases
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
var/list/cached_gasheats = GLOB.gas_data.specific_heats
for(var/id in cached_gases)
. += cached_gases[id] * cached_gasheats[id]
if(!.)
@@ -56,20 +56,20 @@
return gases[gas_type]
/datum/gas_mixture/set_moles(gas_type, moles)
gases[gas_type] = moles
/datum/gas_mixture/scrub_into(datum/gas_mixture/target, list/gases)
/datum/gas_mixture/scrub_into(datum/gas_mixture/target, ratio, list/gases)
if(isnull(target))
return FALSE
var/list/removed_gases = target.gases
var/list/removed_gases = gases
//Filter it
var/datum/gas_mixture/filtered_out = new
var/list/filtered_gases = filtered_out.gases
filtered_out.temperature = removed.temperature
for(var/gas in filter_types & removed_gases)
filtered_gases[gas] = removed_gases[gas]
removed_gases[gas] = 0
merge(filtered_out)
filtered_gases[gas] = removed_gases[gas] * ratio
removed_gases[gas] = removed_gases[gas] * (1 - ratio)
target.merge(filtered_out)
/datum/gas_mixture/mark_immutable()
return
/datum/gas_mixture/get_gases()
@@ -208,7 +208,7 @@
var/delta
var/gas_heat_capacity
//and also cache this shit rq because that results in sanic speed for reasons byond explanation
var/list/cached_gasheats = GLOB.meta_gas_specific_heats
var/list/cached_gasheats = GLOB.gas_data.specific_heats
//GAS TRANSFER
for(var/id in cached_gases | sharer_gases) // transfer gases
+63 -63
View File
@@ -94,63 +94,63 @@
var/list/TLV = list( // Breathable air.
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
/datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
/datum/gas/water_vapor = new/datum/tlv/dangerous,
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
GAS_O2 = new/datum/tlv(16, 19, 40, 50), // Partial pressure, kpa
GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000),
GAS_CO2 = new/datum/tlv(-1, -1, 5, 10),
GAS_MIASMA = new/datum/tlv(-1, -1, 2, 5),
GAS_PLASMA = new/datum/tlv/dangerous,
GAS_NITROUS = new/datum/tlv/dangerous,
GAS_BZ = new/datum/tlv/dangerous,
GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
GAS_H2O = new/datum/tlv/dangerous,
GAS_TRITIUM = new/datum/tlv/dangerous,
GAS_STIMULUM = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 5, 6), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
GAS_METHANE = new/datum/tlv(-1, -1, 3, 6),
GAS_METHYL_BROMIDE = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/server // No checks here.
TLV = list(
"pressure" = new/datum/tlv/no_checks,
"temperature" = new/datum/tlv/no_checks,
/datum/gas/oxygen = new/datum/tlv/no_checks,
/datum/gas/nitrogen = new/datum/tlv/no_checks,
/datum/gas/carbon_dioxide = new/datum/tlv/no_checks,
/datum/gas/miasma = new/datum/tlv/no_checks,
/datum/gas/plasma = new/datum/tlv/no_checks,
/datum/gas/nitrous_oxide = new/datum/tlv/no_checks,
/datum/gas/bz = new/datum/tlv/no_checks,
/datum/gas/hypernoblium = new/datum/tlv/no_checks,
/datum/gas/water_vapor = new/datum/tlv/no_checks,
/datum/gas/tritium = new/datum/tlv/no_checks,
/datum/gas/stimulum = new/datum/tlv/no_checks,
/datum/gas/nitryl = new/datum/tlv/no_checks,
/datum/gas/pluoxium = new/datum/tlv/no_checks,
/datum/gas/methane = new/datum/tlv/no_checks,
/datum/gas/methyl_bromide = new/datum/tlv/no_checks
GAS_O2 = new/datum/tlv/no_checks,
GAS_N2 = new/datum/tlv/no_checks,
GAS_CO2 = new/datum/tlv/no_checks,
GAS_MIASMA = new/datum/tlv/no_checks,
GAS_PLASMA = new/datum/tlv/no_checks,
GAS_NITROUS = new/datum/tlv/no_checks,
GAS_BZ = new/datum/tlv/no_checks,
GAS_HYPERNOB = new/datum/tlv/no_checks,
GAS_H2O = new/datum/tlv/no_checks,
GAS_TRITIUM = new/datum/tlv/no_checks,
GAS_STIMULUM = new/datum/tlv/no_checks,
GAS_NITRYL = new/datum/tlv/no_checks,
GAS_PLUOXIUM = new/datum/tlv/no_checks,
GAS_METHANE = new/datum/tlv/no_checks,
GAS_METHYL_BROMIDE = new/datum/tlv/no_checks
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
TLV = list(
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(T0C-73.15, T0C-63.15, T0C, T0C+10),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
/datum/gas/miasma = new/datum/tlv/(-1, -1, 2, 5),
/datum/gas/plasma = new/datum/tlv/dangerous,
/datum/gas/nitrous_oxide = new/datum/tlv/dangerous,
/datum/gas/bz = new/datum/tlv/dangerous,
/datum/gas/hypernoblium = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
/datum/gas/water_vapor = new/datum/tlv/dangerous,
/datum/gas/tritium = new/datum/tlv/dangerous,
/datum/gas/stimulum = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
/datum/gas/nitryl = new/datum/tlv/dangerous,
/datum/gas/pluoxium = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
/datum/gas/methane = new/datum/tlv(-1, -1, 3, 6),
/datum/gas/methyl_bromide = new/datum/tlv/dangerous
GAS_O2 = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
GAS_N2 = new/datum/tlv(-1, -1, 1000, 1000),
GAS_CO2 = new/datum/tlv(-1, -1, 5, 10),
GAS_MIASMA = new/datum/tlv/(-1, -1, 2, 5),
GAS_PLASMA = new/datum/tlv/dangerous,
GAS_NITROUS = new/datum/tlv/dangerous,
GAS_BZ = new/datum/tlv/dangerous,
GAS_HYPERNOB = new/datum/tlv(-1, -1, 1000, 1000), // Hyper-Noblium is inert and nontoxic
GAS_H2O = new/datum/tlv/dangerous,
GAS_TRITIUM = new/datum/tlv/dangerous,
GAS_STIMULUM = new/datum/tlv(-1, -1, 1000, 1000), // Stimulum has only positive effects
GAS_NITRYL = new/datum/tlv/dangerous,
GAS_PLUOXIUM = new/datum/tlv(-1, -1, 1000, 1000), // Unlike oxygen, pluoxium does not fuel plasma/tritium fires
GAS_METHANE = new/datum/tlv(-1, -1, 3, 6),
GAS_METHYL_BROMIDE = new/datum/tlv/dangerous
)
/obj/machinery/airalarm/unlocked
@@ -298,7 +298,7 @@
continue
cur_tlv = TLV[gas_id]
data["environment_data"] += list(list(
"name" = GLOB.meta_gas_names[gas_id],
"name" = GLOB.gas_data.names[gas_id],
"value" = environment.get_moles(gas_id) / total_moles * 100,
"unit" = "%",
"danger_level" = cur_tlv.get_danger_level(environment.get_moles(gas_id) * partial_pressure)
@@ -368,11 +368,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 GLOB.meta_gas_names)
for(var/gas_id in GLOB.gas_data.names)
if(!(gas_id in TLV)) // We're not interested in this gas, it seems.
continue
selected = TLV[gas_id]
thresholds += list(list("name" = GLOB.meta_gas_names[gas_id], "settings" = list()))
thresholds += list(list("name" = GLOB.gas_data.names[gas_id], "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))
@@ -532,7 +532,7 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
"set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma),
"set_filters" = list(GAS_CO2, GAS_MIASMA),
"scrubbing" = 1,
"widenet" = 0,
))
@@ -547,19 +547,19 @@
send_signal(device_id, list(
"power" = 1,
"set_filters" = list(
/datum/gas/carbon_dioxide,
/datum/gas/miasma,
/datum/gas/plasma,
/datum/gas/water_vapor,
/datum/gas/hypernoblium,
/datum/gas/nitrous_oxide,
/datum/gas/nitryl,
/datum/gas/tritium,
/datum/gas/bz,
/datum/gas/stimulum,
/datum/gas/pluoxium,
/datum/gas/methane,
/datum/gas/methyl_bromide
GAS_CO2,
GAS_MIASMA,
GAS_PLASMA,
GAS_H2O,
GAS_HYPERNOB,
GAS_NITROUS,
GAS_NITRYL,
GAS_TRITIUM,
GAS_BZ,
GAS_STIMULUM,
GAS_PLUOXIUM,
GAS_METHANE,
GAS_METHYL_BROMIDE
),
"scrubbing" = 1,
"widenet" = 1,
@@ -587,7 +587,7 @@
for(var/device_id in A.air_scrub_names)
send_signal(device_id, list(
"power" = 1,
"set_filters" = list(/datum/gas/carbon_dioxide, /datum/gas/miasma),
"set_filters" = list(GAS_CO2, GAS_MIASMA),
"scrubbing" = 1,
"widenet" = 0,
))
@@ -39,6 +39,7 @@
var/construction_type
var/pipe_state //icon_state as a pipe item
var/on = FALSE
var/interacts_with_air = FALSE
/obj/machinery/atmospherics/examine(mob/user)
. = ..()
@@ -57,7 +58,10 @@
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70)
..()
if(process)
SSair.atmos_machinery += src
if(interacts_with_air)
SSair.atmos_air_machinery += src
else
SSair.atmos_machinery += src
SetInitDirections()
/obj/machinery/atmospherics/Destroy()
@@ -65,6 +69,7 @@
nullifyNode(i)
SSair.atmos_machinery -= src
SSair.atmos_air_machinery -= src
SSair.pipenets_needing_rebuilt -= src
dropContents()
@@ -15,6 +15,9 @@
desc = "Has a valve and pump attached to it. There are two ports."
level = 1
interacts_with_air = TRUE
var/frequency = 0
var/id = null
var/datum/radio_frequency/radio_connection
@@ -69,12 +72,7 @@
if(air1.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
//Removed can be null if there is no atmosphere in air1
if(!removed)
return
loc.assume_air(removed)
loc.assume_air_moles(air1, transfer_moles)
air_update_turf()
var/datum/pipeline/parent1 = parents[1]
@@ -90,11 +88,7 @@
moles_delta = min(moles_delta, (input_pressure_min - air2.return_pressure()) * our_multiplier)
if(moles_delta > 0)
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if (isnull(removed)) // in space
return
air2.merge(removed)
loc.transfer_air(air2, moles_delta)
air_update_turf()
var/datum/pipeline/parent2 = parents[2]
@@ -81,9 +81,7 @@
var/pressure_delta = target_pressure - output_starting_pressure
var/transfer_moles = pressure_delta*air2.return_volume()/(air1.return_temperature() * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
air2.merge(removed)
air1.transfer_to(air2,transfer_moles)
update_parents()
@@ -67,9 +67,7 @@
var/transfer_ratio = transfer_rate/air1.return_volume()
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
air2.merge(removed)
air1.transfer_ratio_to(air2,transfer_ratio)
update_parents()
@@ -120,14 +120,9 @@
times_lost++
var/shared_loss = lost/times_lost
var/datum/gas_mixture/to_release
for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i]
if(!to_release)
to_release = air.remove(shared_loss)
continue
to_release.merge(air.remove(shared_loss))
T.assume_air(to_release)
T.assume_air_moles(air, shared_loss)
air_update_turf(1)
/obj/machinery/atmospherics/components/proc/safe_input(var/title, var/text, var/default_set)
@@ -98,33 +98,11 @@
//Actually transfer the gas
if(transfer_ratio > 0)
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
if(!removed)
return
var/filtering = TRUE
if(!ispath(filter_type))
if(filter_type)
filter_type = gas_id2path(filter_type) //support for mappers so they don't need to type out paths
else
filtering = FALSE
if(filtering && removed.get_moles(filter_type))
var/datum/gas_mixture/filtered_out = new
filtered_out.set_temperature(removed.return_temperature())
filtered_out.set_moles(filter_type, removed.get_moles(filter_type))
removed.set_moles(filter_type, 0)
var/datum/gas_mixture/target = (air2.return_pressure() < 9000 ? air2 : air1)
target.merge(filtered_out)
if(filter_type && air2.return_pressure() <= 9000)
air1.scrub_into(air2, transfer_ratio, list(filter_type))
if(air3.return_pressure() <= 9000)
air3.merge(removed)
else
air1.merge(removed) // essentially just leaving it in
air1.transfer_ratio_to(air3, transfer_ratio)
update_parents()
@@ -145,9 +123,9 @@
data["max_rate"] = round(MAX_TRANSFER_RATE)
data["filter_types"] = list()
data["filter_types"] += list(list("name" = "Nothing", "path" = "", "selected" = !filter_type))
for(var/path in GLOB.meta_gas_ids)
data["filter_types"] += list(list("name" = GLOB.meta_gas_names[path], "id" = GLOB.meta_gas_ids[path], "selected" = (path == gas_id2path(filter_type))))
data["filter_types"] += list(list("name" = "Nothing", "id" = "", "selected" = !filter_type))
for(var/id in GLOB.gas_data.ids)
data["filter_types"] += list(list("name" = GLOB.gas_data.names[id], "id" = id, "selected" = (id == filter_type)))
return data
@@ -177,10 +155,10 @@
if("filter")
filter_type = null
var/filter_name = "nothing"
var/gas = gas_id2path(params["mode"])
if(gas in GLOB.meta_gas_names)
var/gas = params["mode"]
if(gas in GLOB.gas_data.names)
filter_type = gas
filter_name = GLOB.meta_gas_names[gas]
filter_name = GLOB.gas_data.names[gas]
investigate_log("was set to filter [filter_name] by [key_name(usr)]", INVESTIGATE_ATMOS)
. = TRUE
update_icon()
@@ -110,14 +110,12 @@
//Actually transfer the gas
if(transfer_moles1)
var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
air3.merge(removed1)
air1.transfer_to(air3, transfer_moles1)
var/datum/pipeline/parent1 = parents[1]
parent1.update = TRUE
if(transfer_moles2)
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
air3.merge(removed2)
air2.transfer_to(air3, transfer_moles2)
var/datum/pipeline/parent2 = parents[2]
parent2.update = TRUE
@@ -210,7 +210,7 @@
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
beaker.reagents.reaction(occupant, VAPOR)
air1.adjust_moles(/datum/gas/oxygen, -max(0,air1.get_moles(/datum/gas/oxygen) - 2 / efficiency)) //Let's use gas for this
air1.adjust_moles(GAS_O2, -max(0,air1.get_moles(GAS_O2) - 2 / efficiency)) //Let's use gas for this
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
reagent_transfer = 0
@@ -224,7 +224,7 @@
var/datum/gas_mixture/air1 = airs[1]
if(!nodes[1] || !airs[1] || air1.get_moles(/datum/gas/oxygen) < 5) // Turn off if the machine won't work.
if(!nodes[1] || !airs[1] || air1.get_moles(GAS_O2) < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
@@ -16,6 +16,7 @@
var/datum/radio_frequency/radio_connection
level = 1
interacts_with_air = TRUE
layer = GAS_SCRUBBER_LAYER
pipe_state = "injector"
@@ -65,11 +66,7 @@
var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
air_update_turf()
update_parents()
@@ -84,9 +81,7 @@
injecting = 1
if(air_contents.return_temperature() > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
loc.assume_air_ratio(air_contents, volume_rate / air_contents.return_volume())
update_parents()
flick("inje_inject", src)
@@ -6,6 +6,7 @@
can_unwrench = TRUE
level = 1
interacts_with_air = TRUE
layer = GAS_SCRUBBER_LAYER
pipe_state = "pvent"
@@ -29,23 +30,10 @@
var/pressure_delta = abs(external_pressure - internal_pressure)
if(pressure_delta > 0.5)
if(external_pressure < internal_pressure)
var/air_temperature = (external.return_temperature() > 0) ? external.return_temperature() : internal.return_temperature()
var/transfer_moles = (pressure_delta * external.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = internal.remove(transfer_moles)
external.merge(removed)
else
var/air_temperature = (internal.return_temperature() > 0) ? internal.return_temperature() : external.return_temperature()
var/transfer_moles = (pressure_delta * internal.return_volume()) / (air_temperature * R_IDEAL_GAS_EQUATION)
transfer_moles = min(transfer_moles, external.total_moles() * internal.return_volume() / external.return_volume())
var/datum/gas_mixture/removed = external.remove(transfer_moles)
if(isnull(removed))
return
internal.merge(removed)
equalize_all_gases_in_list(list(internal,external))
active = TRUE
active = internal.temperature_share(external, OPEN_HEAT_TRANSFER_COEFFICIENT) ? TRUE : active
active = internal.temperature_share(external, OPEN_HEAT_TRANSFER_COEFFICIENT) || active
if(active)
air_update_turf()
@@ -5,6 +5,7 @@
icon_state = "relief_valve-e-map"
can_unwrench = TRUE
interaction_flags_machine = INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
interacts_with_air = TRUE
var/opened = FALSE
var/open_pressure = ONE_ATMOSPHERE * 3
var/close_pressure = ONE_ATMOSPHERE
@@ -49,14 +50,11 @@
else if(!opened && our_pressure >= open_pressure)
opened = TRUE
update_icon_nopipes()
if(opened && air_contents.return_temperature() > 0)
if(opened)
var/datum/gas_mixture/environment = loc.return_air()
var/pressure_delta = our_pressure - environment.return_pressure()
var/transfer_moles = pressure_delta*200/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
if(transfer_moles > 0)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
var/pressure_delta = abs(our_pressure - environment.return_pressure())
if(pressure_delta > 0.1)
equalize_all_gases_in_list(list(air_contents,environment))
air_update_turf()
update_parents()
@@ -21,8 +21,8 @@
air_contents.set_volume(volume)
air_contents.set_temperature(T20C)
if(gas_type)
air_contents.set_moles(gas_type, AIR_CONTENTS)
name = "[name] ([GLOB.meta_gas_names[gas_type]])"
air_contents.set_moles(gas_type,AIR_CONTENTS)
name = "[name] ([GLOB.gas_data.names[gas_type]])"
setPipingLayer(piping_layer)
/obj/machinery/atmospherics/components/unary/tank/air
@@ -32,30 +32,30 @@
/obj/machinery/atmospherics/components/unary/tank/air/New()
..()
var/datum/gas_mixture/air_contents = airs[1]
air_contents.set_moles(/datum/gas/oxygen, AIR_CONTENTS * 0.21)
air_contents.set_moles(/datum/gas/nitrogen, AIR_CONTENTS * 0.79)
air_contents.set_moles(GAS_O2, AIR_CONTENTS * 0.21)
air_contents.set_moles(GAS_N2, AIR_CONTENTS * 0.79)
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
gas_type = /datum/gas/carbon_dioxide
gas_type = GAS_CO2
/obj/machinery/atmospherics/components/unary/tank/toxins
icon_state = "orange"
gas_type = /datum/gas/plasma
gas_type = GAS_PLASMA
/obj/machinery/atmospherics/components/unary/tank/nitrogen
icon_state = "red"
gas_type = /datum/gas/nitrogen
gas_type = GAS_N2
/obj/machinery/atmospherics/components/unary/tank/oxygen
icon_state = "blue"
gas_type = /datum/gas/oxygen
gas_type = GAS_O2
/obj/machinery/atmospherics/components/unary/tank/nitrous
icon_state = "red_white"
gas_type = /datum/gas/nitrous_oxide
gas_type = GAS_NITROUS
/obj/machinery/atmospherics/components/unary/tank/bz
gas_type = /datum/gas/bz
gas_type = GAS_BZ
// /obj/machinery/atmospherics/components/unary/tank/freon
// icon_state = "blue"
@@ -75,17 +75,17 @@
/obj/machinery/atmospherics/components/unary/tank/hypernoblium
icon_state = "blue"
gas_type = /datum/gas/hypernoblium
gas_type = GAS_HYPERNOB
/obj/machinery/atmospherics/components/unary/tank/miasma
gas_type = /datum/gas/miasma
gas_type = GAS_MIASMA
/obj/machinery/atmospherics/components/unary/tank/nitryl
gas_type = /datum/gas/nitryl
gas_type = GAS_NITRYL
/obj/machinery/atmospherics/components/unary/tank/pluoxium
icon_state = "blue"
gas_type = /datum/gas/pluoxium
gas_type = GAS_PLUOXIUM
// /obj/machinery/atmospherics/components/unary/tank/proto_nitrate
// icon_state = "red"
@@ -93,14 +93,14 @@
/obj/machinery/atmospherics/components/unary/tank/stimulum
icon_state = "red"
gas_type = /datum/gas/stimulum
gas_type = GAS_STIMULUM
/obj/machinery/atmospherics/components/unary/tank/tritium
gas_type = /datum/gas/tritium
gas_type = GAS_TRITIUM
/obj/machinery/atmospherics/components/unary/tank/water_vapor
icon_state = "grey"
gas_type = /datum/gas/water_vapor
gas_type = GAS_H2O
// /obj/machinery/atmospherics/components/unary/tank/zauker
// gas_type = /datum/gas/zauker
@@ -15,6 +15,8 @@
level = 1
layer = GAS_SCRUBBER_LAYER
interacts_with_air = TRUE
var/id_tag = null
var/pump_direction = RELEASING
@@ -107,9 +109,7 @@
if(air_contents.return_temperature() > 0)
var/transfer_moles = pressure_delta*environment.return_volume()/(air_contents.return_temperature() * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
loc.assume_air_moles(air_contents, transfer_moles)
air_update_turf()
else // external -> internal
@@ -122,11 +122,7 @@
moles_delta = min(moles_delta, (internal_pressure_bound - air_contents.return_pressure()) * our_multiplier)
if(moles_delta > 0)
var/datum/gas_mixture/removed = loc.remove_air(moles_delta)
if (isnull(removed)) // in space
return
air_contents.merge(removed)
loc.transfer_air(air_contents, moles_delta)
air_update_turf()
update_parents()
@@ -13,10 +13,12 @@
level = 1
layer = GAS_SCRUBBER_LAYER
interacts_with_air = TRUE
var/id_tag = null
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
var/filter_types = list(/datum/gas/carbon_dioxide)
var/filter_types = list(GAS_CO2)
var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
var/list/turf/adjacent_turfs = list()
@@ -33,11 +35,6 @@
if(!id_tag)
id_tag = assign_uid_vents()
for(var/f in filter_types)
if(istext(f))
filter_types -= f
filter_types += gas_id2path(f)
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
var/area/A = get_base_area(src)
if (A)
@@ -97,8 +94,8 @@
return FALSE
var/list/f_types = list()
for(var/path in GLOB.meta_gas_ids)
f_types += list(list("gas_id" = GLOB.meta_gas_ids[path], "gas_name" = GLOB.meta_gas_names[path], "enabled" = (path in filter_types)))
for(var/id in GLOB.gas_data.ids)
f_types += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in filter_types)))
var/datum/signal/signal = new(list(
"tag" = id_tag,
@@ -150,32 +147,17 @@
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE || !islist(filter_types))
return FALSE
if(scrubbing & SCRUBBING)
var/transfer_moles = min(1, volume_rate/environment.return_volume())*environment.total_moles()
environment.scrub_into(air_contents, volume_rate/environment.return_volume(), filter_types)
//Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
//Nothing left to remove from the tile
if(isnull(removed))
return FALSE
removed.scrub_into(air_contents, filter_types)
//Remix the resulting gases
tile.assume_air(removed)
tile.air_update_turf()
else //Just siphoning all air
var/transfer_moles = environment.total_moles()*(volume_rate/environment.return_volume())
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
air_contents.merge(removed)
environment.transfer_ratio_to(air_contents, volume_rate/environment.return_volume())
tile.air_update_turf()
update_parents()
@@ -222,12 +204,12 @@
investigate_log(" was toggled to [scrubbing ? "scrubbing" : "siphon"] mode by [key_name(signal_sender)]",INVESTIGATE_ATMOS)
if("toggle_filter" in signal.data)
filter_types ^= gas_id2path(signal.data["toggle_filter"])
filter_types ^= signal.data["toggle_filter"]
if("set_filters" in signal.data)
filter_types = list()
for(var/gas in signal.data["set_filters"])
filter_types += gas_id2path(gas)
filter_types += gas
if("init" in signal.data)
name = signal.data["init"]
@@ -241,25 +241,4 @@
/datum/pipeline/proc/reconcile_air()
var/list/datum/gas_mixture/GL = get_all_connected_airs()
var/total_thermal_energy = 0
var/total_heat_capacity = 0
var/datum/gas_mixture/total_gas_mixture = new(0)
for(var/i in GL)
var/datum/gas_mixture/G = i
total_gas_mixture.set_volume(total_gas_mixture.return_volume() + G.return_volume())
total_gas_mixture.merge(G)
total_thermal_energy += G.thermal_energy()
total_heat_capacity += G.heat_capacity()
total_gas_mixture.set_temperature(total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0)
if(total_gas_mixture.return_volume() > 0)
//Update individual gas_mixtures by volume ratio
for(var/i in GL)
var/datum/gas_mixture/G = i
G.copy_from(total_gas_mixture)
G.multiply(G.return_volume()/total_gas_mixture.return_volume())
equalize_all_gases_in_list(GL)
@@ -12,6 +12,7 @@
icon_state = "miner"
density = FALSE
resistance_flags = INDESTRUCTIBLE|ACID_PROOF|FIRE_PROOF
interacts_with_air = TRUE
var/spawn_id = null
var/spawn_temp = T20C
var/spawn_mol = MOLES_CELLSTANDARD * 10
@@ -117,7 +118,7 @@
on_overlay.color = overlay_color
add_overlay(on_overlay)
/obj/machinery/atmospherics/miner/process()
/obj/machinery/atmospherics/miner/process_atmos()
update_power()
check_operation()
if(active && !broken)
@@ -144,34 +145,34 @@
/obj/machinery/atmospherics/miner/n2o
name = "\improper N2O Gas Miner"
overlay_color = "#FFCCCC"
spawn_id = /datum/gas/nitrous_oxide
spawn_id = GAS_NITROUS
/obj/machinery/atmospherics/miner/nitrogen
name = "\improper N2 Gas Miner"
overlay_color = "#CCFFCC"
spawn_id = /datum/gas/nitrogen
spawn_id = GAS_N2
/obj/machinery/atmospherics/miner/oxygen
name = "\improper O2 Gas Miner"
overlay_color = "#007FFF"
spawn_id = /datum/gas/oxygen
spawn_id = GAS_O2
/obj/machinery/atmospherics/miner/toxins
name = "\improper Plasma Gas Miner"
overlay_color = "#FF0000"
spawn_id = /datum/gas/plasma
spawn_id = GAS_PLASMA
/obj/machinery/atmospherics/miner/carbon_dioxide
name = "\improper CO2 Gas Miner"
overlay_color = "#CDCDCD"
spawn_id = /datum/gas/carbon_dioxide
spawn_id = GAS_CO2
/obj/machinery/atmospherics/miner/bz
name = "\improper BZ Gas Miner"
overlay_color = "#FAFF00"
spawn_id = /datum/gas/bz
spawn_id = GAS_BZ
/obj/machinery/atmospherics/miner/water_vapor
name = "\improper Water Vapor Gas Miner"
overlay_color = "#99928E"
spawn_id = /datum/gas/water_vapor
spawn_id = GAS_H2O
@@ -6,6 +6,7 @@
buckle_lying = 1
var/icon_temperature = T20C //stop small changes in temperature causing icon refresh
resistance_flags = LAVA_PROOF | FIRE_PROOF
interacts_with_air = TRUE
/obj/machinery/atmospherics/pipe/heat_exchanging/Initialize()
. = ..()
@@ -54,6 +54,9 @@
/obj/machinery/atmospherics/pipe/remove_air(amount)
return parent.air.remove(amount)
/obj/machinery/atmospherics/pipe/remove_air_ratio(ratio)
return parent.air.remove_ratio(ratio)
/obj/machinery/atmospherics/pipe/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/pipe_meter))
var/obj/item/pipe_meter/meter = W
@@ -28,7 +28,7 @@
// var/pressure_limit = 50000
var/temperature_resistance = 1000 + T0C
var/starter_temp
var/starter_temp = T20C
// Prototype vars
var/prototype = FALSE
var/valve_timer = null
@@ -74,37 +74,37 @@
name = "n2 canister"
desc = "Nitrogen. Reportedly useful for something."
icon_state = "red"
gas_type = /datum/gas/nitrogen
gas_type = GAS_N2
/obj/machinery/portable_atmospherics/canister/oxygen
name = "o2 canister"
desc = "Oxygen. Necessary for human life."
icon_state = "blue"
gas_type = /datum/gas/oxygen
gas_type = GAS_O2
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
name = "co2 canister"
desc = "Carbon dioxide. What the fuck is carbon dioxide?"
icon_state = "black"
gas_type = /datum/gas/carbon_dioxide
gas_type = GAS_CO2
/obj/machinery/portable_atmospherics/canister/toxins
name = "plasma canister"
desc = "Plasma. The reason YOU are here. Highly toxic."
icon_state = "orange"
gas_type = /datum/gas/plasma
gas_type = GAS_PLASMA
/obj/machinery/portable_atmospherics/canister/bz
name = "\improper BZ canister"
desc = "BZ. A powerful hallucinogenic nerve agent."
icon_state = "purple"
gas_type = /datum/gas/bz
gas_type = GAS_BZ
/obj/machinery/portable_atmospherics/canister/nitrous_oxide
name = "n2o canister"
desc = "Nitrous oxide. Known to cause drowsiness."
icon_state = "redws"
gas_type = /datum/gas/nitrous_oxide
gas_type = GAS_NITROUS
/obj/machinery/portable_atmospherics/canister/air
name = "air canister"
@@ -115,57 +115,57 @@
name = "tritium canister"
desc = "Tritium. Inhalation might cause irradiation."
icon_state = "green"
gas_type = /datum/gas/tritium
gas_type = GAS_TRITIUM
/obj/machinery/portable_atmospherics/canister/nob
name = "hyper-noblium canister"
desc = "Hyper-Noblium. More noble than all other gases."
icon_state = "freon"
gas_type = /datum/gas/hypernoblium
gas_type = GAS_HYPERNOB
/obj/machinery/portable_atmospherics/canister/nitryl
name = "nitryl canister"
desc = "Nitryl. Feels great 'til the acid eats your lungs."
icon_state = "brown"
gas_type = /datum/gas/nitryl
gas_type = GAS_NITRYL
/obj/machinery/portable_atmospherics/canister/stimulum
name = "stimulum canister"
desc = "Stimulum. High energy gas, high energy people."
icon_state = "darkpurple"
gas_type = /datum/gas/stimulum
gas_type = GAS_STIMULUM
/obj/machinery/portable_atmospherics/canister/pluoxium
name = "pluoxium canister"
desc = "Pluoxium. Like oxygen, but more bang for your buck."
icon_state = "darkblue"
gas_type = /datum/gas/pluoxium
gas_type = GAS_PLUOXIUM
/obj/machinery/portable_atmospherics/canister/water_vapor
name = "water vapor canister"
desc = "Water vapor. We get it, you vape."
icon_state = "water_vapor"
gas_type = /datum/gas/water_vapor
gas_type = GAS_H2O
filled = 1
/obj/machinery/portable_atmospherics/canister/miasma
name = "miasma canister"
desc = "Miasma. Makes you wish your nose were blocked."
icon_state = "miasma"
gas_type = /datum/gas/miasma
gas_type = GAS_MIASMA
filled = 1
/obj/machinery/portable_atmospherics/canister/methane
name = "methane canister"
desc = "Methane. The simplest of hydrocarbons. Non-toxic but highly flammable."
icon_state = "greyblackred"
gas_type = /datum/gas/methane
gas_type = GAS_METHANE
/obj/machinery/portable_atmospherics/canister/methyl_bromide
name = "methyl bromide canister"
desc = "Methyl bromide. A potent toxin to most, essential for the Kharmaan to live."
icon_state = "purplecyan"
gas_type = /datum/gas/methyl_bromide
gas_type = GAS_METHYL_BROMIDE
/obj/machinery/portable_atmospherics/canister/proc/get_time_left()
if(timing)
@@ -198,7 +198,7 @@
name = "prototype canister"
desc = "A prototype canister for a prototype bike, what could go wrong?"
icon_state = "proto"
gas_type = /datum/gas/oxygen
gas_type = GAS_O2
filled = 1
release_pressure = ONE_ATMOSPHERE*2
@@ -217,13 +217,13 @@
// air_contents.add_gas(gas_type)
if(starter_temp)
air_contents.set_temperature(starter_temp)
if(!air_contents.return_volume())
CRASH("Auxtools is failing somehow! Gas with pointer [air_contents._extools_pointer_gasmixture] is not valid.")
air_contents.set_moles(gas_type,(maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
if(starter_temp)
air_contents.set_temperature(starter_temp)
/obj/machinery/portable_atmospherics/canister/air/create_gas()
air_contents.set_moles(/datum/gas/oxygen, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(GAS_O2, (O2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
air_contents.set_moles(GAS_N2, (N2STANDARD * maximum_pressure * filled) * air_contents.return_volume() / (R_IDEAL_GAS_EQUATION * air_contents.return_temperature()))
/obj/machinery/portable_atmospherics/canister/update_icon_state()
if(stat & BROKEN)
@@ -287,9 +287,8 @@
/obj/machinery/portable_atmospherics/canister/proc/canister_break()
disconnect()
var/datum/gas_mixture/expelled_gas = air_contents.remove(air_contents.total_moles())
var/turf/T = get_turf(src)
T.assume_air(expelled_gas)
T.assume_air(air_contents)
air_update_turf()
obj_break()
@@ -434,10 +433,10 @@
var/list/danger = list()
for(var/id in air_contents.get_gases())
var/gas = air_contents.get_moles(id)
if(!GLOB.meta_gas_dangers[id])
if(!GLOB.gas_data.flags[id] & GAS_FLAG_DANGEROUS)
continue
if(gas > (GLOB.meta_gas_visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[GLOB.meta_gas_names[id]] = gas //ex. "plasma" = 20
if(gas > (GLOB.gas_data.visibility[id] || MOLES_GAS_VISIBLE)) //if moles_visible is undefined, default to default visibility
danger[GLOB.gas_data.names[id]] = gas //ex. "plasma" = 20
if(danger.len)
message_admins("[ADMIN_LOOKUPFLW(usr)] opened a canister that contains the following at [ADMIN_VERBOSEJMP(src)]:")
@@ -16,7 +16,7 @@
/obj/machinery/portable_atmospherics/New()
..()
SSair.atmos_machinery += src
SSair.atmos_air_machinery += src
air_contents = new(volume)
air_contents.set_temperature(T20C)
@@ -24,7 +24,7 @@
return 1
/obj/machinery/portable_atmospherics/Destroy()
SSair.atmos_machinery -= src
SSair.atmos_air_machinery -= src
disconnect()
qdel(air_contents)
@@ -112,8 +112,8 @@
if("power")
on = !on
if(on && !holding)
var/plasma = air_contents.get_moles(/datum/gas/plasma)
var/n2o = air_contents.get_moles(/datum/gas/nitrous_oxide)
var/plasma = air_contents.get_moles(GAS_PLASMA)
var/n2o = air_contents.get_moles(GAS_NITROUS)
if(n2o || plasma)
message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [ADMIN_VERBOSEJMP(src)]")
log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [AREACOORD(src)]")
@@ -10,7 +10,7 @@
var/use_overlays = TRUE
volume = 1000
var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor)
var/list/scrubbing = list(GAS_PLASMA, GAS_CO2, GAS_NITROUS, GAS_BZ, GAS_NITRYL, GAS_TRITIUM, GAS_HYPERNOB, GAS_H2O)
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
@@ -42,14 +42,7 @@
scrub(T.return_air())
/obj/machinery/portable_atmospherics/scrubber/proc/scrub(var/datum/gas_mixture/mixture)
var/transfer_moles = min(1, volume_rate / mixture.return_volume()) * mixture.total_moles()
var/datum/gas_mixture/filtering = mixture.remove(transfer_moles) // Remove part of the mixture to filter.
if(!filtering)
return
filtering.scrub_into(air_contents,scrubbing)
mixture.merge(filtering) // Returned the cleaned gas.
mixture.scrub_into(air_contents, volume_rate / mixture.return_volume(), scrubbing)
if(!holding)
air_update_turf()
@@ -76,8 +69,8 @@
data["id_tag"] = -1 //must be defined in order to reuse code between portable and vent scrubbers
data["filter_types"] = list()
for(var/path in GLOB.meta_gas_ids)
data["filter_types"] += list(list("gas_id" = GLOB.meta_gas_ids[path], "gas_name" = GLOB.meta_gas_names[path], "enabled" = (path in scrubbing)))
for(var/id in GLOB.gas_data.ids)
data["filter_types"] += list(list("gas_id" = id, "gas_name" = GLOB.gas_data.names[id], "enabled" = (id in scrubbing)))
if(holding)
data["holding"] = list()
@@ -100,7 +93,7 @@
holding = null
. = TRUE
if("toggle_filter")
scrubbing ^= gas_id2path(params["val"])
scrubbing ^= params["val"]
. = TRUE
update_icon()
@@ -156,13 +156,13 @@
/turf/open/floor/plasteel/dark/snowdin
initial_gas_mix = FROZEN_ATMOS
planetary_atmos = 1
temperature = 180
initial_temperature = 180
/turf/open/lava/plasma
name = "liquid plasma"
desc = "A flowing stream of chilled liquid plasma. You probably shouldn't get in."
icon_state = "liquidplasma"
initial_gas_mix = "o2=0;n2=82;plasma=24;TEMP=120"
initial_gas_mix = "n2=82;plasma=24;TEMP=120"
baseturfs = /turf/open/lava/plasma
slowdown = 2
+3 -3
View File
@@ -4,7 +4,7 @@
reward = 7500
wanted_types = list(/obj/item/tank)
var/moles_required = 20 // A full tank is 28 moles, but CentCom ignores that fact.
var/gas_type = /datum/gas/pluoxium
var/gas_type = GAS_PLUOXIUM
/datum/bounty/item/engineering/gas/applies_to(obj/O)
if(!..())
@@ -15,12 +15,12 @@
//datum/bounty/item/engineering/gas/nitryl_tank
// name = "Full Tank of Nitryl"
// description = "The non-human staff of Station 88 has been volunteered to test performance enhancing drugs. Ship them a tank full of Nitryl so they can get started."
// gas_type = /datum/gas/nitryl
// gas_type = GAS_NITRYL
/datum/bounty/item/engineering/gas/tritium_tank
name = "Full Tank of Tritium"
description = "Station 49 is looking to kickstart their research program. Ship them a tank full of Tritium."
gas_type = /datum/gas/tritium
gas_type = GAS_TRITIUM
/datum/bounty/item/engineering/pacman
name = "P.A.C.M.A.N.-type portable generator"
+7 -7
View File
@@ -169,13 +169,13 @@
/datum/export/large/gas_canister/get_cost(obj/O)
var/obj/machinery/portable_atmospherics/canister/C = O
var/worth = 10
worth += C.air_contents.get_moles(/datum/gas/bz)*3
worth += C.air_contents.get_moles(/datum/gas/stimulum)*25
worth += C.air_contents.get_moles(/datum/gas/hypernoblium)*20
worth += C.air_contents.get_moles(/datum/gas/miasma)*2
worth += C.air_contents.get_moles(/datum/gas/tritium)*7
worth += C.air_contents.get_moles(/datum/gas/pluoxium)*6
worth += C.air_contents.get_moles(/datum/gas/nitryl)*10
worth += C.air_contents.get_moles(GAS_BZ)*3
worth += C.air_contents.get_moles(GAS_STIMULUM)*25
worth += C.air_contents.get_moles(GAS_HYPERNOB)*20
worth += C.air_contents.get_moles(GAS_MIASMA)*2
worth += C.air_contents.get_moles(GAS_TRITIUM)*7
worth += C.air_contents.get_moles(GAS_PLUOXIUM)*6
worth += C.air_contents.get_moles(GAS_NITRYL)*10
return worth
+4 -4
View File
@@ -171,7 +171,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
GM.set_moles(/datum/gas/oxygen, max(GM.get_moles(/datum/gas/oxygen) - severity * holder.energy, 0))
GM.set_moles(GAS_O2, max(GM.get_moles(GAS_O2) - severity * holder.energy, 0))
/datum/spacevine_mutation/nitro_eater
name = "nitrogen consuming"
@@ -183,7 +183,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
GM.set_moles(/datum/gas/nitrogen, max(GM.get_moles(/datum/gas/nitrogen) - severity * holder.energy, 0))
GM.set_moles(GAS_N2, max(GM.get_moles(GAS_N2) - severity * holder.energy, 0))
/datum/spacevine_mutation/carbondioxide_eater
name = "CO2 consuming"
@@ -195,7 +195,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
GM.set_moles(/datum/gas/carbon_dioxide, max(GM.get_moles(/datum/gas/carbon_dioxide) - severity * holder.energy, 0))
GM.set_moles(GAS_CO2, max(GM.get_moles(GAS_CO2) - severity * holder.energy, 0))
/datum/spacevine_mutation/plasma_eater
name = "toxins consuming"
@@ -207,7 +207,7 @@
var/turf/open/floor/T = holder.loc
if(istype(T))
var/datum/gas_mixture/GM = T.air
GM.set_moles(/datum/gas/plasma, max(GM.get_moles(/datum/gas/plasma) - severity * holder.energy, 0))
GM.set_moles(GAS_PLASMA, max(GM.get_moles(GAS_PLASMA) - severity * holder.energy, 0))
/datum/spacevine_mutation/thorns
name = "thorny"
-1
View File
@@ -139,7 +139,6 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list(
if(toupdate.len)
for(var/turf/T1 in toupdate)
CALCULATE_ADJACENT_TURFS(T1)
SSair.add_to_active(T1,1)
return copiedobjs
+1 -1
View File
@@ -61,7 +61,7 @@
var/datum/effect_system/spark_spread/s = new
s.set_up(3, 1, T)
s.start()
T.temperature = 5000
T.set_temperature(5000)
T.hotspot_expose(50000, 50000, TRUE, TRUE)
+1 -1
View File
@@ -58,7 +58,7 @@
return
var/datum/gas_mixture/stank = new
stank.adjust_moles(/datum/gas/miasma,(yield + 6)*7*0.02) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
stank.adjust_moles(GAS_MIASMA,(yield + 6)*0.14) // 0.14 = 7*0.02, this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses
stank.set_temperature(T20C) // without this the room would eventually freeze and miasma mining would be easier
T.assume_air(stank)
T.air_update_turf()
+1 -1
View File
@@ -226,7 +226,7 @@
var/turf/open/O = loc
if(O.air)
var/datum/gas_mixture/loc_air = O.air
if(loc_air.get_moles(/datum/gas/oxygen) > 13)
if(loc_air.get_moles(GAS_O2) > 13)
return TRUE
return FALSE
@@ -131,11 +131,10 @@
var/pressure_delta = target_pressure - target_air.return_pressure()
if(pressure_delta > 0.1)
var/transfer_moles = (pressure_delta*target_air.return_volume()/(source_air.return_temperature() * R_IDEAL_GAS_EQUATION))*PUMP_EFFICIENCY
var/datum/gas_mixture/removed = source_air.remove(transfer_moles)
if(istype(snowflake)) //Snowflake check for tanks specifically, because tank ruptures are handled in a very snowflakey way that expects all tank interactions to be handled via the tank's procs
snowflake.assume_air(removed)
snowflake.assume_air_moles(source_air, transfer_moles)
else
target_air.merge(removed)
source_air.transfer_to(target_air, transfer_moles)
// - volume pump - // **Works**
@@ -183,12 +182,10 @@
//The second part of the min caps the pressure built by the volume pumps to the max pump pressure
var/transfer_ratio = min(transfer_rate,target_air.return_volume()*PUMP_MAX_PRESSURE/source_air.return_pressure())/source_air.return_volume()
var/datum/gas_mixture/removed = source_air.remove_ratio(transfer_ratio * PUMP_EFFICIENCY)
if(istype(snowflake))
snowflake.assume_air(removed)
snowflake.assume_air_ratio(source_air, transfer_ratio * PUMP_EFFICIENCY)
else
target_air.merge(removed)
source_air.transfer_ratio_to(target_air, transfer_ratio * PUMP_EFFICIENCY)
// - gas vent - // **works**
@@ -376,7 +373,7 @@
for(var/filtered_gas in removed.get_gases())
//Get the name of the gas and see if it is in the list
if(GLOB.meta_gas_names[filtered_gas] in wanted)
if(GLOB.gas_data.names[filtered_gas] in wanted)
//The gas that is put in all the filtered out gases
filtered_out.set_temperature(removed.return_temperature())
filtered_out.set_moles(filtered_gas, removed.get_moles(filtered_gas))
@@ -468,16 +465,12 @@
var/snowflakecheck = istype(gas_output, /obj/item/tank)
var/datum/gas_mixture/mix = source_1_gases.remove(transfer_moles * gas_percentage)
if(snowflakecheck)
gas_output.assume_air(mix)
gas_output.assume_air_moles(source_1_gases, transfer_moles * gas_percentage)
gas_output.assume_air_moles(source_2_gases, transfer_moles * (1-gas_percentage))
else
output_gases.merge(mix)
mix = source_2_gases.remove(transfer_moles * (1-gas_percentage))
if(snowflakecheck)
gas_output.assume_air(mix)
else
output_gases.merge(mix)
source_1_gases.transfer_to(output_gases, transfer_moles * gas_percentage)
source_2_gases.transfer_to(output_gases, transfer_moles * (1-gas_percentage))
// - integrated tank - // **works**
@@ -1163,7 +1163,7 @@
var/list/gas_names = list()
var/list/gas_amounts = list()
for(var/id in air_contents.get_gases())
var/name = GLOB.meta_gas_names[id]
var/name = GLOB.gas_data.names[id]
var/amt = round(air_contents.get_moles(id), 0.001)
gas_names.Add(name)
gas_amounts.Add(amt)
@@ -292,10 +292,7 @@
if(!source_air || !target_air)
return
var/datum/gas_mixture/removed = source_air.remove(gas_per_throw)
if(!removed)
return
target_air.merge(removed)
source_air.transfer_to(target_air, gas_per_throw)
// If the item is in a grabber circuit we'll update the grabber's outputs after we've thrown it.
var/obj/item/integrated_circuit/manipulation/grabber/G = A.loc
-1
View File
@@ -152,7 +152,6 @@
locate(min(T.x + width + 1, world.maxx), min(T.y + height + 1, world.maxy), T.z))
for(var/i in border)
var/turf/turf_to_disable = i
SSair.remove_from_active(turf_to_disable) //stop processing turfs along the border to prevent runtimes, we return it in initTemplateBounds()
turf_to_disable.atmos_adjacent_turfs?.Cut()
if(annihilate == MAP_TEMPLATE_ANNIHILATE_PRELOAD)
+5 -5
View File
@@ -16,20 +16,20 @@
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
var/Toxins_pp = (breath.get_moles(GAS_PLASMA)/breath.total_moles())*breath_pressure
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
adjustPlasma(breath.get_moles(/datum/gas/plasma)*250)
adjustPlasma(breath.get_moles(GAS_PLASMA)*250)
throw_alert("alien_tox", /obj/screen/alert/alien_tox)
toxins_used = breath.get_moles(/datum/gas/plasma)
toxins_used = breath.get_moles(GAS_PLASMA)
else
clear_alert("alien_tox")
//Breathe in toxins and out oxygen
breath.adjust_moles(/datum/gas/plasma, -toxins_used)
breath.adjust_moles(/datum/gas/oxygen, toxins_used)
breath.adjust_moles(GAS_PLASMA, -toxins_used)
breath.adjust_moles(GAS_O2, toxins_used)
//BREATH TEMPERATURE
handle_breath_temperature(breath)
@@ -37,7 +37,7 @@
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment)
if(environment.total_moles())
if(environment.get_moles(/datum/gas/oxygen) >= 1) //Same threshhold that extinguishes fire
if(environment.get_moles(GAS_O2) >= 1) //Same threshhold that extinguishes fire
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
+26 -24
View File
@@ -115,16 +115,18 @@
breath = loc_as_obj.handle_internal_lifeform(src, BREATH_VOLUME)
else if(isturf(loc)) //Breathe from loc as turf
var/breath_moles = 0
var/breath_ratio = 0
if(environment)
breath_moles = environment.total_moles()*BREATH_PERCENTAGE
breath_ratio = BREATH_VOLUME/environment.return_volume()
breath = loc.remove_air(breath_moles)
breath = loc.remove_air_ratio(breath_ratio)
else //Breathe from loc as obj again
if(istype(loc, /obj/))
var/obj/loc_as_obj = loc
loc_as_obj.handle_internal_lifeform(src,0)
if(breath)
breath.set_volume(BREATH_VOLUME)
check_breath(breath)
if(breath)
@@ -163,11 +165,11 @@
var/SA_para_min = 1
var/SA_sleep_min = 5
var/oxygen_used = 0
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
var/O2_partialpressure = (breath.get_moles(/datum/gas/oxygen)/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath.get_moles(/datum/gas/plasma)/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath.get_moles(/datum/gas/carbon_dioxide)/breath.total_moles())*breath_pressure
var/moles = breath.total_moles()
var/breath_pressure = (moles*R_IDEAL_GAS_EQUATION*breath.return_temperature())/BREATH_VOLUME
var/O2_partialpressure = ((breath.get_moles(GAS_O2)/moles)*breath_pressure) + (((breath.get_moles(GAS_PLUOXIUM)*8)/moles)*breath_pressure)
var/Toxins_partialpressure = (breath.get_moles(GAS_PLASMA)/moles)*breath_pressure
var/CO2_partialpressure = (breath.get_moles(GAS_CO2)/moles)*breath_pressure
//OXYGEN
@@ -191,7 +193,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1
oxygen_used = breath.get_moles(/datum/gas/oxygen)*ratio
oxygen_used = breath.get_moles(GAS_O2)*ratio
else
adjustOxyLoss(3)
failed_last_breath = 1
@@ -203,12 +205,12 @@
o2overloadtime = 0 //reset our counter for this too
if(health >= crit_threshold)
adjustOxyLoss(-5)
oxygen_used = breath.get_moles(/datum/gas/oxygen)
oxygen_used = breath.get_moles(GAS_O2)
clear_alert("not_enough_oxy")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
breath.adjust_moles(/datum/gas/oxygen, -oxygen_used)
breath.adjust_moles(/datum/gas/carbon_dioxide, oxygen_used)
breath.adjust_moles(GAS_O2, -oxygen_used)
breath.adjust_moles(GAS_CO2, oxygen_used)
//CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max)
@@ -227,15 +229,15 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_tox_max) * 10
var/ratio = (breath.get_moles(GAS_PLASMA)/safe_tox_max) * 10
adjustToxLoss(clamp(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
clear_alert("too_much_tox")
//NITROUS OXIDE
if(breath.get_moles(/datum/gas/nitrous_oxide))
var/SA_partialpressure = (breath.get_moles(/datum/gas/nitrous_oxide)/breath.total_moles())*breath_pressure
if(breath.get_moles(GAS_NITROUS))
var/SA_partialpressure = (breath.get_moles(GAS_NITROUS)/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
Unconscious(60)
if(SA_partialpressure > SA_sleep_min)
@@ -248,26 +250,26 @@
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "chemical_euphoria")
//BZ (Facepunch port of their Agent B)
if(breath.get_moles(/datum/gas/bz))
var/bz_partialpressure = (breath.get_moles(/datum/gas/bz)/breath.total_moles())*breath_pressure
if(breath.get_moles(GAS_BZ))
var/bz_partialpressure = (breath.get_moles(GAS_BZ)/breath.total_moles())*breath_pressure
if(bz_partialpressure > 1)
hallucination += 10
else if(bz_partialpressure > 0.01)
hallucination += 5
//TRITIUM
if(breath.get_moles(/datum/gas/tritium))
var/tritium_partialpressure = (breath.get_moles(/datum/gas/tritium)/breath.total_moles())*breath_pressure
if(breath.get_moles(GAS_TRITIUM))
var/tritium_partialpressure = (breath.get_moles(GAS_TRITIUM)/breath.total_moles())*breath_pressure
radiation += tritium_partialpressure/10
//NITRYL
if(breath.get_moles(/datum/gas/nitryl))
var/nitryl_partialpressure = (breath.get_moles(/datum/gas/nitryl)/breath.total_moles())*breath_pressure
if(breath.get_moles(GAS_NITRYL))
var/nitryl_partialpressure = (breath.get_moles(GAS_NITRYL)/breath.total_moles())*breath_pressure
adjustFireLoss(nitryl_partialpressure/4)
//MIASMA
if(breath.get_moles(/datum/gas/miasma))
var/miasma_partialpressure = (breath.get_moles(/datum/gas/miasma)/breath.total_moles())*breath_pressure
if(breath.get_moles(GAS_MIASMA))
var/miasma_partialpressure = (breath.get_moles(GAS_MIASMA)/breath.total_moles())*breath_pressure
if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE)
if(prob(0.05 * miasma_partialpressure))
@@ -365,7 +367,7 @@
var/datum/gas_mixture/stank = new
stank.set_moles(/datum/gas/miasma,0.1)
stank.set_moles(GAS_MIASMA,0.1)
stank.set_temperature(BODYTEMP_NORMAL)
+1 -1
View File
@@ -141,7 +141,7 @@
ExtinguishMob()
return
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(!G.get_moles(/datum/gas/oxygen, 1))
if(!G.get_moles(GAS_O2, 1))
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return
var/turf/location = get_turf(src)
+1 -1
View File
@@ -995,7 +995,7 @@
loc_temp = obj_temp
else if(isspaceturf(get_turf(src)))
var/turf/heat_turf = get_turf(src)
loc_temp = heat_turf.temperature
loc_temp = heat_turf.return_temperature()
return loc_temp
/mob/living/proc/get_standard_pixel_x_offset(lying = 0)
@@ -575,7 +575,7 @@
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0.01)
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%<br>"
dat += "[GLOB.gas_data.names[id]]: [round(gas_level*100)]%<br>"
dat += "Temperature: [round(environment.return_temperature()-T0C)]&deg;C<br>"
dat += "<a href='byond://?src=[REF(src)];software=atmosensor;sub=0'>Refresh Reading</a> <br>"
dat += "<br>"
@@ -753,6 +753,12 @@
else
return null
/mob/living/simple_animal/bot/mulebot/remove_air_ratio(ratio)
if(loc)
return loc.remove_air_ratio(ratio)
else
return null
/mob/living/simple_animal/bot/mulebot/do_resist()
. = ..()
if(load)
@@ -50,12 +50,12 @@
if(isopenturf(loc))
var/turf/open/T = src.loc
if(T.air)
var/co2 = T.air.get_moles(/datum/gas/carbon_dioxide)
var/co2 = T.air.get_moles(GAS_CO2)
if(co2 > 0)
if(prob(25))
var/amt = min(co2, 9)
T.air.adjust_moles(/datum/gas/carbon_dioxide, -amt)
T.atmos_spawn_air("o2=[amt]")
T.air.adjust_moles(GAS_CO2, -amt)
T.atmos_spawn_air("o2=[amt];TEMP=293.15")
/mob/living/simple_animal/hostile/tree/AttackingTarget()
. = ..()
@@ -264,10 +264,10 @@
var/turf/open/ST = src.loc
if(ST.air)
var/tox = ST.air.get_moles(/datum/gas/plasma)
var/oxy = ST.air.get_moles(/datum/gas/oxygen)
var/n2 = ST.air.get_moles(/datum/gas/nitrogen)
var/co2 = ST.air.get_moles(/datum/gas/carbon_dioxide)
var/tox = ST.air.get_moles(GAS_PLASMA)
var/oxy = ST.air.get_moles(GAS_O2)
var/n2 = ST.air.get_moles(GAS_N2)
var/co2 = ST.air.get_moles(GAS_CO2)
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
. = FALSE
@@ -129,7 +129,7 @@
Tempstun = 0
if(stat != DEAD)
var/bz_percentage = environment.total_moles() ? (environment.get_moles(/datum/gas/bz) / environment.total_moles()) : 0
var/bz_percentage = environment.total_moles() ? (environment.get_moles(GAS_BZ) / environment.total_moles()) : 0
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
if(stat == CONSCIOUS && stasis)
+1 -1
View File
@@ -70,7 +70,7 @@
t += "<span class='danger'>Temperature: [environment.return_temperature()] \n</span>"
for(var/id in environment.get_gases())
if(environment.get_moles(id))
t+="<span class='notice'>[GLOB.meta_gas_names[id]]: [environment.get_moles(id)] \n</span>"
t+="<span class='notice'>[GLOB.gas_data.names[id]]: [environment.get_moles(id)] \n</span>"
to_chat(usr, t)
@@ -31,7 +31,7 @@
for(var/id in env_gases)
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0)
airlist += list(list("name" = "[GLOB.meta_gas_names[id]]", "percentage" = round(gas_level*100, 0.01)))
airlist += list(list("name" = "[GLOB.gas_data.names[id]]", "percentage" = round(gas_level*100, 0.01)))
data["AirData"] = airlist
else
data["AirPressure"] = 0
@@ -139,13 +139,13 @@
var/amount = air.get_moles(gasid)
if(amount)
gasdata.Add(list(list(
"name"= GLOB.meta_gas_names[gasid],
"name"= GLOB.gas_data.names[gasid],
"amount" = round(100*amount/air.total_moles(),0.01))))
else
for(var/gasid in air.get_gases())
gasdata.Add(list(list(
"name"= GLOB.meta_gas_names[gasid],
"name"= GLOB.gas_data.names[gasid],
"amount" = 0)))
data["gases"] = gasdata
+9 -9
View File
@@ -47,29 +47,29 @@
if(!loaded_tank)
return
if(!bitcoinmining)
if(loaded_tank.air_contents.get_moles(/datum/gas/plasma) < 0.0001)
if(loaded_tank.air_contents.get_moles(GAS_PLASMA) < 0.0001)
investigate_log("<font color='red'>out of fuel</font>.", INVESTIGATE_SINGULO)
playsound(src, 'sound/machines/ding.ogg', 50, 1)
Radio.talk_into(src, "Insufficient plasma in [get_area(src)] [src], ejecting \the [loaded_tank].", FREQ_ENGINEERING)
eject()
else
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.get_moles(/datum/gas/plasma))
loaded_tank.air_contents.adjust_moles(/datum/gas/plasma, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, gasdrained)
var/gasdrained = min(powerproduction_drain*drainratio,loaded_tank.air_contents.get_moles(GAS_PLASMA))
loaded_tank.air_contents.adjust_moles(GAS_PLASMA, -gasdrained)
loaded_tank.air_contents.adjust_moles(GAS_TRITIUM, gasdrained)
var/power_produced = RAD_COLLECTOR_OUTPUT
add_avail(power_produced)
stored_power-=power_produced
else if(is_station_level(z) && SSresearch.science_tech)
if(!loaded_tank.air_contents.get_moles(/datum/gas/tritium) || !loaded_tank.air_contents.get_moles(/datum/gas/oxygen))
if(!loaded_tank.air_contents.get_moles(GAS_TRITIUM) || !loaded_tank.air_contents.get_moles(GAS_O2))
playsound(src, 'sound/machines/ding.ogg', 50, 1)
Radio.talk_into(src, "Insufficient oxygen and tritium in [get_area(src)] [src] to produce research points, ejecting \the [loaded_tank].", FREQ_ENGINEERING)
eject()
else
var/gasdrained = bitcoinproduction_drain*drainratio
loaded_tank.air_contents.adjust_moles(/datum/gas/tritium, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/oxygen, -gasdrained)
loaded_tank.air_contents.adjust_moles(/datum/gas/carbon_dioxide, gasdrained*2)
loaded_tank.air_contents.adjust_moles(GAS_TRITIUM, -gasdrained)
loaded_tank.air_contents.adjust_moles(GAS_O2, -gasdrained)
loaded_tank.air_contents.adjust_moles(GAS_CO2, gasdrained*2)
var/bitcoins_mined = stored_power*RAD_COLLECTOR_MINING_CONVERSION_RATE
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
if(D)
@@ -84,7 +84,7 @@
toggle_power()
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
"<span class='notice'>You turn the [src.name] [active? "on":"off"].</span>")
var/fuel = loaded_tank.air_contents.get_moles(/datum/gas/plasma)
var/fuel = loaded_tank.air_contents.get_moles(GAS_PLASMA)
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [key_name(user)]. [loaded_tank?"Fuel: [round(fuel/0.29)]%":"<font color='red'>It is empty</font>"].", INVESTIGATE_SINGULO)
return
else
+56 -56
View File
@@ -150,71 +150,71 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/gas_change_rate = 0.05
///The list of gases we will be interacting with in process_atoms()
var/list/gases_we_care_about = list(
/datum/gas/oxygen,
/datum/gas/water_vapor,
/datum/gas/plasma,
/datum/gas/carbon_dioxide,
/datum/gas/nitrous_oxide,
/datum/gas/nitrogen,
/datum/gas/pluoxium,
/datum/gas/tritium,
/datum/gas/bz,
GAS_O2,
GAS_H2O,
GAS_PLASMA,
GAS_CO2,
GAS_NITROUS,
GAS_N2,
GAS_PLUOXIUM,
GAS_TRITIUM,
GAS_BZ,
// /datum/gas/freon,
// /datum/gas/hydrogen,
)
///The list of gases mapped against their current comp. We use this to calculate different values the supermatter uses, like power or heat resistance. It doesn't perfectly match the air around the sm, instead moving up at a rate determined by gas_change_rate per call. Ranges from 0 to 1
var/list/gas_comp = list(
/datum/gas/oxygen = 0,
/datum/gas/water_vapor = 0,
/datum/gas/plasma = 0,
/datum/gas/carbon_dioxide = 0,
/datum/gas/nitrous_oxide = 0,
/datum/gas/nitrogen = 0,
/datum/gas/pluoxium = 0,
/datum/gas/tritium = 0,
/datum/gas/bz = 0,
GAS_O2 = 0,
GAS_H2O = 0,
GAS_PLASMA = 0,
GAS_CO2 = 0,
GAS_NITROUS = 0,
GAS_N2 = 0,
GAS_PLUOXIUM = 0,
GAS_TRITIUM = 0,
GAS_BZ = 0,
// /datum/gas/freon = 0,
// /datum/gas/hydrogen = 0,
)
///The list of gases mapped against their transmit values. We use it to determine the effect different gases have on radiation
var/list/gas_trans = list(
/datum/gas/oxygen = OXYGEN_TRANSMIT_MODIFIER,
/datum/gas/water_vapor = H2O_TRANSMIT_MODIFIER,
/datum/gas/plasma = PLASMA_TRANSMIT_MODIFIER,
/datum/gas/pluoxium = PLUOXIUM_TRANSMIT_MODIFIER,
/datum/gas/tritium = TRITIUM_TRANSMIT_MODIFIER,
/datum/gas/bz = BZ_TRANSMIT_MODIFIER,
GAS_O2 = OXYGEN_TRANSMIT_MODIFIER,
GAS_H2O = H2O_TRANSMIT_MODIFIER,
GAS_PLASMA = PLASMA_TRANSMIT_MODIFIER,
GAS_PLUOXIUM = PLUOXIUM_TRANSMIT_MODIFIER,
GAS_TRITIUM = TRITIUM_TRANSMIT_MODIFIER,
GAS_BZ = BZ_TRANSMIT_MODIFIER,
// /datum/gas/hydrogen = HYDROGEN_TRANSMIT_MODIFIER,
)
///The list of gases mapped against their heat penaltys. We use it to determin molar and heat output
var/list/gas_heat = list(
/datum/gas/oxygen = OXYGEN_HEAT_PENALTY,
/datum/gas/water_vapor = H2O_HEAT_PENALTY,
/datum/gas/plasma = PLASMA_HEAT_PENALTY,
/datum/gas/carbon_dioxide = CO2_HEAT_PENALTY,
/datum/gas/nitrogen = NITROGEN_HEAT_PENALTY,
/datum/gas/pluoxium = PLUOXIUM_HEAT_PENALTY,
/datum/gas/tritium = TRITIUM_HEAT_PENALTY,
/datum/gas/bz = BZ_HEAT_PENALTY,
GAS_O2 = OXYGEN_HEAT_PENALTY,
GAS_H2O = H2O_HEAT_PENALTY,
GAS_PLASMA = PLASMA_HEAT_PENALTY,
GAS_CO2 = CO2_HEAT_PENALTY,
GAS_N2 = NITROGEN_HEAT_PENALTY,
GAS_PLUOXIUM = PLUOXIUM_HEAT_PENALTY,
GAS_TRITIUM = TRITIUM_HEAT_PENALTY,
GAS_BZ = BZ_HEAT_PENALTY,
// /datum/gas/freon = FREON_HEAT_PENALTY,
// /datum/gas/hydrogen = HYDROGEN_HEAT_PENALTY,
)
///The list of gases mapped against their heat resistance. We use it to moderate heat damage.
var/list/gas_resist = list(
/datum/gas/nitrous_oxide = N2O_HEAT_RESISTANCE,
/datum/gas/pluoxium = PLUOXIUM_HEAT_RESISTANCE,
GAS_NITROUS = N2O_HEAT_RESISTANCE,
GAS_PLUOXIUM = PLUOXIUM_HEAT_RESISTANCE,
// /datum/gas/hydrogen = HYDROGEN_HEAT_RESISTANCE,
)
///The list of gases mapped against their powermix ratio
var/list/gas_powermix = list(
/datum/gas/oxygen = 1,
/datum/gas/water_vapor = 1,
/datum/gas/plasma = 1,
/datum/gas/carbon_dioxide = 1,
/datum/gas/nitrogen = -1,
/datum/gas/pluoxium = -1,
/datum/gas/tritium = 1,
/datum/gas/bz = 1,
GAS_O2 = 1,
GAS_H2O = 1,
GAS_PLASMA = 1,
GAS_CO2 = 1,
GAS_N2 = -1,
GAS_PLUOXIUM = -1,
GAS_TRITIUM = 1,
GAS_BZ = 1,
// /datum/gas/freon = -1,
// /datum/gas/hydrogen = 1,
)
@@ -283,7 +283,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
/obj/machinery/power/supermatter_crystal/Initialize()
. = ..()
uid = gl_uid++
SSair.atmos_machinery += src
SSair.atmos_air_machinery += src
countdown = new(src)
countdown.start()
GLOB.poi_list |= src
@@ -302,7 +302,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
/obj/machinery/power/supermatter_crystal/Destroy()
investigate_log("has been destroyed.", INVESTIGATE_SUPERMATTER)
SSair.atmos_machinery -= src
SSair.atmos_air_machinery -= src
QDEL_NULL(radio)
GLOB.poi_list -= src
QDEL_NULL(countdown)
@@ -475,7 +475,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/datum/gas_mixture/removed
if(produces_gas)
//Remove gas from surrounding area
removed = env.remove(gasefficency * env.total_moles())
removed = env.remove_ratio(gasefficency)
else
// Pass all the gas related code an empty gas container
removed = new()
@@ -538,13 +538,13 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/list/resistance_mod = gases_we_care_about.Copy()
//We're concerned about pluoxium being too easy to abuse at low percents, so we make sure there's a substantial amount.
var/pluoxiumbonus = (gas_comp[/datum/gas/pluoxium] >= 0.15) //makes pluoxium only work at 15%+
var/h2obonus = 1 - (gas_comp[/datum/gas/water_vapor] * 0.25)//At max this value should be 0.75
var/pluoxiumbonus = (gas_comp[GAS_PLUOXIUM] >= 0.15) //makes pluoxium only work at 15%+
var/h2obonus = 1 - (gas_comp[GAS_H2O] * 0.25)//At max this value should be 0.75
// var/freonbonus = (gas_comp[/datum/gas/freon] <= 0.03) //Let's just yeet power output if this shit is high
heat_mod[/datum/gas/pluoxium] = pluoxiumbonus
transit_mod[/datum/gas/pluoxium] = pluoxiumbonus
resistance_mod[/datum/gas/pluoxium] = pluoxiumbonus
heat_mod[GAS_PLUOXIUM] = pluoxiumbonus
transit_mod[GAS_PLUOXIUM] = pluoxiumbonus
resistance_mod[GAS_PLUOXIUM] = pluoxiumbonus
//No less then zero, and no greater then one, we use this to do explosions and heat to power transfer
//Be very careful with modifing this var by large amounts, and for the love of god do not push it past 1
@@ -578,8 +578,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//Ramps up or down in increments of 0.02 up to the proportion of co2
//Given infinite time, powerloss_dynamic_scaling = co2comp
//Some value between 0 and 1
if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && gas_comp[/datum/gas/carbon_dioxide] > POWERLOSS_INHIBITION_GAS_THRESHOLD) //If there are more then 20 mols, and more then 20% co2
powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(gas_comp[/datum/gas/carbon_dioxide] - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1)
if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && gas_comp[GAS_CO2] > POWERLOSS_INHIBITION_GAS_THRESHOLD) //If there are more then 20 mols, and more then 20% co2
powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(gas_comp[GAS_CO2] - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1)
else
powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling - 0.05, 0, 1)
//Ranges from 0 to 1(1-(value between 0 and 1 * ranges from 1 to 1.5(mol / 500)))
@@ -611,8 +611,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(prob(50))
//(1 + (tritRad + pluoxDampen * bzDampen * o2Rad * plasmaRad / (10 - bzrads))) * freonbonus
radiation_pulse(src, power * max(0, (1 + (power_transmission_bonus/(10-(gas_comp[/datum/gas/bz] * BZ_RADIOACTIVITY_MODIFIER)))) * 1))//freonbonus))// RadModBZ(500%)
if(gas_comp[/datum/gas/bz] >= 0.4 && prob(30 * gas_comp[/datum/gas/bz]))
radiation_pulse(src, power * max(0, (1 + (power_transmission_bonus/(10-(gas_comp[GAS_BZ] * BZ_RADIOACTIVITY_MODIFIER)))) * 1))//freonbonus))// RadModBZ(500%)
if(gas_comp[GAS_BZ] >= 0.4 && prob(30 * gas_comp[GAS_BZ]))
src.fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick
//Power * 0.55 * a value between 1 and 0.8
@@ -632,9 +632,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
//Calculate how much gas to release
//Varies based on power and gas content
removed.adjust_moles(/datum/gas/plasma, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
removed.adjust_moles(GAS_PLASMA, max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0))
//Varies based on power, gas content, and heat
removed.adjust_moles(/datum/gas/oxygen, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0))
removed.adjust_moles(GAS_O2, max(((device_energy + removed.return_temperature() * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0))
if(produces_gas)
env.merge(removed)
+3 -7
View File
@@ -128,13 +128,10 @@
cut_overlays()
rpm = 0.9* rpm + 0.1 * rpmtarget
var/datum/gas_mixture/environment = inturf.return_air()
// It's a simplified version taking only 1/10 of the moles from the turf nearby. It should be later changed into a better version
// above todo 7 years and counting
var/transfer_moles = environment.total_moles()/10
var/datum/gas_mixture/removed = inturf.remove_air(transfer_moles)
gas_contained.merge(removed)
inturf.transfer_air_ratio(gas_contained, 0.1)
// RPM function to include compression friction - be advised that too low/high of a compfriction value can make things screwy
@@ -221,8 +218,7 @@
if(compressor.gas_contained.total_moles()>0)
var/oamount = min(compressor.gas_contained.total_moles(), (compressor.rpm+100)/35000*compressor.capacity)
var/datum/gas_mixture/removed = compressor.gas_contained.remove(oamount)
outturf.assume_air(removed)
outturf.assume_air_moles(compressor.gas_contained, oamount)
// If it works, put an overlay that it works!
@@ -10,16 +10,13 @@
if(!mother)
return
var/list/map = mother.map
for(var/turf/T in map)
SSair.remove_from_active(T)
for(var/turf/open/T in map)
if(T.air)
if(T.initial_gas_mix)
T.air.parse_gas_string(T.initial_gas_mix)
T.temperature = T.air.return_temperature()
T.set_temperature(T.air.return_temperature())
else
T.air.copy_from_turf(T)
SSair.add_to_active(T)
/datum/mapGeneratorModule/bottomLayer/massdelete
spawnableAtoms = list()
@@ -524,10 +524,9 @@
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles())
lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,0))
var/datum/gas_mixture/lowertemp = T.return_air()
lowertemp.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,TCMB))
lowertemp.react(src)
T.assume_air(lowertemp)
qdel(hotspot)
/datum/reagent/consumable/enzyme
@@ -235,8 +235,7 @@
if(holder && holder.my_atom)
var/turf/open/T = get_turf(holder.my_atom)
if(istype(T))
var/datum/gas/gastype = /datum/gas/nitrogen
T.atmos_spawn_air("[initial(gastype.id)]=50;TEMP=2.7")
T.atmos_spawn_air("n2=50;TEMP=2.7")
/datum/chemical_reaction/slime/slimefireproof
name = "Slime Fireproof"
+2 -16
View File
@@ -362,14 +362,7 @@
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions, melting [exp_on] and leaking hot air!</span>")
var/datum/gas_mixture/env = loc.return_air()
var/transfer_moles = 0.25 * env.total_moles()
var/datum/gas_mixture/removed = env.remove(transfer_moles)
if(removed)
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.set_temperature(min((removed.return_temperature()*heat_capacity + 100000)/heat_capacity, 1000))
env.merge(removed)
env.adjust_heat(100000)
air_update_turf()
investigate_log("Experimentor has released hot air.", INVESTIGATE_EXPERIMENTOR)
ejectItem(TRUE)
@@ -408,14 +401,7 @@
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
visible_message("<span class='warning'>[src] malfunctions, shattering [exp_on] and leaking cold air!</span>")
var/datum/gas_mixture/env = loc.return_air()
var/transfer_moles = 0.25 * env.total_moles()
var/datum/gas_mixture/removed = env.remove(transfer_moles)
if(removed)
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.set_temperature((removed.return_temperature()*heat_capacity - 75000)/heat_capacity)
env.merge(removed)
env.adjust_heat(-75000)
air_update_turf()
investigate_log("Experimentor has released cold air.", INVESTIGATE_EXPERIMENTOR)
ejectItem(TRUE)
+6 -19
View File
@@ -7,12 +7,11 @@
circuit = /obj/item/circuitboard/machine/rdserver
var/datum/techweb/stored_research
var/heat_health = 100
//Code for point mining here.
var/working = TRUE //temperature should break it.
var/server_id = 0
var/base_mining_income = 2
var/heat_gen = 100
var/heat_gen = 1
var/heating_power = 40000
var/delay = 5
var/temp_tolerance_low = 0
@@ -32,7 +31,7 @@
var/tot_rating = 0
for(var/obj/item/stock_parts/SP in src)
tot_rating += SP.rating
heat_gen /= max(1, tot_rating)
heat_gen = initial(src.heat_gen) / max(1, tot_rating)
/obj/machinery/rnd/server/proc/refresh_working()
if(stat & EMPED)
@@ -56,31 +55,19 @@
. = base_mining_income
var/penalty = max((get_env_temp() - temp_tolerance_high), 0) * temp_penalty_coefficient
. = max(. - penalty, 0)
produce_heat(. / base_mining_income)
/obj/machinery/rnd/server/proc/get_env_temp()
var/datum/gas_mixture/environment = loc.return_air()
return environment.return_temperature()
/obj/machinery/rnd/server/proc/produce_heat(heat_amt)
/obj/machinery/rnd/server/proc/produce_heat(perc)
if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater.
var/turf/L = loc
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
if(env.return_temperature() < (heat_amt+T0C))
var/transfer_moles = 0.25 * env.total_moles()
var/datum/gas_mixture/removed = env.remove(transfer_moles)
if(removed)
var/heat_capacity = removed.heat_capacity()
if(heat_capacity == 0 || heat_capacity == null)
heat_capacity = 1
removed.set_temperature(min((removed.return_temperature()*heat_capacity + heating_power)/heat_capacity, 1000))
env.merge(removed)
air_update_turf()
env.adjust_heat(heating_power * perc * heat_gen)
air_update_turf()
/proc/fix_noid_research_servers()
var/list/no_id_servers = list()
@@ -100,7 +100,7 @@ Chilling extracts:
for(var/turf/open/T in A)
var/datum/gas_mixture/G = T.air
if(istype(G))
G.set_moles(/datum/gas/plasma, 0)
G.set_moles(GAS_PLASMA, 0)
filtered = TRUE
T.air_update_turf()
if(filtered)
+6
View File
@@ -205,3 +205,9 @@
var/turf/oldT = moved_atoms[moved_object]
moved_object.lateShuttleMove(oldT, movement_force, movement_direction)
/obj/docking_port/mobile/proc/reset_air()
var/list/turfs = return_ordered_turfs(x, y, z, dir)
for(var/i in 1 to length(turfs))
var/turf/open/T = turfs[i]
if(istype(T))
T.air.copy_from_turf(T)
+1 -2
View File
@@ -254,8 +254,7 @@
to_chat(H, "<span class='notice'>You feel resistant to airborne toxins.</span>")
if(locate(/obj/item/organ/lungs) in H.internal_organs)
var/obj/item/organ/lungs/L = H.internal_organs_slot[ORGAN_SLOT_LUNGS]
L.tox_breath_dam_min = 0
L.tox_breath_dam_max = 0
L.gas_max -= GAS_PLASMA
ADD_TRAIT(H, TRAIT_VIRUSIMMUNE, "dna_vault")
if(VAULT_NOBREATH)
to_chat(H, "<span class='notice'>Your lungs feel great.</span>")
@@ -210,13 +210,9 @@
// Priority 3: use internals tank.
var/obj/item/tank/I = owner.internal
if(I && I.air_contents && I.air_contents.total_moles() > num)
var/datum/gas_mixture/removed = I.air_contents.remove(num)
if(removed.total_moles() > 0.005)
T.assume_air(removed)
return 1
else
T.assume_air(removed)
if(I && I.air_contents && I.air_contents.total_moles() >= num)
T.assume_air_moles(I.air_contents, num)
return 1
toggle(silent = TRUE)
return 0
+180 -269
View File
@@ -27,40 +27,36 @@
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/salbutamol = 5)
//Breath damage
var/breathing_class = BREATH_OXY // can be a gas instead of a breathing class
var/safe_breath_min = 16
var/safe_breath_max = 50
var/safe_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
var/safe_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
var/safe_damage_type = OXY
var/list/gas_min = list()
var/list/gas_max = list(
GAS_CO2 = 30, // Yes it's an arbitrary value who cares?
GAS_METHYL_BROMIDE = 1,
GAS_PLASMA = MOLES_GAS_VISIBLE
)
var/list/gas_damage = list(
"default" = list(
min = MIN_TOXIC_GAS_DAMAGE,
max = MAX_TOXIC_GAS_DAMAGE,
damage_type = OXY
),
GAS_PLASMA = list(
min = MIN_TOXIC_GAS_DAMAGE,
max = MAX_TOXIC_GAS_DAMAGE,
damage_type = TOX
)
)
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
var/safe_oxygen_max = 50 // Too much of a good thing, in kPa as well.
var/safe_nitro_min = 0
var/safe_nitro_max = 0
var/safe_co2_min = 0
var/safe_co2_max = 10 // Yes it's an arbitrary value who cares?
var/safe_toxins_min = 0
var/safe_toxins_max = MOLES_GAS_VISIBLE
var/safe_ch3br_min = 0
var/safe_ch3br_max = 1 //problematic even at low concentrations
var/safe_methane_min = 0
var/safe_methane_max = 0
var/SA_para_min = 1 //Sleeping agent
var/SA_sleep_min = 5 //Sleeping agent
var/SA_para_min = 1 //nitrous values
var/SA_sleep_min = 5
var/BZ_trip_balls_min = 1 //BZ gas
var/gas_stimulation_min = 0.002 //Nitryl and Stimulum
var/oxy_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
var/oxy_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
var/oxy_damage_type = OXY
var/nitro_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
var/nitro_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
var/nitro_damage_type = OXY
var/co2_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
var/co2_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
var/co2_damage_type = OXY
var/tox_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
var/tox_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
var/tox_damage_type = TOX
var/methane_breath_dam_min = MIN_TOXIC_GAS_DAMAGE
var/methane_breath_dam_max = MAX_TOXIC_GAS_DAMAGE
var/methane_damage_type = OXY
var/cold_message = "your face freezing and an icicle forming"
var/cold_level_1_threshold = 260
var/cold_level_2_threshold = 200
@@ -81,7 +77,18 @@
var/crit_stabilizing_reagent = /datum/reagent/medicine/epinephrine
/obj/item/organ/lungs/New()
. = ..()
populate_gas_info()
/obj/item/organ/lungs/proc/populate_gas_info()
gas_min[breathing_class] = safe_breath_min
gas_max[breathing_class] = safe_breath_max
gas_damage[breathing_class] = list(
min = safe_breath_dam_min,
max = safe_breath_dam_max,
damage_type = safe_damage_type
)
//TODO: lung health affects lung function
/obj/item/organ/lungs/onDamage(damage_mod) //damage might be too low atm.
@@ -128,227 +135,126 @@
H.adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
H.failed_last_breath = TRUE
if(safe_oxygen_min)
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else if(safe_toxins_min)
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else if(safe_co2_min)
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else if(safe_nitro_min)
H.throw_alert("not_enough_nitro", /obj/screen/alert/not_enough_nitro)
else if(safe_ch3br_min)
H.throw_alert("not_enough_ch3br", /obj/screen/alert/not_enough_ch3br)
var/alert_category
var/alert_type
if(ispath(breathing_class))
var/datum/breathing_class/class = GLOB.gas_data.breathing_classes[breathing_class]
alert_category = class.low_alert_category
alert_type = class.low_alert_datum
else
var/list/breath_alert_info = GLOB.gas_data.breath_alert_info
if(breathing_class in breath_alert_info)
var/list/alert = breath_alert_info[breathing_class]["not_enough_alert"]
alert_category = alert["alert_category"]
alert_type = alert["alert_type"]
if(alert_category)
H.throw_alert(alert_category, alert_type)
return FALSE
#define PP_MOLES(X) ((X / total_moles) * pressure)
#define PP(air, gas) PP_MOLES(air.get_moles(gas))
var/gas_breathed = 0
//Partial pressures in our breath
var/O2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/oxygen))+(8*breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/pluoxium)))
var/N2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrogen))
var/Toxins_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
var/CO2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/carbon_dioxide))
var/CH4_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/methane))
var/CH3Br_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/methyl_bromide))
//-- OXY --//
//Too much oxygen! //Yes, some species may not like it.
if(safe_oxygen_max)
if((O2_pp > safe_oxygen_max) && safe_oxygen_max == 0) //I guess plasma men technically need to have a check.
var/ratio = (breath.get_moles(/datum/gas/oxygen)/safe_oxygen_max) * 10
H.apply_damage_type(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
else if((O2_pp > safe_oxygen_max) && !(safe_oxygen_max == 0)) //Why yes, this is like too much CO2 and spahget. Dirty lizards.
if(!H.o2overloadtime)
H.o2overloadtime = world.time
else if(world.time - H.o2overloadtime > 120)
H.Dizzy(10) // better than a minute of you're fucked KO, but certainly a wake up call. Honk.
H.adjustOxyLoss(3)
if(world.time - H.o2overloadtime > 300)
H.adjustOxyLoss(8)
if(prob(20))
H.emote("cough")
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
var/pressure = breath.return_pressure()
var/total_moles = breath.total_moles()
var/list/breath_alert_info = GLOB.gas_data.breath_alert_info
var/list/breath_results = GLOB.gas_data.breath_results
var/list/breathing_classes = GLOB.gas_data.breathing_classes
var/list/mole_adjustments = list()
for(var/entry in gas_min)
var/required_pp = 0
var/required_moles = 0
var/safe_min = gas_min[entry]
var/alert_category = null
var/alert_type = null
if(ispath(entry))
var/datum/breathing_class/class = breathing_classes[entry]
var/list/gases = class.gases
var/list/products = class.products
alert_category = class.low_alert_category
alert_type = class.low_alert_datum
for(var/gas in gases)
var/moles = breath.get_moles(gas)
var/multiplier = gases[gas]
mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - moles : -moles
required_pp += PP_MOLES(moles) * multiplier
required_moles += moles
if(multiplier > 0)
var/to_add = moles * multiplier
for(var/product in products)
mole_adjustments[product] = (product in mole_adjustments) ? mole_adjustments[product] + to_add : to_add
else
H.o2overloadtime = 0
H.clear_alert("too_much_oxy")
//Too little oxygen!
if(safe_oxygen_min)
if(O2_pp < safe_oxygen_min)
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.get_moles(/datum/gas/oxygen))
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier) //More damaged lungs = slower oxy rate up to a factor of half
gas_breathed = breath.get_moles(/datum/gas/oxygen)
H.clear_alert("not_enough_oxy")
//Exhale
breath.adjust_moles(/datum/gas/oxygen, -gas_breathed)
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
gas_breathed = 0
//-- Nitrogen --//
//Too much nitrogen!
if(safe_nitro_max)
if(N2_pp > safe_nitro_max)
var/ratio = (breath.get_moles(/datum/gas/nitrogen)/safe_nitro_max) * 10
H.apply_damage_type(clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro)
H.losebreath += 2
else
H.clear_alert("too_much_nitro")
//Too little nitrogen!
if(safe_nitro_min)
if(N2_pp < safe_nitro_min)
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.get_moles(/datum/gas/nitrogen))
H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro)
required_moles = breath.get_moles(entry)
required_pp = PP_MOLES(required_moles)
if(entry in breath_alert_info)
var/list/alert = breath_alert_info[entry]["not_enough_alert"]
alert_category = alert["alert_category"]
alert_type = alert["alert_type"]
mole_adjustments[entry] = -required_moles
mole_adjustments[breath_results[entry]] = required_moles
if(required_pp < safe_min)
var/multiplier = 0
if(required_moles > 0)
multiplier = handle_too_little_breath(H, required_pp, safe_min, required_moles) / required_moles
for(var/adjustment in mole_adjustments)
mole_adjustments[adjustment] *= multiplier
if(alert_category)
H.throw_alert(alert_category, alert_type)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath.get_moles(/datum/gas/nitrogen)
H.clear_alert("nitro")
//Exhale
breath.adjust_moles(/datum/gas/nitrogen, -gas_breathed)
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
gas_breathed = 0
//-- CO2 --//
//CO2 does not affect failed_last_breath. So if there was enough oxygen in the air but too much co2, this will hurt you, but only once per 4 ticks, instead of once per tick.
if(safe_co2_max)
if(CO2_pp > safe_co2_max)
if(!H.co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so.
H.co2overloadtime = world.time
else if(world.time - H.co2overloadtime > 120)
H.Unconscious(60)
H.apply_damage_type(3, co2_damage_type) // Lets hurt em a little, let them know we mean business
if(world.time - H.co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good!
H.apply_damage_type(8, co2_damage_type)
H.throw_alert("too_much_co2", /obj/screen/alert/too_much_co2)
if(prob(20)) // Lets give them some chance to know somethings not right though I guess.
H.emote("cough")
if(alert_category)
H.clear_alert(alert_category)
var/list/danger_reagents = GLOB.gas_data.breath_reagents_dangerous
for(var/entry in gas_max)
var/found_pp = 0
var/datum/breathing_class/breathing_class = entry
var/datum/reagent/danger_reagent = null
var/alert_category = null
var/alert_type = null
if(ispath(breathing_class))
breathing_class = breathing_classes[breathing_class]
var/list/gases = breathing_class.gases
alert_category = breathing_class.high_alert_category
alert_type = breathing_class.high_alert_datum
danger_reagent = breathing_class.danger_reagent
for(var/gas in gases)
found_pp += PP(breath, gas)
else
H.co2overloadtime = 0
H.clear_alert("too_much_co2")
danger_reagent = danger_reagents[entry]
if(entry in breath_alert_info)
var/list/alert = breath_alert_info[entry]["too_much_alert"]
alert_category = alert["alert_category"]
alert_type = alert["alert_type"]
found_pp = PP(breath, entry)
if(found_pp > gas_max[entry])
if(istype(danger_reagent))
H.reagents.add_reagent(danger_reagent,1)
var/list/damage_info = (entry in gas_damage) ? gas_damage[entry] : gas_damage["default"]
var/dam = found_pp / gas_max[entry] * 10
H.apply_damage_type(clamp(dam, damage_info["min"], damage_info["max"]), damage_info["damage_type"])
if(alert_category && alert_type)
H.throw_alert(alert_category, alert_type)
else if(alert_category)
H.clear_alert(alert_category)
var/list/breath_reagents = GLOB.gas_data.breath_reagents
for(var/gas in breath.get_gases())
if(gas in breath_reagents)
var/datum/reagent/R = breath_reagents[gas]
H.reagents.add_reagent(R, PP(breath,gas))
mole_adjustments[gas] = (gas in mole_adjustments) ? mole_adjustments[gas] - breath.get_moles(gas) : -breath.get_moles(gas)
//Too little CO2!
if(safe_co2_min)
if(CO2_pp < safe_co2_min)
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.get_moles(/datum/gas/carbon_dioxide))
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath.get_moles(/datum/gas/carbon_dioxide)
H.clear_alert("not_enough_co2")
//Exhale
breath.adjust_moles(/datum/gas/carbon_dioxide, -gas_breathed)
breath.adjust_moles(/datum/gas/oxygen, gas_breathed)
gas_breathed = 0
//-- TOX --//
//Too much toxins!
if(safe_toxins_max)
if(Toxins_pp > safe_toxins_max)
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_toxins_max) * 10
H.apply_damage_type(clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type)
H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
H.clear_alert("too_much_tox")
//Too little toxins!
if(safe_toxins_min)
if(Toxins_pp < safe_toxins_min)
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.get_moles(/datum/gas/plasma))
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath.get_moles(/datum/gas/plasma)
H.clear_alert("not_enough_tox")
//Exhale
breath.adjust_moles(/datum/gas/plasma, -gas_breathed)
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
gas_breathed = 0
//-- METHANE --//
//Too much methane!
if(safe_methane_max)
if(CH4_pp > safe_methane_max) //Same effect as excess nitrogen, generally nontoxic
var/ratio = (breath.get_moles(/datum/gas/methane)/safe_methane_max) * 10
H.apply_damage_type(clamp(ratio, methane_breath_dam_min, methane_breath_dam_max), methane_damage_type)
H.throw_alert("too_much_ch4", /obj/screen/alert/too_much_ch4)
H.losebreath += 2
else
H.clear_alert("too_much_ch4")
//Too little methane!
if(safe_methane_min)
if(CH4_pp < safe_methane_min)
gas_breathed = handle_too_little_breath(H, CH4_pp, safe_methane_min, breath.get_moles(/datum/gas/methane))
H.throw_alert("not_enough_ch4", /obj/screen/alert/not_enough_ch4)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath.get_moles(/datum/gas/methane)
H.clear_alert("not_enough_ch4")
//Exhale
breath.adjust_moles(/datum/gas/methane, -gas_breathed)
breath.adjust_moles(/datum/gas/methyl_bromide, gas_breathed)
gas_breathed = 0
//-- CH3BR --//
//Too much methyl bromide!
if(safe_ch3br_max)
if(CH3Br_pp > safe_ch3br_max)
if(prob(CH3Br_pp/0.5))
H.adjustOrganLoss(ORGAN_SLOT_LUNGS, 3, 150) //Inhaling this is a bad idea
if(prob(CH3Br_pp/2))
to_chat(H, "<span class='alert'>Your throat closes up!</span>")
H.silent = max(H.silent, 3)
H.throw_alert("too_much_ch3br", /obj/screen/alert/too_much_ch3br)
else
H.clear_alert("too_much_ch3br")
//Too little methyl bromide!
if(safe_ch3br_min)
if(CH3Br_pp < safe_ch3br_min)
gas_breathed = handle_too_little_breath(H, CH3Br_pp, safe_ch3br_min, breath.get_moles(/datum/gas/methyl_bromide))
H.throw_alert("not_enough_ch3br", /obj/screen/alert/not_enough_ch3br)
else
H.failed_last_breath = FALSE
if(H.health >= H.crit_threshold)
H.adjustOxyLoss(-breathModifier)
gas_breathed = breath.get_moles(/datum/gas/methyl_bromide)
H.clear_alert("not_enough_ch3br")
//-- TRACES --//
for(var/gas in mole_adjustments)
breath.adjust_moles(gas, mole_adjustments[gas])
if(breath) // If there's some other shit in the air lets deal with it here.
// N2O
var/SA_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrous_oxide))
var/SA_pp = PP(breath, GAS_NITROUS)
if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
@@ -362,7 +268,7 @@
// BZ
var/bz_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/bz))
var/bz_pp = PP(breath, GAS_BZ)
if(bz_pp > BZ_trip_balls_min)
H.hallucination += 10
H.reagents.add_reagent(/datum/reagent/bz_metabolites,5)
@@ -373,16 +279,8 @@
H.hallucination += 5
H.reagents.add_reagent(/datum/reagent/bz_metabolites,1)
// Tritium
var/trit_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/tritium))
if (trit_pp > 50)
H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up.
else
H.radiation += trit_pp/10
// Nitryl
var/nitryl_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitryl))
var/nitryl_pp = PP(breath,GAS_NITRYL)
if (prob(nitryl_pp))
to_chat(H, "<span class='alert'>Your mouth feels like it's burning!</span>")
if (nitryl_pp >40)
@@ -393,22 +291,22 @@
H.silent = max(H.silent, 3)
else
H.adjustFireLoss(nitryl_pp/4)
gas_breathed = breath.get_moles(/datum/gas/nitryl)
gas_breathed = breath.get_moles(GAS_NITRYL)
if (gas_breathed > gas_stimulation_min)
H.reagents.add_reagent(/datum/reagent/nitryl,1)
breath.adjust_moles(/datum/gas/nitryl, -gas_breathed)
breath.adjust_moles(GAS_NITRYL, -gas_breathed)
// Stimulum
gas_breathed = breath.get_moles(/datum/gas/stimulum)
gas_breathed = PP(breath,GAS_STIMULUM)
if (gas_breathed > gas_stimulation_min)
var/existing = H.reagents.get_reagent_amount(/datum/reagent/stimulum)
H.reagents.add_reagent(/datum/reagent/stimulum, max(0, 5 - existing))
breath.adjust_moles(/datum/gas/stimulum, -gas_breathed)
breath.adjust_moles(GAS_STIMULUM, -gas_breathed)
// Miasma
if (breath.get_moles(/datum/gas/miasma))
var/miasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/miasma))
if (breath.get_moles(GAS_MIASMA))
var/miasma_pp = PP(breath,GAS_MIASMA)
if(miasma_pp > MINIMUM_MOLES_DELTA_TO_MOVE)
//Miasma sickness
@@ -448,7 +346,7 @@
// Then again, this is a purely hypothetical scenario and hardly reachable
owner.adjust_disgust(0.1 * miasma_pp)
breath.adjust_moles(/datum/gas/miasma, -gas_breathed)
breath.adjust_moles(GAS_MIASMA, -gas_breathed)
// Clear out moods when no miasma at all
else
@@ -539,13 +437,13 @@
name = "plasma filter"
desc = "A spongy rib-shaped mass for filtering plasma from the air."
icon_state = "lungs-plasma"
safe_oxygen_min = 0 //We don't breath this
safe_oxygen_max = 0 // Like, at all.
safe_toxins_min = 16 //We breath THIS!
safe_toxins_max = 0
breathing_class = BREATH_PLASMA
maxHealth = INFINITY//I don't understand how plamamen work, so I'm not going to try t give them special lungs atm
/obj/item/organ/lungs/plasmaman/populate_gas_info()
..()
gas_max -= GAS_PLASMA
/obj/item/organ/lungs/cybernetic
name = "basic cybernetic lungs"
desc = "A basic cybernetic version of the lungs found in traditional humanoid entities."
@@ -560,8 +458,8 @@
desc = "A cybernetic version of the lungs found in traditional humanoid entities. Allows for greater intakes of oxygen than organic lungs, requiring slightly less pressure."
icon_state = "lungs-c-u"
maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD
safe_oxygen_min = 13
safe_oxygen_max = 100
safe_breath_min = 13
safe_breath_max = 100
emp_vulnerability = 2
/obj/item/organ/lungs/cybernetic/tier3
@@ -569,10 +467,13 @@
desc = "A more advanced version of the stock cybernetic lungs. Features the ability to filter out various airbourne toxins and carbon dioxide even at heavy levels."
icon_state = "lungs-c-u2"
maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
safe_oxygen_min = 4 //You could literally be breathing the thinnest amount of oxygen and be fine
safe_oxygen_max = 250 //Or be in an enriched oxygen room for that matter
safe_toxins_max = 30
safe_co2_max = 30
safe_breath_min = 4 //You could literally be breathing the thinnest amount of oxygen and be fine
safe_breath_max = 250 //Or be in an enriched oxygen room for that matter
gas_max = list(
GAS_PLASMA = 30,
GAS_CO2 = 30,
GAS_METHYL_BROMIDE = 10
)
SA_para_min = 30
SA_sleep_min = 50
BZ_trip_balls_min = 30
@@ -597,9 +498,8 @@
name = "ash lungs"
desc = "blackened lungs identical from specimens recovered from lavaland, unsuited to higher air pressures."
icon_state = "lungs-ll"
safe_oxygen_min = 3 //able to handle much thinner oxygen, something something ash storm adaptation
safe_oxygen_max = 18 // Air standard is 22kpA of O2, LL is 14kpA
safe_nitro_max = 28 // Air standard is 82kpA of N2, LL is 23kpA
safe_breath_min = 3 //able to handle much thinner oxygen, something something ash storm adaptation
safe_breath_max = 18 // Air standards is 22kPa of O2, LL is 14kPa
cold_level_1_threshold = 280 // Ash Lizards can't take the cold very well, station air is only just warm enough
cold_level_2_threshold = 240
@@ -608,23 +508,31 @@
heat_level_1_threshold = 400 // better adapted for heat, obv. Lavaland standard is 300
heat_level_2_threshold = 600 // up 200 from level 1, 1000 is silly but w/e for level 3
/obj/item/organ/lungs/ashwalker/populate_gas_info()
..()
gas_max[GAS_N2] = 28
/obj/item/organ/lungs/slime
name = "vacuole"
icon_state = "lungs-s"
desc = "A large organelle designed to store oxygen and other important gasses."
safe_toxins_max = 0 //We breathe this to gain POWER.
cold_level_1_threshold = 285 // Remember when slimes used to be succeptable to cold? Well....
cold_level_2_threshold = 260
cold_level_3_threshold = 230
maxHealth = 250
/obj/item/organ/lungs/ashwalker/populate_gas_info()
..()
gas_max -= GAS_PLASMA
/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
. = ..()
if (breath)
var/plasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
var/total_moles = breath.total_moles()
var/pressure = breath.return_pressure()
var/plasma_pp = PP(breath, GAS_PLASMA)
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
/obj/item/organ/lungs/yamerol
@@ -637,3 +545,6 @@
. = ..()
if(.)
applyOrganDamage(2) //Yamerol lungs are temporary
#undef PP
#undef PP_MOLES