Shadows-of-Fire / Shadows-of-Greg

An addon for GregTech Community Edition with the goal of making it much more complicated and realistic through the use of GregTech 5 Unofficial and GregTech 6 features.
GNU General Public License v3.0
16 stars 30 forks source link

Fusion reactors can run recipes with unsatisfied EU-to-start requirements in certain cases #75

Closed phantamanta44 closed 4 years ago

phantamanta44 commented 4 years ago

Suppose a given fusion recipe r is intended to be unrunnable in a given fusion reactor because its EU-to-start threshold is too high. The EU-to-start threshold can be bypassed if the inputs are present in sufficient quantity to execute r more than one time. The inputs for the first run will be destroyed, then the remainder of the runs will complete normally.

The mechanism for this behaviour spans two iterations of the updateFormedValid() method in TileEntityFusionReactor, and is as follows:

  1. In the first iteration, the previously-matched recipe is retrieved from the recipe logic at 160, which will be nil.
  2. A recipe match is performed at 161, which produces the recipe r; this destroys the first batch of ingredients, as they are to be consumed for the successfully-matched recipe.
  3. We check to see if the recipe has changed at 163; since r != nil, we continue into the conditional block.
  4. We check to see if the EU-to-start threshold is satisfied; since it is not, we continue into the conditional block.
  5. An attempt is made to reset the state of the recipe logic by clearing various variables using reflection. Note in particular that the previously-matched recipe is not cleared.
  6. In the second iteration, the previously-matched recipe is retrieved once again at 160; since this wasn't cleared, we get r.
  7. A recipe match is once again performed at 161 because we reset the recipe progress time to zero. Since there are still enough ingredients for the recipe, the second batch of ingredients are destroyed and r is produced once more.
  8. We check to see if the recipe has changed at 163; since r = r, we skip the conditional block.
  9. Since the EU-to-start threshold check has been skipped, we can now continue on and run the recipe normally (as well as all subsequent runs, as long as the previously-matched recipe does not change).

This issue could be patched with minor changes to the logic here, but the code is extraordinarily hacky and makes bad abuse of reflection. As such, I would suggest using this opportunity to perform a major refactoring of the code to reduce the hackiness and avoid abusing reflection. In particular, I would suggest subclassing MultiBlockRecipeLogic so that the EU-to-start check can be directly implemented in the recipe matching routine rather than in the roundabout way it is currently implemented.

huneau commented 4 years ago

thx for this info, I will take a look.