package net.minecraft.advancements.critereon; import com.mojang.serialization.Codec; import io.netty.buffer.ByteBuf; import net.minecraft.core.component.DataComponentGetter; import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.Tag; import net.minecraft.nbt.TagParser; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.CustomData; import org.jetbrains.annotations.Nullable; public record NbtPredicate(CompoundTag tag) { public static final Codec CODEC = TagParser.LENIENT_CODEC.xmap(NbtPredicate::new, NbtPredicate::tag); public static final StreamCodec STREAM_CODEC = ByteBufCodecs.COMPOUND_TAG.map(NbtPredicate::new, NbtPredicate::tag); public boolean matches(DataComponentGetter componentGetter) { CustomData customData = componentGetter.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY); return customData.matchedBy(this.tag); } public boolean matches(Entity entity) { return this.matches(getEntityTagToCompare(entity)); } public boolean matches(@Nullable Tag tag) { return tag != null && NbtUtils.compareNbt(this.tag, tag, true); } public static CompoundTag getEntityTagToCompare(Entity entity) { CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag()); if (entity instanceof Player player) { ItemStack itemStack = player.getInventory().getSelectedItem(); if (!itemStack.isEmpty()) { compoundTag.put("SelectedItem", itemStack.save(entity.registryAccess())); } } return compoundTag; } }