mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 06:57:42 +01:00
Adds Hydrogen - The Framework for more Atmos Gases (#30742)
* IMPORTANT MILESTONE, AIR IS BREATHABLE * the vibrations of the SM in my headphones are pleasing (no stupid hotspots) * sanity check, it all works * SM is fine * this will work first try * linter * "thank you, warriorstar" everyone says in unison * Build Rust library * finishing touches (hopefully) * Build Rust library * update gas_mixture.dm to include hydrogen burning * Build Rust library * hydrogen should be the right color on gas analyzers * i JUST rebuilt it * adds agent B and Hydrogen floors * update the h2 canister * caniser bad speling * in aa we trust * Build Rust library * Build Rust library --------- Co-authored-by: paradisess13[bot] <165046124+paradisess13[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
paradisess13[bot] <165046124+paradisess13[bot]@users.noreply.github.com>
parent
096cbdd9a1
commit
99d57fd35d
@@ -4,6 +4,7 @@
|
||||
#define GAS_CO2 (1 << 3)
|
||||
#define GAS_N2O (1 << 4)
|
||||
#define GAS_A_B (1 << 5)
|
||||
#define GAS_H2 (1 << 6)
|
||||
|
||||
//ATMOS
|
||||
//stuff you should probably leave well alone!
|
||||
@@ -75,6 +76,10 @@
|
||||
#define MAX_TOXIC_GAS_DAMAGE 10
|
||||
#define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible
|
||||
|
||||
//HYDROGEN
|
||||
#define HYDROGEN_BURN_ENERGY 2500000
|
||||
#define HYDROGEN_MIN_IGNITE_TEMP 500
|
||||
|
||||
// Pressure limits.
|
||||
#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant)
|
||||
#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE)
|
||||
|
||||
@@ -545,6 +545,7 @@
|
||||
#define LINDA_SPAWN_AGENT_B (1<<7)
|
||||
#define LINDA_SPAWN_AIR (1<<8)
|
||||
#define LINDA_SPAWN_COLD (1<<9)
|
||||
#define LINDA_SPAWN_HYDROGEN (1<<10)
|
||||
|
||||
#define MAPROTATION_MODE_NORMAL_VOTE "Vote"
|
||||
#define MAPROTATION_MODE_NO_DUPLICATES "Nodupes"
|
||||
|
||||
+22
-21
@@ -71,8 +71,8 @@
|
||||
ASSERT(istype(high_corner))
|
||||
return RUSTLIB_CALL(milla_load_turfs, "milla_data", low_corner, high_corner)
|
||||
|
||||
/proc/set_tile_atmos(turf/T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume)
|
||||
return RUSTLIB_CALL(milla_set_tile, T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume)
|
||||
/proc/set_tile_atmos(turf/T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume)
|
||||
return RUSTLIB_CALL(milla_set_tile, T, airtight_north, airtight_east, airtight_south, airtight_west, atmos_mode, environment_id, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, temperature, innate_heat_capacity, hotspot_temperature, hotspot_volume)
|
||||
|
||||
/proc/get_tile_atmos(turf/T, list/L)
|
||||
return RUSTLIB_CALL(milla_get_tile, T, L)
|
||||
@@ -119,8 +119,8 @@
|
||||
/proc/get_random_interesting_tile()
|
||||
return RUSTLIB_CALL(milla_get_random_interesting_tile)
|
||||
|
||||
/proc/create_environment(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature)
|
||||
return RUSTLIB_CALL(milla_create_environment, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature)
|
||||
/proc/create_environment(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, temperature)
|
||||
return RUSTLIB_CALL(milla_create_environment, oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, temperature)
|
||||
|
||||
/proc/set_zlevel_freeze(z, bool_frozen)
|
||||
return RUSTLIB_CALL(milla_set_zlevel_frozen, z, bool_frozen)
|
||||
@@ -258,28 +258,29 @@
|
||||
#define MILLA_INDEX_TOXINS 5
|
||||
#define MILLA_INDEX_SLEEPING_AGENT 6
|
||||
#define MILLA_INDEX_AGENT_B 7
|
||||
#define MILLA_INDEX_ATMOS_MODE 8
|
||||
#define MILLA_INDEX_ENVIRONMENT_ID 9
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_NORTH 10
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_EAST 11
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_SOUTH 12
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_WEST 13
|
||||
#define MILLA_INDEX_INNATE_HEAT_CAPACITY 14
|
||||
#define MILLA_INDEX_TEMPERATURE 15
|
||||
#define MILLA_INDEX_HOTSPOT_TEMPERATURE 16
|
||||
#define MILLA_INDEX_HOTSPOT_VOLUME 17
|
||||
#define MILLA_INDEX_WIND_X 18
|
||||
#define MILLA_INDEX_WIND_Y 19
|
||||
#define MILLA_INDEX_FUEL_BURNT 20
|
||||
#define MILLA_INDEX_HYDROGEN 8
|
||||
#define MILLA_INDEX_ATMOS_MODE 9
|
||||
#define MILLA_INDEX_ENVIRONMENT_ID 10
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_NORTH 11
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_EAST 12
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_SOUTH 13
|
||||
#define MILLA_INDEX_SUPERCONDUCTIVITY_WEST 14
|
||||
#define MILLA_INDEX_INNATE_HEAT_CAPACITY 15
|
||||
#define MILLA_INDEX_TEMPERATURE 16
|
||||
#define MILLA_INDEX_HOTSPOT_TEMPERATURE 17
|
||||
#define MILLA_INDEX_HOTSPOT_VOLUME 18
|
||||
#define MILLA_INDEX_WIND_X 19
|
||||
#define MILLA_INDEX_WIND_Y 20
|
||||
#define MILLA_INDEX_FUEL_BURNT 21
|
||||
|
||||
/// The number of values per tile.
|
||||
#define MILLA_TILE_SIZE MILLA_INDEX_FUEL_BURNT
|
||||
|
||||
// These are only for InterestingTiles.
|
||||
#define MILLA_INDEX_TURF 21
|
||||
#define MILLA_INDEX_INTERESTING_REASONS 22
|
||||
#define MILLA_INDEX_AIRFLOW_X 23
|
||||
#define MILLA_INDEX_AIRFLOW_Y 24
|
||||
#define MILLA_INDEX_TURF 22
|
||||
#define MILLA_INDEX_INTERESTING_REASONS 23
|
||||
#define MILLA_INDEX_AIRFLOW_X 24
|
||||
#define MILLA_INDEX_AIRFLOW_Y 25
|
||||
|
||||
/// The number of values per interesting tile.
|
||||
#define MILLA_INTERESTING_TILE_SIZE MILLA_INDEX_AIRFLOW_Y
|
||||
|
||||
@@ -12,14 +12,15 @@
|
||||
var/moles_of_gas = null
|
||||
///Linda flag for the expelled gas because we need to use special flags for it that are not readable in game well.
|
||||
var/linda_flags = null
|
||||
/// Possible gases to expel, with how much moles they create.
|
||||
/// Possible gases to expel, with how many moles they create.
|
||||
var/static/list/possible_gases = list(
|
||||
"Oxygen" = 50,
|
||||
"Nitrogen" = 750, //overpressurizing is hard!.
|
||||
"N2O" = 15,
|
||||
"CO2" = 50,
|
||||
"Plasma" = 5,
|
||||
"Agent B" = 5
|
||||
"Agent B" = 5,
|
||||
"Hydrogen" = 15
|
||||
)
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/gaseous/Initialize(mapload, mob/living/host)
|
||||
@@ -66,6 +67,8 @@
|
||||
linda_flags = LINDA_SPAWN_TOXINS | LINDA_SPAWN_20C
|
||||
if("Agent B")
|
||||
linda_flags = LINDA_SPAWN_AGENT_B | LINDA_SPAWN_20C
|
||||
if("Hydrogen")
|
||||
linda_flags = LINDA_SPAWN_HYDROGEN | LINDA_SPAWN_20C
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/gaseous/experience_pressure_difference(flow_x, flow_y)
|
||||
return // Immune to gas flow.
|
||||
|
||||
@@ -7,6 +7,7 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
#define SENSOR_N2 (1<<4)
|
||||
#define SENSOR_CO2 (1<<5)
|
||||
#define SENSOR_N2O (1<<6)
|
||||
#define SENSOR_H2 (1<<7)
|
||||
|
||||
/obj/machinery/atmospherics/air_sensor
|
||||
icon_state = "gsensor1"
|
||||
@@ -62,6 +63,7 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
"Nitrogen: [ONOFF_TOGGLE(SENSOR_N2)]" = SENSOR_N2,
|
||||
"Carbon Dioxide: [ONOFF_TOGGLE(SENSOR_CO2)]" = SENSOR_CO2,
|
||||
"Nitrous Oxide: [ONOFF_TOGGLE(SENSOR_N2O)]" = SENSOR_N2O,
|
||||
"Hydrogen: [ONOFF_TOGGLE(SENSOR_H2)]" = SENSOR_H2,
|
||||
"-SAVE TO BUFFER-" = "multitool"
|
||||
)
|
||||
|
||||
@@ -86,6 +88,8 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
output ^= SENSOR_CO2
|
||||
if(SENSOR_N2O)
|
||||
output ^= SENSOR_N2O
|
||||
if(SENSOR_H2)
|
||||
output ^= SENSOR_H2
|
||||
if("multitool")
|
||||
if(!ismultitool(I)) // Should never happen
|
||||
return
|
||||
@@ -258,6 +262,11 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
else
|
||||
sensor_data -= "n2o"
|
||||
|
||||
if(AS.output & SENSOR_H2)
|
||||
sensor_data["h2"] = round(100 * air_sample.hydrogen() / total_moles, 0.1)
|
||||
else
|
||||
sensor_data -= "h2"
|
||||
|
||||
else if(istype(AM, /obj/machinery/atmospherics/meter))
|
||||
var/list/meter_data = sensor_name_data_map[sensor_name]
|
||||
var/obj/machinery/atmospherics/meter/the_meter = AM
|
||||
@@ -350,7 +359,8 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
"filter_n2" = scrubber.scrub_N2,
|
||||
"filter_co2" = scrubber.scrub_CO2,
|
||||
"filter_toxins" = scrubber.scrub_Toxins,
|
||||
"filter_n2o" = scrubber.scrub_N2O))
|
||||
"filter_n2o" = scrubber.scrub_N2O,
|
||||
"filter_h2" = scrubber.scrub_H2))
|
||||
|
||||
|
||||
/obj/machinery/computer/general_air_control/large_tank_control/multitool_act(mob/living/user, obj/item/I)
|
||||
@@ -477,7 +487,8 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
"filter_n2" = scrubber.scrub_N2,
|
||||
"filter_co2" = scrubber.scrub_CO2,
|
||||
"filter_toxins" = scrubber.scrub_Toxins,
|
||||
"filter_n2o" = scrubber.scrub_N2O))
|
||||
"filter_n2o" = scrubber.scrub_N2O,
|
||||
"filter_h2" = scrubber.scrub_H2))
|
||||
refresh_outlets()
|
||||
to_chat(user, "<span class='notice'>Successfully added an outlet scrubber</span>")
|
||||
return
|
||||
@@ -565,6 +576,7 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
outlet_scrubber_data[uid]["filter_co2"] = scrubber.scrub_CO2
|
||||
outlet_scrubber_data[uid]["filter_toxins"] = scrubber.scrub_Toxins
|
||||
outlet_scrubber_data[uid]["filter_n2o"] = scrubber.scrub_N2O
|
||||
outlet_scrubber_data[uid]["filter_h2"] = scrubber.scrub_H2
|
||||
|
||||
/obj/machinery/computer/general_air_control/large_tank_control/refresh_all()
|
||||
..()
|
||||
@@ -650,6 +662,8 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
scrubber.scrub_N2 = !scrubber.scrub_N2
|
||||
if("o2_scrub")
|
||||
scrubber.scrub_O2 = !scrubber.scrub_O2
|
||||
if("scrub_h2")
|
||||
scrubber.scrub_H2 = !scrubber.scrub_H2
|
||||
if("widenet")
|
||||
scrubber.widenet = !scrubber.widenet
|
||||
if("scrubbing")
|
||||
@@ -704,3 +718,4 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
#undef SENSOR_N2
|
||||
#undef SENSOR_CO2
|
||||
#undef SENSOR_N2O
|
||||
#undef SENSOR_H2
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
gasdata.Add(list(list("name"= "Plasma", "amount" = air.toxins(), "portion" = round(100 * air.toxins() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name"= "Nitrous Oxide", "amount" = air.sleeping_agent(), "portion" = round(100 * air.sleeping_agent() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name"= "Agent B", "amount" = air.agent_b(), "portion" = round(100 * air.agent_b() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name"= "Hydrogen", "amount" = air.hydrogen(), "portion" = round(100 * air.hydrogen() / TM, 0.01))))
|
||||
else
|
||||
gasdata.Add(list(list("name"= "Oxygen", "amount" = 0, "portion" = 0)))
|
||||
gasdata.Add(list(list("name"= "Carbon Dioxide", "amount" = 0,"portion" = 0)))
|
||||
@@ -74,6 +75,7 @@
|
||||
gasdata.Add(list(list("name"= "Plasma", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name"= "Nitrous Oxide", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name"= "Agent B", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name"= "Hydrogen", "amount" = 0,"portion" = 0)))
|
||||
data["gases"] = gasdata
|
||||
else
|
||||
var/list/SMS = list()
|
||||
|
||||
@@ -749,6 +749,7 @@ SLIME SCANNER
|
||||
var/carbon_dioxide = 0
|
||||
var/sleeping_agent = 0
|
||||
var/agent_b = 0
|
||||
var/hydrogen = 0
|
||||
|
||||
if(detailed)// Present all mixtures one by one
|
||||
for(var/datum/gas_mixture/air as anything in airs)
|
||||
@@ -771,6 +772,8 @@ SLIME SCANNER
|
||||
message += " <span class='sleeping_agent'>Nitrous Oxide: [round(air.sleeping_agent(), 0.01)] moles ([round(air.sleeping_agent() / total_moles * 100, 0.01)] %)</span>"
|
||||
if(air.agent_b() && (milla_turf_details || air.agent_b() / total_moles > 0.01))
|
||||
message += " <span class='agent_b'>Agent B: [round(air.agent_b(), 0.01)] moles ([round(air.agent_b() / total_moles * 100, 0.01)] %)</span>"
|
||||
if(air.hydrogen() && (milla_turf_details || air.hydrogen() / total_moles > 0.01))
|
||||
message += " <span class='plasma'>Hydrogen: [round(air.hydrogen(), 0.01)] moles ([round(air.hydrogen() / total_moles * 100, 0.01)] %)</span>"
|
||||
message += "<span class='notice'>Temperature: [round(air.temperature()-T0C)] °C ([round(air.temperature())] K)</span>"
|
||||
message += "<span class='notice'>Volume: [round(volume)] Liters</span>"
|
||||
message += "<span class='notice'>Pressure: [round(pressure, 0.1)] kPa</span>"
|
||||
@@ -794,6 +797,7 @@ SLIME SCANNER
|
||||
carbon_dioxide += air.carbon_dioxide()
|
||||
sleeping_agent += air.sleeping_agent()
|
||||
agent_b += air.agent_b()
|
||||
hydrogen += air.hydrogen()
|
||||
|
||||
var/temperature = heat_capacity ? thermal_energy / heat_capacity : 0
|
||||
pressure = volume ? total_moles * R_IDEAL_GAS_EQUATION * temperature / volume : 0
|
||||
@@ -812,6 +816,8 @@ SLIME SCANNER
|
||||
message += " <span class='sleeping_agent'>Nitrous Oxide: [round(sleeping_agent, 0.01)] moles ([round(sleeping_agent / total_moles * 100, 0.01)] %)</span>"
|
||||
if(agent_b && (milla_turf_details || agent_b / total_moles > 0.01))
|
||||
message += " <span class='agent_b'>Agent B: [round(agent_b, 0.01)] moles ([round(agent_b / total_moles * 100, 0.01)] %)</span>"
|
||||
if(hydrogen && (milla_turf_details || hydrogen / total_moles > 0.01))
|
||||
message += " <span class='hydrogen'>Hydrogen: [round(hydrogen, 0.01)] moles ([round(hydrogen / total_moles * 100, 0.01)] %)</span>"
|
||||
message += "<span class='notice'>Temperature: [round(temperature-T0C)] °C ([round(temperature)] K)</span>"
|
||||
message += "<span class='notice'>Volume: [round(volume)] Liters</span>"
|
||||
message += "<span class='notice'>Pressure: [round(pressure, 0.1)] kPa</span>"
|
||||
|
||||
@@ -303,6 +303,18 @@
|
||||
oxygen = 2644
|
||||
nitrogen = 10580
|
||||
|
||||
/turf/simulated/floor/engine/agent_b
|
||||
name = "\improper agent B floor"
|
||||
agent_b = 10000
|
||||
oxygen = 0
|
||||
nitrogen = 0
|
||||
|
||||
/turf/simulated/floor/engine/hydrogen
|
||||
name = "\improper H2 floor"
|
||||
hydrogen = 100000
|
||||
oxygen = 0
|
||||
nitrogen = 0
|
||||
|
||||
/turf/simulated/floor/engine/xenobio
|
||||
oxygen = 0
|
||||
temperature = 80
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
var/toxins = 0
|
||||
var/sleeping_agent = 0
|
||||
var/agent_b = 0
|
||||
var/hydrogen = 0
|
||||
|
||||
//Properties for airtight tiles (/wall)
|
||||
var/thermal_conductivity = 0.05
|
||||
@@ -448,6 +449,7 @@
|
||||
merged.set_toxins(merged.toxins() / turf_count)
|
||||
merged.set_sleeping_agent(merged.sleeping_agent() / turf_count)
|
||||
merged.set_agent_b(merged.agent_b() / turf_count)
|
||||
merged.set_hydrogen(merged.hydrogen() / turf_count)
|
||||
get_turf_air(self).copy_from(merged)
|
||||
|
||||
/turf/proc/ReplaceWithLattice()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
if(T.active_hotspot)
|
||||
burning = 1
|
||||
|
||||
to_chat(usr, "<span class='notice'>@[target.x],[target.y]: O:[GM.oxygen()] T:[GM.toxins()] N:[GM.nitrogen()] C:[GM.carbon_dioxide()] N2O: [GM.sleeping_agent()] Agent B: [GM.agent_b()] w [GM.temperature()] Kelvin, [GM.return_pressure()] kPa [(burning)?("<span class='warning'>BURNING</span>"):(null)]</span>")
|
||||
to_chat(usr, "<span class='notice'>@[target.x],[target.y]: O:[GM.oxygen()] T:[GM.toxins()] N:[GM.nitrogen()] C:[GM.carbon_dioxide()] N2O: [GM.sleeping_agent()] Agent B: [GM.agent_b()] Hydrogen: [GM.hydrogen()] w [GM.temperature()] Kelvin, [GM.return_pressure()] kPa [(burning)?("<span class='warning'>BURNING</span>"):(null)]</span>")
|
||||
|
||||
message_admins("[key_name_admin(usr)] has checked the air status of [target]")
|
||||
log_admin("[key_name(usr)] has checked the air status of [target]")
|
||||
|
||||
@@ -144,4 +144,7 @@
|
||||
G.set_oxygen(G.oxygen() + MOLES_O2STANDARD * amount)
|
||||
G.set_nitrogen(G.nitrogen() + MOLES_N2STANDARD * amount)
|
||||
|
||||
if(flag & LINDA_SPAWN_HYDROGEN)
|
||||
G.set_hydrogen(G.hydrogen() + amount)
|
||||
|
||||
blind_release_air(G)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
air.set_toxins(toxins)
|
||||
air.set_sleeping_agent(sleeping_agent)
|
||||
air.set_agent_b(agent_b)
|
||||
air.set_hydrogen(hydrogen)
|
||||
air.set_temperature(temperature)
|
||||
else
|
||||
air.set_oxygen(0)
|
||||
@@ -20,6 +21,7 @@
|
||||
air.set_toxins(0)
|
||||
air.set_sleeping_agent(0)
|
||||
air.set_agent_b(0)
|
||||
air.set_hydrogen(0)
|
||||
air.set_temperature(0)
|
||||
return air
|
||||
|
||||
@@ -178,7 +180,7 @@
|
||||
/turf/proc/Initialize_Atmos(milla_tick)
|
||||
// This is one of two places expected to call this otherwise-unsafe method.
|
||||
var/list/connectivity = private_unsafe_recalculate_atmos_connectivity()
|
||||
var/list/air = list(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, temperature)
|
||||
var/list/air = list(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, temperature)
|
||||
milla_data = connectivity[1] + list(atmos_mode, SSmapping.environments[atmos_environment]) + air + connectivity[2]
|
||||
|
||||
/turf/simulated/Initialize_Atmos(milla_tick)
|
||||
|
||||
@@ -8,9 +8,16 @@ What are the archived variables for?
|
||||
#define SPECIFIC_HEAT_CDO 30
|
||||
#define SPECIFIC_HEAT_N2O 40
|
||||
#define SPECIFIC_HEAT_AGENT_B 300
|
||||
#define SPECIFIC_HEAT_HYDROGEN 15
|
||||
|
||||
#define HEAT_CAPACITY_CALCULATION(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, innate_heat_capacity) \
|
||||
(carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + toxins * SPECIFIC_HEAT_TOXIN + sleeping_agent * SPECIFIC_HEAT_N2O + agent_b * SPECIFIC_HEAT_AGENT_B + innate_heat_capacity)
|
||||
#define HEAT_CAPACITY_CALCULATION(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, innate_heat_capacity) \
|
||||
(carbon_dioxide * SPECIFIC_HEAT_CDO + \
|
||||
(oxygen + nitrogen) * SPECIFIC_HEAT_AIR + \
|
||||
toxins * SPECIFIC_HEAT_TOXIN + \
|
||||
sleeping_agent * SPECIFIC_HEAT_N2O + \
|
||||
agent_b * SPECIFIC_HEAT_AGENT_B + \
|
||||
hydrogen * SPECIFIC_HEAT_HYDROGEN + \
|
||||
innate_heat_capacity)
|
||||
|
||||
#define MINIMUM_HEAT_CAPACITY 0.0003
|
||||
#define MINIMUM_MOLE_COUNT 0.01
|
||||
@@ -32,6 +39,7 @@ What are the archived variables for?
|
||||
var/private_toxins = 0
|
||||
var/private_sleeping_agent = 0
|
||||
var/private_agent_b = 0
|
||||
var/private_hydrogen = 0
|
||||
var/private_temperature = 0 //in Kelvin
|
||||
var/private_hotspot_temperature = 0
|
||||
var/private_hotspot_volume = 0
|
||||
@@ -45,6 +53,7 @@ What are the archived variables for?
|
||||
var/private_toxins_archived = 0
|
||||
var/private_sleeping_agent_archived = 0
|
||||
var/private_agent_b_archived = 0
|
||||
var/private_hydrogen_archived = 0
|
||||
var/private_temperature_archived = 0
|
||||
|
||||
/// Is this mixture currently synchronized with MILLA? Always true for non-bound mixtures.
|
||||
@@ -120,6 +129,18 @@ What are the archived variables for?
|
||||
stack_trace("Out-of-bounds value [value] clamped to [clamped].")
|
||||
private_agent_b = clamped
|
||||
|
||||
/datum/gas_mixture/proc/hydrogen()
|
||||
return private_hydrogen
|
||||
|
||||
/datum/gas_mixture/proc/set_hydrogen(value)
|
||||
if(isnan(value) || !isnum(value))
|
||||
CRASH("Bad value: [value]")
|
||||
var/clamped = clamp(value, 0, 1e10)
|
||||
if(value != clamped)
|
||||
stack_trace("Out-of-bounds value [value] clamped to [clamped].")
|
||||
private_hydrogen = clamped
|
||||
|
||||
|
||||
/datum/gas_mixture/proc/temperature()
|
||||
return private_temperature
|
||||
|
||||
@@ -142,14 +163,14 @@ What are the archived variables for?
|
||||
|
||||
///joules per kelvin
|
||||
/datum/gas_mixture/proc/heat_capacity()
|
||||
return HEAT_CAPACITY_CALCULATION(private_oxygen, private_carbon_dioxide, private_nitrogen, private_toxins, private_sleeping_agent, private_agent_b, innate_heat_capacity)
|
||||
return HEAT_CAPACITY_CALCULATION(private_oxygen, private_carbon_dioxide, private_nitrogen, private_toxins, private_sleeping_agent, private_agent_b, private_hydrogen, innate_heat_capacity)
|
||||
|
||||
/datum/gas_mixture/proc/heat_capacity_archived()
|
||||
return HEAT_CAPACITY_CALCULATION(private_oxygen_archived, private_carbon_dioxide_archived, private_nitrogen_archived, private_toxins_archived, private_sleeping_agent_archived, private_agent_b_archived, innate_heat_capacity)
|
||||
return HEAT_CAPACITY_CALCULATION(private_oxygen_archived, private_carbon_dioxide_archived, private_nitrogen_archived, private_toxins_archived, private_sleeping_agent_archived, private_agent_b_archived, private_hydrogen_archived, innate_heat_capacity)
|
||||
|
||||
/// Calculate moles
|
||||
/datum/gas_mixture/proc/total_moles()
|
||||
return private_oxygen + private_carbon_dioxide + private_nitrogen + private_toxins + private_sleeping_agent + private_agent_b
|
||||
return private_oxygen + private_carbon_dioxide + private_nitrogen + private_toxins + private_sleeping_agent + private_agent_b + private_hydrogen
|
||||
|
||||
/datum/gas_mixture/proc/total_trace_moles()
|
||||
return private_agent_b
|
||||
@@ -176,6 +197,7 @@ What are the archived variables for?
|
||||
private_toxins_archived = private_toxins
|
||||
private_sleeping_agent_archived = private_sleeping_agent
|
||||
private_agent_b_archived = private_agent_b
|
||||
private_hydrogen_archived = private_hydrogen
|
||||
|
||||
private_temperature_archived = private_temperature
|
||||
|
||||
@@ -200,6 +222,7 @@ What are the archived variables for?
|
||||
private_toxins += giver.private_toxins
|
||||
private_sleeping_agent += giver.private_sleeping_agent
|
||||
private_agent_b += giver.private_agent_b
|
||||
private_hydrogen += giver.private_hydrogen
|
||||
|
||||
set_dirty()
|
||||
return TRUE
|
||||
@@ -228,6 +251,7 @@ What are the archived variables for?
|
||||
removed.private_toxins = QUANTIZE((private_toxins / sum) * amount)
|
||||
removed.private_sleeping_agent = QUANTIZE((private_sleeping_agent / sum) * amount)
|
||||
removed.private_agent_b = QUANTIZE((private_agent_b / sum) * amount)
|
||||
removed.private_hydrogen = QUANTIZE((private_hydrogen / sum) * amount)
|
||||
|
||||
private_oxygen = max(private_oxygen - removed.private_oxygen, 0)
|
||||
private_nitrogen = max(private_nitrogen - removed.private_nitrogen, 0)
|
||||
@@ -235,6 +259,7 @@ What are the archived variables for?
|
||||
private_toxins = max(private_toxins - removed.private_toxins, 0)
|
||||
private_sleeping_agent = max(private_sleeping_agent - removed.private_sleeping_agent, 0)
|
||||
private_agent_b = max(private_agent_b - removed.private_agent_b, 0)
|
||||
private_hydrogen = max(private_hydrogen - removed.private_hydrogen, 0)
|
||||
|
||||
removed.private_temperature = private_temperature
|
||||
|
||||
@@ -258,6 +283,7 @@ What are the archived variables for?
|
||||
removed.private_toxins = QUANTIZE(private_toxins * ratio)
|
||||
removed.private_sleeping_agent = QUANTIZE(private_sleeping_agent * ratio)
|
||||
removed.private_agent_b = QUANTIZE(private_agent_b * ratio)
|
||||
removed.private_hydrogen = QUANTIZE(private_hydrogen * ratio)
|
||||
|
||||
private_oxygen = max(private_oxygen - removed.private_oxygen, 0)
|
||||
private_nitrogen = max(private_nitrogen - removed.private_nitrogen, 0)
|
||||
@@ -265,6 +291,7 @@ What are the archived variables for?
|
||||
private_toxins = max(private_toxins - removed.private_toxins, 0)
|
||||
private_sleeping_agent = max(private_sleeping_agent - removed.private_sleeping_agent, 0)
|
||||
private_agent_b = max(private_agent_b - removed.private_agent_b, 0)
|
||||
private_hydrogen = max(private_hydrogen - removed.private_hydrogen, 0)
|
||||
|
||||
removed.private_temperature = private_temperature
|
||||
set_dirty()
|
||||
@@ -279,6 +306,7 @@ What are the archived variables for?
|
||||
private_toxins = sample.private_toxins
|
||||
private_sleeping_agent = sample.private_sleeping_agent
|
||||
private_agent_b = sample.private_agent_b
|
||||
private_hydrogen = sample.private_hydrogen
|
||||
|
||||
private_temperature = sample.private_temperature
|
||||
set_dirty()
|
||||
@@ -294,6 +322,7 @@ What are the archived variables for?
|
||||
private_toxins = model.toxins
|
||||
private_sleeping_agent = model.sleeping_agent
|
||||
private_agent_b = model.agent_b
|
||||
private_hydrogen = model.hydrogen
|
||||
|
||||
//acounts for changes in temperature
|
||||
var/turf/model_parent = model.parent_type
|
||||
@@ -318,6 +347,7 @@ What are the archived variables for?
|
||||
var/delta_toxins = QUANTIZE(private_toxins_archived - sharer.private_toxins_archived) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_sleeping_agent = QUANTIZE(private_sleeping_agent_archived - sharer.private_sleeping_agent_archived) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_agent_b = QUANTIZE(private_agent_b_archived - sharer.private_agent_b_archived) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_hydrogen = QUANTIZE(private_hydrogen_archived - sharer.private_hydrogen_archived) / (atmos_adjacent_turfs + 1)
|
||||
|
||||
var/delta_temperature = (private_temperature_archived - sharer.private_temperature_archived)
|
||||
|
||||
@@ -365,6 +395,13 @@ What are the archived variables for?
|
||||
else
|
||||
heat_capacity_sharer_to_self -= agent_b_heat_capacity
|
||||
|
||||
if(delta_hydrogen)
|
||||
var/hydrogen_heat_capacity = SPECIFIC_HEAT_HYDROGEN * delta_hydrogen
|
||||
if(delta_hydrogen > 0)
|
||||
heat_capacity_self_to_sharer += hydrogen_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= hydrogen_heat_capacity
|
||||
|
||||
old_self_heat_capacity = heat_capacity()
|
||||
old_sharer_heat_capacity = sharer.heat_capacity()
|
||||
|
||||
@@ -386,7 +423,10 @@ What are the archived variables for?
|
||||
private_agent_b -= delta_agent_b
|
||||
sharer.private_agent_b += delta_agent_b
|
||||
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins + delta_sleeping_agent + delta_agent_b)
|
||||
private_hydrogen -= delta_hydrogen
|
||||
sharer.private_hydrogen += delta_hydrogen
|
||||
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins + delta_sleeping_agent + delta_agent_b + delta_hydrogen)
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
|
||||
@@ -416,6 +456,7 @@ What are the archived variables for?
|
||||
var/delta_toxins = QUANTIZE(private_toxins_archived - model.toxins) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_sleeping_agent = QUANTIZE(private_sleeping_agent_archived - model.sleeping_agent) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_agent_b = QUANTIZE(private_agent_b_archived - model.agent_b) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_hydrogen = QUANTIZE(private_hydrogen_archived - model.hydrogen) / (atmos_adjacent_turfs + 1)
|
||||
|
||||
var/delta_temperature = (private_temperature_archived - model.temperature)
|
||||
|
||||
@@ -451,6 +492,11 @@ What are the archived variables for?
|
||||
heat_transferred -= agent_b_heat_capacity * model.temperature
|
||||
heat_capacity_transferred -= agent_b_heat_capacity
|
||||
|
||||
if(delta_hydrogen)
|
||||
var/hydrogen_heat_capacity = SPECIFIC_HEAT_HYDROGEN * delta_hydrogen
|
||||
heat_transferred -= hydrogen_heat_capacity * model.temperature
|
||||
heat_capacity_transferred -= hydrogen_heat_capacity
|
||||
|
||||
old_self_heat_capacity = heat_capacity()
|
||||
|
||||
private_oxygen -= delta_oxygen
|
||||
@@ -459,8 +505,9 @@ What are the archived variables for?
|
||||
private_toxins -= delta_toxins
|
||||
private_sleeping_agent -= delta_sleeping_agent
|
||||
private_agent_b -= delta_agent_b
|
||||
private_hydrogen -= delta_hydrogen
|
||||
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins + delta_sleeping_agent + delta_agent_b)
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins + delta_sleeping_agent + delta_agent_b + delta_hydrogen)
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred
|
||||
@@ -471,7 +518,7 @@ What are the archived variables for?
|
||||
|
||||
set_dirty()
|
||||
if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/delta_pressure = private_temperature_archived * (total_moles() + moved_moles) - model.temperature * (model.oxygen + model.carbon_dioxide + model.nitrogen + model.toxins + model.sleeping_agent + model.agent_b)
|
||||
var/delta_pressure = private_temperature_archived * (total_moles() + moved_moles) - model.temperature * (model.oxygen + model.carbon_dioxide + model.nitrogen + model.toxins + model.sleeping_agent + model.agent_b + model.hydrogen)
|
||||
return delta_pressure * R_IDEAL_GAS_EQUATION / volume
|
||||
else
|
||||
return 0
|
||||
@@ -484,6 +531,7 @@ What are the archived variables for?
|
||||
var/delta_toxins = (private_toxins_archived - model.toxins) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_sleeping_agent = (private_sleeping_agent_archived - model.sleeping_agent) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_agent_b = (private_agent_b_archived - model.agent_b) / (atmos_adjacent_turfs + 1)
|
||||
var/delta_hydrogen = (private_hydrogen_archived - model.hydrogen) / (atmos_adjacent_turfs + 1)
|
||||
|
||||
var/delta_temperature = (private_temperature_archived - model.temperature)
|
||||
|
||||
@@ -492,7 +540,8 @@ What are the archived variables for?
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= private_nitrogen_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= private_toxins_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_sleeping_agent) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_sleeping_agent) >= private_sleeping_agent_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_agent_b) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_agent_b) >= private_agent_b_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
|| ((abs(delta_agent_b) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_agent_b) >= private_agent_b_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_hydrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_hydrogen) >= private_hydrogen_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return FALSE
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return FALSE
|
||||
@@ -561,6 +610,9 @@ What are the archived variables for?
|
||||
if((abs(private_agent_b - sample.private_agent_b) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((private_agent_b < (1 - MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.private_agent_b) || (private_agent_b > (1 + MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.private_agent_b)))
|
||||
return FALSE
|
||||
if((abs(private_hydrogen - sample.private_hydrogen) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((private_hydrogen < (1 - MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.private_hydrogen) || (private_hydrogen > (1 + MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.private_hydrogen)))
|
||||
return FALSE
|
||||
|
||||
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
if((abs(private_temperature - sample.private_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
|
||||
@@ -575,6 +627,7 @@ What are the archived variables for?
|
||||
var/delta_toxins = (private_toxins - model.toxins)
|
||||
var/delta_sleeping_agent = (private_sleeping_agent - model.sleeping_agent)
|
||||
var/delta_agent_b = (private_agent_b - model.agent_b)
|
||||
var/delta_hydrogen = (private_hydrogen - model.hydrogen)
|
||||
|
||||
var/delta_temperature = (private_temperature - model.temperature)
|
||||
|
||||
@@ -583,7 +636,8 @@ What are the archived variables for?
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= private_nitrogen * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= private_toxins * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_sleeping_agent) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_sleeping_agent) >= private_sleeping_agent * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_agent_b) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_agent_b) >= private_agent_b * MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
|| ((abs(delta_agent_b) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_agent_b) >= private_agent_b * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_hydrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_hydrogen) >= private_hydrogen * MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return FALSE
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return FALSE
|
||||
@@ -668,6 +722,34 @@ What are the archived variables for?
|
||||
if(fuel_burnt)
|
||||
reacting = TRUE
|
||||
|
||||
// handles hydrogen burning
|
||||
if((private_hydrogen >= 0) && (private_oxygen >= 0) && private_temperature > HYDROGEN_MIN_IGNITE_TEMP)
|
||||
// Calculate the reaction rate based on temperature and pressure
|
||||
var/reaction_rate = (private_temperature / (private_temperature + 2000)) * (return_pressure() / (return_pressure() + 100))
|
||||
// Burn a portion of our hydrogen equal to reaction_rate, but no more than we have or have oxygen for.
|
||||
var/burned_hydrogen = min(reaction_rate * private_hydrogen, private_hydrogen, private_oxygen * 2)
|
||||
var/burned_oxygen = min(burned_hydrogen / 2, private_oxygen)
|
||||
// var/produced_water_vapor = (burned_hydrogen / H2_NEEDED_FOR_H2O)
|
||||
|
||||
|
||||
var/old_heat_capacity = heat_capacity()
|
||||
|
||||
// Burn gasses
|
||||
private_hydrogen -= burned_hydrogen
|
||||
private_oxygen -= burned_oxygen
|
||||
// private_water_vapor += produced_water_vapor
|
||||
|
||||
// Calculate gained energy
|
||||
var/energy_released = HYDROGEN_BURN_ENERGY * burned_hydrogen
|
||||
// Calculate post-burn heat capacity
|
||||
var/new_heat_capacity = heat_capacity()
|
||||
// Calculate new temperature
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
private_temperature = (private_temperature * old_heat_capacity + energy_released) / new_heat_capacity
|
||||
|
||||
if(fuel_burnt)
|
||||
reacting = TRUE
|
||||
|
||||
set_dirty()
|
||||
return reacting
|
||||
|
||||
@@ -691,6 +773,7 @@ What are the archived variables for?
|
||||
private_toxins = milla[MILLA_INDEX_TOXINS]
|
||||
private_sleeping_agent = milla[MILLA_INDEX_SLEEPING_AGENT]
|
||||
private_agent_b = milla[MILLA_INDEX_AGENT_B]
|
||||
private_hydrogen = milla[MILLA_INDEX_HYDROGEN]
|
||||
innate_heat_capacity = milla[MILLA_INDEX_INNATE_HEAT_CAPACITY]
|
||||
private_temperature = milla[MILLA_INDEX_TEMPERATURE]
|
||||
private_hotspot_temperature = milla[MILLA_INDEX_HOTSPOT_TEMPERATURE]
|
||||
@@ -705,6 +788,7 @@ What are the archived variables for?
|
||||
var/total_carbon_dioxide = 0
|
||||
var/total_sleeping_agent = 0
|
||||
var/total_agent_b = 0
|
||||
var/total_hydrogen = 0
|
||||
var/must_share = FALSE
|
||||
|
||||
// Collect all the cheap data and check if there's a significant temperature difference.
|
||||
@@ -725,11 +809,12 @@ What are the archived variables for?
|
||||
total_carbon_dioxide += G.private_carbon_dioxide
|
||||
total_sleeping_agent += G.private_sleeping_agent
|
||||
total_agent_b += G.private_agent_b
|
||||
total_hydrogen += G.private_hydrogen
|
||||
|
||||
if(total_volume == 0)
|
||||
return
|
||||
|
||||
if(total_volume < 0 || isnan(total_volume) || !isnum(total_volume) || total_oxygen < 0 || isnan(total_oxygen) || !isnum(total_oxygen) || total_nitrogen < 0 || isnan(total_nitrogen) || !isnum(total_nitrogen) || total_toxins < 0 || isnan(total_toxins) || !isnum(total_toxins) || total_carbon_dioxide < 0 || isnan(total_carbon_dioxide) || !isnum(total_carbon_dioxide) || total_sleeping_agent < 0 || isnan(total_sleeping_agent) || !isnum(total_sleeping_agent) || total_agent_b < 0 || isnan(total_agent_b) || !isnum(total_agent_b))
|
||||
if(total_volume < 0 || isnan(total_volume) || !isnum(total_volume) || total_oxygen < 0 || isnan(total_oxygen) || !isnum(total_oxygen) || total_nitrogen < 0 || isnan(total_nitrogen) || !isnum(total_nitrogen) || total_toxins < 0 || isnan(total_toxins) || !isnum(total_toxins) || total_carbon_dioxide < 0 || isnan(total_carbon_dioxide) || !isnum(total_carbon_dioxide) || total_sleeping_agent < 0 || isnan(total_sleeping_agent) || !isnum(total_sleeping_agent) || total_agent_b < 0 || isnan(total_agent_b) || !isnum(total_agent_b) || total_hydrogen < 0 || isnan(total_hydrogen) || !isnum(total_hydrogen))
|
||||
CRASH("A pipenet with [length(mixtures)] connected airs is corrupt and cannot flow safely. Pipenet root is [root] at ([root.x], [root.y], [root.z]).")
|
||||
|
||||
// If we don't have a significant temperature difference, check for a significant gas amount difference.
|
||||
@@ -755,6 +840,9 @@ What are the archived variables for?
|
||||
if(abs(G.private_agent_b - total_agent_b * G.volume / total_volume) > 0.1)
|
||||
must_share = TRUE
|
||||
break
|
||||
if(abs(G.private_hydrogen - total_hydrogen * G.volume / total_volume) > 0.1)
|
||||
must_share = TRUE
|
||||
break
|
||||
|
||||
if(!must_share)
|
||||
// Nothing significant, don't do any more work.
|
||||
@@ -788,6 +876,7 @@ What are the archived variables for?
|
||||
G.private_carbon_dioxide = total_carbon_dioxide * G.volume / total_volume
|
||||
G.private_sleeping_agent = total_sleeping_agent * G.volume / total_volume
|
||||
G.private_agent_b = total_agent_b * G.volume / total_volume
|
||||
G.private_hydrogen = total_hydrogen * G.volume / total_volume
|
||||
|
||||
G.private_temperature = temperature
|
||||
// In theory, we should G.set_dirty() here, but that's only useful for bound mixtures, and these can't be.
|
||||
@@ -800,6 +889,7 @@ What are the archived variables for?
|
||||
#undef SPECIFIC_HEAT_CDO
|
||||
#undef SPECIFIC_HEAT_N2O
|
||||
#undef SPECIFIC_HEAT_AGENT_B
|
||||
#undef SPECIFIC_HEAT_HYDROGEN
|
||||
#undef HEAT_CAPACITY_CALCULATION
|
||||
#undef MINIMUM_HEAT_CAPACITY
|
||||
#undef MINIMUM_MOLE_COUNT
|
||||
@@ -826,6 +916,7 @@ What are the archived variables for?
|
||||
readonly.private_toxins = private_toxins
|
||||
readonly.private_sleeping_agent = private_sleeping_agent
|
||||
readonly.private_agent_b = private_agent_b
|
||||
readonly.private_hydrogen = private_hydrogen
|
||||
readonly.private_temperature = private_temperature
|
||||
readonly.private_hotspot_temperature = private_hotspot_temperature
|
||||
readonly.private_hotspot_volume = private_hotspot_volume
|
||||
@@ -860,6 +951,10 @@ What are the archived variables for?
|
||||
private_agent_b = value
|
||||
set_dirty()
|
||||
|
||||
/datum/gas_mixture/bound_to_turf/set_hydrogen(value)
|
||||
private_hydrogen = value
|
||||
set_dirty()
|
||||
|
||||
/datum/gas_mixture/bound_to_turf/set_temperature(value)
|
||||
private_temperature = value
|
||||
set_dirty()
|
||||
@@ -871,8 +966,17 @@ What are the archived variables for?
|
||||
private_hotspot_volume = max(private_hotspot_volume, (volume / CELL_VOLUME))
|
||||
|
||||
/datum/gas_mixture/bound_to_turf/proc/private_unsafe_write()
|
||||
set_tile_atmos(bound_turf, oxygen = private_oxygen, carbon_dioxide = private_carbon_dioxide, nitrogen = private_nitrogen, toxins = private_toxins, sleeping_agent = private_sleeping_agent, agent_b = private_agent_b, temperature = private_temperature)
|
||||
|
||||
set_tile_atmos(
|
||||
bound_turf,
|
||||
oxygen = private_oxygen,
|
||||
carbon_dioxide = private_carbon_dioxide,
|
||||
nitrogen = private_nitrogen,
|
||||
toxins = private_toxins,
|
||||
sleeping_agent = private_sleeping_agent,
|
||||
agent_b = private_agent_b,
|
||||
hydrogen = private_hydrogen,
|
||||
temperature = private_temperature
|
||||
)
|
||||
/datum/gas_mixture/bound_to_turf/proc/get_readonly()
|
||||
if(isnull(readonly))
|
||||
readonly = new(src)
|
||||
@@ -888,6 +992,7 @@ What are the archived variables for?
|
||||
private_toxins = parent.private_toxins
|
||||
private_sleeping_agent = parent.private_sleeping_agent
|
||||
private_agent_b = parent.private_agent_b
|
||||
private_hydrogen = parent.private_hydrogen
|
||||
|
||||
private_temperature = parent.private_temperature
|
||||
private_hotspot_temperature = parent.private_hotspot_temperature
|
||||
@@ -915,5 +1020,8 @@ What are the archived variables for?
|
||||
/datum/gas_mixture/readonly/set_agent_b(value)
|
||||
CRASH("Attempted to modify a readonly gas_mixture.")
|
||||
|
||||
/datum/gas_mixture/readonly/set_hydrogen(value)
|
||||
CRASH("Attempted to modify a readonly gas_mixture.")
|
||||
|
||||
/datum/gas_mixture/readonly/set_temperature(value)
|
||||
CRASH("Attempted to modify a readonly gas_mixture.")
|
||||
|
||||
@@ -151,6 +151,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
"carbon dioxide" = new/datum/tlv(-1.0, -1.0, 5, 10), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"nitrous oxide" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"hydrogen" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20), /* kpa */
|
||||
"temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K
|
||||
@@ -163,6 +164,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
"carbon dioxide" = new/datum/tlv(-1.0, -1.0, 5, 10), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"nitrous oxide" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"hydrogen" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20), /* kpa */
|
||||
"temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K
|
||||
@@ -174,6 +176,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
"carbon dioxide" = new/datum/tlv(-1.0, -1.0, 5, 10), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"nitrous oxide" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"hydrogen" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.50,ONE_ATMOSPHERE*1.60), /* kpa */
|
||||
"temperature" = new/datum/tlv(T0C-50, T0C-20, T0C, T20C), // K
|
||||
@@ -185,6 +188,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
"carbon dioxide" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"nitrous oxide" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"hydrogen" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), /* kpa */
|
||||
"temperature" = new/datum/tlv(0, 0, T20C + 5, T20C + 15), // K
|
||||
@@ -197,6 +201,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
"carbon dioxide" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"plasma" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"nitrous oxide" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"hydrogen" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"other" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // Partial pressure, kpa
|
||||
"pressure" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), /* kpa */
|
||||
"temperature" = new/datum/tlv(-1.0, -1.0, -1.0, -1.0), // K
|
||||
@@ -294,6 +299,9 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
cur_tlv = TLV["nitrous oxide"]
|
||||
var/sleeping_agent_dangerlevel = cur_tlv.get_danger_level(environment.sleeping_agent() * GET_PP)
|
||||
|
||||
cur_tlv = TLV["hydrogen"]
|
||||
var/hydrogen_dangerlevel = cur_tlv.get_danger_level(environment.hydrogen() * GET_PP)
|
||||
|
||||
cur_tlv = TLV["other"]
|
||||
var/other_dangerlevel = cur_tlv.get_danger_level(environment.total_trace_moles() * GET_PP)
|
||||
|
||||
@@ -308,6 +316,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
co2_dangerlevel,
|
||||
plasma_dangerlevel,
|
||||
sleeping_agent_dangerlevel,
|
||||
hydrogen_dangerlevel,
|
||||
other_dangerlevel,
|
||||
temperature_dangerlevel
|
||||
)
|
||||
@@ -410,6 +419,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
S.scrub_CO2 = TRUE
|
||||
S.scrub_Toxins = FALSE
|
||||
S.scrub_N2O = FALSE
|
||||
S.scrub_H2 = FALSE
|
||||
S.scrubbing = TRUE
|
||||
S.widenet = FALSE
|
||||
S.update_icon(UPDATE_ICON_STATE)
|
||||
@@ -431,6 +441,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
S.scrub_CO2 = TRUE
|
||||
S.scrub_Toxins = TRUE
|
||||
S.scrub_N2O = TRUE
|
||||
S.scrub_H2 = TRUE
|
||||
S.scrubbing = TRUE
|
||||
S.widenet = TRUE
|
||||
S.update_icon(UPDATE_ICON_STATE)
|
||||
@@ -470,6 +481,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
S.scrub_CO2 = TRUE
|
||||
S.scrub_Toxins = FALSE
|
||||
S.scrub_N2O = FALSE
|
||||
S.scrub_H2 = FALSE
|
||||
S.scrubbing = TRUE
|
||||
S.widenet = FALSE
|
||||
S.update_icon(UPDATE_ICON_STATE)
|
||||
@@ -619,6 +631,10 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
var/sleeping_agent_dangerlevel = cur_tlv.get_danger_level(environment.sleeping_agent() * GET_PP)
|
||||
var/sleeping_agent_percent = total ? environment.sleeping_agent() / total * 100 : 0
|
||||
|
||||
cur_tlv = TLV["hydrogen"]
|
||||
var/hydrogen_dangerlevel = cur_tlv.get_danger_level(environment.hydrogen() * GET_PP)
|
||||
var/hydrogen_percent = total ? environment.hydrogen() / total * 100 : 0
|
||||
|
||||
cur_tlv = TLV["other"]
|
||||
var/other_moles = total - known_total
|
||||
var/other_dangerlevel = cur_tlv.get_danger_level(other_moles*GET_PP)
|
||||
@@ -639,6 +655,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
percentages["co2"] = co2_percent
|
||||
percentages["plasma"] = plasma_percent
|
||||
percentages["n2o"] = sleeping_agent_percent
|
||||
percentages["hydrogen"] = hydrogen_percent
|
||||
percentages["other"] = other_percent
|
||||
data["contents"] = percentages
|
||||
|
||||
@@ -650,8 +667,9 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
danger["co2"] = co2_dangerlevel
|
||||
danger["plasma"] = plasma_dangerlevel
|
||||
danger["n2o"] = sleeping_agent_dangerlevel
|
||||
danger["hydrogen"] = hydrogen_dangerlevel
|
||||
danger["other"] = other_dangerlevel
|
||||
danger["overall"] = max(pressure_dangerlevel,oxygen_dangerlevel,nitrogen_dangerlevel,co2_dangerlevel,plasma_dangerlevel,other_dangerlevel,temperature_dangerlevel)
|
||||
danger["overall"] = max(pressure_dangerlevel,oxygen_dangerlevel,nitrogen_dangerlevel,co2_dangerlevel,plasma_dangerlevel,hydrogen_dangerlevel,other_dangerlevel,temperature_dangerlevel)
|
||||
data["danger"] = danger
|
||||
return data
|
||||
|
||||
@@ -725,6 +743,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
scrubber_info["filter_co2"] = S.scrub_CO2
|
||||
scrubber_info["filter_toxins"] = S.scrub_Toxins
|
||||
scrubber_info["filter_n2o"] = S.scrub_N2O
|
||||
scrubber_info["filter_h2"] = S.scrub_H2
|
||||
scrubbers += list(scrubber_info)
|
||||
data["scrubbers"] = scrubbers
|
||||
return data
|
||||
@@ -752,6 +771,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
"carbon dioxide" = "CO2",
|
||||
"plasma" = "Toxin",
|
||||
"nitrous oxide" = "N2O",
|
||||
"hydrogen" = "H2",
|
||||
"other" = "Other")
|
||||
for(var/g in gas_names)
|
||||
thresholds += list(list("name" = gas_names[g], "settings" = list()))
|
||||
@@ -865,6 +885,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
"n2o_scrub",
|
||||
"n2_scrub",
|
||||
"o2_scrub",
|
||||
"h2_scrub",
|
||||
"widenet",
|
||||
"scrubbing",
|
||||
"direction")
|
||||
@@ -927,6 +948,8 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
|
||||
S.scrub_N2 = val
|
||||
if("o2_scrub")
|
||||
S.scrub_O2 = val
|
||||
if("h2_scrub")
|
||||
S.scrub_H2 = val
|
||||
if("widenet")
|
||||
S.widenet = val
|
||||
if("scrubbing")
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#define FILTER_CO2 3
|
||||
/// Nitrous oxide only.
|
||||
#define FILTER_N2O 4
|
||||
/// Hydrogen only.
|
||||
#define FILTER_H2 5
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter
|
||||
name = "gas filter"
|
||||
@@ -28,7 +30,8 @@
|
||||
"O2" = FILTER_OXYGEN,
|
||||
"N2" = FILTER_NITROGEN,
|
||||
"CO2" = FILTER_CO2,
|
||||
"N2O" = FILTER_N2O
|
||||
"N2O" = FILTER_N2O,
|
||||
"H2" = FILTER_H2,
|
||||
)
|
||||
|
||||
// So we can CtrlClick without triggering the anchored message.
|
||||
@@ -144,6 +147,10 @@
|
||||
if(FILTER_N2O)
|
||||
filtered_out.set_sleeping_agent(removed.sleeping_agent())
|
||||
removed.set_sleeping_agent(0)
|
||||
|
||||
if(FILTER_H2)
|
||||
filtered_out.set_hydrogen(removed.hydrogen())
|
||||
removed.set_hydrogen(0)
|
||||
else
|
||||
filtered_out = null
|
||||
|
||||
@@ -240,3 +247,4 @@
|
||||
#undef FILTER_NITROGEN
|
||||
#undef FILTER_CO2
|
||||
#undef FILTER_N2O
|
||||
#undef FILTER_H2
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
var/scrub_CO2 = TRUE
|
||||
var/scrub_Toxins = FALSE
|
||||
var/scrub_N2O = FALSE
|
||||
var/scrub_H2 = FALSE
|
||||
|
||||
var/volume_rate = 200
|
||||
var/widenet = FALSE //is this scrubber acting on the 3x3 area around it.
|
||||
@@ -165,6 +166,8 @@
|
||||
return TRUE
|
||||
if(environment.agent_b() > 0.001)
|
||||
return TRUE
|
||||
if(environment.hydrogen() > 0.001)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
@@ -209,6 +212,10 @@
|
||||
filtered_out.set_sleeping_agent(removed.sleeping_agent())
|
||||
removed.set_sleeping_agent(0)
|
||||
|
||||
if(scrubber.scrub_H2)
|
||||
filtered_out.set_hydrogen(removed.hydrogen())
|
||||
removed.set_hydrogen(0)
|
||||
|
||||
//Remix the resulting gases
|
||||
scrubber.air_contents.merge(filtered_out)
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
list("name" = "\[O2\]", "icon" = "blue"),
|
||||
list("name" = "\[Toxin (Bio)\]", "icon" = "orange"),
|
||||
list("name" = "\[CO2\]", "icon" = "black"),
|
||||
list("name" = "\[H2\]", "icon" = "white"),
|
||||
list("name" = "\[Air\]", "icon" = "grey"),
|
||||
list("name" = "\[CAUTION\]", "icon" = "yellow"),
|
||||
list("name" = "\[SPECIAL\]", "icon" = "whiters")
|
||||
@@ -114,7 +115,7 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
|
||||
|
||||
/obj/machinery/atmospherics/portable/canister/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Connect a canister to a connector port using a wrench. To fill a tank, attach it to the caniser, increase the \
|
||||
. += "<span class='notice'>Connect a canister to a connector port using a wrench. To fill a tank, attach it to the canister, increase the \
|
||||
release pressure, and open the valve. Alt-click to eject the tank, or use another to hot-swap. A gas analyzer can be used to check \
|
||||
the contents of the canister.</span>"
|
||||
if(isAntag(user))
|
||||
@@ -373,6 +374,11 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
|
||||
log_admin("[key_name(ui.user)] opened a canister that contains N2O at [get_area(src)]: [x], [y], [z]")
|
||||
ui.user.create_log(MISC_LOG, "has opened a canister of N2O")
|
||||
|
||||
if(air_contents.hydrogen() > 0)
|
||||
message_admins("[key_name_admin(ui.user)] opened a canister that contains Hydrogen in [get_area(src)]! (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_admin("[key_name(ui.user)] opened a canister that contains Hydrogen at [get_area(src)]: [x], [y], [z]")
|
||||
ui.user.create_log(MISC_LOG, "has opened a canister of Hydrogen")
|
||||
|
||||
else
|
||||
logmsg = "Valve was <b>closed</b> by [key_name(ui.user)], stopping the transfer into the [holding_tank || "air"].<br>"
|
||||
|
||||
@@ -435,6 +441,10 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
|
||||
name = "Canister \[CO2\]"
|
||||
icon_state = "black" //See Initialize()
|
||||
can_label = FALSE
|
||||
/obj/machinery/atmospherics/portable/canister/hydrogen
|
||||
name = "Canister \[H2\]"
|
||||
icon_state = "white" //See Initialize()
|
||||
can_label = FALSE
|
||||
/obj/machinery/atmospherics/portable/canister/air
|
||||
name = "Canister \[Air\]"
|
||||
icon_state = "grey" //See Initialize()
|
||||
@@ -486,6 +496,14 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/portable/canister/hydrogen/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
canister_color["prim"] = "white"
|
||||
air_contents.set_hydrogen((maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature()))
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/portable/canister/air/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -90,6 +90,9 @@
|
||||
filtered_out.set_agent_b(removed.agent_b())
|
||||
removed.set_agent_b(0)
|
||||
|
||||
filtered_out.set_hydrogen(removed.hydrogen())
|
||||
removed.set_hydrogen(0)
|
||||
|
||||
//Remix the resulting gases
|
||||
air_contents.merge(filtered_out)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
var/cdiox = 0
|
||||
var/nitrox = 0
|
||||
var/agentbx = 0
|
||||
var/hydrogen = 0
|
||||
|
||||
|
||||
/datum/buildmode_mode/atmos/show_help(mob/user)
|
||||
@@ -31,6 +32,7 @@
|
||||
cdiox = tgui_input_number(user, "CO2 ratio", "Input", 0, 100000, 0, round_value = FALSE)
|
||||
nitrox = tgui_input_number(user, "N2O ratio", "Input", 0, 100000, 0, round_value = FALSE)
|
||||
agentbx = tgui_input_number(user, "Agent B ratio", "Input", 0, 100000, 0, round_value = FALSE)
|
||||
hydrogen = tgui_input_number(user, "Hydrogen ratio", "Input", 0, 100000, 0, round_value = FALSE)
|
||||
|
||||
/datum/buildmode_mode/atmos/proc/ppratio_to_moles(ppratio)
|
||||
// ideal gas equation: Pressure * Volume = Moles * r * Temperature
|
||||
@@ -51,6 +53,7 @@
|
||||
air.set_carbon_dioxide(ppratio_to_moles(cdiox))
|
||||
air.set_sleeping_agent(ppratio_to_moles(nitrox))
|
||||
air.set_agent_b(ppratio_to_moles(agentbx))
|
||||
air.set_hydrogen(ppratio_to_moles(hydrogen))
|
||||
|
||||
for(var/turf/T in block(cornerA,cornerB))
|
||||
if(issimulatedturf(T))
|
||||
@@ -66,6 +69,7 @@
|
||||
T.carbon_dioxide = air.carbon_dioxide()
|
||||
T.sleeping_agent = air.sleeping_agent()
|
||||
T.agent_b = air.agent_b()
|
||||
T.hydrogen = air.hydrogen()
|
||||
|
||||
// admin log
|
||||
log_admin("Build Mode: [key_name(user)] changed the atmos of region [COORD(cornerA)] to [COORD(cornerB)]. T: [temperature], P: [pressure], Ox: [oxygen]%, N2: [nitrogen]%, Plsma: [plasma]%, CO2: [cdiox]%, N2O: [nitrox]%. [ctrl_click ? "Overwrote base space turf gases." : ""]")
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
t+= "<span class='notice'>Carbon Dioxide: [environment.carbon_dioxide()] \n</span>"
|
||||
t+= "<span class='notice'>N2O: [environment.sleeping_agent()] \n</span>"
|
||||
t+= "<span class='notice'>Agent B: [environment.agent_b()] \n</span>"
|
||||
t+= "<span class='notice'>Hydrogen: [environment.hydrogen()] \n</span>"
|
||||
|
||||
usr.show_message(t, EMOTE_VISIBLE)
|
||||
|
||||
|
||||
@@ -114,7 +114,8 @@
|
||||
var/co2_level = environment.carbon_dioxide() / total_moles
|
||||
var/plasma_level = environment.toxins() / total_moles
|
||||
var/n2o_level = environment.sleeping_agent() / total_moles
|
||||
var/unknown_level = 1 - (o2_level + n2_level + co2_level + plasma_level + n2o_level)
|
||||
var/h2_level = environment.hydrogen() / total_moles
|
||||
var/unknown_level = 1 - (o2_level + n2_level + co2_level + plasma_level + n2o_level + h2_level)
|
||||
results = list(
|
||||
list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
|
||||
list("entry" = "Temperature", "units" = "C", "val" = "[round(environment.temperature()-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
|
||||
@@ -123,6 +124,7 @@
|
||||
list("entry" = "Carbon Dioxide", "units" = "%", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
|
||||
list("entry" = "Plasma", "units" = "%", "val" = "[round(plasma_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
|
||||
list("entry" = "Nitrous Oxide", "units" = "%", "val" = "[round(n2o_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
|
||||
list("entry" = "Hydrogen", "units" = "%", "val" = "[round(h2_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
|
||||
list("entry" = "Other", "units" = "%", "val" = "[round(unknown_level*100,0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
|
||||
)
|
||||
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
#define OXYGEN_HEAT_PENALTY 1
|
||||
#define CO2_HEAT_PENALTY 0.1
|
||||
#define NITROGEN_HEAT_PENALTY -1.5
|
||||
#define HYDROGEN_HEAT_PENALTY 20
|
||||
|
||||
#define OXYGEN_TRANSMIT_MODIFIER 1.5 //Higher == Bigger bonus to power generation.
|
||||
#define PLASMA_TRANSMIT_MODIFIER 4
|
||||
#define HYDROGEN_TRANSMIT_MODIFIER 3
|
||||
|
||||
#define N2O_HEAT_RESISTANCE 6 //Higher == Gas makes the crystal more resistant against heat damage.
|
||||
|
||||
@@ -30,6 +32,7 @@
|
||||
#define N2_CRUNCH 0.55
|
||||
#define N2O_CRUNCH 0.55
|
||||
#define PLASMA_CRUNCH 4
|
||||
#define HYDROGEN_CRUNCH 2
|
||||
|
||||
#define MOLE_CRUNCH_THRESHOLD 1700 //Above this value we can get lord singulo and
|
||||
#define MOLE_PENALTY_THRESHOLD 1800 //Above this value we can get lord singulo and independent mol damage, below it we can heal damage
|
||||
@@ -152,6 +155,7 @@
|
||||
var/o2comp = 0
|
||||
var/co2comp = 0
|
||||
var/n2ocomp = 0
|
||||
var/h2comp = 0
|
||||
|
||||
///The last air sample's total molar count, will always be above or equal to 0
|
||||
var/combined_gas = 0
|
||||
@@ -517,10 +521,11 @@
|
||||
co2comp = max(removed.carbon_dioxide() / combined_gas, 0)
|
||||
n2ocomp = max(removed.sleeping_agent() / combined_gas, 0)
|
||||
n2comp = max(removed.nitrogen() / combined_gas, 0)
|
||||
h2comp = max(removed.hydrogen() / combined_gas, 0)
|
||||
|
||||
gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp - n2comp, 0), 1)
|
||||
gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp + h2comp - n2comp, 0), 1)
|
||||
|
||||
dynamic_heat_modifier = max((plasmacomp * PLASMA_HEAT_PENALTY) + (o2comp * OXYGEN_HEAT_PENALTY) + (co2comp * CO2_HEAT_PENALTY) + (n2comp * NITROGEN_HEAT_PENALTY), 0.5)
|
||||
dynamic_heat_modifier = max((plasmacomp * PLASMA_HEAT_PENALTY) + (o2comp * OXYGEN_HEAT_PENALTY) + (co2comp * CO2_HEAT_PENALTY) + (n2comp * NITROGEN_HEAT_PENALTY) + (h2comp * HYDROGEN_HEAT_PENALTY), 0.5)
|
||||
dynamic_heat_resistance = max(n2ocomp * N2O_HEAT_RESISTANCE, 1)
|
||||
|
||||
power_transmission_bonus = max((plasmacomp * PLASMA_TRANSMIT_MODIFIER) + (o2comp * OXYGEN_TRANSMIT_MODIFIER), 0)
|
||||
@@ -563,7 +568,7 @@
|
||||
|
||||
var/crush_ratio = combined_gas / MOLE_CRUNCH_THRESHOLD
|
||||
|
||||
gas_coefficient = 1 + (crush_ratio ** 2 * (crush_ratio <= 1) + (crush_ratio > 1) * 2 * crush_ratio / (crush_ratio + 1)) * (plasmacomp * PLASMA_CRUNCH + o2comp * O2_CRUNCH + co2comp * CO2_CRUNCH + n2comp * N2_CRUNCH + n2ocomp * N2O_CRUNCH)
|
||||
gas_coefficient = 1 + (crush_ratio ** 2 * (crush_ratio <= 1) + (crush_ratio > 1) * 2 * crush_ratio / (crush_ratio + 1)) * (plasmacomp * PLASMA_CRUNCH + o2comp * O2_CRUNCH + co2comp * CO2_CRUNCH + n2comp * N2_CRUNCH + n2ocomp * N2O_CRUNCH + h2comp * HYDROGEN_CRUNCH)
|
||||
|
||||
radiation_pulse(src, 6 * power * (gas_coefficient + max(0, ((power_transmission_bonus / 10)))), GAMMA_RAD)
|
||||
|
||||
@@ -1276,8 +1281,10 @@
|
||||
#undef OXYGEN_HEAT_PENALTY
|
||||
#undef CO2_HEAT_PENALTY
|
||||
#undef NITROGEN_HEAT_PENALTY
|
||||
#undef HYDROGEN_HEAT_PENALTY
|
||||
#undef OXYGEN_TRANSMIT_MODIFIER
|
||||
#undef PLASMA_TRANSMIT_MODIFIER
|
||||
#undef HYDROGEN_TRANSMIT_MODIFIER
|
||||
#undef N2O_HEAT_RESISTANCE
|
||||
#undef POWERLOSS_INHIBITION_GAS_THRESHOLD
|
||||
#undef POWERLOSS_INHIBITION_MOLE_THRESHOLD
|
||||
@@ -1320,3 +1327,4 @@
|
||||
#undef N2_CRUNCH
|
||||
#undef N2O_CRUNCH
|
||||
#undef PLASMA_CRUNCH
|
||||
#undef HYDROGEN_CRUNCH
|
||||
|
||||
@@ -111,6 +111,15 @@
|
||||
/datum/engi_event/supermatter_event/charlie_tier/heat_penalty_threshold/on_start()
|
||||
supermatter.heat_penalty_threshold -= 173
|
||||
|
||||
// hydrogen
|
||||
/datum/engi_event/supermatter_event/charlie_tier/hydrogen
|
||||
name = "C-4"
|
||||
|
||||
/datum/engi_event/supermatter_event/charlie_tier/hydrogen/on_start()
|
||||
var/datum/gas_mixture/air = new()
|
||||
air.set_hydrogen(2000)
|
||||
supermatter_turf.blind_release_air(air)
|
||||
|
||||
//Class B events
|
||||
/datum/engi_event/supermatter_event/bravo_tier
|
||||
threat_level = SM_EVENT_THREAT_B
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
air.set_toxins(T.toxins)
|
||||
air.set_sleeping_agent(T.sleeping_agent)
|
||||
air.set_agent_b(T.agent_b)
|
||||
air.set_hydrogen(T.hydrogen)
|
||||
air.set_temperature(T.temperature)
|
||||
T.blind_set_air(air)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
/datum/engi_event/bluespace_tap_event/gas/on_start()
|
||||
var/datum/gas_mixture/air = new()
|
||||
var/picked_gas = pick("N2O", "N2", "O2", "CO2", "Plasma", "Unknown")
|
||||
var/picked_gas = pick("N2O", "N2", "O2", "CO2", "Plasma", "Unknown", "H2")
|
||||
switch(picked_gas)
|
||||
if("N2")
|
||||
name = "G-1"
|
||||
@@ -50,6 +50,9 @@
|
||||
if("Unknown")
|
||||
name = "G-6"
|
||||
air.set_agent_b(250)
|
||||
if("Hydrogen")
|
||||
name = "G-7"
|
||||
air.set_hydrogen(250)
|
||||
|
||||
air.set_temperature(T20C)
|
||||
var/turf/tap_turf = get_turf(tap)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 36 KiB |
+18
-2
@@ -47,6 +47,7 @@ fn milla_create_environment(
|
||||
toxins: ByondValue,
|
||||
sleeping_agent: ByondValue,
|
||||
agent_b: ByondValue,
|
||||
hydrogen: ByondValue,
|
||||
temperature: ByondValue,
|
||||
) -> eyre::Result<ByondValue> {
|
||||
logging::setup_panic_handler();
|
||||
@@ -57,6 +58,7 @@ fn milla_create_environment(
|
||||
conversion::byond_to_option_f32(toxins)?,
|
||||
conversion::byond_to_option_f32(sleeping_agent)?,
|
||||
conversion::byond_to_option_f32(agent_b)?,
|
||||
conversion::byond_to_option_f32(hydrogen)?,
|
||||
conversion::byond_to_option_f32(temperature)?,
|
||||
) as f32))
|
||||
}
|
||||
@@ -69,6 +71,7 @@ pub(crate) fn internal_create_environment(
|
||||
toxins: Option<f32>,
|
||||
sleeping_agent: Option<f32>,
|
||||
agent_b: Option<f32>,
|
||||
hydrogen: Option<f32>,
|
||||
temperature: Option<f32>,
|
||||
) -> u8 {
|
||||
let mut tile = Tile::new();
|
||||
@@ -90,6 +93,9 @@ pub(crate) fn internal_create_environment(
|
||||
if let Some(value) = agent_b {
|
||||
tile.gases.set_agent_b(value);
|
||||
}
|
||||
if let Some(value) = hydrogen {
|
||||
tile.gases.set_hydrogen(value);
|
||||
}
|
||||
if let Some(value) = temperature {
|
||||
tile.thermal_energy = value * tile.heat_capacity();
|
||||
}
|
||||
@@ -112,7 +118,7 @@ fn milla_load_turfs(
|
||||
let data = property.get_list_values()?;
|
||||
property.decrement_tempref();
|
||||
|
||||
if data.len() != 17 {
|
||||
if data.len() != 18 {
|
||||
return Err(eyre!(
|
||||
"data property has the wrong length: {} vs {}",
|
||||
data.len(),
|
||||
@@ -137,6 +143,7 @@ fn milla_load_turfs(
|
||||
conversion::bounded_byond_to_option_f32(data[10], 0.0, f32::INFINITY)?,
|
||||
conversion::bounded_byond_to_option_f32(data[11], 0.0, f32::INFINITY)?,
|
||||
conversion::bounded_byond_to_option_f32(data[12], 0.0, f32::INFINITY)?,
|
||||
conversion::bounded_byond_to_option_f32(data[13], 0.0, f32::INFINITY)?,
|
||||
None,
|
||||
Some(0.0),
|
||||
Some(0.0),
|
||||
@@ -148,10 +155,10 @@ fn milla_load_turfs(
|
||||
x as i32 - 1,
|
||||
y as i32 - 1,
|
||||
z as i32 - 1,
|
||||
conversion::bounded_byond_to_option_f32(data[13], 0.0, 1.0)?,
|
||||
conversion::bounded_byond_to_option_f32(data[14], 0.0, 1.0)?,
|
||||
conversion::bounded_byond_to_option_f32(data[15], 0.0, 1.0)?,
|
||||
conversion::bounded_byond_to_option_f32(data[16], 0.0, 1.0)?,
|
||||
conversion::bounded_byond_to_option_f32(data[17], 0.0, 1.0)?,
|
||||
)?;
|
||||
}
|
||||
Ok(ByondValue::null())
|
||||
@@ -173,6 +180,7 @@ fn milla_set_tile(
|
||||
toxins: ByondValue,
|
||||
sleeping_agent: ByondValue,
|
||||
agent_b: ByondValue,
|
||||
hydrogen: ByondValue,
|
||||
temperature: ByondValue,
|
||||
_innate_heat_capacity: ByondValue,
|
||||
hotspot_temperature: ByondValue,
|
||||
@@ -196,6 +204,7 @@ fn milla_set_tile(
|
||||
conversion::bounded_byond_to_option_f32(toxins, 0.0, f32::INFINITY)?,
|
||||
conversion::bounded_byond_to_option_f32(sleeping_agent, 0.0, f32::INFINITY)?,
|
||||
conversion::bounded_byond_to_option_f32(agent_b, 0.0, f32::INFINITY)?,
|
||||
conversion::bounded_byond_to_option_f32(hydrogen, 0.0, f32::INFINITY)?,
|
||||
conversion::bounded_byond_to_option_f32(temperature, 0.0, f32::INFINITY)?,
|
||||
None,
|
||||
// Temporarily disabled to better match the existing system.
|
||||
@@ -240,6 +249,7 @@ fn milla_set_tile_airtight(
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
Ok(ByondValue::null())
|
||||
}
|
||||
@@ -262,6 +272,7 @@ pub(crate) fn internal_set_tile(
|
||||
toxins: Option<f32>,
|
||||
sleeping_agent: Option<f32>,
|
||||
agent_b: Option<f32>,
|
||||
hydrogen: Option<f32>,
|
||||
temperature: Option<f32>,
|
||||
thermal_energy: Option<f32>,
|
||||
innate_heat_capacity: Option<f32>,
|
||||
@@ -332,6 +343,9 @@ pub(crate) fn internal_set_tile(
|
||||
if let Some(value) = agent_b {
|
||||
tile.gases.set_agent_b(value);
|
||||
}
|
||||
if let Some(value) = hydrogen {
|
||||
tile.gases.set_hydrogen(value);
|
||||
}
|
||||
// Done sooner because we need innate heat capacity to calculate thermal energy from
|
||||
// temperature.
|
||||
if let Some(value) = innate_heat_capacity {
|
||||
@@ -763,6 +777,7 @@ mod tests {
|
||||
Some(1.0),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(1.0),
|
||||
None,
|
||||
Some(1.0),
|
||||
@@ -803,6 +818,7 @@ mod tests {
|
||||
Some(1.0),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(1.0),
|
||||
None,
|
||||
Some(1.0),
|
||||
|
||||
@@ -59,8 +59,11 @@ pub(crate) const GAS_SLEEPING_AGENT: usize = 4;
|
||||
/// Index for agent b in gas list.
|
||||
pub(crate) const GAS_AGENT_B: usize = 5;
|
||||
|
||||
/// Index for hydrogen in gas list.
|
||||
pub(crate) const GAS_HYDROGEN: usize = 6;
|
||||
|
||||
/// How many gases are there?
|
||||
pub(crate) const GAS_COUNT: usize = GAS_AGENT_B + 1;
|
||||
pub(crate) const GAS_COUNT: usize = GAS_HYDROGEN + 1; // should contain the gas right above it
|
||||
|
||||
/// The two axes, Y and X. The order is arbitrary, but may break things if changed.
|
||||
pub(crate) const AXES: [(i32, i32); 2] = [(1, 0), (0, 1)];
|
||||
@@ -103,6 +106,9 @@ pub(crate) const SPECIFIC_HEAT_SLEEPING_AGENT: f32 = 40.0;
|
||||
// The specific heat of agent b, in joules per kelvin-mole.
|
||||
pub(crate) const SPECIFIC_HEAT_AGENT_B: f32 = 300.0;
|
||||
|
||||
// The specific heat of hydrogen, in joules per kelvin-mole.
|
||||
pub(crate) const SPECIFIC_HEAT_HYDROGEN: f32 = 15.0;
|
||||
|
||||
// Convenience array, so we can add loop through gases and calculate heat capacity.
|
||||
pub(crate) const SPECIFIC_HEATS: [f32; GAS_COUNT] = [
|
||||
SPECIFIC_HEAT_OXYGEN,
|
||||
@@ -111,6 +117,7 @@ pub(crate) const SPECIFIC_HEATS: [f32; GAS_COUNT] = [
|
||||
SPECIFIC_HEAT_TOXINS,
|
||||
SPECIFIC_HEAT_SLEEPING_AGENT,
|
||||
SPECIFIC_HEAT_AGENT_B,
|
||||
SPECIFIC_HEAT_HYDROGEN,
|
||||
];
|
||||
|
||||
/// How hot does it need to be for a plasma fire to start?
|
||||
@@ -131,6 +138,18 @@ pub(crate) const PLASMA_BURN_HOTSPOT_RATIO_BOOST: f32 = 10.0;
|
||||
/// How much oxygen do we use per plasma?
|
||||
pub(crate) const PLASMA_BURN_OXYGEN_PER_PLASMA: f32 = 0.4;
|
||||
|
||||
/// How hot does hydrogen need to be for it to ignite?
|
||||
pub(crate) const HYDROGEN_MIN_IGNITE_TEMP: f32 = 500.0 + T0C;
|
||||
|
||||
/// How hot does hydrogen need to be for it to burn as well as possible?
|
||||
pub(crate) const HYDROGEN_OPTIMAL_BURN_TEMP: f32 = 2500.0 + T0C;
|
||||
|
||||
/// How much of the hydrogen are we willing to burn each tick?
|
||||
pub(crate) const HYDROGEN_BURN_MAX_RATIO: f32 = 0.07;
|
||||
|
||||
/// How much oxygen do we consume for every hydrogen?
|
||||
pub(crate) const HYDROGEN_BURN_OXYGEN_PER_HYDROGEN: f32 = 0.5;
|
||||
|
||||
/// How much thermal energy is produced, in joules per mole of agent b.
|
||||
pub(crate) const AGENT_B_CONVERSION_ENERGY: f32 = 20_000.0;
|
||||
|
||||
@@ -140,6 +159,9 @@ pub(crate) const NITROUS_BREAKDOWN_ENERGY: f32 = 200_000.0;
|
||||
/// How much thermal energy is produced, in joules per mole of sleeping toxins.
|
||||
pub(crate) const PLASMA_BURN_ENERGY: f32 = 3_000_000.0;
|
||||
|
||||
/// How much thermal energy is produced, in joules per mole of hydrogen.
|
||||
pub(crate) const HYDROGEN_BURN_ENERGY: f32 = 2_500_000.0;
|
||||
|
||||
/// We allow small deviations in tests as our spring chain solution is not exact.
|
||||
#[cfg(test)]
|
||||
pub(crate) const TEST_TOLERANCE: f32 = 0.1;
|
||||
|
||||
+10
-2
@@ -68,6 +68,13 @@ impl GasSet {
|
||||
self.values[GAS_AGENT_B] = value;
|
||||
self.dirty.store(true, Relaxed);
|
||||
}
|
||||
pub(crate) fn hydrogen(&self) -> f32 {
|
||||
self.values[GAS_HYDROGEN]
|
||||
}
|
||||
pub(crate) fn set_hydrogen(&mut self, value: f32) {
|
||||
self.values[GAS_HYDROGEN] = value;
|
||||
self.dirty.store(true, Relaxed);
|
||||
}
|
||||
pub(crate) fn set_dirty(&mut self) {
|
||||
self.dirty.store(true, Relaxed);
|
||||
}
|
||||
@@ -333,6 +340,7 @@ impl From<&Tile> for Vec<ByondValue> {
|
||||
ByondValue::from(value.gases.toxins()),
|
||||
ByondValue::from(value.gases.sleeping_agent()),
|
||||
ByondValue::from(value.gases.agent_b()),
|
||||
ByondValue::from(value.gases.hydrogen()),
|
||||
ByondValue::from(value.mode),
|
||||
ByondValue::from(environment_id as f32),
|
||||
ByondValue::from(value.superconductivity.north),
|
||||
@@ -413,7 +421,7 @@ impl ZLevel {
|
||||
ZLevel {
|
||||
tiles: unbuilt.into_boxed_slice().try_into().unwrap(),
|
||||
active_pressure_chunks: HashSet::new(),
|
||||
frozen: false,
|
||||
frozen: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,7 +465,7 @@ impl ZLevel {
|
||||
self.tiles[i].copy_from(&other.tiles[i]);
|
||||
}
|
||||
self.active_pressure_chunks = other.active_pressure_chunks.clone();
|
||||
self.frozen = other.frozen;
|
||||
self.frozen = other.frozen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -636,13 +636,64 @@ pub(crate) fn react(my_next_tile: &mut Tile, hotspot_step: bool) {
|
||||
cached_heat_capacity = fraction * my_next_tile.heat_capacity();
|
||||
// THEN we can add in the new thermal energy.
|
||||
thermal_energy += PLASMA_BURN_ENERGY * plasma_burnt;
|
||||
// Recalculate temperature for any subsequent reactions.
|
||||
|
||||
// (or we would, but this is the last reaction)
|
||||
//cached_temperature = thermal_energy / cached_heat_capacity;
|
||||
|
||||
my_next_tile.fuel_burnt += plasma_burnt;
|
||||
}
|
||||
|
||||
// Hydrogen BURNING, also know as Knallgas, which is Swedish. The more you know.
|
||||
if cached_temperature > HYDROGEN_MIN_IGNITE_TEMP
|
||||
&& my_next_tile.gases.hydrogen() > 0.0
|
||||
&& my_next_tile.gases.oxygen() > 0.0
|
||||
{
|
||||
// How efficient is the burn?
|
||||
// Linear scaling fom 0 to 1 as temperatue goes from minimum to optimal.
|
||||
let efficiency = ((cached_temperature - HYDROGEN_MIN_IGNITE_TEMP)
|
||||
/ (HYDROGEN_OPTIMAL_BURN_TEMP - HYDROGEN_MIN_IGNITE_TEMP))
|
||||
.max(0.5)
|
||||
.min(1.0);
|
||||
|
||||
// How much hydrogen is available to burn?
|
||||
let burnable_hydrogen = my_next_tile.gases.hydrogen();
|
||||
|
||||
// Actual burn amount.
|
||||
let mut hydrogen_burnt =
|
||||
efficiency * 2.0 * HYDROGEN_BURN_MAX_RATIO * hotspot_boost * burnable_hydrogen;
|
||||
if hydrogen_burnt < PLASMA_BURN_MIN_MOLES {
|
||||
// Boost up to the minimum.
|
||||
hydrogen_burnt = PLASMA_BURN_MIN_MOLES.min(burnable_hydrogen);
|
||||
}
|
||||
if hydrogen_burnt * HYDROGEN_BURN_OXYGEN_PER_HYDROGEN
|
||||
> fraction * my_next_tile.gases.oxygen()
|
||||
{
|
||||
// Restrict based on available oxygen.
|
||||
hydrogen_burnt =
|
||||
fraction * my_next_tile.gases.oxygen() / HYDROGEN_BURN_OXYGEN_PER_HYDROGEN;
|
||||
}
|
||||
|
||||
my_next_tile
|
||||
.gases
|
||||
.set_hydrogen(my_next_tile.gases.hydrogen() - hydrogen_burnt);
|
||||
my_next_tile.gases.set_oxygen(
|
||||
my_next_tile.gases.oxygen() - hydrogen_burnt * HYDROGEN_BURN_OXYGEN_PER_HYDROGEN,
|
||||
);
|
||||
// my_next_tile
|
||||
// .gases
|
||||
// .set_water_vapor(my_next_tile.gases.water_vapor() + hydrogen_burnt);
|
||||
|
||||
// Recalculate heat capacity.
|
||||
cached_heat_capacity = fraction * my_next_tile.heat_capacity();
|
||||
// THEN we can add in the new thermal energy.
|
||||
thermal_energy += HYDROGEN_BURN_ENERGY * hydrogen_burnt;
|
||||
// Recalculate temperature for any subsequent reactions.
|
||||
// (or we would, but this is the last reaction)
|
||||
//cached_temperature = thermal_energy / cached_heat_capacity;
|
||||
|
||||
my_next_tile.fuel_burnt += hydrogen_burnt;
|
||||
}
|
||||
|
||||
if hotspot_step {
|
||||
adjust_hotspot(my_next_tile, thermal_energy - initial_thermal_energy);
|
||||
} else {
|
||||
|
||||
@@ -176,6 +176,7 @@ mod tests {
|
||||
.toxins(0.0)
|
||||
.sleeping_agent(0.0)
|
||||
.agent_b(0.0)
|
||||
.hydrogen(0.0)
|
||||
.thermal_energy(100.0),
|
||||
'0' => TileChecker::new() //
|
||||
.oxygen(0.0)
|
||||
@@ -184,6 +185,7 @@ mod tests {
|
||||
.toxins(0.0)
|
||||
.sleeping_agent(0.0)
|
||||
.agent_b(0.0)
|
||||
.hydrogen(0.0)
|
||||
.thermal_energy(0.0),
|
||||
'#' => TileChecker::new(),
|
||||
' ' => TileChecker::new(),
|
||||
@@ -282,6 +284,10 @@ mod tests {
|
||||
self.0.gases.set_agent_b(value);
|
||||
self
|
||||
}
|
||||
fn hydrogen(mut self, value: f32) -> Self {
|
||||
self.0.gases.set_hydrogen(value);
|
||||
self
|
||||
}
|
||||
fn thermal_energy(mut self, value: f32) -> Self {
|
||||
self.0.thermal_energy = value;
|
||||
self
|
||||
@@ -306,6 +312,7 @@ mod tests {
|
||||
toxins_: Option<f32>,
|
||||
sleeping_agent_: Option<f32>,
|
||||
agent_b_: Option<f32>,
|
||||
hydrogen: Option<f32>,
|
||||
thermal_energy_: Option<f32>,
|
||||
temperature_: Option<f32>,
|
||||
}
|
||||
@@ -319,6 +326,7 @@ mod tests {
|
||||
toxins_: None,
|
||||
sleeping_agent_: None,
|
||||
agent_b_: None,
|
||||
hydrogen: None,
|
||||
thermal_energy_: None,
|
||||
temperature_: None,
|
||||
}
|
||||
@@ -384,6 +392,16 @@ mod tests {
|
||||
y
|
||||
);
|
||||
}
|
||||
if let Some(value) = self.hydrogen_ {
|
||||
assert!(
|
||||
(tile.gases.hydrogen() - value).abs() < TEST_TOLERANCE,
|
||||
"{} != {} @ ({}, {})",
|
||||
tile.gases.hydrogen(),
|
||||
value,
|
||||
x,
|
||||
y
|
||||
);
|
||||
}
|
||||
if let Some(value) = self.thermal_energy_ {
|
||||
assert!(
|
||||
(tile.thermal_energy - value).abs() < TEST_TOLERANCE,
|
||||
@@ -429,6 +447,10 @@ mod tests {
|
||||
self.agent_b_ = Some(value);
|
||||
self
|
||||
}
|
||||
fn hydrogen(mut self, value: f32) -> Self {
|
||||
self.hydrogen_ = Some(value);
|
||||
self
|
||||
}
|
||||
fn thermal_energy(mut self, value: f32) -> Self {
|
||||
self.thermal_energy_ = Some(value);
|
||||
self
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -747,6 +747,10 @@ span.body .coderesponses {
|
||||
color: teal;
|
||||
}
|
||||
|
||||
.hydrogen {
|
||||
color: #997379;
|
||||
}
|
||||
|
||||
// MARK: Boxed messages
|
||||
.boxed_message {
|
||||
background: hsl(220, 10%, 10%);
|
||||
|
||||
@@ -345,6 +345,10 @@ span.body .coderesponses {
|
||||
color: #004d4d;
|
||||
}
|
||||
|
||||
.hydrogen {
|
||||
color: #997379;
|
||||
}
|
||||
|
||||
// MARK: Boxed messages
|
||||
.boxed_message {
|
||||
background: hsl(220, 100%, 97.5%);
|
||||
|
||||
@@ -231,7 +231,7 @@ const GASES = [
|
||||
'id': 'hydrogen',
|
||||
'name': 'Hydrogen',
|
||||
'label': 'H₂',
|
||||
'color': 'white',
|
||||
'color': '#997379',
|
||||
},
|
||||
{
|
||||
'id': 'ab',
|
||||
|
||||
@@ -112,6 +112,11 @@ const AirStatus = (props) => {
|
||||
<ProgressBar value={air.contents.n2o / 100} fractionDigits="1" color={Danger2Colour(air.danger.n2o)} />
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{air.contents.h2 > 0.1 && (
|
||||
<LabeledList.Item label="Hydrogen">
|
||||
<ProgressBar value={air.contents.h2 / 100} fractionDigits="1" color={Danger2Colour(air.danger.h2)} />
|
||||
</LabeledList.Item>
|
||||
)}
|
||||
{air.contents.other > 0.1 && (
|
||||
<LabeledList.Item label="Other">
|
||||
<ProgressBar
|
||||
@@ -365,6 +370,17 @@ const AirAlarmScrubbersView = (props) => {
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
content="Hydrogen"
|
||||
selected={s.filter_h2}
|
||||
onClick={() =>
|
||||
act('command', {
|
||||
cmd: 'h2_scrub',
|
||||
val: !s.filter_h2,
|
||||
id_tag: s.id_tag,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
|
||||
@@ -27,7 +27,7 @@ export const AtmosTankControl = (props) => {
|
||||
''
|
||||
)}
|
||||
|
||||
{['o2', 'n2', 'plasma', 'co2', 'n2o'].map((g) =>
|
||||
{['o2', 'n2', 'plasma', 'co2', 'n2o', 'h2'].map((g) =>
|
||||
Object.keys(sensors_list[s]).indexOf(g) > -1 ? (
|
||||
<LabeledList.Item key={getGasLabel(g)} label={getGasLabel(g)}>
|
||||
<ProgressBar color={getGasColor(g)} value={sensors_list[s][g]} minValue={0} maxValue={100}>
|
||||
@@ -225,6 +225,16 @@ const TankControlScrubbersView = (props) => {
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
content="Hydrogen"
|
||||
selected={s.filter_h2}
|
||||
onClick={() =>
|
||||
act('command', {
|
||||
cmd: 'h2_scrub',
|
||||
id_tag: s.id_tag,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Reference in New Issue
Block a user