package net.minecraft.world.item.crafting; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.util.ExtraCodecs; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.display.SlotDisplay; public record TransmuteResult(Holder item, int count, DataComponentPatch components) { private static final Codec FULL_CODEC = RecordCodecBuilder.create( instance -> instance.group( Item.CODEC.fieldOf("id").forGetter(TransmuteResult::item), ExtraCodecs.intRange(1, 99).optionalFieldOf("count", 1).forGetter(TransmuteResult::count), DataComponentPatch.CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY).forGetter(TransmuteResult::components) ) .apply(instance, TransmuteResult::new) ); public static final Codec CODEC = Codec.>withAlternative( FULL_CODEC, Item.CODEC, holder -> new TransmuteResult((Item)holder.value()) ) .validate(TransmuteResult::validate); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( Item.STREAM_CODEC, TransmuteResult::item, ByteBufCodecs.VAR_INT, TransmuteResult::count, DataComponentPatch.STREAM_CODEC, TransmuteResult::components, TransmuteResult::new ); public TransmuteResult(Item item) { this(item.builtInRegistryHolder(), 1, DataComponentPatch.EMPTY); } private static DataResult validate(TransmuteResult result) { return ItemStack.validateStrict(new ItemStack(result.item, result.count, result.components)).map(itemStack -> result); } public ItemStack apply(ItemStack stack) { ItemStack itemStack = stack.transmuteCopy(this.item.value(), this.count); itemStack.applyComponents(this.components); return itemStack; } public boolean isResultUnchanged(ItemStack stack) { ItemStack itemStack = this.apply(stack); return itemStack.getCount() == 1 && ItemStack.isSameItemSameComponents(stack, itemStack); } public SlotDisplay display() { return new SlotDisplay.ItemStackSlotDisplay(new ItemStack(this.item, this.count, this.components)); } }