Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix occasional infinite reactions #946

Merged
merged 2 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions code/modules/reagents/chemistry/equilibrium.dm
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@
//Calculate DeltaT (Deviation of T from optimal)
if(!reaction.is_cold_recipe)
if (cached_temp < reaction.optimal_temp && cached_temp >= reaction.required_temp)
delta_t = (((cached_temp - reaction.required_temp)**reaction.temp_exponent_factor)/((reaction.optimal_temp - reaction.required_temp)**reaction.temp_exponent_factor))
delta_t = ((cached_temp - reaction.required_temp) / (reaction.optimal_temp - reaction.required_temp)) ** reaction.temp_exponent_factor
else if (cached_temp >= reaction.optimal_temp)
delta_t = 1
else //too hot
Expand All @@ -249,7 +249,7 @@
return
else
if (cached_temp > reaction.optimal_temp && cached_temp <= reaction.required_temp)
delta_t = (((reaction.required_temp - cached_temp)**reaction.temp_exponent_factor)/((reaction.required_temp - reaction.optimal_temp)**reaction.temp_exponent_factor))
delta_t = ((reaction.required_temp - cached_temp) / (reaction.required_temp - reaction.optimal_temp)) ** reaction.temp_exponent_factor
else if (cached_temp <= reaction.optimal_temp)
delta_t = 1
else //Too cold
Expand All @@ -266,7 +266,7 @@
delta_t *= speed_mod

//Now we calculate how much to add - this is normalised to the rate up limiter
var/delta_chem_factor = (reaction.rate_up_lim*delta_t)*delta_time//add/remove factor
var/delta_chem_factor = reaction.rate_up_lim * delta_t *delta_time //add/remove factor
var/total_step_added = 0
//keep limited
if(delta_chem_factor > step_target_vol)
Expand All @@ -278,16 +278,21 @@
return

//Calculate how much product to make and how much reactant to remove factors..
for(var/reagent in reaction.required_reagents)
holder.remove_reagent(reagent, (delta_chem_factor * reaction.required_reagents[reagent]), safety = TRUE)
var/required_amount
for(var/datum/reagent/requirement as anything in reaction.required_reagents)
required_amount = reaction.required_reagents[requirement]
if(!holder.remove_reagent(requirement, delta_chem_factor * required_amount))
to_delete = TRUE
return

var/step_add
for(var/product in reaction.results)
//create the products
step_add = delta_chem_factor * reaction.results[product]
//Default handiling
holder.add_reagent(product, step_add, null, cached_temp)
for(var/datum/reagent/product as anything in reaction.results)
step_add = holder.add_reagent(product, delta_chem_factor * reaction.results[product])
if(!step_add)
to_delete = TRUE
return

//record amounts created
reacted_vol += step_add
total_step_added += step_add

Expand Down Expand Up @@ -315,12 +320,15 @@
if(!(check_fail_states(total_step_added)))
to_delete = TRUE

//end reactions faster so plumbing is faster
if((step_add >= step_target_vol) && (length(holder.reaction_list == 1)))//length is so that plumbing is faster - but it doesn't disable competitive reactions. Basically, competitive reactions will likely reach their step target at the start, so this will disable that. We want to avoid that. But equally, we do want to full stop a holder from reacting asap so plumbing isn't waiting an tick to resolve.
//If the volume of reagents created(total_step_added) >= volume of reagents still to be created(step_target_vol) then end
//i.e. we have created all the reagents needed for this reaction
//This is only accurate when a single reaction is present and we don't have multiple reactions where
//reaction B consumes the products formed from reaction A(which can happen in add_reagent() as it also triggers handle_reactions() which can consume the reagent just added)
//because total_step_added will be higher than the actual volume that was created leading to the reaction ending early
//and yielding less products than intended
if(total_step_added >= step_target_vol && length(holder.reaction_list) == 1)
to_delete = TRUE

holder.update_total()//do NOT recalculate reactions

///Panic stop a reaction - cleanup should be handled by the next timestep
/datum/equilibrium/proc/force_clear_reactive_agents()
for(var/reagent in reaction.required_reagents)
Expand Down
6 changes: 2 additions & 4 deletions code/modules/reagents/chemistry/holder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
SEND_SIGNAL(src, COMSIG_REAGENTS_ADD_REAGENT, iter_reagent, amount, reagtemp, data, no_react)
if(!no_react && !is_reacting) //To reduce the amount of calculations for a reaction the reaction list is only updated on a reagents addition.
handle_reactions()
return TRUE
return amount

//otherwise make a new one
var/datum/reagent/new_reagent = new reagent(data)
Expand Down Expand Up @@ -879,8 +879,6 @@
is_reacting = FALSE
LAZYNULL(previous_reagent_list) //reset it to 0 - because any change will be different now.
update_total()
if(!QDELING(src))
handle_reactions() //Should be okay without. Each step checks.

/*
* Force stops the current holder/reagents datum from reacting
Expand Down Expand Up @@ -1020,7 +1018,7 @@
continue
remove_reagent(_reagent, (multiplier * cached_required_reagents[_reagent]), safety = 1)

for(var/product in selected_reaction.results)
for(var/product in cached_results)
multiplier = max(multiplier, 1) //this shouldn't happen ...
var/yield = (cached_results[product]*multiplier)
SSblackbox.record_feedback("tally", "chemical_reaction", yield, product)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@

/datum/reagent/medicine/ryetalyn
name = "Ryetalyn"
description = "Ryetalyn can cure all genetic abnomalities via a catalytic process."
description = "Ryetalyn can cure all genetic mutations and abnormalities via a catalytic process."
taste_description = "acid"
reagent_state = SOLID
color = "#004000"
Expand Down
Loading