115 lines
5.4 KiB
Java
115 lines
5.4 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* com.mojang.datafixers.kinds.App
|
|
* com.mojang.datafixers.kinds.Applicative
|
|
* com.mojang.serialization.Codec
|
|
* com.mojang.serialization.MapCodec
|
|
* com.mojang.serialization.codecs.RecordCodecBuilder
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
package net.minecraft.client.renderer.item;
|
|
|
|
import com.mojang.datafixers.kinds.App;
|
|
import com.mojang.datafixers.kinds.Applicative;
|
|
import com.mojang.serialization.Codec;
|
|
import com.mojang.serialization.MapCodec;
|
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import net.minecraft.client.multiplayer.ClientLevel;
|
|
import net.minecraft.client.renderer.item.ItemModel;
|
|
import net.minecraft.client.renderer.item.ItemModelResolver;
|
|
import net.minecraft.client.renderer.item.ItemModels;
|
|
import net.minecraft.client.renderer.item.ItemStackRenderState;
|
|
import net.minecraft.client.renderer.item.properties.numeric.RangeSelectItemModelProperties;
|
|
import net.minecraft.client.renderer.item.properties.numeric.RangeSelectItemModelProperty;
|
|
import net.minecraft.client.resources.model.ResolvableModel;
|
|
import net.minecraft.world.entity.ItemOwner;
|
|
import net.minecraft.world.item.ItemDisplayContext;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import org.jspecify.annotations.Nullable;
|
|
|
|
public class RangeSelectItemModel
|
|
implements ItemModel {
|
|
private static final int LINEAR_SEARCH_THRESHOLD = 16;
|
|
private final RangeSelectItemModelProperty property;
|
|
private final float scale;
|
|
private final float[] thresholds;
|
|
private final ItemModel[] models;
|
|
private final ItemModel fallback;
|
|
|
|
private RangeSelectItemModel(RangeSelectItemModelProperty property, float scale, float[] thresholds, ItemModel[] models, ItemModel fallback) {
|
|
this.property = property;
|
|
this.thresholds = thresholds;
|
|
this.models = models;
|
|
this.fallback = fallback;
|
|
this.scale = scale;
|
|
}
|
|
|
|
private static int lastIndexLessOrEqual(float[] haystack, float needle) {
|
|
if (haystack.length < 16) {
|
|
for (int i = 0; i < haystack.length; ++i) {
|
|
if (!(haystack[i] > needle)) continue;
|
|
return i - 1;
|
|
}
|
|
return haystack.length - 1;
|
|
}
|
|
int index = Arrays.binarySearch(haystack, needle);
|
|
if (index < 0) {
|
|
int insertionPoint = ~index;
|
|
return insertionPoint - 1;
|
|
}
|
|
return index;
|
|
}
|
|
|
|
@Override
|
|
public void update(ItemStackRenderState output, ItemStack item, ItemModelResolver resolver, ItemDisplayContext displayContext, @Nullable ClientLevel level, @Nullable ItemOwner owner, int seed) {
|
|
int index;
|
|
output.appendModelIdentityElement(this);
|
|
float value = this.property.get(item, level, owner, seed) * this.scale;
|
|
ItemModel selectedModel = Float.isNaN(value) ? this.fallback : ((index = RangeSelectItemModel.lastIndexLessOrEqual(this.thresholds, value)) == -1 ? this.fallback : this.models[index]);
|
|
selectedModel.update(output, item, resolver, displayContext, level, owner, seed);
|
|
}
|
|
|
|
public record Entry(float threshold, ItemModel.Unbaked model) {
|
|
public static final Codec<Entry> CODEC = RecordCodecBuilder.create(i -> i.group((App)Codec.FLOAT.fieldOf("threshold").forGetter(Entry::threshold), (App)ItemModels.CODEC.fieldOf("model").forGetter(Entry::model)).apply((Applicative)i, Entry::new));
|
|
public static final Comparator<Entry> BY_THRESHOLD = Comparator.comparingDouble(Entry::threshold);
|
|
}
|
|
|
|
public record Unbaked(RangeSelectItemModelProperty property, float scale, List<Entry> entries, Optional<ItemModel.Unbaked> fallback) implements ItemModel.Unbaked
|
|
{
|
|
public static final MapCodec<Unbaked> MAP_CODEC = RecordCodecBuilder.mapCodec(i -> i.group((App)RangeSelectItemModelProperties.MAP_CODEC.forGetter(Unbaked::property), (App)Codec.FLOAT.optionalFieldOf("scale", (Object)Float.valueOf(1.0f)).forGetter(Unbaked::scale), (App)Entry.CODEC.listOf().fieldOf("entries").forGetter(Unbaked::entries), (App)ItemModels.CODEC.optionalFieldOf("fallback").forGetter(Unbaked::fallback)).apply((Applicative)i, Unbaked::new));
|
|
|
|
public MapCodec<Unbaked> type() {
|
|
return MAP_CODEC;
|
|
}
|
|
|
|
@Override
|
|
public ItemModel bake(ItemModel.BakingContext context) {
|
|
float[] thresholds = new float[this.entries.size()];
|
|
ItemModel[] models = new ItemModel[this.entries.size()];
|
|
ArrayList<Entry> mutableEntries = new ArrayList<Entry>(this.entries);
|
|
mutableEntries.sort(Entry.BY_THRESHOLD);
|
|
for (int i = 0; i < mutableEntries.size(); ++i) {
|
|
Entry entry = (Entry)mutableEntries.get(i);
|
|
thresholds[i] = entry.threshold;
|
|
models[i] = entry.model.bake(context);
|
|
}
|
|
ItemModel bakedFallback = this.fallback.map(m -> m.bake(context)).orElse(context.missingItemModel());
|
|
return new RangeSelectItemModel(this.property, this.scale, thresholds, models, bakedFallback);
|
|
}
|
|
|
|
@Override
|
|
public void resolveDependencies(ResolvableModel.Resolver resolver) {
|
|
this.fallback.ifPresent(m -> m.resolveDependencies(resolver));
|
|
this.entries.forEach(entry -> entry.model.resolveDependencies(resolver));
|
|
}
|
|
}
|
|
}
|
|
|