Fix JEI compat

This commit is contained in:
thedarkcolour 2026-05-14 23:49:19 -07:00
parent aa7bf56d0f
commit 964c82b709
19 changed files with 282 additions and 196 deletions

View File

@ -60,7 +60,6 @@ sourceSets.main.resources { srcDir 'src/generated/resources' }
// Exclude compat packages for libraries without 1.26.1 support yet // Exclude compat packages for libraries without 1.26.1 support yet
sourceSets.main.java.exclude( sourceSets.main.java.exclude(
'**/compat/jei/**',
'**/compat/emi/**', '**/compat/emi/**',
'**/compat/jade/**', '**/compat/jade/**',
'**/compat/kubejs/**', '**/compat/kubejs/**',
@ -124,9 +123,9 @@ dependencies {
//} //}
// JADE OPTIONAL // JADE OPTIONAL
//implementation("curse.maven:jade-324717:6291517") //implementation("curse.maven:jade-324717:6291517")
// JEI OPTIONAL // JEI OPTIONAL todo change back to mc_version
//compileOnly("mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}") compileOnly("mezz.jei:jei-${'26.1.2'}-neoforge-api:${jei_version}")
//runtimeOnly("mezz.jei:jei-${mc_version}-neoforge:${jei_version}") runtimeOnly("mezz.jei:jei-${'26.1.2'}-neoforge:${jei_version}")
// EMI OPTIONAL // EMI OPTIONAL
//compileOnly("dev.emi:emi-neoforge:${emi_version}+${mc_version}:api") //compileOnly("dev.emi:emi-neoforge:${emi_version}+${mc_version}:api")
//runtimeOnly("dev.emi:emi-neoforge:${emi_version}+${mc_version}") //runtimeOnly("dev.emi:emi-neoforge:${emi_version}+${mc_version}")

View File

@ -10,7 +10,7 @@ neo_version=26.1.1.1-beta
neo_version_range=[26.1,) neo_version_range=[26.1,)
loader_version_range=[4,) loader_version_range=[4,)
#jei_version=19.25.0.323 jei_version=29.5.0.28
#emi_version=1.1.21 #emi_version=1.1.21
#cloth_config_version=15.0.127 #cloth_config_version=15.0.127
#top_version=12.0.3-5 #top_version=12.0.3-5

View File

@ -2,26 +2,36 @@ package thedarkcolour.exdeorum.compat;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import thedarkcolour.exdeorum.ExDeorum;
import thedarkcolour.exdeorum.client.RenderUtil;
import thedarkcolour.exdeorum.data.TranslationKeys; import thedarkcolour.exdeorum.data.TranslationKeys;
import thedarkcolour.exdeorum.material.DefaultMaterials;
// TODO: port ClientXeiUtil to MC 26.x:
// - GuiGraphics GuiGraphicsExtractor
// - BakedModel/ItemRenderer removed; use new item rendering API
// - BlockRenderDispatcher/renderSingleBlock removed
// - ItemBlockRenderTypes.getRenderLayer removed; use FluidStateModelSet/FluidModel
// - RenderTypeHelper removed
// - ModelData moved package
// - OAK_BARREL_COMPOSTING removed from ClientHandler (ModelResourceLocation removed)
// client-only logic shared between JEI and EMI // client-only logic shared between JEI and EMI
public class ClientXeiUtil { public class ClientXeiUtil {
private static final ItemStack OAK_BARREL = new ItemStack(DefaultMaterials.OAK_BARREL.getItem());
public static void renderBlock(GuiGraphicsExtractor guiGraphics, BlockState state, float x, float y, float z, float scale) { public static void renderBlock(GuiGraphicsExtractor guiGraphics, BlockState state, float x, float y, float z, float scale) {
// TODO: port block/fluid rendering using 26.x FluidRenderer and block model APIs var fluidState = state.getFluidState();
if (!fluidState.isEmpty()) {
var sprite = RenderUtil.getFluidSprite(fluidState.getType());
guiGraphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprite, Math.round(x), Math.round(y), Math.round(scale), Math.round(scale));
return;
}
var stack = new ItemStack(state.getBlock());
if (!stack.isEmpty()) {
renderScaledItem(guiGraphics, stack, x, y, scale);
}
} }
public static void renderItemWithAsterisk(GuiGraphicsExtractor graphics, net.minecraft.world.item.ItemStack stack) { public static void renderItemWithAsterisk(GuiGraphicsExtractor graphics, ItemStack stack) {
// TODO: port item rendering using 26.x item model API graphics.fakeItem(stack, 0, 0);
renderAsterisk(graphics, 0, 0);
} }
public static void renderAsterisk(GuiGraphicsExtractor graphics, int xOffset, int yOffset) { public static void renderAsterisk(GuiGraphicsExtractor graphics, int xOffset, int yOffset) {
@ -31,7 +41,9 @@ public class ClientXeiUtil {
} }
public static void renderFilledCompostBarrel(GuiGraphicsExtractor guiGraphics, int xOffset, int yOffset) { public static void renderFilledCompostBarrel(GuiGraphicsExtractor guiGraphics, int xOffset, int yOffset) {
// TODO: port using 26.x item model API (ModelResourceLocation/OAK_BARREL_COMPOSTING removed) guiGraphics.fakeItem(OAK_BARREL, xOffset, yOffset);
var sprite = RenderUtil.getBlockSprite(ExDeorum.loc("block/compost_dirt"));
guiGraphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprite, xOffset + 4, yOffset + 5, 8, 8);
} }
// Takes a decimal probability and returns a user-friendly percentage value // Takes a decimal probability and returns a user-friendly percentage value
@ -39,4 +51,13 @@ public class ClientXeiUtil {
var chance = XeiUtil.FORMATTER.format(probability * 100); var chance = XeiUtil.FORMATTER.format(probability * 100);
return Component.translatable(TranslationKeys.SIEVE_RECIPE_CHANCE, chance).withStyle(ChatFormatting.GRAY); return Component.translatable(TranslationKeys.SIEVE_RECIPE_CHANCE, chance).withStyle(ChatFormatting.GRAY);
} }
private static void renderScaledItem(GuiGraphicsExtractor graphics, ItemStack stack, float x, float y, float scale) {
var pose = graphics.pose();
pose.pushMatrix();
pose.translate(x, y);
pose.scale(scale / 16f);
graphics.fakeItem(stack, 0, 0);
pose.popMatrix();
}
} }

View File

@ -24,10 +24,10 @@ import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.recipe.types.IRecipeType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import thedarkcolour.exdeorum.compat.ClientXeiUtil; import thedarkcolour.exdeorum.compat.ClientXeiUtil;
import thedarkcolour.exdeorum.data.TranslationKeys; import thedarkcolour.exdeorum.data.TranslationKeys;
@ -37,20 +37,18 @@ class BarrelCompostCategory implements IRecipeCategory<BarrelCompostRecipe> {
public static final int WIDTH = 120; public static final int WIDTH = 120;
public static final int HEIGHT = 18; public static final int HEIGHT = 18;
private final IDrawable background;
private final IDrawable slot; private final IDrawable slot;
private final IDrawable icon; private final IDrawable icon;
private final Component title; private final Component title;
public BarrelCompostCategory(IGuiHelper helper) { public BarrelCompostCategory(IGuiHelper helper) {
this.background = helper.createBlankDrawable(WIDTH, HEIGHT);
this.slot = helper.getSlotDrawable(); this.slot = helper.getSlotDrawable();
this.icon = new DrawableIcon(); this.icon = new DrawableIcon();
this.title = Component.translatable(TranslationKeys.BARREL_COMPOST_CATEGORY_TITLE); this.title = Component.translatable(TranslationKeys.BARREL_COMPOST_CATEGORY_TITLE);
} }
@Override @Override
public RecipeType<BarrelCompostRecipe> getRecipeType() { public IRecipeType<BarrelCompostRecipe> getRecipeType() {
return ExDeorumJeiPlugin.BARREL_COMPOST; return ExDeorumJeiPlugin.BARREL_COMPOST;
} }
@ -60,8 +58,13 @@ class BarrelCompostCategory implements IRecipeCategory<BarrelCompostRecipe> {
} }
@Override @Override
public IDrawable getBackground() { public int getWidth() {
return this.background; return WIDTH;
}
@Override
public int getHeight() {
return HEIGHT;
} }
@Override @Override
@ -71,17 +74,17 @@ class BarrelCompostCategory implements IRecipeCategory<BarrelCompostRecipe> {
@Override @Override
public void setRecipe(IRecipeLayoutBuilder builder, BarrelCompostRecipe recipe, IFocusGroup focuses) { public void setRecipe(IRecipeLayoutBuilder builder, BarrelCompostRecipe recipe, IFocusGroup focuses) {
builder.addSlot(RecipeIngredientRole.INPUT, 1, 1).addIngredients(recipe.ingredient()); builder.addSlot(RecipeIngredientRole.INPUT, 1, 1).add(recipe.ingredient());
} }
@Override @Override
public void draw(BarrelCompostRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { public void draw(BarrelCompostRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphicsExtractor graphics, double mouseX, double mouseY) {
this.slot.draw(graphics); this.slot.draw(graphics);
var volume = recipe.getVolume(); var volume = recipe.getVolume();
var volumeLabel = Component.translatable(TranslationKeys.BARREL_COMPOST_RECIPE_VOLUME, volume); var volumeLabel = Component.translatable(TranslationKeys.BARREL_COMPOST_RECIPE_VOLUME, volume);
graphics.drawString(Minecraft.getInstance().font, volumeLabel, 24, 5, 0xff808080, false); graphics.text(Minecraft.getInstance().font, volumeLabel, 24, 5, 0xff808080, false);
} }
private static class DrawableIcon implements IDrawable { private static class DrawableIcon implements IDrawable {
@ -96,7 +99,7 @@ class BarrelCompostCategory implements IRecipeCategory<BarrelCompostRecipe> {
} }
@Override @Override
public void draw(GuiGraphics guiGraphics, int xOffset, int yOffset) { public void draw(GuiGraphicsExtractor guiGraphics, int xOffset, int yOffset) {
ClientXeiUtil.renderFilledCompostBarrel(guiGraphics, xOffset, yOffset); ClientXeiUtil.renderFilledCompostBarrel(guiGraphics, xOffset, yOffset);
} }
} }

View File

@ -24,10 +24,10 @@ import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.recipe.types.IRecipeType;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -41,7 +41,6 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
public static final int WIDTH = 120; public static final int WIDTH = 120;
public static final int HEIGHT = 18; public static final int HEIGHT = 18;
private final IDrawable background;
private final IDrawable slot; private final IDrawable slot;
private final IDrawable plus; private final IDrawable plus;
private final IDrawable arrow; private final IDrawable arrow;
@ -49,7 +48,6 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
private final Component title; private final Component title;
public BarrelMixingCategory(IGuiHelper helper, IDrawable plus, IDrawable arrow, String titleKey, Item iconItem) { public BarrelMixingCategory(IGuiHelper helper, IDrawable plus, IDrawable arrow, String titleKey, Item iconItem) {
this.background = helper.createBlankDrawable(WIDTH, HEIGHT);
this.slot = helper.getSlotDrawable(); this.slot = helper.getSlotDrawable();
this.plus = plus; this.plus = plus;
this.arrow = arrow; this.arrow = arrow;
@ -63,8 +61,13 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
} }
@Override @Override
public IDrawable getBackground() { public int getWidth() {
return this.background; return WIDTH;
}
@Override
public int getHeight() {
return HEIGHT;
} }
@Override @Override
@ -73,7 +76,7 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
} }
@Override @Override
public void draw(T recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { public void draw(T recipe, IRecipeSlotsView recipeSlotsView, GuiGraphicsExtractor graphics, double mouseX, double mouseY) {
this.slot.draw(graphics); this.slot.draw(graphics);
this.plus.draw(graphics, 21, 5); this.plus.draw(graphics, 21, 5);
this.slot.draw(graphics, 18 + 3 + 3 + 8, 0); this.slot.draw(graphics, 18 + 3 + 3 + 8, 0);
@ -89,12 +92,12 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
@Override @Override
public void setRecipe(IRecipeLayoutBuilder builder, BarrelMixingRecipe recipe, IFocusGroup focuses) { public void setRecipe(IRecipeLayoutBuilder builder, BarrelMixingRecipe recipe, IFocusGroup focuses) {
JeiUtil.addFluidIngredient(builder.addSlot(RecipeIngredientRole.INPUT, 1, 1), recipe.fluid).setFluidRenderer(1000, false, 16, 16); JeiUtil.addFluidIngredient(builder.addSlot(RecipeIngredientRole.INPUT, 1, 1), recipe.fluid).setFluidRenderer(1000, false, 16, 16);
builder.addSlot(RecipeIngredientRole.INPUT, 33, 1).addIngredients(recipe.ingredient()); builder.addSlot(RecipeIngredientRole.INPUT, 33, 1).add(recipe.ingredient());
builder.addSlot(RecipeIngredientRole.OUTPUT, 79, 1).addItemStack(recipe.result.create()); builder.addSlot(RecipeIngredientRole.OUTPUT, 79, 1).add(recipe.result.create());
} }
@Override @Override
public RecipeType<BarrelMixingRecipe> getRecipeType() { public IRecipeType<BarrelMixingRecipe> getRecipeType() {
return ExDeorumJeiPlugin.BARREL_MIXING; return ExDeorumJeiPlugin.BARREL_MIXING;
} }
} }
@ -113,18 +116,18 @@ public abstract class BarrelMixingCategory<T> implements IRecipeCategory<T> {
var additiveSlot = JeiUtil.addFluidIngredient(builder.addSlot(RecipeIngredientRole.INPUT, 33, 1), recipe.additiveFluid(), 1000) var additiveSlot = JeiUtil.addFluidIngredient(builder.addSlot(RecipeIngredientRole.INPUT, 33, 1), recipe.additiveFluid(), 1000)
.setFluidRenderer(1000, false, 16, 16); .setFluidRenderer(1000, false, 16, 16);
if (recipe.consumesAdditive()) { if (recipe.consumesAdditive()) {
additiveSlot.addTooltipCallback((view, tooltip) -> tooltip.add(CONTENTS_ARE_CONSUMED_TOOLTIP)); additiveSlot.addRichTooltipCallback((_, tooltip) -> tooltip.add(CONTENTS_ARE_CONSUMED_TOOLTIP));
} }
builder.addSlot(RecipeIngredientRole.OUTPUT, 79, 1).addItemStack(recipe.result().create()); builder.addSlot(RecipeIngredientRole.OUTPUT, 79, 1).add(recipe.result().create());
} }
@Override @Override
public RecipeType<BarrelFluidMixingRecipe> getRecipeType() { public IRecipeType<BarrelFluidMixingRecipe> getRecipeType() {
return ExDeorumJeiPlugin.BARREL_FLUID_MIXING; return ExDeorumJeiPlugin.BARREL_FLUID_MIXING;
} }
@Override @Override
public void draw(BarrelFluidMixingRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { public void draw(BarrelFluidMixingRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphicsExtractor graphics, double mouseX, double mouseY) {
super.draw(recipe, recipeSlotsView, graphics, mouseX, mouseY); super.draw(recipe, recipeSlotsView, graphics, mouseX, mouseY);
if (recipe.consumesAdditive()) { if (recipe.consumesAdditive()) {

View File

@ -18,7 +18,6 @@
package thedarkcolour.exdeorum.compat.jei; package thedarkcolour.exdeorum.compat.jei;
import com.mojang.blaze3d.systems.RenderSystem;
import mezz.jei.api.ingredients.IIngredientRenderer; import mezz.jei.api.ingredients.IIngredientRenderer;
import mezz.jei.api.ingredients.IIngredientType; import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.ingredients.ITypedIngredient; import mezz.jei.api.ingredients.ITypedIngredient;
@ -27,7 +26,7 @@ import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.runtime.IIngredientManager; import mezz.jei.api.runtime.IIngredientManager;
import mezz.jei.api.runtime.IRecipesGui; import mezz.jei.api.runtime.IRecipesGui;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
@ -41,10 +40,11 @@ import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
class ClientJeiUtil { class ClientJeiUtil {
// todo is this still needed? i'm not supporting REI anymore
// Required due to broken JEI implementation in REI plugin compatibility // Required due to broken JEI implementation in REI plugin compatibility
static <T> void checkTypedIngredient(IIngredientManager manager, IIngredientType<T> ingredientType, @Nullable T uncheckedIngredient, Consumer<ITypedIngredient<T>> action) { static <T> void checkTypedIngredient(IIngredientManager manager, IIngredientType<T> ingredientType, @Nullable T uncheckedIngredient, Consumer<ITypedIngredient<T>> action) {
if ((uncheckedIngredient instanceof ItemStack stack && !stack.isEmpty()) || (uncheckedIngredient instanceof FluidStack fluidStack && !fluidStack.isEmpty())) { if ((uncheckedIngredient instanceof ItemStack stack && !stack.isEmpty()) || (uncheckedIngredient instanceof FluidStack fluidStack && !fluidStack.isEmpty())) {
manager.createTypedIngredient(ingredientType, uncheckedIngredient).ifPresent(action); manager.createTypedIngredient(ingredientType, uncheckedIngredient, false).ifPresent(action);
} }
} }
@ -57,7 +57,7 @@ class ClientJeiUtil {
static <T> void showUsages(IFocusFactory focusFactory, ITypedIngredient<T> ingredient) { static <T> void showUsages(IFocusFactory focusFactory, ITypedIngredient<T> ingredient) {
if (Minecraft.getInstance().screen instanceof IRecipesGui recipesGui) { if (Minecraft.getInstance().screen instanceof IRecipesGui recipesGui) {
// input + catalyst // input + catalyst
recipesGui.show(List.of(focusFactory.createFocus(RecipeIngredientRole.INPUT, ingredient), focusFactory.createFocus(RecipeIngredientRole.CATALYST, ingredient))); recipesGui.show(List.of(focusFactory.createFocus(RecipeIngredientRole.INPUT, ingredient), focusFactory.createFocus(RecipeIngredientRole.CRAFTING_STATION, ingredient)));
} }
} }
@ -65,13 +65,10 @@ class ClientJeiUtil {
INSTANCE; INSTANCE;
@Override @Override
public void render(GuiGraphics graphics, @Nullable ItemStack ingredient) { public void render(GuiGraphicsExtractor graphics, @Nullable ItemStack ingredient) {
if (ingredient != null) { if (ingredient != null) {
// From mezz.jei.library.render.ItemStackRenderer // From mezz.jei.library.render.ItemStackRenderer.render
RenderSystem.enableDepthTest();
ClientXeiUtil.renderItemWithAsterisk(graphics, ingredient); ClientXeiUtil.renderItemWithAsterisk(graphics, ingredient);
// From end of DrawableIngredient
RenderSystem.disableDepthTest();
} }
} }

View File

@ -1,7 +1,7 @@
package thedarkcolour.exdeorum.compat.jei; package thedarkcolour.exdeorum.compat.jei;
import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.types.IRecipeType;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import thedarkcolour.exdeorum.compat.XeiSieveRecipe; import thedarkcolour.exdeorum.compat.XeiSieveRecipe;
import thedarkcolour.exdeorum.data.TranslationKeys; import thedarkcolour.exdeorum.data.TranslationKeys;
@ -13,7 +13,7 @@ class CompressedSieveCategory extends SieveCategory {
} }
@Override @Override
public RecipeType<XeiSieveRecipe> getRecipeType() { public IRecipeType<XeiSieveRecipe> getRecipeType() {
return ExDeorumJeiPlugin.COMPRESSED_SIEVE; return ExDeorumJeiPlugin.COMPRESSED_SIEVE;
} }
} }

View File

@ -23,17 +23,22 @@ import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.builder.ITooltipBuilder; import mezz.jei.api.gui.builder.ITooltipBuilder;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.inputs.IJeiInputHandler;
import mezz.jei.api.gui.inputs.IJeiUserInput;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder;
import mezz.jei.api.helpers.IJeiHelpers; import mezz.jei.api.helpers.IJeiHelpers;
import mezz.jei.api.helpers.IModIdHelper; import mezz.jei.api.helpers.IModIdHelper;
import mezz.jei.api.recipe.IFocusFactory; import mezz.jei.api.recipe.IFocusFactory;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.recipe.types.IRecipeType;
import mezz.jei.api.runtime.IIngredientManager; import mezz.jei.api.runtime.IIngredientManager;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.navigation.ScreenRectangle;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -44,8 +49,10 @@ import thedarkcolour.exdeorum.registry.EItems;
public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> { public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
private static final Component REQUIRES_CERTAIN_STATE = Component.translatable(TranslationKeys.CROOK_CATEGORY_REQUIRES_STATE).withStyle(ChatFormatting.GRAY); private static final Component REQUIRES_CERTAIN_STATE = Component.translatable(TranslationKeys.CROOK_CATEGORY_REQUIRES_STATE).withStyle(ChatFormatting.GRAY);
private static final int WIDTH = 120;
private static final int HEIGHT = 48;
private static final ScreenRectangle BLOCK_AREA = new ScreenRectangle(12, 10, 32, 32);
private final IDrawable background;
private final IDrawable icon; private final IDrawable icon;
private final IDrawable arrow; private final IDrawable arrow;
private final IDrawable slot; private final IDrawable slot;
@ -59,7 +66,6 @@ public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
public CrookCategory(IJeiHelpers helpers, IDrawable arrow) { public CrookCategory(IJeiHelpers helpers, IDrawable arrow) {
var helper = helpers.getGuiHelper(); var helper = helpers.getGuiHelper();
this.background = helper.createBlankDrawable(120, 48);
this.icon = helper.createDrawableItemStack(new ItemStack(EItems.CROOK.get())); this.icon = helper.createDrawableItemStack(new ItemStack(EItems.CROOK.get()));
this.arrow = arrow; this.arrow = arrow;
this.slot = helper.getSlotDrawable(); this.slot = helper.getSlotDrawable();
@ -71,7 +77,7 @@ public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
} }
@Override @Override
public RecipeType<CrookJeiRecipe> getRecipeType() { public IRecipeType<CrookJeiRecipe> getRecipeType() {
return ExDeorumJeiPlugin.CROOK; return ExDeorumJeiPlugin.CROOK;
} }
@ -81,8 +87,13 @@ public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
} }
@Override @Override
public IDrawable getBackground() { public int getWidth() {
return this.background; return WIDTH;
}
@Override
public int getHeight() {
return HEIGHT;
} }
@Override @Override
@ -93,14 +104,29 @@ public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
@Override @Override
public void setRecipe(IRecipeLayoutBuilder builder, CrookJeiRecipe recipe, IFocusGroup focuses) { public void setRecipe(IRecipeLayoutBuilder builder, CrookJeiRecipe recipe, IFocusGroup focuses) {
recipe.addIngredients(builder); recipe.addIngredients(builder);
builder.addSlot(RecipeIngredientRole.OUTPUT, 80, 18).addItemStack(recipe.result).addRichTooltipCallback((recipeSlotView, tooltip) -> { builder.addSlot(RecipeIngredientRole.OUTPUT, 80, 18).add(recipe.result).addRichTooltipCallback((_, tooltip) -> {
tooltip.add(ClientXeiUtil.formatChance(recipe.chance)); tooltip.add(ClientXeiUtil.formatChance(recipe.chance));
}); });
} }
@Override @Override
public void draw(CrookJeiRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { public void createRecipeExtras(IRecipeExtrasBuilder builder, CrookJeiRecipe recipe, IFocusGroup focuses) {
this.timer.onDraw(); builder.addInputHandler(new IJeiInputHandler() {
@Override
public ScreenRectangle getArea() {
return BLOCK_AREA;
}
@Override
public boolean handleInput(double mouseX, double mouseY, IJeiUserInput input) {
return CrookCategory.this.handleBlockInput(recipe, input);
}
});
}
@Override
public void draw(CrookJeiRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphicsExtractor graphics, double mouseX, double mouseY) {
this.timer.onDraw(Minecraft.getInstance().hasShiftDown());
this.arrow.draw(graphics, 50, 18); this.arrow.draw(graphics, 50, 18);
this.slot.draw(graphics, 79, 17); this.slot.draw(graphics, 79, 17);
@ -126,22 +152,24 @@ public class CrookCategory implements IRecipeCategory<CrookJeiRecipe> {
} }
} }
@Override private boolean handleBlockInput(CrookJeiRecipe recipe, IJeiUserInput input) {
public boolean handleInput(CrookJeiRecipe recipe, double mouseX, double mouseY, InputConstants.Key input) { var key = input.getKey();
if (input.getType() == InputConstants.Type.MOUSE && (input.getValue() == InputConstants.MOUSE_BUTTON_LEFT || input.getValue() == InputConstants.MOUSE_BUTTON_RIGHT)) { if (key.getType() == InputConstants.Type.MOUSE && (key.getValue() == InputConstants.MOUSE_BUTTON_LEFT || key.getValue() == InputConstants.MOUSE_BUTTON_RIGHT)) {
if (12 < mouseX && mouseX < 44 && 10 < mouseY && mouseY < 42) { if (input.isSimulate()) {
var block = this.timer.getCycledItem(recipe.states).getBlock();
ClientJeiUtil.checkTypedIngredient(this.ingredientManager, VanillaTypes.ITEM_STACK, new ItemStack(block.asItem()), ingredient -> {
if (input.getValue() == InputConstants.MOUSE_BUTTON_LEFT) {
ClientJeiUtil.showRecipes(this.focusFactory, ingredient);
} else if (input.getValue() == InputConstants.MOUSE_BUTTON_RIGHT) {
ClientJeiUtil.showUsages(this.focusFactory, ingredient);
}
});
return true; return true;
} }
var block = this.timer.getCycledItem(recipe.states).getBlock();
ClientJeiUtil.checkTypedIngredient(this.ingredientManager, VanillaTypes.ITEM_STACK, new ItemStack(block.asItem()), ingredient -> {
if (key.getValue() == InputConstants.MOUSE_BUTTON_LEFT) {
ClientJeiUtil.showRecipes(this.focusFactory, ingredient);
} else {
ClientJeiUtil.showUsages(this.focusFactory, ingredient);
}
});
return true;
} }
return false; return false;
} }

View File

@ -25,11 +25,12 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ItemStackTemplate;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import org.jetbrains.annotations.Nullable; import org.jspecify.annotations.Nullable;
import thedarkcolour.exdeorum.compat.XeiUtil; import thedarkcolour.exdeorum.compat.XeiUtil;
import thedarkcolour.exdeorum.recipe.BlockPredicate; import thedarkcolour.exdeorum.recipe.BlockPredicate;
import thedarkcolour.exdeorum.recipe.crook.CrookRecipe; import thedarkcolour.exdeorum.recipe.crook.CrookRecipe;
@ -40,10 +41,10 @@ import java.util.List;
public sealed abstract class CrookJeiRecipe { public sealed abstract class CrookJeiRecipe {
public final List<BlockState> states; public final List<BlockState> states;
public ItemStack result; public ItemStackTemplate result;
public float chance; public float chance;
public CrookJeiRecipe(List<BlockState> states, ItemStack result, float chance) { public CrookJeiRecipe(List<BlockState> states, ItemStackTemplate result, float chance) {
this.states = states; this.states = states;
this.result = result; this.result = result;
this.chance = chance; this.chance = chance;
@ -78,7 +79,12 @@ public sealed abstract class CrookJeiRecipe {
private final List<ItemStack> itemIngredients; private final List<ItemStack> itemIngredients;
public final List<Component> requirements; public final List<Component> requirements;
StatesRecipe(@Nullable BlockPredicate.BlockStatePredicate predicate, List<BlockState> states, ItemStack result, float chance) { StatesRecipe(
BlockPredicate.@Nullable BlockStatePredicate predicate,
List<BlockState> states,
ItemStackTemplate result,
float chance
) {
super(states, result, chance); super(states, result, chance);
ImmutableList.Builder<ItemStack> itemIngredients = ImmutableList.builder(); ImmutableList.Builder<ItemStack> itemIngredients = ImmutableList.builder();
@ -112,30 +118,31 @@ public sealed abstract class CrookJeiRecipe {
static final class TagRecipe extends StatesRecipe { static final class TagRecipe extends StatesRecipe {
public final TagKey<Block> tag; public final TagKey<Block> tag;
public TagRecipe(TagKey<Block> tag, List<BlockState> states, ItemStack result, float chance) { public TagRecipe(TagKey<Block> tag, List<BlockState> states, ItemStackTemplate result, float chance) {
super(null, states, result, chance); super(null, states, result, chance);
this.tag = tag; this.tag = tag;
} }
} }
static final class BlockRecipe extends CrookJeiRecipe { static final class BlockRecipe extends CrookJeiRecipe {
private final ItemStack itemIngredient; @Nullable
private final ItemStackTemplate itemIngredient;
BlockRecipe(Block block, ItemStack result, float chance) { BlockRecipe(Block block, ItemStackTemplate result, float chance) {
super(ImmutableList.of(block.defaultBlockState()), result, chance); super(ImmutableList.of(block.defaultBlockState()), result, chance);
var item = block.asItem(); var item = block.asItem();
if (item == Items.AIR) { if (item == Items.AIR) {
this.itemIngredient = ItemStack.EMPTY; this.itemIngredient = null;
} else { } else {
this.itemIngredient = new ItemStack(item); this.itemIngredient = new ItemStackTemplate(item);
} }
} }
@Override @Override
public void addIngredients(IRecipeLayoutBuilder builder) { public void addIngredients(IRecipeLayoutBuilder builder) {
if (!this.itemIngredient.isEmpty()) { if (this.itemIngredient != null) {
builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).addItemStack(this.itemIngredient); builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).add(this.itemIngredient);
} }
} }
} }

View File

@ -21,7 +21,7 @@ package thedarkcolour.exdeorum.compat.jei;
import mezz.jei.api.gui.builder.IRecipeSlotBuilder; import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.types.IRecipeType;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -36,12 +36,12 @@ abstract class CrucibleCategory extends OneToOneCategory<CrucibleRecipe> {
@Override @Override
protected void addInput(IRecipeSlotBuilder slot, CrucibleRecipe recipe) { protected void addInput(IRecipeSlotBuilder slot, CrucibleRecipe recipe) {
slot.addIngredients(recipe.ingredient()); slot.add(recipe.ingredient());
} }
@Override @Override
protected void addOutput(IRecipeSlotBuilder slot, CrucibleRecipe recipe) { protected void addOutput(IRecipeSlotBuilder slot, CrucibleRecipe recipe) {
slot.addFluidStack(recipe.getResult().fluid().value(), recipe.getResult().amount()) slot.add(recipe.getResult().fluid().value(), recipe.getResult().amount())
.setFluidRenderer(Math.max(1000, recipe.getResult().amount()), false, 16, 16); .setFluidRenderer(Math.max(1000, recipe.getResult().amount()), false, 16, 16);
} }
@ -51,7 +51,7 @@ abstract class CrucibleCategory extends OneToOneCategory<CrucibleRecipe> {
} }
@Override @Override
public RecipeType<CrucibleRecipe> getRecipeType() { public IRecipeType<CrucibleRecipe> getRecipeType() {
return ExDeorumJeiPlugin.LAVA_CRUCIBLE; return ExDeorumJeiPlugin.LAVA_CRUCIBLE;
} }
} }
@ -62,7 +62,7 @@ abstract class CrucibleCategory extends OneToOneCategory<CrucibleRecipe> {
} }
@Override @Override
public RecipeType<CrucibleRecipe> getRecipeType() { public IRecipeType<CrucibleRecipe> getRecipeType() {
return ExDeorumJeiPlugin.WATER_CRUCIBLE; return ExDeorumJeiPlugin.WATER_CRUCIBLE;
} }
} }

View File

@ -22,6 +22,8 @@ import mezz.jei.api.ingredients.IIngredientType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
// constructor must be different from field types to make generics happy
@SuppressWarnings("ClassCanBeRecord")
final class CrucibleHeatSourceRecipe { final class CrucibleHeatSourceRecipe {
private final int meltRate; private final int meltRate;
private final BlockState blockState; private final BlockState blockState;

View File

@ -21,18 +21,24 @@ package thedarkcolour.exdeorum.compat.jei;
import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.platform.InputConstants;
import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.builder.ITooltipBuilder;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.inputs.IJeiInputHandler;
import mezz.jei.api.gui.inputs.IJeiUserInput;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder;
import mezz.jei.api.helpers.IJeiHelpers; import mezz.jei.api.helpers.IJeiHelpers;
import mezz.jei.api.helpers.IModIdHelper; import mezz.jei.api.helpers.IModIdHelper;
import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.recipe.IFocusFactory; import mezz.jei.api.recipe.IFocusFactory;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.recipe.types.IRecipeType;
import mezz.jei.api.runtime.IIngredientManager; import mezz.jei.api.runtime.IIngredientManager;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.navigation.ScreenRectangle;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -41,13 +47,11 @@ import thedarkcolour.exdeorum.compat.ClientXeiUtil;
import thedarkcolour.exdeorum.data.TranslationKeys; import thedarkcolour.exdeorum.data.TranslationKeys;
import thedarkcolour.exdeorum.material.DefaultMaterials; import thedarkcolour.exdeorum.material.DefaultMaterials;
import java.util.List;
class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceRecipe> { class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceRecipe> {
public static final int WIDTH = 120; public static final int WIDTH = 120;
public static final int HEIGHT = 48; public static final int HEIGHT = 48;
private static final ScreenRectangle HEAT_SOURCE_AREA = new ScreenRectangle(44, 16, 32, 32);
private final IDrawable background;
private final IDrawable icon; private final IDrawable icon;
private final Component title; private final Component title;
@ -57,7 +61,6 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
public CrucibleHeatSourcesCategory(IJeiHelpers helpers) { public CrucibleHeatSourcesCategory(IJeiHelpers helpers) {
var helper = helpers.getGuiHelper(); var helper = helpers.getGuiHelper();
this.background = helper.createBlankDrawable(WIDTH, HEIGHT);
this.title = Component.translatable(TranslationKeys.CRUCIBLE_HEAT_SOURCE_CATEGORY_TITLE); this.title = Component.translatable(TranslationKeys.CRUCIBLE_HEAT_SOURCE_CATEGORY_TITLE);
this.icon = helper.createDrawableItemStack(new ItemStack(DefaultMaterials.PORCELAIN_CRUCIBLE.getItem())); this.icon = helper.createDrawableItemStack(new ItemStack(DefaultMaterials.PORCELAIN_CRUCIBLE.getItem()));
@ -67,7 +70,7 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
} }
@Override @Override
public RecipeType<CrucibleHeatSourceRecipe> getRecipeType() { public IRecipeType<CrucibleHeatSourceRecipe> getRecipeType() {
return ExDeorumJeiPlugin.CRUCIBLE_HEAT_SOURCES; return ExDeorumJeiPlugin.CRUCIBLE_HEAT_SOURCES;
} }
@ -77,8 +80,13 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
} }
@Override @Override
public IDrawable getBackground() { public int getWidth() {
return this.background; return WIDTH;
}
@Override
public int getHeight() {
return HEIGHT;
} }
@Override @Override
@ -89,61 +97,75 @@ class CrucibleHeatSourcesCategory implements IRecipeCategory<CrucibleHeatSourceR
@Override @Override
public void setRecipe(IRecipeLayoutBuilder builder, CrucibleHeatSourceRecipe recipe, IFocusGroup focuses) { public void setRecipe(IRecipeLayoutBuilder builder, CrucibleHeatSourceRecipe recipe, IFocusGroup focuses) {
if (recipe.ingredientType() != null && recipe.ingredient() != null) { if (recipe.ingredientType() != null && recipe.ingredient() != null) {
builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).addIngredient(recipe.ingredientType(), recipe.ingredient()); builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).add(recipe.ingredientType(), recipe.ingredient());
} else { } else {
builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).addIngredient(VanillaTypes.ITEM_STACK, ItemStack.EMPTY); builder.addInvisibleIngredients(RecipeIngredientRole.INPUT).add(VanillaTypes.ITEM_STACK, ItemStack.EMPTY);
} }
} }
@Override @Override
public void draw(CrucibleHeatSourceRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { public void createRecipeExtras(IRecipeExtrasBuilder builder, CrucibleHeatSourceRecipe recipe, IFocusGroup focuses) {
builder.addInputHandler(new IJeiInputHandler() {
@Override
public ScreenRectangle getArea() {
return HEAT_SOURCE_AREA;
}
@Override
public boolean handleInput(double mouseX, double mouseY, IJeiUserInput input) {
return CrucibleHeatSourcesCategory.this.handleHeatSourceInput(recipe, input);
}
});
}
@Override
public void draw(CrucibleHeatSourceRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphicsExtractor graphics, double mouseX, double mouseY) {
var volume = recipe.meltRate(); var volume = recipe.meltRate();
var volumeLabel = Component.translatable(TranslationKeys.CRUCIBLE_HEAT_SOURCE_CATEGORY_MULTIPLIER, volume); var volumeLabel = Component.translatable(TranslationKeys.CRUCIBLE_HEAT_SOURCE_CATEGORY_MULTIPLIER, volume);
var font = Minecraft.getInstance().font; var font = Minecraft.getInstance().font;
graphics.drawString(font, volumeLabel, 60 - font.width(volumeLabel) / 2, 5, 0xff808080, false); graphics.text(font, volumeLabel, 60 - font.width(volumeLabel) / 2, 5, 0xff808080, false);
ClientXeiUtil.renderBlock(graphics, recipe.blockState(), 60, 24, 10, 20F); ClientXeiUtil.renderBlock(graphics, recipe.blockState(), 60, 24, 10, 20F);
} }
@Override @Override
public List<Component> getTooltipStrings(CrucibleHeatSourceRecipe recipe, IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) { public void getTooltip(ITooltipBuilder tooltip, CrucibleHeatSourceRecipe recipe, IRecipeSlotsView recipeSlotsView, double mouseX, double mouseY) {
if (44.0 < mouseX && mouseX < 76.0 && 16 < mouseY && mouseY < 48) { if (44.0 < mouseX && mouseX < 76.0 && 16 < mouseY && mouseY < 48) {
if (recipe.ingredientType() != null && recipe.ingredient() != null) { if (recipe.ingredientType() != null && recipe.ingredient() != null) {
var tooltip = this.ingredientManager.getIngredientRenderer(recipe.ingredientType()).getTooltip(recipe.ingredient(), Minecraft.getInstance().options.advancedItemTooltips ? TooltipFlag.ADVANCED : TooltipFlag.NORMAL); var tooltipLines = this.ingredientManager.getIngredientRenderer(recipe.ingredientType()).getTooltip(recipe.ingredient(), Minecraft.getInstance().options.advancedItemTooltips ? TooltipFlag.ADVANCED : TooltipFlag.NORMAL);
return this.modIdHelper.addModNameToIngredientTooltip(tooltip, recipe.ingredient(), this.ingredientManager.getIngredientHelper(recipe.ingredientType())); tooltip.addAll(tooltipLines);
this.ingredientManager.createTypedIngredient(recipe.ingredientType(), recipe.ingredient(), false)
.flatMap(this.modIdHelper::getModNameForTooltip)
.ifPresent(tooltip::add);
} else { } else {
var block = recipe.blockState().getBlock(); var block = recipe.blockState().getBlock();
var modId = BuiltInRegistries.BLOCK.getKey(block).getNamespace(); var modId = BuiltInRegistries.BLOCK.getKey(block).getNamespace();
return List.of(Component.translatable(block.getDescriptionId()), Component.literal(this.modIdHelper.getFormattedModNameForModId(modId))); tooltip.add(Component.translatable(block.getDescriptionId()));
tooltip.add(Component.literal(this.modIdHelper.getFormattedModNameForModId(modId)));
} }
} }
return List.of();
} }
@Override private boolean handleHeatSourceInput(CrucibleHeatSourceRecipe recipe, IJeiUserInput input) {
public boolean handleInput(CrucibleHeatSourceRecipe recipe, double mouseX, double mouseY, InputConstants.Key input) { var key = input.getKey();
if (input.getType() == InputConstants.Type.MOUSE && (input.getValue() == InputConstants.MOUSE_BUTTON_LEFT || input.getValue() == InputConstants.MOUSE_BUTTON_RIGHT)) { if (key.getType() == InputConstants.Type.MOUSE && (key.getValue() == InputConstants.MOUSE_BUTTON_LEFT || key.getValue() == InputConstants.MOUSE_BUTTON_RIGHT)) {
if (44.0 < mouseX && mouseX < 76.0 && 16 < mouseY && mouseY < 48) { if (input.isSimulate()) {
if (recipe.ingredientType() != null) {
ClientJeiUtil.checkTypedIngredient(this.ingredientManager, recipe.ingredientType(), recipe.ingredient(), ingredient -> {
if (input.getValue() == InputConstants.MOUSE_BUTTON_LEFT) {
ClientJeiUtil.showRecipes(this.focusFactory, ingredient);
} else if (input.getValue() == InputConstants.MOUSE_BUTTON_RIGHT) {
ClientJeiUtil.showUsages(this.focusFactory, ingredient);
}
});
}
return true; return true;
} }
if (recipe.ingredientType() != null) {
ClientJeiUtil.checkTypedIngredient(this.ingredientManager, recipe.ingredientType(), recipe.ingredient(), ingredient -> {
if (key.getValue() == InputConstants.MOUSE_BUTTON_LEFT) {
ClientJeiUtil.showRecipes(this.focusFactory, ingredient);
} else {
ClientJeiUtil.showUsages(this.focusFactory, ingredient);
}
});
}
return true;
} }
return false; return false;
} }
@Override
public int getHeight() {
return 48;
}
} }

View File

@ -42,8 +42,8 @@ public class CycleTimer {
return list.get(Math.toIntExact(index)); return list.get(Math.toIntExact(index));
} }
public void onDraw() { public void onDraw(boolean hasShiftDown) {
if (!Screen.hasShiftDown()) { if (!hasShiftDown) {
if (pausedDuration > 0) { if (pausedDuration > 0) {
this.startTime += this.pausedDuration; this.startTime += this.pausedDuration;
this.pausedDuration = 0; this.pausedDuration = 0;

View File

@ -25,7 +25,7 @@ import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.handlers.IGuiClickableArea; import mezz.jei.api.gui.handlers.IGuiClickableArea;
import mezz.jei.api.gui.handlers.IGuiContainerHandler; import mezz.jei.api.gui.handlers.IGuiContainerHandler;
import mezz.jei.api.neoforge.NeoForgeTypes; import mezz.jei.api.neoforge.NeoForgeTypes;
import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.types.IRecipeType;
import mezz.jei.api.registration.IGuiHandlerRegistration; import mezz.jei.api.registration.IGuiHandlerRegistration;
import mezz.jei.api.registration.IRecipeCatalystRegistration; import mezz.jei.api.registration.IRecipeCatalystRegistration;
import mezz.jei.api.registration.IRecipeCategoryRegistration; import mezz.jei.api.registration.IRecipeCategoryRegistration;
@ -75,22 +75,22 @@ import java.util.function.Supplier;
public class ExDeorumJeiPlugin implements IModPlugin { public class ExDeorumJeiPlugin implements IModPlugin {
public static final Identifier EX_DEORUM_JEI_TEXTURE = ExDeorum.loc("textures/gui/jei/enr_jei.png"); public static final Identifier EX_DEORUM_JEI_TEXTURE = ExDeorum.loc("textures/gui/jei/enr_jei.png");
static final RecipeType<BarrelCompostRecipe> BARREL_COMPOST = recipeType("barrel_compost", BarrelCompostRecipe.class); static final IRecipeType<BarrelCompostRecipe> BARREL_COMPOST = recipeType("barrel_compost", BarrelCompostRecipe.class);
static final RecipeType<BarrelMixingRecipe> BARREL_MIXING = recipeType("barrel_mixing", BarrelMixingRecipe.class); static final IRecipeType<BarrelMixingRecipe> BARREL_MIXING = recipeType("barrel_mixing", BarrelMixingRecipe.class);
static final RecipeType<BarrelFluidMixingRecipe> BARREL_FLUID_MIXING = recipeType("barrel_fluid_mixing", BarrelFluidMixingRecipe.class); static final IRecipeType<BarrelFluidMixingRecipe> BARREL_FLUID_MIXING = recipeType("barrel_fluid_mixing", BarrelFluidMixingRecipe.class);
static final RecipeType<CrucibleRecipe> LAVA_CRUCIBLE = recipeType("lava_crucible", CrucibleRecipe.class); static final IRecipeType<CrucibleRecipe> LAVA_CRUCIBLE = recipeType("lava_crucible", CrucibleRecipe.class);
static final RecipeType<CrucibleRecipe> WATER_CRUCIBLE = recipeType("water_crucible", CrucibleRecipe.class); static final IRecipeType<CrucibleRecipe> WATER_CRUCIBLE = recipeType("water_crucible", CrucibleRecipe.class);
static final RecipeType<CrucibleHeatSourceRecipe> CRUCIBLE_HEAT_SOURCES = recipeType("crucible_heat_sources", CrucibleHeatSourceRecipe.class); static final IRecipeType<CrucibleHeatSourceRecipe> CRUCIBLE_HEAT_SOURCES = recipeType("crucible_heat_sources", CrucibleHeatSourceRecipe.class);
static final RecipeType<XeiSieveRecipe> SIEVE = recipeType("sieve", XeiSieveRecipe.class); static final IRecipeType<XeiSieveRecipe> SIEVE = recipeType("sieve", XeiSieveRecipe.class);
static final RecipeType<XeiSieveRecipe> COMPRESSED_SIEVE = recipeType("compressed_sieve", XeiSieveRecipe.class); static final IRecipeType<XeiSieveRecipe> COMPRESSED_SIEVE = recipeType("compressed_sieve", XeiSieveRecipe.class);
static final RecipeType<HammerRecipe> HAMMER = recipeType("hammer", HammerRecipe.class); static final IRecipeType<HammerRecipe> HAMMER = recipeType("hammer", HammerRecipe.class);
static final RecipeType<HammerRecipe> COMPRESSED_HAMMER = recipeType("compressed_hammer", CompressedHammerRecipe.class); static final IRecipeType<HammerRecipe> COMPRESSED_HAMMER = recipeType("compressed_hammer", CompressedHammerRecipe.class);
static final RecipeType<CrookJeiRecipe> CROOK = recipeType("crook", CrookJeiRecipe.class); static final IRecipeType<CrookJeiRecipe> CROOK = recipeType("crook", CrookJeiRecipe.class);
private static <T> RecipeType<T> recipeType(String path, Class<? extends T> type) { private static <T> IRecipeType<T> recipeType(String path, Class<? extends T> type) {
// use alternative namespace so that EMI doesn't skip JEI compatibility // use alternative namespace so that EMI doesn't skip JEI compatibility
String namespace = ModList.get().isLoaded(ModIds.EMI) ? ExDeorum.ID + "_" + ModIds.EMI : ExDeorum.ID; String namespace = ModList.get().isLoaded(ModIds.EMI) ? ExDeorum.ID + "_" + ModIds.EMI : ExDeorum.ID;
return RecipeType.create(namespace, path, type); return IRecipeType.create(namespace, path, type);
} }
@Override @Override
@ -127,42 +127,42 @@ public class ExDeorumJeiPlugin implements IModPlugin {
for (var barrel : barrels) { for (var barrel : barrels) {
var stack = new ItemStack(barrel); var stack = new ItemStack(barrel);
registration.addRecipeCatalyst(stack, BARREL_COMPOST); registration.addCraftingStation(BARREL_COMPOST, stack);
registration.addRecipeCatalyst(stack, BARREL_MIXING); registration.addCraftingStation(BARREL_MIXING, stack);
registration.addRecipeCatalyst(stack, BARREL_FLUID_MIXING); registration.addCraftingStation(BARREL_FLUID_MIXING, stack);
} }
for (var lavaCrucible : lavaCrucibles) { for (var lavaCrucible : lavaCrucibles) {
var stack = new ItemStack(lavaCrucible); var stack = new ItemStack(lavaCrucible);
registration.addRecipeCatalyst(stack, LAVA_CRUCIBLE); registration.addCraftingStation(LAVA_CRUCIBLE, stack);
registration.addRecipeCatalyst(stack, CRUCIBLE_HEAT_SOURCES); registration.addCraftingStation(CRUCIBLE_HEAT_SOURCES, stack);
} }
for (var waterCrucible : waterCrucibles) { for (var waterCrucible : waterCrucibles) {
registration.addRecipeCatalyst(new ItemStack(waterCrucible), WATER_CRUCIBLE); registration.addCraftingStation(WATER_CRUCIBLE, new ItemStack(waterCrucible));
} }
for (var sieve : sieves) { for (var sieve : sieves) {
registration.addRecipeCatalyst(new ItemStack(sieve), SIEVE); registration.addCraftingStation(SIEVE, new ItemStack(sieve));
} }
for (var compressedSieve : compressedSieves) { for (var compressedSieve : compressedSieves) {
registration.addRecipeCatalyst(new ItemStack(compressedSieve), COMPRESSED_SIEVE); registration.addCraftingStation(COMPRESSED_SIEVE, new ItemStack(compressedSieve));
} }
registration.addRecipeCatalyst(new ItemStack(EItems.WOODEN_HAMMER.get()), HAMMER); registration.addCraftingStation(HAMMER, new ItemStack(EItems.WOODEN_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.STONE_HAMMER.get()), HAMMER); registration.addCraftingStation(HAMMER, new ItemStack(EItems.STONE_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.GOLDEN_HAMMER.get()), HAMMER); registration.addCraftingStation(HAMMER, new ItemStack(EItems.GOLDEN_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.IRON_HAMMER.get()), HAMMER); registration.addCraftingStation(HAMMER, new ItemStack(EItems.IRON_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.DIAMOND_HAMMER.get()), HAMMER); registration.addCraftingStation(HAMMER, new ItemStack(EItems.DIAMOND_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.NETHERITE_HAMMER.get()), HAMMER); registration.addCraftingStation(HAMMER, new ItemStack(EItems.NETHERITE_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.MECHANICAL_HAMMER.get()), HAMMER); registration.addCraftingStation(HAMMER, new ItemStack(EItems.MECHANICAL_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.COMPRESSED_WOODEN_HAMMER.get()), COMPRESSED_HAMMER); registration.addCraftingStation(COMPRESSED_HAMMER, new ItemStack(EItems.COMPRESSED_WOODEN_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.COMPRESSED_STONE_HAMMER.get()), COMPRESSED_HAMMER); registration.addCraftingStation(COMPRESSED_HAMMER, new ItemStack(EItems.COMPRESSED_STONE_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.COMPRESSED_GOLDEN_HAMMER.get()), COMPRESSED_HAMMER); registration.addCraftingStation(COMPRESSED_HAMMER, new ItemStack(EItems.COMPRESSED_GOLDEN_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.COMPRESSED_IRON_HAMMER.get()), COMPRESSED_HAMMER); registration.addCraftingStation(COMPRESSED_HAMMER, new ItemStack(EItems.COMPRESSED_IRON_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.COMPRESSED_DIAMOND_HAMMER.get()), COMPRESSED_HAMMER); registration.addCraftingStation(COMPRESSED_HAMMER, new ItemStack(EItems.COMPRESSED_DIAMOND_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.COMPRESSED_NETHERITE_HAMMER.get()), COMPRESSED_HAMMER); registration.addCraftingStation(COMPRESSED_HAMMER, new ItemStack(EItems.COMPRESSED_NETHERITE_HAMMER.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.CROOK.get()), CROOK); registration.addCraftingStation(CROOK, new ItemStack(EItems.CROOK.get()));
registration.addRecipeCatalyst(new ItemStack(EItems.BONE_CROOK.get()), CROOK); registration.addCraftingStation(CROOK, new ItemStack(EItems.BONE_CROOK.get()));
} }
@Override @Override
@ -299,7 +299,7 @@ public class ExDeorumJeiPlugin implements IModPlugin {
}); });
} }
private static <C extends RecipeInput, T extends Recipe<C>> void addRecipes(IRecipeRegistration registration, RecipeType<T> category, Supplier<net.minecraft.world.item.crafting.RecipeType<T>> type) { private static <C extends RecipeInput, T extends Recipe<C>> void addRecipes(IRecipeRegistration registration, IRecipeType<T> category, Supplier<net.minecraft.world.item.crafting.RecipeType<T>> type) {
registration.addRecipes(category, CompatUtil.collectAllRecipes(type.get(), Function.identity())); registration.addRecipes(category, CompatUtil.collectAllRecipes(type.get(), Function.identity()));
} }
} }

View File

@ -21,7 +21,7 @@ package thedarkcolour.exdeorum.compat.jei;
import mezz.jei.api.gui.builder.IRecipeSlotBuilder; import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.recipe.types.IRecipeType;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -31,30 +31,30 @@ import thedarkcolour.exdeorum.recipe.hammer.HammerRecipe;
import java.util.function.Supplier; import java.util.function.Supplier;
class HammerCategory extends OneToOneCategory<HammerRecipe> { class HammerCategory extends OneToOneCategory<HammerRecipe> {
private final RecipeType<HammerRecipe> recipeType; private final IRecipeType<HammerRecipe> recipeType;
public HammerCategory(IGuiHelper helper, IDrawable arrow, Supplier<? extends Item> icon, Component title, RecipeType<HammerRecipe> recipeType) { public HammerCategory(IGuiHelper helper, IDrawable arrow, Supplier<? extends Item> icon, Component title, IRecipeType<HammerRecipe> recipeType) {
super(helper, arrow, helper.createDrawableItemStack(new ItemStack(icon.get())), title); super(helper, arrow, helper.createDrawableItemStack(new ItemStack(icon.get())), title);
this.recipeType = recipeType; this.recipeType = recipeType;
} }
@Override @Override
public RecipeType<HammerRecipe> getRecipeType() { public IRecipeType<HammerRecipe> getRecipeType() {
return this.recipeType; return this.recipeType;
} }
@Override @Override
protected void addInput(IRecipeSlotBuilder slot, HammerRecipe recipe) { protected void addInput(IRecipeSlotBuilder slot, HammerRecipe recipe) {
slot.addIngredients(recipe.ingredient()); slot.add(recipe.ingredient());
} }
@Override @Override
protected void addOutput(IRecipeSlotBuilder slot, HammerRecipe recipe) { protected void addOutput(IRecipeSlotBuilder slot, HammerRecipe recipe) {
if (recipe.resultAmount instanceof ConstantValue constant) { if (recipe.resultAmount instanceof ConstantValue(float value)) {
slot.addItemStack(recipe.result.count() == 1 ? recipe.result.create() : recipe.result.withCount((int) constant.value()).create()); slot.add(recipe.result.count() == 1 ? recipe.result.create() : recipe.result.withCount((int) value).create());
} else { } else {
slot.addItemStack(recipe.result.create()); slot.add(recipe.result.create());
SieveCategory.addTooltips(slot, false, recipe.resultAmount); SieveCategory.addTooltips(slot, false, recipe.resultAmount);
} }
} }

View File

@ -10,8 +10,8 @@ class JeiUtil {
} }
public static IRecipeSlotBuilder addFluidIngredient(IRecipeSlotBuilder builder, FluidIngredient ingredient, int amount) { public static IRecipeSlotBuilder addFluidIngredient(IRecipeSlotBuilder builder, FluidIngredient ingredient, int amount) {
for (var stack : ingredient.getStacks()) { for (var fluidHolder : ingredient.fluids()) {
builder.addFluidStack(stack.getFluid(), amount); builder.add(fluidHolder.value(), amount);
} }
return builder; return builder;
} }

View File

@ -26,21 +26,19 @@ import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
abstract class OneToOneCategory<T> implements IRecipeCategory<T> { abstract class OneToOneCategory<T> implements IRecipeCategory<T> {
public static final int WIDTH = 72; public static final int WIDTH = 72;
public static final int HEIGHT = 18; public static final int HEIGHT = 18;
private final IDrawable background;
private final IDrawable arrow; private final IDrawable arrow;
private final IDrawable icon; private final IDrawable icon;
private final IDrawable slot; private final IDrawable slot;
private final Component title; private final Component title;
public OneToOneCategory(IGuiHelper helper, IDrawable arrow, IDrawable icon, Component title) { public OneToOneCategory(IGuiHelper helper, IDrawable arrow, IDrawable icon, Component title) {
this.background = helper.createBlankDrawable(WIDTH, HEIGHT);
this.arrow = arrow; this.arrow = arrow;
this.icon = icon; this.icon = icon;
this.slot = helper.getSlotDrawable(); this.slot = helper.getSlotDrawable();
@ -48,6 +46,7 @@ abstract class OneToOneCategory<T> implements IRecipeCategory<T> {
} }
protected abstract void addInput(IRecipeSlotBuilder slot, T recipe); protected abstract void addInput(IRecipeSlotBuilder slot, T recipe);
protected abstract void addOutput(IRecipeSlotBuilder slot, T recipe); protected abstract void addOutput(IRecipeSlotBuilder slot, T recipe);
@Override @Override
@ -62,8 +61,13 @@ abstract class OneToOneCategory<T> implements IRecipeCategory<T> {
} }
@Override @Override
public IDrawable getBackground() { public int getWidth() {
return this.background; return WIDTH;
}
@Override
public int getHeight() {
return HEIGHT;
} }
@Override @Override
@ -72,7 +76,7 @@ abstract class OneToOneCategory<T> implements IRecipeCategory<T> {
} }
@Override @Override
public void draw(T recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { public void draw(T recipe, IRecipeSlotsView recipeSlotsView, GuiGraphicsExtractor graphics, double mouseX, double mouseY) {
this.slot.draw(graphics); this.slot.draw(graphics);
this.arrow.draw(graphics, 25, 1); this.arrow.draw(graphics, 25, 1);
this.slot.draw(graphics, 54, 0); this.slot.draw(graphics, 54, 0);

View File

@ -26,9 +26,9 @@ import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole; import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory; import mezz.jei.api.recipe.category.IRecipeCategory;
import net.minecraft.client.gui.GuiGraphics; import mezz.jei.api.recipe.types.IRecipeType;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.ItemLike;
@ -59,7 +59,7 @@ class SieveCategory implements IRecipeCategory<XeiSieveRecipe> {
} }
@Override @Override
public RecipeType<XeiSieveRecipe> getRecipeType() { public IRecipeType<XeiSieveRecipe> getRecipeType() {
return ExDeorumJeiPlugin.SIEVE; return ExDeorumJeiPlugin.SIEVE;
} }
@ -85,12 +85,12 @@ class SieveCategory implements IRecipeCategory<XeiSieveRecipe> {
@Override @Override
public void setRecipe(IRecipeLayoutBuilder builder, XeiSieveRecipe recipe, IFocusGroup focuses) { public void setRecipe(IRecipeLayoutBuilder builder, XeiSieveRecipe recipe, IFocusGroup focuses) {
builder.addSlot(RecipeIngredientRole.INPUT, 59, 1).addIngredients(recipe.ingredient()); builder.addSlot(RecipeIngredientRole.INPUT, 59, 1).add(recipe.ingredient());
builder.addSlot(RecipeIngredientRole.CATALYST, 87, 1).addItemStack(recipe.mesh()); builder.addSlot(RecipeIngredientRole.CRAFTING_STATION, 87, 1).add(recipe.mesh());
for (int i = 0; i < recipe.results().size(); i++) { for (int i = 0; i < recipe.results().size(); i++) {
var result = recipe.results().get(i); var result = recipe.results().get(i);
var slot = builder.addSlot(RecipeIngredientRole.OUTPUT, 1 + (i % 9) * 18, 1 + XeiUtil.SIEVE_ROW_START + 18 * (i / 9)).addItemStack(result.item); var slot = builder.addSlot(RecipeIngredientRole.OUTPUT, 1 + (i % 9) * 18, 1 + XeiUtil.SIEVE_ROW_START + 18 * (i / 9)).add(result.item);
addTooltips(slot, result.byHandOnly, result.provider); addTooltips(slot, result.byHandOnly, result.provider);
} }
@ -100,13 +100,13 @@ class SieveCategory implements IRecipeCategory<XeiSieveRecipe> {
if (byHandOnly) { if (byHandOnly) {
slot.setCustomRenderer(VanillaTypes.ITEM_STACK, ClientJeiUtil.AsteriskItemRenderer.INSTANCE); slot.setCustomRenderer(VanillaTypes.ITEM_STACK, ClientJeiUtil.AsteriskItemRenderer.INSTANCE);
} }
slot.addRichTooltipCallback((slotView, tooltip) -> { slot.addRichTooltipCallback((_, tooltip) -> {
XeiUtil.addSieveDropTooltip(byHandOnly, provider, tooltip::add); XeiUtil.addSieveDropTooltip(byHandOnly, provider, tooltip::add);
}); });
} }
@Override @Override
public void draw(XeiSieveRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { public void draw(XeiSieveRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphicsExtractor graphics, double mouseX, double mouseY) {
this.slot.draw(graphics, 58, 0); this.slot.draw(graphics, 58, 0);
this.slot.draw(graphics, 86, 0); this.slot.draw(graphics, 86, 0);

View File

@ -16,5 +16,5 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@javax.annotation.ParametersAreNonnullByDefault @org.jspecify.annotations.NullMarked
package thedarkcolour.exdeorum.compat.jei; package thedarkcolour.exdeorum.compat.jei;