MinMaxBounds.java

net.minecraft.advancements.criterion.MinMaxBounds

信息

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

    TODO

字段/常量

  • ERROR_EMPTY

    • 类型: SimpleCommandExceptionType
    • 修饰符: package-private
    • 源码定位: L22
    • 说明:

      TODO

  • ERROR_SWAPPED

    • 类型: SimpleCommandExceptionType
    • 修饰符: package-private
    • 源码定位: L23
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.advancements.criterion.MinMaxBounds.Bounds

    • 类型: record
    • 修饰符: public
    • 源码定位: L49
    • 说明:

      TODO

  • net.minecraft.advancements.criterion.MinMaxBounds.Doubles

    • 类型: record
    • 修饰符: public
    • 源码定位: L201
    • 说明:

      TODO

  • net.minecraft.advancements.criterion.MinMaxBounds.FloatDegrees

    • 类型: record
    • 修饰符: public
    • 源码定位: L253
    • 说明:

      TODO

  • net.minecraft.advancements.criterion.MinMaxBounds.Ints

    • 类型: record
    • 修饰符: public
    • 源码定位: L268
    • 说明:

      TODO

构造器

方法

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

MinMaxBounds.Bounds<T> bounds() @ L25

  • 方法名:bounds
  • 源码定位:L25
  • 返回类型:MinMaxBounds.Bounds
  • 修饰符:package-private

参数:

说明:

TODO

default Optional<T> min() @ L27

  • 方法名:min
  • 源码定位:L27
  • 返回类型:Optional
  • 修饰符:default

参数:

说明:

TODO

default Optional<T> max() @ L31

  • 方法名:max
  • 源码定位:L31
  • 返回类型:Optional
  • 修饰符:default

参数:

说明:

TODO

default boolean isAny() @ L35

  • 方法名:isAny
  • 源码定位:L35
  • 返回类型:boolean
  • 修饰符:default

参数:

说明:

TODO

static <V extends Number &Comparable<V>,B extends MinMaxBounds<V>> Function<B,DataResult<B>> validateContainedInRange(MinMaxBounds<V> allowed) @ L39

  • 方法名:validateContainedInRange
  • 源码定位:L39
  • 返回类型:<V extends Number &Comparable,B extends MinMaxBounds> Function<B,DataResult>
  • 修饰符:static

参数:

  • allowed: MinMaxBounds

说明:

TODO

代码

public interface MinMaxBounds<T extends Number & Comparable<T>> {
    SimpleCommandExceptionType ERROR_EMPTY = new SimpleCommandExceptionType(Component.translatable("argument.range.empty"));
    SimpleCommandExceptionType ERROR_SWAPPED = new SimpleCommandExceptionType(Component.translatable("argument.range.swapped"));
 
    MinMaxBounds.Bounds<T> bounds();
 
    default Optional<T> min() {
        return this.bounds().min;
    }
 
    default Optional<T> max() {
        return this.bounds().max;
    }
 
    default boolean isAny() {
        return this.bounds().isAny();
    }
 
    static <V extends Number & Comparable<V>, B extends MinMaxBounds<V>> Function<B, DataResult<B>> validateContainedInRange(MinMaxBounds<V> allowed) {
        Range<V> allowedRange = allowed.bounds().asRange();
        return target -> {
            Range<V> selfAsRange = target.bounds().asRange();
            return !allowedRange.encloses(selfAsRange)
                ? DataResult.error(() -> "Range must be within " + allowedRange + ", but was " + selfAsRange)
                : DataResult.success(target);
        };
    }
 
    public record Bounds<T extends Number & Comparable<T>>(Optional<T> min, Optional<T> max) {
        public boolean isAny() {
            return this.min().isEmpty() && this.max().isEmpty();
        }
 
        public DataResult<MinMaxBounds.Bounds<T>> validateSwappedBoundsInCodec() {
            return this.areSwapped()
                ? DataResult.error(() -> "Swapped bounds in range: " + this.min() + " is higher than " + this.max())
                : DataResult.success(this);
        }
 
        public boolean areSwapped() {
            return this.min.isPresent() && this.max.isPresent() && this.min.get().compareTo(this.max.get()) > 0;
        }
 
        public Range<T> asRange() {
            if (this.min.isPresent()) {
                return this.max.isPresent() ? Range.closed(this.min.get(), this.max.get()) : Range.atLeast(this.min.get());
            } else {
                return this.max.isPresent() ? Range.atMost(this.max.get()) : Range.all();
            }
        }
 
