minecraft-src/net/minecraft/data/recipes/RecipeProvider.java
2025-07-04 02:00:41 +03:00

723 lines
31 KiB
Java

package net.minecraft.data.recipes;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.advancements.Criterion;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.advancements.critereon.EnterBlockTrigger.TriggerInstance;
import net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance.Slots;
import net.minecraft.advancements.critereon.MinMaxBounds.Ints;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.BlockFamilies;
import net.minecraft.data.BlockFamily;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
import net.minecraft.data.BlockFamily.Variant;
import net.minecraft.data.PackOutput.PathProvider;
import net.minecraft.data.recipes.RecipeProvider.Runner.1;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.item.HoneycombItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.BlastingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.SmeltingRecipe;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SuspiciousEffectHolder;
import org.jetbrains.annotations.Nullable;
public abstract class RecipeProvider {
protected final HolderLookup.Provider registries;
private final HolderGetter<Item> items;
protected final RecipeOutput output;
private static final Map<Variant, RecipeProvider.FamilyRecipeProvider> SHAPE_BUILDERS = ImmutableMap.<Variant, RecipeProvider.FamilyRecipeProvider>builder()
.put(Variant.BUTTON, (recipeProvider, itemLike, itemLike2) -> recipeProvider.buttonBuilder(itemLike, Ingredient.of(itemLike2)))
.put(
Variant.CHISELED,
(recipeProvider, itemLike, itemLike2) -> recipeProvider.chiseledBuilder(RecipeCategory.BUILDING_BLOCKS, itemLike, Ingredient.of(itemLike2))
)
.put(Variant.CUT, (recipeProvider, itemLike, itemLike2) -> recipeProvider.cutBuilder(RecipeCategory.BUILDING_BLOCKS, itemLike, Ingredient.of(itemLike2)))
.put(Variant.DOOR, (recipeProvider, itemLike, itemLike2) -> recipeProvider.doorBuilder(itemLike, Ingredient.of(itemLike2)))
.put(Variant.CUSTOM_FENCE, (recipeProvider, itemLike, itemLike2) -> recipeProvider.fenceBuilder(itemLike, Ingredient.of(itemLike2)))
.put(Variant.FENCE, (recipeProvider, itemLike, itemLike2) -> recipeProvider.fenceBuilder(itemLike, Ingredient.of(itemLike2)))
.put(Variant.CUSTOM_FENCE_GATE, (recipeProvider, itemLike, itemLike2) -> recipeProvider.fenceGateBuilder(itemLike, Ingredient.of(itemLike2)))
.put(Variant.FENCE_GATE, (recipeProvider, itemLike, itemLike2) -> recipeProvider.fenceGateBuilder(itemLike, Ingredient.of(itemLike2)))
.put(Variant.SIGN, (recipeProvider, itemLike, itemLike2) -> recipeProvider.signBuilder(itemLike, Ingredient.of(itemLike2)))
.put(Variant.SLAB, (recipeProvider, itemLike, itemLike2) -> recipeProvider.slabBuilder(RecipeCategory.BUILDING_BLOCKS, itemLike, Ingredient.of(itemLike2)))
.put(Variant.STAIRS, (recipeProvider, itemLike, itemLike2) -> recipeProvider.stairBuilder(itemLike, Ingredient.of(itemLike2)))
.put(
Variant.PRESSURE_PLATE,
(recipeProvider, itemLike, itemLike2) -> recipeProvider.pressurePlateBuilder(RecipeCategory.REDSTONE, itemLike, Ingredient.of(itemLike2))
)
.put(
Variant.POLISHED,
(recipeProvider, itemLike, itemLike2) -> recipeProvider.polishedBuilder(RecipeCategory.BUILDING_BLOCKS, itemLike, Ingredient.of(itemLike2))
)
.put(Variant.TRAPDOOR, (recipeProvider, itemLike, itemLike2) -> recipeProvider.trapdoorBuilder(itemLike, Ingredient.of(itemLike2)))
.put(Variant.WALL, (recipeProvider, itemLike, itemLike2) -> recipeProvider.wallBuilder(RecipeCategory.DECORATIONS, itemLike, Ingredient.of(itemLike2)))
.build();
protected RecipeProvider(HolderLookup.Provider provider, RecipeOutput recipeOutput) {
this.registries = provider;
this.items = provider.lookupOrThrow(Registries.ITEM);
this.output = recipeOutput;
}
protected abstract void buildRecipes();
protected void generateForEnabledBlockFamilies(FeatureFlagSet featureFlagSet) {
BlockFamilies.getAllFamilies().filter(BlockFamily::shouldGenerateRecipe).forEach(blockFamily -> this.generateRecipes(blockFamily, featureFlagSet));
}
protected void oneToOneConversionRecipe(ItemLike itemLike, ItemLike itemLike2, @Nullable String string) {
this.oneToOneConversionRecipe(itemLike, itemLike2, string, 1);
}
protected void oneToOneConversionRecipe(ItemLike itemLike, ItemLike itemLike2, @Nullable String string, int i) {
this.shapeless(RecipeCategory.MISC, itemLike, i)
.requires(itemLike2)
.group(string)
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output, getConversionRecipeName(itemLike, itemLike2));
}
protected void oreSmelting(List<ItemLike> list, RecipeCategory recipeCategory, ItemLike itemLike, float f, int i, String string) {
this.oreCooking(RecipeSerializer.SMELTING_RECIPE, SmeltingRecipe::new, list, recipeCategory, itemLike, f, i, string, "_from_smelting");
}
protected void oreBlasting(List<ItemLike> list, RecipeCategory recipeCategory, ItemLike itemLike, float f, int i, String string) {
this.oreCooking(RecipeSerializer.BLASTING_RECIPE, BlastingRecipe::new, list, recipeCategory, itemLike, f, i, string, "_from_blasting");
}
private <T extends AbstractCookingRecipe> void oreCooking(
RecipeSerializer<T> recipeSerializer,
AbstractCookingRecipe.Factory<T> factory,
List<ItemLike> list,
RecipeCategory recipeCategory,
ItemLike itemLike,
float f,
int i,
String string,
String string2
) {
for (ItemLike itemLike2 : list) {
SimpleCookingRecipeBuilder.generic(Ingredient.of(itemLike2), recipeCategory, itemLike, f, i, recipeSerializer, factory)
.group(string)
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output, getItemName(itemLike) + string2 + "_" + getItemName(itemLike2));
}
}
protected void netheriteSmithing(Item item, RecipeCategory recipeCategory, Item item2) {
SmithingTransformRecipeBuilder.smithing(
Ingredient.of(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE), Ingredient.of(item), this.tag(ItemTags.NETHERITE_TOOL_MATERIALS), recipeCategory, item2
)
.unlocks("has_netherite_ingot", this.has(ItemTags.NETHERITE_TOOL_MATERIALS))
.save(this.output, getItemName(item2) + "_smithing");
}
protected void trimSmithing(Item item, ResourceKey<Recipe<?>> resourceKey) {
SmithingTrimRecipeBuilder.smithingTrim(Ingredient.of(item), this.tag(ItemTags.TRIMMABLE_ARMOR), this.tag(ItemTags.TRIM_MATERIALS), RecipeCategory.MISC)
.unlocks("has_smithing_trim_template", this.has(item))
.save(this.output, resourceKey);
}
protected void twoByTwoPacker(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.shaped(recipeCategory, itemLike, 1)
.define('#', itemLike2)
.pattern("##")
.pattern("##")
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
protected void threeByThreePacker(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2, String string) {
this.shapeless(recipeCategory, itemLike).requires(itemLike2, 9).unlockedBy(string, this.has(itemLike2)).save(this.output);
}
protected void threeByThreePacker(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.threeByThreePacker(recipeCategory, itemLike, itemLike2, getHasName(itemLike2));
}
protected void planksFromLog(ItemLike itemLike, TagKey<Item> tagKey, int i) {
this.shapeless(RecipeCategory.BUILDING_BLOCKS, itemLike, i).requires(tagKey).group("planks").unlockedBy("has_log", this.has(tagKey)).save(this.output);
}
protected void planksFromLogs(ItemLike itemLike, TagKey<Item> tagKey, int i) {
this.shapeless(RecipeCategory.BUILDING_BLOCKS, itemLike, i).requires(tagKey).group("planks").unlockedBy("has_logs", this.has(tagKey)).save(this.output);
}
protected void woodFromLogs(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.BUILDING_BLOCKS, itemLike, 3)
.define('#', itemLike2)
.pattern("##")
.pattern("##")
.group("bark")
.unlockedBy("has_log", this.has(itemLike2))
.save(this.output);
}
protected void woodenBoat(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.TRANSPORTATION, itemLike)
.define('#', itemLike2)
.pattern("# #")
.pattern("###")
.group("boat")
.unlockedBy("in_water", insideOf(Blocks.WATER))
.save(this.output);
}
protected void chestBoat(ItemLike itemLike, ItemLike itemLike2) {
this.shapeless(RecipeCategory.TRANSPORTATION, itemLike)
.requires(Blocks.CHEST)
.requires(itemLike2)
.group("chest_boat")
.unlockedBy("has_boat", this.has(ItemTags.BOATS))
.save(this.output);
}
private RecipeBuilder buttonBuilder(ItemLike material, Ingredient ingredient) {
return this.shapeless(RecipeCategory.REDSTONE, material).requires(ingredient);
}
protected RecipeBuilder doorBuilder(ItemLike material, Ingredient ingredient) {
return this.shaped(RecipeCategory.REDSTONE, material, 3).define('#', ingredient).pattern("##").pattern("##").pattern("##");
}
private RecipeBuilder fenceBuilder(ItemLike material, Ingredient ingredient) {
int i = material == Blocks.NETHER_BRICK_FENCE ? 6 : 3;
Item item = material == Blocks.NETHER_BRICK_FENCE ? Items.NETHER_BRICK : Items.STICK;
return this.shaped(RecipeCategory.DECORATIONS, material, i).define('W', ingredient).define('#', item).pattern("W#W").pattern("W#W");
}
private RecipeBuilder fenceGateBuilder(ItemLike material, Ingredient ingredient) {
return this.shaped(RecipeCategory.REDSTONE, material).define('#', Items.STICK).define('W', ingredient).pattern("#W#").pattern("#W#");
}
protected void pressurePlate(ItemLike itemLike, ItemLike itemLike2) {
this.pressurePlateBuilder(RecipeCategory.REDSTONE, itemLike, Ingredient.of(itemLike2))
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
private RecipeBuilder pressurePlateBuilder(RecipeCategory pressurePlate, ItemLike material, Ingredient ingredient) {
return this.shaped(pressurePlate, material).define('#', ingredient).pattern("##");
}
protected void slab(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.slabBuilder(recipeCategory, itemLike, Ingredient.of(itemLike2)).unlockedBy(getHasName(itemLike2), this.has(itemLike2)).save(this.output);
}
protected RecipeBuilder slabBuilder(RecipeCategory slab, ItemLike material, Ingredient ingredient) {
return this.shaped(slab, material, 6).define('#', ingredient).pattern("###");
}
protected RecipeBuilder stairBuilder(ItemLike material, Ingredient ingredient) {
return this.shaped(RecipeCategory.BUILDING_BLOCKS, material, 4).define('#', ingredient).pattern("# ").pattern("## ").pattern("###");
}
protected RecipeBuilder trapdoorBuilder(ItemLike material, Ingredient ingredient) {
return this.shaped(RecipeCategory.REDSTONE, material, 2).define('#', ingredient).pattern("###").pattern("###");
}
private RecipeBuilder signBuilder(ItemLike material, Ingredient ingredient) {
return this.shaped(RecipeCategory.DECORATIONS, material, 3)
.group("sign")
.define('#', ingredient)
.define('X', Items.STICK)
.pattern("###")
.pattern("###")
.pattern(" X ");
}
protected void hangingSign(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.DECORATIONS, itemLike, 6)
.group("hanging_sign")
.define('#', itemLike2)
.define('X', Items.CHAIN)
.pattern("X X")
.pattern("###")
.pattern("###")
.unlockedBy("has_stripped_logs", this.has(itemLike2))
.save(this.output);
}
protected void colorBlockWithDye(List<Item> list, List<Item> list2, String string) {
this.colorWithDye(list, list2, null, string, RecipeCategory.BUILDING_BLOCKS);
}
protected void colorWithDye(List<Item> list, List<Item> list2, @Nullable Item item, String string, RecipeCategory recipeCategory) {
for (int i = 0; i < list.size(); i++) {
Item item2 = (Item)list.get(i);
Item item3 = (Item)list2.get(i);
Stream<Item> stream = list2.stream().filter(item2x -> !item2x.equals(item3));
if (item != null) {
stream = Stream.concat(stream, Stream.of(item));
}
this.shapeless(recipeCategory, item3)
.requires(item2)
.requires(Ingredient.of(stream))
.group(string)
.unlockedBy("has_needed_dye", this.has(item2))
.save(this.output, "dye_" + getItemName(item3));
}
}
protected void carpet(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.DECORATIONS, itemLike, 3)
.define('#', itemLike2)
.pattern("##")
.group("carpet")
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
protected void bedFromPlanksAndWool(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.DECORATIONS, itemLike)
.define('#', itemLike2)
.define('X', ItemTags.PLANKS)
.pattern("###")
.pattern("XXX")
.group("bed")
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
protected void banner(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.DECORATIONS, itemLike)
.define('#', itemLike2)
.define('|', Items.STICK)
.pattern("###")
.pattern("###")
.pattern(" | ")
.group("banner")
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
protected void stainedGlassFromGlassAndDye(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.BUILDING_BLOCKS, itemLike, 8)
.define('#', Blocks.GLASS)
.define('X', itemLike2)
.pattern("###")
.pattern("#X#")
.pattern("###")
.group("stained_glass")
.unlockedBy("has_glass", this.has(Blocks.GLASS))
.save(this.output);
}
protected void stainedGlassPaneFromStainedGlass(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.DECORATIONS, itemLike, 16)
.define('#', itemLike2)
.pattern("###")
.pattern("###")
.group("stained_glass_pane")
.unlockedBy("has_glass", this.has(itemLike2))
.save(this.output);
}
protected void stainedGlassPaneFromGlassPaneAndDye(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.DECORATIONS, itemLike, 8)
.define('#', Blocks.GLASS_PANE)
.define('$', itemLike2)
.pattern("###")
.pattern("#$#")
.pattern("###")
.group("stained_glass_pane")
.unlockedBy("has_glass_pane", this.has(Blocks.GLASS_PANE))
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output, getConversionRecipeName(itemLike, Blocks.GLASS_PANE));
}
protected void coloredTerracottaFromTerracottaAndDye(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.BUILDING_BLOCKS, itemLike, 8)
.define('#', Blocks.TERRACOTTA)
.define('X', itemLike2)
.pattern("###")
.pattern("#X#")
.pattern("###")
.group("stained_terracotta")
.unlockedBy("has_terracotta", this.has(Blocks.TERRACOTTA))
.save(this.output);
}
protected void concretePowder(ItemLike itemLike, ItemLike itemLike2) {
this.shapeless(RecipeCategory.BUILDING_BLOCKS, itemLike, 8)
.requires(itemLike2)
.requires(Blocks.SAND, 4)
.requires(Blocks.GRAVEL, 4)
.group("concrete_powder")
.unlockedBy("has_sand", this.has(Blocks.SAND))
.unlockedBy("has_gravel", this.has(Blocks.GRAVEL))
.save(this.output);
}
protected void candle(ItemLike itemLike, ItemLike itemLike2) {
this.shapeless(RecipeCategory.DECORATIONS, itemLike)
.requires(Blocks.CANDLE)
.requires(itemLike2)
.group("dyed_candle")
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
protected void wall(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.wallBuilder(recipeCategory, itemLike, Ingredient.of(itemLike2)).unlockedBy(getHasName(itemLike2), this.has(itemLike2)).save(this.output);
}
private RecipeBuilder wallBuilder(RecipeCategory wall, ItemLike material, Ingredient ingredient) {
return this.shaped(wall, material, 6).define('#', ingredient).pattern("###").pattern("###");
}
protected void polished(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.polishedBuilder(recipeCategory, itemLike, Ingredient.of(itemLike2)).unlockedBy(getHasName(itemLike2), this.has(itemLike2)).save(this.output);
}
private RecipeBuilder polishedBuilder(RecipeCategory result, ItemLike material, Ingredient ingredient) {
return this.shaped(result, material, 4).define('S', ingredient).pattern("SS").pattern("SS");
}
protected void cut(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.cutBuilder(recipeCategory, itemLike, Ingredient.of(itemLike2)).unlockedBy(getHasName(itemLike2), this.has(itemLike2)).save(this.output);
}
private ShapedRecipeBuilder cutBuilder(RecipeCategory cutResult, ItemLike material, Ingredient ingredient) {
return this.shaped(cutResult, material, 4).define('#', ingredient).pattern("##").pattern("##");
}
protected void chiseled(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.chiseledBuilder(recipeCategory, itemLike, Ingredient.of(itemLike2)).unlockedBy(getHasName(itemLike2), this.has(itemLike2)).save(this.output);
}
protected void mosaicBuilder(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.shaped(recipeCategory, itemLike)
.define('#', itemLike2)
.pattern("#")
.pattern("#")
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
protected ShapedRecipeBuilder chiseledBuilder(RecipeCategory chiseledResult, ItemLike material, Ingredient ingredient) {
return this.shaped(chiseledResult, material).define('#', ingredient).pattern("#").pattern("#");
}
protected void stonecutterResultFromBase(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2) {
this.stonecutterResultFromBase(recipeCategory, itemLike, itemLike2, 1);
}
protected void stonecutterResultFromBase(RecipeCategory recipeCategory, ItemLike itemLike, ItemLike itemLike2, int i) {
SingleItemRecipeBuilder.stonecutting(Ingredient.of(itemLike2), recipeCategory, itemLike, i)
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output, getConversionRecipeName(itemLike, itemLike2) + "_stonecutting");
}
private void smeltingResultFromBase(ItemLike itemLike, ItemLike itemLike2) {
SimpleCookingRecipeBuilder.smelting(Ingredient.of(itemLike2), RecipeCategory.BUILDING_BLOCKS, itemLike, 0.1F, 200)
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output);
}
protected void nineBlockStorageRecipes(RecipeCategory recipeCategory, ItemLike itemLike, RecipeCategory recipeCategory2, ItemLike itemLike2) {
this.nineBlockStorageRecipes(recipeCategory, itemLike, recipeCategory2, itemLike2, getSimpleRecipeName(itemLike2), null, getSimpleRecipeName(itemLike), null);
}
protected void nineBlockStorageRecipesWithCustomPacking(
RecipeCategory recipeCategory, ItemLike itemLike, RecipeCategory recipeCategory2, ItemLike itemLike2, String string, String string2
) {
this.nineBlockStorageRecipes(recipeCategory, itemLike, recipeCategory2, itemLike2, string, string2, getSimpleRecipeName(itemLike), null);
}
protected void nineBlockStorageRecipesRecipesWithCustomUnpacking(
RecipeCategory recipeCategory, ItemLike itemLike, RecipeCategory recipeCategory2, ItemLike itemLike2, String string, String string2
) {
this.nineBlockStorageRecipes(recipeCategory, itemLike, recipeCategory2, itemLike2, getSimpleRecipeName(itemLike2), null, string, string2);
}
private void nineBlockStorageRecipes(
RecipeCategory recipeCategory,
ItemLike itemLike,
RecipeCategory recipeCategory2,
ItemLike itemLike2,
String string,
@Nullable String string2,
String string3,
@Nullable String string4
) {
this.shapeless(recipeCategory, itemLike, 9)
.requires(itemLike2)
.group(string4)
.unlockedBy(getHasName(itemLike2), this.has(itemLike2))
.save(this.output, ResourceKey.create(Registries.RECIPE, ResourceLocation.parse(string3)));
this.shaped(recipeCategory2, itemLike2)
.define('#', itemLike)
.pattern("###")
.pattern("###")
.pattern("###")
.group(string2)
.unlockedBy(getHasName(itemLike), this.has(itemLike))
.save(this.output, ResourceKey.create(Registries.RECIPE, ResourceLocation.parse(string)));
}
protected void copySmithingTemplate(ItemLike itemLike, ItemLike itemLike2) {
this.shaped(RecipeCategory.MISC, itemLike, 2)
.define('#', Items.DIAMOND)
.define('C', itemLike2)
.define('S', itemLike)
.pattern("#S#")
.pattern("#C#")
.pattern("###")
.unlockedBy(getHasName(itemLike), this.has(itemLike))
.save(this.output);
}
protected void copySmithingTemplate(ItemLike itemLike, Ingredient ingredient) {
this.shaped(RecipeCategory.MISC, itemLike, 2)
.define('#', Items.DIAMOND)
.define('C', ingredient)
.define('S', itemLike)
.pattern("#S#")
.pattern("#C#")
.pattern("###")
.unlockedBy(getHasName(itemLike), this.has(itemLike))
.save(this.output);
}
protected <T extends AbstractCookingRecipe> void cookRecipes(
String string, RecipeSerializer<T> recipeSerializer, AbstractCookingRecipe.Factory<T> factory, int i
) {
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.BEEF, Items.COOKED_BEEF, 0.35F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.CHICKEN, Items.COOKED_CHICKEN, 0.35F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.COD, Items.COOKED_COD, 0.35F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.KELP, Items.DRIED_KELP, 0.1F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.SALMON, Items.COOKED_SALMON, 0.35F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.MUTTON, Items.COOKED_MUTTON, 0.35F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.PORKCHOP, Items.COOKED_PORKCHOP, 0.35F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.POTATO, Items.BAKED_POTATO, 0.35F);
this.simpleCookingRecipe(string, recipeSerializer, factory, i, Items.RABBIT, Items.COOKED_RABBIT, 0.35F);
}
private <T extends AbstractCookingRecipe> void simpleCookingRecipe(
String string, RecipeSerializer<T> recipeSerializer, AbstractCookingRecipe.Factory<T> factory, int i, ItemLike itemLike, ItemLike itemLike2, float f
) {
SimpleCookingRecipeBuilder.generic(Ingredient.of(itemLike), RecipeCategory.FOOD, itemLike2, f, i, recipeSerializer, factory)
.unlockedBy(getHasName(itemLike), this.has(itemLike))
.save(this.output, getItemName(itemLike2) + "_from_" + string);
}
protected void waxRecipes(FeatureFlagSet featureFlagSet) {
((BiMap)HoneycombItem.WAXABLES.get())
.forEach(
(block, block2) -> {
if (block2.requiredFeatures().isSubsetOf(featureFlagSet)) {
this.shapeless(RecipeCategory.BUILDING_BLOCKS, block2)
.requires(block)
.requires(Items.HONEYCOMB)
.group(getItemName(block2))
.unlockedBy(getHasName(block), this.has(block))
.save(this.output, getConversionRecipeName(block2, Items.HONEYCOMB));
}
}
);
}
protected void grate(Block block, Block block2) {
this.shaped(RecipeCategory.BUILDING_BLOCKS, block, 4)
.define('M', block2)
.pattern(" M ")
.pattern("M M")
.pattern(" M ")
.unlockedBy(getHasName(block2), this.has(block2))
.save(this.output);
}
protected void copperBulb(Block block, Block block2) {
this.shaped(RecipeCategory.REDSTONE, block, 4)
.define('C', block2)
.define('R', Items.REDSTONE)
.define('B', Items.BLAZE_ROD)
.pattern(" C ")
.pattern("CBC")
.pattern(" R ")
.unlockedBy(getHasName(block2), this.has(block2))
.save(this.output);
}
protected void suspiciousStew(Item item, SuspiciousEffectHolder suspiciousEffectHolder) {
ItemStack itemStack = new ItemStack(
Items.SUSPICIOUS_STEW.builtInRegistryHolder(),
1,
DataComponentPatch.builder().set(DataComponents.SUSPICIOUS_STEW_EFFECTS, suspiciousEffectHolder.getSuspiciousEffects()).build()
);
this.shapeless(RecipeCategory.FOOD, itemStack)
.requires(Items.BOWL)
.requires(Items.BROWN_MUSHROOM)
.requires(Items.RED_MUSHROOM)
.requires(item)
.group("suspicious_stew")
.unlockedBy(getHasName(item), this.has(item))
.save(this.output, getItemName(itemStack.getItem()) + "_from_" + getItemName(item));
}
protected void generateRecipes(BlockFamily blockFamily, FeatureFlagSet featureFlagSet) {
blockFamily.getVariants().forEach((variant, block) -> {
if (block.requiredFeatures().isSubsetOf(featureFlagSet)) {
RecipeProvider.FamilyRecipeProvider familyRecipeProvider = (RecipeProvider.FamilyRecipeProvider)SHAPE_BUILDERS.get(variant);
ItemLike itemLike = this.getBaseBlock(blockFamily, variant);
if (familyRecipeProvider != null) {
RecipeBuilder recipeBuilder = familyRecipeProvider.create(this, block, itemLike);
blockFamily.getRecipeGroupPrefix().ifPresent(string -> recipeBuilder.group(string + (variant == Variant.CUT ? "" : "_" + variant.getRecipeGroup())));
recipeBuilder.unlockedBy((String)blockFamily.getRecipeUnlockedBy().orElseGet(() -> getHasName(itemLike)), this.has(itemLike));
recipeBuilder.save(this.output);
}
if (variant == Variant.CRACKED) {
this.smeltingResultFromBase(block, itemLike);
}
}
});
}
private Block getBaseBlock(BlockFamily variant, Variant variant2) {
if (variant2 == Variant.CHISELED) {
if (!variant.getVariants().containsKey(Variant.SLAB)) {
throw new IllegalStateException("Slab is not defined for the family.");
} else {
return variant.get(Variant.SLAB);
}
} else {
return variant.getBaseBlock();
}
}
private static Criterion<TriggerInstance> insideOf(Block block) {
return CriteriaTriggers.ENTER_BLOCK.createCriterion(new TriggerInstance(Optional.empty(), Optional.of(block.builtInRegistryHolder()), Optional.empty()));
}
private Criterion<net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance> has(Ints item, ItemLike itemLike) {
return inventoryTrigger(ItemPredicate.Builder.item().of(this.items, itemLike).withCount(item));
}
protected Criterion<net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance> has(ItemLike itemLike) {
return inventoryTrigger(ItemPredicate.Builder.item().of(this.items, itemLike));
}
protected Criterion<net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance> has(TagKey<Item> tagKey) {
return inventoryTrigger(ItemPredicate.Builder.item().of(this.items, tagKey));
}
private static Criterion<net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance> inventoryTrigger(ItemPredicate.Builder... items) {
return inventoryTrigger((ItemPredicate[])Arrays.stream(items).map(ItemPredicate.Builder::build).toArray(ItemPredicate[]::new));
}
private static Criterion<net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance> inventoryTrigger(ItemPredicate... predicates) {
return CriteriaTriggers.INVENTORY_CHANGED
.createCriterion(new net.minecraft.advancements.critereon.InventoryChangeTrigger.TriggerInstance(Optional.empty(), Slots.ANY, List.of(predicates)));
}
protected static String getHasName(ItemLike itemLike) {
return "has_" + getItemName(itemLike);
}
protected static String getItemName(ItemLike itemLike) {
return BuiltInRegistries.ITEM.getKey(itemLike.asItem()).getPath();
}
protected static String getSimpleRecipeName(ItemLike itemLike) {
return getItemName(itemLike);
}
protected static String getConversionRecipeName(ItemLike result, ItemLike ingredient) {
return getItemName(result) + "_from_" + getItemName(ingredient);
}
protected static String getSmeltingRecipeName(ItemLike itemLike) {
return getItemName(itemLike) + "_from_smelting";
}
protected static String getBlastingRecipeName(ItemLike itemLike) {
return getItemName(itemLike) + "_from_blasting";
}
protected Ingredient tag(TagKey<Item> tagKey) {
return Ingredient.of(this.items.getOrThrow(tagKey));
}
protected ShapedRecipeBuilder shaped(RecipeCategory recipeCategory, ItemLike itemLike) {
return ShapedRecipeBuilder.shaped(this.items, recipeCategory, itemLike);
}
protected ShapedRecipeBuilder shaped(RecipeCategory recipeCategory, ItemLike itemLike, int i) {
return ShapedRecipeBuilder.shaped(this.items, recipeCategory, itemLike, i);
}
protected ShapelessRecipeBuilder shapeless(RecipeCategory recipeCategory, ItemStack itemStack) {
return ShapelessRecipeBuilder.shapeless(this.items, recipeCategory, itemStack);
}
protected ShapelessRecipeBuilder shapeless(RecipeCategory recipeCategory, ItemLike itemLike) {
return ShapelessRecipeBuilder.shapeless(this.items, recipeCategory, itemLike);
}
protected ShapelessRecipeBuilder shapeless(RecipeCategory recipeCategory, ItemLike itemLike, int i) {
return ShapelessRecipeBuilder.shapeless(this.items, recipeCategory, itemLike, i);
}
@FunctionalInterface
interface FamilyRecipeProvider {
RecipeBuilder create(RecipeProvider recipeProvider, ItemLike itemLike, ItemLike itemLike2);
}
protected abstract static class Runner implements DataProvider {
private final PackOutput packOutput;
private final CompletableFuture<HolderLookup.Provider> registries;
protected Runner(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> completableFuture) {
this.packOutput = packOutput;
this.registries = completableFuture;
}
@Override
public final CompletableFuture<?> run(CachedOutput output) {
return this.registries.thenCompose(provider -> {
PathProvider pathProvider = this.packOutput.createRegistryElementsPathProvider(Registries.RECIPE);
PathProvider pathProvider2 = this.packOutput.createRegistryElementsPathProvider(Registries.ADVANCEMENT);
Set<ResourceKey<Recipe<?>>> set = Sets.<ResourceKey<Recipe<?>>>newHashSet();
List<CompletableFuture<?>> list = new ArrayList();
RecipeOutput recipeOutput = new 1(this, set, list, output, provider, pathProvider, pathProvider2);
this.createRecipeProvider(provider, recipeOutput).buildRecipes();
return CompletableFuture.allOf((CompletableFuture[])list.toArray(CompletableFuture[]::new));
});
}
protected abstract RecipeProvider createRecipeProvider(HolderLookup.Provider provider, RecipeOutput recipeOutput);
}
}