NumberRangeInput.java

net.minecraft.server.dialog.input.NumberRangeInput

信息

  • 全限定名:net.minecraft.server.dialog.input.NumberRangeInput
  • 类型:public record
  • 包:net.minecraft.server.dialog.input
  • 源码路径:src/main/java/net/minecraft/server/dialog/input/NumberRangeInput.java
  • 起始行号:L14
  • 实现:InputControl
  • 职责:

    TODO

字段/常量

  • MAP_CODEC
    • 类型: MapCodec<NumberRangeInput>
    • 修饰符: public static final
    • 源码定位: L15
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.server.dialog.input.NumberRangeInput.RangeInfo
    • 类型: record
    • 修饰符: public
    • 源码定位: L34
    • 说明:

      TODO

构造器

方法

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

public MapCodec<NumberRangeInput> mapCodec() @ L25

  • 方法名:mapCodec
  • 源码定位:L25
  • 返回类型:MapCodec
  • 修饰符:public

参数:

说明:

TODO

public Component computeLabel(String value) @ L30

  • 方法名:computeLabel
  • 源码定位:L30
  • 返回类型:Component
  • 修饰符:public

参数:

  • value: String

说明:

TODO

代码

public record NumberRangeInput(int width, Component label, String labelFormat, NumberRangeInput.RangeInfo rangeInfo) implements InputControl {
    public static final MapCodec<NumberRangeInput> MAP_CODEC = RecordCodecBuilder.mapCodec(
        i -> i.group(
                Dialog.WIDTH_CODEC.optionalFieldOf("width", 200).forGetter(NumberRangeInput::width),
                ComponentSerialization.CODEC.fieldOf("label").forGetter(NumberRangeInput::label),
                Codec.STRING.optionalFieldOf("label_format", "options.generic_value").forGetter(NumberRangeInput::labelFormat),
                NumberRangeInput.RangeInfo.MAP_CODEC.forGetter(NumberRangeInput::rangeInfo)
            )
            .apply(i, NumberRangeInput::new)
    );
 
    @Override
    public MapCodec<NumberRangeInput> mapCodec() {
        return MAP_CODEC;
    }
 
    public Component computeLabel(String value) {
        return Component.translatable(this.labelFormat, this.label, value);
    }
 
    public record RangeInfo(float start, float end, Optional<Float> initial, Optional<Float> step) {
        public static final MapCodec<NumberRangeInput.RangeInfo> MAP_CODEC = RecordCodecBuilder.<NumberRangeInput.RangeInfo>mapCodec(
                i -> i.group(
                        Codec.FLOAT.fieldOf("start").forGetter(NumberRangeInput.RangeInfo::start),
                        Codec.FLOAT.fieldOf("end").forGetter(NumberRangeInput.RangeInfo::end),
                        Codec.FLOAT.optionalFieldOf("initial").forGetter(NumberRangeInput.RangeInfo::initial),
                        ExtraCodecs.POSITIVE_FLOAT.optionalFieldOf("step").forGetter(NumberRangeInput.RangeInfo::step)
                    )
                    .apply(i, NumberRangeInput.RangeInfo::new)
            )
            .validate(range -> {
                if (range.initial.isPresent()) {
                    double initial = range.initial.get().floatValue();
                    double min = Math.min(range.start, range.end);
                    double max = Math.max(range.start, range.end);
                    if (initial < min || initial > max) {
                        return DataResult.error(() -> "Initial value " + initial + " is outside of range [" + min + ", " + max + "]");
                    }
                }
 
                return DataResult.success(range);
            });
 
        public float computeScaledValue(float sliderValue) {
            float valueInRange = Mth.lerp(sliderValue, this.start, this.end);
            if (this.step.isEmpty()) {
                return valueInRange;
            } else {
                float step = this.step.get();
                float initialValue = this.initialScaledValue();
                float deltaToInitial = valueInRange - initialValue;
                int stepsOutsideInitial = Math.round(deltaToInitial / step);
                float result = initialValue + stepsOutsideInitial * step;
                if (!this.isOutOfRange(result)) {
                    return result;
                } else {
                    int oneStepLess = stepsOutsideInitial - Mth.sign(stepsOutsideInitial);
                    return initialValue + oneStepLess * step;
                }
            }
        }
 
        private boolean isOutOfRange(float scaledValue) {
            float sliderPos = this.scaledValueToSlider(scaledValue);
            return sliderPos < 0.0 || sliderPos > 1.0;
        }
 
        private float initialScaledValue() {
            return this.initial.isPresent() ? this.initial.get() : (this.start + this.end) / 2.0F;
        }
 
        public float initialSliderValue() {
            float value = this.initialScaledValue();
            return this.scaledValueToSlider(value);
        }
 
        private float scaledValueToSlider(float value) {
            return this.start == this.end ? 0.5F : Mth.inverseLerp(value, this.start, this.end);
        }
    }
}

引用的其他类

  • Component

    • 引用位置: 方法调用/返回值
    • 关联成员: Component.translatable()
  • InputControl

    • 引用位置: 实现
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.inverseLerp(), Mth.lerp(), Mth.sign()