From 39f034b07a7a50ac1101d7d4898c00945b76cb7e Mon Sep 17 00:00:00 2001 From: dudko Date: Sat, 9 Aug 2025 00:41:37 +0200 Subject: [PATCH 1/3] The great BasinRecipe split - add support for custom ProcessingRecipeParams in AbstractBasinRecipe by extending ProcessingRecipe instead of StandardProcessingRecipe - make BasinRecipe extend AbstractBasinRecipe, move most of its functionality - for basic Basin recipes --- .../com/simibubi/create/AllRecipeTypes.java | 13 +- .../api/data/recipe/CompactingRecipeGen.java | 15 +- .../api/data/recipe/MixingRecipeGen.java | 16 +- .../simibubi/create/compat/jei/CreateJEI.java | 102 ++++---- .../fluids/potion/PotionMixingRecipes.java | 14 +- .../processing/basin/AbstractBasinRecipe.java | 222 ++++++++++++++++ .../content/processing/basin/BasinRecipe.java | 245 ++++-------------- .../recipe/ProcessingRecipeParams.java | 2 +- 8 files changed, 356 insertions(+), 273 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java diff --git a/src/main/java/com/simibubi/create/AllRecipeTypes.java b/src/main/java/com/simibubi/create/AllRecipeTypes.java index 481b2785a1..0e3596fe30 100644 --- a/src/main/java/com/simibubi/create/AllRecipeTypes.java +++ b/src/main/java/com/simibubi/create/AllRecipeTypes.java @@ -4,8 +4,6 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import com.simibubi.create.content.kinetics.deployer.ItemApplicationRecipeParams; - import org.jetbrains.annotations.ApiStatus.Internal; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -20,6 +18,7 @@ import com.simibubi.create.content.kinetics.crusher.CrushingRecipe; import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe; import com.simibubi.create.content.kinetics.deployer.ItemApplicationRecipe; +import com.simibubi.create.content.kinetics.deployer.ItemApplicationRecipeParams; import com.simibubi.create.content.kinetics.deployer.ManualApplicationRecipe; import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe; import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe; @@ -60,9 +59,9 @@ public enum AllRecipeTypes implements IRecipeTypeInfo, StringRepresentable { CRUSHING(CrushingRecipe::new), CUTTING(CuttingRecipe::new), MILLING(MillingRecipe::new), - BASIN(BasinRecipe::new), - MIXING(MixingRecipe::new), - COMPACTING(CompactingRecipe::new), + BASIN(() -> new BasinRecipe.Serializer<>(BasinRecipe::new)), + MIXING(() -> new BasinRecipe.Serializer<>(MixingRecipe::new)), + COMPACTING(() -> new BasinRecipe.Serializer<>(CompactingRecipe::new)), PRESSING(PressingRecipe::new), SANDPAPER_POLISHING(SandPaperPolishingRecipe::new), SPLASHING(SplashingRecipe::new), @@ -79,8 +78,8 @@ public enum AllRecipeTypes implements IRecipeTypeInfo, StringRepresentable { ITEM_COPYING(() -> new SimpleCraftingRecipeSerializer<>(ItemCopyingRecipe::new), () -> RecipeType.CRAFTING, false); public static final Predicate> CAN_BE_AUTOMATED = r -> !r.id() - .getPath() - .endsWith("_manual_only"); + .getPath() + .endsWith("_manual_only"); public final ResourceLocation id; public final Supplier> serializerSupplier; diff --git a/src/main/java/com/simibubi/create/api/data/recipe/CompactingRecipeGen.java b/src/main/java/com/simibubi/create/api/data/recipe/CompactingRecipeGen.java index 4f15e37f9e..8a979c2756 100644 --- a/src/main/java/com/simibubi/create/api/data/recipe/CompactingRecipeGen.java +++ b/src/main/java/com/simibubi/create/api/data/recipe/CompactingRecipeGen.java @@ -3,11 +3,14 @@ import java.util.concurrent.CompletableFuture; import com.simibubi.create.AllRecipeTypes; - import com.simibubi.create.content.kinetics.mixer.CompactingRecipe; +import com.simibubi.create.content.processing.basin.BasinRecipe; +import com.simibubi.create.content.processing.basin.BasinRecipe.Builder; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeParams; import net.minecraft.core.HolderLookup; import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceLocation; /** * The base class for Compacting recipe generation. @@ -16,7 +19,7 @@ * For an example of how you might do this, see Create's implementation: {@link com.simibubi.create.foundation.data.recipe.CreateCompactingRecipeGen}. * Needs to be added to a registered recipe provider to do anything, see {@link com.simibubi.create.foundation.data.recipe.CreateRecipeProvider} */ -public abstract class CompactingRecipeGen extends StandardProcessingRecipeGen { +public abstract class CompactingRecipeGen extends ProcessingRecipeGen> { public CompactingRecipeGen(PackOutput output, CompletableFuture registries, String defaultNamespace) { super(output, registries, defaultNamespace); @@ -27,4 +30,12 @@ protected AllRecipeTypes getRecipeType() { return AllRecipeTypes.COMPACTING; } + protected BasinRecipe.Serializer getSerializer() { + return getRecipeType().getSerializer(); + } + + @Override + protected Builder getBuilder(ResourceLocation id) { + return new BasinRecipe.Builder<>(getSerializer().factory(), id); + } } diff --git a/src/main/java/com/simibubi/create/api/data/recipe/MixingRecipeGen.java b/src/main/java/com/simibubi/create/api/data/recipe/MixingRecipeGen.java index 3bb479a9cb..808c472347 100644 --- a/src/main/java/com/simibubi/create/api/data/recipe/MixingRecipeGen.java +++ b/src/main/java/com/simibubi/create/api/data/recipe/MixingRecipeGen.java @@ -3,10 +3,14 @@ import java.util.concurrent.CompletableFuture; import com.simibubi.create.AllRecipeTypes; - import com.simibubi.create.content.kinetics.mixer.MixingRecipe; +import com.simibubi.create.content.processing.basin.BasinRecipe; +import com.simibubi.create.content.processing.basin.BasinRecipe.Builder; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeParams; + import net.minecraft.core.HolderLookup; import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceLocation; /** * The base class for Mixing recipe generation. @@ -15,7 +19,7 @@ * For an example of how you might do this, see Create's implementation: {@link com.simibubi.create.foundation.data.recipe.CreateMixingRecipeGen}. * Needs to be added to a registered recipe provider to do anything, see {@link com.simibubi.create.foundation.data.recipe.CreateRecipeProvider} */ -public abstract class MixingRecipeGen extends StandardProcessingRecipeGen { +public abstract class MixingRecipeGen extends ProcessingRecipeGen> { public MixingRecipeGen(PackOutput output, CompletableFuture registries, String defaultNamespace) { super(output, registries, defaultNamespace); @@ -26,4 +30,12 @@ protected AllRecipeTypes getRecipeType() { return AllRecipeTypes.MIXING; } + protected BasinRecipe.Serializer getSerializer() { + return getRecipeType().getSerializer(); + } + + @Override + protected Builder getBuilder(ResourceLocation id) { + return new BasinRecipe.Builder<>(getSerializer().factory(), id); + } } diff --git a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java index 74e4a5142d..1889739bcc 100644 --- a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java +++ b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java @@ -2,14 +2,11 @@ import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Consumer; -import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.Supplier; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; @@ -68,16 +65,12 @@ import com.simibubi.create.foundation.data.recipe.LogStrippingFakeRecipes; import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen; import com.simibubi.create.foundation.item.ItemHelper; -import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; -import com.simibubi.create.foundation.utility.CreateLang; import com.simibubi.create.foundation.utility.RecipeGenericsUtil; import com.simibubi.create.infrastructure.config.AllConfigs; -import com.simibubi.create.infrastructure.config.CRecipes; import mezz.jei.api.IModPlugin; import mezz.jei.api.JeiPlugin; import mezz.jei.api.constants.RecipeTypes; -import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.helpers.IPlatformFluidHelper; import mezz.jei.api.neoforge.NeoForgeTypes; import mezz.jei.api.recipe.category.IRecipeCategory; @@ -90,7 +83,6 @@ import mezz.jei.api.registration.ISubtypeRegistration; import mezz.jei.api.runtime.IIngredientManager; import mezz.jei.api.runtime.IJeiRuntime; -import net.createmod.catnip.config.ConfigBase.ConfigBool; import net.minecraft.client.Minecraft; import net.minecraft.core.Holder; import net.minecraft.core.Holder.Reference; @@ -110,8 +102,8 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.item.crafting.SmokingRecipe; -import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.Blocks; + import net.neoforged.neoforge.fluids.FluidStack; @JeiPlugin @@ -131,14 +123,14 @@ private void loadCategories() { CreateRecipeCategory - milling = builder(AbstractCrushingRecipe.class) - .addTypedRecipes(AllRecipeTypes.MILLING) - .catalyst(AllBlocks.MILLSTONE::get) - .doubleItemIcon(AllBlocks.MILLSTONE.get(), AllItems.WHEAT_FLOUR.get()) - .emptyBackground(177, 53) - .build("milling", MillingCategory::new), + milling = builder(AbstractCrushingRecipe.class) + .addTypedRecipes(AllRecipeTypes.MILLING) + .catalyst(AllBlocks.MILLSTONE::get) + .doubleItemIcon(AllBlocks.MILLSTONE.get(), AllItems.WHEAT_FLOUR.get()) + .emptyBackground(177, 53) + .build("milling", MillingCategory::new), - crushing = builder(AbstractCrushingRecipe.class) + crushing = builder(AbstractCrushingRecipe.class) .addTypedRecipes(AllRecipeTypes.CRUSHING) .addTypedRecipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType) .catalyst(AllBlocks.CRUSHING_WHEEL::get) @@ -146,21 +138,21 @@ private void loadCategories() { .emptyBackground(177, 100) .build("crushing", CrushingCategory::new), - pressing = builder(PressingRecipe.class) + pressing = builder(PressingRecipe.class) .addTypedRecipes(AllRecipeTypes.PRESSING) .catalyst(AllBlocks.MECHANICAL_PRESS::get) .doubleItemIcon(AllBlocks.MECHANICAL_PRESS.get(), AllItems.IRON_SHEET.get()) .emptyBackground(177, 70) .build("pressing", PressingCategory::new), - washing = builder(SplashingRecipe.class) + washing = builder(SplashingRecipe.class) .addTypedRecipes(AllRecipeTypes.SPLASHING) .catalystStack(ProcessingViaFanCategory.getFan("fan_washing")) .doubleItemIcon(AllItems.PROPELLER.get(), Items.WATER_BUCKET) .emptyBackground(178, 72) .build("fan_washing", FanWashingCategory::new), - smoking = builder(SmokingRecipe.class) + smoking = builder(SmokingRecipe.class) .addTypedRecipes(() -> RecipeType.SMOKING) .removeNonAutomation() .catalystStack(ProcessingViaFanCategory.getFan("fan_smoking")) @@ -168,7 +160,7 @@ private void loadCategories() { .emptyBackground(178, 72) .build("fan_smoking", FanSmokingCategory::new), - blasting = builder(AbstractCookingRecipe.class) + blasting = builder(AbstractCookingRecipe.class) .addTypedRecipesExcluding(() -> RecipeType.SMELTING, () -> RecipeType.BLASTING) .addTypedRecipes(() -> RecipeType.BLASTING) .removeRecipes(() -> RecipeType.SMOKING) @@ -178,14 +170,14 @@ private void loadCategories() { .emptyBackground(178, 72) .build("fan_blasting", FanBlastingCategory::new), - haunting = builder(HauntingRecipe.class) + haunting = builder(HauntingRecipe.class) .addTypedRecipes(AllRecipeTypes.HAUNTING) .catalystStack(ProcessingViaFanCategory.getFan("fan_haunting")) .doubleItemIcon(AllItems.PROPELLER.get(), Items.SOUL_CAMPFIRE) .emptyBackground(178, 72) .build("fan_haunting", FanHauntingCategory::new), - mixing = builder(BasinRecipe.class) + mixing = builder(BasinRecipe.class) .addTypedRecipes(AllRecipeTypes.MIXING) .catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.BASIN::get) @@ -193,20 +185,20 @@ private void loadCategories() { .emptyBackground(177, 103) .build("mixing", MixingCategory::standard), - autoShapeless = builder(BasinRecipe.class) + autoShapeless = builder(BasinRecipe.class) .enableWhen(AllConfigs.server().recipes.allowShapelessInMixer) .addAllRecipesIf(r -> r.value() instanceof CraftingRecipe && !(r.value() instanceof ShapedRecipe) - && r.value().getIngredients() - .size() > 1 - && !MechanicalPressBlockEntity.canCompress(r.value()) && !AllRecipeTypes.shouldIgnoreInAutomation(r), - BasinRecipe::convertShapeless) + && r.value().getIngredients() + .size() > 1 + && !MechanicalPressBlockEntity.canCompress(r.value()) && !AllRecipeTypes.shouldIgnoreInAutomation(r), + BasinRecipe::convertShapeless) .catalyst(AllBlocks.MECHANICAL_MIXER::get) .catalyst(AllBlocks.BASIN::get) .doubleItemIcon(AllBlocks.MECHANICAL_MIXER.get(), Items.CRAFTING_TABLE) .emptyBackground(177, 85) .build("automatic_shapeless", MixingCategory::autoShapeless), - brewing = builder(BasinRecipe.class) + brewing = builder(BasinRecipe.class) .enableWhen(AllConfigs.server().recipes.allowBrewingInMixer) .addRecipes(() -> RecipeGenericsUtil.cast(PotionMixingRecipes.createRecipes(Minecraft.getInstance().level))) .catalyst(AllBlocks.MECHANICAL_MIXER::get) @@ -215,7 +207,7 @@ private void loadCategories() { .emptyBackground(177, 103) .build("automatic_brewing", MixingCategory::autoBrewing), - packing = builder(BasinRecipe.class) + packing = builder(BasinRecipe.class) .addTypedRecipes(AllRecipeTypes.COMPACTING) .catalyst(AllBlocks.MECHANICAL_PRESS::get) .catalyst(AllBlocks.BASIN::get) @@ -223,26 +215,26 @@ private void loadCategories() { .emptyBackground(177, 103) .build("packing", PackingCategory::standard), - autoSquare = builder(BasinRecipe.class) + autoSquare = builder(BasinRecipe.class) .enableWhen(AllConfigs.server().recipes.allowShapedSquareInPress) .addAllRecipesIf( - r -> (r.value() instanceof CraftingRecipe) && !(r.value() instanceof MechanicalCraftingRecipe) - && MechanicalPressBlockEntity.canCompress(r.value()) && !AllRecipeTypes.shouldIgnoreInAutomation(r), - BasinRecipe::convertShapeless) + r -> (r.value() instanceof CraftingRecipe) && !(r.value() instanceof MechanicalCraftingRecipe) + && MechanicalPressBlockEntity.canCompress(r.value()) && !AllRecipeTypes.shouldIgnoreInAutomation(r), + BasinRecipe::convertShapeless) .catalyst(AllBlocks.MECHANICAL_PRESS::get) .catalyst(AllBlocks.BASIN::get) .doubleItemIcon(AllBlocks.MECHANICAL_PRESS.get(), Blocks.CRAFTING_TABLE) .emptyBackground(177, 85) .build("automatic_packing", PackingCategory::autoSquare), - sawing = builder(CuttingRecipe.class) + sawing = builder(CuttingRecipe.class) .addTypedRecipes(AllRecipeTypes.CUTTING) .catalyst(AllBlocks.MECHANICAL_SAW::get) .doubleItemIcon(AllBlocks.MECHANICAL_SAW.get(), Items.OAK_LOG) .emptyBackground(177, 70) .build("sawing", SawingCategory::new), - blockCutting = builder(CondensedBlockCuttingRecipe.class) + blockCutting = builder(CondensedBlockCuttingRecipe.class) .enableWhen(AllConfigs.server().recipes.allowStonecuttingOnSaw) .addRecipes(() -> BlockCuttingCategory.condenseRecipes(getTypedRecipesExcluding(RecipeType.STONECUTTING, AllRecipeTypes::shouldIgnoreInAutomation))) .catalyst(AllBlocks.MECHANICAL_SAW::get) @@ -250,7 +242,7 @@ private void loadCategories() { .emptyBackground(177, 70) .build("block_cutting", BlockCuttingCategory::new), - polishing = builder(SandPaperPolishingRecipe.class) + polishing = builder(SandPaperPolishingRecipe.class) .addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING) .catalyst(AllItems.SAND_PAPER::get) .catalyst(AllItems.RED_SAND_PAPER::get) @@ -258,14 +250,14 @@ private void loadCategories() { .emptyBackground(177, 55) .build("sandpaper_polishing", PolishingCategory::new), - item_application = builder(ItemApplicationRecipe.class) + item_application = builder(ItemApplicationRecipe.class) .addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION) .addRecipes(() -> RecipeGenericsUtil.cast(LogStrippingFakeRecipes.createRecipes())) .itemIcon(AllItems.BRASS_HAND.get()) .emptyBackground(177, 60) .build("item_application", ItemApplicationCategory::new), - deploying = builder(DeployerApplicationRecipe.class) + deploying = builder(DeployerApplicationRecipe.class) .addTypedRecipes(AllRecipeTypes.DEPLOYING) .addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING::getType, DeployerApplicationRecipe::convert) .addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION::getType, ManualApplicationRecipe::asDeploying) @@ -277,7 +269,7 @@ private void loadCategories() { .emptyBackground(177, 70) .build("deploying", DeployingCategory::new), - spoutFilling = builder(FillingRecipe.class) + spoutFilling = builder(FillingRecipe.class) .addTypedRecipes(AllRecipeTypes.FILLING) .addRecipeListConsumer(recipes -> SpoutCategory.consumeRecipes(recipes::add, ingredientManager)) .catalyst(AllBlocks.SPOUT::get) @@ -285,7 +277,7 @@ private void loadCategories() { .emptyBackground(177, 70) .build("spout_filling", SpoutCategory::new), - draining = builder(EmptyingRecipe.class) + draining = builder(EmptyingRecipe.class) .addRecipeListConsumer(recipes -> ItemDrainCategory.consumeRecipes(recipes::add, ingredientManager)) .addTypedRecipes(AllRecipeTypes.EMPTYING) .catalyst(AllBlocks.ITEM_DRAIN::get) @@ -293,33 +285,33 @@ private void loadCategories() { .emptyBackground(177, 50) .build("draining", ItemDrainCategory::new), - autoShaped = builder(CraftingRecipe.class) + autoShaped = builder(CraftingRecipe.class) .enableWhen(AllConfigs.server().recipes.allowRegularCraftingInCrafter) .addAllRecipesIf(r -> r.value() instanceof CraftingRecipe && !(r.value() instanceof ShapedRecipe) - && r.value().getIngredients() - .size() == 1 - && !AllRecipeTypes.shouldIgnoreInAutomation(r)) + && r.value().getIngredients() + .size() == 1 + && !AllRecipeTypes.shouldIgnoreInAutomation(r)) .addTypedRecipesIf(() -> RecipeType.CRAFTING, - recipe -> recipe.value() instanceof ShapedRecipe && !AllRecipeTypes.shouldIgnoreInAutomation(recipe)) + recipe -> recipe.value() instanceof ShapedRecipe && !AllRecipeTypes.shouldIgnoreInAutomation(recipe)) .catalyst(AllBlocks.MECHANICAL_CRAFTER::get) .itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()) .emptyBackground(177, 107) .build("automatic_shaped", MechanicalCraftingCategory::new), - mechanicalCrafting = builder(CraftingRecipe.class) + mechanicalCrafting = builder(CraftingRecipe.class) .addTypedRecipes(AllRecipeTypes.MECHANICAL_CRAFTING) .catalyst(AllBlocks.MECHANICAL_CRAFTER::get) .itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()) .emptyBackground(177, 107) .build("mechanical_crafting", MechanicalCraftingCategory::new), - seqAssembly = builder(SequencedAssemblyRecipe.class) + seqAssembly = builder(SequencedAssemblyRecipe.class) .addTypedRecipes(AllRecipeTypes.SEQUENCED_ASSEMBLY) .itemIcon(AllItems.PRECISION_MECHANISM.get()) .emptyBackground(180, 115) .build("sequenced_assembly", SequencedAssemblyCategory::new), - mysteryConversion = builder(ConversionRecipe.class) + mysteryConversion = builder(ConversionRecipe.class) .addRecipes(() -> MysteriousItemConversionCategory.RECIPES) .itemIcon(AllBlocks.PECULIAR_BELL.get()) .emptyBackground(177, 50) @@ -403,7 +395,7 @@ public void registerExtraIngredients(IExtraIngredientRegistration registration) registration.addExtraIngredients(NeoForgeTypes.FLUID_STACK, potionFluids); } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public void registerGuiHandlers(IGuiHandlerRegistration registration) { registration.addGenericGuiContainerHandler(AbstractSimiContainerScreen.class, new SlotMover()); @@ -462,7 +454,7 @@ public static boolean doInputsMatch(Recipe recipe1, Recipe recipe2) { if (recipe1.getIngredients() .isEmpty() || recipe2.getIngredients() - .isEmpty()) { + .isEmpty()) { return false; } ItemStack[] matchingStacks = recipe1.getIngredients() @@ -472,8 +464,8 @@ public static boolean doInputsMatch(Recipe recipe1, Recipe recipe2) { return false; } return recipe2.getIngredients() - .getFirst() - .test(matchingStacks[0]); + .getFirst() + .test(matchingStacks[0]); } public static boolean doOutputsMatch(Recipe recipe1, Recipe recipe2) { @@ -482,8 +474,8 @@ public static boolean doOutputsMatch(Recipe recipe1, Recipe recipe2) { } @Override - public void onRuntimeAvailable(IJeiRuntime runtime) { - CreateJEI.runtime = runtime; - } + public void onRuntimeAvailable(IJeiRuntime runtime) { + CreateJEI.runtime = runtime; + } } diff --git a/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java b/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java index b38022e680..b1b275759c 100644 --- a/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java +++ b/src/main/java/com/simibubi/create/content/fluids/potion/PotionMixingRecipes.java @@ -10,8 +10,8 @@ import com.simibubi.create.Create; import com.simibubi.create.content.fluids.potion.PotionFluid.BottleType; import com.simibubi.create.content.kinetics.mixer.MixingRecipe; +import com.simibubi.create.content.processing.basin.BasinRecipe.Builder; import com.simibubi.create.content.processing.recipe.HeatCondition; -import com.simibubi.create.content.processing.recipe.StandardProcessingRecipe.Builder; import com.simibubi.create.foundation.fluid.FluidIngredient; import com.simibubi.create.foundation.mixin.accessor.PotionBrewingAccessor; @@ -127,7 +127,7 @@ private static List> createRecipesImpl(Level level) { for (ItemStack stack : supportedContainerStacks) { if (input.test(stack)) { ItemStack[] stacks = input.getItems(); - if (stacks.length == 0){ + if (stacks.length == 0) { continue; } FluidStack inputFluid = PotionFluidHandler.getFluidFromPotionItem(stacks[0]); @@ -148,11 +148,11 @@ private static List> createRecipesImpl(Level level) { private static RecipeHolder createRecipe(String id, Ingredient ingredient, FluidStack fromFluid, FluidStack toFluid) { ResourceLocation recipeId = Create.asResource(id); MixingRecipe recipe = new Builder<>(MixingRecipe::new, recipeId) - .require(ingredient) - .require(FluidIngredient.fromFluidStack(fromFluid)) - .output(toFluid) - .requiresHeat(HeatCondition.HEATED) - .build(); + .require(ingredient) + .require(FluidIngredient.fromFluidStack(fromFluid)) + .output(toFluid) + .requiresHeat(HeatCondition.HEATED) + .build(); return new RecipeHolder<>(recipeId, recipe); } diff --git a/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java b/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java new file mode 100644 index 0000000000..f5235e448b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java @@ -0,0 +1,222 @@ +package com.simibubi.create.content.processing.basin; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import javax.annotation.Nonnull; + +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel; +import com.simibubi.create.content.processing.recipe.ProcessingRecipe; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeParams; +import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment; +import com.simibubi.create.foundation.fluid.FluidIngredient; +import com.simibubi.create.foundation.recipe.DummyCraftingContainer; +import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; + +import net.createmod.catnip.data.Iterate; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeInput; +import net.minecraft.world.level.Level; + +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.capability.IFluidHandler; +import net.neoforged.neoforge.items.IItemHandler; + +public abstract class AbstractBasinRecipe

extends ProcessingRecipe { + + public static boolean match(BasinBlockEntity basin, Recipe recipe) { + FilteringBehaviour filter = basin.getFilter(); + if (filter == null) + return false; + + boolean filterTest = filter.test(recipe.getResultItem(basin.getLevel() + .registryAccess())); + if (recipe instanceof AbstractBasinRecipe basinRecipe) { + if (basinRecipe.getRollableResults() + .isEmpty() + && !basinRecipe.getFluidResults() + .isEmpty()) + filterTest = filter.test(basinRecipe.getFluidResults() + .get(0)); + } + + if (!filterTest) + return false; + + return apply(basin, recipe, true); + } + + public static boolean apply(BasinBlockEntity basin, Recipe recipe) { + return apply(basin, recipe, false); + } + + private static boolean apply(BasinBlockEntity basin, Recipe recipe, boolean test) { + boolean isBasinRecipe = recipe instanceof AbstractBasinRecipe; + IItemHandler availableItems = basin.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, basin.getBlockPos(), null); + IFluidHandler availableFluids = basin.getLevel().getCapability(Capabilities.FluidHandler.BLOCK, basin.getBlockPos(), null); + + if (availableItems == null || availableFluids == null) + return false; + + HeatLevel heat = BasinBlockEntity.getHeatLevelOf(basin.getLevel() + .getBlockState(basin.getBlockPos() + .below(1))); + if (isBasinRecipe && !((AbstractBasinRecipe) recipe).getRequiredHeat() + .testBlazeBurner(heat)) + return false; + + List recipeOutputItems = new ArrayList<>(); + List recipeOutputFluids = new ArrayList<>(); + + List ingredients = new LinkedList<>(recipe.getIngredients()); + List fluidIngredients = + isBasinRecipe ? ((AbstractBasinRecipe) recipe).getFluidIngredients() : Collections.emptyList(); + + for (boolean simulate : Iterate.trueAndFalse) { + + if (!simulate && test) + return true; + + int[] extractedItemsFromSlot = new int[availableItems.getSlots()]; + int[] extractedFluidsFromTank = new int[availableFluids.getTanks()]; + + Ingredients: + for (Ingredient ingredient : ingredients) { + for (int slot = 0; slot < availableItems.getSlots(); slot++) { + if (simulate && availableItems.getStackInSlot(slot) + .getCount() <= extractedItemsFromSlot[slot]) + continue; + ItemStack extracted = availableItems.extractItem(slot, 1, true); + if (!ingredient.test(extracted)) + continue; + if (!simulate) + availableItems.extractItem(slot, 1, false); + extractedItemsFromSlot[slot]++; + continue Ingredients; + } + + // something wasn't found + return false; + } + + boolean fluidsAffected = false; + FluidIngredients: + for (FluidIngredient fluidIngredient : fluidIngredients) { + int amountRequired = fluidIngredient.getRequiredAmount(); + + for (int tank = 0; tank < availableFluids.getTanks(); tank++) { + FluidStack fluidStack = availableFluids.getFluidInTank(tank); + if (simulate && fluidStack.getAmount() <= extractedFluidsFromTank[tank]) + continue; + if (!fluidIngredient.test(fluidStack)) + continue; + int drainedAmount = Math.min(amountRequired, fluidStack.getAmount()); + if (!simulate) { + fluidStack.shrink(drainedAmount); + fluidsAffected = true; + } + amountRequired -= drainedAmount; + if (amountRequired != 0) + continue; + extractedFluidsFromTank[tank] += drainedAmount; + continue FluidIngredients; + } + + // something wasn't found + return false; + } + + if (fluidsAffected) { + basin.getBehaviour(SmartFluidTankBehaviour.INPUT) + .forEach(TankSegment::onFluidStackChanged); + basin.getBehaviour(SmartFluidTankBehaviour.OUTPUT) + .forEach(TankSegment::onFluidStackChanged); + } + + if (simulate) { + CraftingInput remainderInput = new DummyCraftingContainer(availableItems, extractedItemsFromSlot) + .asCraftInput(); + + if (recipe instanceof AbstractBasinRecipe basinRecipe) { + recipeOutputItems.addAll(basinRecipe.rollResults()); + + for (FluidStack fluidStack : basinRecipe.getFluidResults()) + if (!fluidStack.isEmpty()) + recipeOutputFluids.add(fluidStack); + for (ItemStack stack : basinRecipe.getRemainingItems(remainderInput)) + if (!stack.isEmpty()) + recipeOutputItems.add(stack); + + } else { + recipeOutputItems.add(recipe.getResultItem(basin.getLevel() + .registryAccess())); + + if (recipe instanceof CraftingRecipe craftingRecipe) { + for (ItemStack stack : craftingRecipe.getRemainingItems(remainderInput)) + if (!stack.isEmpty()) + recipeOutputItems.add(stack); + } + } + } + + if (!basin.acceptOutputs(recipeOutputItems, recipeOutputFluids, simulate)) + return false; + } + + return true; + } + + protected AbstractBasinRecipe(IRecipeTypeInfo type, P params) { + super(type, params); + } + + public AbstractBasinRecipe(P params) { + this(AllRecipeTypes.BASIN, params); + } + + @Override + protected int getMaxInputCount() { + return 64; + } + + @Override + protected int getMaxOutputCount() { + return 4; + } + + @Override + protected int getMaxFluidInputCount() { + return 2; + } + + @Override + protected int getMaxFluidOutputCount() { + return 2; + } + + @Override + protected boolean canRequireHeat() { + return true; + } + + @Override + protected boolean canSpecifyDuration() { + return true; + } + + @Override + public boolean matches(RecipeInput input, @Nonnull Level worldIn) { + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java index 556c62b533..aaeff3b03b 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java @@ -1,181 +1,27 @@ package com.simibubi.create.content.processing.basin; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import javax.annotation.Nonnull; - -import com.simibubi.create.AllRecipeTypes; -import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel; +import com.mojang.serialization.MapCodec; +import com.simibubi.create.content.processing.recipe.ProcessingRecipe; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder; import com.simibubi.create.content.processing.recipe.ProcessingRecipeParams; -import com.simibubi.create.content.processing.recipe.StandardProcessingRecipe; -import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour; -import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment; -import com.simibubi.create.foundation.fluid.FluidIngredient; -import com.simibubi.create.foundation.recipe.DummyCraftingContainer; import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; -import net.createmod.catnip.data.Iterate; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.client.Minecraft; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.CraftingInput; -import net.minecraft.world.item.crafting.CraftingRecipe; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.crafting.RecipeHolder; -import net.minecraft.world.item.crafting.RecipeInput; -import net.minecraft.world.level.Level; - -import net.neoforged.neoforge.capabilities.Capabilities; -import net.neoforged.neoforge.fluids.FluidStack; -import net.neoforged.neoforge.fluids.capability.IFluidHandler; -import net.neoforged.neoforge.items.IItemHandler; - -public class BasinRecipe extends StandardProcessingRecipe { - - public static boolean match(BasinBlockEntity basin, Recipe recipe) { - FilteringBehaviour filter = basin.getFilter(); - if (filter == null) - return false; - - boolean filterTest = filter.test(recipe.getResultItem(basin.getLevel() - .registryAccess())); - if (recipe instanceof BasinRecipe basinRecipe) { - if (basinRecipe.getRollableResults() - .isEmpty() - && !basinRecipe.getFluidResults() - .isEmpty()) - filterTest = filter.test(basinRecipe.getFluidResults() - .get(0)); - } +import net.minecraft.world.item.crafting.RecipeSerializer; - if (!filterTest) - return false; +public class BasinRecipe extends AbstractBasinRecipe { - return apply(basin, recipe, true); - } - - public static boolean apply(BasinBlockEntity basin, Recipe recipe) { - return apply(basin, recipe, false); + protected BasinRecipe(IRecipeTypeInfo type, ProcessingRecipeParams params) { + super(type, params); } - private static boolean apply(BasinBlockEntity basin, Recipe recipe, boolean test) { - boolean isBasinRecipe = recipe instanceof BasinRecipe; - IItemHandler availableItems = basin.getLevel().getCapability(Capabilities.ItemHandler.BLOCK, basin.getBlockPos(), null); - IFluidHandler availableFluids = basin.getLevel().getCapability(Capabilities.FluidHandler.BLOCK, basin.getBlockPos(), null); - - if (availableItems == null || availableFluids == null) - return false; - - HeatLevel heat = BasinBlockEntity.getHeatLevelOf(basin.getLevel() - .getBlockState(basin.getBlockPos() - .below(1))); - if (isBasinRecipe && !((BasinRecipe) recipe).getRequiredHeat() - .testBlazeBurner(heat)) - return false; - - List recipeOutputItems = new ArrayList<>(); - List recipeOutputFluids = new ArrayList<>(); - - List ingredients = new LinkedList<>(recipe.getIngredients()); - List fluidIngredients = - isBasinRecipe ? ((BasinRecipe) recipe).getFluidIngredients() : Collections.emptyList(); - - for (boolean simulate : Iterate.trueAndFalse) { - - if (!simulate && test) - return true; - - int[] extractedItemsFromSlot = new int[availableItems.getSlots()]; - int[] extractedFluidsFromTank = new int[availableFluids.getTanks()]; - - Ingredients: - for (Ingredient ingredient : ingredients) { - for (int slot = 0; slot < availableItems.getSlots(); slot++) { - if (simulate && availableItems.getStackInSlot(slot) - .getCount() <= extractedItemsFromSlot[slot]) - continue; - ItemStack extracted = availableItems.extractItem(slot, 1, true); - if (!ingredient.test(extracted)) - continue; - if (!simulate) - availableItems.extractItem(slot, 1, false); - extractedItemsFromSlot[slot]++; - continue Ingredients; - } - - // something wasn't found - return false; - } - - boolean fluidsAffected = false; - FluidIngredients: - for (FluidIngredient fluidIngredient : fluidIngredients) { - int amountRequired = fluidIngredient.getRequiredAmount(); - - for (int tank = 0; tank < availableFluids.getTanks(); tank++) { - FluidStack fluidStack = availableFluids.getFluidInTank(tank); - if (simulate && fluidStack.getAmount() <= extractedFluidsFromTank[tank]) - continue; - if (!fluidIngredient.test(fluidStack)) - continue; - int drainedAmount = Math.min(amountRequired, fluidStack.getAmount()); - if (!simulate) { - fluidStack.shrink(drainedAmount); - fluidsAffected = true; - } - amountRequired -= drainedAmount; - if (amountRequired != 0) - continue; - extractedFluidsFromTank[tank] += drainedAmount; - continue FluidIngredients; - } - - // something wasn't found - return false; - } - - if (fluidsAffected) { - basin.getBehaviour(SmartFluidTankBehaviour.INPUT) - .forEach(TankSegment::onFluidStackChanged); - basin.getBehaviour(SmartFluidTankBehaviour.OUTPUT) - .forEach(TankSegment::onFluidStackChanged); - } - - if (simulate) { - CraftingInput remainderInput = new DummyCraftingContainer(availableItems, extractedItemsFromSlot) - .asCraftInput(); - - if (recipe instanceof BasinRecipe basinRecipe) { - recipeOutputItems.addAll(basinRecipe.rollResults()); - - for (FluidStack fluidStack : basinRecipe.getFluidResults()) - if (!fluidStack.isEmpty()) - recipeOutputFluids.add(fluidStack); - for (ItemStack stack : basinRecipe.getRemainingItems(remainderInput)) - if (!stack.isEmpty()) - recipeOutputItems.add(stack); - - } else { - recipeOutputItems.add(recipe.getResultItem(basin.getLevel() - .registryAccess())); - - if (recipe instanceof CraftingRecipe craftingRecipe) { - for (ItemStack stack : craftingRecipe.getRemainingItems(remainderInput)) - if (!stack.isEmpty()) - recipeOutputItems.add(stack); - } - } - } - - if (!basin.acceptOutputs(recipeOutputItems, recipeOutputFluids, simulate)) - return false; - } - - return true; + public BasinRecipe(ProcessingRecipeParams params) { + super(params); } public static RecipeHolder convertShapeless(RecipeHolder recipe) { @@ -186,47 +32,48 @@ public static RecipeHolder convertShapeless(RecipeHolder recipe) return new RecipeHolder<>(recipe.id(), basinRecipe); } - protected BasinRecipe(IRecipeTypeInfo type, ProcessingRecipeParams params) { - super(type, params); - } + public static class Builder extends ProcessingRecipeBuilder> { - public BasinRecipe(ProcessingRecipeParams params) { - this(AllRecipeTypes.BASIN, params); - } + public Builder(ProcessingRecipe.Factory factory, ResourceLocation recipeId) { + super(factory, recipeId); + } - @Override - protected int getMaxInputCount() { - return 64; - } + @Override + protected ProcessingRecipeParams createParams() { + return new ProcessingRecipeParams(); + } - @Override - protected int getMaxOutputCount() { - return 4; + @Override + public Builder self() { + return this; + } } - @Override - protected int getMaxFluidInputCount() { - return 2; - } + @MethodsReturnNonnullByDefault + public static class Serializer implements RecipeSerializer { + private final ProcessingRecipe.Factory factory; + private final MapCodec codec; + private final StreamCodec streamCodec; - @Override - protected int getMaxFluidOutputCount() { - return 2; - } + public Serializer(ProcessingRecipe.Factory factory) { + this.factory = factory; + this.codec = ProcessingRecipe.codec(factory, ProcessingRecipeParams.CODEC); + this.streamCodec = ProcessingRecipe.streamCodec(factory, ProcessingRecipeParams.STREAM_CODEC); + } - @Override - protected boolean canRequireHeat() { - return true; - } + @Override + public MapCodec codec() { + return codec; + } - @Override - protected boolean canSpecifyDuration() { - return true; - } + @Override + public StreamCodec streamCodec() { + return streamCodec; + } - @Override - public boolean matches(RecipeInput input, @Nonnull Level worldIn) { - return false; + public ProcessingRecipe.Factory factory() { + return factory; + } } } diff --git a/src/main/java/com/simibubi/create/content/processing/recipe/ProcessingRecipeParams.java b/src/main/java/com/simibubi/create/content/processing/recipe/ProcessingRecipeParams.java index f51465f40c..77f145823b 100644 --- a/src/main/java/com/simibubi/create/content/processing/recipe/ProcessingRecipeParams.java +++ b/src/main/java/com/simibubi/create/content/processing/recipe/ProcessingRecipeParams.java @@ -30,7 +30,7 @@ public class ProcessingRecipeParams { protected int processingDuration; protected HeatCondition requiredHeat; - protected ProcessingRecipeParams() { + public ProcessingRecipeParams() { ingredients = NonNullList.create(); results = NonNullList.create(); fluidIngredients = NonNullList.create(); From 1836c1008f0776398842eeffac2b0109a7d5f61d Mon Sep 17 00:00:00 2001 From: dudko <45921058+dudek26@users.noreply.github.com> Date: Sat, 9 Aug 2025 10:50:16 +0200 Subject: [PATCH 2/3] The greater BasinRecipe split - add type parameter to BasinCategory (JEI) - move basin recipe type definition to BasinRecipe --- .../compat/jei/category/BasinCategory.java | 35 +++++++++---------- .../compat/jei/category/MixingCategory.java | 7 ++-- .../compat/jei/category/PackingCategory.java | 19 +++++----- .../processing/basin/AbstractBasinRecipe.java | 6 +--- .../content/processing/basin/BasinRecipe.java | 3 +- 5 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java index 65e88096f1..11bb31e1f0 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java @@ -9,7 +9,7 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; -import com.simibubi.create.content.processing.basin.BasinRecipe; +import com.simibubi.create.content.processing.basin.AbstractBasinRecipe; import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.content.processing.recipe.HeatCondition; import com.simibubi.create.content.processing.recipe.ProcessingOutput; @@ -20,7 +20,6 @@ import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; -import mezz.jei.api.neoforge.NeoForgeTypes; import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.RecipeIngredientRole; import net.createmod.catnip.data.Pair; @@ -32,17 +31,17 @@ import net.neoforged.neoforge.fluids.FluidStack; @ParametersAreNonnullByDefault -public class BasinCategory extends CreateRecipeCategory { +public class BasinCategory> extends CreateRecipeCategory { private final boolean needsHeating; - public BasinCategory(Info info, boolean needsHeating) { + public BasinCategory(Info info, boolean needsHeating) { super(info); this.needsHeating = needsHeating; } @Override - public void setRecipe(IRecipeLayoutBuilder builder, BasinRecipe recipe, IFocusGroup focuses) { + public void setRecipe(IRecipeLayoutBuilder builder, R recipe, IFocusGroup focuses) { List> condensedIngredients = ItemHelper.condenseIngredients(recipe.getIngredients()); int size = condensedIngredients.size() + recipe.getFluidIngredients().size(); @@ -58,9 +57,9 @@ public void setRecipe(IRecipeLayoutBuilder builder, BasinRecipe recipe, IFocusGr } builder - .addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19) - .setBackground(getRenderedSlot(), -1, -1) - .addItemStacks(stacks); + .addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19) + .setBackground(getRenderedSlot(), -1, -1) + .addItemStacks(stacks); i++; } for (FluidIngredient fluidIngredient : recipe.getFluidIngredients()) { @@ -78,10 +77,10 @@ public void setRecipe(IRecipeLayoutBuilder builder, BasinRecipe recipe, IFocusGr int yPosition = -19 * (i / 2) + 51; builder - .addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition) - .setBackground(getRenderedSlot(result), -1, -1) - .addItemStack(result.getStack()) - .addRichTooltipCallback(addStochasticTooltip(result)); + .addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition) + .setBackground(getRenderedSlot(result), -1, -1) + .addItemStack(result.getStack()) + .addRichTooltipCallback(addStochasticTooltip(result)); i++; } @@ -95,18 +94,18 @@ public void setRecipe(IRecipeLayoutBuilder builder, BasinRecipe recipe, IFocusGr HeatCondition requiredHeat = recipe.getRequiredHeat(); if (!requiredHeat.testBlazeBurner(HeatLevel.NONE)) { builder - .addSlot(RecipeIngredientRole.RENDER_ONLY, 134, 81) - .addItemStack(AllBlocks.BLAZE_BURNER.asStack()); + .addSlot(RecipeIngredientRole.RENDER_ONLY, 134, 81) + .addItemStack(AllBlocks.BLAZE_BURNER.asStack()); } if (!requiredHeat.testBlazeBurner(HeatLevel.KINDLED)) { builder - .addSlot(RecipeIngredientRole.CATALYST, 153, 81) - .addItemStack(AllItems.BLAZE_CAKE.asStack()); + .addSlot(RecipeIngredientRole.CATALYST, 153, 81) + .addItemStack(AllItems.BLAZE_CAKE.asStack()); } } @Override - public void draw(BasinRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { + public void draw(R recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) { HeatCondition requiredHeat = recipe.getRequiredHeat(); boolean noHeat = requiredHeat == HeatCondition.NONE; @@ -125,7 +124,7 @@ public void draw(BasinRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphi AllGuiTextures heatBar = noHeat ? AllGuiTextures.JEI_NO_HEAT_BAR : AllGuiTextures.JEI_HEAT_BAR; heatBar.render(graphics, 4, 80); graphics.drawString(Minecraft.getInstance().font, CreateLang.translateDirect(requiredHeat.getTranslationKey()), 9, - 86, requiredHeat.getColor(), false); + 86, requiredHeat.getColor(), false); } } diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java index 2c8c621fb4..849cdf5048 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java @@ -1,16 +1,17 @@ package com.simibubi.create.compat.jei.category; +import javax.annotation.ParametersAreNonnullByDefault; + import com.simibubi.create.compat.jei.category.animations.AnimatedBlazeBurner; import com.simibubi.create.compat.jei.category.animations.AnimatedMixer; import com.simibubi.create.content.processing.basin.BasinRecipe; import com.simibubi.create.content.processing.recipe.HeatCondition; + import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import net.minecraft.client.gui.GuiGraphics; -import javax.annotation.ParametersAreNonnullByDefault; - @ParametersAreNonnullByDefault -public class MixingCategory extends BasinCategory { +public class MixingCategory extends BasinCategory { private final AnimatedMixer mixer = new AnimatedMixer(); private final AnimatedBlazeBurner heater = new AnimatedBlazeBurner(); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java index 1b207bf247..1a39b594ac 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java @@ -1,10 +1,13 @@ package com.simibubi.create.compat.jei.category; +import javax.annotation.ParametersAreNonnullByDefault; + import com.simibubi.create.compat.jei.category.animations.AnimatedBlazeBurner; import com.simibubi.create.compat.jei.category.animations.AnimatedPress; import com.simibubi.create.content.processing.basin.BasinRecipe; import com.simibubi.create.content.processing.recipe.HeatCondition; import com.simibubi.create.foundation.gui.AllGuiTextures; + import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; import mezz.jei.api.gui.ingredient.IRecipeSlotsView; import mezz.jei.api.recipe.IFocusGroup; @@ -13,10 +16,8 @@ import net.minecraft.core.NonNullList; import net.minecraft.world.item.crafting.Ingredient; -import javax.annotation.ParametersAreNonnullByDefault; - @ParametersAreNonnullByDefault -public class PackingCategory extends BasinCategory { +public class PackingCategory extends BasinCategory { private final AnimatedPress press = new AnimatedPress(true); private final AnimatedBlazeBurner heater = new AnimatedBlazeBurner(); @@ -53,17 +54,17 @@ public void setRecipe(IRecipeLayoutBuilder builder, BasinRecipe recipe, IFocusGr while (i < size) { Ingredient ingredient = ingredients.get(i); builder - .addSlot(RecipeIngredientRole.INPUT, (rows == 2 ? 27 : 18) + (i % rows) * 19, 51 - (i / rows) * 19) - .setBackground(getRenderedSlot(), -1, -1) - .addIngredients(ingredient); + .addSlot(RecipeIngredientRole.INPUT, (rows == 2 ? 27 : 18) + (i % rows) * 19, 51 - (i / rows) * 19) + .setBackground(getRenderedSlot(), -1, -1) + .addIngredients(ingredient); i++; } builder - .addSlot(RecipeIngredientRole.OUTPUT, 142, 51) - .setBackground(getRenderedSlot(), -1, -1) - .addItemStack(getResultItem(recipe)); + .addSlot(RecipeIngredientRole.OUTPUT, 142, 51) + .setBackground(getRenderedSlot(), -1, -1) + .addItemStack(getResultItem(recipe)); } @Override diff --git a/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java b/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java index f5235e448b..5d639941c0 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java @@ -7,7 +7,6 @@ import javax.annotation.Nonnull; -import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.content.processing.recipe.ProcessingRecipe; import com.simibubi.create.content.processing.recipe.ProcessingRecipeParams; @@ -47,7 +46,7 @@ public static boolean match(BasinBlockEntity basin, Recipe recipe) { && !basinRecipe.getFluidResults() .isEmpty()) filterTest = filter.test(basinRecipe.getFluidResults() - .get(0)); + .getFirst()); } if (!filterTest) @@ -180,9 +179,6 @@ protected AbstractBasinRecipe(IRecipeTypeInfo type, P params) { super(type, params); } - public AbstractBasinRecipe(P params) { - this(AllRecipeTypes.BASIN, params); - } @Override protected int getMaxInputCount() { diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java index aaeff3b03b..67745f92f0 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.processing.basin; import com.mojang.serialization.MapCodec; +import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.processing.recipe.ProcessingRecipe; import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder; import com.simibubi.create.content.processing.recipe.ProcessingRecipeParams; @@ -21,7 +22,7 @@ protected BasinRecipe(IRecipeTypeInfo type, ProcessingRecipeParams params) { } public BasinRecipe(ProcessingRecipeParams params) { - super(params); + super(AllRecipeTypes.BASIN, params); } public static RecipeHolder convertShapeless(RecipeHolder recipe) { From 6812ce1748d4582cb1a0c9b1be6b194aba534705 Mon Sep 17 00:00:00 2001 From: dudko <45921058+dudek26@users.noreply.github.com> Date: Wed, 17 Sep 2025 17:21:01 +0200 Subject: [PATCH 3/3] Post-merge fixes --- .../content/processing/basin/AbstractBasinRecipe.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java b/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java index 5d639941c0..4bd4dd16b0 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/AbstractBasinRecipe.java @@ -5,7 +5,7 @@ import java.util.LinkedList; import java.util.List; -import javax.annotation.Nonnull; +import org.jetbrains.annotations.NotNull; import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.content.processing.recipe.ProcessingRecipe; @@ -67,9 +67,7 @@ private static boolean apply(BasinBlockEntity basin, Recipe recipe, boolean t if (availableItems == null || availableFluids == null) return false; - HeatLevel heat = BasinBlockEntity.getHeatLevelOf(basin.getLevel() - .getBlockState(basin.getBlockPos() - .below(1))); + HeatLevel heat = basin.getHeatLevel(); if (isBasinRecipe && !((AbstractBasinRecipe) recipe).getRequiredHeat() .testBlazeBurner(heat)) return false; @@ -147,7 +145,7 @@ private static boolean apply(BasinBlockEntity basin, Recipe recipe, boolean t .asCraftInput(); if (recipe instanceof AbstractBasinRecipe basinRecipe) { - recipeOutputItems.addAll(basinRecipe.rollResults()); + recipeOutputItems.addAll(basinRecipe.rollResults(basin.getLevel().random)); for (FluidStack fluidStack : basinRecipe.getFluidResults()) if (!fluidStack.isEmpty()) @@ -211,7 +209,7 @@ protected boolean canSpecifyDuration() { } @Override - public boolean matches(RecipeInput input, @Nonnull Level worldIn) { + public boolean matches(RecipeInput input, @NotNull Level worldIn) { return false; }