        public Optional<T> asPoint() {
            Optional<T> min = this.min();
            Optional<T> max = this.max();
            return min.equals(max) ? min : Optional.empty();
        }
 
        public static <T extends Number & Comparable<T>> MinMaxBounds.Bounds<T> any() {
            return new MinMaxBounds.Bounds<T>(Optional.empty(), Optional.empty());
        }
 
        public static <T extends Number & Comparable<T>> MinMaxBounds.Bounds<T> exactly(T value) {
            Optional<T> wrapped = Optional.of(value);
            return new MinMaxBounds.Bounds<>(wrapped, wrapped);
        }
 
        public static <T extends Number & Comparable<T>> MinMaxBounds.Bounds<T> between(T min, T max) {
            return new MinMaxBounds.Bounds<>(Optional.of(min), Optional.of(max));
        }
 
        public static <T extends Number & Comparable<T>> MinMaxBounds.Bounds<T> atLeast(T value) {
            return new MinMaxBounds.Bounds<>(Optional.of(value), Optional.empty());
        }
 
        public static <T extends Number & Comparable<T>> MinMaxBounds.Bounds<T> atMost(T value) {
            return new MinMaxBounds.Bounds<>(Optional.empty(), Optional.of(value));
        }
 
        public <U extends Number & Comparable<U>> MinMaxBounds.Bounds<U> map(Function<T, U> mapper) {
            return new MinMaxBounds.Bounds<>(this.min.map(mapper), this.max.map(mapper));
        }
 
        static <T extends Number & Comparable<T>> Codec<MinMaxBounds.Bounds<T>> createCodec(Codec<T> numberCodec) {
            Codec<MinMaxBounds.Bounds<T>> rangeCodec = RecordCodecBuilder.create(
                i -> i.group(
                        numberCodec.optionalFieldOf("min").forGetter(MinMaxBounds.Bounds::min),
                        numberCodec.optionalFieldOf("max").forGetter(MinMaxBounds.Bounds::max)
                    )
                    .apply(i, MinMaxBounds.Bounds::new)
            );
            return Codec.either(rangeCodec, numberCodec).xmap(either -> either.map(v -> v, x$0 -> exactly((T)x$0)), bounds -> {
                Optional<T> point = bounds.asPoint();
                return point.isPresent() ? Either.right(point.get()) : Either.left((MinMaxBounds.Bounds<T>)bounds);
            });
        }
 
        static <B extends ByteBuf, T extends Number & Comparable<T>> StreamCodec<B, MinMaxBounds.Bounds<T>> createStreamCodec(StreamCodec<B, T> numberCodec) {
            return new StreamCodec<B, MinMaxBounds.Bounds<T>>() {
                private static final int MIN_FLAG = 1;
                private static final int MAX_FLAG = 2;
 
                public MinMaxBounds.Bounds<T> decode(B input) {
                    byte flags = input.readByte();
                    Optional<T> min = (flags & 1) != 0 ? Optional.of(numberCodec.decode(input)) : Optional.empty();
                    Optional<T> max = (flags & 2) != 0 ? Optional.of(numberCodec.decode(input)) : Optional.empty();
                    return new MinMaxBounds.Bounds<>(min, max);
                }
 
                public void encode(B output, MinMaxBounds.Bounds<T> value) {
                    Optional<T> min = value.min();
                    Optional<T> max = value.max();
                    output.writeByte((min.isPresent() ? 1 : 0) | (max.isPresent() ? 2 : 0));
                    min.ifPresent(v -> numberCodec.encode(output, (T)v));
                    max.ifPresent(v -> numberCodec.encode(output, (T)v));
                }
            };
        }
 
        public static <T extends Number & Comparable<T>> MinMaxBounds.Bounds<T> fromReader(
            StringReader reader, Function<String, T> converter, Supplier<DynamicCommandExceptionType> parseExc
        ) throws CommandSyntaxException {
            if (!reader.canRead()) {
                throw MinMaxBounds.ERROR_EMPTY.createWithContext(reader);
            } else {
                int start = reader.getCursor();
 
                try {
                    Optional<T> min = readNumber(reader, converter, parseExc);
                    Optional<T> max;
                    if (reader.canRead(2) && reader.peek() == '.' && reader.peek(1) == '.') {
                        reader.skip();
                        reader.skip();
                        max = readNumber(reader, converter, parseExc);
                    } else {
                        max = min;
                    }
 
                    if (min.isEmpty() && max.isEmpty()) {
                        throw MinMaxBounds.ERROR_EMPTY.createWithContext(reader);
                    } else {
                        return new MinMaxBounds.Bounds<>(min, max);
                    }
                } catch (CommandSyntaxException var6) {
                    reader.setCursor(start);
                    throw new CommandSyntaxException(var6.getType(), var6.getRawMessage(), var6.getInput(), start);
                }
            }
        }
 
