diff --git a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch b/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch index e1cbdae41d..f33bac52e3 100644 --- a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch +++ b/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch @@ -1,14 +1,23 @@ --- a/net/minecraft/world/item/crafting/RecipeManager.java +++ b/net/minecraft/world/item/crafting/RecipeManager.java -@@ -260,6 +_,11 @@ +@@ -69,7 +_,7 @@ + protected RecipeMap prepare(ResourceManager p_379845_, ProfilerFiller p_380058_) { + SortedMap> sortedmap = new TreeMap<>(); + SimpleJsonResourceReloadListener.scanDirectory( +- p_379845_, Registries.elementsDirPath(Registries.RECIPE), this.registries.createSerializationContext(JsonOps.INSTANCE), Recipe.CODEC, sortedmap ++ p_379845_, Registries.elementsDirPath(Registries.RECIPE), new net.neoforged.neoforge.common.conditions.ConditionalOps<>(this.registries.createSerializationContext(JsonOps.INSTANCE), getContext()), Recipe.CODEC, sortedmap // Neo: add condition context + ); + List> list = new ArrayList<>(sortedmap.size()); + sortedmap.forEach((p_379232_, p_379233_) -> { +@@ -258,6 +_,11 @@ + return p_380850_ -> p_380850_.getType() == p_381108_ && p_380850_ instanceof SingleItemRecipe singleitemrecipe + ? Optional.of(singleitemrecipe.input()) : Optional.empty(); - } - ++ } ++ + // Neo: expose recipe map + public RecipeMap recipeMap() { + return this.recipes; -+ } -+ - public interface CachedCheck> { - Optional> getRecipeFor(I p_344938_, ServerLevel p_379487_); } + + public interface CachedCheck> { diff --git a/tests/src/generated/resources/data/neotests_test_conditional_recipe/advancement/recipes/misc/always_disabled_recipe.json b/tests/src/generated/resources/data/neotests_test_conditional_recipe/advancement/recipes/misc/always_disabled_recipe.json new file mode 100644 index 0000000000..e13d7504ae --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_conditional_recipe/advancement/recipes/misc/always_disabled_recipe.json @@ -0,0 +1,37 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:false" + } + ], + "parent": "minecraft:recipes/root", + "criteria": { + "has_stone": { + "conditions": { + "items": [ + { + "items": "minecraft:stone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "neotests_test_conditional_recipe:always_disabled_recipe" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_stone" + ] + ], + "rewards": { + "recipes": [ + "neotests_test_conditional_recipe:always_disabled_recipe" + ] + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/data/neotests_test_conditional_recipe/recipe/always_disabled_recipe.json b/tests/src/generated/resources/data/neotests_test_conditional_recipe/recipe/always_disabled_recipe.json new file mode 100644 index 0000000000..404842c813 --- /dev/null +++ b/tests/src/generated/resources/data/neotests_test_conditional_recipe/recipe/always_disabled_recipe.json @@ -0,0 +1,16 @@ +{ + "neoforge:conditions": [ + { + "type": "neoforge:false" + } + ], + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:stone" + ], + "result": { + "count": 1, + "id": "minecraft:bedrock" + } +} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java new file mode 100644 index 0000000000..e4b71b535f --- /dev/null +++ b/tests/src/main/java/net/neoforged/neoforge/debug/ConditionalRecipeTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.debug; + +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.data.recipes.RecipeProvider; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; +import net.neoforged.neoforge.common.conditions.FalseCondition; +import net.neoforged.neoforge.event.server.ServerStartedEvent; +import net.neoforged.testframework.DynamicTest; +import net.neoforged.testframework.annotation.ForEachTest; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.registration.RegistrationHelper; + +@ForEachTest(groups = "conditional_recipes") +public interface ConditionalRecipeTest { + @TestHolder(description = "Validates that recipes support conditionals by generating a new recipe disabled by the FALSE condition", enabledByDefault = true) + static void testConditionalRecipe(DynamicTest test, RegistrationHelper reg) { + // name pointing to recipe which should never be enabled + var recipeName = ResourceKey.create(Registries.RECIPE, ResourceLocation.fromNamespaceAndPath(reg.modId(), "always_disabled_recipe")); + + reg.addProvider(event -> new RecipeProvider.Runner(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + return new RecipeProvider(registries, output) { + @Override + protected void buildRecipes() { + // generic stone -> bedrock recipe + shapeless(RecipeCategory.MISC, Items.BEDROCK) + .requires(Items.STONE) + .unlockedBy("has_stone", has(Items.STONE)) + // false condition to have this recipe always disabled + .save(output.withConditions(FalseCondition.INSTANCE), recipeName); + } + }; + } + + @Override + public String getName() { + return "always_disabled_recipe_provider"; + } + }); + + test.eventListeners().forge().addListener((ServerStartedEvent event) -> { + var recipe = event.getServer().getRecipeManager().recipeMap().byKey(recipeName); + + if (recipe == null) + test.pass(); + else + test.fail("Found recipe: '" + recipeName.location() + "', This should always be disabled due to 'FALSE' condition!"); + }); + } +}