diff --git a/gradle.properties b/gradle.properties index ed0ce3adf..f5c4f859c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,4 @@ curse_project_id=238222 version_major=4 version_minor=14 -version_patch=1 +version_patch=2 diff --git a/src/api/java/mezz/jei/api/ingredients/IIngredientHelper.java b/src/api/java/mezz/jei/api/ingredients/IIngredientHelper.java index fc8dbf0be..b2c6014dc 100644 --- a/src/api/java/mezz/jei/api/ingredients/IIngredientHelper.java +++ b/src/api/java/mezz/jei/api/ingredients/IIngredientHelper.java @@ -3,8 +3,10 @@ import javax.annotation.Nullable; import java.awt.Color; import java.util.Collection; +import java.util.Collections; import java.util.List; +import mezz.jei.api.recipe.IFocus; import mezz.jei.api.recipe.IIngredientType; import net.minecraft.item.ItemStack; @@ -21,24 +23,47 @@ public interface IIngredientHelper { /** * Expands any wildcard ingredients into all its subtypes. * Ingredients like FluidStack that have no wildcard ingredients should simply return the collection without editing it. + * + * @since JEI 3.11.0 + * Has a default implementation since JEI 4.14.2 + */ + default List expandSubtypes(List ingredients) { + return ingredients; + } + + /** + * Change one focus into a different focus. + * This can be used to treat lookups of one focus as if it were something else. + * + * On example is looking up fluid blocks, which get translated here into looking up the fluid itself. + * + * @since JEI 4.14.2 */ - List expandSubtypes(List ingredients); + default IFocus translateFocus(IFocus focus, IFocusFactory focusFactory) { + return focus; + } /** * Find a matching ingredient from a group of them. * Used for finding a specific focused ingredient in a recipe. * Return null if there is no match. + * + * @since JEI 3.11.0 */ @Nullable V getMatch(Iterable ingredients, V ingredientToMatch); /** * Display name used for searching. Normally this is the first line of the tooltip. + * + * @since JEI 3.11.0 */ String getDisplayName(V ingredient); /** * Unique ID for use in comparing, blacklisting, and looking up ingredients. + * + * @since JEI 3.11.0 */ String getUniqueId(V ingredient); @@ -46,16 +71,21 @@ public interface IIngredientHelper { * Wildcard ID for use in comparing, blacklisting, and looking up ingredients. * For an example, ItemStack's wildcardId does not include NBT or meta. * For ingredients like FluidStacks which do not have a wildcardId, just return the uniqueId here. + * + * @since JEI 3.11.0 */ String getWildcardId(V ingredient); /** * Return the modId of the mod that created this ingredient. + * + * @since JEI 3.11.0 */ String getModId(V ingredient); /** * Return the modId of the mod that should be displayed. + * * @since JEI 4.8.0 */ default String getDisplayModId(V ingredient) { @@ -65,8 +95,13 @@ default String getDisplayModId(V ingredient) { /** * Get the main colors of this ingredient. Used for the color search. * If this is too difficult to implement for your ingredient, just return an empty collection. + * + * @since JEI 3.11.0 + * Has a default implementation since JEI 4.14.2 */ - Iterable getColors(V ingredient); + default Iterable getColors(V ingredient) { + return Collections.emptyList(); + } /** * Return the resource id of the given ingredient. @@ -120,9 +155,31 @@ default boolean isIngredientOnServer(V ingredient) { return true; } + /** + * Get a list of ore dictionary names that include this ingredient. + * Used for searching by ore dictionary name. + * + * @since JEI 4.14.2 + */ + default Collection getOreDictNames(V ingredient) { + return Collections.emptyList(); + } + + /** + * Get a list of creative tab names that include this ingredient. + * Used for searching by creative tab name. + * + * @since JEI 4.14.2 + */ + default Collection getCreativeTabNames(V ingredient) { + return Collections.emptyList(); + } + /** * Get information for error messages involving this ingredient. * Be extremely careful not to crash here, get as much useful info as possible. + * + * @since JEI 3.11.0 */ String getErrorInfo(@Nullable V ingredient); @@ -144,4 +201,14 @@ default boolean isIngredientOnServer(V ingredient) { default ItemStack cheatIngredient(V ingredient, boolean fullStack) { return ItemStack.EMPTY; } + + /** + * @since JEI 4.14.2 + */ + interface IFocusFactory { + /** + * Returns a new focus. + */ + IFocus createFocus(IFocus.Mode mode, V ingredient); + } } diff --git a/src/api/java/mezz/jei/api/recipe/IVanillaRecipeFactory.java b/src/api/java/mezz/jei/api/recipe/IVanillaRecipeFactory.java index 04221ba8c..13a7e76c6 100644 --- a/src/api/java/mezz/jei/api/recipe/IVanillaRecipeFactory.java +++ b/src/api/java/mezz/jei/api/recipe/IVanillaRecipeFactory.java @@ -18,7 +18,7 @@ */ public interface IVanillaRecipeFactory { /** - * Adds an anvil recipe for the given inputs and output. + * Create an anvil recipe for the given inputs and output. * * @param leftInput The itemStack placed on the left slot. * @param rightInputs The itemStack(s) placed on the right slot. @@ -28,7 +28,7 @@ public interface IVanillaRecipeFactory { IRecipeWrapper createAnvilRecipe(ItemStack leftInput, List rightInputs, List outputs); /** - * Adds an anvil recipe for the given inputs and output. + * Create an anvil recipe for the given inputs and output. * The number of inputs in the left and right side must match. * * @param leftInputs The itemStack(s) placed on the left slot. diff --git a/src/main/java/mezz/jei/ingredients/IngredientListElement.java b/src/main/java/mezz/jei/ingredients/IngredientListElement.java index 204ed9ac2..ee45a9435 100644 --- a/src/main/java/mezz/jei/ingredients/IngredientListElement.java +++ b/src/main/java/mezz/jei/ingredients/IngredientListElement.java @@ -8,11 +8,6 @@ import mezz.jei.util.LegacyUtil; import mezz.jei.util.Log; import mezz.jei.util.Translator; -import net.minecraft.client.resources.I18n; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.oredict.OreDictionary; import javax.annotation.Nullable; import java.util.ArrayList; @@ -130,36 +125,18 @@ public final List getTooltipStrings() { @Override public Collection getOreDictStrings() { - Collection oreDictStrings = new ArrayList<>(); - - if (ingredient instanceof ItemStack) { - ItemStack itemStack = (ItemStack) ingredient; - for (int oreId : OreDictionary.getOreIDs(itemStack)) { - String oreNameLowercase = OreDictionary.getOreName(oreId).toLowerCase(Locale.ENGLISH); - oreDictStrings.add(oreNameLowercase); - } - } - - return oreDictStrings; + Collection oreDictNames = ingredientHelper.getOreDictNames(ingredient); + return oreDictNames.stream() + .map(s -> s.toLowerCase(Locale.ENGLISH)) + .collect(Collectors.toList()); } @Override public Collection getCreativeTabsStrings() { - Collection creativeTabsStrings = new ArrayList<>(); - - if (ingredient instanceof ItemStack) { - ItemStack itemStack = (ItemStack) ingredient; - Item item = itemStack.getItem(); - for (CreativeTabs creativeTab : item.getCreativeTabs()) { - if (creativeTab != null) { - String creativeTabName = I18n.format(creativeTab.getTranslationKey()); - String creativeTabNameLowercase = Translator.toLowercaseWithLocale(creativeTabName); - creativeTabsStrings.add(creativeTabNameLowercase); - } - } - } - - return creativeTabsStrings; + Collection creativeTabsStrings = ingredientHelper.getCreativeTabNames(ingredient); + return creativeTabsStrings.stream() + .map(Translator::toLowercaseWithLocale) + .collect(Collectors.toList()); } @Override diff --git a/src/main/java/mezz/jei/ingredients/Ingredients.java b/src/main/java/mezz/jei/ingredients/Ingredients.java index 9d2c8beca..1b1a20da7 100644 --- a/src/main/java/mezz/jei/ingredients/Ingredients.java +++ b/src/main/java/mezz/jei/ingredients/Ingredients.java @@ -51,15 +51,14 @@ public void setInputLists(Class ingredientClass, List> } @Override - public void setInputs(IIngredientType ingredientType, List input) { + public void setInputs(IIngredientType ingredientType, List inputs) { IIngredientRegistry ingredientRegistry = Internal.getIngredientRegistry(); IIngredientHelper ingredientHelper = ingredientRegistry.getIngredientHelper(ingredientType); List expandedInputs = new ArrayList<>(); - for (T input1 : input) { - List itemStacks = ingredientHelper.expandSubtypes(Collections.singletonList(input1)); - expandedInputs.add(itemStacks); + for (T input : inputs) { + List expandedInput = ingredientHelper.expandSubtypes(Collections.singletonList(input)); + expandedInputs.add(expandedInput); } - this.inputs.put(ingredientType, expandedInputs); } diff --git a/src/main/java/mezz/jei/plugins/jei/ingredients/DebugIngredientHelper.java b/src/main/java/mezz/jei/plugins/jei/ingredients/DebugIngredientHelper.java index e0c6350fc..63911abf1 100644 --- a/src/main/java/mezz/jei/plugins/jei/ingredients/DebugIngredientHelper.java +++ b/src/main/java/mezz/jei/plugins/jei/ingredients/DebugIngredientHelper.java @@ -14,11 +14,6 @@ import net.minecraft.util.text.TextFormatting; public class DebugIngredientHelper implements IIngredientHelper { - @Override - public List expandSubtypes(List ingredients) { - return ingredients; - } - @Nullable @Override public DebugIngredient getMatch(Iterable ingredients, DebugIngredient ingredientToMatch) { diff --git a/src/main/java/mezz/jei/plugins/vanilla/VanillaPlugin.java b/src/main/java/mezz/jei/plugins/vanilla/VanillaPlugin.java index 58a94485b..697c7c84f 100644 --- a/src/main/java/mezz/jei/plugins/vanilla/VanillaPlugin.java +++ b/src/main/java/mezz/jei/plugins/vanilla/VanillaPlugin.java @@ -62,6 +62,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; @@ -116,8 +117,15 @@ public void registerIngredients(IModIngredientRegistration ingredientRegistratio StackHelper stackHelper = Internal.getStackHelper(); ItemStackListFactory itemStackListFactory = new ItemStackListFactory(this.subtypeRegistry); - ingredientRegistration.register(VanillaTypes.ITEM, itemStackListFactory.create(stackHelper), new ItemStackHelper(stackHelper), new ItemStackRenderer()); - ingredientRegistration.register(VanillaTypes.FLUID, FluidStackListFactory.create(), new FluidStackHelper(), new FluidStackRenderer()); + List itemStacks = itemStackListFactory.create(stackHelper); + ItemStackHelper itemStackHelper = new ItemStackHelper(stackHelper); + ItemStackRenderer itemStackRenderer = new ItemStackRenderer(); + ingredientRegistration.register(VanillaTypes.ITEM, itemStacks, itemStackHelper, itemStackRenderer); + + List fluidStacks = FluidStackListFactory.create(); + FluidStackHelper fluidStackHelper = new FluidStackHelper(); + FluidStackRenderer fluidStackRenderer = new FluidStackRenderer(); + ingredientRegistration.register(VanillaTypes.FLUID, fluidStacks, fluidStackHelper, fluidStackRenderer); } @Override diff --git a/src/main/java/mezz/jei/plugins/vanilla/ingredients/fluid/FluidStackHelper.java b/src/main/java/mezz/jei/plugins/vanilla/ingredients/fluid/FluidStackHelper.java index a9847a882..b66e95fa3 100644 --- a/src/main/java/mezz/jei/plugins/vanilla/ingredients/fluid/FluidStackHelper.java +++ b/src/main/java/mezz/jei/plugins/vanilla/ingredients/fluid/FluidStackHelper.java @@ -20,11 +20,6 @@ import net.minecraftforge.fluids.FluidUtil; public class FluidStackHelper implements IIngredientHelper { - @Override - public List expandSubtypes(List contained) { - return contained; - } - @Override @Nullable public FluidStack getMatch(Iterable ingredients, FluidStack toMatch) { diff --git a/src/main/java/mezz/jei/plugins/vanilla/ingredients/item/ItemStackHelper.java b/src/main/java/mezz/jei/plugins/vanilla/ingredients/item/ItemStackHelper.java index a1a5c8bc2..93c43aab4 100644 --- a/src/main/java/mezz/jei/plugins/vanilla/ingredients/item/ItemStackHelper.java +++ b/src/main/java/mezz/jei/plugins/vanilla/ingredients/item/ItemStackHelper.java @@ -2,16 +2,28 @@ import javax.annotation.Nullable; import java.awt.Color; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.Locale; import mezz.jei.api.ingredients.IIngredientHelper; +import mezz.jei.api.recipe.IFocus; import mezz.jei.color.ColorGetter; import mezz.jei.startup.StackHelper; import mezz.jei.util.ErrorUtil; +import net.minecraft.block.Block; +import net.minecraft.client.resources.I18n; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.oredict.OreDictionary; public class ItemStackHelper implements IIngredientHelper { private final StackHelper stackHelper; @@ -25,6 +37,23 @@ public List expandSubtypes(List contained) { return stackHelper.getAllSubtypes(contained); } + @Override + public IFocus translateFocus(IFocus focus, IFocusFactory focusFactory) { + ItemStack itemStack = focus.getValue(); + Item item = itemStack.getItem(); + // Special case for ItemBlocks containing fluid blocks. + // Nothing crafts those, the player probably wants to look up fluids. + if (item instanceof ItemBlock) { + Block block = ((ItemBlock) item).getBlock(); + Fluid fluid = FluidRegistry.lookupFluidForBlock(block); + if (fluid != null) { + FluidStack fluidStack = new FluidStack(fluid, Fluid.BUCKET_VOLUME); + return focusFactory.createFocus(focus.getMode(), fluidStack); + } + } + return focus; + } + @Override @Nullable public ItemStack getMatch(Iterable ingredients, ItemStack toMatch) { @@ -115,6 +144,29 @@ public boolean isIngredientOnServer(ItemStack ingredient) { return ForgeRegistries.ITEMS.containsValue(item); } + @Override + public Collection getOreDictNames(ItemStack ingredient) { + Collection names = new ArrayList<>(); + for (int oreId : OreDictionary.getOreIDs(ingredient)) { + String oreNameLowercase = OreDictionary.getOreName(oreId).toLowerCase(Locale.ENGLISH); + names.add(oreNameLowercase); + } + return names; + } + + @Override + public Collection getCreativeTabNames(ItemStack ingredient) { + Collection creativeTabsStrings = new ArrayList<>(); + Item item = ingredient.getItem(); + for (CreativeTabs creativeTab : item.getCreativeTabs()) { + if (creativeTab != null) { + String creativeTabName = I18n.format(creativeTab.getTranslationKey()); + creativeTabsStrings.add(creativeTabName); + } + } + return creativeTabsStrings; + } + @Override public String getErrorInfo(@Nullable ItemStack ingredient) { return ErrorUtil.getItemStackInfo(ingredient); diff --git a/src/main/java/mezz/jei/recipes/RecipeRegistry.java b/src/main/java/mezz/jei/recipes/RecipeRegistry.java index 5d08d8ea3..74c205b77 100644 --- a/src/main/java/mezz/jei/recipes/RecipeRegistry.java +++ b/src/main/java/mezz/jei/recipes/RecipeRegistry.java @@ -33,15 +33,9 @@ import mezz.jei.plugins.vanilla.furnace.SmeltingRecipe; import mezz.jei.util.ErrorUtil; import mezz.jei.util.Log; -import net.minecraft.block.Block; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.inventory.Container; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.ProgressManager; import javax.annotation.Nullable; @@ -540,46 +534,23 @@ public RecipeClickableArea getRecipeClickableArea(GuiContainer gui, int mouseX, return null; } - /** - * Special case for ItemBlocks containing fluid blocks. - * Nothing crafts those, the player probably wants to look up fluids. - */ - @Nullable - private static FluidStack getFluidFromItemBlock(IFocus focus) { - Object ingredient = focus.getValue(); - if (ingredient instanceof ItemStack) { - ItemStack itemStack = (ItemStack) ingredient; - Item item = itemStack.getItem(); - if (item instanceof ItemBlock) { - Block block = ((ItemBlock) item).getBlock(); - Fluid fluid = FluidRegistry.lookupFluidForBlock(block); - if (fluid != null) { - return new FluidStack(fluid, Fluid.BUCKET_VOLUME); - } - } - } - - return null; - } - @Override public List getRecipeCategories(IFocus focus) { focus = Focus.check(focus); - FluidStack fluidStack = getFluidFromItemBlock(focus); - if (fluidStack != null) { - return getRecipeCategories(createFocus(focus.getMode(), fluidStack)); - } + IIngredientHelper ingredientHelper = ingredientRegistry.getIngredientHelper(focus.getValue()); + IFocus translatedFocus = ingredientHelper.translateFocus(focus, this::createFocus); + translatedFocus = Focus.check(translatedFocus); List allRecipeCategoryUids = new ArrayList<>(); for (IRecipeRegistryPlugin plugin : this.plugins) { - List recipeCategoryUids = plugin.getRecipeCategoryUids(focus); + List recipeCategoryUids = plugin.getRecipeCategoryUids(translatedFocus); for (String recipeCategoryUid : recipeCategoryUids) { if (!allRecipeCategoryUids.contains(recipeCategoryUid)) { if (hiddenRecipes.containsKey(recipeCategoryUid)) { IRecipeCategory recipeCategory = getRecipeCategory(recipeCategoryUid); if (recipeCategory != null) { - List recipeWrappers = getRecipeWrappers(recipeCategory, focus); + List recipeWrappers = getRecipeWrappers(recipeCategory, translatedFocus); if (!recipeWrappers.isEmpty()) { allRecipeCategoryUids.add(recipeCategoryUid); } @@ -599,14 +570,13 @@ public List getRecipeWrappers(IRecipeCategory ingredientHelper = ingredientRegistry.getIngredientHelper(focus.getValue()); + IFocus translatedFocus = ingredientHelper.translateFocus(focus, this::createFocus); + translatedFocus = Focus.check(translatedFocus); List allRecipeWrappers = new ArrayList<>(); for (IRecipeRegistryPlugin plugin : this.plugins) { - List recipeWrappers = plugin.getRecipeWrappers(recipeCategory, focus); + List recipeWrappers = plugin.getRecipeWrappers(recipeCategory, translatedFocus); allRecipeWrappers.addAll(recipeWrappers); } diff --git a/src/main/java/mezz/jei/startup/ForgeModIdHelper.java b/src/main/java/mezz/jei/startup/ForgeModIdHelper.java index 0833503e4..e024727a0 100644 --- a/src/main/java/mezz/jei/startup/ForgeModIdHelper.java +++ b/src/main/java/mezz/jei/startup/ForgeModIdHelper.java @@ -102,6 +102,7 @@ public String getModNameTooltipFormatting() { @Override public List addModNameToIngredientTooltip(List tooltip, T ingredient, IIngredientHelper ingredientHelper) { if (Config.isDebugModeEnabled() && Minecraft.getMinecraft().gameSettings.advancedItemTooltips) { + tooltip = new ArrayList<>(tooltip); tooltip.add(TextFormatting.GRAY + "JEI Debug:"); tooltip.add(TextFormatting.GRAY + "info: " + ingredientHelper.getErrorInfo(ingredient)); tooltip.add(TextFormatting.GRAY + "uid: " + ingredientHelper.getUniqueId(ingredient)); diff --git a/src/test/java/mezz/jei/test/lib/TestIngredientHelper.java b/src/test/java/mezz/jei/test/lib/TestIngredientHelper.java index ccc080183..18f24325a 100644 --- a/src/test/java/mezz/jei/test/lib/TestIngredientHelper.java +++ b/src/test/java/mezz/jei/test/lib/TestIngredientHelper.java @@ -8,11 +8,6 @@ import java.util.List; public class TestIngredientHelper implements IIngredientHelper { - @Override - public List expandSubtypes(List ingredients) { - return ingredients; - } - @Nullable @Override public TestIngredient getMatch(Iterable ingredients, TestIngredient ingredientToMatch) {