April fools 2023

This commit is contained in:
Sollace 2023-03-30 01:46:03 +01:00
parent 32d1ffbe7c
commit d9769e32ee
31 changed files with 401 additions and 54 deletions

View file

@ -52,6 +52,8 @@ public class PonyConfig extends Config {
public final Setting<Boolean> frustrum = value("settings", "frustrum", true) public final Setting<Boolean> frustrum = value("settings", "frustrum", true)
.addComment("Adjust camera intersection checks to properly cull entities when they're not in view.") .addComment("Adjust camera intersection checks to properly cull entities when they're not in view.")
.addComment("Helps to prevent entities from vanishing when they're in long stacks"); .addComment("Helps to prevent entities from vanishing when they're in long stacks");
public final Setting<Boolean> horsieMode = value("settings", "horsieMode", false)
.addComment("Enables the alternative horsey models from the April Fools 2023 update");
public final Setting<Sizes> sizeOverride = value("debug", "sizeOverride", Sizes.UNSET) public final Setting<Sizes> sizeOverride = value("debug", "sizeOverride", Sizes.UNSET)
.addComment("Overrides pony sizes") .addComment("Overrides pony sizes")

View file

@ -1,8 +1,7 @@
package com.minelittlepony.api.model; package com.minelittlepony.api.model;
import com.minelittlepony.api.pony.*; import com.minelittlepony.api.pony.*;
import com.minelittlepony.client.IPreviewModel; import com.minelittlepony.client.*;
import com.minelittlepony.client.SkinsProxy;
import com.minelittlepony.client.pony.PonyData; import com.minelittlepony.client.pony.PonyData;
import com.minelittlepony.common.util.animation.Interpolator; import com.minelittlepony.common.util.animation.Interpolator;
import com.minelittlepony.util.MathUtil; import com.minelittlepony.util.MathUtil;
@ -64,6 +63,10 @@ public class ModelAttributes {
* Flag indicating that this model is performing a rainboom (flight). * Flag indicating that this model is performing a rainboom (flight).
*/ */
public boolean isGoingFast; public boolean isGoingFast;
/**
* Flag indicating that this model should mimic the vanilla horse models.
*/
public boolean isHorsey;
/** /**
* Vertical pitch whilst flying. * Vertical pitch whilst flying.
@ -149,6 +152,7 @@ public class ModelAttributes {
interpolatorId = entity.getUuid(); interpolatorId = entity.getUuid();
} }
isLeftHanded = entity.getMainArm() == Arm.LEFT; isLeftHanded = entity.getMainArm() == Arm.LEFT;
isHorsey = MineLittlePony.getInstance().getConfig().horsieMode.get();
featureSkins = SkinsProxy.instance.getAvailableSkins(entity); featureSkins = SkinsProxy.instance.getAvailableSkins(entity);
} }

View file

@ -1,10 +1,12 @@
package com.minelittlepony.client; package com.minelittlepony.client;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.*; import net.minecraft.text.*;
import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.client.render.MobRenderers;
import com.minelittlepony.client.render.PonyRenderDispatcher;
import com.minelittlepony.client.settings.ClientPonyConfig; import com.minelittlepony.client.settings.ClientPonyConfig;
import com.minelittlepony.common.client.gui.GameGui; import com.minelittlepony.common.client.gui.GameGui;
import com.minelittlepony.common.client.gui.ScrollContainer; import com.minelittlepony.common.client.gui.ScrollContainer;
@ -113,7 +115,12 @@ public class GuiPonySettings extends GameGui {
boolean enabled = i != config.fillycam || allowCameraChange; boolean enabled = i != config.fillycam || allowCameraChange;
Button button = content Button button = content
.addButton(new Toggle(LEFT, row += 20, ((Setting<Boolean>)i).get())) .addButton(new Toggle(LEFT, row += 20, ((Setting<Boolean>)i).get()))
.onChange((Setting<Boolean>)i) .onChange(i == config.horsieMode ? (v -> {
v = ((Setting<Boolean>)i).set(v);
PonyRenderDispatcher.getInstance().initialise(MinecraftClient.getInstance().getEntityRenderDispatcher(), true);
return v;
}) : (Setting<Boolean>)i)
.setEnabled(enabled); .setEnabled(enabled);
button.getStyle().setText(OPTIONS_PREFIX + i.name().toLowerCase()); button.getStyle().setText(OPTIONS_PREFIX + i.name().toLowerCase());
if (!enabled) { if (!enabled) {

View file

@ -94,7 +94,7 @@ public class MineLittlePony implements ClientModInitializer {
} }
private void onClientReady(MinecraftClient client) { private void onClientReady(MinecraftClient client) {
renderManager.initialise(client.getEntityRenderDispatcher()); renderManager.initialise(client.getEntityRenderDispatcher(), false);
} }
private void onTick(MinecraftClient client) { private void onTick(MinecraftClient client) {

View file

@ -6,6 +6,7 @@ import com.minelittlepony.api.pony.meta.Sizes;
import com.minelittlepony.client.transform.PonyTransformation; import com.minelittlepony.client.transform.PonyTransformation;
import com.minelittlepony.client.util.render.RenderList; import com.minelittlepony.client.util.render.RenderList;
import com.minelittlepony.util.MathUtil; import com.minelittlepony.util.MathUtil;
import com.minelittlepony.util.MathUtil.Angles;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -37,6 +38,9 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
public static final Pivot BACK_LEGS_SLEEPING = new Pivot(0, 2, -6); public static final Pivot BACK_LEGS_SLEEPING = new Pivot(0, 2, -6);
protected final ModelPart neck; protected final ModelPart neck;
private final ModelPart mane;
private final ModelPart nose;
private final ModelPart tailStub;
public final RenderList helmetRenderList; public final RenderList helmetRenderList;
protected final RenderList neckRenderList; protected final RenderList neckRenderList;
@ -55,6 +59,9 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
super(tree); super(tree);
neck = tree.getChild("neck"); neck = tree.getChild("neck");
mane = neck.getChild("mane");
nose = head.getChild("nose");
tailStub = body.getChild("tail_stub");
mainRenderList = RenderList.of() mainRenderList = RenderList.of()
.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)))
@ -105,7 +112,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(entity, this, ModelAttributes.Mode.OTHER); PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(entity, this, ModelAttributes.Mode.OTHER);
super.setAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch); super.setAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch);
head.setPivot(head.getDefaultTransform().pivotX, head.getDefaultTransform().pivotY, head.getDefaultTransform().pivotZ); resetPivot(head, neck, leftArm, rightArm, leftLeg, rightLeg);
setModelAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch); setModelAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch);
@ -148,9 +155,6 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
} else { } else {
adjustBody(0, ORIGIN); adjustBody(0, ORIGIN);
rightLeg.pivotY = FRONT_LEGS_Y;
leftLeg.pivotY = FRONT_LEGS_Y;
if (!attributes.isSleeping) { if (!attributes.isSleeping) {
animateBreathing(animationProgress); animateBreathing(animationProgress);
} }
@ -165,6 +169,12 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
ponySleep(); ponySleep();
} }
if (attributes.isHorsey) {
head.pivotY -= 3;
head.pivotZ -= 2;
head.pitch = 0.5F;
}
parts.forEach(part -> part.setPartAngles(attributes, limbAngle, limbSpeed, wobbleAmount, animationProgress)); parts.forEach(part -> part.setPartAngles(attributes, limbAngle, limbSpeed, wobbleAmount, animationProgress));
} }
@ -183,9 +193,6 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
rightArm.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT; rightArm.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT;
leftArm.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT; leftArm.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT;
leftLeg.pivotY = FRONT_LEGS_Y;
rightLeg.pivotY = FRONT_LEGS_Y;
} }
protected void ponySleep() { protected void ponySleep() {
@ -275,6 +282,9 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
leftArm.pivotZ = 2 - sin; leftArm.pivotZ = 2 - sin;
float legRPX = attributes.getMainInterpolator().interpolate("legOffset", cos - getLegOutset() - 0.001F, 2); float legRPX = attributes.getMainInterpolator().interpolate("legOffset", cos - getLegOutset() - 0.001F, 2);
if (attributes.isHorsey) {
legRPX += 2;
}
rightArm.pivotX = -legRPX; rightArm.pivotX = -legRPX;
rightLeg.pivotX = -legRPX; rightLeg.pivotX = -legRPX;
@ -285,8 +295,12 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
rightArm.yaw += body.yaw; rightArm.yaw += body.yaw;
leftArm.yaw += body.yaw; leftArm.yaw += body.yaw;
rightArm.pivotY = leftArm.pivotY = 8; if (attributes.isHorsey) {
rightLeg.pivotZ = leftLeg.pivotZ = 11; rightArm.pivotZ = leftArm.pivotZ = -1;
rightArm.pivotY = leftArm.pivotY = 6;
rightLeg.pivotZ = leftLeg.pivotZ = 19;
rightLeg.pivotY = leftLeg.pivotY = 6;
}
} }
/** /**
@ -517,7 +531,14 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
protected void adjustBody(float pitch, Pivot pivot) { protected void adjustBody(float pitch, Pivot pivot) {
adjustBodyComponents(pitch, pivot); adjustBodyComponents(pitch, pivot);
if (!attributes.isHorsey) {
neck.setPivot(NECK_X + pitch, pivot.y(), pivot.z()); neck.setPivot(NECK_X + pitch, pivot.y(), pivot.z());
rightLeg.pivotY = FRONT_LEGS_Y;
leftLeg.pivotY = FRONT_LEGS_Y;
} else {
neck.setPivot(NECK_X + pitch, pivot.y() - 1, pivot.z() - 2);
neck.pitch = Angles._30_DEG;
}
} }
protected void adjustBodyComponents(float pitch, Pivot pivot) { protected void adjustBodyComponents(float pitch, Pivot pivot) {
@ -541,16 +562,33 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
public void setVisible(boolean visible) { public void setVisible(boolean visible) {
super.setVisible(visible); super.setVisible(visible);
neck.visible = visible; neck.visible = visible;
hat.visible &= !attributes.isHorsey;
mane.visible = attributes.isHorsey;
nose.visible = attributes.isHorsey;
tailStub.visible = !attributes.isHorsey;
parts.forEach(part -> part.setVisible(visible, attributes)); parts.forEach(part -> part.setVisible(visible, attributes));
} }
@Override @Override
public void transform(BodyPart part, MatrixStack stack) { public void transform(BodyPart part, MatrixStack stack) {
if (attributes.isHorsey) {
stack.translate(0, 0.1F, 0);
}
if (attributes.isSleeping || attributes.isRiptide) { if (attributes.isSleeping || attributes.isRiptide) {
stack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); stack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
stack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); stack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180));
} }
if (attributes.isHorsey) {
if (part == BodyPart.BODY) {
stack.scale(1.5F, 1, 1.5F);
}
neck.visible = head.visible;
}
PonyTransformation.forSize(getSize()).transform(this, part, stack); PonyTransformation.forSize(getSize()).transform(this, part, stack);
} }
} }

View file

@ -106,6 +106,16 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
} }
static void resetPivot(ModelPart part) {
part.setPivot(part.getDefaultTransform().pivotX, part.getDefaultTransform().pivotY, part.getDefaultTransform().pivotZ);
}
static void resetPivot(ModelPart...parts) {
for (ModelPart part : parts) {
resetPivot(part);
}
}
public interface PosingCallback<T extends LivingEntity> { public interface PosingCallback<T extends LivingEntity> {
void poseModel(ClientPonyModel<T> model, float move, float swing, float ticks, T entity); void poseModel(ClientPonyModel<T> model, float move, float swing, float ticks, T entity);
} }

View file

@ -0,0 +1,106 @@
package com.minelittlepony.client.model;
import net.minecraft.client.model.Model;
import net.minecraft.client.model.ModelPart;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import com.google.common.base.Preconditions;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.mson.api.*;
import com.minelittlepony.mson.api.MsonModel.Factory;
import com.minelittlepony.mson.api.model.traversal.PartSkeleton;
import com.minelittlepony.mson.api.model.traversal.SkeletonisedModel;
import com.minelittlepony.mson.api.parser.FileContent;
import com.minelittlepony.mson.api.parser.locals.LocalBlock;
import com.minelittlepony.mson.impl.model.RootContext;
import java.util.*;
import java.util.concurrent.CompletableFuture;
final class ModelKeyImpl<M extends Model> implements ModelKey<M>, LocalBlock {
private final Map<String, Incomplete<Float>> horseModeValues = Util.make(new HashMap<>(), map -> {
map.put("head_elongation", Incomplete.completed(-1F));
map.put("neck_dilate_z", Incomplete.completed(1.5F));
map.put("neck_dilate_y", Incomplete.completed(3F));
map.put("global_ear_shortening", Incomplete.completed(-0.5F));
});
private final ModelKey<M> key;
private final MsonModel.Factory<M> constr;
ModelKeyImpl(Identifier id, MsonModel.Factory<M> constr) {
this.key = Mson.getInstance().registerModel(id, constr);
this.constr = constr;
}
@Override
public Identifier getId() {
return key.getId();
}
@SuppressWarnings("unchecked")
@Override
public <V extends M> V createModel() {
return (V)createModel(constr);
}
@Override
public <V extends M> V createModel(Factory<V> factory) {
Preconditions.checkNotNull(factory, "Factory should not be null");
return getModelData().map(content -> {
ModelContext ctx = getModelContext(content);
ModelPart root = ctx.toTree();
V t = factory.create(root);
if (t instanceof SkeletonisedModel) {
((SkeletonisedModel)t).setSkeleton(content.getSkeleton()
.map(s -> PartSkeleton.of(root, s))
.orElseGet(() -> PartSkeleton.of(root)));
}
if (t instanceof MsonModel) {
if (ctx instanceof RootContext) {
((RootContext)ctx).setModel(t);
}
((MsonModel)t).init(ctx);
}
return t;
})
.orElseThrow(() -> new IllegalStateException("Model file for " + getId() + " was not loaded!"));
}
@Override
public Optional<ModelPart> createTree() {
return getModelData().map(this::getModelContext).map(ModelContext::toTree);
}
private ModelContext getModelContext(FileContent<?> content) {
if (MineLittlePony.getInstance().getConfig().horsieMode.get()) {
return content.createContext(null, null, content.getLocals().extendWith(getId(), Optional.of(this), Optional.empty()).bake());
}
return content.createContext(null, null, content.getLocals().bake());
}
@Override
public Optional<FileContent<?>> getModelData() {
return key.getModelData();
}
@Override
public Set<String> appendKeys(Set<String> output) {
output.addAll(horseModeValues.keySet());
return output;
}
@Override
public Optional<CompletableFuture<Incomplete<Float>>> get(String name) {
if (horseModeValues.containsKey(name)) {
return Optional.of(CompletableFuture.completedFuture(horseModeValues.get(name)));
}
return Optional.empty();
}
}

View file

@ -68,7 +68,7 @@ public final class ModelType {
public static final PlayerModelKey<LivingEntity, AlicornModel<?>> ALICORN = registerPlayer("alicorn", Race.ALICORN, AlicornModel::new); public static final PlayerModelKey<LivingEntity, AlicornModel<?>> ALICORN = registerPlayer("alicorn", Race.ALICORN, AlicornModel::new);
public static final PlayerModelKey<LivingEntity, UnicornModel<?>> UNICORN = registerPlayer("unicorn", Race.UNICORN, UnicornModel::new); public static final PlayerModelKey<LivingEntity, UnicornModel<?>> UNICORN = registerPlayer("unicorn", Race.UNICORN, UnicornModel::new);
public static final PlayerModelKey<LivingEntity, UnicornModel<?>> KIRIN = registerPlayer("kirin", Race.KIRIN, UnicornModel::new); public static final PlayerModelKey<LivingEntity, KirinModel<?>> KIRIN = registerPlayer("kirin", Race.KIRIN, KirinModel::new);
public static final PlayerModelKey<LivingEntity, PegasusModel<?>> PEGASUS = registerPlayer("pegasus", Race.PEGASUS, PegasusModel::new); public static final PlayerModelKey<LivingEntity, PegasusModel<?>> PEGASUS = registerPlayer("pegasus", Race.PEGASUS, PegasusModel::new);
public static final PlayerModelKey<LivingEntity, PegasusModel<?>> GRYPHON = registerPlayer("gryphon", Race.GRYPHON, PegasusModel::new); public static final PlayerModelKey<LivingEntity, PegasusModel<?>> GRYPHON = registerPlayer("gryphon", Race.GRYPHON, PegasusModel::new);
public static final PlayerModelKey<LivingEntity, PegasusModel<?>> HIPPOGRIFF = registerPlayer("hippogriff", Race.HIPPOGRIFF, PegasusModel::new); public static final PlayerModelKey<LivingEntity, PegasusModel<?>> HIPPOGRIFF = registerPlayer("hippogriff", Race.HIPPOGRIFF, PegasusModel::new);
@ -113,7 +113,7 @@ public final class ModelType {
} }
static <T extends Model> ModelKey<T> register(String name, MsonModel.Factory<T> constructor) { static <T extends Model> ModelKey<T> register(String name, MsonModel.Factory<T> constructor) {
return Mson.getInstance().registerModel(new Identifier("minelittlepony", name), constructor); return new ModelKeyImpl<T>(new Identifier("minelittlepony", name), constructor);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View file

@ -12,9 +12,7 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.api.model.IModel; import com.minelittlepony.api.model.IModel;
import com.minelittlepony.client.model.armour.PonyArmourModel; import com.minelittlepony.client.model.armour.PonyArmourModel;
import com.minelittlepony.mson.api.ModelKey; import com.minelittlepony.mson.api.*;
import com.minelittlepony.mson.api.Mson;
import com.minelittlepony.mson.api.MsonModel;
import java.util.function.*; import java.util.function.*;
@ -26,8 +24,8 @@ public record PlayerModelKey<T extends LivingEntity, M extends Model & MsonModel
) { ) {
PlayerModelKey(String name, BiFunction<ModelPart, Boolean, M> modelFactory, RendererFactory rendererFactory, MsonModel.Factory<PonyArmourModel<T>> armorFactory) { PlayerModelKey(String name, BiFunction<ModelPart, Boolean, M> modelFactory, RendererFactory rendererFactory, MsonModel.Factory<PonyArmourModel<T>> armorFactory) {
this( this(
Mson.getInstance().registerModel(new Identifier("minelittlepony", "races/steve/" + name), tree -> modelFactory.apply(tree, false)), new ModelKeyImpl<>(new Identifier("minelittlepony", "races/steve/" + name), tree -> modelFactory.apply(tree, false)),
Mson.getInstance().registerModel(new Identifier("minelittlepony", "races/alex/" + name), tree -> modelFactory.apply(tree, true)), new ModelKeyImpl<>(new Identifier("minelittlepony", "races/alex/" + name), tree -> modelFactory.apply(tree, true)),
rendererFactory, rendererFactory,
armorFactory armorFactory
); );

View file

@ -0,0 +1,23 @@
package com.minelittlepony.client.model.entity.race;
import net.minecraft.client.model.ModelPart;
import net.minecraft.entity.LivingEntity;
import com.minelittlepony.api.model.Pivot;
public class KirinModel<T extends LivingEntity> extends UnicornModel<T> {
private final ModelPart beard;
public KirinModel(ModelPart tree, boolean smallArms) {
super(tree, smallArms);
beard = neck.getChild("beard");
}
@Override
protected void adjustBody(float pitch, Pivot pivot) {
super.adjustBody(pitch, pivot);
beard.resetTransform();
beard.pitch -= neck.pitch;
}
}

View file

@ -19,6 +19,7 @@ public class LionTail implements IPart {
@Override @Override
public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) {
tail.resetTransform();
bodySwing *= 5; bodySwing *= 5;
@ -82,6 +83,11 @@ public class LionTail implements IPart {
tail4.roll += bend; tail4.roll += bend;
tail5.roll += bend; tail5.roll += bend;
tail6.roll += bend; tail6.roll += bend;
if (attributes.isHorsey) {
tail.pivotZ = 14;
tail.pivotY = 7;
}
} }
@Override @Override

View file

@ -33,5 +33,15 @@ public class PonyEars implements IPart, MsonModel {
public void setVisible(boolean visible, ModelAttributes attributes) { public void setVisible(boolean visible, ModelAttributes attributes) {
right.visible = visible && !attributes.metadata.getRace().isHuman(); right.visible = visible && !attributes.metadata.getRace().isHuman();
left.visible = visible && !attributes.metadata.getRace().isHuman(); left.visible = visible && !attributes.metadata.getRace().isHuman();
if (attributes.isHorsey) {
left.pivotX = -1;
right.pivotX = 1;
left.pivotY = right.pivotY = 1;
left.pivotZ = right.pivotZ = 1.5F;
} else {
left.resetTransform();
right.resetTransform();
}
} }
} }

View file

@ -39,7 +39,9 @@ public class PonySnout implements IPart, MsonModel {
@Override @Override
public void setVisible(boolean visible, ModelAttributes attributes) { public void setVisible(boolean visible, ModelAttributes attributes) {
visible &= !attributes.metadata.getRace().isHuman() && MineLittlePony.getInstance().getConfig().snuzzles.get(); visible &= !attributes.isHorsey
&& !attributes.metadata.getRace().isHuman()
&& MineLittlePony.getInstance().getConfig().snuzzles.get();
Gender gender = attributes.metadata.getGender(); Gender gender = attributes.metadata.getGender();
mare.visible = (visible && gender.isMare()); mare.visible = (visible && gender.isMare());

View file

@ -5,8 +5,7 @@ import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import com.minelittlepony.api.model.IPart; import com.minelittlepony.api.model.*;
import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.pony.meta.TailShape; import com.minelittlepony.api.pony.meta.TailShape;
import com.minelittlepony.client.model.AbstractPonyModel; import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.mson.api.*; import com.minelittlepony.mson.api.*;
@ -21,6 +20,8 @@ public class PonyTail implements IPart, MsonModel {
private static final float TAIL_RIDING_Z = 13; private static final float TAIL_RIDING_Z = 13;
private static final float TAIL_SNEAKING_Z = 15; private static final float TAIL_SNEAKING_Z = 15;
private static final Pivot HORSEY_TAIL_PIVOT = new Pivot(0, 6, -6);
private ModelPart tail; private ModelPart tail;
private AbstractPonyModel<?> model; private AbstractPonyModel<?> model;
@ -90,7 +91,7 @@ public class PonyTail implements IPart, MsonModel {
tail.rotate(stack); tail.rotate(stack);
for (int i = 0; i < segments.size(); i++) { for (int i = 0; i < segments.size(); i++) {
segments.get(i).render(this, stack, vertices, i, overlayUv, lightUv, red, green, blue, alpha); segments.get(i).render(this, stack, vertices, i, overlayUv, lightUv, red, green, blue, alpha, attributes);
} }
stack.pop(); stack.pop();
@ -103,14 +104,20 @@ public class PonyTail implements IPart, MsonModel {
this.tree = tree; this.tree = tree;
} }
public void render(PonyTail tail, MatrixStack stack, VertexConsumer renderContext, int index, int overlayUv, int lightUv, float red, float green, float blue, float alpha) { public void render(PonyTail tail, MatrixStack stack, VertexConsumer renderContext, int index, int overlayUv, int lightUv, float red, float green, float blue, float alpha, ModelAttributes attributes) {
if (index >= tail.tailStop) { if (index >= tail.tailStop) {
return; return;
} }
if (tail.shape == TailShape.STRAIGHT) { if (attributes.isHorsey) {
tree.pitch = 0.5F;
HORSEY_TAIL_PIVOT.set(tree);
} else {
tree.resetTransform();
}
if (attributes.isHorsey || tail.shape == TailShape.STRAIGHT) {
tree.yaw = 0; tree.yaw = 0;
tree.pivotZ = 0;
tree.render(stack, renderContext, overlayUv, lightUv, red, green, blue, alpha); tree.render(stack, renderContext, overlayUv, lightUv, red, green, blue, alpha);
return; return;
} }

View file

@ -83,7 +83,7 @@ public final class MobRenderers {
public boolean set(boolean value) { public boolean set(boolean value) {
value = option().set(value); value = option().set(value);
apply(PonyRenderDispatcher.getInstance()); apply(PonyRenderDispatcher.getInstance(), false);
return value; return value;
} }
@ -95,9 +95,9 @@ public final class MobRenderers {
return REGISTRY.computeIfAbsent(name, n -> new MobRenderers(name, changer)); return REGISTRY.computeIfAbsent(name, n -> new MobRenderers(name, changer));
} }
void apply(PonyRenderDispatcher dispatcher) { void apply(PonyRenderDispatcher dispatcher, boolean force) {
boolean state = get(); boolean state = get();
if (state != lastState) { if (state != lastState || force) {
lastState = state; lastState = state;
changer.accept(this, dispatcher); changer.accept(this, dispatcher);
} }

View file

@ -40,13 +40,13 @@ public class PonyRenderDispatcher {
/** /**
* Registers all new player skin types. (currently only pony and slimpony). * Registers all new player skin types. (currently only pony and slimpony).
*/ */
public void initialise(EntityRenderDispatcher manager) { public void initialise(EntityRenderDispatcher manager, boolean force) {
Race.REGISTRY.forEach(r -> { Race.REGISTRY.forEach(r -> {
if (!r.isHuman()) { if (!r.isHuman()) {
registerPlayerSkin(manager, r); registerPlayerSkin(manager, r);
} }
}); });
MobRenderers.REGISTRY.values().forEach(i -> i.apply(this)); MobRenderers.REGISTRY.values().forEach(i -> i.apply(this, force));
} }
private void registerPlayerSkin(EntityRenderDispatcher manager, Race race) { private void registerPlayerSkin(EntityRenderDispatcher manager, Race race) {

View file

@ -6,7 +6,8 @@ public interface MathUtil {
interface Angles { interface Angles {
float float
_270_DEG = 270 * MathHelper.RADIANS_PER_DEGREE, _270_DEG = 270 * MathHelper.RADIANS_PER_DEGREE,
_90_DEG = 90 * MathHelper.RADIANS_PER_DEGREE _90_DEG = 90 * MathHelper.RADIANS_PER_DEGREE,
_30_DEG = 30 * MathHelper.RADIANS_PER_DEGREE
; ;
} }

View file

@ -21,6 +21,7 @@
"minelp.options.ponyskulls": "Pony Skulls", "minelp.options.ponyskulls": "Pony Skulls",
"minelp.options.frustrum": "Frustum checks", "minelp.options.frustrum": "Frustum checks",
"minelp.options.flappyelytras": "Flap Wings whilst Gliding", "minelp.options.flappyelytras": "Flap Wings whilst Gliding",
"minelp.options.horsiemode": "Horsey Horse Mode",
"minelp.options.nofun": "Boring Mode", "minelp.options.nofun": "Boring Mode",
"minelp.options.button": "Display On Title Screen", "minelp.options.button": "Display On Title Screen",
"minelp.options.button.on": "Always Display\n\nBoth the pony button and HD Skins button are visible (if installed)", "minelp.options.button.on": "Always Display\n\nBoth the pony button and HD Skins button are visible (if installed)",

View file

@ -5,6 +5,7 @@
"y": 0, "y": 0,
"z": 0, "z": 0,
"ear_pronouncement": 0, "ear_pronouncement": 0,
"ear_shortening": 0,
"ear_spread": 0, "ear_spread": 0,
"ear_spread_neg": [0, "-", "#ear_spread"] "ear_spread_neg": [0, "-", "#ear_spread"]
}, },
@ -14,7 +15,7 @@
"pivot": ["#x", "#y", "#z"], "pivot": ["#x", "#y", "#z"],
"rotate": [0, 0, "#ear_spread"], "rotate": [0, 0, "#ear_spread"],
"cubes": [ "cubes": [
{ "from": [-4, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", 0] }, { "from": [-4, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", "#ear_shortening"] },
{ "from": [-3.5, -8.49, 0], "size": [1, 1, 1], "texture": {"u": 0, "v": 3}, "dilate": [0, "#ear_pronouncement", 0] }, { "from": [-3.5, -8.49, 0], "size": [1, 1, 1], "texture": {"u": 0, "v": 3}, "dilate": [0, "#ear_pronouncement", 0] },
{ "from": [-2.998, -8.49, -1], "size": [1, 1, 1], "texture": {"u": 0, "v": 5}, "dilate": [0, "#ear_pronouncement", 0] } { "from": [-2.998, -8.49, -1], "size": [1, 1, 1], "texture": {"u": 0, "v": 5}, "dilate": [0, "#ear_pronouncement", 0] }
] ]
@ -25,7 +26,7 @@
"mirror": [true, false, false], "mirror": [true, false, false],
"rotate": [0, 0, "#ear_spread_neg"], "rotate": [0, 0, "#ear_spread_neg"],
"cubes": [ "cubes": [
{ "from": [2, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", 0] }, { "from": [2, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", "#ear_shortening"] },
{ "from": [2.5, -8.49, 0], "size": [1, 1, 1], "texture": {"u": 0, "v": 3}, "dilate": [0, "#ear_pronouncement", 0] }, { "from": [2.5, -8.49, 0], "size": [1, 1, 1], "texture": {"u": 0, "v": 3}, "dilate": [0, "#ear_pronouncement", 0] },
{ "from": [1.998, -8.49, -1], "size": [1, 1, 1], "texture": {"u": 0, "v": 5}, "dilate": [0, "#ear_pronouncement", 0] } { "from": [1.998, -8.49, -1], "size": [1, 1, 1], "texture": {"u": 0, "v": 5}, "dilate": [0, "#ear_pronouncement", 0] }
] ]

View file

@ -5,6 +5,7 @@
"y": 0, "y": 0,
"z": 0, "z": 0,
"ear_pronouncement": 0, "ear_pronouncement": 0,
"ear_shortening": 0,
"ear_spread": 0, "ear_spread": 0,
"ear_spread_neg": [0, "-", "#ear_spread"] "ear_spread_neg": [0, "-", "#ear_spread"]
}, },
@ -14,7 +15,7 @@
"pivot": ["#x", "#y", "#z"], "pivot": ["#x", "#y", "#z"],
"rotate": [0, 0, "#ear_spread"], "rotate": [0, 0, "#ear_spread"],
"cubes": [ "cubes": [
{ "from": [-4, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", 0] } { "from": [-4, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", "#ear_shortening"] }
] ]
}, },
"left": { "left": {
@ -23,7 +24,7 @@
"mirror": [true, false, false], "mirror": [true, false, false],
"rotate": [0, 0, "#ear_spread_neg"], "rotate": [0, 0, "#ear_spread_neg"],
"cubes": [ "cubes": [
{ "from": [2, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", 0] } { "from": [2, -8, -1], "size": [2, 2, 2], "dilate": [0, "#ear_pronouncement", "#ear_shortening"] }
] ]
} }
} }

