Fix le bugs

This commit is contained in:
Sollace 2024-12-12 00:06:49 +01:00
parent a02fad8732
commit 00e69317e9
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
61 changed files with 234 additions and 181 deletions

View file

@ -1,20 +0,0 @@
package com.minelittlepony.api.model;
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
import net.minecraft.client.render.entity.state.*;
import net.minecraft.util.Arm;
public interface HornedPonyModel<T extends EntityRenderState & PonyModel.AttributedHolder> extends PonyModel<T> {
/**
* Returns true if this model is currently using magic (horn is lit).
*/
default boolean isCasting(T state) {
return state instanceof PlayerEntityRenderState s
&& (getArmPoseForSide(s, Arm.LEFT) != ArmPose.EMPTY || getArmPoseForSide(s, Arm.RIGHT) != ArmPose.EMPTY);
}
@Override
default float getWobbleAmplitude(T state) {
return isCasting(state) ? 0 : 1;
}
}

View file

@ -2,7 +2,7 @@ package com.minelittlepony.api.model;
import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.api.pony.*; import com.minelittlepony.api.pony.*;
import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.api.pony.meta.*;
import com.minelittlepony.common.util.animation.Interpolator; import com.minelittlepony.common.util.animation.Interpolator;
import com.minelittlepony.util.MathUtil; import com.minelittlepony.util.MathUtil;
@ -126,6 +126,8 @@ public class ModelAttributes {
*/ */
public PonyData metadata = PonyData.NULL; public PonyData metadata = PonyData.NULL;
public Size size = SizePreset.NORMAL;
public Arm mainArm; public Arm mainArm;
public Hand activeHand; public Hand activeHand;
public ItemStack heldStack = ItemStack.EMPTY; public ItemStack heldStack = ItemStack.EMPTY;
@ -160,6 +162,8 @@ public class ModelAttributes {
} }
public void updateLivingState(LivingEntity entity, Pony pony, Mode mode) { public void updateLivingState(LivingEntity entity, Pony pony, Mode mode) {
metadata = pony.metadata();
size = entity.isBaby() ? SizePreset.FOAL : PonyConfig.getEffectiveSize(metadata.size());
isPlayer = entity instanceof PlayerEntity; isPlayer = entity instanceof PlayerEntity;
visualHeight = entity.getHeight() + 0.125F; visualHeight = entity.getHeight() + 0.125F;
isSitting = PonyPosture.isSitting(entity); isSitting = PonyPosture.isSitting(entity);

View file

@ -43,8 +43,10 @@ abstract class MixinHeldItemRenderer {
VertexConsumerProvider vertices, VertexConsumerProvider vertices,
@Nullable World world, @Nullable World world,
int light, int overlay, int seed, Operation<Void> operation) { int light, int overlay, int seed, Operation<Void> operation) {
if (!MineLittlePony.getInstance().getRenderDispatcher().getMagicRenderer().renderItem(target, entity, stack, mode, left, matrices, vertices, world, light, overlay, seed, operation)) { if (!MineLittlePony.getInstance().getRenderDispatcher().getMagicRenderer().renderItem(target, entity, stack, mode, left, matrices, vertices, world, light, overlay, seed, operation)) {
operation.call(entity, stack, mode, left, matrices, vertices, world, light, overlay, seed); operation.call(target, entity, stack, mode, left, matrices, vertices, world, light, overlay, seed);
} }
} }
} }

View file

