[MIRROR] Refactors SM gas behavior to be datum based instead of list based + powerloss co2 buff [MDB IGNORE] (#16000)

* Refactors SM gas behavior to be datum based instead of list based + powerloss co2 buff (#69158)

About The Pull Request

Title!
The CO2 thing is there because it makes my job much easier. Can probably find a way to make it move slowly if a maint insist on it. Prefer not to though.

Drafting because I want to make a second PR that have more sweeping changes (clean vars up, make a simpler formula for damage and heat production, delete underused behaviors, etc). Would honestly prefer if both this and that gets merged at the same time but I'm separating it out since it might be rejected. Or maybe ill combine it here we'll see.
Ignore that, looks like i can keep this one absolutely atomic.
Why It's Good For The Game

Had a lot of trouble when trying to document the SM gas interactions into the wiki, the interactions are all scattered and tracking down everything a gas does is extremely annoying. Hopefully this fixes that.
Changelog

cl
balance: CO2 powerloss inhibition now works immediately based on gas composition instead of slowly ramping up.
refactor: refactored how the SM fetches it's gas info and data. No changes expected except for the co2 thing.
/cl

* Refactors SM gas behavior to be datum based instead of list based + powerloss co2 buff

Co-authored-by: vincentiusvin <54709710+vincentiusvin@users.noreply.github.com>
This commit is contained in:
SkyratBot
2022-09-02 11:35:23 +01:00
committed by GitHub
co-authored by vincentiusvin
parent 5567fac8db
commit f0ceecff46
5 changed files with 229 additions and 239 deletions
-49
View File
@@ -1,44 +1,3 @@
#define PLASMA_HEAT_PENALTY 15 // Higher == Bigger heat and waste penalty from having the crystal surrounded by this gas. Negative numbers reduce penalty.
#define OXYGEN_HEAT_PENALTY 1
#define PLUOXIUM_HEAT_PENALTY -0.5 //Better then co2, worse then n2
#define TRITIUM_HEAT_PENALTY 10
#define CO2_HEAT_PENALTY 2
#define NITROGEN_HEAT_PENALTY -1.5
#define BZ_HEAT_PENALTY 5
#define H2O_HEAT_PENALTY 12 //This'll get made slowly over time, I want my spice rock spicy god damnit
#define FREON_HEAT_PENALTY -10 //very good heat absorbtion and less plasma and o2 generation
#define HYDROGEN_HEAT_PENALTY 10 // similar heat penalty as tritium (dangerous)
#define HEALIUM_HEAT_PENALTY 4
#define PROTO_NITRATE_HEAT_PENALTY -3
#define ZAUKER_HEAT_PENALTY 8
#define HYPERNOBLIUM_HEAT_PENALTY -13
#define ANTINOBLIUM_HEAT_PENALTY 15
//All of these get divided by 10-bzcomp * 5 before having 1 added and being multiplied with power to determine rads
//Keep the negative values here above -10 and we won't get negative rads
#define OXYGEN_TRANSMIT_MODIFIER 1.5 //Higher == Bigger bonus to power generation.
#define PLASMA_TRANSMIT_MODIFIER 4
#define BZ_TRANSMIT_MODIFIER -2
#define TRITIUM_TRANSMIT_MODIFIER 30 //We divide by 10, so this works out to 3
#define PLUOXIUM_TRANSMIT_MODIFIER -5 //Should halve the power output
#define H2O_TRANSMIT_MODIFIER 2
#define HYDROGEN_TRANSMIT_MODIFIER 25 //increase the radiation emission, but less than the trit (2.5)
#define HEALIUM_TRANSMIT_MODIFIER 2.4
#define PROTO_NITRATE_TRANSMIT_MODIFIER 15
#define ZAUKER_TRANSMIT_MODIFIER 20
#define ANTINOBLIUM_TRANSMIT_MODIFIER -5
#define HYPERNOBLIUM_TRANSMIT_MODIFIER 3
#define H20_TRANSMIT_MODIFIER -2.5
#define FREON_TRANSMIT_MODIFIER -30
#define N2O_HEAT_RESISTANCE 6 //Higher == Gas makes the crystal more resistant against heat damage.
#define HYDROGEN_HEAT_RESISTANCE 2 // just a bit of heat resistance to spice it up
#define PROTO_NITRATE_HEAT_RESISTANCE 5
/// The minimum portion of the miasma in the air that will be consumed. Higher values mean more miasma will be consumed be default.
#define MIASMA_CONSUMPTION_RATIO_MIN 0
/// The maximum portion of the miasma in the air that will be consumed. Lower values mean the miasma consumption rate caps earlier.
#define MIASMA_CONSUMPTION_RATIO_MAX 1
/// The minimum pressure for a pure miasma atmosphere to begin being consumed. Higher values mean it takes more miasma pressure to make miasma start being consumed. Should be >= 0
#define MIASMA_CONSUMPTION_PP (ONE_ATMOSPHERE*0.01)
/// How the amount of miasma consumed per tick scales with partial pressure. Higher values decrease the rate miasma consumption scales with partial pressure. Should be >0
@@ -48,10 +7,6 @@
/// The amount of matter power generated for every mole of miasma consumed. Higher values mean miasma generates more power.
#define MIASMA_POWER_GAIN 10
/// The minimum portion of the CO2 in the air that will be consumed. Higher values mean more CO2 will be consumed be default.
#define CO2_CONSUMPTION_RATIO_MIN 0
/// The maximum portion of the CO2 in the air that will be consumed. Lower values mean the CO2 consumption rate caps earlier.
#define CO2_CONSUMPTION_RATIO_MAX 1
/// The minimum pressure for a pure CO2 atmosphere to begin being consumed. Higher values mean it takes more CO2 pressure to make CO2 be consumed. Should be >= 0
#define CO2_CONSUMPTION_PP (ONE_ATMOSPHERE*0.01)
/// How the amount of CO2 consumed per tick scales with partial pressure. Higher values decrease the rate CO2 consumption scales with partial pressure. Should be >0
@@ -59,10 +14,6 @@
/// How much the amount of CO2 consumed per tick scales with gasmix power ratio. Higher values means gasmix has a greater effect on the CO2 consumed.
#define CO2_GASMIX_SCALING (0.1)
#define POWERLOSS_INHIBITION_GAS_THRESHOLD 0.20 //Higher == Higher percentage of inhibitor gas needed before the charge inertia chain reaction effect starts.
#define POWERLOSS_INHIBITION_MOLE_THRESHOLD 20 //Higher == More moles of the gas are needed before the charge inertia chain reaction effect starts. //Scales powerloss inhibition down until this amount of moles is reached
#define POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD 500 //bonus powerloss inhibition boost if this amount of moles is reached
#define MOLE_PENALTY_THRESHOLD 1800 //Above this value we can get lord singulo and independent mol damage, below it we can heal damage
#define MOLE_HEAT_PENALTY 350 //Heat damage scales around this. Too hot setups with this amount of moles do regular damage, anything above and below is scaled
//Along with damage_penalty_point, makes flux anomalies.
+2 -101
View File
@@ -62,107 +62,8 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
var/lastwarning = 0
///Refered to as eer on the moniter. This value effects gas output, heat, damage, and radiation.
var/power = 0
///Determines the rate of positve change in gas comp values
var/gas_change_rate = 0.05
///The list of gases we will be interacting with in process_atoms()
var/list/gases_we_care_about = list(
/datum/gas/oxygen,
/datum/gas/water_vapor,
/datum/gas/plasma,
/datum/gas/carbon_dioxide,
/datum/gas/nitrous_oxide,
/datum/gas/nitrogen,
/datum/gas/pluoxium,
/datum/gas/tritium,
/datum/gas/bz,
/datum/gas/freon,
/datum/gas/hydrogen,
/datum/gas/healium,
/datum/gas/proto_nitrate,
/datum/gas/zauker,
/datum/gas/miasma,
/datum/gas/hypernoblium,
/datum/gas/antinoblium,
)
///The list of gases mapped against their current comp. We use this to calculate different values the supermatter uses, like power or heat resistance. It doesn't perfectly match the air around the sm, instead moving up at a rate determined by gas_change_rate per call. Ranges from 0 to 1
var/list/gas_comp = list(
/datum/gas/oxygen = 0,
/datum/gas/water_vapor = 0,
/datum/gas/plasma = 0,
/datum/gas/carbon_dioxide = 0,
/datum/gas/nitrous_oxide = 0,
/datum/gas/nitrogen = 0,
/datum/gas/pluoxium = 0,
/datum/gas/tritium = 0,
/datum/gas/bz = 0,
/datum/gas/freon = 0,
/datum/gas/hydrogen = 0,
/datum/gas/healium = 0,
/datum/gas/proto_nitrate = 0,
/datum/gas/zauker = 0,
/datum/gas/hypernoblium = 0,
/datum/gas/antinoblium = 0,
)
///The list of gases mapped against their transmit values. We use it to determine the effect different gases have on the zaps
var/list/gas_trans = list(
/datum/gas/oxygen = OXYGEN_TRANSMIT_MODIFIER,
/datum/gas/water_vapor = H2O_TRANSMIT_MODIFIER,
/datum/gas/plasma = PLASMA_TRANSMIT_MODIFIER,
/datum/gas/pluoxium = PLUOXIUM_TRANSMIT_MODIFIER,
/datum/gas/tritium = TRITIUM_TRANSMIT_MODIFIER,
/datum/gas/bz = BZ_TRANSMIT_MODIFIER,
/datum/gas/hydrogen = HYDROGEN_TRANSMIT_MODIFIER,
/datum/gas/healium = HEALIUM_TRANSMIT_MODIFIER,
/datum/gas/proto_nitrate = PROTO_NITRATE_TRANSMIT_MODIFIER,
/datum/gas/zauker = ZAUKER_TRANSMIT_MODIFIER,
/datum/gas/hypernoblium = HYPERNOBLIUM_TRANSMIT_MODIFIER,
/datum/gas/antinoblium = ANTINOBLIUM_TRANSMIT_MODIFIER,
/datum/gas/freon = FREON_TRANSMIT_MODIFIER,
/datum/gas/water_vapor = H20_TRANSMIT_MODIFIER,
)
///The list of gases mapped against their heat penaltys. We use it to determin molar and heat output
var/list/gas_heat = list(
/datum/gas/oxygen = OXYGEN_HEAT_PENALTY,
/datum/gas/water_vapor = H2O_HEAT_PENALTY,
/datum/gas/plasma = PLASMA_HEAT_PENALTY,
/datum/gas/carbon_dioxide = CO2_HEAT_PENALTY,
/datum/gas/nitrogen = NITROGEN_HEAT_PENALTY,
/datum/gas/pluoxium = PLUOXIUM_HEAT_PENALTY,
/datum/gas/tritium = TRITIUM_HEAT_PENALTY,
/datum/gas/bz = BZ_HEAT_PENALTY,
/datum/gas/freon = FREON_HEAT_PENALTY,
/datum/gas/hydrogen = HYDROGEN_HEAT_PENALTY,
/datum/gas/healium = HEALIUM_HEAT_PENALTY,
/datum/gas/proto_nitrate = PROTO_NITRATE_HEAT_PENALTY,
/datum/gas/zauker = ZAUKER_HEAT_PENALTY,
/datum/gas/hypernoblium = HYPERNOBLIUM_HEAT_PENALTY,
/datum/gas/antinoblium = ANTINOBLIUM_HEAT_PENALTY,
)
///The list of gases mapped against their heat resistance. We use it to moderate heat damage.
var/list/gas_resist = list(
/datum/gas/nitrous_oxide = N2O_HEAT_RESISTANCE,
/datum/gas/hydrogen = HYDROGEN_HEAT_RESISTANCE,
/datum/gas/proto_nitrate = PROTO_NITRATE_HEAT_RESISTANCE,
)
///The list of gases mapped against their powermix ratio
var/list/gas_powermix = list(
/datum/gas/oxygen = 1,
/datum/gas/water_vapor = 1,
/datum/gas/plasma = 1,
/datum/gas/carbon_dioxide = 1,
/datum/gas/nitrogen = -1,
/datum/gas/pluoxium = -1,
/datum/gas/tritium = 1,
/datum/gas/bz = 1,
/datum/gas/freon = -1,
/datum/gas/hydrogen = 1,
/datum/gas/healium = 1,
/datum/gas/proto_nitrate = 1,
/datum/gas/zauker = 1,
/datum/gas/miasma = 0.5,
/datum/gas/antinoblium = 1,
/datum/gas/hypernoblium = -1,
)
///The list of gases mapped against their current comp. We use this to calculate different values the supermatter uses, like power or heat resistance. Ranges from 0 to 1
var/list/gas_percentage
///The last air sample's total molar count, will always be above or equal to 0
var/combined_gas = 0
///Total mole count of the environment we are in
@@ -0,0 +1,191 @@
/proc/init_sm_gas()
var/list/gas_list = list()
for (var/sm_gas_path in subtypesof(/datum/sm_gas))
var/datum/sm_gas/sm_gas = new sm_gas_path
gas_list[sm_gas.gas_path] = sm_gas
return gas_list
/// Assoc of sm_gas_behavior[/datum/gas (path)] = datum/sm_gas (instance)
GLOBAL_LIST_INIT(sm_gas_behavior, init_sm_gas())
/// Contains effects of gases when absorbed by the sm.
/datum/sm_gas
/// Path of the [/datum/gas] involved with this interaction.
var/gas_path
/// Influences zap power without interfering with the crystal's own energy.
var/transmit_modifier = 0
/// How much more waste heat and gas the SM generates.
var/heat_penalty = 0
/// How extra hot the SM can run before taking damage
var/heat_resistance = 0
/// Lets the sm generate extra power from heat. Yeah...
var/powermix = 0
/// How much powerloss do we get rid of.
var/powerloss_inhibition = 0
/datum/sm_gas/proc/extra_effects(obj/machinery/power/supermatter_crystal/sm, datum/gas_mixture/env)
return
/datum/sm_gas/oxygen
gas_path = /datum/gas/oxygen
heat_penalty = 1
transmit_modifier = 1.5
powermix = 1
/datum/sm_gas/nitrogen
gas_path = /datum/gas/nitrogen
heat_penalty = -1.5
powermix = -1
/datum/sm_gas/carbon_dioxide
gas_path = /datum/gas/carbon_dioxide
heat_penalty = 2
powermix = 1
powerloss_inhibition = 1
/// Can be on Oxygen or CO2, but better lump it here since CO2 is rarer.
/datum/sm_gas/carbon_dioxide/extra_effects(obj/machinery/power/supermatter_crystal/sm, datum/gas_mixture/env)
if(!(sm.gas_percentage[/datum/gas/carbon_dioxide] && sm.gas_percentage[/datum/gas/oxygen]))
return
var/co2_pp = env.return_pressure() * sm.gas_percentage[/datum/gas/carbon_dioxide]
/// Our consumption ratio, not the actual ratio in SM we already have that.
/// This var is a fucking lie, we only consume half of it.
var/co2_ratio = (co2_pp - CO2_CONSUMPTION_PP) / (co2_pp + CO2_PRESSURE_SCALING)
co2_ratio = clamp(co2_ratio, 0, 1)
var/consumed_co2 = sm.absorbed_gasmix.gases[/datum/gas/carbon_dioxide][MOLES] * co2_ratio
consumed_co2 = min(
consumed_co2,
sm.absorbed_gasmix.gases[/datum/gas/carbon_dioxide][MOLES] * INVERSE(0.5),
sm.absorbed_gasmix.gases[/datum/gas/oxygen][MOLES] * INVERSE(0.5)
)
if(!consumed_co2)
return
sm.absorbed_gasmix.gases[/datum/gas/carbon_dioxide][MOLES] -= consumed_co2 * 0.5
sm.absorbed_gasmix.gases[/datum/gas/oxygen][MOLES] -= consumed_co2 * 0.5
ASSERT_GAS(/datum/gas/pluoxium, sm.absorbed_gasmix)
sm.absorbed_gasmix.gases[/datum/gas/pluoxium][MOLES] += consumed_co2 * 0.25
/datum/sm_gas/plasma
gas_path = /datum/gas/plasma
heat_penalty = 15
transmit_modifier = 4
powermix = 1
/datum/sm_gas/water_vapor
gas_path = /datum/gas/water_vapor
heat_penalty = 12
transmit_modifier = -2.5
powermix = 1
/datum/sm_gas/hypernoblium
gas_path = /datum/gas/hypernoblium
heat_penalty = -13
transmit_modifier = 3
powermix = -1
/datum/sm_gas/nitrous_oxide
gas_path = /datum/gas/nitrous_oxide
heat_resistance = 6
/datum/sm_gas/nitrium
gas_path = /datum/gas/nitrium
/datum/sm_gas/tritium
gas_path = /datum/gas/tritium
heat_penalty = 10
transmit_modifier = 30
powermix = 1
/datum/sm_gas/bz
gas_path = /datum/gas/bz
heat_penalty = 5
transmit_modifier = -2
powermix = 1
/// Start to emit radballs at a maximum of 30% chance per tick
/datum/sm_gas/bz/extra_effects(obj/machinery/power/supermatter_crystal/sm, datum/gas_mixture/env)
if(sm.gas_percentage[/datum/gas/bz] >= 0.4 && prob(30 * sm.gas_percentage[/datum/gas/bz]))
sm.fire_nuclear_particle()
/datum/sm_gas/pluoxium
gas_path = /datum/gas/pluoxium
heat_penalty = -0.5
transmit_modifier = -5
powermix = 1
/datum/sm_gas/miasma
gas_path = /datum/gas/miasma
powermix = 0.5
///Miasma is really just microscopic particulate. It gets consumed like anything else that touches the crystal.
/datum/sm_gas/miasma/extra_effects(obj/machinery/power/supermatter_crystal/sm, datum/gas_mixture/env)
if(!sm.gas_percentage[/datum/gas/miasma])
return
var/miasma_pp = env.return_pressure() * sm.gas_percentage[/datum/gas/miasma]
/// Our consumption ratio, not the actual ratio in SM we already have that.
var/miasma_ratio = ((miasma_pp - MIASMA_CONSUMPTION_PP) / (miasma_pp + MIASMA_PRESSURE_SCALING)) * (1 + (sm.gasmix_power_ratio * MIASMA_GASMIX_SCALING))
miasma_ratio = clamp(miasma_ratio, 0, 1)
var/consumed_miasma = sm.absorbed_gasmix.gases[/datum/gas/miasma][MOLES] * miasma_ratio
if(!consumed_miasma)
return
sm.absorbed_gasmix.gases[/datum/gas/miasma][MOLES] -= consumed_miasma
sm.matter_power += consumed_miasma * MIASMA_POWER_GAIN
/datum/sm_gas/freon
gas_path = /datum/gas/freon
heat_penalty = -10
transmit_modifier = -30
powermix = 1
/datum/sm_gas/hydrogen
gas_path = /datum/gas/hydrogen
heat_penalty = 10
transmit_modifier = 25
heat_resistance = 2
powermix = 1
/datum/sm_gas/healium
gas_path = /datum/gas/healium
heat_penalty = 4
transmit_modifier = 2.4
powermix = 1
/datum/sm_gas/proto_nitrate
gas_path = /datum/gas/proto_nitrate
heat_penalty = -3
transmit_modifier = 15
heat_resistance = 5
powermix = 1
/datum/sm_gas/zauker
gas_path = /datum/gas/zauker
heat_penalty = 8
transmit_modifier = 20
powermix = 1
/datum/sm_gas/zauker/extra_effects(obj/machinery/power/supermatter_crystal/sm, datum/gas_mixture/env)
if(!prob(sm.gas_percentage[/datum/gas/zauker]))
return
playsound(sm.loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10)
sm.supermatter_zap(
sm,
range = 6,
zap_str = clamp(sm.power * 2, 4000, 20000),
zap_flags = ZAP_MOB_STUN,
zap_cutoff = sm.zap_cutoff,
power_level = sm.power,
zap_icon = sm.zap_icon
)
/datum/sm_gas/halon
gas_path = /datum/gas/halon
/datum/sm_gas/helium
gas_path = /datum/gas/helium
/datum/sm_gas/antinoblium
gas_path = /datum/gas/antinoblium
transmit_modifier = -5
heat_penalty = 15
powermix = 1
@@ -22,10 +22,11 @@
environment_total_moles = env.total_moles()
if(produces_gas)
//Remove gas from surrounding area
absorbed_gasmix = env.remove(absorption_ratio * env.total_moles())
absorbed_gasmix = env.remove_ratio(absorption_ratio)
else
// Pass all the gas related code an empty gas container
absorbed_gasmix = new()
overlays -= psyOverlay
if(psy_overlay)
overlays -= psyOverlay
@@ -53,14 +54,38 @@
env.merge(absorbed_gasmix)
air_update_turf(FALSE, FALSE)
else
combined_gas = absorbed_gasmix.total_moles()
gas_percentage = list()
power_transmission_bonus = 0
dynamic_heat_modifier = 0
dynamic_heat_resistance = 0
gasmix_power_ratio = 0
powerloss_dynamic_scaling = 0
for (var/gas_path in absorbed_gasmix.gases)
var/datum/sm_gas/sm_gas = GLOB.sm_gas_behavior[gas_path]
gas_percentage[gas_path] = absorbed_gasmix.gases[gas_path][MOLES] / combined_gas
power_transmission_bonus += sm_gas.transmit_modifier * gas_percentage[gas_path]
dynamic_heat_modifier += sm_gas.heat_penalty * gas_percentage[gas_path]
dynamic_heat_resistance += sm_gas.heat_resistance * gas_percentage[gas_path]
gasmix_power_ratio += sm_gas.powermix * gas_percentage[gas_path]
powerloss_dynamic_scaling += sm_gas.powerloss_inhibition * gas_percentage[gas_path]
gasmix_power_ratio = clamp(gasmix_power_ratio, 0, 1)
dynamic_heat_modifier = max(dynamic_heat_modifier, 0.5)
dynamic_heat_resistance = max(dynamic_heat_resistance, 1)
// Extra effects should always fire after the compositions are all finished
// Some extra effects like [/datum/sm_gas/carbon_dioxide/extra_effects] needs more than one gas.
for (var/gas_path in absorbed_gasmix.gases)
var/datum/sm_gas/sm_gas = GLOB.sm_gas_behavior[gas_path]
sm_gas.extra_effects(src, env)
if(takes_damage)
//causing damage
deal_damage(absorbed_gasmix)
//registers the current enviromental gases in the various lists and vars
setup_lists(absorbed_gasmix)
//some gases can have special interactions
special_gases_interactions(env, absorbed_gasmix)
//main power calculations proc
power_calculations(env, absorbed_gasmix)
//irradiate at this point
@@ -128,6 +153,8 @@
break
var/delam_damage_multipler = delamination_strategy.damage_multiplier(src)
//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, 0.25)
//Due to DAMAGE_INCREASE_MULTIPLIER, we only deal one 4th of the damage the statements otherwise would cause
//((((some value between 0.5 and 1 * temp - ((273.15 + 40) * some values between 1 and 10)) * some number between 0.25 and knock your socks off / 150) * 0.25
@@ -150,93 +177,10 @@
//This means we can only deal 1.8 damage per function call
damage = min(damage_archived + (DAMAGE_HARDCAP * explosion_point),damage)
/obj/machinery/power/supermatter_crystal/proc/setup_lists(datum/gas_mixture/removed)
for(var/gas_id in gases_we_care_about)
removed.assert_gas(gas_id)
//calculating gas related values
//Wanna know a secret? See that max() to zero? it's used for error checking. If we get a mol count in the negative, we'll get a divide by zero error //Old me, you're insane
combined_gas = max(removed.total_moles(), 0)
//This is more error prevention, according to all known laws of atmos, gas_mix.remove() should never make negative mol values.
//But this is tg
//Lets get the proportions of the gasses in the mix for scaling stuff later
//They range between 0 and 1
for(var/gas_id in gases_we_care_about)
gas_comp[gas_id] = clamp(removed.gases[gas_id][MOLES] / combined_gas, 0, 1)
var/list/heat_mod = gases_we_care_about.Copy()
var/list/transit_mod = gases_we_care_about.Copy()
var/list/resistance_mod = gases_we_care_about.Copy()
//No less then zero, and no greater then one, we use this to do explosions and heat to power transfer
//Be very careful with modifing this var by large amounts, and for the love of god do not push it past 1
gasmix_power_ratio = 0
for(var/gas_id in gas_powermix)
gasmix_power_ratio += gas_comp[gas_id] * gas_powermix[gas_id]
gasmix_power_ratio = clamp(gasmix_power_ratio, 0, 1)
//Minimum value of -10, maximum value of 23. Effects plasma and o2 output and the output heat
dynamic_heat_modifier = 0
for(var/gas_id in gas_heat)
dynamic_heat_modifier += gas_comp[gas_id] * gas_heat[gas_id] * (isnull(heat_mod[gas_id]) ? 1 : heat_mod[gas_id])
dynamic_heat_modifier = max(dynamic_heat_modifier, 0.5)
//Value between 1 and 10. Effects the damage heat does to the crystal
dynamic_heat_resistance = 0
for(var/gas_id in gas_resist)
dynamic_heat_resistance += gas_comp[gas_id] * gas_resist[gas_id] * (isnull(resistance_mod[gas_id]) ? 1 : resistance_mod[gas_id])
dynamic_heat_resistance = max(dynamic_heat_resistance, 1)
//Value between -5 and 30, used to determine radiation output as it concerns things like collectors.
power_transmission_bonus = 0
for(var/gas_id in gas_trans)
power_transmission_bonus += gas_comp[gas_id] * gas_trans[gas_id] * (isnull(transit_mod[gas_id]) ? 1 : transit_mod[gas_id])
/obj/machinery/power/supermatter_crystal/proc/special_gases_interactions(datum/gas_mixture/env, datum/gas_mixture/removed)
//Miasma is really just microscopic particulate. It gets consumed like anything else that touches the crystal.
if(gas_comp[/datum/gas/miasma])
var/miasma_pp = env.return_pressure() * gas_comp[/datum/gas/miasma]
var/consumed_miasma = clamp(((miasma_pp - MIASMA_CONSUMPTION_PP) / (miasma_pp + MIASMA_PRESSURE_SCALING)) * (1 + (gasmix_power_ratio * MIASMA_GASMIX_SCALING)), MIASMA_CONSUMPTION_RATIO_MIN, MIASMA_CONSUMPTION_RATIO_MAX)
consumed_miasma *= gas_comp[/datum/gas/miasma] * combined_gas
if(consumed_miasma)
removed.gases[/datum/gas/miasma][MOLES] -= consumed_miasma
matter_power += consumed_miasma * MIASMA_POWER_GAIN
//Let's say that the CO2 touches the SM surface and the radiation turns it into Pluoxium.
if(gas_comp[/datum/gas/carbon_dioxide] && gas_comp[/datum/gas/oxygen])
var/carbon_dioxide_pp = env.return_pressure() * gas_comp[/datum/gas/carbon_dioxide]
var/consumed_carbon_dioxide = clamp(((carbon_dioxide_pp - CO2_CONSUMPTION_PP) / (carbon_dioxide_pp + CO2_PRESSURE_SCALING)), CO2_CONSUMPTION_RATIO_MIN, CO2_CONSUMPTION_RATIO_MAX)
consumed_carbon_dioxide = min(consumed_carbon_dioxide * gas_comp[/datum/gas/carbon_dioxide] * combined_gas, removed.gases[/datum/gas/carbon_dioxide][MOLES] * INVERSE(0.5), removed.gases[/datum/gas/oxygen][MOLES] * INVERSE(0.5))
if(consumed_carbon_dioxide)
removed.gases[/datum/gas/carbon_dioxide][MOLES] -= consumed_carbon_dioxide * 0.5
removed.gases[/datum/gas/oxygen][MOLES] -= consumed_carbon_dioxide * 0.5
removed.gases[/datum/gas/pluoxium][MOLES] += consumed_carbon_dioxide * 0.25
if(prob(gas_comp[/datum/gas/zauker]))
playsound(loc, 'sound/weapons/emitter2.ogg', 100, TRUE, extrarange = 10)
supermatter_zap(src, 6, clamp(power * 2, 4000, 20000), ZAP_MOB_STUN, zap_cutoff = src.zap_cutoff, power_level = power, zap_icon = src.zap_icon)
if(gas_comp[/datum/gas/bz] >= 0.4 && prob(30 * gas_comp[/datum/gas/bz]))
fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick
/obj/machinery/power/supermatter_crystal/proc/power_calculations(datum/gas_mixture/env, datum/gas_mixture/removed)
//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, 0.25)
//Ramps up or down in increments of 0.02 up to the proportion of co2
//Given infinite time, powerloss_dynamic_scaling = co2comp
//Some value between 0 and 1
if (combined_gas > POWERLOSS_INHIBITION_MOLE_THRESHOLD && gas_comp[/datum/gas/carbon_dioxide] > POWERLOSS_INHIBITION_GAS_THRESHOLD) //If there are more then 20 mols, and more then 20% co2
powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling + clamp(gas_comp[/datum/gas/carbon_dioxide] - powerloss_dynamic_scaling, -0.02, 0.02), 0, 1)
else
powerloss_dynamic_scaling = clamp(powerloss_dynamic_scaling - 0.05, 0, 1)
//Ranges from 0 to 1(1-(value between 0 and 1 * ranges from 1 to 1.5(mol / 500)))
//We take the mol count, and scale it to be our inhibitor
powerloss_inhibitor = clamp(1-(powerloss_dynamic_scaling * clamp(combined_gas/POWERLOSS_INHIBITION_MOLE_BOOST_THRESHOLD, 1, 1.5)), 0, 1)
powerloss_inhibitor = clamp(1-powerloss_dynamic_scaling, 0, 1)
//Releases stored power into the general pool
//We get this by consuming shit or being scalpeled
@@ -297,6 +241,8 @@
//Calculate how much gas to release
//Varies based on power and gas content
absorbed_gasmix.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
removed.gases[/datum/gas/plasma][MOLES] += max((device_energy * dynamic_heat_modifier) / PLASMA_RELEASE_MODIFIER, 0)
//Varies based on power, gas content, and heat
removed.gases[/datum/gas/oxygen][MOLES] += max(((device_energy + removed.temperature * dynamic_heat_modifier) - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
+1
View File
@@ -3998,6 +3998,7 @@
#include "code\modules\power\singularity\narsie.dm"
#include "code\modules\power\singularity\singularity.dm"
#include "code\modules\power\supermatter\supermatter.dm"
#include "code\modules\power\supermatter\supermatter_gas.dm"
#include "code\modules\power\supermatter\supermatter_hit_procs.dm"
#include "code\modules\power\supermatter\supermatter_process.dm"
#include "code\modules\power\supermatter\supermatter_radiation.dm"