View file

@ -7,12 +7,26 @@
}, },
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "data": "minelittlepony:components/snout", "implementation": "com.minelittlepony.client.model.part.PonySnout" }, "snout": { "data": "minelittlepony:components/snout", "implementation": "com.minelittlepony.client.model.part.PonySnout" },
"ears": { "data": "minelittlepony:components/ears", "implementation": "com.minelittlepony.client.model.part.PonyEars" }, "ears": {
"data": "minelittlepony:components/ears",
"implementation": "com.minelittlepony.client.model.part.PonyEars",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
},
"horn": { "data": "minelittlepony:components/horn", "implementation": "com.minelittlepony.client.model.part.UnicornHorn" }, "horn": { "data": "minelittlepony:components/horn", "implementation": "com.minelittlepony.client.model.part.UnicornHorn" },
"left_horn": { "left_horn": {
"texture": {"u": 0, "v": 52}, "texture": {"u": 0, "v": 52},

View file

@ -3,10 +3,18 @@
"parent": "minelittlepony:zombie", "parent": "minelittlepony:zombie",
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"left_flap": { "left_flap": {
"name": "left_flap", "name": "left_flap",
"texture": {"u": 64, "v": 0}, "texture": {"u": 64, "v": 0},

View file

@ -2,17 +2,28 @@
"parent": "minelittlepony:steve_pony", "parent": "minelittlepony:steve_pony",
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "snout": {
"data": "minelittlepony:components/snout", "data": "minelittlepony:components/snout",
"implementation": "com.minelittlepony.client.model.part.PonySnout" "implementation": "com.minelittlepony.client.model.part.PonySnout"
}, },
"ears": { "ears": {
"data": "minelittlepony:components/bat_ears", "data": "minelittlepony:components/bat_ears",
"implementation": "com.minelittlepony.client.model.part.PonyEars" "implementation": "com.minelittlepony.client.model.part.PonyEars",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
} }
} }
}, },

