
[Bug]: JEI Assumes All Potion Types Have One Recipe
voidsong-dragonfly opened this issue ยท 1 comments
Steps to Reproduce the Bug
- Clone Natural Philosophy (found here)
- Run
./gradlew runClient
- Check JEI for recipes for the
Water Breathing
potion, onlyPufferfish
will be shown as an ingredient.
Expected Behavior
The recipe using Red Algae
from Natural Philosophy to craft Water Breathing
potions should also be shown in JEI, alongside the Pufferfish
recipe.
Actual Behavior
Only one (the first registered) ingredient for a potion type will be shown in JEI, instead of all reagents for a specific potion type.
Mod Pack URL (Optional)
No response
Mod Pack Version (Optional)
No response
Extra Notes (Optional)
Bug is present in both 19.21.0.247
and 19.21.2.313
versions of JEI on NeoForge.
latest.log
https://gist.github.com/voidsong-dragonfly/a653d59384638563374fc91cf514e9b4
I believe this is caused by an assumption in BrewingRecipeMakerCommon::getNewPotions
's construction of the uid
passed into createBrewingRecipe
. It appears to be an issue in both 1.21.1 and 1.21.7's code bases, and presumably all versions between them. Likewise, it also seems to appear in the 1.20.1 branch.
Simply put:
String inputPathId = PotionSubtypeInterpreter.INSTANCE.getStringName(potionInput);
...
String outputPathId = PotionSubtypeInterpreter.INSTANCE.getStringName(potionOutput);
String outputModId = outputResourceLocation.getNamespace();
String uidPath = ResourceLocationUtil.sanitizePath(inputPathId + ".to." + outputPathId);
The inputPathId
and outputPathId
are combined on BrewingRecipeMakerCommon::150
(around 129
in 1.21.1) to create a resource location which is later used by (at least on 1.21.1) JeiBrewingRecipe
as the hash code for the recipe.
This means that adding additional recipes for Vanilla potions, or additional reagents, will properly construct those recipes but with a hash that only considers the input item and the output item, not any of the ingredients.
The !recipes.contains(recipe)
check at BrewRecipeMakerCommon::152
then fails, which means the recipe is then discarded.
Interestingly enough, at least with JeiBrewingRecipe
on 1.21.1, this would be properly handled if the uid
was not passed in to the createBrewingRecipe
, which would result in a null uid
:
if (uid != null) {
this.hashCode = uid.hashCode();
} else {
this.hashCode = Objects.hash(
ingredients.stream().map(ItemStack::getItem).toList(),
potionInputs.stream().map(ItemStack::getItem).toList(),
potionOutput.getItem()
);
}
Potential fix
A potential solution for this would be to modify line BrewingRecipeMakerCommon::145
to include the ingredient as an determiner in the uidPath
:
String ingredientResourceLocation = itemStackHelper.getResourceLocation(potionReagent);
String uidPath = ResourceLocationUtil.sanitizePath(
inputPathId +
".to." +
outputPathId +
".with." +
ResourceLocationUtil.sanitizePath(ingredientResourceLocation)
);
This would allow JEI to automatically show all recipes which use the same inputs and outputs but different ingredients to create potions.
I'm not sure what the ordering is like, but it might also be theoretically possible for certain modded recipes to supplant Vanilla recipes with the current code, if they are processed first and then the Vanilla recipe conflicts at a later point in processing knownPotions
.
Alternately, it might make more sense to detect the pre-existing recipe and merge the ingredients from that along with the ingredients from the "duplicate" into a new recipe. I'm not sure of the best approach for a PR.
EDIT: Further consideration would need to be made for any mods that have explicitly encountered this bug and manually added their own recipes via a plug-in.