From 737c368264d6ffe66dcc620d0d2aebb608d4b261 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 5 Jul 2022 22:47:41 +0200 Subject: [PATCH] Randomise wearable stacking --- .../render/entity/feature/GearFeature.java | 93 +++++++++---------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java index 57e0b01c..8b1e71f8 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java @@ -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 & IPon MOD_GEARS.add(gear); } - private final List gears; + private final List 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> randomisedGearCache = CacheBuilder.newBuilder() + .expireAfterAccess(3, TimeUnit.MINUTES) + .build(CacheLoader.from(entity -> { + List randomizedOrder = new ArrayList<>(); + List 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 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 & IPon final Map 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 & 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) {} }