package net.minecraft.world.item.crafting; import com.mojang.serialization.Codec; import net.minecraft.core.HolderLookup; import net.minecraft.core.NonNullList; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; public interface Recipe { Codec> CODEC = BuiltInRegistries.RECIPE_SERIALIZER.byNameCodec().dispatch(Recipe::getSerializer, RecipeSerializer::codec); StreamCodec> STREAM_CODEC = ByteBufCodecs.registry(Registries.RECIPE_SERIALIZER) .dispatch(Recipe::getSerializer, RecipeSerializer::streamCodec); boolean matches(T input, Level level); ItemStack assemble(T input, HolderLookup.Provider registries); /** * Used to determine if this recipe can fit in a grid of the given width/height */ boolean canCraftInDimensions(int width, int height); ItemStack getResultItem(HolderLookup.Provider registries); default NonNullList getRemainingItems(T input) { NonNullList nonNullList = NonNullList.withSize(input.size(), ItemStack.EMPTY); for (int i = 0; i < nonNullList.size(); i++) { Item item = input.getItem(i).getItem(); if (item.hasCraftingRemainingItem()) { nonNullList.set(i, new ItemStack(item.getCraftingRemainingItem())); } } return nonNullList; } default NonNullList getIngredients() { return NonNullList.create(); } /** * If true, this recipe does not appear in the recipe book and does not respect recipe unlocking (and the doLimitedCrafting gamerule) */ default boolean isSpecial() { return false; } default boolean showNotification() { return true; } /** * Recipes with equal group are combined into one button in the recipe book */ default String getGroup() { return ""; } default ItemStack getToastSymbol() { return new ItemStack(Blocks.CRAFTING_TABLE); } RecipeSerializer getSerializer(); RecipeType getType(); default boolean isIncomplete() { NonNullList nonNullList = this.getIngredients(); return nonNullList.isEmpty() || nonNullList.stream().anyMatch(ingredient -> ingredient.getItems().length == 0); } }