package net.minecraft.world.item.crafting; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; 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.item.crafting.display.FurnaceRecipeDisplay; import net.minecraft.world.item.crafting.display.RecipeDisplay; import net.minecraft.world.item.crafting.display.SlotDisplay; public abstract class AbstractCookingRecipe extends SingleItemRecipe { private final CookingBookCategory category; private final float experience; private final int cookingTime; public AbstractCookingRecipe(String group, CookingBookCategory category, Ingredient input, ItemStack result, float experience, int cookingTime) { super(group, input, result); this.category = category; this.experience = experience; this.cookingTime = cookingTime; } @Override public abstract RecipeSerializer getSerializer(); @Override public abstract RecipeType getType(); public float experience() { return this.experience; } public int cookingTime() { return this.cookingTime; } public CookingBookCategory category() { return this.category; } protected abstract Item furnaceIcon(); @Override public List display() { return List.of( new FurnaceRecipeDisplay( this.input().display(), SlotDisplay.AnyFuel.INSTANCE, new SlotDisplay.ItemStackSlotDisplay(this.result()), new SlotDisplay.ItemSlotDisplay(this.furnaceIcon()), this.cookingTime, this.experience ) ); } @FunctionalInterface public interface Factory { T create(String string, CookingBookCategory cookingBookCategory, Ingredient ingredient, ItemStack itemStack, float f, int i); } public static class Serializer implements RecipeSerializer { private final MapCodec codec; private final StreamCodec streamCodec; public Serializer(AbstractCookingRecipe.Factory factory, int defaultCookingTime) { this.codec = RecordCodecBuilder.mapCodec( instance -> instance.group( Codec.STRING.optionalFieldOf("group", "").forGetter(SingleItemRecipe::group), CookingBookCategory.CODEC.fieldOf("category").orElse(CookingBookCategory.MISC).forGetter(AbstractCookingRecipe::category), Ingredient.CODEC.fieldOf("ingredient").forGetter(SingleItemRecipe::input), ItemStack.STRICT_SINGLE_ITEM_CODEC.fieldOf("result").forGetter(SingleItemRecipe::result), Codec.FLOAT.fieldOf("experience").orElse(0.0F).forGetter(AbstractCookingRecipe::experience), Codec.INT.fieldOf("cookingtime").orElse(defaultCookingTime).forGetter(AbstractCookingRecipe::cookingTime) ) .apply(instance, factory::create) ); this.streamCodec = StreamCodec.composite( ByteBufCodecs.STRING_UTF8, SingleItemRecipe::group, CookingBookCategory.STREAM_CODEC, AbstractCookingRecipe::category, Ingredient.CONTENTS_STREAM_CODEC, SingleItemRecipe::input, ItemStack.STREAM_CODEC, SingleItemRecipe::result, ByteBufCodecs.FLOAT, AbstractCookingRecipe::experience, ByteBufCodecs.INT, AbstractCookingRecipe::cookingTime, factory::create ); } @Override public MapCodec codec() { return this.codec; } @Override public StreamCodec streamCodec() { return this.streamCodec; } } }