Code/net/minecraft/advancements/critereon/EntityPredicate.java

342 lines
16 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.advancements.critereon;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.mojang.serialization.codecs.RecordCodecBuilder.Instance;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.component.DataComponentGetter;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.TagKey;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemEntityPropertyCondition;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.scores.Team;
public record EntityPredicate(
Optional<EntityTypePredicate> entityType,
Optional<DistancePredicate> distanceToPlayer,
Optional<MovementPredicate> movement,
EntityPredicate.LocationWrapper location,
Optional<MobEffectsPredicate> effects,
Optional<NbtPredicate> nbt,
Optional<EntityFlagsPredicate> flags,
Optional<EntityEquipmentPredicate> equipment,
Optional<EntitySubPredicate> subPredicate,
Optional<Integer> periodicTick,
Optional<EntityPredicate> vehicle,
Optional<EntityPredicate> passenger,
Optional<EntityPredicate> targetedEntity,
Optional<String> team,
Optional<SlotsPredicate> slots,
DataComponentMatchers components
) {
public static final Codec<EntityPredicate> CODEC = Codec.recursive(
"EntityPredicate",
p_296121_ -> RecordCodecBuilder.create(
p_340757_ -> p_340757_.group(
EntityTypePredicate.CODEC.optionalFieldOf("type").forGetter(EntityPredicate::entityType),
DistancePredicate.CODEC.optionalFieldOf("distance").forGetter(EntityPredicate::distanceToPlayer),
MovementPredicate.CODEC.optionalFieldOf("movement").forGetter(EntityPredicate::movement),
EntityPredicate.LocationWrapper.CODEC.forGetter(EntityPredicate::location),
MobEffectsPredicate.CODEC.optionalFieldOf("effects").forGetter(EntityPredicate::effects),
NbtPredicate.CODEC.optionalFieldOf("nbt").forGetter(EntityPredicate::nbt),
EntityFlagsPredicate.CODEC.optionalFieldOf("flags").forGetter(EntityPredicate::flags),
EntityEquipmentPredicate.CODEC.optionalFieldOf("equipment").forGetter(EntityPredicate::equipment),
EntitySubPredicate.CODEC.optionalFieldOf("type_specific").forGetter(EntityPredicate::subPredicate),
ExtraCodecs.POSITIVE_INT.optionalFieldOf("periodic_tick").forGetter(EntityPredicate::periodicTick),
p_296121_.optionalFieldOf("vehicle").forGetter(EntityPredicate::vehicle),
p_296121_.optionalFieldOf("passenger").forGetter(EntityPredicate::passenger),
p_296121_.optionalFieldOf("targeted_entity").forGetter(EntityPredicate::targetedEntity),
Codec.STRING.optionalFieldOf("team").forGetter(EntityPredicate::team),
SlotsPredicate.CODEC.optionalFieldOf("slots").forGetter(EntityPredicate::slots),
DataComponentMatchers.CODEC.forGetter(EntityPredicate::components)
)
.apply(p_340757_, EntityPredicate::new)
)
);
public static final Codec<ContextAwarePredicate> ADVANCEMENT_CODEC = Codec.withAlternative(ContextAwarePredicate.CODEC, CODEC, EntityPredicate::wrap);
public static ContextAwarePredicate wrap(EntityPredicate.Builder p_298584_) {
return wrap(p_298584_.build());
}
public static Optional<ContextAwarePredicate> wrap(Optional<EntityPredicate> p_300980_) {
return p_300980_.map(EntityPredicate::wrap);
}
public static List<ContextAwarePredicate> wrap(EntityPredicate.Builder... p_299692_) {
return Stream.of(p_299692_).map(EntityPredicate::wrap).toList();
}
public static ContextAwarePredicate wrap(EntityPredicate p_286570_) {
LootItemCondition lootitemcondition = LootItemEntityPropertyCondition.hasProperties(LootContext.EntityTarget.THIS, p_286570_).build();
return new ContextAwarePredicate(List.of(lootitemcondition));
}
public boolean matches(ServerPlayer p_36612_, @Nullable Entity p_36613_) {
return this.matches(p_36612_.serverLevel(), p_36612_.position(), p_36613_);
}
public boolean matches(ServerLevel p_36608_, @Nullable Vec3 p_36609_, @Nullable Entity p_36610_) {
if (p_36610_ == null) {
return false;
} else if (this.entityType.isPresent() && !this.entityType.get().matches(p_36610_.getType())) {
return false;
} else {
if (p_36609_ == null) {
if (this.distanceToPlayer.isPresent()) {
return false;
}
} else if (this.distanceToPlayer.isPresent()
&& !this.distanceToPlayer
.get()
.matches(p_36609_.x, p_36609_.y, p_36609_.z, p_36610_.getX(), p_36610_.getY(), p_36610_.getZ())) {
return false;
}
if (this.movement.isPresent()) {
Vec3 vec3 = p_36610_.getKnownMovement();
Vec3 vec31 = vec3.scale(20.0);
if (!this.movement.get().matches(vec31.x, vec31.y, vec31.z, p_36610_.fallDistance)) {
return false;
}
}
if (this.location.located.isPresent()
&& !this.location.located.get().matches(p_36608_, p_36610_.getX(), p_36610_.getY(), p_36610_.getZ())) {
return false;
} else {
if (this.location.steppingOn.isPresent()) {
Vec3 vec32 = Vec3.atCenterOf(p_36610_.getOnPos());
if (!p_36610_.onGround() || !this.location.steppingOn.get().matches(p_36608_, vec32.x(), vec32.y(), vec32.z())) {
return false;
}
}
if (this.location.affectsMovement.isPresent()) {
Vec3 vec33 = Vec3.atCenterOf(p_36610_.getBlockPosBelowThatAffectsMyMovement());
if (!this.location.affectsMovement.get().matches(p_36608_, vec33.x(), vec33.y(), vec33.z())) {
return false;
}
}
if (this.effects.isPresent() && !this.effects.get().matches(p_36610_)) {
return false;
} else if (this.flags.isPresent() && !this.flags.get().matches(p_36610_)) {
return false;
} else if (this.equipment.isPresent() && !this.equipment.get().matches(p_36610_)) {
return false;
} else if (this.subPredicate.isPresent() && !this.subPredicate.get().matches(p_36610_, p_36608_, p_36609_)) {
return false;
} else if (this.vehicle.isPresent() && !this.vehicle.get().matches(p_36608_, p_36609_, p_36610_.getVehicle())) {
return false;
} else if (this.passenger.isPresent()
&& p_36610_.getPassengers().stream().noneMatch(p_296124_ -> this.passenger.get().matches(p_36608_, p_36609_, p_296124_))) {
return false;
} else if (this.targetedEntity.isPresent()
&& !this.targetedEntity.get().matches(p_36608_, p_36609_, p_36610_ instanceof Mob ? ((Mob)p_36610_).getTarget() : null)) {
return false;
} else if (this.periodicTick.isPresent() && p_36610_.tickCount % this.periodicTick.get() != 0) {
return false;
} else {
if (this.team.isPresent()) {
Team team = p_36610_.getTeam();
if (team == null || !this.team.get().equals(team.getName())) {
return false;
}
}
if (this.slots.isPresent() && !this.slots.get().matches(p_36610_)) {
return false;
} else {
return !this.components.test((DataComponentGetter)p_36610_) ? false : this.nbt.isEmpty() || this.nbt.get().matches(p_36610_);
}
}
}
}
}
public static LootContext createContext(ServerPlayer p_36617_, Entity p_36618_) {
LootParams lootparams = new LootParams.Builder(p_36617_.serverLevel())
.withParameter(LootContextParams.THIS_ENTITY, p_36618_)
.withParameter(LootContextParams.ORIGIN, p_36617_.position())
.create(LootContextParamSets.ADVANCEMENT_ENTITY);
return new LootContext.Builder(lootparams).create(Optional.empty());
}
public static class Builder {
private Optional<EntityTypePredicate> entityType = Optional.empty();
private Optional<DistancePredicate> distanceToPlayer = Optional.empty();
private Optional<MovementPredicate> movement = Optional.empty();
private Optional<LocationPredicate> located = Optional.empty();
private Optional<LocationPredicate> steppingOnLocation = Optional.empty();
private Optional<LocationPredicate> movementAffectedBy = Optional.empty();
private Optional<MobEffectsPredicate> effects = Optional.empty();
private Optional<NbtPredicate> nbt = Optional.empty();
private Optional<EntityFlagsPredicate> flags = Optional.empty();
private Optional<EntityEquipmentPredicate> equipment = Optional.empty();
private Optional<EntitySubPredicate> subPredicate = Optional.empty();
private Optional<Integer> periodicTick = Optional.empty();
private Optional<EntityPredicate> vehicle = Optional.empty();
private Optional<EntityPredicate> passenger = Optional.empty();
private Optional<EntityPredicate> targetedEntity = Optional.empty();
private Optional<String> team = Optional.empty();
private Optional<SlotsPredicate> slots = Optional.empty();
private DataComponentMatchers components = DataComponentMatchers.ANY;
public static EntityPredicate.Builder entity() {
return new EntityPredicate.Builder();
}
public EntityPredicate.Builder of(HolderGetter<EntityType<?>> p_370143_, EntityType<?> p_36637_) {
this.entityType = Optional.of(EntityTypePredicate.of(p_370143_, p_36637_));
return this;
}
public EntityPredicate.Builder of(HolderGetter<EntityType<?>> p_361882_, TagKey<EntityType<?>> p_204078_) {
this.entityType = Optional.of(EntityTypePredicate.of(p_361882_, p_204078_));
return this;
}
public EntityPredicate.Builder entityType(EntityTypePredicate p_36647_) {
this.entityType = Optional.of(p_36647_);
return this;
}
public EntityPredicate.Builder distance(DistancePredicate p_36639_) {
this.distanceToPlayer = Optional.of(p_36639_);
return this;
}
public EntityPredicate.Builder moving(MovementPredicate p_342759_) {
this.movement = Optional.of(p_342759_);
return this;
}
public EntityPredicate.Builder located(LocationPredicate.Builder p_297650_) {
this.located = Optional.of(p_297650_.build());
return this;
}
public EntityPredicate.Builder steppingOn(LocationPredicate.Builder p_298486_) {
this.steppingOnLocation = Optional.of(p_298486_.build());
return this;
}
public EntityPredicate.Builder movementAffectedBy(LocationPredicate.Builder p_344369_) {
this.movementAffectedBy = Optional.of(p_344369_.build());
return this;
}
public EntityPredicate.Builder effects(MobEffectsPredicate.Builder p_300139_) {
this.effects = p_300139_.build();
return this;
}
public EntityPredicate.Builder nbt(NbtPredicate p_36655_) {
this.nbt = Optional.of(p_36655_);
return this;
}
public EntityPredicate.Builder flags(EntityFlagsPredicate.Builder p_300535_) {
this.flags = Optional.of(p_300535_.build());
return this;
}
public EntityPredicate.Builder equipment(EntityEquipmentPredicate.Builder p_297462_) {
this.equipment = Optional.of(p_297462_.build());
return this;
}
public EntityPredicate.Builder equipment(EntityEquipmentPredicate p_36641_) {
this.equipment = Optional.of(p_36641_);
return this;
}
public EntityPredicate.Builder subPredicate(EntitySubPredicate p_218801_) {
this.subPredicate = Optional.of(p_218801_);
return this;
}
public EntityPredicate.Builder periodicTick(int p_343808_) {
this.periodicTick = Optional.of(p_343808_);
return this;
}
public EntityPredicate.Builder vehicle(EntityPredicate.Builder p_300159_) {
this.vehicle = Optional.of(p_300159_.build());
return this;
}
public EntityPredicate.Builder passenger(EntityPredicate.Builder p_297891_) {
this.passenger = Optional.of(p_297891_.build());
return this;
}
public EntityPredicate.Builder targetedEntity(EntityPredicate.Builder p_298127_) {
this.targetedEntity = Optional.of(p_298127_.build());
return this;
}
public EntityPredicate.Builder team(String p_36659_) {
this.team = Optional.of(p_36659_);
return this;
}
public EntityPredicate.Builder slots(SlotsPredicate p_330666_) {
this.slots = Optional.of(p_330666_);
return this;
}
public EntityPredicate.Builder components(DataComponentMatchers p_395894_) {
this.components = p_395894_;
return this;
}
public EntityPredicate build() {
return new EntityPredicate(
this.entityType,
this.distanceToPlayer,
this.movement,
new EntityPredicate.LocationWrapper(this.located, this.steppingOnLocation, this.movementAffectedBy),
this.effects,
this.nbt,
this.flags,
this.equipment,
this.subPredicate,
this.periodicTick,
this.vehicle,
this.passenger,
this.targetedEntity,
this.team,
this.slots,
this.components
);
}
}
public record LocationWrapper(Optional<LocationPredicate> located, Optional<LocationPredicate> steppingOn, Optional<LocationPredicate> affectsMovement) {
public static final MapCodec<EntityPredicate.LocationWrapper> CODEC = RecordCodecBuilder.mapCodec(
p_343798_ -> p_343798_.group(
LocationPredicate.CODEC.optionalFieldOf("location").forGetter(EntityPredicate.LocationWrapper::located),
LocationPredicate.CODEC.optionalFieldOf("stepping_on").forGetter(EntityPredicate.LocationWrapper::steppingOn),
LocationPredicate.CODEC.optionalFieldOf("movement_affected_by").forGetter(EntityPredicate.LocationWrapper::affectsMovement)
)
.apply(p_343798_, EntityPredicate.LocationWrapper::new)
);
}
}