View file

@ -16,10 +16,17 @@
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ], "pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "snout": {
"implementation": "com.minelittlepony.client.model.part.PonySnout", "implementation": "com.minelittlepony.client.model.part.PonySnout",
"data": "minelittlepony:components/beak" "data": "minelittlepony:components/beak"

View file

@ -2,10 +2,18 @@
"parent": "minelittlepony:races/steve/unicorn", "parent": "minelittlepony:races/steve/unicorn",
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "snout": {
"data": "minelittlepony:components/snout", "data": "minelittlepony:components/snout",
"implementation": "com.minelittlepony.client.model.part.PonySnout" "implementation": "com.minelittlepony.client.model.part.PonySnout"
@ -30,7 +38,7 @@
}, },
"neck": { "neck": {
"type": "mson:planar", "type": "mson:planar",
"dilate": [ -0.3, "#neck_dilate_y", -0.3 ], "dilate": [ -0.3, "#neck_dilate_y", "#neck_dilate_z" ],
"texture": { "u": 0, "v": 16 }, "texture": { "u": 0, "v": 16 },
"rotate": [9, 0, 0], "rotate": [9, 0, 0],
"north": [-2, 1.199998, -2.8, 4, 4], "north": [-2, 1.199998, -2.8, 4, 4],
@ -38,10 +46,21 @@
"east": [ 2, 1.199998, -2.8, 4, 4], "east": [ 2, 1.199998, -2.8, 4, 4],
"west": [-2, 1.199998, -2.8, 4, 4], "west": [-2, 1.199998, -2.8, 4, 4],
"children": { "children": {
"mane": {
"type": "mson:planar",
"pivot": [0, -2.9, 1.5],
"dilate": [ -0.8, 2, 0 ],
"texture": { "u": 32, "v": 0 },
"rotate": [0, 0, 0],
"north": [-2, 1.199998, -2.8, 4, 4],
"south": [-2, 1.199998, 1.2, 4, 4],
"east": [ 2, 1.199998, -2.8, 4, 4],
"west": [-2, 1.199998, -2.8, 4, 4]
},
"beard": { "beard": {
"texture": { "u": 16, "v": 16 }, "texture": { "u": 16, "v": 16 },
"pivot": [-4, 2, -2], "pivot": [-4, 2, -2],
"rotate": [-29, 0, 0], "rotate": [-20, 0, 0],
"cubes": [ "cubes": [
{ "from": [0, 0, 0], "size": [ 8, 8, 4], "dilate": [0.5, -0.5, 0] } { "from": [0, 0, 0], "size": [ 8, 8, 4], "dilate": [0.5, -0.5, 0] }
] ]

View file

@ -2,10 +2,18 @@
"parent": "minelittlepony:races/steve/alicorn", "parent": "minelittlepony:races/steve/alicorn",
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "snout": {
"data": "minelittlepony:components/snout", "data": "minelittlepony:components/snout",
"implementation": "com.minelittlepony.client.model.part.PonySnout" "implementation": "com.minelittlepony.client.model.part.PonySnout"

View file

@ -32,7 +32,10 @@
"from": [-3, 5, 1], "from": [-3, 5, 1],
"size": [6, 7, 9] "size": [6, 7, 9]
} }
] ],
"children": {
"tail_stub": {}
}
}, },
"tail": { "tail": {
"implementation": "com.minelittlepony.client.model.part.SeaponyTail", "implementation": "com.minelittlepony.client.model.part.SeaponyTail",

View file

@ -2,12 +2,26 @@
"parent": "minelittlepony:steve_pony", "parent": "minelittlepony:steve_pony",
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "data": "minelittlepony:components/snout", "implementation": "com.minelittlepony.client.model.part.PonySnout" }, "snout": { "data": "minelittlepony:components/snout", "implementation": "com.minelittlepony.client.model.part.PonySnout" },
"ears": { "data": "minelittlepony:components/ears", "implementation": "com.minelittlepony.client.model.part.PonyEars" }, "ears": {
"data": "minelittlepony:components/ears",
"implementation": "com.minelittlepony.client.model.part.PonyEars",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
},
"horn": { "data": "minelittlepony:components/horn", "implementation": "com.minelittlepony.client.model.part.UnicornHorn" } "horn": { "data": "minelittlepony:components/horn", "implementation": "com.minelittlepony.client.model.part.UnicornHorn" }
} }
}, },