@ -14,6 +14,7 @@ import java.util.function.Supplier;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityPose;
@ -42,19 +43,17 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
protected final ModelPart neck; protected final ModelPart neck;
public final RenderList helmetRenderList;
protected final RenderList neckRenderList; protected final RenderList neckRenderList;
public final RenderList headRenderList; public final RenderList headRenderList;
protected final RenderList bodyRenderList; protected final RenderList bodyRenderList;
protected final RenderList vestRenderList;
protected final RenderList legsRenderList; protected final RenderList legsRenderList;
protected final RenderList sleevesRenderList;
protected final RenderList mainRenderList; protected final RenderList mainRenderList;
private final List<SubModel<? super T>> parts = new ArrayList<>(); private final List<SubModel<? super T>> parts = new ArrayList<>();
@Deprecated
@Nullable @Nullable
protected T currentState; protected T currentState;
@ -66,10 +65,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
.add(withStage(BodyPart.BODY, bodyRenderList = RenderList.of(body).add(body::rotate))) .add(withStage(BodyPart.BODY, bodyRenderList = RenderList.of(body).add(body::rotate)))
.add(withStage(BodyPart.NECK, neckRenderList = RenderList.of(neck))) .add(withStage(BodyPart.NECK, neckRenderList = RenderList.of(neck)))
.add(withStage(BodyPart.HEAD, headRenderList = RenderList.of(head))) .add(withStage(BodyPart.HEAD, headRenderList = RenderList.of(head)))
.add(withStage(BodyPart.LEGS, legsRenderList = RenderList.of().add(leftArm, rightArm, leftLeg, rightLeg))) .add(withStage(BodyPart.LEGS, legsRenderList = RenderList.of().add(leftArm, rightArm, leftLeg, rightLeg)));
.add(withStage(BodyPart.LEGS, sleevesRenderList = RenderList.of().add(leftSleeve, rightSleeve, leftPants, rightPants)))
.add(withStage(BodyPart.BODY, vestRenderList = RenderList.of(jacket)))
.add(withStage(BodyPart.HEAD, helmetRenderList = RenderList.of(hat)));
} }
protected <P extends SubModel<? super T>> P addPart(P part) { protected <P extends SubModel<? super T>> P addPart(P part) {
@ -88,14 +84,16 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
protected RenderList withStage(BodyPart part, RenderList action) { protected RenderList withStage(BodyPart part, RenderList action) {
return (stack, vertices, overlay, light, color) -> { return (stack, vertices, overlay, light, color) -> {
stack.push(); stack.push();
if (currentState != null) {
transform(currentState, part, stack); transform(currentState, part, stack);
}
action.accept(stack, vertices, overlay, light, color); action.accept(stack, vertices, overlay, light, color);
stack.pop(); stack.pop();
}; };
} }
@Override @Override
public void render(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { public final void render(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) {
mainRenderList.accept(stack, vertices, overlay, light, color); mainRenderList.accept(stack, vertices, overlay, light, color);
} }
@ -112,13 +110,6 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
setModelVisibilities((T)entity); setModelVisibilities((T)entity);
setModelAngles((T)entity); setModelAngles((T)entity);
leftSleeve.copyTransform(leftArm);
rightSleeve.copyTransform(rightArm);
leftPants.copyTransform(leftLeg);
rightPants.copyTransform(rightLeg);
jacket.copyTransform(body);
hat.copyTransform(head);
} }
protected void setModelVisibilities(T state) { protected void setModelVisibilities(T state) {
@ -126,6 +117,14 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
parts.forEach(part -> part.setVisible(body.visible, state)); parts.forEach(part -> part.setVisible(body.visible, state));
} }
@SuppressWarnings("unchecked")
public void copyTransforms(BipedEntityModel<PlayerEntityRenderState> model) {
super.copyTransforms(model);
if (model instanceof AbstractPonyModel m) {
((AbstractPonyModel<T>)m).currentState = currentState;
}
}
protected void setModelAngles(T entity) { protected void setModelAngles(T entity) {
float pitch = entity.attributes.motionPitch * MathHelper.RADIANS_PER_DEGREE; float pitch = entity.attributes.motionPitch * MathHelper.RADIANS_PER_DEGREE;
head.setAngles( head.setAngles(
@ -186,7 +185,6 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
public void setHeadRotation(float animationProgress, float yaw, float pitch) { public void setHeadRotation(float animationProgress, float yaw, float pitch) {
head.yaw = yaw * MathHelper.RADIANS_PER_DEGREE; head.yaw = yaw * MathHelper.RADIANS_PER_DEGREE;
head.pitch = pitch * MathHelper.RADIANS_PER_DEGREE; head.pitch = pitch * MathHelper.RADIANS_PER_DEGREE;
hat.copyTransform(head);
} }
/** /**
@ -286,7 +284,6 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
* Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles} * Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles}
*/ */
protected void rotateLegsSwimming(T state, @Deprecated float move, @Deprecated float swing, @Deprecated float ticks) { protected void rotateLegsSwimming(T state, @Deprecated float move, @Deprecated float swing, @Deprecated float ticks) {
float lerp = state.isInPose(EntityPose.SWIMMING) ? (float)state.attributes.motionLerp : 1; float lerp = state.isInPose(EntityPose.SWIMMING) ? (float)state.attributes.motionLerp : 1;
float legLeft = (MathUtil.Angles._90_DEG + MathHelper.sin((state.limbFrequency / 3) + 2 * MathHelper.PI/3) / 2) * lerp; float legLeft = (MathUtil.Angles._90_DEG + MathHelper.sin((state.limbFrequency / 3) + 2 * MathHelper.PI/3) / 2) * lerp;
@ -307,8 +304,8 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
protected void rotateLegsOnGround(T state, float move, float swing, float ticks) { protected void rotateLegsOnGround(T state, float move, float swing, float ticks) {
float angle = MathHelper.PI * (float) Math.pow(swing, 16); float angle = MathHelper.PI * (float) Math.pow(swing, 16);
float baseRotation = move * 0.6662F; // magic number ahoy float baseRotation = state.limbFrequency * 0.6662F; // magic number ahoy
float scale = swing / 4; float scale = state.limbAmplitudeMultiplier / 4;
float rainboomLegLotation = state.attributes.getMainInterpolator().interpolate( float rainboomLegLotation = state.attributes.getMainInterpolator().interpolate(
"rainboom_leg_rotation", "rainboom_leg_rotation",
@ -415,10 +412,10 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
arm.pivotX -= 6 * sigma; arm.pivotX -= 6 * sigma;
arm.pivotZ -= 2; arm.pivotZ -= 2;
} }
if (state.size == SizePreset.TALL) { if (state.attributes.size == SizePreset.TALL) {
arm.pivotY += 1; arm.pivotY += 1;
} }
if (state.size == SizePreset.FOAL) { if (state.attributes.size == SizePreset.FOAL) {
arm.pivotY -= 2; arm.pivotY -= 2;
} }
@ -529,8 +526,10 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
@Override @Override
public final void setArmAngle(Arm arm, MatrixStack matrices) { public final void setArmAngle(Arm arm, MatrixStack matrices) {
super.setArmAngle(arm, matrices); super.setArmAngle(arm, matrices);
if (currentState != null) {
positionheldItem(currentState, arm, matrices); positionheldItem(currentState, arm, matrices);
} }
}
protected void positionheldItem(T state, Arm arm, MatrixStack matrices) { protected void positionheldItem(T state, Arm arm, MatrixStack matrices) {
float left = arm == Arm.LEFT ? -1 : 1; float left = arm == Arm.LEFT ? -1 : 1;
@ -584,6 +583,6 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
neck.hidden = !head.visible; neck.hidden = !head.visible;
} }
PonyTransformation.forSize(state.size).transform(state.attributes, part, stack); PonyTransformation.forSize(state.attributes.size).transform(state.attributes, part, stack);
} }
} }

View file

@ -39,7 +39,7 @@ public abstract class ClientPonyModel<T extends PonyRenderState> extends PlayerE
} }
@Override @Override
public <S extends PlayerEntityRenderState> ArmPose getArmPoseForSide(S state, Arm side) { public final <S extends PlayerEntityRenderState> ArmPose getArmPoseForSide(S state, Arm side) {
return getArmPose(state, side); return getArmPose(state, side);
} }

View file

@ -26,13 +26,9 @@ public record ArmourTexture(Identifier texture, ArmourVariant variant) {
return INTERNER.intern(new ArmourTexture(texture, ArmourVariant.NORMAL)); return INTERNER.intern(new ArmourTexture(texture, ArmourVariant.NORMAL));
} }
public Stream<ArmourTexture> named() {
return Stream.of(legacy(texture().withPath(p -> p.replace("1", "inner").replace("2", "outer"))), this);
}
public Stream<ArmourTexture> ponify() { public Stream<ArmourTexture> ponify() {
if (!PonyConfig.getInstance().disablePonifiedArmour.get()) { if (!PonyConfig.getInstance().disablePonifiedArmour.get()) {
return Stream.of(this, modern(ResourceUtil.ponify(texture()))); return Stream.of(this, modern(texture().withPath(p -> p.replace("humanoid", "ponified"))));
} }
return Stream.of(this); return Stream.of(this);
} }

View file

@ -4,5 +4,5 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel; import net.minecraft.item.equipment.EquipmentModel;
public interface ArmourTextureLookup { public interface ArmourTextureLookup {
ArmourTexture getTexture(ItemStack stack, ArmourLayer layerType, EquipmentModel.Layer layer); ArmourTexture getTexture(ItemStack stack, EquipmentModel.LayerType layerType, EquipmentModel.Layer layer);
} }

View file

@ -39,12 +39,7 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR
private final LoadingCache<ArmourParameters, ArmourTexture> layerCache = CacheBuilder.newBuilder() private final LoadingCache<ArmourParameters, ArmourTexture> layerCache = CacheBuilder.newBuilder()
.expireAfterAccess(30, TimeUnit.SECONDS) .expireAfterAccess(30, TimeUnit.SECONDS)
.build(CacheLoader.from(parameters -> { .build(CacheLoader.from(parameters -> {
return Stream.of(ArmourTexture.legacy(parameters.material().textureId())).flatMap(i -> { return Stream.of(ArmourTexture.legacy(parameters.textureId())).flatMap(i -> {
if (parameters.layer() == ArmourLayer.OUTER) {
return Stream.of(i, ArmourTexture.legacy(parameters.material().textureId()));
}
return Stream.of(i);
}).flatMap(i -> {
if (parameters.customModelId() != 0) { if (parameters.customModelId() != 0) {
return Stream.of(ArmourTexture.legacy(i.texture().withPath(p -> p.replace(".png", parameters.customModelId() + ".png"))), i); return Stream.of(ArmourTexture.legacy(i.texture().withPath(p -> p.replace(".png", parameters.customModelId() + ".png"))), i);
} }
@ -53,10 +48,7 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR
})); }));
private Stream<ArmourTexture> performLookup(ArmourTexture id) { private Stream<ArmourTexture> performLookup(ArmourTexture id) {
List<ArmourTexture> options = Stream.of(id) List<ArmourTexture> options = Stream.of(id).flatMap(ArmourTexture::ponify).toList();
.flatMap(ArmourTexture::named)
.flatMap(ArmourTexture::ponify)
.toList();
return options.stream().distinct() return options.stream().distinct()
.filter(ArmourTexture::validate) .filter(ArmourTexture::validate)
.findFirst() .findFirst()
@ -84,15 +76,17 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR
} }
@Override @Override
public ArmourTexture getTexture(ItemStack stack, ArmourLayer layer, EquipmentModel.Layer armorLayer) { public ArmourTexture getTexture(ItemStack stack, EquipmentModel.LayerType layerType, EquipmentModel.Layer layer) {
return layerCache.getUnchecked(new ArmourParameters(layer, armorLayer, getCustom(stack))); return layerCache.getUnchecked(new ArmourParameters(layer, layerType, getCustom(stack)));
} }
private int getCustom(ItemStack stack) { private int getCustom(ItemStack stack) {
return stack.getOrDefault(DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelDataComponent.DEFAULT).value(); return stack.getOrDefault(DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelDataComponent.DEFAULT).value();
} }
private record ArmourParameters(ArmourLayer layer, EquipmentModel.Layer material, int customModelId) { private record ArmourParameters(EquipmentModel.Layer layer, EquipmentModel.LayerType layerType, int customModelId) {
public Identifier textureId() {
return layer.getFullTextureId(layerType);
}
} }
} }

View file

@ -37,19 +37,21 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
EquipmentSlot equipmentSlot, EquipmentSlot equipmentSlot,
EquipmentModel.LayerType layerType, EquipmentModel.LayerType layerType,
Identifier modelId, Identifier modelId,
S entity,
Models<? extends PonyModel<S>> models, Models<? extends PonyModel<S>> models,
ItemStack stack, ItemStack stack,
MatrixStack matrices, MatrixStack matrices,
VertexConsumerProvider vertexConsumers, VertexConsumerProvider vertexConsumers,
int light int light
) { ) {
this.render(equipmentSlot, layerType, modelId, models, stack, matrices, vertexConsumers, light, null); this.render(equipmentSlot, layerType, modelId, entity, models, stack, matrices, vertexConsumers, light, null);
} }
public <S extends PonyRenderState, V extends PonyArmourModel<S>> void render( public <S extends PonyRenderState, V extends PonyArmourModel<S>> void render(
EquipmentSlot equipmentSlot, EquipmentSlot equipmentSlot,
EquipmentModel.LayerType layerType, EquipmentModel.LayerType layerType,
Identifier modelId, Identifier modelId,
S entity,
Models<? extends PonyModel<S>> models, Models<? extends PonyModel<S>> models,
ItemStack stack, ItemStack stack,
MatrixStack matrices, MatrixStack matrices,
@ -72,7 +74,7 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
int j = getDyeColor(layer, i); int j = getDyeColor(layer, i);
if (j != 0) { if (j != 0) {
ArmourLayer armourLayer = layerType == LayerType.HUMANOID_LEGGINGS ? ArmourLayer.INNER : ArmourLayer.OUTER; ArmourLayer armourLayer = layerType == LayerType.HUMANOID_LEGGINGS ? ArmourLayer.INNER : ArmourLayer.OUTER;
ArmourTexture armorTexture = plugin.getTextureLookup().getTexture(stack, armourLayer, layer); ArmourTexture armorTexture = plugin.getTextureLookup().getTexture(stack, layerType, layer);
Identifier layerTexture = layer.usePlayerTexture() && texture != null Identifier layerTexture = layer.usePlayerTexture() && texture != null
? texture ? texture
: armorTexture.texture(); : armorTexture.texture();
@ -80,9 +82,10 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
VertexConsumer armorConsumer = plugin.getArmourConsumer(equipmentSlot, vertexConsumers, layerTexture, layerType); VertexConsumer armorConsumer = plugin.getArmourConsumer(equipmentSlot, vertexConsumers, layerTexture, layerType);
if (armorConsumer != null) { if (armorConsumer != null) {
ArmourVariant variant = layer.usePlayerTexture() ? ArmourVariant.NORMAL : armorTexture.variant(); ArmourVariant variant = layer.usePlayerTexture() ? ArmourVariant.NORMAL : armorTexture.variant();
models.getArmourModel(stack, null, variant).ifPresent(model -> { models.getArmourModel(stack, armourLayer, variant).ifPresent(model -> {
VertexConsumer glintConsumer = hasGlint ? plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType) : null; VertexConsumer glintConsumer = hasGlint ? plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType) : null;
if (model.poseModel(equipmentSlot, armourLayer, models.body())) { if (model.poseModel(equipmentSlot, armourLayer, models.body())) {
model.setAngles(entity);
model.render(matrices, glintConsumer != null ? VertexConsumers.union(plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType), armorConsumer) : armorConsumer, light, OverlayTexture.DEFAULT_UV, j); model.render(matrices, glintConsumer != null ? VertexConsumers.union(plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType), armorConsumer) : armorConsumer, light, OverlayTexture.DEFAULT_UV, j);
} }
}); });

View file

@ -5,6 +5,7 @@ import net.minecraft.entity.EquipmentSlot;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.client.model.AbstractPonyModel; import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class PonyArmourModel<S extends PonyRenderState> extends AbstractPonyModel<S> { public class PonyArmourModel<S extends PonyRenderState> extends AbstractPonyModel<S> {
@ -17,7 +18,7 @@ public class PonyArmourModel<S extends PonyRenderState> extends AbstractPonyMode
if (!setVisibilities(slot, layer)) { if (!setVisibilities(slot, layer)) {
return false; return false;
} }
if (mainModel instanceof AbstractPonyModel abs) { if (mainModel instanceof ClientPonyModel abs) {
abs.copyTransforms(this); abs.copyTransforms(this);
} }
return true; return true;

View file

@ -1,9 +1,9 @@
package com.minelittlepony.client.model.entity; package com.minelittlepony.client.model.entity;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.client.render.entity.EnderStallionRenderer; import com.minelittlepony.client.render.entity.EnderStallionRenderer;
public class EnderStallionModel extends SkeleponyModel<EnderStallionRenderer.State> { public class EnderStallionModel extends SkeleponyModel<EnderStallionRenderer.State> {
@ -36,11 +36,9 @@ public class EnderStallionModel extends SkeleponyModel<EnderStallionRenderer.Sta
} }
@Override @Override
public void render(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { public void transform(EnderStallionRenderer.State state, BodyPart part, MatrixStack stack) {
stack.push();
stack.translate(0, -1.15F, 0); stack.translate(0, -1.15F, 0);
super.render(stack, vertices, overlay, light, color); super.transform(state, part, stack);
stack.pop();
} }
@Override @Override

View file

@ -13,8 +13,6 @@ import com.minelittlepony.client.render.entity.SkeleponyRenderer;
public class SkeleponyModel<T extends SkeleponyRenderer.State> extends AlicornModel<T> { public class SkeleponyModel<T extends SkeleponyRenderer.State> extends AlicornModel<T> {
public SkeleponyModel(ModelPart tree) { public SkeleponyModel(ModelPart tree) {
super(tree, false); super(tree, false);
vestRenderList.clear();
sleevesRenderList.clear();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View file

@ -20,7 +20,7 @@ public class AlicornModel<T extends PonyRenderState> extends UnicornModel<T> imp
public void init(ModelView context) { public void init(ModelView context) {
super.init(context); super.init(context);
wings = addPart(context.findByName("wings")); wings = addPart(context.findByName("wings"));
bodyRenderList.add(forPart(this::getWings).checked(() -> currentState.race.hasWings())); bodyRenderList.add(forPart(this::getWings));
} }
@Override @Override

View file

@ -9,6 +9,7 @@ import com.minelittlepony.mson.api.ModelView;
import com.minelittlepony.mson.util.RenderList; import com.minelittlepony.mson.util.RenderList;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.consume.UseAction; import net.minecraft.item.consume.UseAction;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
@ -17,7 +18,7 @@ import net.minecraft.util.*;
/** /**
* Used for both unicorns and alicorns since there's no logical way to keep them distinct and not duplicate stuff. * Used for both unicorns and alicorns since there's no logical way to keep them distinct and not duplicate stuff.
*/ */
public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> implements HornedPonyModel<T> { public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> {
protected final ModelPart unicornArmRight; protected final ModelPart unicornArmRight;
protected final ModelPart unicornArmLeft; protected final ModelPart unicornArmLeft;
@ -30,14 +31,24 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> i
unicornArmLeft = tree.getChild("left_cast"); unicornArmLeft = tree.getChild("left_cast");
} }
public boolean isCasting(T state) {
return state instanceof PlayerEntityRenderState s
&& (getArmPose(s, Arm.LEFT) != ArmPose.EMPTY || getArmPose(s, Arm.RIGHT) != ArmPose.EMPTY);
}
@Override
public float getWobbleAmplitude(T state) {
return isCasting(state) ? 0 : 1;
}
@Override @Override
public void init(ModelView context) { public void init(ModelView context) {
super.init(context); super.init(context);
horn = addPart(context.findByName("horn")); horn = addPart(context.findByName("horn"));
headRenderList.add(RenderList.of().add(head::rotate).add(forPart(horn)).checked(() -> currentState.race.hasHorn())); headRenderList.add(RenderList.of().add(head::rotate).add(forPart(horn)));
this.mainRenderList.add(withStage(BodyPart.HEAD, RenderList.of().add(head::rotate).add((stack, vertices, overlay, light, color) -> { mainRenderList.add(withStage(BodyPart.HEAD, RenderList.of().add(head::rotate).add((stack, vertices, overlay, light, color) -> {
horn.renderMagic(stack, vertices, currentState.attributes.metadata.glowColor()); horn.renderMagic(stack, vertices, currentState == null ? 0 : currentState.attributes.metadata.glowColor());
})).checked(() -> currentState.hasMagicGlow() && isCasting(currentState))); })).checked(() -> isCasting(currentState)));
} }
@Override @Override
@ -60,7 +71,7 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> i
@Override @Override
public ModelPart getArm(Arm side) { public ModelPart getArm(Arm side) {
if (currentState.hasMagicGlow() && getArmPoseForSide(currentState, side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) { if (currentState != null && currentState.hasMagicGlow() && getArmPoseForSide(currentState, side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) {
return side == Arm.LEFT ? unicornArmLeft : unicornArmRight; return side == Arm.LEFT ? unicornArmLeft : unicornArmRight;
} }
return super.getArm(side); return super.getArm(side);
@ -70,7 +81,7 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> i
protected void positionheldItem(T state, Arm arm, MatrixStack matrices) { protected void positionheldItem(T state, Arm arm, MatrixStack matrices) {
super.positionheldItem(state, arm, matrices); super.positionheldItem(state, arm, matrices);
if (!PonyConfig.getInstance().tpsmagic.get() || !currentState.hasMagicGlow()) { if (!PonyConfig.getInstance().tpsmagic.get() || !state.hasMagicGlow()) {
return; return;
} }
@ -93,9 +104,9 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> i
float x = 0.3F; float x = 0.3F;
float z = -0.4F; float z = -0.4F;
if (state.size == SizePreset.TALL || state.size == SizePreset.YEARLING) { if (state.attributes.size == SizePreset.TALL || state.attributes.size == SizePreset.YEARLING) {
z += 0.05F; z += 0.05F;
} else if (state.size == SizePreset.FOAL) { } else if (state.attributes.size == SizePreset.FOAL) {
x -= 0.1F; x -= 0.1F;
z -= 0.1F; z -= 0.1F;
} }

View file

@ -112,7 +112,7 @@ public class PonyTail implements SubModel<PonyRenderState>, MsonModel {
} }
public void setAngles(int index, PonyTail tail, ModelAttributes attributes) { public void setAngles(int index, PonyTail tail, ModelAttributes attributes) {
tree.visible = index >= tail.tailStop; tree.visible = index < tail.tailStop;
shape = tail.shape; shape = tail.shape;
horsey = attributes.isHorsey; horsey = attributes.isHorsey;

View file

@ -21,6 +21,8 @@ public class PonyWings<S extends PonyRenderState> implements SubModel<S>, MsonMo
protected Wing<S> legacyWing; protected Wing<S> legacyWing;
private boolean visible;
public PonyWings(ModelPart tree) { public PonyWings(ModelPart tree) {
} }
@ -113,6 +115,10 @@ public class PonyWings<S extends PonyRenderState> implements SubModel<S>, MsonMo
} }
} }
@Override
public void setVisible(boolean visible, S state) {
visible = state.race.hasWings();
}
private boolean isBurdened(S state) { private boolean isBurdened(S state) {
return state.getAttributes().isWearing(Wearable.SADDLE_BAGS_BOTH) return state.getAttributes().isWearing(Wearable.SADDLE_BAGS_BOTH)
@ -122,10 +128,12 @@ public class PonyWings<S extends PonyRenderState> implements SubModel<S>, MsonMo
@Override @Override
public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) {
if (visible) {
leftWing.render(stack, vertices, overlay, light, color); leftWing.render(stack, vertices, overlay, light, color);
rightWing.render(stack, vertices, overlay, light, color); rightWing.render(stack, vertices, overlay, light, color);
legacyWing.render(stack, vertices, overlay, light, color); legacyWing.render(stack, vertices, overlay, light, color);
} }
}
public static class Wing<S extends PonyRenderState> implements MsonModel { public static class Wing<S extends PonyRenderState> implements MsonModel {

View file

@ -17,6 +17,7 @@ public class UnicornHorn<T extends PonyRenderState> implements SubModel<T> {
private final ModelPart glow; private final ModelPart glow;
protected boolean visible = true; protected boolean visible = true;
protected boolean glowing;
public UnicornHorn(ModelPart tree) { public UnicornHorn(ModelPart tree) {
horn = tree.getChild("bone"); horn = tree.getChild("bone");
@ -39,7 +40,7 @@ public class UnicornHorn<T extends PonyRenderState> implements SubModel<T> {
@Override @Override
public void setVisible(boolean visible, T state) { public void setVisible(boolean visible, T state) {
horn.visible = this.visible && visible; horn.visible = this.visible && visible && state.race.hasHorn();
glow.visible = this.visible && visible; glow.visible = this.visible && visible && state.hasMagicGlow();
} }
} }

View file

@ -37,7 +37,7 @@ public final class DebugBoundingBoxRenderer {
} }
public static Box getBoundingBox(PonyRenderState state) { public static Box getBoundingBox(PonyRenderState state) {
return getBoundingBox(state.x, state.y, state.z, state.size.scaleFactor(), state.width, state.height); return getBoundingBox(state.x, state.y, state.z, state.attributes.size.scaleFactor(), state.width, state.height);
} }
public static Box getBoundingBox(double x, double y, double z, float scale, float width, float height) { public static Box getBoundingBox(double x, double y, double z, float scale, float width, float height) {

View file

@ -94,7 +94,7 @@ public class EquineRenderManager<
} }
public void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) { public void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) {
float s = state.size.scaleFactor(); float s = state.attributes.size.scaleFactor();
stack.scale(s, s, s); stack.scale(s, s, s);
if (state instanceof PlayerEntityRenderState && state.attributes.isSitting) { if (state instanceof PlayerEntityRenderState && state.attributes.isSitting) {

View file

@ -37,8 +37,8 @@ public class LevitatingItemRenderer {
* Renders an item with a magical overlay. * Renders an item with a magical overlay.
*/ */
public boolean renderItem(ItemRenderer itemRenderer, @Nullable LivingEntity entity, ItemStack stack, ModelTransformationMode mode, boolean left, public boolean renderItem(ItemRenderer itemRenderer, @Nullable LivingEntity entity, ItemStack stack, ModelTransformationMode mode, boolean left,
MatrixStack matrix, VertexConsumerProvider renderContext, @Nullable World world, MatrixStack matrices, VertexConsumerProvider vertices, @Nullable World world,
int lightUv, int overlay, int seed, Operation<Void> original) { int light, int overlay, int seed, Operation<Void> original) {
if (entity == null || !(mode.isFirstPerson() if (entity == null || !(mode.isFirstPerson()
|| mode == ModelTransformationMode.THIRD_PERSON_LEFT_HAND || mode == ModelTransformationMode.THIRD_PERSON_LEFT_HAND
@ -54,18 +54,18 @@ public class LevitatingItemRenderer {
var state = context.getAndUpdateRenderState(entity, MinecraftClient.getInstance().getRenderTickCounter().getTickDelta(false)); var state = context.getAndUpdateRenderState(entity, MinecraftClient.getInstance().getRenderTickCounter().getTickDelta(false));
matrix.push(); matrices.push();
boolean doMagic = (mode.isFirstPerson() ? PonyConfig.getInstance().fpsmagic : PonyConfig.getInstance().tpsmagic).get() && state.hasMagicGlow(); boolean doMagic = (mode.isFirstPerson() ? PonyConfig.getInstance().fpsmagic : PonyConfig.getInstance().tpsmagic).get() && state.hasMagicGlow();
if (doMagic && mode.isFirstPerson()) { if (doMagic && mode.isFirstPerson()) {
setupPerspective(entity, stack, left, matrix); setupPerspective(entity, stack, left, matrices);
} }
original.call(entity, stack, mode, left, matrix, renderContext, world, lightUv, overlay, seed); original.call(itemRenderer, entity, stack, mode, left, matrices, vertices, world, light, overlay, seed);
if (doMagic) { if (doMagic) {
VertexConsumerProvider interceptedContext = getProvider(state.pony, renderContext); VertexConsumerProvider interceptedContext = getProvider(state.pony, vertices);
if (stack.hasGlint()) { if (stack.hasGlint()) {
stack = stack.copy(); stack = stack.copy();
@ -80,16 +80,16 @@ public class LevitatingItemRenderer {
float zDrift = MathHelper.cos((tickDelta + 20) / 20F) * driftStrength; float zDrift = MathHelper.cos((tickDelta + 20) / 20F) * driftStrength;
float scale = 1.1F + (MathHelper.sin(tickDelta / 20F) + 1) * driftStrength; float scale = 1.1F + (MathHelper.sin(tickDelta / 20F) + 1) * driftStrength;
matrix.scale(scale, scale, scale); matrices.scale(scale, scale, scale);
matrix.translate(0.015F + xDrift, 0.01F, 0.01F + zDrift); matrices.translate(0.015F + xDrift, 0.01F, 0.01F + zDrift);
original.call(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, seed); original.call(itemRenderer, entity, stack, mode, left, matrices, interceptedContext, world, light, OverlayTexture.DEFAULT_UV, seed);
matrix.scale(scale, scale, scale); matrices.scale(scale, scale, scale);
matrix.translate(-0.03F - xDrift, -0.02F, -0.02F - zDrift); matrices.translate(-0.03F - xDrift, -0.02F, -0.02F - zDrift);
original.call(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, seed); original.call(itemRenderer, entity, stack, mode, left, matrices, interceptedContext, world, light, OverlayTexture.DEFAULT_UV, seed);
} }
matrix.pop(); matrices.pop();
return true; return true;
} }

View file

@ -6,6 +6,7 @@ import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.client.model.AbstractPonyModel; import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.client.render.MobRenderers;
import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer.ISkull; import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer.ISkull;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import com.minelittlepony.mson.api.ModelKey; import com.minelittlepony.mson.api.ModelKey;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -20,15 +21,17 @@ import net.minecraft.util.math.RotationAxis;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f; import org.joml.Vector3f;
public class MobSkull implements ISkull { public class MobSkull<S extends PonyRenderState> implements ISkull {
private final Identifier texture; private final Identifier texture;
private final MobRenderers type; private final MobRenderers type;
private final Supplier<AbstractPonyModel<?>> ponyHead; private final Supplier<AbstractPonyModel<?>> ponyHead;
private final Supplier<S> state;
MobSkull(Identifier texture, MobRenderers type, ModelKey<? extends AbstractPonyModel<?>> modelKey) { MobSkull(Identifier texture, MobRenderers type, ModelKey<? extends AbstractPonyModel<?>> modelKey, Supplier<S> state) {
this.texture = texture; this.texture = texture;
this.type = type; this.type = type;
this.state = Suppliers.memoize(state::get);
this.ponyHead = Suppliers.memoize(modelKey::createModel); this.ponyHead = Suppliers.memoize(modelKey::createModel);
} }
@ -44,6 +47,11 @@ public class MobSkull implements ISkull {
@Override @Override
public boolean bindPony(Pony pony) { public boolean bindPony(Pony pony) {
S state = this.state.get();
state.pony = pony;
state.race = pony.race();
state.attributes.size = pony.size();
state.attributes.metadata = pony.metadata();
return true; return true;
} }
@ -51,11 +59,12 @@ public class MobSkull implements ISkull {
public void setAngles(float yaw, float animationProgress) { public void setAngles(float yaw, float animationProgress) {
Vector3f v = new Vector3f(0, -2, 1.99F); Vector3f v = new Vector3f(0, -2, 1.99F);
v.rotate(RotationAxis.POSITIVE_Y.rotationDegrees(yaw)); v.rotate(RotationAxis.POSITIVE_Y.rotationDegrees(yaw));
ponyHead.get().setVisible(true);
ponyHead.get().setAngles(state.get());
ModelPart head = ponyHead.get().getHead(); ModelPart head = ponyHead.get().getHead();
head.pivotX = v.x; head.pivotX = v.x;
head.pivotY = v.y; head.pivotY = v.y;
head.pivotZ = v.z; head.pivotZ = v.z;
ponyHead.get().setVisible(true);
ponyHead.get().setHeadRotation(animationProgress, yaw, 0); ponyHead.get().setHeadRotation(animationProgress, yaw, 0);
} }

View file

@ -83,9 +83,6 @@ public class PlayerPonySkull implements ISkull {
stack.push(); stack.push();
ponyHead.headRenderList.accept(stack, vertices, light, overlay, color); ponyHead.headRenderList.accept(stack, vertices, light, overlay, color);
stack.pop(); stack.pop();
stack.push();
ponyHead.helmetRenderList.accept(stack, vertices, light, overlay, color);
stack.pop();
if (renderingEars) { if (renderingEars) {
stack.push(); stack.push();
stack.scale(1.3333334f, 1.3333334f, 1.3333334f); stack.scale(1.3333334f, 1.3333334f, 1.3333334f);

View file

@ -6,6 +6,7 @@ import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.model.armour.ArmourRendererPlugin;
import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.client.render.MobRenderers;
import com.minelittlepony.client.render.entity.*; import com.minelittlepony.client.render.entity.*;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.block.AbstractSkullBlock; import net.minecraft.block.AbstractSkullBlock;
import net.minecraft.block.SkullBlock; import net.minecraft.block.SkullBlock;
@ -51,10 +52,10 @@ public class PonySkullRenderer {
public void reload() { public void reload() {
skulls = Util.make(new HashMap<>(), skullMap -> { skulls = Util.make(new HashMap<>(), skullMap -> {
skullMap.put(SkullBlock.Type.SKELETON, new MobSkull(SkeleponyRenderer.SKELETON, MobRenderers.SKELETON, ModelType.SKELETON)); skullMap.put(SkullBlock.Type.SKELETON, new MobSkull<>(SkeleponyRenderer.SKELETON, MobRenderers.SKELETON, ModelType.SKELETON, SkeleponyRenderer.State::new));
skullMap.put(SkullBlock.Type.WITHER_SKELETON, new MobSkull(SkeleponyRenderer.WITHER, MobRenderers.SKELETON, ModelType.SKELETON)); skullMap.put(SkullBlock.Type.WITHER_SKELETON, new MobSkull<>(SkeleponyRenderer.WITHER, MobRenderers.SKELETON, ModelType.SKELETON, SkeleponyRenderer.State::new));
skullMap.put(SkullBlock.Type.ZOMBIE, new MobSkull(ZomponyRenderer.ZOMBIE, MobRenderers.ZOMBIE, ModelType.ZOMBIE)); skullMap.put(SkullBlock.Type.ZOMBIE, new MobSkull<>(ZomponyRenderer.ZOMBIE, MobRenderers.ZOMBIE, ModelType.ZOMBIE, PonyRenderState::new));
skullMap.put(SkullBlock.Type.PIGLIN, new MobSkull(PonyPiglinRenderer.PIGLIN, MobRenderers.PIGLIN, ModelType.PIGLIN)); skullMap.put(SkullBlock.Type.PIGLIN, new MobSkull<>(PonyPiglinRenderer.PIGLIN, MobRenderers.PIGLIN, ModelType.PIGLIN, PonyPiglinRenderer.State::new));
skullMap.put(SkullBlock.Type.PLAYER, new PlayerPonySkull()); skullMap.put(SkullBlock.Type.PLAYER, new PlayerPonySkull());
}); });
headModels = SkullBlockEntityRenderer.getModels(MinecraftClient.getInstance().getEntityModelLoader()); headModels = SkullBlockEntityRenderer.getModels(MinecraftClient.getInstance().getEntityModelLoader());

View file

@ -116,7 +116,7 @@ public abstract class AbstractPonyRenderer<
@Override @Override
public void scale(S state, MatrixStack stack) { public void scale(S state, MatrixStack stack) {
shadowRadius = state.size.shadowSize(); shadowRadius = state.attributes.size.shadowSize();
if (state.baby) { if (state.baby) {
shadowRadius *= 3; // undo vanilla shadow scaling shadowRadius *= 3; // undo vanilla shadow scaling

View file

@ -73,7 +73,7 @@ public class PlayerPonyRenderer
public Vec3d getPositionOffset(PlayerEntityRenderState state) { public Vec3d getPositionOffset(PlayerEntityRenderState state) {
Vec3d offset = super.getPositionOffset(state); Vec3d offset = super.getPositionOffset(state);
return offset.add(state.baseScale * ((PlayerPonyRenderState)state).yOffset).multiply(((PonyRenderState)state).size.scaleFactor()); return offset.add(state.baseScale * ((PlayerPonyRenderState)state).yOffset).multiply(((PonyRenderState)state).attributes.size.scaleFactor());
} }
@Override @Override
@ -102,7 +102,7 @@ public class PlayerPonyRenderer
@Override @Override
public void render(PlayerEntityRenderState state, MatrixStack stack, VertexConsumerProvider vertices, int light) { public void render(PlayerEntityRenderState state, MatrixStack stack, VertexConsumerProvider vertices, int light) {
// EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering // EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering
shadowRadius = ((PlayerPonyRenderState)state).size.shadowSize(); shadowRadius = ((PlayerPonyRenderState)state).attributes.size.shadowSize();
super.render(state, stack, vertices, light); super.render(state, stack, vertices, light);
DebugBoundingBoxRenderer.render((PlayerPonyRenderState)state, stack, vertices); DebugBoundingBoxRenderer.render((PlayerPonyRenderState)state, stack, vertices);

View file

@ -45,6 +45,6 @@ public class PonyPiglinRenderer extends PonyRenderer<HostileEntity, PonyPiglinRe
public static class State extends PonyRenderState { public static class State extends PonyRenderState {
public boolean zombified; public boolean zombified;
public PiglinActivity activity; public PiglinActivity activity = PiglinActivity.DEFAULT;
} }
} }

View file

@ -50,7 +50,7 @@ public class SeaponyRenderer extends PonyRenderer<GuardianEntity, SeaponyRendere
super.updateRenderState(entity, state, tickDelta); super.updateRenderState(entity, state, tickDelta);
state.spikesExtension = entity.getSpikesExtension(tickDelta); state.spikesExtension = entity.getSpikesExtension(tickDelta);
state.tailAngle = entity.getTailAngle(tickDelta); state.tailAngle = entity.getTailAngle(tickDelta);
state.cameraPosVec = getScaledCameraPosVec(entity, tickDelta, state.size.scaleFactor()); state.cameraPosVec = getScaledCameraPosVec(entity, tickDelta, state.attributes.size.scaleFactor());
Entity cameraBeamTarget = GuardianEntityRenderer.getBeamTarget(entity); Entity cameraBeamTarget = GuardianEntityRenderer.getBeamTarget(entity);
state.rotationVec = cameraBeamTarget != null ? entity.getRotationVec(tickDelta) : null; state.rotationVec = cameraBeamTarget != null ? entity.getRotationVec(tickDelta) : null;
state.lookAtPos = cameraBeamTarget != null ? cameraBeamTarget.getCameraPosVec(tickDelta) : null; state.lookAtPos = cameraBeamTarget != null ? cameraBeamTarget.getCameraPosVec(tickDelta) : null;

View file

@ -65,7 +65,7 @@ public class ArmourFeature<
? EquipmentModel.LayerType.HUMANOID_LEGGINGS ? EquipmentModel.LayerType.HUMANOID_LEGGINGS
: EquipmentModel.LayerType.HUMANOID; : EquipmentModel.LayerType.HUMANOID;
Identifier modelId = equippableComponent.model().orElseThrow(); Identifier modelId = equippableComponent.model().orElseThrow();
equipmentRenderer.render(armorSlot, layerType, modelId, models, stack, matrices, vertices, light); equipmentRenderer.render(armorSlot, layerType, modelId, entity, models, stack, matrices, vertices, light);
} }
} }

View file

@ -13,7 +13,7 @@ import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.api.events.PonyModelPrepareCallback; import com.minelittlepony.api.events.PonyModelPrepareCallback;
import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.*;
import com.minelittlepony.api.pony.meta.*; import com.minelittlepony.api.pony.meta.*;
import com.minelittlepony.client.transform.PonyPosture; import com.minelittlepony.client.transform.PonyPosture;
@ -31,15 +31,14 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
public boolean onGround; public boolean onGround;
public boolean isTechnoblade; public boolean isTechnoblade;
public Pony pony; public Pony pony = Pony.getManager().getPony(DefaultPonySkinHelper.STEVE);
public Size size; public Race race = Race.HUMAN;
public Race race;
public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) { public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) {
this.pony = pony; this.pony = pony;
attributes.updateLivingState(entity, pony, mode); attributes.updateLivingState(entity, pony, mode);
attributes.checkRainboom(entity, model, age); attributes.checkRainboom(entity, model, age);
size = baby ? SizePreset.FOAL : PonyConfig.getEffectiveSize(attributes.metadata.size()); baby = attributes.size == SizePreset.FOAL;
race = PonyConfig.getEffectiveRace(attributes.metadata.race()); race = PonyConfig.getEffectiveRace(attributes.metadata.race());
vehicleOffset = hasVehicle ? entity.getVehicle().getEyeHeight(pose) : 0; vehicleOffset = hasVehicle ? entity.getVehicle().getEyeHeight(pose) : 0;
riderOffset = getRiderYOffset(); riderOffset = getRiderYOffset();
@ -94,7 +93,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
* Gets the y-offset applied to entities riding this one. * Gets the y-offset applied to entities riding this one.
*/ */
protected float getRiderYOffset() { protected float getRiderYOffset() {
return switch ((SizePreset)size) { return switch ((SizePreset)attributes.size) {
case NORMAL -> 0.4F; case NORMAL -> 0.4F;
default -> 0.25F; default -> 0.25F;
}; };
@ -112,7 +111,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
float y = -(height + 0.5F); float y = -(height + 0.5F);
// Then we add our own offsets. // Then we add our own offsets.
y += attributes.visualHeight * size.scaleFactor() + 0.25F; y += attributes.visualHeight * attributes.size.scaleFactor() + 0.25F;
y += vehicleOffset; y += vehicleOffset;
if (isInSneakingPose) { if (isInSneakingPose) {

View file

@ -3,8 +3,6 @@ package com.minelittlepony.util;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import com.minelittlepony.client.MineLittlePony;
import java.util.Optional; import java.util.Optional;
public final class ResourceUtil { public final class ResourceUtil {
@ -30,16 +28,4 @@ public final class ResourceUtil {
public static Optional<Identifier> verifyTexture(Identifier texture) { public static Optional<Identifier> verifyTexture(Identifier texture) {
return textureExists(texture) ? Optional.of(texture) : Optional.empty(); return textureExists(texture) ? Optional.of(texture) : Optional.empty();
} }
public static Identifier ponify(Identifier texture) {
String path = texture.getPath();
if (path.endsWith("_pony.png")) {
return texture;
}
if (Identifier.DEFAULT_NAMESPACE.contentEquals(texture.getNamespace())) {
return MineLittlePony.id(path.replace(".png", "_pony.png")); // it's in the vanilla namespace, we provide these.
}
return texture.withPath(p -> p.replace(".png", "_pony.png"));
}
} }

View file

@ -22,7 +22,6 @@
}, },
"hat": { "hat": {
"texture": { "u": 40, "v": 27 }, "texture": { "u": 40, "v": 27 },
"pivot": [0, 1, -4],
"children": { "children": {
"hat_parts": { "hat_parts": {
"pivot": [0, 2, 0], "pivot": [0, 2, 0],

View file

@ -5,7 +5,12 @@
"texture": {"u": 16, "v": 8}, "texture": {"u": 16, "v": 8},
"cubes": [ "cubes": [
{"from": [-4, 4, -2], "size": [8, 8, 16]} {"from": [-4, 4, -2], "size": [8, 8, 16]}
] ],
"children": {
"jacket": {
"visible": false
}
}
}, },
"right_leg": { "right_leg": {
"pivot": ["#arm_rotation_x_neg", 0, 0], "pivot": ["#arm_rotation_x_neg", 0, 0],
@ -15,7 +20,12 @@
"from": [ "#arm_x_neg", 4, "#arm_z"], "from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ] "size": [ "#arm_width", "#arm_length", "#arm_depth" ]
} }
] ],
"children": {
"right_pants": {
"visible": false
}
}
}, },
"left_leg": { "left_leg": {
"pivot": ["#arm_rotation_x", 0, 0], "pivot": ["#arm_rotation_x", 0, 0],
@ -26,7 +36,12 @@
"from": [ "#arm_x", 4, "#arm_z"], "from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ] "size": [ "#arm_width", "#arm_length", "#arm_depth" ]
} }
] ],
"children": {
"left_pants": {
"visible": false
}
}
} }
} }
} }

View file

@ -17,6 +17,9 @@
"south": [-4, 4, 10, 8, 8, 32, 23], "south": [-4, 4, 10, 8, 8, 32, 23],
"up": [ -4, 4, 1, 8, 12, 32, 23], "up": [ -4, 4, 1, 8, 12, 32, 23],
"__comment": "it's a little short, so the butt tends to show. :/" "__comment": "it's a little short, so the butt tends to show. :/"
},
"jacket": {
"visible": false
} }
} }
}, },
@ -25,7 +28,17 @@
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }, { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 },
{ "from": [-4, -8, -1], "size": [ 2, 2, 2], "texture": {"u": 0, "v": 0}, "dilate": -0.0125 }, { "from": [-4, -8, -1], "size": [ 2, 2, 2], "texture": {"u": 0, "v": 0}, "dilate": -0.0125 },
{ "from": [ 2, -8, -1], "size": [ 2, 2, 2], "texture": {"u": 0, "v": 4}, "dilate": -0.0125 } { "from": [ 2, -8, -1], "size": [ 2, 2, 2], "texture": {"u": 0, "v": 4}, "dilate": -0.0125 }
],
"children": {
"hat": {
"texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 0 ],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }
] ]
}
}
}, },
"right_arm": { "right_arm": {
"pivot": ["#arm_rotation_x_neg", "#arm_rotation_y", 0], "pivot": ["#arm_rotation_x_neg", "#arm_rotation_y", 0],
@ -35,7 +48,12 @@
"from": [ "#arm_x_neg", 4, "#arm_z"], "from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ] "size": [ "#arm_width", "#arm_length", "#arm_depth" ]
} }
] ],
"children": {
"right_sleeve": {
"visible": false
}
}
}, },
"left_arm": { "left_arm": {
"pivot": ["#arm_rotation_x", "#arm_rotation_y", 0], "pivot": ["#arm_rotation_x", "#arm_rotation_y", 0],
@ -46,7 +64,12 @@
"from": [ "#arm_x", 4, "#arm_z"], "from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ] "size": [ "#arm_width", "#arm_length", "#arm_depth" ]
} }
] ],
"children": {
"left_sleeve": {
"visible": false
}
}
}, },
"right_leg": { "right_leg": {
"pivot": ["#arm_rotation_x_neg", 0, 0], "pivot": ["#arm_rotation_x_neg", 0, 0],
@ -56,7 +79,12 @@
"from": [ "#arm_x_neg", 4, "#arm_z"], "from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ] "size": [ "#arm_width", "#arm_length", "#arm_depth" ]
} }
] ],
"children": {
"right_pants": {
"visible": false
}
}
}, },
"left_leg": { "left_leg": {
"pivot": ["#arm_rotation_x", 0, 0], "pivot": ["#arm_rotation_x", 0, 0],
@ -67,7 +95,12 @@
"from": [ "#arm_x", 4, "#arm_z"], "from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ] "size": [ "#arm_width", "#arm_length", "#arm_depth" ]
} }
] ],
"children": {
"left_pants": {
"visible": false
}
}
} }
} }
} }

View file

@ -7,7 +7,12 @@
"dilate": 0.41, "dilate": 0.41,
"cubes": [ "cubes": [
{"from": [-4, 4, -2], "size": [8, 8, 16]} {"from": [-4, 4, -2], "size": [8, 8, 16]}
] ],
"children": {
"jacket": {
"visible": false
}
}
} }
} }
} }

