package net.minecraft.advancements.critereon; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Optional; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderSet; import net.minecraft.core.RegistryCodecs; import net.minecraft.core.registries.Registries; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; public record FluidPredicate(Optional> fluids, Optional properties) { public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( RegistryCodecs.homogeneousList(Registries.FLUID).optionalFieldOf("fluids").forGetter(FluidPredicate::fluids), StatePropertiesPredicate.CODEC.optionalFieldOf("state").forGetter(FluidPredicate::properties) ) .apply(instance, FluidPredicate::new) ); public boolean matches(ServerLevel level, BlockPos pos) { if (!level.isLoaded(pos)) { return false; } else { FluidState fluidState = level.getFluidState(pos); return this.fluids.isPresent() && !fluidState.is((HolderSet)this.fluids.get()) ? false : !this.properties.isPresent() || ((StatePropertiesPredicate)this.properties.get()).matches(fluidState); } } public static class Builder { private Optional> fluids = Optional.empty(); private Optional properties = Optional.empty(); private Builder() { } public static FluidPredicate.Builder fluid() { return new FluidPredicate.Builder(); } public FluidPredicate.Builder of(Fluid fluid) { this.fluids = Optional.of(HolderSet.direct(fluid.builtInRegistryHolder())); return this; } public FluidPredicate.Builder of(HolderSet fluids) { this.fluids = Optional.of(fluids); return this; } public FluidPredicate.Builder setProperties(StatePropertiesPredicate properties) { this.properties = Optional.of(properties); return this; } public FluidPredicate build() { return new FluidPredicate(this.fluids, this.properties); } } }