Assembler causing bucket duplication with shapeless recipes
CrysMia opened this issue ยท 3 comments
Minecraft Version
1.21.1
Immersive Engineering Version
12.4.2-194
Expected Behavior
Recipes involving a bucket from other mods that instead use the Assembler's internal fluid buffer should never output an empty bucket. Immersive Engineering's recipes work as intended due to their declaration as another type ("immersiveengineering:shaped_fluid" instead of "minecraft:crafting_shapeless" or "minecraft:crafting_shaped")
Actual Behavior
When using fluids directly instead of the buckets in the Assembler then all shaped-type and shapeless-type recipes that use a bucket instead of the fluidstack implementation of IE will output an empty bucket even tho no bucket was used in the recipe. I did experience this behaviour first in a modpack with Theurgy and it's Sal Ammoniac Bucket to Sal Ammoniac Crystal recipe but can also be reproduced in a minimal setup instead. Also tried Ars Nouveau with it's recipe Water Essence + Lava Bucket -> Obsidian and the same issue appeared (this recipe was also used for testing in a minimal environment).
Using an internal conversion for bucket-involving recipes to the fluidstack type instead would probably get rid of this issue.
Assembler with previously mentioned Obsidian recipe:

The input only consisting of Water Essences:

Output with additional buckets:

Steps to reproduce
- Fill the internal fluid buffer of the Assembler and set a recipe that involves a bucket that is declared as either "minecraft:crafting_shapeless" or "minecraft:crafting_shaped"
- Let the Assembler run
- See the normal recipe output as intended but also an extra bucket that should not be there
Debug Crash Log
Looking at the code more, I think this will actually affect shaped recipes too, but only sometimes.
Current Assembler Code
The current Assembler code assumes that Recipe#getRemainingItems(@Nonnull CraftingInput inv) will return a list equivalent to the full crafting inventory passed into it, ie a 9 slot 3x3 grid with the current items placed inside that grid as necessary. What it actually returns is a list equal to the size of the smallest rectangle that can be fit around the recipe; for stairs as an example this is a 3x3 grid, for a button this is a 1x1 grid, and for a crafting table this is a 2x2 grid.
What ends up happening is that many recipes thus have a mismatch between where the assembler thinks the bucket is (to disable Recipe#getRemainingItems returns) and where the bucket actually is. Thus, returning remaining items has its blacklist applied to a slot that would never return remaining items (for example, a 2x2 square in the bottom right with the bottom rightmost item a bucket will actually see the fourth square from the top left have the blacklist applied).
Thus, what ends up happening is you sometimes (but not always) return extra items.
Possible Fixes
I see two possible methods to fix this:
- We invent some algorithm to turn a grid of size N into a full crafting inventory 3x3 based upon a list of crafting inventory slots to check against where the items actually are. This option I think is reasonably possible so long as scan order is generally the same, but would take some fiddling.
- We get the list and treat it as a list, not as an
ItemStack[3][3]and remove items from that list compared to the recipe's returned items to be removed. Not sure if this is the best option, but it's at least a simpler option. This might, however, conflict with recipe classes that return nonstandard lists of what items they have for remainders.
I would generally suggest 1), and I can probably get some code done for that, but it will be a bit of a hassle.
Having tested this, I can only see it happening in dev with shapeless recipes. Can you test further to make sure it's also happening for shaped recipes?