diff --git a/code/modules/reagents/chemistry/equilibrium.dm b/code/modules/reagents/chemistry/equilibrium.dm index bc7cbd37f48..76f45e77cab 100644 --- a/code/modules/reagents/chemistry/equilibrium.dm +++ b/code/modules/reagents/chemistry/equilibrium.dm @@ -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) diff --git a/code/modules/reagents/chemistry/holder/holder.dm b/code/modules/reagents/chemistry/holder/holder.dm index 7a599edc133..be74e5cfb85 100644 --- a/code/modules/reagents/chemistry/holder/holder.dm +++ b/code/modules/reagents/chemistry/holder/holder.dm @@ -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) diff --git a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm index 9b0773a8316..3cf570250d6 100644 --- a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm +++ b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm @@ -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