Skip to content

Commit

Permalink
[WIP] Adds AP, CNO, TPA - [PLAYTEST PLEASE]
Browse files Browse the repository at this point in the history
https://en.wikipedia.org/wiki/Stellar_nucleosynthesis

Also does miscellanious cleanup and adds a hopefully better sorting of reactions
This is probably going to irradiate the entire Torch
Also fixes a bug where reactants wouldn't be properly added to the copy. 4 hours......
  • Loading branch information
Cupax3 committed Oct 18, 2021
1 parent 598d5e0 commit d018717
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 123 deletions.
6 changes: 6 additions & 0 deletions code/_helpers/cmp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@
/proc/cmp_fusion_reaction_des(var/decl/fusion_reaction/A, var/decl/fusion_reaction/B)
return B.priority - A.priority

/proc/cmp_fusion_reaction_c_asc(var/decl/fusion_reaction/A, var/decl/fusion_reaction/B)
return A.reaction_chance * A.priority - B.reaction_chance * B.priority

/proc/cmp_fusion_reaction_c_des(var/decl/fusion_reaction/A, var/decl/fusion_reaction/B)
return B.reaction_chance * B.priority - A.reaction_chance * A.priority

/proc/cmp_program(var/datum/computer_file/program/A, var/datum/computer_file/program/B)
return cmp_text_asc(A.filedesc, B.filedesc)

Expand Down
46 changes: 24 additions & 22 deletions code/modules/power/fusion/core/core_field.dm
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
check_instability()
Radiate()
if(radiation)
SSradiation.radiate(src, round(radiation*0.001))
SSradiation.radiate(src, round(radiation))
return 1

/obj/effect/fusion_em_field/proc/check_instability()
Expand Down Expand Up @@ -384,42 +384,42 @@
if (reactants_copy.len)
var/sum = 0

for(var/reactant in reactants_copy)
for (var/reactant in reactants_copy)
sum += reactants_copy[reactant] // Sum all reactants conveniently in the loop for later use
for(var/decl/fusion_reaction/reaction in all_reactions)
for (var/decl/fusion_reaction/reaction in all_reactions)
/*
* Begin looping the reactions and checking their requirements.
* The order of this might change for optimisation purposes.continue
* Currently, check for temperature, energy and then for present reactants.
*/
if(reaction.minimum_reaction_temperature > plasma_temperature)
if (reaction.minimum_reaction_temperature > plasma_temperature)
continue
if(reaction.maximum_reaction_temperature != 0 && reaction.maximum_reaction_temperature < plasma_temperature)
if (reaction.maximum_reaction_temperature != 0 && reaction.maximum_reaction_temperature < plasma_temperature)
continue
if(reaction.minimum_energy_level > energy)
if (reaction.minimum_energy_level > energy)
continue
if(reaction.maximum_reaction_temperature != 0 && reaction.maximum_energy_level < energy)
if (reaction.maximum_reaction_temperature != 0 && reaction.maximum_energy_level < energy)
continue
var/i = list_find(reaction.l_reactants, reactant)
if(i == 0) // Since Find returns 0 if not found, we break if we cannot find the reactant in the list of reactants
if (i == 0) // Since Find returns 0 if not found, we break if we cannot find the reactant in the list of reactants
continue
var/possible = TRUE // Per default we assume the reaction to be possible
for(var/reaction_reactant in reaction.l_reactants) // Check if all needed reactants are present
for (var/reaction_reactant in reaction.l_reactants) // Check if all needed reactants are present
var/j = list_find(reactants_copy, reaction_reactant)
if(j == 0)
if (j == 0)
possible = FALSE
break // Goto next reaction
if(!possible)
if (!possible)
break // Goto next reaction
reaction.reaction_chance += reactants_copy[reactant] // We calculate the reaction chance later, for now we want the sum of present reaction reactants
if(list_find(possible_reactions, reaction) == 0)
if (list_find(possible_reactions, reaction) == 0)
possible_reactions.Add(reaction) // Add the found reaction

if(possible_reactions.len == 0)
if (possible_reactions.len == 0)
return

for(var/decl/fusion_reaction/reaction in possible_reactions)
if(reaction.reaction_chance != 0) // If this is somehow 0, we can skip this calculation because it's not going to be executed anyway. This is a div-by-zero prevention.
for (var/decl/fusion_reaction/reaction in possible_reactions)
if (reaction.reaction_chance != 0) // If this is somehow 0, we can skip this calculation because it's not going to be executed anyway. This is a div-by-zero prevention.
/*
* Get the percentage this reaction will take place based on: present reaction reactants / sum of all present reactants
* This currently does not take into account other reactions we will iterate and may result in calculation misssteps.
Expand All @@ -428,18 +428,20 @@

// TODO: Fit this onto a beta distribution

sortTim(possible_reactions, /proc/cmp_fusion_reaction_des) // proc compares A.priority and B.priority
sortTim(possible_reactions, /proc/cmp_fusion_reaction_c_des) // proc compares A.priority and B.priority

for(var/decl/fusion_reaction/reaction in possible_reactions)
for (var/decl/fusion_reaction/reaction in possible_reactions)
// We begin looking at each reaction we cached earlier
var/list/reaction_reactant_pool = reactants_copy & reaction.l_reactants // Cache the reactants we need based on the list_reactants of the reaction
var/list/hackystuff = new/list // This might not be necessary anymore, prevents wrong caluclation of the max_possible
for(var/reactant in reaction_reactant_pool)
for (var/reactant in reaction_reactant_pool)
hackystuff.Add(reaction_reactant_pool[reactant])
var/max_possible = min(hackystuff) // Calculate the maximum possible amount of reaction that can take place based on lowest reactant amount
var/reaction_amount = max_possible * reaction.reaction_chance // The chance is used as a stand-in for random particle movement

for(var/reactant in reaction_reactant_pool)
for (var/reactant in reaction_reactant_pool)
if (reaction_reactant_pool[reactant] < reaction_amount)
continue
// Remove reactants from the pool
reactants_copy[reactant] -= reaction_amount

Expand All @@ -449,11 +451,11 @@
radiation += reaction_amount * reaction.radiation
tick_instability += reaction_amount * reaction.instability

for(var/reactant in reaction.products)
for (var/reactant in reaction.products)
// Add results back. It's a multiplication because products can be larger than 1 and there may also be multiple results
reactants_copy[reactant] = (reaction.products[reactant] * reaction_amount)
reactants_copy[reactant] += (reaction.products[reactant] * reaction_amount)

if(reaction.is_special)
if (reaction.is_special)
// Handle anything special this reaction does, like explode
reaction.handle_reaction_special(src)

Expand Down
Loading

0 comments on commit d018717

Please sign in to comment.