StatePropertiesPredicate.java

net.minecraft.advancements.criterion.StatePropertiesPredicate

信息

  • 全限定名:net.minecraft.advancements.criterion.StatePropertiesPredicate
  • 类型:public record
  • 包:net.minecraft.advancements.criterion
  • 源码路径:src/main/java/net/minecraft/advancements/criterion/StatePropertiesPredicate.java
  • 起始行号:L20
  • 职责:

    TODO

字段/常量

  • PROPERTIES_CODEC

    • 类型: Codec<List<StatePropertiesPredicate.PropertyMatcher>>
    • 修饰符: private static final
    • 源码定位: L21
    • 说明:

      TODO

  • CODEC

    • 类型: Codec<StatePropertiesPredicate>
    • 修饰符: public static final
    • 源码定位: L29
    • 说明:

      TODO

  • STREAM_CODEC

    • 类型: StreamCodec<ByteBuf,StatePropertiesPredicate>
    • 修饰符: public static final
    • 源码定位: L30
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.advancements.criterion.StatePropertiesPredicate.Builder

    • 类型: class
    • 修饰符: public static
    • 源码定位: L63
    • 说明:

      TODO

  • net.minecraft.advancements.criterion.StatePropertiesPredicate.ExactMatcher

    • 类型: record
    • 修饰符: private
    • 源码定位: L95
    • 说明:

      TODO

  • net.minecraft.advancements.criterion.StatePropertiesPredicate.PropertyMatcher

    • 类型: record
    • 修饰符: private
    • 源码定位: L109
    • 说明:

      TODO

  • net.minecraft.advancements.criterion.StatePropertiesPredicate.RangedMatcher

    • 类型: record
    • 修饰符: private
    • 源码定位: L129
    • 说明:

      TODO

  • net.minecraft.advancements.criterion.StatePropertiesPredicate.ValueMatcher

    • 类型: interface
    • 修饰符: private
    • 源码定位: L166
    • 说明:

      TODO

构造器

方法

下面的方法块按源码顺序生成。

public <S extends StateHolder<?,S>> boolean matches(StateDefinition<?,S> definition, S state) @ L34

  • 方法名:matches
  • 源码定位:L34
  • 返回类型:<S extends StateHolder<?,S>> boolean
  • 修饰符:public

参数:

  • definition: StateDefinition<?,S>
  • state: S

说明:

TODO

public boolean matches(BlockState state) @ L44

  • 方法名:matches
  • 源码定位:L44
  • 返回类型:boolean
  • 修饰符:public

参数:

  • state: BlockState

说明:

TODO

public boolean matches(FluidState state) @ L48

  • 方法名:matches
  • 源码定位:L48
  • 返回类型:boolean
  • 修饰符:public

参数:

  • state: FluidState

说明:

TODO

public Optional<String> checkState(StateDefinition<?,?> states) @ L52

  • 方法名:checkState
  • 源码定位:L52
  • 返回类型:Optional
  • 修饰符:public

参数:

  • states: StateDefinition

说明:

TODO

代码

public record StatePropertiesPredicate(List<StatePropertiesPredicate.PropertyMatcher> properties) {
    private static final Codec<List<StatePropertiesPredicate.PropertyMatcher>> PROPERTIES_CODEC = Codec.unboundedMap(
            Codec.STRING, StatePropertiesPredicate.ValueMatcher.CODEC
        )
        .xmap(
            map -> map.entrySet().stream().map(entry -> new StatePropertiesPredicate.PropertyMatcher(entry.getKey(), entry.getValue())).toList(),
            properties -> properties.stream()
                .collect(Collectors.toMap(StatePropertiesPredicate.PropertyMatcher::name, StatePropertiesPredicate.PropertyMatcher::valueMatcher))
        );
    public static final Codec<StatePropertiesPredicate> CODEC = PROPERTIES_CODEC.xmap(StatePropertiesPredicate::new, StatePropertiesPredicate::properties);
    public static final StreamCodec<ByteBuf, StatePropertiesPredicate> STREAM_CODEC = StatePropertiesPredicate.PropertyMatcher.STREAM_CODEC
        .apply(ByteBufCodecs.list())
        .map(StatePropertiesPredicate::new, StatePropertiesPredicate::properties);
 
