diff --git a/byond-extools/src/monstermos/GasMixture.cpp b/byond-extools/src/monstermos/GasMixture.cpp index 51711c4..7493227 100644 --- a/byond-extools/src/monstermos/GasMixture.cpp +++ b/byond-extools/src/monstermos/GasMixture.cpp @@ -69,6 +69,7 @@ void GasMixture::merge(const GasMixture &giver) { for(int i = 0; i < TOTAL_NUM_GASES; i++) { moles[i] += giver.moles[i]; } + set_dirty(true); } GasMixture GasMixture::remove(float amount) { @@ -161,6 +162,14 @@ float GasMixture::share(GasMixture &sharer, int atmos_adjacent_turfs) { float their_moles = sharer.total_moles();; return (temperature_archived*(our_moles + moved_moles) - sharer.temperature_archived*(their_moles - moved_moles)) * R_IDEAL_GAS_EQUATION / volume; } + if(moved_moles > 0) + { + sharer.set_dirty(true); + } + else + { + set_dirty(true); + } return 0; } @@ -176,6 +185,14 @@ void GasMixture::temperature_share(GasMixture &sharer, float conduction_coeffici temperature = std::max(temperature - heat/self_heat_capacity, TCMB); if(!sharer.immutable) sharer.temperature = std::max(sharer.temperature + heat/sharer_heat_capacity, TCMB); + if(temperature_delta > 0) + { + sharer.set_dirty(true); + } + else + { + set_dirty(true); + } } } } @@ -202,6 +219,7 @@ int GasMixture::compare(GasMixture &sample) const { void GasMixture::clear() { if (immutable) return; memset(moles, 0, sizeof(moles)); + set_dirty(false); } void GasMixture::multiply(float multiplier) { @@ -209,4 +227,5 @@ void GasMixture::multiply(float multiplier) { for (int i = 0; i < TOTAL_NUM_GASES; i++) { moles[i] *= multiplier; } + set_dirty(true); } diff --git a/byond-extools/src/monstermos/GasMixture.h b/byond-extools/src/monstermos/GasMixture.h index e30d438..b913a1e 100644 --- a/byond-extools/src/monstermos/GasMixture.h +++ b/byond-extools/src/monstermos/GasMixture.h @@ -46,7 +46,8 @@ class GasMixture inline float get_volume() const { return volume; } inline void set_volume(float new_vol) { volume = new_vol; } inline float get_last_share() const { return last_share; } - + inline void set_dirty(bool dirty) { dirty_react = dirty; } + inline float sleeping() { return !dirty_react || total_moles() == 0; } private: GasMixture(); float moles[TOTAL_NUM_GASES]; @@ -57,6 +58,7 @@ class GasMixture float last_share = 0; float min_heat_capacity = 0; bool immutable = false; + bool dirty_react = true; // you might thing, "damn, all the gases, wont that use up more memory"? // well no. Let's look at the average gas mixture in BYOND land containing both oxygen and nitrogen: // gases (28+8 bytes) diff --git a/byond-extools/src/monstermos/Reaction.cpp b/byond-extools/src/monstermos/Reaction.cpp new file mode 100644 index 0000000..d7bfa42 --- /dev/null +++ b/byond-extools/src/monstermos/Reaction.cpp @@ -0,0 +1,258 @@ +#include "Reaction.h" + +#include "reaction_defines.h" + +#include + +using namespace monstermos::constants; + +extern std::unordered_map gas_id_strings; + +extern int o2,plasma,co2,tritium,water_vapor,n2o,bz,no2; + +bool ByondReaction::check_conditions(GasMixture& air) +{ + auto temp = air.get_temperature(); + auto ener = air.thermal_energy(); + if(temp < min_temp_req || ener < min_ener_req) + { + return false; + } + else + { + for(int i = 0; i < TOTAL_NUM_GASES; i++) + { + if(air.get_moles(i) < min_gas_reqs[i]) + { + return false; + } + } + } + return true; +} + +int ByondReaction::react(GasMixture& air,Value src,Value holder) +{ + return (int)(float)(Core::get_proc(proc_id).call({src,holder})); +} +/* +bool PlasmaFire::check_conditions(GasMixture& air) +{ + return air.get_temperature() > PLASMA_MINIMUM_BURN_TEMPERATURE && + air.get_moles(plasma) > MINIMUM_MOLE_COUNT && + air.get_moles(o2) > MINIMUM_MOLE_COUNT; +} + +int PlasmaFire::react(GasMixture& air,Value src,Value holder) +{ + bool superSaturation = false; + float temperature_scale; + float plasma_burn_rate; + float oxygen_burn_rate; + float energy_released = 0.0; + auto initial_oxygen = air.get_moles(o2); + auto initial_plasma = air.get_moles(plasma); + auto old_energy = air.thermal_energy(); + auto temperature = air.get_temperature(); + Container results = src.get("reaction_results"); + results["fire"] = 0.0; + if(temperature > PLASMA_UPPER_TEMPERATURE) + { + temperature_scale = 1; + } + else + { + temperature_scale = (temperature - PLASMA_MINIMUM_BURN_TEMPERATURE) / (PLASMA_UPPER_TEMPERATURE - PLASMA_MINIMUM_BURN_TEMPERATURE); + } + if(temperature_scale > 0) + { + oxygen_burn_rate = (OXYGEN_BURN_RATE_BASE-temperature_scale); + superSaturation = (initial_oxygen/initial_plasma>SUPER_SATURATION_THRESHOLD); + if(initial_oxygen>initial_plasma*PLASMA_OXYGEN_FULLBURN) + { + plasma_burn_rate = initial_plasma*temperature_scale/PLASMA_BURN_RATE_DELTA; + } + else + { + plasma_burn_rate = (temperature_scale*(initial_oxygen/PLASMA_OXYGEN_FULLBURN))/PLASMA_BURN_RATE_DELTA; + } + plasma_burn_rate = std::min(plasma_burn_rate,std::min(initial_plasma,initial_oxygen/oxygen_burn_rate)); + air.set_moles(plasma,initial_plasma - plasma_burn_rate); + air.set_moles(o2,initial_oxygen - (plasma_burn_rate*oxygen_burn_rate)); + if(superSaturation) + { + air.set_moles(tritium,air.get_moles(tritium) + plasma_burn_rate); + } + else + { + air.set_moles(co2,air.get_moles(co2) + plasma_burn_rate); + } + energy_released = FIRE_PLASMA_ENERGY_RELEASED * plasma_burn_rate; + results["fire"] = plasma_burn_rate*(1+oxygen_burn_rate); + } + if(energy_released > 0) + { + air.set_temperature((old_energy+energy_released)/air.heat_capacity()); + } + if(holder.type == DataType::TURF) + { + temperature = air.get_temperature(); + if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + { + holder.invoke("hotspot_expose",{temperature, CELL_VOLUME}); + IncRefCount(src.type,src.value); + holder.invoke("temperature_expose",{src,temperature,CELL_VOLUME}); + } + } + return results.at("fire") > 0.0 ? REACTING : NO_REACTION; +} + +bool TritFire::check_conditions(GasMixture& air) +{ + return air.get_temperature() > FIRE_MINIMUM_TEMPERATURE_TO_EXIST && + air.get_moles(tritium) > MINIMUM_MOLE_COUNT && + air.get_moles(o2) > MINIMUM_MOLE_COUNT; +} + +#include + +#include "../core/proc_management.h" + +int TritFire::react(GasMixture& air,Value src,Value holder) +{ + float energy_released = 0.0; + float old_heat_capacity = air.heat_capacity(); + float temperature = air.get_temperature(); + Container results = src.get("reaction_results"); + results["fire"] = 0.0; + float burned_fuel = 0.0; + if(air.get_moles(o2) < air.get_moles(tritium)) + { + burned_fuel = air.get_moles(o2)/TRITIUM_BURN_OXY_FACTOR; + air.set_moles(tritium, air.get_moles(tritium)-burned_fuel); + } + else + { + burned_fuel = air.get_moles(tritium)*TRITIUM_BURN_TRIT_FACTOR; + air.set_moles(tritium, air.get_moles(tritium)-air.get_moles(tritium)/TRITIUM_BURN_TRIT_FACTOR); + air.set_moles(o2,air.get_moles(o2)-air.get_moles(tritium)); + } + if(burned_fuel > 0.0) + { + energy_released += FIRE_HYDROGEN_ENERGY_RELEASED * burned_fuel; + if(holder.type == TURF && burned_fuel > TRITIUM_MINIMUM_RADIATION_ENERGY) + { + std::random_device rd; + std::mt19937 gen(rd()); + if(std::generate_canonical(gen) < 0.1) + { + IncRefCount(holder.type,holder.value); + Core::get_proc("/proc/radiation_pulse").call({holder, energy_released/TRITIUM_BURN_RADIOACTIVITY_FACTOR}); + } + air.set_moles(water_vapor, air.get_moles(water_vapor) + burned_fuel/TRITIUM_BURN_OXY_FACTOR); + results["fire"] = burned_fuel; + } + } + if(energy_released > 0.0) + { + auto new_heat_capacity = air.heat_capacity(); + if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) + { + air.set_temperature((temperature*old_heat_capacity + energy_released)/new_heat_capacity); + } + } + if(holder.type == DataType::TURF) + { + temperature = air.get_temperature(); + if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + { + holder.invoke("hotspot_expose",{temperature, CELL_VOLUME}); + IncRefCount(src.type,src.value); + holder.invoke("temperature_expose",{src,temperature,CELL_VOLUME}); + } + } + return results.at("fire") > 0.0 ? REACTING : NO_REACTION; +} + +#define _USE_MATH_DEFINES + +#include + +#include + +bool Fusion::check_conditions(GasMixture& air) +{ + return air.get_temperature() > FUSION_TEMPERATURE_THRESHOLD && + air.get_moles(tritium) > FUSION_TRITIUM_MOLES_USED && + air.get_moles(plasma) > FUSION_MOLE_THRESHOLD && + air.get_moles(co2) > FUSION_MOLE_THRESHOLD; +} + +extern float gas_fusion_power[TOTAL_NUM_GASES]; + +int Fusion::react(GasMixture& air,Value src,Value holder) +{ + Container analyzer_results = src.get("analyzer_results"); + auto old_heat_capacity = air.heat_capacity(); + auto initial_plasma = air.get_moles(plasma); + auto initial_carbon = air.get_moles(co2); + auto scale_factor = air.get_volume() / M_PI; + auto toroidal_size = 2*M_PI+atan((air.get_volume()-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN); + auto gas_power = 0.0; + for(int i = 0;i < TOTAL_NUM_GASES;i++) + { + gas_power += gas_fusion_power[i] * air.get_moles(i); + } + auto instability = fmod(pow(gas_power*INSTABILITY_GAS_POWER_FACTOR,2), toroidal_size); + auto plasma_2 = (initial_plasma - FUSION_MOLE_THRESHOLD)/scale_factor; + auto carbon_2 = (initial_carbon - FUSION_MOLE_THRESHOLD)/scale_factor; + plasma_2 = fmod(plasma_2 - (instability * sin(carbon_2)),toroidal_size); + carbon_2 = fmod(carbon_2 - plasma_2, toroidal_size); + air.set_moles(plasma,plasma_2*scale_factor + FUSION_MOLE_THRESHOLD); + air.set_moles(co2,carbon_2*scale_factor + FUSION_MOLE_THRESHOLD); + auto delta_plasma = initial_plasma - air.get_moles(plasma); + + float reaction_energy = delta_plasma * PLASMA_BINDING_ENERGY; + if(instability < FUSION_INSTABILITY_ENDOTHERMALITY) + { + reaction_energy = std::max((double)reaction_energy,0.0); + } + else if(reaction_energy < 0.0) + { + reaction_energy *= std::sqrtf(instability-FUSION_INSTABILITY_ENDOTHERMALITY); + } + if(air.thermal_energy() + reaction_energy < 0) + { + air.set_moles(plasma,initial_plasma); + air.set_moles(co2,initial_carbon); + return NO_REACTION; + } + air.set_moles(tritium,-FUSION_TRITIUM_MOLES_USED); + if(reaction_energy > 0) + { + air.set_moles(o2,air.get_moles(o2)+FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)); + air.set_moles(n2o,air.get_moles(o2)+FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)); + } + else + { + air.set_moles(bz,air.get_moles(o2)+FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)); + air.set_moles(no2,air.get_moles(o2)+FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)); + } + if(reaction_energy != 0.0) + { + if(holder.type != DataType::NULL_D) + { + auto particle_chance = (PARTICLE_CHANCE_CONSTANT/(reaction_energy/PARTICLE_CHANCE_CONSTANT)) + 1; + auto rad_power = std::max((FUSION_RAD_COEFFICIENT/instability) + FUSION_RAD_MAX,0.0); + IncRefCount(holder.type,holder.value); + Core::get_proc("/proc/fusion_effects").call({holder,(float)particle_chance,(float)rad_power}); + } + auto new_heat_capacity = air.heat_capacity(); + if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) + { + air.set_temperature(std::clamp(air.get_temperature()*old_heat_capacity+reaction_energy,TCMB,INFINITY)); + } + return REACTING; + } + return NO_REACTION; +}*/ \ No newline at end of file diff --git a/byond-extools/src/monstermos/Reaction.h b/byond-extools/src/monstermos/Reaction.h new file mode 100644 index 0000000..52f3700 --- /dev/null +++ b/byond-extools/src/monstermos/Reaction.h @@ -0,0 +1,86 @@ +#pragma once + +#include "GasMixture.h" + +#include "../core/core.h" + +#include "../core/proc_management.h" + +extern std::vector gas_id_to_type; + +extern std::unordered_map gas_rarities; + +class Reaction +{ + public: + virtual bool check_conditions(GasMixture& mix) = 0; + virtual int react(GasMixture& mix,Value src,Value holder) = 0; + inline float get_priority() { return priority; } + protected: + float priority; +}; + +class ByondReaction : public Reaction +{ + public: + virtual bool check_conditions(GasMixture& mix); + virtual int react(GasMixture& mix,Value src,Value holder); + ByondReaction(Value v) { + List min_reqs = v.get("min_requirements"); + if(min_reqs.at("TEMP").type == DataType::NUMBER) min_temp_req = min_reqs.at("TEMP"); + if(min_reqs.at("ENER").type == DataType::NUMBER) min_ener_req = min_reqs.at("ENER"); + size_t next_thing = 0; + for(int i=0;i < TOTAL_NUM_GASES;i++) + { + auto gasReq = min_reqs.at(gas_id_to_type[i]); + if(gasReq.type == DataType::NUMBER) + { + min_gas_reqs[i] = (float)gasReq; + next_thing++; + } + } + priority = v.get("priority"); + auto proc = Core::try_get_proc(Core::stringify(v.get("type")) + "/react"); + if(!proc) + { + Core::alert_dd("Could not find proc for reaction! " + Core::stringify(v.get("type")) + "/react"); + } + else + { + Core::alert_dd("Found proc for reaction: " + Core::stringify(v.get("type")) + "/react"); + } + proc_id = proc->id; + } + private: + float min_temp_req = -1.0; + float min_ener_req = -1.0; + float min_gas_reqs[TOTAL_NUM_GASES] = {-1.0}; + unsigned int proc_id; +}; + +class PlasmaFire : public Reaction +{ + public: + virtual bool check_conditions(GasMixture& mix); + virtual int react(GasMixture& mix,Value src,Value holder); + protected: + int priority = -2; +}; + +class TritFire : public Reaction +{ + public: + virtual bool check_conditions(GasMixture& mix); + virtual int react(GasMixture& mix,Value src,Value holder); + protected: + int priority = -1; +}; + +class Fusion : public Reaction +{ + public: + virtual bool check_conditions(GasMixture& mix); + virtual int react(GasMixture& mix,Value src,Value holder); + protected: + int priority = 2; +}; \ No newline at end of file diff --git a/byond-extools/src/monstermos/monstermos.cpp b/byond-extools/src/monstermos/monstermos.cpp index 1b349fe..5f11150 100644 --- a/byond-extools/src/monstermos/monstermos.cpp +++ b/byond-extools/src/monstermos/monstermos.cpp @@ -2,6 +2,7 @@ #include "../core/core.h" #include "GasMixture.h" +#include "Reaction.h" #include "turf_grid.h" #include "../dmdism/opcodes.h" @@ -19,13 +20,17 @@ std::unordered_map gas_types; std::unordered_map gas_ids; //std::unordered_map> gas_mixtures; std::vector gas_id_to_type; +std::vector> cached_reactions; TurfGrid all_turfs; Value SSair; int str_id_extools_pointer; int gas_mixture_count = 0; float gas_moles_visible[TOTAL_NUM_GASES]; +float gas_fusion_power[TOTAL_NUM_GASES]; std::vector gas_overlays[TOTAL_NUM_GASES]; +int o2,plasma,tritium,co2,water_vapor,n2o,bz,no2; + std::shared_ptr &get_gas_mixture(Value val) { uint32_t v = val.get_by_id(str_id_extools_pointer).value; @@ -183,7 +188,9 @@ trvh gasmixture_set_temperature(unsigned int args_len, Value* args, Value src) if (std::isnan(vf) || std::isinf(vf)) { Runtime("Attempt to set temperature to NaN or Infinity"); } else { - get_gas_mixture(src)->set_temperature(vf); + GasMixture &src_gas = *get_gas_mixture(src); + src_gas.set_temperature(vf); + src_gas.set_dirty(true); } return Value::Null(); } @@ -207,7 +214,9 @@ trvh gasmixture_set_moles(unsigned int args_len, Value* args, Value src) if (args_len < 2 || args[0].type != DATUM_TYPEPATH) return Value::Null(); int index = gas_ids[args[0].value]; - get_gas_mixture(src)->set_moles(index, args[1].valuef); + GasMixture &src_gas = *get_gas_mixture(src); + src_gas.set_moles(index, args[1].valuef); + src_gas.set_dirty(true); return Value::Null(); } @@ -266,6 +275,34 @@ trvh gasmixture_multiply(unsigned int args_len, Value* args, Value src) return Value::Null(); } +trvh gasmixture_react(unsigned int args_len, Value* args, Value src) +{ + GasMixture &src_gas = *get_gas_mixture(src); + if(src_gas.sleeping()) return Value((float)NO_REACTION); + auto ret = 0; + Value holder; + if(args_len == 0) + { + holder = Value(); + } + else + { + holder = args[0]; + } + for(int i=0;icheck_conditions(src_gas)) { + IncRefCount(src.type,src.value); // have to do this or the gas mixture will be GC'd at the end of the function + IncRefCount(holder.type,holder.value); // i'm assuming this would also end up GC'd--even worse + ret |= cached_reactions[i]->react(src_gas,src,holder); + } + if(ret & STOP_REACTIONS) return Value((float)ret); + } + src_gas.set_dirty(ret != NO_REACTION); + return Value((float)ret); +} + trvh turf_update_adjacent(unsigned int args_len, Value* args, Value src) { if (src.type != TURF) { return Value::Null(); } @@ -433,12 +470,14 @@ void initialize_gas_overlays() { if (!GLOB) return; Container meta_gas_visibility = GLOB.get("meta_gas_visibility"); Container meta_gas_overlays = GLOB.get("meta_gas_overlays"); + Container meta_gas_fusions = GLOB.get("meta_gas_fusions"); if (!meta_gas_visibility.type) return; for (int i = 0; i < TOTAL_NUM_GASES; ++i) { Value v = gas_id_to_type[i]; gas_moles_visible[i] = meta_gas_visibility.at(v); gas_overlays[i].clear(); + gas_fusion_power[i] = meta_gas_fusions.at(v); Container gas_overlays_list = meta_gas_overlays.at(v); int num_overlays = gas_overlays_list.length(); for (int j = 0; j < num_overlays; j++) { @@ -453,13 +492,27 @@ trvh SSair_update_ssair(unsigned int args_len, Value* args, Value src) { return Value::Null(); } +#include + +trvh SSair_update_gas_reactions(unsigned int args_len, Value* args, Value src) { + Container gas_reactions = SSair.get("gas_reactions"); + cached_reactions.clear(); + for(int i = 0; i < gas_reactions.length(); i++) + { + cached_reactions.push_back(std::make_shared(gas_reactions.at(i))); + } + std::sort(cached_reactions.begin(),cached_reactions.end(), + [](std::shared_ptr a, std::shared_ptr b) { return a->get_priority() > b->get_priority(); }); + return Value::Null(); +} + int str_id_air; int str_id_atmosadj; int str_id_is_openturf; int str_id_x, str_id_y, str_id_z; int str_id_current_cycle, str_id_archived_cycle, str_id_planetary_atmos, str_id_initial_gas_mix; int str_id_active_turfs; -int str_id_react, str_id_consider_pressure_difference, str_id_update_visuals, str_id_floor_rip; +int str_id_react, str_id_gas_reactions, str_id_consider_pressure_difference, str_id_update_visuals, str_id_floor_rip; int str_id_monstermos_turf_limit, str_id_monstermos_hard_turf_limit; const char* enable_monstermos() @@ -480,6 +533,7 @@ const char* enable_monstermos() str_id_initial_gas_mix = Core::GetStringId("initial_gas_mix", true); str_id_atmos_overlay_types = Core::GetStringId("atmos_overlay_types", true); str_id_react = Core::GetStringId("react", true); + str_id_gas_reactions = Core::GetStringId("gas_reactions", true); str_id_consider_pressure_difference = Core::GetStringId("consider pressure difference", true); // byond replaces "_" with " " in proc names. thanks BYOND. str_id_update_visuals = Core::GetStringId("update visuals", true); str_id_floor_rip = Core::GetStringId("handle decompression floor rip", true); @@ -498,8 +552,17 @@ const char* enable_monstermos() for (int i = 0; i < gaslen; ++i) { Value v = gas_types_list.at(i); - gas_types[Core::stringify(v)] = gas_types_list.at(i); + std::string type_name = Core::stringify(v); + gas_types[type_name] = gas_types_list.at(i); gas_ids[v.value] = i; + if(type_name == "/datum/gas/oxygen") o2 = i; + else if(type_name == "/datum/gas/carbon_dioxide") co2 = i; + else if(type_name == "/datum/gas/tritium") tritium = i; + else if(type_name == "/datum/gas/plasma") plasma = i; + else if(type_name == "/datum/gas/water_vapor") water_vapor = i; + else if(type_name == "/datum/gas/nitrous_oxide") n2o = i; + else if(type_name == "/datum/gas/nitryl") no2 = i; + else if(type_name == "/datum/gas/bz") bz = i; gas_specific_heat[i] = gas_types_list.at(v).valuef; gas_id_to_type.push_back(v); } @@ -531,6 +594,7 @@ const char* enable_monstermos() Core::get_proc("/datum/gas_mixture/proc/clear").hook(gasmixture_clear); Core::get_proc("/datum/gas_mixture/proc/multiply").hook(gasmixture_multiply); Core::get_proc("/datum/gas_mixture/proc/get_last_share").hook(gasmixture_get_last_share); + Core::get_proc("/datum/gas_mixture/proc/react").hook(gasmixture_react); Core::get_proc("/turf/proc/__update_extools_adjacent_turfs").hook(turf_update_adjacent); Core::get_proc("/turf/proc/update_air_ref").hook(turf_update_air_ref); Core::get_proc("/turf/open/proc/eg_reset_cooldowns").hook(turf_eg_reset_cooldowns); @@ -544,6 +608,7 @@ const char* enable_monstermos() Core::get_proc("/datum/controller/subsystem/air/proc/process_excited_groups_extools").hook(SSair_process_excited_groups); Core::get_proc("/datum/controller/subsystem/air/proc/get_amt_excited_groups").hook(SSair_get_amt_excited_groups); Core::get_proc("/datum/controller/subsystem/air/proc/extools_update_ssair").hook(SSair_update_ssair); + Core::get_proc("/datum/controller/subsystem/air/proc/extools_setup_gas_reactions").hook(SSair_update_gas_reactions); all_turfs.refresh(); return "ok"; diff --git a/byond-extools/src/monstermos/reaction_defines.h b/byond-extools/src/monstermos/reaction_defines.h new file mode 100644 index 0000000..af16d1f --- /dev/null +++ b/byond-extools/src/monstermos/reaction_defines.h @@ -0,0 +1,45 @@ +//Defines used in atmos gas reactions. Used to be located in ..\modules\atmospherics\gasmixtures\reactions.dm, but were moved here because fusion added so fucking many. + +const int MINIMUM_MOLE_COUNT = 0.01; +//Plasma fire properties +const float OXYGEN_BURN_RATE_BASE = 1.4; +const int PLASMA_BURN_RATE_DELTA = 9; +const int PLASMA_MINIMUM_OXYGEN_NEEDED = 2; +const int PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO = 30; +const int FIRE_CARBON_ENERGY_RELEASED = 100000; //Amount of heat released per mole of burnt carbon into the tile +const int FIRE_HYDROGEN_ENERGY_RELEASED = 280000; //Amount of heat released per mole of burnt hydrogen and/or tritium(hydrogen isotope) +const int FIRE_PLASMA_ENERGY_RELEASED = 3000000; //Amount of heat released per mole of burnt plasma into the tile +//General assmos defines. +const int WATER_VAPOR_FREEZE = 200; +const int NITRYL_FORMATION_ENERGY = 100000; +const int TRITIUM_BURN_OXY_FACTOR = 100; +const int TRITIUM_BURN_TRIT_FACTOR = 10; +const int TRITIUM_BURN_RADIOACTIVITY_FACTOR = 50000; //The neutrons gotta go somewhere. Completely arbitrary number. +const float TRITIUM_MINIMUM_RADIATION_ENERGY = 0.1; //minimum 0.01 moles trit or 10 moles oxygen to start producing rads +const int SUPER_SATURATION_THRESHOLD = 96; +const int STIMULUM_HEAT_SCALE = 100000; +const float STIMULUM_FIRST_RISE = 0.65; +const float STIMULUM_FIRST_DROP = 0.065; +const float STIMULUM_SECOND_RISE = 0.0009; +const float STIMULUM_ABSOLUTE_DROP = 0.00000335; +const int REACTION_OPPRESSION_THRESHOLD = 5; +const int NOBLIUM_FORMATION_ENERGY = 2e9; //1 Mole of Noblium takes the planck energy to condense. +//Research point amounts +const int NOBLIUM_RESEARCH_AMOUNT = 1000; +const int BZ_RESEARCH_SCALE = 4; +const int BZ_RESEARCH_MAX_AMOUNT = 400; +const int MIASMA_RESEARCH_AMOUNT = 6; +const int STIMULUM_RESEARCH_AMOUNT = 50; +//Plasma fusion properties +const float FUSION_ENERGY_THRESHOLD = 3e9; //Amount of energy it takes to start a fusion reaction +const int FUSION_MOLE_THRESHOLD = 250; //Mole count required (tritium/plasma) to start a fusion reaction +const float FUSION_TRITIUM_CONVERSION_COEFFICIENT = (1e-10); +const float INSTABILITY_GAS_POWER_FACTOR = 0.003; +const int FUSION_TRITIUM_MOLES_USED = 1; +const int PLASMA_BINDING_ENERGY = 20000000; +const int TOROID_VOLUME_BREAKEVEN = 1000; +const int FUSION_TEMPERATURE_THRESHOLD = 10000; +const int PARTICLE_CHANCE_CONSTANT = (-20000000); +const int FUSION_RAD_MAX = 2000; +const int FUSION_RAD_COEFFICIENT = (-1000); +const int FUSION_INSTABILITY_ENDOTHERMALITY = 2; \ No newline at end of file