package net.minecraft.advancements.critereon; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Optional; import java.util.function.Predicate; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.FireworkExplosion; import net.minecraft.world.item.component.FireworkExplosion.Shape; public record ItemFireworkExplosionPredicate(ItemFireworkExplosionPredicate.FireworkPredicate predicate) implements SingleComponentItemPredicate { public static final Codec CODEC = ItemFireworkExplosionPredicate.FireworkPredicate.CODEC .xmap(ItemFireworkExplosionPredicate::new, ItemFireworkExplosionPredicate::predicate); @Override public DataComponentType componentType() { return DataComponents.FIREWORK_EXPLOSION; } public boolean matches(ItemStack itemStack, FireworkExplosion fireworkExplosion) { return this.predicate.test(fireworkExplosion); } public record FireworkPredicate(Optional shape, Optional twinkle, Optional trail) implements Predicate { public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( Shape.CODEC.optionalFieldOf("shape").forGetter(ItemFireworkExplosionPredicate.FireworkPredicate::shape), Codec.BOOL.optionalFieldOf("has_twinkle").forGetter(ItemFireworkExplosionPredicate.FireworkPredicate::twinkle), Codec.BOOL.optionalFieldOf("has_trail").forGetter(ItemFireworkExplosionPredicate.FireworkPredicate::trail) ) .apply(instance, ItemFireworkExplosionPredicate.FireworkPredicate::new) ); public boolean test(FireworkExplosion explosion) { if (this.shape.isPresent() && this.shape.get() != explosion.shape()) { return false; } else { return this.twinkle.isPresent() && this.twinkle.get() != explosion.hasTwinkle() ? false : !this.trail.isPresent() || (Boolean)this.trail.get() == explosion.hasTrail(); } } } }