        private static <T extends Number> Optional<T> readNumber(
            StringReader reader, Function<String, T> converter, Supplier<DynamicCommandExceptionType> parseExc
        ) throws CommandSyntaxException {
            int start = reader.getCursor();
 
            while (reader.canRead() && isAllowedInputChar(reader)) {
                reader.skip();
            }
 
            String number = reader.getString().substring(start, reader.getCursor());
            if (number.isEmpty()) {
                return Optional.empty();
            } else {
                try {
                    return Optional.of(converter.apply(number));
                } catch (NumberFormatException var6) {
                    throw parseExc.get().createWithContext(reader, number);
                }
            }
        }
 
        private static boolean isAllowedInputChar(StringReader reader) {
            char c = reader.peek();
            if ((c < '0' || c > '9') && c != '-') {
                return c != '.' ? false : !reader.canRead(2) || reader.peek(1) != '.';
            } else {
                return true;
            }
        }
    }
 
    public record Doubles(MinMaxBounds.Bounds<Double> bounds, MinMaxBounds.Bounds<Double> boundsSqr) implements MinMaxBounds<Double> {
        public static final MinMaxBounds.Doubles ANY = new MinMaxBounds.Doubles(MinMaxBounds.Bounds.any());
        public static final Codec<MinMaxBounds.Doubles> CODEC = MinMaxBounds.Bounds.createCodec(Codec.DOUBLE)
            .validate(MinMaxBounds.Bounds::validateSwappedBoundsInCodec)
            .xmap(MinMaxBounds.Doubles::new, MinMaxBounds.Doubles::bounds);
        public static final StreamCodec<ByteBuf, MinMaxBounds.Doubles> STREAM_CODEC = MinMaxBounds.Bounds.createStreamCodec(ByteBufCodecs.DOUBLE)
            .map(MinMaxBounds.Doubles::new, MinMaxBounds.Doubles::bounds);
 
        private Doubles(MinMaxBounds.Bounds<Double> bounds) {
            this(bounds, bounds.map(Mth::square));
        }
 
        public static MinMaxBounds.Doubles exactly(double value) {
            return new MinMaxBounds.Doubles(MinMaxBounds.Bounds.exactly(value));
        }
 
        public static MinMaxBounds.Doubles between(double min, double max) {
            return new MinMaxBounds.Doubles(MinMaxBounds.Bounds.between(min, max));
        }
 
        public static MinMaxBounds.Doubles atLeast(double value) {
            return new MinMaxBounds.Doubles(MinMaxBounds.Bounds.atLeast(value));
        }
 
        public static MinMaxBounds.Doubles atMost(double value) {
            return new MinMaxBounds.Doubles(MinMaxBounds.Bounds.atMost(value));
        }
 
        public boolean matches(double value) {
            return this.bounds.min.isPresent() && this.bounds.min.get() > value ? false : this.bounds.max.isEmpty() || !(this.bounds.max.get() < value);
        }
 
        public boolean matchesSqr(double valueSqr) {
            return this.boundsSqr.min.isPresent() && this.boundsSqr.min.get() > valueSqr
                ? false
                : this.boundsSqr.max.isEmpty() || !(this.boundsSqr.max.get() < valueSqr);
        }
 
        public static MinMaxBounds.Doubles fromReader(StringReader reader) throws CommandSyntaxException {
            int start = reader.getCursor();
            MinMaxBounds.Bounds<Double> bounds = MinMaxBounds.Bounds.fromReader(
                reader, Double::parseDouble, CommandSyntaxException.BUILT_IN_EXCEPTIONS::readerInvalidDouble
            );
            if (bounds.areSwapped()) {
                reader.setCursor(start);
                throw ERROR_SWAPPED.createWithContext(reader);
            } else {
                return new MinMaxBounds.Doubles(bounds);
            }
        }
    }
 
