A preliminary implementation of chem gases
This commit is contained in:
@@ -15,6 +15,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
/proc/_auxtools_register_gas(datum/gas/gas) // makes sure auxtools knows stuff about this gas
|
||||
|
||||
/datum/auxgm
|
||||
var/done_initializing = FALSE
|
||||
var/list/datums = list()
|
||||
var/list/specific_heats = list()
|
||||
var/list/names = list()
|
||||
@@ -24,6 +25,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
var/list/ids = list()
|
||||
var/list/typepaths = list()
|
||||
var/list/fusion_powers = list()
|
||||
var/list/turf_reagents = list()
|
||||
var/list/breathing_classes = list()
|
||||
var/list/breath_results = list()
|
||||
var/list/breath_reagents = list()
|
||||
@@ -36,18 +38,19 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
var/list/fire_products = list()
|
||||
var/list/fire_burn_rates = list()
|
||||
|
||||
|
||||
/datum/gas
|
||||
var/id = ""
|
||||
var/specific_heat = 0
|
||||
var/name = ""
|
||||
var/gas_overlay = "" //icon_state in icons/effects/atmospherics.dmi
|
||||
var/color = "#ffff"
|
||||
var/moles_visible = null
|
||||
var/flags = NONE //currently used by canisters
|
||||
var/fusion_power = 0 // How much the gas destabilizes a fusion reaction
|
||||
var/breath_results = GAS_CO2 // what breathing this breathes out
|
||||
var/breath_reagent = null // what breathing this adds to your reagents
|
||||
var/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
|
||||
var/datum/reagent/turf_reagent = null
|
||||
var/datum/reagent/breath_reagent = null // what breathing this adds to your reagents
|
||||
var/datum/reagent/breath_reagent_dangerous = null // what breathing this adds to your reagents IF it's above a danger threshold
|
||||
var/list/breath_alert_info = null // list for alerts that pop up when you have too much/not enough of something
|
||||
var/oxidation_temperature = null // temperature above which this gas is an oxidizer; null for none
|
||||
var/oxidation_rate = 1 // how many moles of this can oxidize how many moles of material
|
||||
@@ -87,7 +90,8 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
breath_reagents[g] = gas.breath_reagent
|
||||
if(gas.breath_reagent_dangerous)
|
||||
breath_reagents_dangerous[g] = gas.breath_reagent_dangerous
|
||||
|
||||
if(gas.turf_reagent)
|
||||
turf_reagents[g] = gas.turf_reagent
|
||||
if(gas.oxidation_temperature)
|
||||
oxidation_temperatures[g] = gas.oxidation_temperature
|
||||
oxidation_rates[g] = gas.oxidation_rate
|
||||
@@ -102,6 +106,11 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
fire_enthalpies[g] = gas.fire_energy_released
|
||||
|
||||
_auxtools_register_gas(gas)
|
||||
if(done_initializing)
|
||||
for(var/r in SSair.gas_reactions)
|
||||
var/datum/gas_reaction/R = r
|
||||
R.init_reqs()
|
||||
SSair.auxtools_update_reactions()
|
||||
|
||||
/proc/finalize_gas_refs()
|
||||
|
||||
@@ -112,6 +121,7 @@ GLOBAL_LIST_INIT(nonreactive_gases, typecacheof(list(GAS_O2, GAS_N2, GAS_CO2, GA
|
||||
for(var/breathing_class_path in subtypesof(/datum/breathing_class))
|
||||
var/datum/breathing_class/class = new breathing_class_path
|
||||
breathing_classes[breathing_class_path] = class
|
||||
done_initializing = TRUE
|
||||
finalize_gas_refs()
|
||||
|
||||
|
||||
|
||||
@@ -56,17 +56,62 @@
|
||||
min_requirements = list(GAS_H2O = MOLES_GAS_VISIBLE)
|
||||
|
||||
/datum/gas_reaction/water_vapor/react(datum/gas_mixture/air, datum/holder)
|
||||
var/turf/open/location = isturf(holder) ? holder : null
|
||||
. = NO_REACTION
|
||||
var/turf/open/location = holder
|
||||
if(!istype(location))
|
||||
return NO_REACTION
|
||||
if (air.return_temperature() <= WATER_VAPOR_FREEZE)
|
||||
if(location && location.freon_gas_act())
|
||||
. = REACTING
|
||||
return REACTING
|
||||
else if(location && location.water_vapor_gas_act())
|
||||
air.adjust_moles(GAS_H2O,-MOLES_GAS_VISIBLE)
|
||||
. = REACTING
|
||||
return REACTING
|
||||
|
||||
// no test cause it's entirely based on location
|
||||
|
||||
/datum/gas_reaction/reagent_stuff
|
||||
priority = 0
|
||||
name = "Condensation"
|
||||
id = "condense"
|
||||
|
||||
/datum/gas_reaction/condensation/init_reqs()
|
||||
var/highest_condensation_temp = -INFINITY
|
||||
var/list/reagents = GLOB.gas_data.turf_reagents
|
||||
for(var/gas in reagents)
|
||||
var/datum/reagent/R = reagents[gas]
|
||||
highest_condensation_temp = max(highest_condensation_temp, initial(R.boiling_point))
|
||||
min_requirements = list(
|
||||
"MAX_TEMP" = highest_condensation_temp,
|
||||
"ANY_REAGENT" = 1
|
||||
)
|
||||
|
||||
/datum/gas_reaction/condensation/react(datum/gas_mixture/air, datum/holder)
|
||||
var/turf/open/location = holder
|
||||
if(!istype(location))
|
||||
return NO_REACTION
|
||||
var/list/gas_reagents = GLOB.gas_data.turf_reagents
|
||||
var/temperature = air.return_temperature()
|
||||
. = NO_REACTION
|
||||
var/static/datum/reagents/reagents_holder = new
|
||||
reagents_holder.clear_reagents()
|
||||
reagents_holder.chem_temp = temperature
|
||||
for(var/G in air.get_gases())
|
||||
if(G in gas_reagents)
|
||||
var/datum/reagent/R = gas_reagents[G]
|
||||
if(temperature < initial(R.boiling_point))
|
||||
var/amt = air.get_moles(G)
|
||||
air.adjust_moles(G, -min(initial(R.condensation_amount), amt))
|
||||
reagents_holder.add_reagent(R, amt)
|
||||
. = REACTING
|
||||
if(. == REACTING)
|
||||
for(var/atom/movable/AM in location)
|
||||
if(location.intact && AM.level == 1) //hidden under the floor
|
||||
continue
|
||||
reagents_holder.reaction(AM, TOUCH)
|
||||
|
||||
reagents_holder.reaction(location, TOUCH)
|
||||
|
||||
|
||||
|
||||
//tritium combustion: combustion of oxygen and tritium (treated as hydrocarbons). creates hotspots. exothermic
|
||||
/datum/gas_reaction/tritfire
|
||||
priority = -1 //fire should ALWAYS be last, but tritium fires happen before plasma fires
|
||||
|
||||
@@ -794,7 +794,7 @@
|
||||
pH = REAGENT_NORMAL_PH
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1)
|
||||
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1, from_gas = 0)
|
||||
var/react_type
|
||||
if(isliving(A))
|
||||
react_type = "LIVING"
|
||||
@@ -818,7 +818,7 @@
|
||||
touch_protection = L.get_permeability_protection()
|
||||
R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection)
|
||||
if("TURF")
|
||||
R.reaction_turf(A, R.volume * volume_modifier, show_message)
|
||||
R.reaction_turf(A, R.volume * volume_modifier, show_message, from_gas)
|
||||
if("OBJ")
|
||||
R.reaction_obj(A, R.volume * volume_modifier, show_message)
|
||||
|
||||
@@ -828,17 +828,16 @@
|
||||
return FALSE
|
||||
|
||||
//Returns the average specific heat for all reagents currently in this holder.
|
||||
/datum/reagents/proc/specific_heat()
|
||||
/datum/reagents/proc/heat_capacity()
|
||||
. = 0
|
||||
var/cached_amount = total_volume //cache amount
|
||||
var/list/cached_reagents = reagent_list //cache reagents
|
||||
for(var/I in cached_reagents)
|
||||
var/datum/reagent/R = I
|
||||
. += R.specific_heat * (R.volume / cached_amount)
|
||||
. += R.specific_heat * R.volume
|
||||
|
||||
/datum/reagents/proc/adjust_thermal_energy(J, min_temp = 2.7, max_temp = 1000)
|
||||
var/S = specific_heat()
|
||||
chem_temp = clamp(chem_temp + (J / (S * total_volume)), min_temp, max_temp)
|
||||
var/S = heat_capacity()
|
||||
chem_temp = clamp(chem_temp + (J / S), min_temp, max_temp)
|
||||
if(istype(my_atom, /obj/item/reagent_containers))
|
||||
var/obj/item/reagent_containers/RC = my_atom
|
||||
RC.temp_check()
|
||||
|
||||
@@ -390,11 +390,11 @@
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent]
|
||||
if(R)
|
||||
var/state = "Unknown"
|
||||
if(initial(R.reagent_state) == 1)
|
||||
if(initial(R.reagent_state) == SOLID)
|
||||
state = "Solid"
|
||||
else if(initial(R.reagent_state) == 2)
|
||||
else if(initial(R.reagent_state) == LIQUID)
|
||||
state = "Liquid"
|
||||
else if(initial(R.reagent_state) == 3)
|
||||
else if(initial(R.reagent_state) == GAS)
|
||||
state = "Gas"
|
||||
var/const/P = 3 //The number of seconds between life ticks
|
||||
var/T = initial(R.metabolization_rate) * (60 / P)
|
||||
|
||||
@@ -54,6 +54,9 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME
|
||||
var/value = REAGENT_VALUE_NONE //How much does it sell for in cargo?
|
||||
var/datum/material/material //are we made of material?
|
||||
var/gas //do we have an associated gas?
|
||||
var/boiling_point = null // point at which this gas boils; if null, will never boil (and thus not become a gas)
|
||||
var/condensation_amount = 1
|
||||
|
||||
/datum/reagent/New()
|
||||
. = ..()
|
||||
@@ -80,8 +83,18 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
/datum/reagent/proc/reaction_obj(obj/O, volume)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/reaction_turf(turf/T, volume)
|
||||
return
|
||||
/datum/reagent/proc/reaction_turf(turf/T, volume, show_message, from_gas)
|
||||
if(!from_gas && boiling_point)
|
||||
var/temp = holder?.chem_temp
|
||||
if(!temp)
|
||||
if(isopenturf(T))
|
||||
var/turf/open/O = T
|
||||
var/datum/gas_mixture/air = O.return_air()
|
||||
temp = air.return_temperature()
|
||||
else
|
||||
temp = T20C
|
||||
if(temp > boiling_point)
|
||||
T.atmos_spawn_air("[get_gas()]=[volume/2];TEMP=[temp]")
|
||||
|
||||
/datum/reagent/proc/on_mob_life(mob/living/carbon/M)
|
||||
current_cycle++
|
||||
@@ -231,6 +244,46 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
|
||||
return rs.Join(" | ")
|
||||
|
||||
/datum/reagent/proc/define_gas()
|
||||
if(reagent_state == SOLID)
|
||||
return null // doesn't make that much sense
|
||||
var/list/cached_reactions = GLOB.chemical_reactions_list
|
||||
for(var/reaction in cached_reactions[src.type])
|
||||
var/datum/chemical_reaction/C = reaction
|
||||
if(!istype(C))
|
||||
continue
|
||||
if(C.required_reagents.len < 2) // no reagents that react on their own
|
||||
return null
|
||||
var/datum/gas/G = new
|
||||
G.id = "[src.type]"
|
||||
G.name = name
|
||||
G.specific_heat = specific_heat / 10
|
||||
G.color = color
|
||||
G.breath_reagent = src.type
|
||||
G.turf_reagent = src.type
|
||||
return G
|
||||
|
||||
/datum/reagent/proc/create_gas()
|
||||
var/datum/gas/G = define_gas()
|
||||
if(istype(G)) // if this reagent should never be a gas, define_gas may return null
|
||||
GLOB.gas_data.add_gas(G)
|
||||
|
||||
/datum/reagent/proc/get_gas()
|
||||
if(gas)
|
||||
return gas
|
||||
else
|
||||
var/datum/auxgm/cached_gas_data = GLOB.gas_data
|
||||
. = "[src.type]"
|
||||
if(!(. in cached_gas_data.ids))
|
||||
var/datum/gas/G = define_gas()
|
||||
if(istype(G))
|
||||
cached_gas_data.add_gas(G)
|
||||
else // this codepath should probably not happen at all, since we never use get_gas() on anything with no boiling point
|
||||
return null
|
||||
|
||||
|
||||
|
||||
|
||||
//For easy bloodsucker disgusting and blood removal
|
||||
/datum/reagent/proc/disgust_bloodsucker(mob/living/carbon/C, disgust, blood_change, blood_puke = TRUE, force)
|
||||
if(AmBloodsucker(C))
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
taste_description = "alcohol"
|
||||
var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning
|
||||
pH = 7.33
|
||||
boiling_point = 351.38
|
||||
value = REAGENT_VALUE_VERY_COMMON //don't bother tweaking all drinks values, way too many can easily be done roundstart or with an upgraded dispenser.
|
||||
|
||||
/*
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "Drug"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
taste_description = "bitterness"
|
||||
boiling_point = T0C + 100
|
||||
var/trippy = TRUE //Does this drug make you trip?
|
||||
|
||||
/datum/reagent/drug/on_mob_end_metabolize(mob/living/M)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
/datum/reagent/medicine
|
||||
name = "Medicine"
|
||||
taste_description = "bitterness"
|
||||
boiling_point = T0C + 100
|
||||
value = REAGENT_VALUE_VERY_COMMON //Low prices, spess medical companies are cheapstakes and products are taxed honk...
|
||||
|
||||
/datum/reagent/medicine/on_mob_life(mob/living/carbon/M)
|
||||
|
||||
@@ -1006,6 +1006,7 @@
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
taste_description = "chlorine"
|
||||
pH = 7.4
|
||||
boiling_point = 239.11
|
||||
|
||||
// You're an idiot for thinking that one of the most corrosive and deadly gasses would be beneficial
|
||||
/datum/reagent/chlorine/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
|
||||
@@ -1272,7 +1273,14 @@
|
||||
glass_name = "glass of welder fuel"
|
||||
glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption."
|
||||
pH = 4
|
||||
boiling_point = 189
|
||||
|
||||
/datum/reagent/fuel/define_gas()
|
||||
var/datum/gas/G = ..()
|
||||
G.fire_energy_released = 200000
|
||||
G.fire_products = list(GAS_CO2 = 1)
|
||||
G.fire_temperature = T20C+30
|
||||
return G
|
||||
|
||||
/datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite!
|
||||
if(method == TOUCH || method == VAPOR)
|
||||
@@ -1290,6 +1298,7 @@
|
||||
description = "A compound used to clean things. Now with 50% more sodium hypochlorite!"
|
||||
color = "#A5F0EE" // rgb: 165, 240, 238
|
||||
taste_description = "sourness"
|
||||
boiling_point = T0C+50
|
||||
pH = 5.5
|
||||
|
||||
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
|
||||
@@ -1302,6 +1311,7 @@
|
||||
O.clean_blood()
|
||||
|
||||
/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume)
|
||||
..()
|
||||
if(reac_volume >= 1)
|
||||
T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
|
||||
@@ -2454,6 +2464,7 @@
|
||||
var/decal_path = /obj/effect/decal/cleanable/semen
|
||||
|
||||
/datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume)
|
||||
..()
|
||||
if(!istype(T))
|
||||
return
|
||||
if(reac_volume < 10)
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
color = "#FFC8C8"
|
||||
metabolization_rate = 4
|
||||
taste_description = "burning"
|
||||
boiling_point = 289.4
|
||||
condensation_amount = 2
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
/datum/reagent/clf3/on_mob_life(mob/living/carbon/M)
|
||||
@@ -82,6 +84,14 @@
|
||||
if(!locate(/obj/effect/hotspot) in M.loc)
|
||||
new /obj/effect/hotspot(M.loc)
|
||||
|
||||
/datum/reagent/clf3/define_gas()
|
||||
var/datum/gas/G = ..()
|
||||
G.fire_energy_released = 123000
|
||||
G.oxidation_rate = 4
|
||||
G.oxidation_temperature = T0C - 50
|
||||
G.turf_reagent = src.type
|
||||
return G
|
||||
|
||||
/datum/reagent/sorium
|
||||
name = "Sorium"
|
||||
description = "Sends everything flying from the detonation point."
|
||||
@@ -149,8 +159,16 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FA00AF"
|
||||
taste_description = "burning"
|
||||
boiling_point = T20C-10
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
|
||||
/datum/reagent/phlogiston/define_gas()
|
||||
var/datum/gas/G = ..()
|
||||
G.fire_energy_released = FIRE_PLASMA_ENERGY_RELEASED / 100
|
||||
G.fire_burn_rate = 1
|
||||
G.fire_temperature = T20C+1
|
||||
return G
|
||||
|
||||
/datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
M.adjust_fire_stacks(1)
|
||||
var/burndmg = max(0.3*M.fire_stacks, 0.3)
|
||||
@@ -281,6 +299,9 @@
|
||||
taste_description = "the inside of a fire extinguisher"
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
|
||||
/datum/reagent/firefighting_foam/define_gas()
|
||||
return null
|
||||
|
||||
/datum/reagent/firefighting_foam/reaction_turf(turf/open/T, reac_volume)
|
||||
if (!istype(T))
|
||||
return
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
taste_description = "bitterness"
|
||||
taste_mult = 1.2
|
||||
value = REAGENT_VALUE_COMMON //Encouraging people to mix toxins for reasons beyond harming each other or mixing reagents such as pen acid.
|
||||
boiling_point = T0C + 100
|
||||
var/toxpwr = 1.5
|
||||
|
||||
// Are you a bad enough dude to poison your own plants?
|
||||
|
||||
Reference in New Issue
Block a user