From 720d53fb97919a1312d26f1e310a105c8f1bf73c Mon Sep 17 00:00:00 2001 From: IM23a-cernik Date: Thu, 29 May 2025 23:08:45 +0200 Subject: [PATCH] Added Custom Recipe Support --- .../net/krituximon/stalinium/Stalinium.java | 2 + .../entity/StaliniumPressBlockEntity.java | 39 +++--- .../stalinium/recipe/ModRecipes.java | 31 +++++ .../recipe/StaliniumPressRecipe.java | 115 ++++++++++++++++++ .../recipe/StaliniumPressRecipeInput.java | 24 ++++ .../stalinium_from_stalinium_press.json | 15 +++ 6 files changed, 212 insertions(+), 14 deletions(-) create mode 100644 src/main/java/net/krituximon/stalinium/recipe/ModRecipes.java create mode 100644 src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java create mode 100644 src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipeInput.java create mode 100644 src/main/resources/data/stalinium/recipe/stalinium_from_stalinium_press.json diff --git a/src/main/java/net/krituximon/stalinium/Stalinium.java b/src/main/java/net/krituximon/stalinium/Stalinium.java index 7599d2a..792cdea 100644 --- a/src/main/java/net/krituximon/stalinium/Stalinium.java +++ b/src/main/java/net/krituximon/stalinium/Stalinium.java @@ -7,6 +7,7 @@ import net.krituximon.stalinium.item.ModCreativeModeTabs; import net.krituximon.stalinium.item.ModItems; import net.krituximon.stalinium.particle.BloodParticle; import net.krituximon.stalinium.particle.ModParticles; +import net.krituximon.stalinium.recipe.ModRecipes; import net.krituximon.stalinium.screen.ModMenuTypes; import net.krituximon.stalinium.screen.custom.StaliniumPressScreen; import net.krituximon.stalinium.sound.ModSounds; @@ -57,6 +58,7 @@ public class Stalinium ModParticles.register(modEventBus); ModCreativeModeTabs.register(modEventBus); PlayerLogEvents.register(); + ModRecipes.register(modEventBus); // Register ourselves for server and other game events we are interested in. // Note that this is necessary if and only if we want *this* class (Stalinium) to respond directly to events. 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 0f793d5..a6327f5 100644 --- a/src/main/java/net/krituximon/stalinium/block/entity/StaliniumPressBlockEntity.java +++ b/src/main/java/net/krituximon/stalinium/block/entity/StaliniumPressBlockEntity.java @@ -1,6 +1,9 @@ package net.krituximon.stalinium.block.entity; import net.krituximon.stalinium.item.ModItems; +import net.krituximon.stalinium.recipe.ModRecipes; +import net.krituximon.stalinium.recipe.StaliniumPressRecipe; +import net.krituximon.stalinium.recipe.StaliniumPressRecipeInput; import net.krituximon.stalinium.screen.custom.StaliniumPressMenu; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; @@ -18,6 +21,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.ContainerData; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -25,6 +29,7 @@ import net.neoforged.neoforge.items.ItemStackHandler; import org.jetbrains.annotations.Nullable; import javax.swing.plaf.basic.BasicComboBoxUI; +import java.util.Optional; public class StaliniumPressBlockEntity extends BlockEntity implements MenuProvider { public final ItemStackHandler itemHandler = new ItemStackHandler(4) { @@ -37,10 +42,10 @@ public class StaliniumPressBlockEntity extends BlockEntity implements MenuProvid } }; - public static final int INPUT_SLOT = 0; - public static final int REDSTONE_FUEL_SLOT = 1; - public static final int LAVA_FUEL_SLOT = 2; - public static final int OUTPUT_SLOT = 3; + public static final int INPUT_SLOT = 0; + public static final int REDSTONE_FUEL_SLOT = 1; + public static final int LAVA_FUEL_SLOT = 2; + public static final int OUTPUT_SLOT = 3; protected final ContainerData data; private int progress = 0; @@ -127,11 +132,12 @@ public class StaliniumPressBlockEntity extends BlockEntity implements MenuProvid } private void craftItem() { - itemHandler.extractItem(INPUT_SLOT, 9, false); + Optional> recipe = getCurrentRecipe(); + itemHandler.extractItem(INPUT_SLOT, 9, false); itemHandler.extractItem(REDSTONE_FUEL_SLOT, 1, false); - itemHandler.extractItem(LAVA_FUEL_SLOT, 1, false); + itemHandler.extractItem(LAVA_FUEL_SLOT, 1, false); itemHandler.setStackInSlot(LAVA_FUEL_SLOT, new ItemStack(Items.BUCKET, 1)); - ItemStack out = new ItemStack(ModItems.STALINIUM_INGOT.get(), 1); + ItemStack out = recipe.get().value().output(); itemHandler.setStackInSlot( OUTPUT_SLOT, new ItemStack( @@ -155,17 +161,22 @@ public class StaliniumPressBlockEntity extends BlockEntity implements MenuProvid } private boolean hasRecipe() { - ItemStack in = itemHandler.getStackInSlot(INPUT_SLOT); - ItemStack red = itemHandler.getStackInSlot(REDSTONE_FUEL_SLOT); - ItemStack lava = itemHandler.getStackInSlot(LAVA_FUEL_SLOT); + Optional> recipe = getCurrentRecipe(); + if (recipe.isEmpty()) return false; - if (in.getItem() != ModItems.STALINIUM_NUGGET.get() || in.getCount() < 9) return false; - if (red.getItem() != Items.REDSTONE_BLOCK || red.getCount() < 1) return false; - if (lava.getItem()!= Items.LAVA_BUCKET || lava.getCount()< 1) return false; - ItemStack out = new ItemStack(ModItems.STALINIUM_INGOT.get(), 1); + ItemStack out = recipe.get().value().output(); return canInsertItemIntoOutputSlot(out) && canInsertAmountIntoOutputSlot(out.getCount()); } + 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(LAVA_FUEL_SLOT) + ), level); + } + private boolean canInsertItemIntoOutputSlot(ItemStack output) { return itemHandler.getStackInSlot(OUTPUT_SLOT).isEmpty() || itemHandler.getStackInSlot(OUTPUT_SLOT).getItem() == output.getItem(); diff --git a/src/main/java/net/krituximon/stalinium/recipe/ModRecipes.java b/src/main/java/net/krituximon/stalinium/recipe/ModRecipes.java new file mode 100644 index 0000000..ed9e4b8 --- /dev/null +++ b/src/main/java/net/krituximon/stalinium/recipe/ModRecipes.java @@ -0,0 +1,31 @@ +package net.krituximon.stalinium.recipe; + +import net.krituximon.stalinium.Stalinium; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.RecipeType; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; + +public class ModRecipes { + public static final DeferredRegister> SERIALIZERS = + DeferredRegister.create(Registries.RECIPE_SERIALIZER, Stalinium.MODID); + public static final DeferredRegister> TYPES = + DeferredRegister.create(Registries.RECIPE_TYPE, Stalinium.MODID); + + public static final DeferredHolder, RecipeSerializer> STALINIUM_PRESS_SERIALIZER = + SERIALIZERS.register("stalinium_press", StaliniumPressRecipe.Serializer::new); + public static final DeferredHolder, RecipeType> STALINIUM_PRESS_TYPE = + TYPES.register("stalinium_press", () -> new RecipeType() { + @Override + public String toString() { + return "stalinium_press"; + } + }); + + public static void register(IEventBus eventBus) { + SERIALIZERS.register(eventBus); + TYPES.register(eventBus); + } +} diff --git a/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java b/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java new file mode 100644 index 0000000..a0b5111 --- /dev/null +++ b/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipe.java @@ -0,0 +1,115 @@ +package net.krituximon.stalinium.recipe; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.NonNullList; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.*; +import net.minecraft.world.level.Level; + +/** + * power – ingredient in slot 0 + * nugget – ingredient in slot 1 + * fuel – ingredient in slot 2 + */ +public record StaliniumPressRecipe(NonNullList ingredients, + ItemStack output) implements Recipe { + + /* --------------------------------------------------------------------- */ + /* Convenience accessors – referenced by the codec */ + /* --------------------------------------------------------------------- */ + public Ingredient power() { + return ingredients.get(0); + } + + public Ingredient nugget() { + return ingredients.get(1); + } + + public Ingredient fuel() { + return ingredients.get(2); + } + + /* --------------------------------------------------------------------- */ + /* Recipe implementation */ + /* --------------------------------------------------------------------- */ + @Override + public boolean matches(StaliniumPressRecipeInput input, Level level) { + if (level.isClientSide()) return false; + if (ingredients.size() != 3) return false; // malformed recipe JSON + + return power().test(input.power()) + && nugget().test(input.nugget()) + && fuel().test(input.fuel()); + } + + @Override + public ItemStack assemble(StaliniumPressRecipeInput input, HolderLookup.Provider provider) { + return output.copy(); + } + + @Override + public boolean canCraftInDimensions(int w, int h) { + return true; + } + + @Override + public ItemStack getResultItem(HolderLookup.Provider prov) { + return output; + } + + + @Override + public RecipeSerializer getSerializer() { + return ModRecipes.STALINIUM_PRESS_SERIALIZER.get(); + } + + @Override + public RecipeType getType() { + return ModRecipes.STALINIUM_PRESS_TYPE.get(); + } + + /* --------------------------------------------------------------------- */ + /* Serializer */ + /* --------------------------------------------------------------------- */ + public static class Serializer implements RecipeSerializer { + + /* ---------- 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), + 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); + })); + + /* ---------- Codec used for network sync ---------- */ + private static final StreamCodec STREAM_CODEC = + StreamCodec.composite( + Ingredient.CONTENTS_STREAM_CODEC, StaliniumPressRecipe::power, + Ingredient.CONTENTS_STREAM_CODEC, StaliniumPressRecipe::nugget, + Ingredient.CONTENTS_STREAM_CODEC, StaliniumPressRecipe::fuel, + ItemStack.STREAM_CODEC, StaliniumPressRecipe::output, + (p, n, f, res) -> { + NonNullList list = NonNullList.of(Ingredient.EMPTY, p, n, f); + return new StaliniumPressRecipe(list, res); + } + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public StreamCodec streamCodec() { + return STREAM_CODEC; + } + } +} \ No newline at end of file diff --git a/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipeInput.java b/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipeInput.java new file mode 100644 index 0000000..c73821f --- /dev/null +++ b/src/main/java/net/krituximon/stalinium/recipe/StaliniumPressRecipeInput.java @@ -0,0 +1,24 @@ +package net.krituximon.stalinium.recipe; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeInput; + +public record StaliniumPressRecipeInput(ItemStack power, ItemStack nugget, ItemStack fuel) implements RecipeInput { + @Override + public ItemStack getItem(int i) { + ItemStack var10000 = null; + switch (i) { + case 1 -> var10000 = power; + case 0 -> var10000 = nugget; + case 2 -> var10000 = fuel; + default -> throw new IllegalArgumentException("Recipe does not contain slot " + i); + } + + return var10000; + } + + @Override + public int size() { + return 3; + } +} diff --git a/src/main/resources/data/stalinium/recipe/stalinium_from_stalinium_press.json b/src/main/resources/data/stalinium/recipe/stalinium_from_stalinium_press.json new file mode 100644 index 0000000..9d226d3 --- /dev/null +++ b/src/main/resources/data/stalinium/recipe/stalinium_from_stalinium_press.json @@ -0,0 +1,15 @@ +{ + "type": "stalinium:stalinium_press", + "nugget": { + "item": "stalinium:stalinium_nugget" + }, + "power": { + "item": "minecraft:redstone_block" + }, + "fuel": { + "item": "minecraft:lava_bucket" + }, + "result": { + "id": "stalinium:stalinium_ingot" + } +} \ No newline at end of file