Randomise wearable stacking

This commit is contained in:
Sollace 2022-07-05 22:47:41 +02:00
parent 2f2e21ee5b
commit 737c368264

View file

@ -1,13 +1,13 @@
package com.minelittlepony.client.render.entity.feature;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.random.Random;
import com.google.common.cache.*;
import com.google.common.collect.Streams;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.gear.IGear;
@ -17,10 +17,8 @@ import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.render.IPonyRenderContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@ -32,20 +30,31 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
MOD_GEARS.add(gear);
}
private final List<Entry> gears;
private final List<Entry> gears = Streams.concat(
ModelType.getWearables().map(e -> new Entry(e.getValue().createModel(), e.getKey())),
MOD_GEARS.stream().map(e -> new Entry(e.get(), Wearable.NONE))
).collect(Collectors.toList());
private final LoadingCache<Entity, List<Entry>> randomisedGearCache = CacheBuilder.newBuilder()
.expireAfterAccess(3, TimeUnit.MINUTES)
.build(CacheLoader.from(entity -> {
List<Entry> randomizedOrder = new ArrayList<>();
List<Entry> pool = new ArrayList<>(gears);
Random rng = Random.create(entity.getUuid().getLeastSignificantBits());
while (!pool.isEmpty()) {
randomizedOrder.add(pool.remove(rng.nextInt(pool.size() + 1) % pool.size()));
}
return randomizedOrder;
}));
public GearFeature(IPonyRenderContext<T, M> renderer) {
super(renderer);
gears = Streams.concat(
ModelType.getWearables().map(e -> new Entry(e.getValue().createModel(), e.getKey())),
MOD_GEARS.stream().map(e -> new Entry(e.get(), Wearable.NONE))
).collect(Collectors.toList());
}
@Override
public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
if (entity.isInvisible()) {
return;
}
@ -54,34 +63,32 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
final Map<BodyPart, Float> renderStackingOffsets = new HashMap<>();
for (Entry entry : gears) {
final IGear gear = entry.gear;
randomisedGearCache.getUnchecked(entity)
.stream()
.filter(entry -> getContext().shouldRender(model, entity, entry.wearable, entry.gear))
.forEach(entry -> {
stack.push();
BodyPart part = entry.gear.getGearLocation();
model.transform(part, stack);
model.getBodyPart(part).rotate(stack);
if (getContext().shouldRender(model, entity, entry.wearable, gear)) {
stack.push();
BodyPart part = gear.getGearLocation();
model.transform(part, stack);
model.getBodyPart(part).rotate(stack);
if (gear instanceof IStackable) {
renderStackingOffsets.compute(part, (k, v) -> {
float offset = ((IStackable)gear).getStackingHeight();
if (v != null) {
stack.translate(0, -v, 0);
offset += v;
}
return offset;
});
}
renderGear(model, entity, gear, stack, renderContext, lightUv, limbDistance, limbAngle, tickDelta);
stack.pop();
if (entry.gear instanceof IStackable) {
renderStackingOffsets.compute(part, (k, v) -> {
float offset = ((IStackable)entry.gear).getStackingHeight();
if (v != null) {
stack.translate(0, -v, 0);
offset += v;
}
return offset;
});
}
}
renderGear(model, entity, entry.gear, stack, renderContext, lightUv, limbDistance, limbAngle, tickDelta);
stack.pop();
});
}
private void renderGear(M model, T entity, IGear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) {
gear.setModelAttributes(model, entity);
gear.pose(model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta);
@ -91,13 +98,5 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
gear.render(stack, vertexConsumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1, entity.getUuid());
}
static class Entry {
IGear gear;
Wearable wearable;
Entry(IGear gear, Wearable wearable) {
this.gear = gear;
this.wearable = wearable;
}
}
static record Entry(IGear gear, Wearable wearable) {}
}