From 223f44bda5377fbfd3de1e0eafcadfa7f4bb6c9c Mon Sep 17 00:00:00 2001 From: KnightMiner Date: Sat, 5 Jan 2019 19:08:44 -0600 Subject: [PATCH] Show melter recipes in their own JEI tab by default This makes the overrides and blacklist more clear to the end user, which should help with #31. Also, it makes it more clear when solid fuel can be used for a recipe. This feature can be disabled if desired, as most times its redundant. --- .../tcomplement/common/Config.java | 5 + .../tcomplement/library/TCompRegistry.java | 53 +++++++++ .../tcomplement/plugin/jei/JEIPlugin.java | 29 ++++- .../jei/melter/MeltingRecipeCategory.java | 105 ++++++++++++++++++ .../jei/melter/MeltingRecipeChecker.java | 30 +++++ .../jei/melter/MeltingRecipeWrapper.java | 37 ++++++ .../assets/tcomplement/lang/en_us.lang | 4 +- .../tcomplement/textures/gui/jei/melter.png | Bin 0 -> 2265 bytes 8 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeCategory.java create mode 100644 src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeChecker.java create mode 100644 src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeWrapper.java create mode 100644 src/main/resources/assets/tcomplement/textures/gui/jei/melter.png diff --git a/src/main/java/knightminer/tcomplement/common/Config.java b/src/main/java/knightminer/tcomplement/common/Config.java index cfd6284..0affb9d 100644 --- a/src/main/java/knightminer/tcomplement/common/Config.java +++ b/src/main/java/knightminer/tcomplement/common/Config.java @@ -18,6 +18,7 @@ public class Config { public static float oreToIngotRatio = 1.0f; public static boolean blacklistMelterStone = true; + public static boolean separateMelterTab = true; static Configuration configFile; @@ -31,6 +32,10 @@ public static void load(FMLPreInitializationEvent event) { oreToIngotRatio = configFile.getFloat("oreToIngotRatio", "melter", 1.0f, 0f, 16.0f, "Ratio of ore to material produced in the melter."); + // jei + separateMelterTab = configFile.getBoolean("separateMelterTab", "jei", true, + "If true, puts the melter in its own recipe tab in JEI to make the blacklist and overrides more clear. If false, the melter is just added to the normal Tinkers tab."); + if(configFile.hasChanged()) { configFile.save(); } diff --git a/src/main/java/knightminer/tcomplement/library/TCompRegistry.java b/src/main/java/knightminer/tcomplement/library/TCompRegistry.java index 0b53206..62c6131 100644 --- a/src/main/java/knightminer/tcomplement/library/TCompRegistry.java +++ b/src/main/java/knightminer/tcomplement/library/TCompRegistry.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.Logger; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import knightminer.tcomplement.library.events.TCompRegisterEvent; @@ -32,6 +33,10 @@ public class TCompRegistry { private static List meltingBlacklist = Lists.newLinkedList(); + /** + * Registers a melter override recipe. This is a recipe that exists only in the melter, typically used to replace a smeltery recipe + * @param recipe Recipe to register + */ public static void registerMelterOverride(MeltingRecipe recipe) { if(new TCompRegisterEvent.MelterOverrideRegisterEvent(recipe).fire()) { meltingOverrides.add(recipe); @@ -46,6 +51,18 @@ public static void registerMelterOverride(MeltingRecipe recipe) { } } + /** + * Gets all melter overrides + * @return Immutable list of all melter overrides + */ + public static List getAllMeltingOverrides() { + return ImmutableList.copyOf(meltingOverrides); + } + + /** + * Blacklists an input from being used for a normal smeltery recipe. This is not needed if an override is added with that input + * @param blacklist Blacklist entry + */ public static void registerMelterBlacklist(IBlacklist blacklist) { if(new TCompRegisterEvent.MelterBlackListRegisterEvent(blacklist).fire()) { meltingBlacklist.add(blacklist); @@ -59,10 +76,46 @@ public static void registerMelterBlacklist(IBlacklist blacklist) { } } + /** + * Registers a blacklist entry using a RecipeMatch entry + * @param blacklist RecipeMatch to blacklist + */ public static void registerMelterBlacklist(RecipeMatch blacklist) { registerMelterBlacklist(new RecipeMatchBlacklist(blacklist)); } + /** + * Checks if a melting recipe is hidden by the melter overrides or blacklist + * @param recipe Recipe to check + * @return true if the recipe would be hidden, false otherwise + */ + public static boolean isSmeltingHidden(MeltingRecipe recipe) { + List inputs = recipe.input.getInputs(); + + // TODO: should probably validate that all inputs match for cases of list inputs, but probably not an issue + // check blacklist first, its probably quicker + for(IBlacklist blacklist : meltingBlacklist) { + if(inputs.stream().anyMatch(blacklist::matches)) { + return true; + } + } + + // next try overrides + for(MeltingRecipe override : meltingOverrides) { + if(inputs.stream().anyMatch(override::matches)) { + return true; + } + } + + return false; + } + + /** + * Gets the melting recipe for a given item stack. + * This checks the overrides first, then runs though the blacklist before checking the smeltery registry + * @param stack Input stack + * @return recipe instance + */ public static MeltingRecipe getMelting(ItemStack stack) { // check if the recipe exists in our overrides for(MeltingRecipe recipe : meltingOverrides) { diff --git a/src/main/java/knightminer/tcomplement/plugin/jei/JEIPlugin.java b/src/main/java/knightminer/tcomplement/plugin/jei/JEIPlugin.java index 2be216e..60d8c59 100644 --- a/src/main/java/knightminer/tcomplement/plugin/jei/JEIPlugin.java +++ b/src/main/java/knightminer/tcomplement/plugin/jei/JEIPlugin.java @@ -6,37 +6,60 @@ import com.google.common.collect.ImmutableList; import knightminer.tcomplement.TinkersComplement; +import knightminer.tcomplement.common.Config; import knightminer.tcomplement.feature.ModuleFeature; import knightminer.tcomplement.feature.client.GuiMelter; import knightminer.tcomplement.plugin.chisel.ChiselPlugin; import knightminer.tcomplement.plugin.exnihilo.ExNihiloPlugin; +import knightminer.tcomplement.plugin.jei.melter.MeltingRecipeCategory; +import knightminer.tcomplement.plugin.jei.melter.MeltingRecipeChecker; +import knightminer.tcomplement.plugin.jei.melter.MeltingRecipeWrapper; +import mezz.jei.api.IGuiHelper; import mezz.jei.api.IModPlugin; import mezz.jei.api.IModRegistry; import mezz.jei.api.gui.IAdvancedGuiHandler; +import mezz.jei.api.recipe.IRecipeCategoryRegistration; import mezz.jei.api.recipe.VanillaRecipeCategoryUid; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.item.ItemStack; +import slimeknights.tconstruct.library.smeltery.MeltingRecipe; import slimeknights.tconstruct.smeltery.client.IGuiLiquidTank; import slimeknights.tconstruct.tools.TinkerMaterials; - @mezz.jei.api.JEIPlugin public class JEIPlugin implements IModPlugin { private static final String FURNACE_FUEL = VanillaRecipeCategoryUid.FUEL; private static final String TINKERS_SMELTERY = "tconstruct.smeltery"; private static final String EXNIHILO_HAMMER = "exnihilocreatio:hammer"; private static final String CHISEL_CHISELING = "chisel.chiseling"; + public static MeltingRecipeCategory meltingCategory; + + @Override + public void registerCategories(IRecipeCategoryRegistration registry) { + final IGuiHelper guiHelper = registry.getJeiHelpers().getGuiHelper(); + + // Melter + if(Config.separateMelterTab && TinkersComplement.pulseManager.isPulseLoaded(ModuleFeature.pulseID)) { + registry.addRecipeCategories(meltingCategory = new MeltingRecipeCategory(guiHelper)); + } + } @Override public void register(IModRegistry registry) { if(TinkersComplement.pulseManager.isPulseLoaded(ModuleFeature.pulseID)) { + String melterCategory = TINKERS_SMELTERY; + if(Config.separateMelterTab) { + melterCategory = MeltingRecipeCategory.CATEGORY; + registry.handleRecipes(MeltingRecipe.class, MeltingRecipeWrapper::new, MeltingRecipeCategory.CATEGORY); + registry.addRecipes(MeltingRecipeChecker.getMeltingRecipes(), MeltingRecipeCategory.CATEGORY); + } // smeltery alternatives if(ModuleFeature.melter != null) { - registry.addRecipeCatalyst(new ItemStack(ModuleFeature.melter), TINKERS_SMELTERY); + registry.addRecipeCatalyst(new ItemStack(ModuleFeature.melter), melterCategory); registry.addRecipeCatalyst(new ItemStack(ModuleFeature.melter, 1, 8), FURNACE_FUEL); } if(ModuleFeature.porcelainMelter != null) { - registry.addRecipeCatalyst(new ItemStack(ModuleFeature.porcelainMelter), TINKERS_SMELTERY); + registry.addRecipeCatalyst(new ItemStack(ModuleFeature.porcelainMelter), melterCategory); registry.addRecipeCatalyst(new ItemStack(ModuleFeature.porcelainMelter, 1, 8), FURNACE_FUEL); } diff --git a/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeCategory.java b/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeCategory.java new file mode 100644 index 0000000..6f9642d --- /dev/null +++ b/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeCategory.java @@ -0,0 +1,105 @@ +package knightminer.tcomplement.plugin.jei.melter; + +import java.util.List; + +import javax.annotation.Nonnull; + +import com.google.common.collect.ImmutableList; + +import knightminer.tcomplement.TinkersComplement; +import knightminer.tcomplement.library.Util; +import mezz.jei.api.IGuiHelper; +import mezz.jei.api.gui.IDrawable; +import mezz.jei.api.gui.IDrawableAnimated; +import mezz.jei.api.gui.IDrawableStatic; +import mezz.jei.api.gui.IGuiFluidStackGroup; +import mezz.jei.api.gui.IGuiItemStackGroup; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.recipe.IRecipeCategory; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import slimeknights.tconstruct.library.client.GuiUtil; +import slimeknights.tconstruct.library.materials.Material; + +public class MeltingRecipeCategory implements IRecipeCategory { + + public static final String CATEGORY = Util.resource("melter"); + public static final ResourceLocation BACKGROUND = Util.getResource("textures/gui/jei/melter.png"); + private static List furnaceFuels; + + private final IDrawable background; + protected final IDrawable solidCover; + protected final IDrawableAnimated flame; + private final IDrawableAnimated progress; + + public MeltingRecipeCategory(IGuiHelper guiHelper) { + background = guiHelper.createDrawable(BACKGROUND, 0, 0, 160, 46, 0, 0, 0, 0); + solidCover = guiHelper.createDrawable(BACKGROUND, 174, 0, 18, 33); + + IDrawableStatic flameDrawable = guiHelper.createDrawable(BACKGROUND, 160, 0, 14, 14); + flame = guiHelper.createAnimatedDrawable(flameDrawable, 200, IDrawableAnimated.StartDirection.TOP, true); + IDrawableStatic progressDrawable = guiHelper.createDrawable(BACKGROUND, 160, 14, 3, 16); + progress = guiHelper.createAnimatedDrawable(progressDrawable, 200, IDrawableAnimated.StartDirection.BOTTOM, false); + } + + @Nonnull + @Override + public String getUid() { + return CATEGORY; + } + + @Nonnull + @Override + public String getTitle() { + return Util.translate("gui.jei.melter.title"); + } + + @Nonnull + @Override + public IDrawable getBackground() { + return background; + } + + @Override + public void drawExtras(Minecraft minecraft) { + progress.draw(minecraft, 49, 21); + } + + @Override + public void setRecipe(IRecipeLayout recipeLayout, MeltingRecipeWrapper recipe, IIngredients ingredients) { + IGuiItemStackGroup items = recipeLayout.getItemStacks(); + items.init(0, true, 52, 20); + items.set(ingredients); + + // if solid fuels are available, add a standard subset + if(recipe.isSolid) { + items.init(1, true, 6, 22); + items.set(1, getFurnaceFuels()); + } + + IGuiFluidStackGroup fluids = recipeLayout.getFluidStacks(); + fluids.addTooltipCallback(GuiUtil::onFluidTooltip); + + fluids.init(0, false, 121, 7, 32, 32, Material.VALUE_Block, false, null); + fluids.set(ingredients); + + fluids.init(1, true, 29, 7, 12, 32, 1000, false, null); + fluids.set(1, recipe.getLiquidFuels()); + } + + @Override + public String getModName() { + return TinkersComplement.modName; + } + + private static List getFurnaceFuels() { + if (furnaceFuels != null) { + return furnaceFuels; + } + return furnaceFuels = ImmutableList.of(new ItemStack(Items.COAL), new ItemStack(Items.COAL, 1, 1), new ItemStack(Blocks.LOG), new ItemStack(Blocks.PLANKS), new ItemStack(Blocks.COAL_BLOCK)); + } +} diff --git a/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeChecker.java b/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeChecker.java new file mode 100644 index 0000000..1920b12 --- /dev/null +++ b/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeChecker.java @@ -0,0 +1,30 @@ +package knightminer.tcomplement.plugin.jei.melter; + +import java.util.ArrayList; +import java.util.List; + +import knightminer.tcomplement.library.TCompRegistry; +import slimeknights.tconstruct.library.smeltery.MeltingRecipe; +import slimeknights.tconstruct.plugin.jei.smelting.SmeltingRecipeChecker; + +public class MeltingRecipeChecker { + public static List getMeltingRecipes() { + List recipes = new ArrayList<>(); + + // first, add all overrides + for(MeltingRecipe recipe : TCompRegistry.getAllMeltingOverrides()) { + if(recipe.output != null && recipe.input != null && recipe.input.getInputs() != null && recipe.input.getInputs().size() > 0) { + recipes.add(recipe); + } + } + + // next, add all normal melting recipes if not hidden by the blacklist or overrides + for(MeltingRecipe recipe : SmeltingRecipeChecker.getSmeltingRecipes()) { + if (!TCompRegistry.isSmeltingHidden(recipe)) { + recipes.add(recipe); + } + } + + return recipes;//recipes.stream().map(MeltingRecipeWrapper::new).collect(Collectors.toList()); + } +} diff --git a/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeWrapper.java b/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeWrapper.java new file mode 100644 index 0000000..52b6df5 --- /dev/null +++ b/src/main/java/knightminer/tcomplement/plugin/jei/melter/MeltingRecipeWrapper.java @@ -0,0 +1,37 @@ +package knightminer.tcomplement.plugin.jei.melter; + +import java.util.List; + +import javax.annotation.Nonnull; + +import knightminer.tcomplement.plugin.jei.JEIPlugin; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fluids.FluidStack; +import slimeknights.tconstruct.library.smeltery.MeltingRecipe; +import slimeknights.tconstruct.plugin.jei.smelting.SmeltingRecipeWrapper; + +public class MeltingRecipeWrapper extends SmeltingRecipeWrapper { + + protected boolean isSolid; + public MeltingRecipeWrapper(MeltingRecipe recipe) { + super(recipe); + // if true, we can use solid fuels + isSolid = recipe.getTemperature() <= 500; + } + + public List getLiquidFuels() { + return fuels; + } + + + @Override + public void drawInfo(@Nonnull Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY) { + // if solid fuel is available, draw the flame icon, otherwise cover the slot + if(isSolid) { + JEIPlugin.meltingCategory.flame.draw(minecraft, 8, 7); + } else { + JEIPlugin.meltingCategory.solidCover.draw(minecraft, 6, 7); + } + super.drawInfo(minecraft, recipeWidth, recipeHeight, mouseX, mouseY); + } +} diff --git a/src/main/resources/assets/tcomplement/lang/en_us.lang b/src/main/resources/assets/tcomplement/lang/en_us.lang index 9f2be1f..d81faa5 100644 --- a/src/main/resources/assets/tcomplement/lang/en_us.lang +++ b/src/main/resources/assets/tcomplement/lang/en_us.lang @@ -67,4 +67,6 @@ gui.tcomplement.melter.progress.wrong_fluid=Resulting fluid is different than fl gui.tcomplement.melter.solid_fuel=Heater gui.tcomplement.melter.solid_fuel.amount=%s units -gui.tcomplement.heater.name=Heater \ No newline at end of file +gui.tcomplement.heater.name=Heater + +gui.jei.melter.title=Melter \ No newline at end of file diff --git a/src/main/resources/assets/tcomplement/textures/gui/jei/melter.png b/src/main/resources/assets/tcomplement/textures/gui/jei/melter.png new file mode 100644 index 0000000000000000000000000000000000000000..9cb28c7b395e7a5da91a76b7ba7808fdcaf4804d GIT binary patch literal 2265 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(0|PTd zfKP}kP~6J|F`7-zoo~H9sB?P>i_>Y|Np!7|NnoWy`x|>1O_|=OylC9V-A!TD(= z<%vb93~dWL$YDee)#LWo7j)5S5QBJS<<-n`2O60VZW$0SnUCPe?# zHBfl}zePE|=9ZPO!_4bp^WND8RqIq|y}7)kBfWg9@!_8ukN-`)BA+1m{9RmksQJbA zVv*qbhTTV>EtO2zmUDh@PJUwr??aiRHjVBIOhpA;AV#u;BNXZ@RoqQcPR6JFrA7J1B52(B~_onC~BEf%bg&%vJ2qHPVC^>`nQ; zPmVS84&z&c`rAMUPG-HaCx2bAbHlRC8(9;c6-8()lV7m+U6sTYfd}W`$LE-O6kF4%*R|H?ZuE$Osks`>q^buC+_UVCd&8S@(L5}>}%%lo1F zHvi^WbKfe9qoBI_G*sVh>x7n#41eO+o_{uP=D91NvLCAW^9P2v1si@g?M}{Wc+Gzu zD(cLz@1*YC@?G;89&bN>g(3X?dZ;_oWE)oJz0ljgoMAERGPW7#pF=eiPhm&~3hdZZ za~x{raZZDvgsg_`;^HtROBfC_1vAf?zdv!c8#{meJim+X`g>stBGyrI?!YF5G? zR~?4KJ)0PQKeu3%cAWW&ezTkLQDeRxkI zu5kL7@;9Fo1Qx{Icz&>eVO_8;kY~YgeWlp9N&^{&(~lS;#MlpPvS65YlyQR&Uqfmk ogHAVdLgc6vRYF5a?!mu*`r^zUW(p