View file

@ -1,18 +1,29 @@
{ {
"parent": "minelittlepony:steve_pony", "parent": "minelittlepony:steve_pony",
"locals": { "locals": {
"head_pivot_y": -1.2,
"neck_dilate_y": 1.6
}, },
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ], "pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "data": "minelittlepony:components/snout", "implementation": "com.minelittlepony.client.model.part.PonySnout" }, "snout": { "data": "minelittlepony:components/snout", "implementation": "com.minelittlepony.client.model.part.PonySnout" },
"ears": { "data": "minelittlepony:components/ears", "implementation": "com.minelittlepony.client.model.part.PonyEars" }, "ears": {
"data": "minelittlepony:components/ears",
"implementation": "com.minelittlepony.client.model.part.PonyEars",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
},
"bristles": { "bristles": {
"texture": {"u": 56, "v": 32}, "texture": {"u": 56, "v": 32},
"rotate": [17, 0, 0], "rotate": [17, 0, 0],

View file

@ -9,32 +9,46 @@
"arm_depth": 4, "arm_depth": 4,
"arm_x": 0, "arm_x": 0,
"arm_x_neg": ["#arm_x", "-", "#arm_width"], "arm_x_neg": ["#arm_x", "-", "#arm_width"],
"arm_z": [2, "-", "#arm_depth"], "arm_z": ["#arm_depth", "/", -2],
"arm_rotation_x": 0, "arm_rotation_x": 0,
"arm_rotation_x_neg": [0, "-", "#arm_rotation_x"], "arm_rotation_x_neg": [0, "-", "#arm_rotation_x"],
"arm_rotation_y": 8, "arm_rotation_y": 8,
"head_pivot_y": 0, "head_pivot_y": 0,
"neck_dilate_y": -0.1 "neck_dilate_y": -0.1,
"neck_dilate_z": -0.3,
"head_elongation": 0,
"global_ear_shortening": 0
}, },
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ], "pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
"children": { "children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": { "snout": {
"implementation": "com.minelittlepony.client.model.part.PonySnout", "implementation": "com.minelittlepony.client.model.part.PonySnout",
"data": "minelittlepony:components/snout" "data": "minelittlepony:components/snout"
}, },
"ears": { "ears": {
"implementation": "com.minelittlepony.client.model.part.PonyEars", "implementation": "com.minelittlepony.client.model.part.PonyEars",
"data": "minelittlepony:components/ears" "data": "minelittlepony:components/ears",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
} }
} }
}, },
"hat": { "hat": {
"texture": { "u": 32, "v": 0 }, "texture": { "u": 32, "v": 0 },
"dilate": ["#head_elongation", "#head_elongation", 0],
"pivot": [ 0, "#head_pivot_y", 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 }
@ -161,13 +175,26 @@
}, },
"neck": { "neck": {
"type": "mson:planar", "type": "mson:planar",
"dilate": [ -0.3, "#neck_dilate_y", -0.3 ], "dilate": [ -0.3, "#neck_dilate_y", "#neck_dilate_z" ],
"texture": { "u": 0, "v": 16 }, "texture": { "u": 0, "v": 16 },
"rotate": [9, 0, 0], "rotate": [9, 0, 0],
"north": [-2, 1.199998, -2.8, 4, 4], "north": [-2, 1.199998, -2.8, 4, 4],
"south": [-2, 1.199998, 1.2, 4, 4], "south": [-2, 1.199998, 1.2, 4, 4],
"east": [ 2, 1.199998, -2.8, 4, 4], "east": [ 2, 1.199998, -2.8, 4, 4],
"west": [-2, 1.199998, -2.8, 4, 4],
"children": {
"mane": {
"type": "mson:planar",
"pivot": [0, -2.9, 1.5],
"dilate": [ -0.8, 2, 0 ],
"texture": { "u": 32, "v": 0 },
"rotate": [0, 0, 0],
"north": [-2, 1.199998, -2.8, 4, 4],
"south": [-2, 1.199998, 1.2, 4, 4],
"east": [ 2, 1.199998, -2.8, 4, 4],
"west": [-2, 1.199998, -2.8, 4, 4] "west": [-2, 1.199998, -2.8, 4, 4]
}
}
}, },
"jacket": { "jacket": {
"texture": { "u": 24, "v": 0 }, "texture": { "u": 24, "v": 0 },

View file

@ -2,6 +2,8 @@
"parent": "minelittlepony:races/steve/alicorn", "parent": "minelittlepony:races/steve/alicorn",
"data": { "data": {
"head": { "head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [ "cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] } { "from": [-4, -6, -6], "size": [ 8, 8, 8] }
], ],
@ -16,13 +18,19 @@
"type": "mson:slot", "type": "mson:slot",
"name": "ears", "name": "ears",
"implementation": "com.minelittlepony.client.model.part.PonyEars", "implementation": "com.minelittlepony.client.model.part.PonyEars",
"data": "minelittlepony:components/ears" "data": "minelittlepony:components/ears",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
}, },
"bat_ears": { "bat_ears": {
"type": "mson:slot", "type": "mson:slot",
"name": "bat_ears", "name": "bat_ears",
"implementation": "com.minelittlepony.client.model.part.PonyEars", "implementation": "com.minelittlepony.client.model.part.PonyEars",
"data": "minelittlepony:components/bat_ears" "data": "minelittlepony:components/bat_ears",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
}, },
"horn": { "horn": {
"type": "mson:slot", "type": "mson:slot",