Adds Water Vapor and the Electrolyzer (#30875)

* this will work first try (adds water vapor and the electrolyzer)

* naming fix

* removes a warn

* makes water vapor able to be seen and adds it to the tiny_test atmos map

* Build Rust library

* adds the electrolyzer to all maps, and linter fix

* linter fix part 2

* electrolyzer tweak and more work on the test_atmos map

* tgui rebuilding

* re
rebuilding tgui

* makes the electrolyzer consume power and some small test atmos touch ups

* im axing the test_tiny because i don't want to map it

* clarifies how much power the electrolyzer uses

* Build Rust library

* suggestionss

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Co-authored-by: JimKil3 <47290811+JimKil3@users.noreply.github.com>
Signed-off-by: Hayden Redacted <91229275+haydenredacted@users.noreply.github.com>

* updating the SM manual

* electrolyzer tweaks

* dg suggestions pt. 2

Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Signed-off-by: Hayden Redacted <91229275+haydenredacted@users.noreply.github.com>

* removed unused code

---------

Signed-off-by: Hayden Redacted <91229275+haydenredacted@users.noreply.github.com>
Co-authored-by: paradisess13[bot] <165046124+paradisess13[bot]@users.noreply.github.com>
Co-authored-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
Co-authored-by: JimKil3 <47290811+JimKil3@users.noreply.github.com>
This commit is contained in:
Hayden Redacted
2025-12-09 19:04:11 -05:00
committed by GitHub
parent be48d7598f
commit 5728e0c46f
54 changed files with 671 additions and 117 deletions
+1 -1
View File
@@ -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()] Hydrogen: [GM.hydrogen()] 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()] Water Vapor: [GM.water_vapor()] 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]")
@@ -147,4 +147,7 @@
if(flag & LINDA_SPAWN_HYDROGEN)
G.set_hydrogen(G.hydrogen() + amount)
if(flag & LINDA_SPAWN_WATER_VAPOR)
G.set_water_vapor(G.water_vapor() + amount)
blind_release_air(G)
@@ -13,6 +13,7 @@
air.set_sleeping_agent(sleeping_agent)
air.set_agent_b(agent_b)
air.set_hydrogen(hydrogen)
air.set_water_vapor(water_vapor)
air.set_temperature(temperature)
else
air.set_oxygen(0)
@@ -22,6 +23,7 @@
air.set_sleeping_agent(0)
air.set_agent_b(0)
air.set_hydrogen(0)
air.set_water_vapor(0)
air.set_temperature(0)
return air
@@ -74,6 +76,8 @@
return GLOB.plmaster
if("sleeping_agent")
return GLOB.slmaster
if("water_vapor")
return GLOB.wvmaster
return null
/turf/simulated/proc/tile_graphic(datum/gas_mixture/air)
@@ -86,6 +90,9 @@
if(air.sleeping_agent() > 1)
return "sleeping_agent"
if(air.water_vapor() > MOLES_WATER_VAPOR_VISIBLE)
return "water_vapor"
return null
/turf/proc/high_pressure_movements(flow_x, flow_y)
@@ -180,7 +187,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, hydrogen, temperature)
var/list/air = list(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, water_vapor, temperature)
milla_data = connectivity[1] + list(atmos_mode, SSmapping.environments[atmos_environment]) + air + connectivity[2]
/turf/simulated/Initialize_Atmos(milla_tick)
@@ -9,14 +9,16 @@ What are the archived variables for?
#define SPECIFIC_HEAT_N2O 40
#define SPECIFIC_HEAT_AGENT_B 300
#define SPECIFIC_HEAT_HYDROGEN 15
#define SPECIFIC_HEAT_WATER_VAPOR 33
#define HEAT_CAPACITY_CALCULATION(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, innate_heat_capacity) \
#define HEAT_CAPACITY_CALCULATION(oxygen, carbon_dioxide, nitrogen, toxins, sleeping_agent, agent_b, hydrogen, water_vapor, 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 + \
water_vapor * SPECIFIC_HEAT_WATER_VAPOR + \
innate_heat_capacity)
#define MINIMUM_HEAT_CAPACITY 0.0003
@@ -40,6 +42,7 @@ What are the archived variables for?
var/private_sleeping_agent = 0
var/private_agent_b = 0
var/private_hydrogen = 0
var/private_water_vapor = 0
var/private_temperature = 0 //in Kelvin
var/private_hotspot_temperature = 0
var/private_hotspot_volume = 0
@@ -54,6 +57,7 @@ What are the archived variables for?
var/private_sleeping_agent_archived = 0
var/private_agent_b_archived = 0
var/private_hydrogen_archived = 0
var/private_water_vapor_archived = 0
var/private_temperature_archived = 0
/// Is this mixture currently synchronized with MILLA? Always true for non-bound mixtures.
@@ -140,6 +144,17 @@ What are the archived variables for?
stack_trace("Out-of-bounds value [value] clamped to [clamped].")
private_hydrogen = clamped
/datum/gas_mixture/proc/water_vapor()
return private_water_vapor
/datum/gas_mixture/proc/set_water_vapor(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_water_vapor = clamped
/datum/gas_mixture/proc/temperature()
return private_temperature
@@ -163,14 +178,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, private_hydrogen, innate_heat_capacity)
return HEAT_CAPACITY_CALCULATION(private_oxygen, private_carbon_dioxide, private_nitrogen, private_toxins, private_sleeping_agent, private_agent_b, private_hydrogen, private_water_vapor, 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, private_hydrogen_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, private_water_vapor_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 + private_hydrogen
return private_oxygen + private_carbon_dioxide + private_nitrogen + private_toxins + private_sleeping_agent + private_agent_b + private_hydrogen + private_water_vapor
/datum/gas_mixture/proc/total_trace_moles()
return private_agent_b
@@ -198,6 +213,7 @@ What are the archived variables for?
private_sleeping_agent_archived = private_sleeping_agent
private_agent_b_archived = private_agent_b
private_hydrogen_archived = private_hydrogen
private_water_vapor_archived = private_water_vapor
private_temperature_archived = private_temperature
@@ -223,6 +239,7 @@ What are the archived variables for?
private_sleeping_agent += giver.private_sleeping_agent
private_agent_b += giver.private_agent_b
private_hydrogen += giver.private_hydrogen
private_water_vapor += giver.private_water_vapor
set_dirty()
return TRUE
@@ -252,6 +269,7 @@ What are the archived variables for?
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)
removed.private_water_vapor = QUANTIZE((private_water_vapor / sum) * amount)
private_oxygen = max(private_oxygen - removed.private_oxygen, 0)
private_nitrogen = max(private_nitrogen - removed.private_nitrogen, 0)
@@ -260,6 +278,7 @@ What are the archived variables for?
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)
private_water_vapor = max(private_water_vapor - removed.private_water_vapor, 0)
removed.private_temperature = private_temperature
@@ -284,6 +303,7 @@ What are the archived variables for?
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)
removed.private_water_vapor = QUANTIZE(private_water_vapor * ratio)
private_oxygen = max(private_oxygen - removed.private_oxygen, 0)
private_nitrogen = max(private_nitrogen - removed.private_nitrogen, 0)
@@ -292,6 +312,7 @@ What are the archived variables for?
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)
private_water_vapor = max(private_water_vapor - removed.private_water_vapor, 0)
removed.private_temperature = private_temperature
set_dirty()
@@ -307,6 +328,7 @@ What are the archived variables for?
private_sleeping_agent = sample.private_sleeping_agent
private_agent_b = sample.private_agent_b
private_hydrogen = sample.private_hydrogen
private_water_vapor = sample.private_water_vapor
private_temperature = sample.private_temperature
set_dirty()
@@ -323,6 +345,7 @@ What are the archived variables for?
private_sleeping_agent = model.sleeping_agent
private_agent_b = model.agent_b
private_hydrogen = model.hydrogen
private_water_vapor = model.water_vapor
//acounts for changes in temperature
var/turf/model_parent = model.parent_type
@@ -348,6 +371,7 @@ What are the archived variables for?
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_water_vapor = QUANTIZE(private_water_vapor_archived - sharer.private_water_vapor_archived) / (atmos_adjacent_turfs + 1)
var/delta_temperature = (private_temperature_archived - sharer.private_temperature_archived)
@@ -402,6 +426,13 @@ What are the archived variables for?
else
heat_capacity_sharer_to_self -= hydrogen_heat_capacity
if(delta_water_vapor)
var/water_vapor_heat_capacity = SPECIFIC_HEAT_WATER_VAPOR * delta_water_vapor
if(delta_water_vapor > 0)
heat_capacity_self_to_sharer += water_vapor_heat_capacity
else
heat_capacity_sharer_to_self -= water_vapor_heat_capacity
old_self_heat_capacity = heat_capacity()
old_sharer_heat_capacity = sharer.heat_capacity()
@@ -426,7 +457,10 @@ What are the archived variables for?
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)
private_water_vapor -= delta_water_vapor
sharer.private_water_vapor += delta_water_vapor
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins + delta_sleeping_agent + delta_agent_b + delta_hydrogen + delta_water_vapor)
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
@@ -457,6 +491,7 @@ What are the archived variables for?
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_water_vapor = QUANTIZE(private_water_vapor_archived - model.water_vapor) / (atmos_adjacent_turfs + 1)
var/delta_temperature = (private_temperature_archived - model.temperature)
@@ -497,6 +532,11 @@ What are the archived variables for?
heat_transferred -= hydrogen_heat_capacity * model.temperature
heat_capacity_transferred -= hydrogen_heat_capacity
if(delta_water_vapor)
var/water_vapor_heat_capacity = SPECIFIC_HEAT_WATER_VAPOR * delta_water_vapor
heat_transferred -= water_vapor_heat_capacity * model.temperature
heat_capacity_transferred -= water_vapor_heat_capacity
old_self_heat_capacity = heat_capacity()
private_oxygen -= delta_oxygen
@@ -506,8 +546,9 @@ What are the archived variables for?
private_sleeping_agent -= delta_sleeping_agent
private_agent_b -= delta_agent_b
private_hydrogen -= delta_hydrogen
private_water_vapor -= delta_water_vapor
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins + delta_sleeping_agent + delta_agent_b + delta_hydrogen)
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins + delta_sleeping_agent + delta_agent_b + delta_hydrogen + delta_water_vapor)
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred
@@ -518,7 +559,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 + model.hydrogen)
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 + model.water_vapor)
return delta_pressure * R_IDEAL_GAS_EQUATION / volume
else
return 0
@@ -532,6 +573,7 @@ What are the archived variables for?
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_water_vapor = (private_water_vapor_archived - model.water_vapor) / (atmos_adjacent_turfs + 1)
var/delta_temperature = (private_temperature_archived - model.temperature)
@@ -541,7 +583,8 @@ What are the archived variables for?
|| ((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_hydrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_hydrogen) >= private_hydrogen_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)))
|| ((abs(delta_hydrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_hydrogen) >= private_hydrogen_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|| ((abs(delta_water_vapor) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_water_vapor) >= private_water_vapor_archived * MINIMUM_AIR_RATIO_TO_SUSPEND)))
return FALSE
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return FALSE
@@ -613,6 +656,9 @@ What are the archived variables for?
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((abs(private_water_vapor - sample.private_water_vapor) > MINIMUM_AIR_TO_SUSPEND) && \
((private_water_vapor < (1 - MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.private_water_vapor) || (private_water_vapor > (1 + MINIMUM_AIR_RATIO_TO_SUSPEND) * sample.private_water_vapor)))
return FALSE
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
if((abs(private_temperature - sample.private_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
@@ -628,6 +674,7 @@ What are the archived variables for?
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_water_vapor = (private_water_vapor - model.water_vapor)
var/delta_temperature = (private_temperature - model.temperature)
@@ -637,7 +684,8 @@ What are the archived variables for?
|| ((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_hydrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_hydrogen) >= private_hydrogen * MINIMUM_AIR_RATIO_TO_SUSPEND)))
|| ((abs(delta_hydrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_hydrogen) >= private_hydrogen * MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|| ((abs(delta_water_vapor) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_water_vapor) >= private_water_vapor * MINIMUM_AIR_RATIO_TO_SUSPEND)))
return FALSE
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
return FALSE
@@ -729,7 +777,7 @@ What are the archived variables for?
// 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/produced_water_vapor = (burned_hydrogen / H2_NEEDED_FOR_H2O)
var/old_heat_capacity = heat_capacity()
@@ -737,7 +785,7 @@ What are the archived variables for?
// Burn gasses
private_hydrogen -= burned_hydrogen
private_oxygen -= burned_oxygen
// private_water_vapor += produced_water_vapor
private_water_vapor += produced_water_vapor
// Calculate gained energy
var/energy_released = HYDROGEN_BURN_ENERGY * burned_hydrogen
@@ -774,6 +822,7 @@ What are the archived variables for?
private_sleeping_agent = milla[MILLA_INDEX_SLEEPING_AGENT]
private_agent_b = milla[MILLA_INDEX_AGENT_B]
private_hydrogen = milla[MILLA_INDEX_HYDROGEN]
private_water_vapor = milla[MILLA_INDEX_WATER_VAPOR]
innate_heat_capacity = milla[MILLA_INDEX_INNATE_HEAT_CAPACITY]
private_temperature = milla[MILLA_INDEX_TEMPERATURE]
private_hotspot_temperature = milla[MILLA_INDEX_HOTSPOT_TEMPERATURE]
@@ -789,6 +838,7 @@ What are the archived variables for?
var/total_sleeping_agent = 0
var/total_agent_b = 0
var/total_hydrogen = 0
var/total_water_vapor = 0
var/must_share = FALSE
// Collect all the cheap data and check if there's a significant temperature difference.
@@ -810,11 +860,12 @@ What are the archived variables for?
total_sleeping_agent += G.private_sleeping_agent
total_agent_b += G.private_agent_b
total_hydrogen += G.private_hydrogen
total_water_vapor += G.private_water_vapor
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) || total_hydrogen < 0 || isnan(total_hydrogen) || !isnum(total_hydrogen))
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) || total_water_vapor < 0 || isnan(total_water_vapor) || !isnum(total_water_vapor))
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.
@@ -843,6 +894,9 @@ What are the archived variables for?
if(abs(G.private_hydrogen - total_hydrogen * G.volume / total_volume) > 0.1)
must_share = TRUE
break
if(abs(G.private_water_vapor - total_water_vapor * G.volume / total_volume) > 0.1)
must_share = TRUE
break
if(!must_share)
// Nothing significant, don't do any more work.
@@ -877,6 +931,7 @@ What are the archived variables for?
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_water_vapor = total_water_vapor * 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.
@@ -890,6 +945,7 @@ What are the archived variables for?
#undef SPECIFIC_HEAT_N2O
#undef SPECIFIC_HEAT_AGENT_B
#undef SPECIFIC_HEAT_HYDROGEN
#undef SPECIFIC_HEAT_WATER_VAPOR
#undef HEAT_CAPACITY_CALCULATION
#undef MINIMUM_HEAT_CAPACITY
#undef MINIMUM_MOLE_COUNT
@@ -917,6 +973,7 @@ What are the archived variables for?
readonly.private_sleeping_agent = private_sleeping_agent
readonly.private_agent_b = private_agent_b
readonly.private_hydrogen = private_hydrogen
readonly.private_water_vapor = private_water_vapor
readonly.private_temperature = private_temperature
readonly.private_hotspot_temperature = private_hotspot_temperature
readonly.private_hotspot_volume = private_hotspot_volume
@@ -955,6 +1012,10 @@ What are the archived variables for?
private_hydrogen = value
set_dirty()
/datum/gas_mixture/bound_to_turf/set_water_vapor(value)
private_water_vapor = value
set_dirty()
/datum/gas_mixture/bound_to_turf/set_temperature(value)
private_temperature = value
set_dirty()
@@ -975,6 +1036,7 @@ What are the archived variables for?
sleeping_agent = private_sleeping_agent,
agent_b = private_agent_b,
hydrogen = private_hydrogen,
water_vapor = private_water_vapor,
temperature = private_temperature
)
/datum/gas_mixture/bound_to_turf/proc/get_readonly()
@@ -993,6 +1055,7 @@ What are the archived variables for?
private_sleeping_agent = parent.private_sleeping_agent
private_agent_b = parent.private_agent_b
private_hydrogen = parent.private_hydrogen
private_water_vapor = parent.private_water_vapor
private_temperature = parent.private_temperature
private_hotspot_temperature = parent.private_hotspot_temperature
@@ -1023,5 +1086,8 @@ What are the archived variables for?
/datum/gas_mixture/readonly/set_hydrogen(value)
CRASH("Attempted to modify a readonly gas_mixture.")
/datum/gas_mixture/readonly/set_water_vapor(value)
CRASH("Attempted to modify a readonly gas_mixture.")
/datum/gas_mixture/readonly/set_temperature(value)
CRASH("Attempted to modify a readonly gas_mixture.")
@@ -152,6 +152,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
"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
"water vapor" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // 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
@@ -165,6 +166,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
"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
"water vapor" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // 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
@@ -177,6 +179,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
"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
"water vapor" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // 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
@@ -189,6 +192,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
"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
"water vapor" = 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
@@ -202,6 +206,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
"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
"water vapor" = 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
@@ -302,6 +307,9 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
cur_tlv = TLV["hydrogen"]
var/hydrogen_dangerlevel = cur_tlv.get_danger_level(environment.hydrogen() * GET_PP)
cur_tlv = TLV["water vapor"]
var/water_vapor_dangerlevel = cur_tlv.get_danger_level(environment.water_vapor() * GET_PP)
cur_tlv = TLV["other"]
var/other_dangerlevel = cur_tlv.get_danger_level(environment.total_trace_moles() * GET_PP)
@@ -317,6 +325,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
plasma_dangerlevel,
sleeping_agent_dangerlevel,
hydrogen_dangerlevel,
water_vapor_dangerlevel,
other_dangerlevel,
temperature_dangerlevel
)
@@ -420,6 +429,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
S.scrub_Toxins = FALSE
S.scrub_N2O = FALSE
S.scrub_H2 = FALSE
S.scrub_H2O = FALSE
S.scrubbing = TRUE
S.widenet = FALSE
S.update_icon(UPDATE_ICON_STATE)
@@ -442,6 +452,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
S.scrub_Toxins = TRUE
S.scrub_N2O = TRUE
S.scrub_H2 = TRUE
S.scrub_H2O = TRUE
S.scrubbing = TRUE
S.widenet = TRUE
S.update_icon(UPDATE_ICON_STATE)
@@ -482,6 +493,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
S.scrub_Toxins = FALSE
S.scrub_N2O = FALSE
S.scrub_H2 = FALSE
S.scrub_H2O = FALSE
S.scrubbing = TRUE
S.widenet = FALSE
S.update_icon(UPDATE_ICON_STATE)
@@ -635,6 +647,10 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
var/hydrogen_dangerlevel = cur_tlv.get_danger_level(environment.hydrogen() * GET_PP)
var/hydrogen_percent = total ? environment.hydrogen() / total * 100 : 0
cur_tlv = TLV["water vapor"]
var/water_vapor_dangerlevel = cur_tlv.get_danger_level(environment.water_vapor() * GET_PP)
var/water_vapor_percent = total ? environment.water_vapor() / 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)
@@ -656,6 +672,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
percentages["plasma"] = plasma_percent
percentages["n2o"] = sleeping_agent_percent
percentages["hydrogen"] = hydrogen_percent
percentages["water_vapor"] = water_vapor_percent
percentages["other"] = other_percent
data["contents"] = percentages
@@ -668,8 +685,9 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
danger["plasma"] = plasma_dangerlevel
danger["n2o"] = sleeping_agent_dangerlevel
danger["hydrogen"] = hydrogen_dangerlevel
danger["water_vapor"] = water_vapor_dangerlevel
danger["other"] = other_dangerlevel
danger["overall"] = max(pressure_dangerlevel,oxygen_dangerlevel,nitrogen_dangerlevel,co2_dangerlevel,plasma_dangerlevel,hydrogen_dangerlevel,other_dangerlevel,temperature_dangerlevel)
danger["overall"] = max(pressure_dangerlevel,oxygen_dangerlevel,nitrogen_dangerlevel,co2_dangerlevel,plasma_dangerlevel,hydrogen_dangerlevel,water_vapor_dangerlevel,other_dangerlevel,temperature_dangerlevel)
data["danger"] = danger
return data
@@ -744,6 +762,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
scrubber_info["filter_toxins"] = S.scrub_Toxins
scrubber_info["filter_n2o"] = S.scrub_N2O
scrubber_info["filter_h2"] = S.scrub_H2
scrubber_info["filter_h2o"] = S.scrub_H2O
scrubbers += list(scrubber_info)
data["scrubbers"] = scrubbers
return data
@@ -772,6 +791,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
"plasma" = "Toxin",
"nitrous oxide" = "N2O",
"hydrogen" = "H2",
"water vapor" = "H2O",
"other" = "Other")
for(var/g in gas_names)
thresholds += list(list("name" = gas_names[g], "settings" = list()))
@@ -886,6 +906,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
"n2_scrub",
"o2_scrub",
"h2_scrub",
"h2o_scrub",
"widenet",
"scrubbing",
"direction")
@@ -950,6 +971,8 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
S.scrub_O2 = val
if("h2_scrub")
S.scrub_H2 = val
if("h2o_scrub")
S.scrub_H2O = val
if("widenet")
S.widenet = val
if("scrubbing")
@@ -13,6 +13,8 @@
#define FILTER_N2O 4
/// Hydrogen only.
#define FILTER_H2 5
/// Water vapor only.
#define FILTER_H2O 6
/obj/machinery/atmospherics/trinary/filter
name = "gas filter"
@@ -32,6 +34,7 @@
"CO2" = FILTER_CO2,
"N2O" = FILTER_N2O,
"H2" = FILTER_H2,
"H2O" = FILTER_H2O,
)
// So we can CtrlClick without triggering the anchored message.
@@ -151,6 +154,11 @@
if(FILTER_H2)
filtered_out.set_hydrogen(removed.hydrogen())
removed.set_hydrogen(0)
if(FILTER_H2O)
filtered_out.set_water_vapor(removed.water_vapor())
removed.set_water_vapor(0)
else
filtered_out = null
@@ -248,3 +256,4 @@
#undef FILTER_CO2
#undef FILTER_N2O
#undef FILTER_H2
#undef FILTER_H2O
@@ -24,6 +24,7 @@
var/scrub_Toxins = FALSE
var/scrub_N2O = FALSE
var/scrub_H2 = FALSE
var/scrub_H2O = FALSE
var/volume_rate = 200
var/widenet = FALSE //is this scrubber acting on the 3x3 area around it.
@@ -168,6 +169,8 @@
return TRUE
if(environment.hydrogen() > 0.001)
return TRUE
if(environment.water_vapor() > 0.001)
return TRUE
return FALSE
@@ -216,6 +219,10 @@
filtered_out.set_hydrogen(removed.hydrogen())
removed.set_hydrogen(0)
if(scrubber.scrub_H2O)
filtered_out.set_water_vapor(removed.water_vapor())
removed.set_water_vapor(0)
//Remix the resulting gases
scrubber.air_contents.merge(filtered_out)
@@ -8,6 +8,7 @@
list("name" = "\[Toxin (Bio)\]", "icon" = "orange"),
list("name" = "\[CO2\]", "icon" = "black"),
list("name" = "\[H2\]", "icon" = "white"),
list("name" = "\[H2O\]", "icon" = "lightgrey"),
list("name" = "\[Air\]", "icon" = "grey"),
list("name" = "\[CAUTION\]", "icon" = "yellow"),
list("name" = "\[SPECIAL\]", "icon" = "whiters")
@@ -445,6 +446,11 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
name = "Canister \[H2\]"
icon_state = "white" //See Initialize()
can_label = FALSE
/obj/machinery/atmospherics/portable/canister/water_vapor
name = "Canister \[H2O\]"
icon_state = "lightgrey" //See Initialize()
can_label = FALSE
/obj/machinery/atmospherics/portable/canister/air
name = "Canister \[Air\]"
icon_state = "grey" //See Initialize()
@@ -504,6 +510,14 @@ GLOBAL_DATUM_INIT(canister_icon_container, /datum/canister_icons, new())
update_icon()
/obj/machinery/atmospherics/portable/canister/water_vapor/Initialize(mapload)
. = ..()
canister_color["prim"] = "lightgrey"
air_contents.set_water_vapor((maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature()))
update_icon()
/obj/machinery/atmospherics/portable/canister/air/Initialize(mapload)
. = ..()
@@ -93,6 +93,9 @@
filtered_out.set_hydrogen(removed.hydrogen())
removed.set_hydrogen(0)
filtered_out.set_water_vapor(removed.water_vapor())
removed.set_water_vapor(0)
//Remix the resulting gases
air_contents.merge(filtered_out)
+4
View File
@@ -11,6 +11,7 @@
var/nitrox = 0
var/agentbx = 0
var/hydrogen = 0
var/water_vapor = 0
/datum/buildmode_mode/atmos/show_help(mob/user)
@@ -33,6 +34,7 @@
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)
water_vapor = tgui_input_number(user, "Water Vapor 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
@@ -54,6 +56,7 @@
air.set_sleeping_agent(ppratio_to_moles(nitrox))
air.set_agent_b(ppratio_to_moles(agentbx))
air.set_hydrogen(ppratio_to_moles(hydrogen))
air.set_water_vapor(ppratio_to_moles(water_vapor))
for(var/turf/T in block(cornerA,cornerB))
if(issimulatedturf(T))
@@ -70,6 +73,7 @@
T.sleeping_agent = air.sleeping_agent()
T.agent_b = air.agent_b()
T.hydrogen = air.hydrogen()
T.water_vapor = air.water_vapor()
// 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." : ""]")
+1
View File
@@ -112,6 +112,7 @@
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>"
t+= "<span class='notice'>Water Vapor: [environment.water_vapor()] \n</span>"
usr.show_message(t, EMOTE_VISIBLE)
+3 -1
View File
@@ -115,7 +115,8 @@
var/plasma_level = environment.toxins() / total_moles
var/n2o_level = environment.sleeping_agent() / total_moles
var/h2_level = environment.hydrogen() / total_moles
var/unknown_level = 1 - (o2_level + n2_level + co2_level + plasma_level + n2o_level + h2_level)
var/h2o_level = environment.water_vapor() / total_moles
var/unknown_level = 1 - (o2_level + n2_level + co2_level + plasma_level + n2o_level + h2_level + h2o_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),
@@ -125,6 +126,7 @@
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" = "Water Vapor", "units" = "%", "val" = "[round(h2o_level*100,0.1)]", "bad_high" = 100, "poor_high" = 80, "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)
)
+142
View File
@@ -0,0 +1,142 @@
/obj/machinery/power/electrolyzer
name = "gas electrolyzer"
desc = "A nifty little machine that is able to produce hydrogen when supplied with water vapor and enough power, allowing for on-the-go hydrogen production! Nanotrasen is not responsible for any accidents that may occur from sudden hydrogen combustion or explosions. It seems it needs around 350 kW of power to funtion properly."
anchored = FALSE
icon = 'icons/obj/atmos.dmi'
icon_state = "electrolyzer_off"
density = TRUE
active_power_consumption = 350000
/// whether or not we're actively using power/seeking water vapor in the air
var/on = FALSE
var/datum/gas_mixture/gas
var/board_path = /obj/item/circuitboard/electrolyzer
/obj/machinery/power/electrolyzer/Initialize(mapload)
. = ..()
component_parts = list()
component_parts += new /obj/item/circuitboard/electrolyzer(src)
component_parts += new /obj/item/stock_parts/micro_laser(src)
component_parts += new /obj/item/stock_parts/micro_laser(src)
component_parts += new /obj/item/stock_parts/matter_bin(src)
component_parts += new /obj/item/stock_parts/matter_bin(src)
component_parts += new /obj/item/stock_parts/capacitor(src)
component_parts += new /obj/item/stack/cable_coil(src, 5)
if(!powernet)
connect_to_network()
if(powernet)
RegisterSignal(powernet)
RefreshParts()
/obj/machinery/power/electrolyzer/wrench_act(mob/living/user, obj/item/I)
if(on)
return
. = TRUE
if(!I.use_tool(src, user, I.tool_volume))
return
if(!anchored)
connect_to_network()
to_chat(user, "<span class='notice'>You secure the generator to the floor.</span>")
else
disconnect_from_network()
to_chat(user, "<span class='notice'>You unsecure the generator from the floor.</span>")
anchored = !anchored
/obj/machinery/power/electrolyzer/screwdriver_act(mob/user, obj/item/I)
. = TRUE
if(!anchored)
to_chat(user, "<span class='warning'>[src] needs to be secured down first!</span>")
return
if(on)
to_chat(user, "<span class='warning'>[src] needs to be turned off first!</span>")
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
panel_open = !panel_open
if(panel_open)
SCREWDRIVER_OPEN_PANEL_MESSAGE
panel_open = TRUE
icon_state = "electrolyzer_open"
else
SCREWDRIVER_CLOSE_PANEL_MESSAGE
icon_state = "electrolyzer_off"
panel_open = FALSE
/obj/machinery/power/electrolyzer/crowbar_act(mob/living/user, obj/item/I)
if(panel_open)
deconstruct(TRUE)
to_chat(user, "<span class='notice'>You disassemble [src].</span>")
I.play_tool_sound(user, I.tool_volume)
return TRUE
return FALSE
/obj/machinery/power/electrolyzer/AltClick(mob/user)
if(anchored)
to_chat(user, "<span class='warning'>[src] is anchored to the floor!</span>")
return
pixel_x = 0
pixel_y = 0
/obj/machinery/power/electrolyzer/Destroy()
if(powernet)
UnregisterSignal(powernet, COMSIG_POWERNET_POWER_CHANGE)
return ..()
/datum/milla_safe/electrolyzer_process
/obj/machinery/power/electrolyzer/process()
if(on && get_surplus() >= active_power_consumption)
consume_direct_power(active_power_consumption)
var/datum/milla_safe/electrolyzer_process/milla = new()
milla.invoke_async(src)
// Turns the electrolyzer on and off
/obj/machinery/power/electrolyzer/attack_hand(mob/user)
if(stat & BROKEN)
return
if(!anchored)
to_chat(user, "<span class='warning'>[src] must be anchored first!</span>")
return
if(panel_open)
to_chat(user, "<span class='warning'>Close the panel first!</span>")
return
var/area/A = get_area(src)
if(!istype(A) || !A.powernet.has_power(PW_CHANNEL_EQUIPMENT))
to_chat(user, "<span class='warning'>[src] must be powered!</span>")
return
. = ..()
if(on)
on = FALSE
to_chat(user, "<span class='notice'>[src] switches off.</span>")
icon_state = "electrolyzer_off"
else
on = TRUE
to_chat(user, "<span class='notice'>[src] begins to hum quietly.</span>")
icon_state = "electrolyzer_on"
add_fingerprint(usr)
/obj/machinery/power/electrolyzer/proc/process_atmos_safely(turf/T, datum/gas_mixture/env)
var/datum/gas_mixture/removed = new()
if(env.water_vapor() > 3)
removed.set_water_vapor(env.water_vapor())
env.set_water_vapor(0)
return removed
/obj/machinery/power/electrolyzer/proc/has_water_vapor(datum/gas_mixture/gas)
if(!gas)
return FALSE
return gas.water_vapor() > 3
/datum/milla_safe/electrolyzer_process/on_run(obj/machinery/power/electrolyzer/electrolyzer, datum/gas_mixture)
var/turf/T = get_turf(electrolyzer)
var/datum/gas_mixture/env = get_turf_air(T)
var/datum/gas_mixture/removed = electrolyzer.process_atmos_safely(T, env)
if(electrolyzer.on && electrolyzer.has_water_vapor(removed))
var/water_vapor_to_remove = removed.water_vapor()
var/hydrogen_produced = water_vapor_to_remove
var/oxygen_produced = water_vapor_to_remove / 2
removed.set_water_vapor(removed.water_vapor() - water_vapor_to_remove)
env.set_hydrogen(env.hydrogen() + hydrogen_produced)
env.set_oxygen(env.oxygen() + oxygen_produced)
@@ -16,10 +16,12 @@
#define CO2_HEAT_PENALTY 0.1
#define NITROGEN_HEAT_PENALTY -1.5
#define HYDROGEN_HEAT_PENALTY 20
#define H2O_HEAT_PENALTY 5
#define OXYGEN_TRANSMIT_MODIFIER 1.5 //Higher == Bigger bonus to power generation.
#define PLASMA_TRANSMIT_MODIFIER 4
#define HYDROGEN_TRANSMIT_MODIFIER 3
#define H2O_TRANSMIT_MODIFIER -10
#define N2O_HEAT_RESISTANCE 6 //Higher == Gas makes the crystal more resistant against heat damage.
@@ -33,6 +35,7 @@
#define N2O_CRUNCH 0.55
#define PLASMA_CRUNCH 4
#define HYDROGEN_CRUNCH 2
#define H2O_CRUNCH 0.75
#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
@@ -156,6 +159,7 @@
var/co2comp = 0
var/n2ocomp = 0
var/h2comp = 0
var/h2ocomp = 0
///The last air sample's total molar count, will always be above or equal to 0
var/combined_gas = 0
@@ -522,13 +526,14 @@
n2ocomp = max(removed.sleeping_agent() / combined_gas, 0)
n2comp = max(removed.nitrogen() / combined_gas, 0)
h2comp = max(removed.hydrogen() / combined_gas, 0)
h2ocomp = max(removed.water_vapor() / combined_gas, 0)
gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp + h2comp - n2comp, 0), 1)
gasmix_power_ratio = min(max(plasmacomp + o2comp + co2comp + h2comp + h2ocomp - n2comp, 0), 1)
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_modifier = max((plasmacomp * PLASMA_HEAT_PENALTY) + (o2comp * OXYGEN_HEAT_PENALTY) + (co2comp * CO2_HEAT_PENALTY) + (n2comp * NITROGEN_HEAT_PENALTY) + (h2comp * HYDROGEN_HEAT_PENALTY) + (h2ocomp * H2O_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)
power_transmission_bonus = max((plasmacomp * PLASMA_TRANSMIT_MODIFIER) + (o2comp * OXYGEN_TRANSMIT_MODIFIER) + (h2comp * HYDROGEN_TRANSMIT_MODIFIER) + (h2ocomp * H2O_TRANSMIT_MODIFIER), 0)
//more moles of gases are harder to heat than fewer, so let's scale heat damage around them
mole_heat_penalty = max(combined_gas / MOLE_HEAT_PENALTY, 1)
@@ -568,7 +573,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 + h2comp * HYDROGEN_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 + h2ocomp * H2O_CRUNCH)
radiation_pulse(src, 6 * power * (gas_coefficient + max(0, ((power_transmission_bonus / 10)))), GAMMA_RAD)
@@ -1282,9 +1287,11 @@
#undef CO2_HEAT_PENALTY
#undef NITROGEN_HEAT_PENALTY
#undef HYDROGEN_HEAT_PENALTY
#undef H2O_HEAT_PENALTY
#undef OXYGEN_TRANSMIT_MODIFIER
#undef PLASMA_TRANSMIT_MODIFIER
#undef HYDROGEN_TRANSMIT_MODIFIER
#undef H2O_TRANSMIT_MODIFIER
#undef N2O_HEAT_RESISTANCE
#undef POWERLOSS_INHIBITION_GAS_THRESHOLD
#undef POWERLOSS_INHIBITION_MOLE_THRESHOLD
@@ -1328,3 +1335,4 @@
#undef N2O_CRUNCH
#undef PLASMA_CRUNCH
#undef HYDROGEN_CRUNCH
#undef H2O_CRUNCH
@@ -120,6 +120,15 @@
air.set_hydrogen(2000)
supermatter_turf.blind_release_air(air)
//water vapor
/datum/engi_event/supermatter_event/charlie_tier/water_vapor
name = "C-5"
/datum/engi_event/supermatter_event/charlie_tier/water_vapor/on_start()
var/datum/gas_mixture/air = new()
air.set_water_vapor(2000)
supermatter_turf.blind_release_air(air)
//Class B events
/datum/engi_event/supermatter_event/bravo_tier
threat_level = SM_EVENT_THREAT_B
@@ -19,6 +19,7 @@
air.set_sleeping_agent(T.sleeping_agent)
air.set_agent_b(T.agent_b)
air.set_hydrogen(T.hydrogen)
air.set_water_vapor(T.water_vapor)
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", "H2")
var/picked_gas = pick("N2O", "N2", "O2", "CO2", "Plasma", "Unknown", "H2", "H2O")
switch(picked_gas)
if("N2")
name = "G-1"
@@ -53,6 +53,9 @@
if("H2")
name = "G-7"
air.set_hydrogen(250)
if("H2O")
name = "G-8"
air.set_water_vapor(250)
air.set_temperature(T20C)
var/turf/tap_turf = get_turf(tap)