View file

@ -8,7 +8,6 @@
], ],
"children": { "children": {
"hat": { "hat": {
"pivot": [ 0, 5, 0 ],
"cubes": [ "cubes": [
{ "from": [ -1, -7, -1 ], "size": [ 2, 7, 2 ], "dilate": 0.5 } { "from": [ -1, -7, -1 ], "size": [ 2, 7, 2 ], "dilate": 0.5 }
] ]

View file

@ -29,7 +29,6 @@
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"visible": false, "visible": false,
"pivot": [0, 0, -2],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": -0.5 } { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": -0.5 }
] ]

View file

@ -29,7 +29,6 @@
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0], "dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 0 ],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 } { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }
] ]

View file

@ -50,7 +50,6 @@
} }
}, },
"left_sleeve": { "left_sleeve": {
"pivot": ["#arm_rotation_x", "#arm_rotation_y", "#arm_rotation_z"],
"visible": false, "visible": false,
"texture": { "u": 48, "v": 48 }, "texture": { "u": 48, "v": 48 },
"cubes": [ "cubes": [
@ -108,7 +107,11 @@
"visible": false, "visible": false,
"texture": { "u": 40, "v": 32 }, "texture": { "u": 40, "v": 32 },
"cubes": [ "cubes": [
{ "from": [-3, -2, -2], "size": [ 4, 12, 4], "dilate": [0.25, 0.25, 0.25] } {
"from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"dilate": 0.25
}
] ]
} }
} }