    public <S extends StateHolder<?, S>> boolean matches(StateDefinition<?, S> definition, S state) {
        for (StatePropertiesPredicate.PropertyMatcher matcher : this.properties) {
            if (!matcher.match(definition, state)) {
                return false;
            }
        }
 
        return true;
    }
 
    public boolean matches(BlockState state) {
        return this.matches(state.getBlock().getStateDefinition(), state);
    }
 
    public boolean matches(FluidState state) {
        return this.matches(state.getType().getStateDefinition(), state);
    }
 
    public Optional<String> checkState(StateDefinition<?, ?> states) {
        for (StatePropertiesPredicate.PropertyMatcher property : this.properties) {
            Optional<String> unknownProperty = property.checkState(states);
            if (unknownProperty.isPresent()) {
                return unknownProperty;
            }
        }
 
        return Optional.empty();
    }
 
    public static class Builder {
        private final ImmutableList.Builder<StatePropertiesPredicate.PropertyMatcher> matchers = ImmutableList.builder();
 
        private Builder() {
        }
 
        public static StatePropertiesPredicate.Builder properties() {
            return new StatePropertiesPredicate.Builder();
        }
 
        public StatePropertiesPredicate.Builder hasProperty(Property<?> property, String value) {
            this.matchers.add(new StatePropertiesPredicate.PropertyMatcher(property.getName(), new StatePropertiesPredicate.ExactMatcher(value)));
            return this;
        }
 
        public StatePropertiesPredicate.Builder hasProperty(Property<Integer> property, int value) {
            return this.hasProperty(property, Integer.toString(value));
        }
 
        public StatePropertiesPredicate.Builder hasProperty(Property<Boolean> property, boolean value) {
            return this.hasProperty(property, Boolean.toString(value));
        }
 
        public <T extends Comparable<T> & StringRepresentable> StatePropertiesPredicate.Builder hasProperty(Property<T> property, T value) {
            return this.hasProperty(property, value.getSerializedName());
        }
 
        public Optional<StatePropertiesPredicate> build() {
            return Optional.of(new StatePropertiesPredicate(this.matchers.build()));
        }
    }
 
    private record ExactMatcher(String value) implements StatePropertiesPredicate.ValueMatcher {
        public static final Codec<StatePropertiesPredicate.ExactMatcher> CODEC = Codec.STRING
            .xmap(StatePropertiesPredicate.ExactMatcher::new, StatePropertiesPredicate.ExactMatcher::value);
        public static final StreamCodec<ByteBuf, StatePropertiesPredicate.ExactMatcher> STREAM_CODEC = ByteBufCodecs.STRING_UTF8
            .map(StatePropertiesPredicate.ExactMatcher::new, StatePropertiesPredicate.ExactMatcher::value);
 
        @Override
        public <T extends Comparable<T>> boolean match(StateHolder<?, ?> state, Property<T> property) {
            T actualValue = state.getValue(property);
            Optional<T> typedExpected = property.getValue(this.value);
            return typedExpected.isPresent() && actualValue.compareTo(typedExpected.get()) == 0;
        }
    }
 
    private record PropertyMatcher(String name, StatePropertiesPredicate.ValueMatcher valueMatcher) {
        public static final StreamCodec<ByteBuf, StatePropertiesPredicate.PropertyMatcher> STREAM_CODEC = StreamCodec.composite(
            ByteBufCodecs.STRING_UTF8,
            StatePropertiesPredicate.PropertyMatcher::name,
            StatePropertiesPredicate.ValueMatcher.STREAM_CODEC,
            StatePropertiesPredicate.PropertyMatcher::valueMatcher,
            StatePropertiesPredicate.PropertyMatcher::new
        );
 
