package net.minecraft.advancements.critereon; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Optional; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; public record DamagePredicate( MinMaxBounds.Doubles dealtDamage, MinMaxBounds.Doubles takenDamage, Optional sourceEntity, Optional blocked, Optional type ) { public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( MinMaxBounds.Doubles.CODEC.optionalFieldOf("dealt", MinMaxBounds.Doubles.ANY).forGetter(DamagePredicate::dealtDamage), MinMaxBounds.Doubles.CODEC.optionalFieldOf("taken", MinMaxBounds.Doubles.ANY).forGetter(DamagePredicate::takenDamage), EntityPredicate.CODEC.optionalFieldOf("source_entity").forGetter(DamagePredicate::sourceEntity), Codec.BOOL.optionalFieldOf("blocked").forGetter(DamagePredicate::blocked), DamageSourcePredicate.CODEC.optionalFieldOf("type").forGetter(DamagePredicate::type) ) .apply(instance, DamagePredicate::new) ); public boolean matches(ServerPlayer player, DamageSource source, float dealtDamage, float takenDamage, boolean blocked) { if (!this.dealtDamage.matches(dealtDamage)) { return false; } else if (!this.takenDamage.matches(takenDamage)) { return false; } else if (this.sourceEntity.isPresent() && !((EntityPredicate)this.sourceEntity.get()).matches(player, source.getEntity())) { return false; } else { return this.blocked.isPresent() && this.blocked.get() != blocked ? false : !this.type.isPresent() || ((DamageSourcePredicate)this.type.get()).matches(player, source); } } public static class Builder { private MinMaxBounds.Doubles dealtDamage = MinMaxBounds.Doubles.ANY; private MinMaxBounds.Doubles takenDamage = MinMaxBounds.Doubles.ANY; private Optional sourceEntity = Optional.empty(); private Optional blocked = Optional.empty(); private Optional type = Optional.empty(); public static DamagePredicate.Builder damageInstance() { return new DamagePredicate.Builder(); } public DamagePredicate.Builder dealtDamage(MinMaxBounds.Doubles dealtDamage) { this.dealtDamage = dealtDamage; return this; } public DamagePredicate.Builder takenDamage(MinMaxBounds.Doubles takenDamage) { this.takenDamage = takenDamage; return this; } public DamagePredicate.Builder sourceEntity(EntityPredicate sourceEntity) { this.sourceEntity = Optional.of(sourceEntity); return this; } public DamagePredicate.Builder blocked(Boolean blocked) { this.blocked = Optional.of(blocked); return this; } public DamagePredicate.Builder type(DamageSourcePredicate type) { this.type = Optional.of(type); return this; } public DamagePredicate.Builder type(DamageSourcePredicate.Builder typeBuilder) { this.type = Optional.of(typeBuilder.build()); return this; } public DamagePredicate build() { return new DamagePredicate(this.dealtDamage, this.takenDamage, this.sourceEntity, this.blocked, this.type); } } }