View file

@ -77,7 +77,6 @@
} }
}, },
"left_sleeve": { "left_sleeve": {
"pivot": ["#arm_rotation_x", "#arm_rotation_y", "#arm_rotation_z"],
"visible": false, "visible": false,
"texture": { "u": 48, "v": 48 }, "texture": { "u": 48, "v": 48 },
"cubes": [ "cubes": [
@ -115,6 +114,17 @@
"height": "#fore_arm_length", "height": "#fore_arm_length",
"depth": "#arm_depth" "depth": "#arm_depth"
} }
},
"right_sleeve": {
"visible": false,
"texture": { "u": 40, "v": 32 },
"cubes": [
{
"from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"dilate": 0.25
}
]
} }
} }
}, },
@ -143,6 +153,17 @@
"height": "#fore_leg_length", "height": "#fore_leg_length",
"depth": "#arm_depth" "depth": "#arm_depth"
} }
},
"left_pants": {
"visible": false,
"texture": { "u": 0, "v": 48 },
"cubes": [
{
"from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"dilate": 0.25
}
]
} }
} }
}, },
@ -172,11 +193,15 @@
"depth": "#arm_depth" "depth": "#arm_depth"
} }
}, },
"right_sleeve": { "right_pants": {
"visible": false, "visible": false,
"texture": { "u": 40, "v": 32 }, "texture": { "u": 0, "v": 32 },
"cubes": [ "cubes": [
{ "from": [-3, -2, -2], "size": [ 4, 12, 4], "dilate": [0.25, 0.25, 0.25] } {
"from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"dilate": 0.25
}
] ]
} }
} }

