GregTechCEu / GregTech

GregTech CE 1.12 fork continuing progression and development
GNU Lesser General Public License v3.0
223 stars 166 forks source link

Fix Ore Dict Ingredients When Changing OreDicts with CT & GS #2456

Closed IntegerLimit closed 1 week ago

IntegerLimit commented 3 weeks ago

What

This PR fixes a situation where sometimes Ore Dict Ingredients would not refresh their input stacks on ore dictionary change.

This sometimes occurred when editing these Ore Dictionaries in CraftTweaker and always in GroovyScript, if the GTRecipeOreInput had getInputStacks() called beforehand, such as in .withRecycling() on Assembler Recipes.

Furthermore, this always occurs on /gs reload.

This issue was first reported here, although the issue with lenses there was caused by comparison of recipes in Nomi-Labs.

This issue can be replicated by copying this short Groovy Demonstration Script:

// Removals of Ore Dict from Recipes
ore('circuitLv').remove(metaitem('circuit.electronic'))

// Addition of Ore Dict from Recipes
ore('circuitLv').remove(item('minecraft:iron_ingot'))

Then, launch the game. Afterwards, load into a world. It would be able to be observed that the assembler recipes, for things like fluid regulators, using electronic circuits still exist, and there are no such recipes for iron ingot.

Comment out one of the lines, and perform /gs reload. You can also do the opposite, adding back one of the lines, but no matter, both of these also break ore dict handling on normal recipes.

A similar script can be used on a CraftTweaker instance. You may observe the same behaviour, but it is somewhat random, due to the priority and event of CT Scripts and GT Running OreDictUnifier Handlers being the same. (RegisterEvent.Register<IRecipe>)

This PR fixes all cases.

Implementation Details

This PR essentially is just a polished up version, without reliance on JEI/HEI, of this Nomi-Labs Mixin Commit.

Essentially, if JEI Module is enabled, the cache is reloaded with JEI Module Starting (Same Behaviour as in the commit). This allows for the most reliability that the change is reflected in the JEI recipe display, both on viewing the recipe itself, and of seeing the uses of any of the recipe's ingredients.

If JEI is not loaded, the cache is reloaded on Load Complete if GroovyScript is not installed, else reloads after GroovyScript Script Load.

This covers all cases:

The cache is reloaded by incrementing a counter. When getInputStacks() is called on the GTRecipeOreInput, it checks if its 'standard' is the same as the global one. If not, it is regenerated. Although this could be regenerated each time, as the call to OreDictionary is just of getting a specific item of a list, running in O(1) time, this wastes memory, as a new array is created each time.

Small thing to look over: the counter is a short. I guess bad things could happen if the counter went above 32767, and wrapped all the way back around. However, would any GroovyScript user run /gs reload in a session more than 32767 times? If so, we could increase it to an int or a long, such as in the testing Nomi-Labs commit.

Outcome

Fixes unreliable GTRecipeOreInput behaviour.

Potential Compatibility Issues

None