        public <S extends StateHolder<?, S>> boolean match(StateDefinition<?, S> definition, S state) {
            Property<?> property = definition.getProperty(this.name);
            return property != null && this.valueMatcher.match(state, property);
        }
 
        public Optional<String> checkState(StateDefinition<?, ?> states) {
            Property<?> property = states.getProperty(this.name);
            return property != null ? Optional.empty() : Optional.of(this.name);
        }
    }
 
    private record RangedMatcher(Optional<String> minValue, Optional<String> maxValue) implements StatePropertiesPredicate.ValueMatcher {
        public static final Codec<StatePropertiesPredicate.RangedMatcher> CODEC = RecordCodecBuilder.create(
            i -> i.group(
                    Codec.STRING.optionalFieldOf("min").forGetter(StatePropertiesPredicate.RangedMatcher::minValue),
                    Codec.STRING.optionalFieldOf("max").forGetter(StatePropertiesPredicate.RangedMatcher::maxValue)
                )
                .apply(i, StatePropertiesPredicate.RangedMatcher::new)
        );
        public static final StreamCodec<ByteBuf, StatePropertiesPredicate.RangedMatcher> STREAM_CODEC = StreamCodec.composite(
            ByteBufCodecs.optional(ByteBufCodecs.STRING_UTF8),
            StatePropertiesPredicate.RangedMatcher::minValue,
            ByteBufCodecs.optional(ByteBufCodecs.STRING_UTF8),
            StatePropertiesPredicate.RangedMatcher::maxValue,
            StatePropertiesPredicate.RangedMatcher::new
        );
 
        @Override
        public <T extends Comparable<T>> boolean match(StateHolder<?, ?> state, Property<T> property) {
            T value = state.getValue(property);
            if (this.minValue.isPresent()) {
                Optional<T> typedMinValue = property.getValue(this.minValue.get());
                if (typedMinValue.isEmpty() || value.compareTo(typedMinValue.get()) < 0) {
                    return false;
                }
            }
 
            if (this.maxValue.isPresent()) {
                Optional<T> typedMaxValue = property.getValue(this.maxValue.get());
                if (typedMaxValue.isEmpty() || value.compareTo(typedMaxValue.get()) > 0) {
                    return false;
                }
            }
 
            return true;
        }
    }
 
    private interface ValueMatcher {
        Codec<StatePropertiesPredicate.ValueMatcher> CODEC = Codec.either(
                StatePropertiesPredicate.ExactMatcher.CODEC, StatePropertiesPredicate.RangedMatcher.CODEC
            )
            .xmap(Either::unwrap, matcher -> {
                if (matcher instanceof StatePropertiesPredicate.ExactMatcher exact) {
                    return Either.left(exact);
                } else if (matcher instanceof StatePropertiesPredicate.RangedMatcher ranged) {
                    return Either.right(ranged);
                } else {
                    throw new UnsupportedOperationException();
                }
            });
        StreamCodec<ByteBuf, StatePropertiesPredicate.ValueMatcher> STREAM_CODEC = ByteBufCodecs.either(
                StatePropertiesPredicate.ExactMatcher.STREAM_CODEC, StatePropertiesPredicate.RangedMatcher.STREAM_CODEC
            )
            .map(Either::unwrap, matcher -> {
                if (matcher instanceof StatePropertiesPredicate.ExactMatcher exact) {
                    return Either.left(exact);
                } else if (matcher instanceof StatePropertiesPredicate.RangedMatcher ranged) {
                    return Either.right(ranged);
                } else {
                    throw new UnsupportedOperationException();
                }
            });
 
        <T extends Comparable<T>> boolean match(StateHolder<?, ?> state, Property<T> property);
    }
}

引用的其他类