diff --git a/build.gradle b/build.gradle index 4501170..73e8d24 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,16 @@ group = mod_group_id repositories { mavenLocal() + maven { + // location of the maven that hosts JEI files since January 2023 + name = "Jared's maven" + url = "https://maven.blamejared.com/" + } + maven { + // location of a maven mirror for JEI files, as a fallback + name = "ModMaven" + url = "https://modmaven.dev" + } } base { @@ -123,6 +133,11 @@ dependencies { // We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it // localRuntime "mezz.jei:jei-${mc_version}-neoforge:${jei_version}" + // compile against the JEI API but do not include it at runtime + compileOnly("mezz.jei:jei-${minecraft_version}-neoforge-api:${jei_version}") + // at runtime, use the full JEI jar for NeoForge + runtimeOnly("mezz.jei:jei-${minecraft_version}-neoforge:${jei_version}") + // Example mod dependency using a mod jar from ./libs with a flat dir repository // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar // The group id is ignored when searching -- in this case, it is "blank" diff --git a/gradle.properties b/gradle.properties index 6554403..821fbf0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,6 +24,8 @@ neo_version_range=[21.1.148,) # The loader version range can only use the major version of FML as bounds loader_version_range=[1,) +jei_version=19.21.1.305 + ## Mod Properties # The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} @@ -34,7 +36,7 @@ mod_name=Stalinium # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=0.0.18 +mod_version=0.0.19 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/net/krituximon/stalinium/block/entity/StaliniumPressBlockEntity.java b/src/main/java/net/krituximon/stalinium/block/entity/StaliniumPressBlockEntity.java index a6327f5..92911a7 100644 --- a/src/main/java/net/krituximon/stalinium/block/entity/StaliniumPressBlockEntity.java +++ b/src/main/java/net/krituximon/stalinium/block/entity/StaliniumPressBlockEntity.java @@ -171,8 +171,8 @@ public class StaliniumPressBlockEntity extends BlockEntity implements MenuProvid private Optional> getCurrentRecipe() { return this.level.getRecipeManager() .getRecipeFor(ModRecipes.STALINIUM_PRESS_TYPE.get(), new StaliniumPressRecipeInput( - itemHandler.getStackInSlot(INPUT_SLOT), itemHandler.getStackInSlot(REDSTONE_FUEL_SLOT), + itemHandler.getStackInSlot(INPUT_SLOT), itemHandler.getStackInSlot(LAVA_FUEL_SLOT) ), level); } diff --git a/src/main/java/net/krituximon/stalinium/compat/JEIStaliniumPlugin.java b/src/main/java/net/krituximon/stalinium/compat/JEIStaliniumPlugin.java new file mode 100644 index 0000000..5167e48 --- /dev/null +++ b/src/main/java/net/krituximon/stalinium/compat/JEIStaliniumPlugin.java @@ -0,0 +1,55 @@ +package net.krituximon.stalinium.compat; + +import mezz.jei.api.IModPlugin; +import mezz.jei.api.JeiPlugin; +import mezz.jei.api.registration.IGuiHandlerRegistration; +import mezz.jei.api.registration.IRecipeCatalystRegistration; +import mezz.jei.api.registration.IRecipeCategoryRegistration; +import mezz.jei.api.registration.IRecipeRegistration; +import net.krituximon.stalinium.Stalinium; +import net.krituximon.stalinium.block.ModBlocks; +import net.krituximon.stalinium.recipe.ModRecipes; +import net.krituximon.stalinium.recipe.StaliniumPressRecipe; +import net.krituximon.stalinium.screen.custom.StaliniumPressScreen; +import net.minecraft.client.Minecraft; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeManager; + +import java.util.List; + +@JeiPlugin +public class JEIStaliniumPlugin implements IModPlugin { + @Override + public ResourceLocation getPluginUid() { + return ResourceLocation.fromNamespaceAndPath(Stalinium.MODID, "jei_plugin"); + } + + @Override + public void registerCategories(IRecipeCategoryRegistration registration) { + registration.addRecipeCategories(new StaliniumPressRecipeCategory( + registration.getJeiHelpers().getGuiHelper())); + } + + @Override + public void registerRecipes(IRecipeRegistration registration) { + RecipeManager recipeManager = Minecraft.getInstance().level.getRecipeManager(); + + List staliniumPressRecipes = recipeManager + .getAllRecipesFor(ModRecipes.STALINIUM_PRESS_TYPE.get()).stream().map(RecipeHolder::value).toList(); + registration.addRecipes(StaliniumPressRecipeCategory.STALINIUM_PRESS_RECIPE_RECIPE_TYPE, staliniumPressRecipes); + } + + @Override + public void registerGuiHandlers(IGuiHandlerRegistration registration) { + registration.addRecipeClickArea(StaliniumPressScreen.class, 74, 30, 22, 20, + StaliniumPressRecipeCategory.STALINIUM_PRESS_RECIPE_RECIPE_TYPE); + } + + @Override + public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { + registration.addRecipeCatalyst(new ItemStack(ModBlocks.STALINIUM_PRESS.get().asItem()), + StaliniumPressRecipeCategory.STALINIUM_PRESS_RECIPE_RECIPE_TYPE); + } +} diff --git a/src/main/java/net/krituximon/stalinium/compat/StaliniumPressRecipeCategory.java b/src/main/java/net/krituximon/stalinium/compat/StaliniumPressRecipeCategory.java new file mode 100644 index 0000000..9b7cd8d --- /dev/null +++ b/src/main/java/net/krituximon/stalinium/compat/StaliniumPressRecipeCategory.java @@ -0,0 +1,93 @@ +package net.krituximon.stalinium.compat; + +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.recipe.IFocusGroup; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.category.IRecipeCategory; +import net.krituximon.stalinium.Stalinium; +import net.krituximon.stalinium.block.ModBlocks; +import net.krituximon.stalinium.recipe.StaliniumPressRecipe; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; + +public class StaliniumPressRecipeCategory implements IRecipeCategory { + + public static final ResourceLocation UID = ResourceLocation.fromNamespaceAndPath(Stalinium.MODID, "stalinium_chamber"); + public static final ResourceLocation TEXTURE = + ResourceLocation.fromNamespaceAndPath(Stalinium.MODID, "textures/gui/stalinium_press_gui.png"); + + public static final RecipeType STALINIUM_PRESS_RECIPE_RECIPE_TYPE = + new RecipeType<>(UID, StaliniumPressRecipe.class); + + private final IDrawable background; + private final IDrawable icon; + + /* --------------------------------------------------------------------- */ + /* GUI layout constants */ + /* --------------------------------------------------------------------- */ + private static final int[][] INPUT_SLOT_POSITIONS = { + {54, 34}, + {54, 14}, + {54, 54} + }; + private static final int OUTPUT_X = 104; + private static final int OUTPUT_Y = 34; + + public StaliniumPressRecipeCategory(IGuiHelper helper) { + this.background = helper.createDrawable(TEXTURE, 0, 0, 176, 85); + this.icon = helper.createDrawableIngredient(VanillaTypes.ITEM_STACK, new ItemStack(ModBlocks.STALINIUM_PRESS)); + } + + @Override + public RecipeType getRecipeType() { + return STALINIUM_PRESS_RECIPE_RECIPE_TYPE; + } + + @Override + public Component getTitle() { + return Component.translatable("block.stalinium.stalinium_press"); + } + + @Override + public @Nullable IDrawable getIcon() { + return icon; + } + + @Override + public IDrawable getBackground() { + return background; + } + + @Override + public void setRecipe(IRecipeLayoutBuilder builder, + StaliniumPressRecipe recipe, + IFocusGroup focuses) { + + // -------------------- INPUT SLOTS -------------------- + var ingredients = recipe.getIngredients(); + int slotCount = Math.min(ingredients.size(), INPUT_SLOT_POSITIONS.length); + + for (int i = 0; i < slotCount; i++) { + int x = INPUT_SLOT_POSITIONS[i][0]; + int y = INPUT_SLOT_POSITIONS[i][1]; + builder.addSlot(RecipeIngredientRole.INPUT, x, y) + .addIngredients(ingredients.get(i)); + } + + // -------------------- OUTPUT SLOT -------------------- + var output = recipe.getResultItem( + net.minecraft.client.Minecraft.getInstance() + .level + .registryAccess()); // <- real registry + builder.addSlot(RecipeIngredientRole.OUTPUT, OUTPUT_X, OUTPUT_Y) + .addItemStack(output); +} +} \ No newline at end of file diff --git a/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java b/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java index a0b5111..92b8b50 100644 --- a/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java +++ b/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java @@ -36,6 +36,12 @@ public record StaliniumPressRecipe(NonNullList ingredients, /* --------------------------------------------------------------------- */ /* Recipe implementation */ /* --------------------------------------------------------------------- */ + + @Override + public NonNullList getIngredients() { // <-- add this + return ingredients; + } + @Override public boolean matches(StaliniumPressRecipeInput input, Level level) { if (level.isClientSide()) return false; @@ -80,15 +86,17 @@ public record StaliniumPressRecipe(NonNullList ingredients, /* ---------- Codec used for JSON files ---------- */ public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group( - Ingredient.CODEC_NONEMPTY.fieldOf("nugget").forGetter(StaliniumPressRecipe::nugget), - Ingredient.CODEC_NONEMPTY.fieldOf("power").forGetter(StaliniumPressRecipe::power), - Ingredient.CODEC_NONEMPTY.fieldOf("fuel").forGetter(StaliniumPressRecipe::fuel), + Ingredient.CODEC_NONEMPTY.fieldOf("nugget").forGetter(r -> r.nugget()), + Ingredient.CODEC_NONEMPTY.fieldOf("power").forGetter(r -> r.power()), + Ingredient.CODEC_NONEMPTY.fieldOf("fuel").forGetter(r -> r.fuel()), ItemStack.CODEC.fieldOf("result").forGetter(StaliniumPressRecipe::output) - ).apply(inst, (p, n, f, res) -> { - NonNullList list = NonNullList.of(Ingredient.EMPTY, p, n, f); - return new StaliniumPressRecipe(list, res); + ).apply(inst, (nugget, power, fuel, result) -> { + NonNullList list = NonNullList.of(Ingredient.EMPTY, + power, nugget, fuel); // keep the slot order you want in JEI + return new StaliniumPressRecipe(list, result); })); + /* ---------- Codec used for network sync ---------- */ private static final StreamCodec STREAM_CODEC = StreamCodec.composite(