Files
Bubberstation/code/modules
SkyratBot ba0b89dbbd [MIRROR] Reaction patches & maintenance [MDB IGNORE] (#25406)
* Reaction patches & maintenance (#80021)

## About The Pull Request
1. Closes #74818
One way to optimize this without using a type cache is to simulate the
behaviour of `istype()` by testing the pots content parent type against
the requested types list and if not present check its parent type and
keep going till we have hit the ceiling of type `obj/item`.
Another optimization is to count the ingredients once in a single for
loop rather than counting twice(i.e. once after looping over the pots
ingredients and again to confirm if we have 0 amount of them remaining).
With this we have removed excess for loops all without using a type
cache

2. Fixes #79979
So this problem actually occurs rarely with reactions that require large
amounts of reagents(e.g. soup requires 50 units of water) or that
produce large amount of products. When you require a large amount of
reagents the `product_ratio` becomes a large value and when you divide
`delta_chem_factor` by this large value and again round it

f2409db8ba/code/modules/reagents/chemistry/equilibrium.dm (L330-L331)

Its chances of becoming 0(only because of rounding) increases. In the
case for soups it did become 0 therefore no new soup was created nor was
any water removed and the reaction also did not have a chance to delete
itself because it saw there was enough water to keep reacting but
`delta_chem_factor` would become 0 by the time it got to reacting
resulting in a stuck state.

Now a sanity check is added to ensure the reaction ends early if this
value does become 0

This also removes the `reaction.data["boiled_over"]` value. Yes this
value would be set to TRUE but no where was it set to FALSE afterwards.
This means once boiled over the remaining reagents from the
`pot.ingredients` would not get transfered over to the pot until a new
reaction got started, which is dumb. You spill over the contents and
continue on with the reaction you don't give up after it happens so yeah
this var is removed and it's proc merged into `reaction_step()` cause
you know saving proc overhead calls.

3. Another problem with reactions is that when they are overheated their
volumes would diminish in an incorrect way. Take a look at

f2409db8ba/code/modules/reagents/chemistry/recipes.dm (L185)
Let's say our volume is 0.9. Doing some simple math
    ```
    0.9 * 0.98 = 0.882
    round(0.882, 0.01) = 0.9
    ```
Yup we are right back to where we started, the solution is to round it
lower i.e. with `CHEMICAL_QUANTIZATION_LEVEL`(0.0001) so we can properly
reduce it to levels where `update_total()` can finally remove it

## Changelog
🆑
fix: soups and other reactions where large quantities of reagents are
required/present should not have a random chance of reacting forever.
fix: reactions which are overheated should diminish all the way to 0
code: cleaned up code in `datam/equilibrium` in general. Slightly
optimized soup reaction code
/🆑

* Reaction patches & maintenance

---------

Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
2023-12-03 01:16:45 -05:00
..