mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 08:14:23 +01:00
Randomise wearable stacking
This commit is contained in:
parent
2f2e21ee5b
commit
737c368264
1 changed files with 46 additions and 47 deletions
|
@ -1,13 +1,13 @@
|
||||||
package com.minelittlepony.client.render.entity.feature;
|
package com.minelittlepony.client.render.entity.feature;
|
||||||
|
|
||||||
import net.minecraft.client.render.OverlayTexture;
|
import net.minecraft.client.render.*;
|
||||||
import net.minecraft.client.render.RenderLayer;
|
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
|
||||||
import net.minecraft.client.render.VertexConsumerProvider;
|
|
||||||
import net.minecraft.client.render.entity.model.EntityModel;
|
import net.minecraft.client.render.entity.model.EntityModel;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
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.google.common.collect.Streams;
|
||||||
import com.minelittlepony.api.model.BodyPart;
|
import com.minelittlepony.api.model.BodyPart;
|
||||||
import com.minelittlepony.api.model.gear.IGear;
|
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.model.ModelType;
|
||||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -32,20 +30,31 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
|
||||||
MOD_GEARS.add(gear);
|
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) {
|
public GearFeature(IPonyRenderContext<T, M> renderer) {
|
||||||
super(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
|
@Override
|
||||||
public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
|
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()) {
|
if (entity.isInvisible()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -54,34 +63,32 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
|
||||||
|
|
||||||
final Map<BodyPart, Float> renderStackingOffsets = new HashMap<>();
|
final Map<BodyPart, Float> renderStackingOffsets = new HashMap<>();
|
||||||
|
|
||||||
for (Entry entry : gears) {
|
randomisedGearCache.getUnchecked(entity)
|
||||||
final IGear gear = entry.gear;
|
.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)) {
|
if (entry.gear instanceof IStackable) {
|
||||||
stack.push();
|
renderStackingOffsets.compute(part, (k, v) -> {
|
||||||
BodyPart part = gear.getGearLocation();
|
float offset = ((IStackable)entry.gear).getStackingHeight();
|
||||||
model.transform(part, stack);
|
if (v != null) {
|
||||||
model.getBodyPart(part).rotate(stack);
|
stack.translate(0, -v, 0);
|
||||||
|
offset += v;
|
||||||
if (gear instanceof IStackable) {
|
}
|
||||||
renderStackingOffsets.compute(part, (k, v) -> {
|
return offset;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
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) {
|
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.setModelAttributes(model, entity);
|
||||||
gear.pose(model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta);
|
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());
|
gear.render(stack, vertexConsumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1, entity.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Entry {
|
static record Entry(IGear gear, Wearable wearable) {}
|
||||||
IGear gear;
|
|
||||||
Wearable wearable;
|
|
||||||
|
|
||||||
Entry(IGear gear, Wearable wearable) {
|
|
||||||
this.gear = gear;
|
|
||||||
this.wearable = wearable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue