PlayerPredicate.java
net.minecraft.advancements.criterion.PlayerPredicate
信息
- 全限定名:net.minecraft.advancements.criterion.PlayerPredicate
- 类型:public record
- 包:net.minecraft.advancements.criterion
- 源码路径:src/main/java/net/minecraft/advancements/criterion/PlayerPredicate.java
- 起始行号:L46
- 实现:EntitySubPredicate
- 职责:
TODO
字段/常量
-
LOOKING_AT_RANGE- 类型:
int - 修饰符:
public static final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
CODEC- 类型:
MapCodec<PlayerPredicate> - 修饰符:
public static final - 源码定位:
L57 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.advancements.criterion.PlayerPredicate.AdvancementCriterionsPredicate- 类型:
record - 修饰符:
private - 源码定位:
L138 - 说明:
TODO
- 类型:
-
net.minecraft.advancements.criterion.PlayerPredicate.AdvancementDonePredicate- 类型:
record - 修饰符:
private - 源码定位:
L154 - 说明:
TODO
- 类型:
-
net.minecraft.advancements.criterion.PlayerPredicate.AdvancementPredicate- 类型:
interface - 修饰符:
private - 源码定位:
L163 - 说明:
TODO
- 类型:
-
net.minecraft.advancements.criterion.PlayerPredicate.Builder- 类型:
class - 修饰符:
public static - 源码定位:
L178 - 说明:
TODO
- 类型:
-
net.minecraft.advancements.criterion.PlayerPredicate.StatMatcher- 类型:
record - 修饰符:
private - 源码定位:
L242 - 说明:
TODO
- 类型:
构造器
- 无
方法
下面的方法块按源码顺序生成。
public boolean matches(Entity entity, ServerLevel level, Vec3 position) @ L73
- 方法名:matches
- 源码定位:L73
- 返回类型:boolean
- 修饰符:public
参数:
- entity: Entity
- level: ServerLevel
- position: Vec3
说明:
TODO
public MapCodec<PlayerPredicate> codec() @ L133
- 方法名:codec
- 源码定位:L133
- 返回类型:MapCodec
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public record PlayerPredicate(
MinMaxBounds.Ints level,
FoodPredicate food,
GameTypePredicate gameType,
List<PlayerPredicate.StatMatcher<?>> stats,
Object2BooleanMap<ResourceKey<Recipe<?>>> recipes,
Map<Identifier, PlayerPredicate.AdvancementPredicate> advancements,
Optional<EntityPredicate> lookingAt,
Optional<InputPredicate> input
) implements EntitySubPredicate {
public static final int LOOKING_AT_RANGE = 100;
public static final MapCodec<PlayerPredicate> CODEC = RecordCodecBuilder.mapCodec(
i -> i.group(
MinMaxBounds.Ints.CODEC.optionalFieldOf("level", MinMaxBounds.Ints.ANY).forGetter(PlayerPredicate::level),
FoodPredicate.CODEC.optionalFieldOf("food", FoodPredicate.ANY).forGetter(PlayerPredicate::food),
GameTypePredicate.CODEC.optionalFieldOf("gamemode", GameTypePredicate.ANY).forGetter(PlayerPredicate::gameType),
PlayerPredicate.StatMatcher.CODEC.listOf().optionalFieldOf("stats", List.of()).forGetter(PlayerPredicate::stats),
ExtraCodecs.object2BooleanMap(Recipe.KEY_CODEC).optionalFieldOf("recipes", Object2BooleanMaps.emptyMap()).forGetter(PlayerPredicate::recipes),
Codec.unboundedMap(Identifier.CODEC, PlayerPredicate.AdvancementPredicate.CODEC)
.optionalFieldOf("advancements", Map.of())
.forGetter(PlayerPredicate::advancements),
EntityPredicate.CODEC.optionalFieldOf("looking_at").forGetter(PlayerPredicate::lookingAt),
InputPredicate.CODEC.optionalFieldOf("input").forGetter(PlayerPredicate::input)
)
.apply(i, PlayerPredicate::new)
);
@Override
public boolean matches(Entity entity, ServerLevel level, @Nullable Vec3 position) {
if (!(entity instanceof ServerPlayer player)) {
return false;
} else if (!this.level.matches(player.experienceLevel)) {
return false;
} else if (!this.food.matches(player.getFoodData())) {
return false;
} else if (!this.gameType.matches(player.gameMode())) {
return false;
} else {
StatsCounter stats = player.getStats();
for (PlayerPredicate.StatMatcher<?> stat : this.stats) {
if (!stat.matches(stats)) {
return false;
}
}
ServerRecipeBook recipes = player.getRecipeBook();
for (Entry<ResourceKey<Recipe<?>>> e : this.recipes.object2BooleanEntrySet()) {
if (recipes.contains(e.getKey()) != e.getBooleanValue()) {
return false;
}
}
if (!this.advancements.isEmpty()) {
PlayerAdvancements advancements = player.getAdvancements();
ServerAdvancementManager serverAdvancements = player.level().getServer().getAdvancements();
for (java.util.Map.Entry<Identifier, PlayerPredicate.AdvancementPredicate> entry : this.advancements.entrySet()) {
AdvancementHolder advancement = serverAdvancements.get(entry.getKey());
if (advancement == null || !entry.getValue().test(advancements.getOrStartProgress(advancement))) {
return false;
}
}
}
if (this.lookingAt.isPresent()) {
Vec3 from = player.getEyePosition();
Vec3 viewVec = player.getViewVector(1.0F);
Vec3 to = from.add(viewVec.x * 100.0, viewVec.y * 100.0, viewVec.z * 100.0);
EntityHitResult lookingAtResult = ProjectileUtil.getEntityHitResult(
player.level(), player, from, to, new AABB(from, to).inflate(1.0), ex -> !ex.isSpectator(), 0.0F
);
if (lookingAtResult == null || lookingAtResult.getType() != HitResult.Type.ENTITY) {
return false;
}
Entity lookingAtEntity = lookingAtResult.getEntity();
if (!this.lookingAt.get().matches(player, lookingAtEntity) || !player.hasLineOfSight(lookingAtEntity)) {
return false;
}
}
return !this.input.isPresent() || this.input.get().matches(player.getLastClientInput());
}
}
@Override
public MapCodec<PlayerPredicate> codec() {
return EntitySubPredicates.PLAYER;
}
private record AdvancementCriterionsPredicate(Object2BooleanMap<String> criterions) implements PlayerPredicate.AdvancementPredicate {
public static final Codec<PlayerPredicate.AdvancementCriterionsPredicate> CODEC = ExtraCodecs.object2BooleanMap(Codec.STRING)
.xmap(PlayerPredicate.AdvancementCriterionsPredicate::new, PlayerPredicate.AdvancementCriterionsPredicate::criterions);
public boolean test(AdvancementProgress progress) {
for (Entry<String> e : this.criterions.object2BooleanEntrySet()) {
CriterionProgress criterion = progress.getCriterion(e.getKey());
if (criterion == null || criterion.isDone() != e.getBooleanValue()) {
return false;
}
}
return true;
}
}
private record AdvancementDonePredicate(boolean state) implements PlayerPredicate.AdvancementPredicate {
public static final Codec<PlayerPredicate.AdvancementDonePredicate> CODEC = Codec.BOOL
.xmap(PlayerPredicate.AdvancementDonePredicate::new, PlayerPredicate.AdvancementDonePredicate::state);
public boolean test(AdvancementProgress progress) {
return progress.isDone() == this.state;
}
}
private interface AdvancementPredicate extends Predicate<AdvancementProgress> {
Codec<PlayerPredicate.AdvancementPredicate> CODEC = Codec.either(
PlayerPredicate.AdvancementDonePredicate.CODEC, PlayerPredicate.AdvancementCriterionsPredicate.CODEC
)
.xmap(Either::unwrap, predicate -> {
if (predicate instanceof PlayerPredicate.AdvancementDonePredicate done) {
return Either.left(done);
} else if (predicate instanceof PlayerPredicate.AdvancementCriterionsPredicate criterions) {
return Either.right(criterions);
} else {
throw new UnsupportedOperationException();
}
});
}
public static class Builder {
private MinMaxBounds.Ints level = MinMaxBounds.Ints.ANY;
private FoodPredicate food = FoodPredicate.ANY;
private GameTypePredicate gameType = GameTypePredicate.ANY;
private final ImmutableList.Builder<PlayerPredicate.StatMatcher<?>> stats = ImmutableList.builder();
private final Object2BooleanMap<ResourceKey<Recipe<?>>> recipes = new Object2BooleanOpenHashMap<>();
private final Map<Identifier, PlayerPredicate.AdvancementPredicate> advancements = Maps.newHashMap();
private Optional<EntityPredicate> lookingAt = Optional.empty();
private Optional<InputPredicate> input = Optional.empty();
public static PlayerPredicate.Builder player() {
return new PlayerPredicate.Builder();
}
public PlayerPredicate.Builder setLevel(MinMaxBounds.Ints level) {
this.level = level;
return this;
}
public PlayerPredicate.Builder setFood(FoodPredicate food) {
this.food = food;
return this;
}
public <T> PlayerPredicate.Builder addStat(StatType<T> type, Holder.Reference<T> value, MinMaxBounds.Ints range) {
this.stats.add(new PlayerPredicate.StatMatcher<>(type, value, range));
return this;
}
public PlayerPredicate.Builder addRecipe(ResourceKey<Recipe<?>> recipe, boolean present) {
this.recipes.put(recipe, present);
return this;
}
public PlayerPredicate.Builder setGameType(GameTypePredicate gameType) {
this.gameType = gameType;
return this;
}
public PlayerPredicate.Builder setLookingAt(EntityPredicate.Builder lookingAt) {
this.lookingAt = Optional.of(lookingAt.build());
return this;
}
public PlayerPredicate.Builder checkAdvancementDone(Identifier advancement, boolean isDone) {
this.advancements.put(advancement, new PlayerPredicate.AdvancementDonePredicate(isDone));
return this;
}
public PlayerPredicate.Builder checkAdvancementCriterions(Identifier advancement, Map<String, Boolean> criterions) {
this.advancements.put(advancement, new PlayerPredicate.AdvancementCriterionsPredicate(new Object2BooleanOpenHashMap<>(criterions)));
return this;
}
public PlayerPredicate.Builder hasInput(InputPredicate input) {
this.input = Optional.of(input);
return this;
}
public PlayerPredicate build() {
return new PlayerPredicate(this.level, this.food, this.gameType, this.stats.build(), this.recipes, this.advancements, this.lookingAt, this.input);
}
}
private record StatMatcher<T>(StatType<T> type, Holder<T> value, MinMaxBounds.Ints range, Supplier<Stat<T>> stat) {
public static final Codec<PlayerPredicate.StatMatcher<?>> CODEC = BuiltInRegistries.STAT_TYPE
.byNameCodec()
.dispatch(PlayerPredicate.StatMatcher::type, PlayerPredicate.StatMatcher::createTypedCodec);
public StatMatcher(StatType<T> type, Holder<T> value, MinMaxBounds.Ints range) {
this(type, value, range, Suppliers.memoize(() -> type.get(value.value())));
}
private static <T> MapCodec<PlayerPredicate.StatMatcher<T>> createTypedCodec(StatType<T> type) {
return RecordCodecBuilder.mapCodec(
i -> i.group(
type.getRegistry()
.holderByNameCodec()
.fieldOf("stat")
.forGetter(PlayerPredicate.StatMatcher::value),
MinMaxBounds.Ints.CODEC
.optionalFieldOf("value", MinMaxBounds.Ints.ANY)
.forGetter(PlayerPredicate.StatMatcher::range)
)
.apply(i, (value, range) -> new PlayerPredicate.StatMatcher<>(type, value, range))
);
}
public boolean matches(StatsCounter counter) {
return this.range.matches(counter.getValue(this.stat.get()));
}
}
}引用的其他类
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ExtraCodecs.object2BooleanMap()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ProjectileUtil.getEntityHitResult()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
AABB()
- 引用位置:
-
- 引用位置:
参数
- 引用位置: