mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Fixes reactions ending prematurely when nearing min conditions (#89109)
## About The Pull Request So when a reaction is approaching its minimum conditions (temps are approaching `required_temp` or ph is appraching `optimal_ph_min`) It would end some good distance from these min values & not very close to them. For e.g. Flurosulphuric acid has a minimum required temp of 380K but the reaction would stop/won't occur if the temps go below 400K itself i.e. 20K from its minimum which is not ideal when we are trying to maximise results at all times. Now it goes all the way down to these min values ensuring the reaction rate never goes below 0.005(which in players terms means the rate of reagents poduced per tick will never go below 0.01u for any given reaction) This also improves the code of debug chem master which caught this bug. ## Changelog 🆑 fix: chemical reactions can now go all the way to their min required temp/ph code: improved code for debug chem master. /🆑
This commit is contained in:
@@ -34,6 +34,8 @@
|
||||
var/delta_t
|
||||
///How pure our step is
|
||||
var/delta_ph
|
||||
///Min reaction rate possible below which rounding errors occur
|
||||
VAR_PRIVATE/min_rate
|
||||
///Modifiers from catalysts, do not use negative numbers.
|
||||
///I should write a better handiler for modifying these
|
||||
///Speed mod
|
||||
@@ -67,7 +69,6 @@
|
||||
LAZYADD(holder.reaction_list, src)
|
||||
SSblackbox.record_feedback("tally", "chemical_reaction", 1, "[reaction.type] attempts")
|
||||
|
||||
|
||||
/datum/equilibrium/Destroy()
|
||||
if(reacted_vol < target_vol) //We did NOT finish from reagents - so we can restart this reaction given property changes in the beaker. (i.e. if it stops due to low temp, this will allow it to fast restart when heated up again)
|
||||
LAZYADD(holder.failed_but_capable_reactions, reaction) //Consider replacing check with calculate_yield()
|
||||
@@ -114,6 +115,8 @@
|
||||
product_ratio += reaction.results[product]
|
||||
else
|
||||
product_ratio = 1
|
||||
min_rate = product_ratio * (CHEMICAL_VOLUME_ROUNDING / 2)
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
@@ -321,10 +324,13 @@
|
||||
purity *= purity_modifier
|
||||
|
||||
//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 * seconds_per_tick//add/remove factor
|
||||
var/delta_chem_factor = reaction.rate_up_lim * delta_t * seconds_per_tick
|
||||
//keep limited
|
||||
if(delta_chem_factor > step_target_vol)
|
||||
delta_chem_factor = step_target_vol
|
||||
//ensure its above minimum rate below which rounding errors occur
|
||||
else if(delta_chem_factor < min_rate)
|
||||
delta_chem_factor = min_rate
|
||||
//Normalise to multiproducts
|
||||
delta_chem_factor = round(delta_chem_factor / product_ratio, CHEMICAL_VOLUME_ROUNDING)
|
||||
if(delta_chem_factor <= 0)
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
for(var/datum/reagent/removed_reagent as anything in removed_reagents)
|
||||
SEND_SIGNAL(src, COMSIG_REAGENTS_REM_REAGENT, removed_reagent, removed_reagents[removed_reagent])
|
||||
|
||||
return round(total_removed_amount, CHEMICAL_VOLUME_ROUNDING)
|
||||
return total_removed_amount
|
||||
|
||||
/**
|
||||
* Removes all reagents either proportionally(amount is the direct volume to remove)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
icon = 'icons/obj/medical/chemical.dmi'
|
||||
icon_state = "HPLC_debug"
|
||||
density = TRUE
|
||||
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.4
|
||||
use_power = NO_POWER_USE
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
|
||||
|
||||
///Temperature to be imposed on the reaction
|
||||
@@ -63,7 +63,7 @@
|
||||
///The target reagents to we are working with. can vary if an reaction requires a specific container
|
||||
var/datum/reagents/target_reagents
|
||||
///The beaker inside this machine, if null will create a new one
|
||||
var/obj/item/reagent_containers/cup/beaker/bluespace/beaker
|
||||
var/obj/item/reagent_containers/container
|
||||
///The default reagent container required for the selected test reaction if any
|
||||
var/obj/item/reagent_containers/required_container
|
||||
|
||||
@@ -85,47 +85,47 @@
|
||||
reactions_to_test.Cut()
|
||||
target_reagents = null
|
||||
edit_reaction = null
|
||||
QDEL_NULL(beaker)
|
||||
QDEL_NULL(container)
|
||||
QDEL_NULL(required_container)
|
||||
UnregisterSignal(reagents, COMSIG_REAGENTS_REACTION_STEP)
|
||||
. = ..()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/chem_recipe_debug/add_context(atom/source, list/context, obj/item/held_item, mob/user)
|
||||
. = ..()
|
||||
if(isnull(held_item) || (held_item.item_flags & ABSTRACT) || (held_item.flags_1 & HOLOGRAM_1))
|
||||
return NONE
|
||||
|
||||
if(!QDELETED(beaker))
|
||||
if(!QDELETED(container))
|
||||
if(is_reagent_container(held_item) && held_item.is_open_container())
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Replace beaker"
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Replace container"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
else if(is_reagent_container(held_item) && held_item.is_open_container())
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Insert beaker"
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Insert container"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/machinery/chem_recipe_debug/examine(mob/user)
|
||||
. = ..()
|
||||
if(!QDELETED(beaker))
|
||||
. += span_notice("A beaker of [beaker.reagents.maximum_volume]u capacity is inside.")
|
||||
if(!QDELETED(container))
|
||||
. += span_notice("A container of [container.reagents.maximum_volume]u capacity is inside.")
|
||||
else
|
||||
. += span_notice("No beaker is present. A new will be created when ejecting.")
|
||||
. += span_notice("No container is present. A new will be created when ejecting.")
|
||||
|
||||
/obj/machinery/chem_recipe_debug/Exited(atom/movable/gone, direction)
|
||||
. = ..()
|
||||
if(gone == beaker)
|
||||
beaker = null
|
||||
if(gone == container)
|
||||
container = null
|
||||
|
||||
/obj/machinery/chem_recipe_debug/attackby(obj/item/held_item, mob/user, params)
|
||||
/obj/machinery/chem_recipe_debug/item_interaction(mob/living/user, obj/item/held_item, list/modifiers)
|
||||
. = NONE
|
||||
if((held_item.item_flags & ABSTRACT) || (held_item.flags_1 & HOLOGRAM_1))
|
||||
return ..()
|
||||
return
|
||||
|
||||
if(is_reagent_container(held_item) && held_item.is_open_container())
|
||||
. = TRUE
|
||||
if(!QDELETED(beaker))
|
||||
try_put_in_hand(beaker, user)
|
||||
if(!QDELETED(container))
|
||||
try_put_in_hand(container, user)
|
||||
if(!user.transferItemToLoc(held_item, src))
|
||||
return
|
||||
beaker = held_item
|
||||
return ITEM_INTERACT_FAILURE
|
||||
container = held_item
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/**
|
||||
* Extracts a human readable name for this chemical reaction
|
||||
@@ -155,13 +155,12 @@
|
||||
var/datum/chemical_reaction/test_reaction = reactions_to_test[current_reaction_index || 1]
|
||||
switch(temp_mode)
|
||||
if(USE_MINIMUM_TEMPERATURE)
|
||||
return test_reaction.required_temp + (test_reaction.is_cold_recipe ? - 20 : 20) //20k is good enough offset to account for reaction rate rounding
|
||||
return test_reaction.required_temp
|
||||
if(USE_OPTIMAL_TEMPERATURE)
|
||||
return test_reaction.optimal_temp
|
||||
if(USE_OVERHEAT_TEMPERATURE)
|
||||
return test_reaction.overheat_temp
|
||||
|
||||
|
||||
/**
|
||||
* Adjusts the temperature, ph & purity of the holder
|
||||
* Arguments
|
||||
@@ -173,7 +172,7 @@
|
||||
|
||||
var/target_temperature = decode_target_temperature()
|
||||
if(!isnull(target_temperature))
|
||||
target_reagents.adjust_thermal_energy((target_temperature - target_reagents.chem_temp) * 0.4 * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * target_reagents.total_volume)
|
||||
target_reagents.adjust_thermal_energy((target_temperature - target_reagents.chem_temp) * 0.45 * seconds_per_tick * target_reagents.heat_capacity())
|
||||
|
||||
if(use_forced_purity)
|
||||
target_reagents.set_all_reagents_purity(forced_purity)
|
||||
@@ -187,7 +186,7 @@
|
||||
/obj/machinery/chem_recipe_debug/process(seconds_per_tick)
|
||||
if(!target_reagents.is_reacting)
|
||||
adjust_environment(seconds_per_tick)
|
||||
target_reagents.handle_reactions()
|
||||
target_reagents.handle_reactions()
|
||||
|
||||
//send updates to ui. faster than SStgui.update_uis
|
||||
for(var/datum/tgui/ui in src.open_uis)
|
||||
@@ -334,11 +333,10 @@
|
||||
.["editReaction"] = reaction_data
|
||||
|
||||
var/list/beaker_data = null
|
||||
if(target_reagents.reagent_list.len)
|
||||
if(!QDELETED(container) || target_reagents.total_volume)
|
||||
beaker_data = list()
|
||||
beaker_data["maxVolume"] = target_reagents.maximum_volume
|
||||
beaker_data["pH"] = round(target_reagents.ph, 0.01)
|
||||
beaker_data["purity"] = round(target_reagents.get_average_purity(), 0.01)
|
||||
beaker_data["currentVolume"] = round(target_reagents.total_volume, CHEMICAL_VOLUME_ROUNDING)
|
||||
beaker_data["currentTemp"] = round(target_reagents.chem_temp, 1)
|
||||
beaker_data["purity"] = round(target_reagents.get_average_purity(), 0.001)
|
||||
@@ -666,12 +664,26 @@
|
||||
tgui_alert(ui.user, "Saved to [dest]")
|
||||
|
||||
if("eject")
|
||||
if(!target_reagents.total_volume)
|
||||
return
|
||||
if(QDELETED(beaker))
|
||||
beaker = new /obj/item/reagent_containers/cup/beaker/bluespace(src)
|
||||
target_reagents.trans_to(beaker, target_reagents.total_volume)
|
||||
try_put_in_hand(beaker, ui.user)
|
||||
//initialize a new container for us
|
||||
if(QDELETED(container))
|
||||
if(QDELETED(required_container))
|
||||
container = new /obj/item/reagent_containers/cup/beaker/bluespace(src)
|
||||
else
|
||||
container = new required_container.type(src)
|
||||
|
||||
//transfer all reagents & ingredients if we are using a soup pot
|
||||
container.reagents.clear_reagents()
|
||||
target_reagents.trans_to(container, target_reagents.total_volume)
|
||||
if(istype(container, /obj/item/reagent_containers/cup/soup_pot) && istype(required_container, /obj/item/reagent_containers/cup/soup_pot))
|
||||
var/obj/item/reagent_containers/cup/soup_pot/pot = container
|
||||
for(var/obj/item as anything in pot.added_ingredients)
|
||||
qdel(item)
|
||||
var/obj/item/reagent_containers/cup/soup_pot/holder = required_container
|
||||
for(var/obj/item as anything in holder.added_ingredients)
|
||||
item.forceMove(pot)
|
||||
LAZYADD(pot.added_ingredients, item)
|
||||
try_put_in_hand(container, ui.user)
|
||||
|
||||
return TRUE
|
||||
|
||||
#undef USE_REACTION_TEMPERATURE
|
||||
|
||||
Reference in New Issue
Block a user