minecraft-src/net/minecraft/advancements/critereon/MobEffectsPredicate.java
2025-07-04 01:41:11 +03:00

90 lines
3.8 KiB
Java

package net.minecraft.advancements.critereon;
import com.google.common.collect.ImmutableMap;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import net.minecraft.core.Holder;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import org.jetbrains.annotations.Nullable;
public record MobEffectsPredicate(Map<Holder<MobEffect>, MobEffectsPredicate.MobEffectInstancePredicate> effectMap) {
public static final Codec<MobEffectsPredicate> CODEC = Codec.unboundedMap(MobEffect.CODEC, MobEffectsPredicate.MobEffectInstancePredicate.CODEC)
.xmap(MobEffectsPredicate::new, MobEffectsPredicate::effectMap);
public boolean matches(Entity entity) {
return entity instanceof LivingEntity livingEntity && this.matches(livingEntity.getActiveEffectsMap());
}
public boolean matches(LivingEntity entity) {
return this.matches(entity.getActiveEffectsMap());
}
public boolean matches(Map<Holder<MobEffect>, MobEffectInstance> effects) {
for (Entry<Holder<MobEffect>, MobEffectsPredicate.MobEffectInstancePredicate> entry : this.effectMap.entrySet()) {
MobEffectInstance mobEffectInstance = (MobEffectInstance)effects.get(entry.getKey());
if (!((MobEffectsPredicate.MobEffectInstancePredicate)entry.getValue()).matches(mobEffectInstance)) {
return false;
}
}
return true;
}
public static class Builder {
private final ImmutableMap.Builder<Holder<MobEffect>, MobEffectsPredicate.MobEffectInstancePredicate> effectMap = ImmutableMap.builder();
public static MobEffectsPredicate.Builder effects() {
return new MobEffectsPredicate.Builder();
}
public MobEffectsPredicate.Builder and(Holder<MobEffect> effect) {
this.effectMap.put(effect, new MobEffectsPredicate.MobEffectInstancePredicate());
return this;
}
public MobEffectsPredicate.Builder and(Holder<MobEffect> effect, MobEffectsPredicate.MobEffectInstancePredicate predicate) {
this.effectMap.put(effect, predicate);
return this;
}
public Optional<MobEffectsPredicate> build() {
return Optional.of(new MobEffectsPredicate(this.effectMap.build()));
}
}
public record MobEffectInstancePredicate(MinMaxBounds.Ints amplifier, MinMaxBounds.Ints duration, Optional<Boolean> ambient, Optional<Boolean> visible) {
public static final Codec<MobEffectsPredicate.MobEffectInstancePredicate> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
MinMaxBounds.Ints.CODEC.optionalFieldOf("amplifier", MinMaxBounds.Ints.ANY).forGetter(MobEffectsPredicate.MobEffectInstancePredicate::amplifier),
MinMaxBounds.Ints.CODEC.optionalFieldOf("duration", MinMaxBounds.Ints.ANY).forGetter(MobEffectsPredicate.MobEffectInstancePredicate::duration),
Codec.BOOL.optionalFieldOf("ambient").forGetter(MobEffectsPredicate.MobEffectInstancePredicate::ambient),
Codec.BOOL.optionalFieldOf("visible").forGetter(MobEffectsPredicate.MobEffectInstancePredicate::visible)
)
.apply(instance, MobEffectsPredicate.MobEffectInstancePredicate::new)
);
public MobEffectInstancePredicate() {
this(MinMaxBounds.Ints.ANY, MinMaxBounds.Ints.ANY, Optional.empty(), Optional.empty());
}
public boolean matches(@Nullable MobEffectInstance effect) {
if (effect == null) {
return false;
} else if (!this.amplifier.matches(effect.getAmplifier())) {
return false;
} else if (!this.duration.matches(effect.getDuration())) {
return false;
} else {
return this.ambient.isPresent() && this.ambient.get() != effect.isAmbient()
? false
: !this.visible.isPresent() || (Boolean)this.visible.get() == effect.isVisible();
}
}
}
}