View file

@ -38,7 +38,6 @@
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0], "dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 0 ],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 } { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }
] ]

View file

@ -31,7 +31,6 @@
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0], "dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 0 ],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 } { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }
] ]

View file

@ -56,7 +56,6 @@
], ],
"children": { "children": {
"right_sleeve": { "right_sleeve": {
"pivot": ["#arm_rotation_x_neg", "#arm_rotation_y", "#arm_rotation_z"],
"rotate": [-80, 29, 0], "rotate": [-80, 29, 0],
"visible": false, "visible": false,
"texture": { "u": 40, "v": 32 }, "texture": { "u": 40, "v": 32 },
@ -82,7 +81,6 @@
], ],
"children": { "children": {
"left_sleeve": { "left_sleeve": {
"pivot": ["#arm_rotation_x", "#arm_rotation_y", "#arm_rotation_z"],
"rotate": [-80, -29, 0], "rotate": [-80, -29, 0],
"visible": false, "visible": false,
"texture": { "u": 48, "v": 48 }, "texture": { "u": 48, "v": 48 },

View file

@ -26,7 +26,6 @@
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0], "dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 0 ],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 } { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }
] ]

View file

@ -28,7 +28,6 @@
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0], "dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 0 ],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 } { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }
] ]

View file

@ -278,7 +278,6 @@
], ],
"children": { "children": {
"right_sleeve": { "right_sleeve": {
"pivot": ["#arm_rotation_x_neg", "#arm_rotation_y", "#arm_rotation_z"],
"visible": false, "visible": false,
"texture": { "u": 40, "v": 32 }, "texture": { "u": 40, "v": 32 },
"cubes": [ "cubes": [
@ -302,7 +301,6 @@
], ],
"children": { "children": {
"left_sleeve": { "left_sleeve": {
"pivot": ["#arm_rotation_x", "#arm_rotation_y", "#arm_rotation_z"],
"visible": false, "visible": false,
"texture": { "u": 48, "v": 48 }, "texture": { "u": 48, "v": 48 },
"cubes": [ "cubes": [
@ -326,7 +324,6 @@
], ],
"children": { "children": {
"right_pants": { "right_pants": {
"pivot": ["#arm_rotation_x_neg", "#arm_rotation_y", 11],
"visible": false, "visible": false,
"texture": { "u": 0, "v": 32 }, "texture": { "u": 0, "v": 32 },
"cubes": [ "cubes": [
@ -350,7 +347,6 @@
], ],
"children": { "children": {
"left_pants": { "left_pants": {
"pivot": ["#arm_rotation_x_neg", "#arm_rotation_y", 11],
"visible": false, "visible": false,
"texture": { "u": 0, "v": 48 }, "texture": { "u": 0, "v": 48 },
"cubes": [ "cubes": [

View file

@ -26,7 +26,6 @@
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0], "dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 0 ],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 } { "from": [-4, -6, -6], "size": [ 8, 8, 8], "dilate": 0.5 }
] ]