Merge pull request #8894 from Citadel-Station-13/tgfusion
T G F U S I O N
This commit is contained in:
@@ -210,9 +210,9 @@
|
||||
|
||||
return cached_results["fire"] ? REACTING : NO_REACTION
|
||||
|
||||
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again)
|
||||
//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again!
|
||||
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
|
||||
//5 reworks
|
||||
//6 reworks
|
||||
|
||||
/datum/gas_reaction/fusion
|
||||
exclude = FALSE
|
||||
@@ -220,100 +220,79 @@
|
||||
name = "Plasmic Fusion"
|
||||
id = "fusion"
|
||||
|
||||
//Since fusion isn't really intended to happen in successive chains, the requirements are very high
|
||||
/datum/gas_reaction/fusion/init_reqs()
|
||||
min_requirements = list(
|
||||
"TEMP" = FUSION_TEMPERATURE_THRESHOLD,
|
||||
"ENER" = FUSION_ENERGY_THRESHOLD,
|
||||
/datum/gas/tritium = FUSION_TRITIUM_MOLES_USED,
|
||||
/datum/gas/plasma = FUSION_MOLE_THRESHOLD,
|
||||
/datum/gas/tritium = FUSION_MOLE_THRESHOLD
|
||||
)
|
||||
/datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
|
||||
|
||||
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
|
||||
var/list/cached_gases = air.gases
|
||||
var/temperature = air.temperature
|
||||
if(!air.analyzer_results)
|
||||
air.analyzer_results = new
|
||||
var/list/cached_scan_results = air.analyzer_results
|
||||
var/turf/open/location
|
||||
if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
|
||||
var/datum/pipeline/fusion_pipenet = holder
|
||||
location = get_turf(pick(fusion_pipenet.members))
|
||||
else
|
||||
location = get_turf(holder)
|
||||
|
||||
if(!air.analyzer_results)
|
||||
air.analyzer_results = new
|
||||
var/list/cached_scan_results = air.analyzer_results
|
||||
var/old_heat_capacity = air.heat_capacity()
|
||||
var/reaction_energy = 0
|
||||
|
||||
var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma]*GLOB.meta_gas_specific_heats[/datum/gas/plasma]))/(air.total_moles()-cached_gases[/datum/gas/plasma]) //This is the average specific heat of the mixture,not including plasma.
|
||||
|
||||
var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma]
|
||||
var/plasma_differential = (cached_gases[/datum/gas/plasma] - gases_fused) / air.total_moles()
|
||||
var/reaction_efficiency = FUSION_EFFICIENCY_BASE ** -((plasma_differential ** 2) / FUSION_EFFICIENCY_DIVISOR) //https://www.desmos.com/calculator/6jjx3vdrvx
|
||||
|
||||
var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
|
||||
var/initial_plasma = cached_gases[/datum/gas/plasma]
|
||||
var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide]
|
||||
var/scale_factor = (air.volume)/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
|
||||
var/toroidal_size = (2*PI)+TORADIANS(arctan((air.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
|
||||
var/gas_power = 0
|
||||
var/list/gas_fusion_powers = GLOB.meta_gas_fusions
|
||||
for (var/gas_id in cached_gases)
|
||||
gas_power += reaction_efficiency * (GLOB.meta_gas_fusions[gas_id]*cached_gases[gas_id])
|
||||
gas_power += (gas_fusion_powers[gas_id]*cached_gases[gas_id])
|
||||
var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
|
||||
cached_scan_results[id] = instability//used for analyzer feedback
|
||||
|
||||
var/power_ratio = gas_power/mediation
|
||||
cached_scan_results[id] = power_ratio //used for analyzer feedback
|
||||
var/plasma = (initial_plasma-FUSION_MOLE_THRESHOLD)/(scale_factor) //We have to scale the amounts of carbon and plasma down a significant amount in order to show the chaotic dynamics we want
|
||||
var/carbon = (initial_carbon-FUSION_MOLE_THRESHOLD)/(scale_factor) //We also subtract out the threshold amount to make it harder for fusion to burn itself out.
|
||||
|
||||
for (var/gas_id in cached_gases) //and now we fuse
|
||||
cached_gases[gas_id] = 0
|
||||
//The reaction is a specific form of the Kicked Rotator system, which displays chaotic behavior and can be used to model particle interactions.
|
||||
plasma = MODULUS(plasma - (instability*sin(TODEGREES(carbon))), toroidal_size)
|
||||
carbon = MODULUS(carbon - plasma, toroidal_size)
|
||||
|
||||
var/radiation_power = (FUSION_RADIATION_FACTOR * power_ratio) / (power_ratio + FUSION_RADIATION_CONSTANT) //https://www.desmos.com/calculator/4i1f296phl
|
||||
var/zap_power = ((FUSION_ZAP_POWER_ASYMPTOTE * power_ratio) / (power_ratio + FUSION_ZAP_POWER_CONSTANT)) + FUSION_ZAP_POWER_BASE //https://www.desmos.com/calculator/n0zkdpxnrr
|
||||
var/do_explosion = FALSE
|
||||
var/zap_range //these ones are set later
|
||||
var/fusion_prepare_to_die_edition_rng
|
||||
|
||||
if (power_ratio > FUSION_SUPER_TIER_THRESHOLD) //power ratio 50+: SUPER TIER. The gases become so energized that they fuse into a ton of tritium, which is pretty nice! Until you consider the fact that everything just exploded, the canister is probably going to break and you're irradiated.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_SUPER * (power_ratio / FUSION_ENERGY_DIVISOR_SUPER)
|
||||
cached_gases[/datum/gas/tritium] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit
|
||||
fusion_prepare_to_die_edition_rng = 100 //Wait a minute..
|
||||
do_explosion = TRUE
|
||||
zap_range = FUSION_ZAP_RANGE_SUPER
|
||||
cached_gases[/datum/gas/plasma] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up
|
||||
cached_gases[/datum/gas/carbon_dioxide] = carbon*scale_factor + FUSION_MOLE_THRESHOLD
|
||||
var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma]
|
||||
|
||||
else if (power_ratio > FUSION_HIGH_TIER_THRESHOLD) //power ratio 20-50; High tier. The reaction is so energized that it fuses into a small amount of stimulum, and some pluoxium. Very dangerous, but super cool and super useful.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_HIGH * (power_ratio / FUSION_ENERGY_DIVISOR_HIGH)
|
||||
cached_gases[/datum/gas/stimulum] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox
|
||||
cached_gases[/datum/gas/pluoxium] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX
|
||||
fusion_prepare_to_die_edition_rng = power_ratio //Now we're getting into dangerous territory
|
||||
do_explosion = TRUE
|
||||
zap_range = FUSION_ZAP_RANGE_HIGH
|
||||
|
||||
else if (power_ratio > FUSION_MID_TIER_THRESHOLD) //power_ratio 5 to 20; Mediation is overpowered, fusion reaction starts to break down.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_MID * (power_ratio / FUSION_ENERGY_DIVISOR_MID)
|
||||
cached_gases[/datum/gas/nitryl] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O
|
||||
cached_gases[/datum/gas/nitrous_oxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O
|
||||
fusion_prepare_to_die_edition_rng = power_ratio * FUSION_MID_TIER_RAD_PROB_FACTOR //Still unlikely, but don't stand next to the reaction unprotected
|
||||
zap_range = FUSION_ZAP_RANGE_MID
|
||||
|
||||
else //power ratio 0 to 5; Gas power is overpowered. Fusion isn't nearly as powerful.
|
||||
reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_LOW * (power_ratio / FUSION_ENERGY_DIVISOR_LOW)
|
||||
cached_gases[/datum/gas/bz] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2
|
||||
cached_gases[/datum/gas/carbon_dioxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2
|
||||
fusion_prepare_to_die_edition_rng = power_ratio * FUSION_LOW_TIER_RAD_PROB_FACTOR //Low, but still something to look out for
|
||||
zap_range = FUSION_ZAP_RANGE_LOW
|
||||
|
||||
//All the deadly consequences of fusion, consolidated for your viewing pleasure
|
||||
if (location)
|
||||
if(prob(fusion_prepare_to_die_edition_rng)) //Some.. permanent effects
|
||||
if(do_explosion)
|
||||
explosion(location, 0, 0, 5, power_ratio, TRUE, TRUE) //large shockwave, the actual radius is quite small - people will recognize that you're doing fusion
|
||||
radiation_pulse(location, radiation_power) //You mean causing a super-tier fusion reaction in the halls is a bad idea?
|
||||
SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, 30000)//The science is cool though.
|
||||
playsound(location, 'sound/effects/supermatter.ogg', 100, 0)
|
||||
else
|
||||
playsound(location, 'sound/effects/phasein.ogg', 75, 0)
|
||||
//These will always happen, so be prepared
|
||||
tesla_zap(location, zap_range, zap_power, TESLA_FUSION_FLAGS) //larpers beware
|
||||
location.fire_nuclear_particles(power_ratio) //see code/modules/projectile/energy/nuclear_particle.dm
|
||||
reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
|
||||
if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
|
||||
reaction_energy = max(reaction_energy,0) //Stable reactions don't end up endothermic.
|
||||
else if (reaction_energy < 0)
|
||||
reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
|
||||
|
||||
if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
|
||||
cached_gases[/datum/gas/plasma] = initial_plasma
|
||||
cached_gases[/datum/gas/carbon_dioxide] = initial_carbon
|
||||
return NO_REACTION
|
||||
cached_gases[/datum/gas/tritium] -= FUSION_TRITIUM_MOLES_USED
|
||||
//The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
|
||||
if(reaction_energy > 0)
|
||||
cached_gases[/datum/gas/oxygen] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
cached_gases[/datum/gas/nitrous_oxide] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
else
|
||||
cached_gases[/datum/gas/bz] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
cached_gases[/datum/gas/nitryl] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
|
||||
|
||||
if(reaction_energy)
|
||||
if(location)
|
||||
var/particle_chance = ((PARTICLE_CHANCE_CONSTANT)/(reaction_energy-PARTICLE_CHANCE_CONSTANT)) + 1//Asymptopically approaches 100% as the energy of the reaction goes up.
|
||||
if(prob(PERCENT(particle_chance)))
|
||||
location.fire_nuclear_particle()
|
||||
var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + FUSION_RAD_MAX,0)
|
||||
radiation_pulse(location,rad_power)
|
||||
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB)
|
||||
air.temperature = CLAMP(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY)
|
||||
return REACTING
|
||||
|
||||
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
|
||||
|
||||
@@ -421,7 +421,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
if(prob(50))
|
||||
radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%)
|
||||
if(bzcomp >= 0.4 && prob(30 * bzcomp))
|
||||
src.fire_nuclear_particles() // Start to emit radballs at a maximum of 30% chance per tick
|
||||
fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick
|
||||
|
||||
var/device_energy = power * REACTION_POWER_MODIFIER
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
name = "nuclear particle"
|
||||
icon_state = "nuclear_particle"
|
||||
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
|
||||
damage = 20
|
||||
damage_type = TOX
|
||||
irradiate = 2500 //enough to knockdown and induce vomiting
|
||||
speed = 0.4
|
||||
flag = "rad"
|
||||
irradiate = 5000
|
||||
speed = 0.4
|
||||
hitsound = 'sound/weapons/emitter2.ogg'
|
||||
impact_type = /obj/effect/projectile/impact/xray
|
||||
var/static/list/particle_colors = list(
|
||||
@@ -25,22 +24,6 @@
|
||||
add_atom_colour(particle_colors[our_color], FIXED_COLOUR_PRIORITY)
|
||||
set_light(4, 3, particle_colors[our_color]) //Range of 4, brightness of 3 - Same range as a flashlight
|
||||
|
||||
/atom/proc/fire_nuclear_particles(power_ratio) //used by fusion to fire random # of nuclear particles - power ratio determines about how many are fired
|
||||
var/random_particles = rand(3,6)
|
||||
var/particles_to_fire
|
||||
var/particles_fired
|
||||
switch(power_ratio) //multiply random_particles * factor for whatever tier
|
||||
if(0 to FUSION_MID_TIER_THRESHOLD)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_LOW
|
||||
if(FUSION_MID_TIER_THRESHOLD to FUSION_HIGH_TIER_THRESHOLD)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_MID
|
||||
if(FUSION_HIGH_TIER_THRESHOLD to FUSION_SUPER_TIER_THRESHOLD)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_HIGH
|
||||
if(FUSION_SUPER_TIER_THRESHOLD to INFINITY)
|
||||
particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_SUPER
|
||||
while(particles_to_fire)
|
||||
particles_fired++
|
||||
var/angle = rand(0,360)
|
||||
var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
|
||||
addtimer(CALLBACK(P, /obj/item/projectile.proc/fire, angle), particles_fired) //multiply particles fired * delay so the particles end up stagnated (once every decisecond)
|
||||
particles_to_fire--
|
||||
/atom/proc/fire_nuclear_particle(angle = rand(0,360)) //used by fusion to fire random nuclear particles. Fires one particle in a random direction.
|
||||
var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
|
||||
P.fire(angle)
|
||||
|
||||
Reference in New Issue
Block a user