package net.minecraft.world.item.crafting; import com.mojang.serialization.Codec; 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.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; public abstract class SingleItemRecipe implements Recipe { protected final Ingredient ingredient; protected final ItemStack result; private final RecipeType type; private final RecipeSerializer serializer; protected final String group; public SingleItemRecipe(RecipeType type, RecipeSerializer serializer, String group, Ingredient ingredient, ItemStack result) { this.type = type; this.serializer = serializer; this.group = group; this.ingredient = ingredient; this.result = result; } @Override public RecipeType getType() { return this.type; } @Override public RecipeSerializer getSerializer() { return this.serializer; } @Override public String getGroup() { return this.group; } @Override public ItemStack getResultItem(HolderLookup.Provider registries) { return this.result; } @Override public NonNullList getIngredients() { NonNullList nonNullList = NonNullList.create(); nonNullList.add(this.ingredient); return nonNullList; } @Override public boolean canCraftInDimensions(int width, int height) { return true; } public ItemStack assemble(SingleRecipeInput input, HolderLookup.Provider registries) { return this.result.copy(); } public interface Factory { T create(String string, Ingredient ingredient, ItemStack itemStack); } public static class Serializer implements RecipeSerializer { final SingleItemRecipe.Factory factory; private final MapCodec codec; private final StreamCodec streamCodec; protected Serializer(SingleItemRecipe.Factory factory) { this.factory = factory; this.codec = RecordCodecBuilder.mapCodec( instance -> instance.group( Codec.STRING.optionalFieldOf("group", "").forGetter(singleItemRecipe -> singleItemRecipe.group), Ingredient.CODEC_NONEMPTY.fieldOf("ingredient").forGetter(singleItemRecipe -> singleItemRecipe.ingredient), ItemStack.STRICT_CODEC.fieldOf("result").forGetter(singleItemRecipe -> singleItemRecipe.result) ) .apply(instance, factory::create) ); this.streamCodec = StreamCodec.composite( ByteBufCodecs.STRING_UTF8, singleItemRecipe -> singleItemRecipe.group, Ingredient.CONTENTS_STREAM_CODEC, singleItemRecipe -> singleItemRecipe.ingredient, ItemStack.STREAM_CODEC, singleItemRecipe -> singleItemRecipe.result, factory::create ); } @Override public MapCodec codec() { return this.codec; } @Override public StreamCodec streamCodec() { return this.streamCodec; } } }