    public record FloatDegrees(MinMaxBounds.Bounds<Float> bounds) implements MinMaxBounds<Float> {
        public static final MinMaxBounds.FloatDegrees ANY = new MinMaxBounds.FloatDegrees(MinMaxBounds.Bounds.any());
        public static final Codec<MinMaxBounds.FloatDegrees> CODEC = MinMaxBounds.Bounds.createCodec(Codec.FLOAT)
            .xmap(MinMaxBounds.FloatDegrees::new, MinMaxBounds.FloatDegrees::bounds);
        public static final StreamCodec<ByteBuf, MinMaxBounds.FloatDegrees> STREAM_CODEC = MinMaxBounds.Bounds.createStreamCodec(ByteBufCodecs.FLOAT)
            .map(MinMaxBounds.FloatDegrees::new, MinMaxBounds.FloatDegrees::bounds);
 
        public static MinMaxBounds.FloatDegrees fromReader(StringReader reader) throws CommandSyntaxException {
            MinMaxBounds.Bounds<Float> bounds = MinMaxBounds.Bounds.fromReader(
                reader, Float::parseFloat, CommandSyntaxException.BUILT_IN_EXCEPTIONS::readerInvalidFloat
            );
            return new MinMaxBounds.FloatDegrees(bounds);
        }
    }
 
    public record Ints(MinMaxBounds.Bounds<Integer> bounds, MinMaxBounds.Bounds<Long> boundsSqr) implements MinMaxBounds<Integer> {
        public static final MinMaxBounds.Ints ANY = new MinMaxBounds.Ints(MinMaxBounds.Bounds.any());
        public static final Codec<MinMaxBounds.Ints> CODEC = MinMaxBounds.Bounds.createCodec(Codec.INT)
            .validate(MinMaxBounds.Bounds::validateSwappedBoundsInCodec)
            .xmap(MinMaxBounds.Ints::new, MinMaxBounds.Ints::bounds);
        public static final StreamCodec<ByteBuf, MinMaxBounds.Ints> STREAM_CODEC = MinMaxBounds.Bounds.createStreamCodec(ByteBufCodecs.INT)
            .map(MinMaxBounds.Ints::new, MinMaxBounds.Ints::bounds);
 
        private Ints(MinMaxBounds.Bounds<Integer> bounds) {
            this(bounds, bounds.map(i -> Mth.square(i.longValue())));
        }
 
        public static MinMaxBounds.Ints exactly(int value) {
            return new MinMaxBounds.Ints(MinMaxBounds.Bounds.exactly(value));
        }
 
        public static MinMaxBounds.Ints between(int min, int max) {
            return new MinMaxBounds.Ints(MinMaxBounds.Bounds.between(min, max));
        }
 
        public static MinMaxBounds.Ints atLeast(int value) {
            return new MinMaxBounds.Ints(MinMaxBounds.Bounds.atLeast(value));
        }
 
        public static MinMaxBounds.Ints atMost(int value) {
            return new MinMaxBounds.Ints(MinMaxBounds.Bounds.atMost(value));
        }
 
        public boolean matches(int value) {
            return this.bounds.min.isPresent() && this.bounds.min.get() > value ? false : this.bounds.max.isEmpty() || this.bounds.max.get() >= value;
        }
 
        public boolean matchesSqr(long valueSqr) {
            return this.boundsSqr.min.isPresent() && this.boundsSqr.min.get() > valueSqr
                ? false
                : this.boundsSqr.max.isEmpty() || this.boundsSqr.max.get() >= valueSqr;
        }
 
        public static MinMaxBounds.Ints fromReader(StringReader reader) throws CommandSyntaxException {
            int start = reader.getCursor();
            MinMaxBounds.Bounds<Integer> bounds = MinMaxBounds.Bounds.fromReader(
                reader, Integer::parseInt, CommandSyntaxException.BUILT_IN_EXCEPTIONS::readerInvalidInt
            );
            if (bounds.areSwapped()) {
                reader.setCursor(start);
                throw ERROR_SWAPPED.createWithContext(reader);
            } else {
                return new MinMaxBounds.Ints(bounds);
            }
        }
    }
}

引用的其他类

  • Component

    • 引用位置: 方法调用
    • 关联成员: Component.translatable()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.square()
  • Column

    • 引用位置: 方法调用
    • 关联成员: Range.all(), Range.atLeast(), Range.atMost(), Range.closed()