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)
.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");
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)
.addComment("Overrides pony sizes")

View file

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

View file

@ -1,10 +1,12 @@
package com.minelittlepony.client;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.*;
import com.minelittlepony.client.render.MobRenderers;
import com.minelittlepony.client.render.PonyRenderDispatcher;
import com.minelittlepony.client.settings.ClientPonyConfig;
import com.minelittlepony.common.client.gui.GameGui;
import com.minelittlepony.common.client.gui.ScrollContainer;
@ -113,7 +115,12 @@ public class GuiPonySettings extends GameGui {
boolean enabled = i != config.fillycam || allowCameraChange;
Button button = content
.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);
button.getStyle().setText(OPTIONS_PREFIX + i.name().toLowerCase());
if (!enabled) {

View file

@ -94,7 +94,7 @@ public class MineLittlePony implements ClientModInitializer {
}
private void onClientReady(MinecraftClient client) {
renderManager.initialise(client.getEntityRenderDispatcher());
renderManager.initialise(client.getEntityRenderDispatcher(), false);
}
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.util.render.RenderList;
import com.minelittlepony.util.MathUtil;
import com.minelittlepony.util.MathUtil.Angles;
import java.util.ArrayList;
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);
protected final ModelPart neck;
private final ModelPart mane;
private final ModelPart nose;
private final ModelPart tailStub;
public final RenderList helmetRenderList;
protected final RenderList neckRenderList;
@ -55,6 +59,9 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
super(tree);
neck = tree.getChild("neck");
mane = neck.getChild("mane");
nose = head.getChild("nose");
tailStub = body.getChild("tail_stub");
mainRenderList = RenderList.of()
.add(withStage(BodyPart.BODY, bodyRenderList = RenderList.of(body).add(body::rotate)))
.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);
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);
@ -148,9 +155,6 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
} else {
adjustBody(0, ORIGIN);
rightLeg.pivotY = FRONT_LEGS_Y;
leftLeg.pivotY = FRONT_LEGS_Y;
if (!attributes.isSleeping) {
animateBreathing(animationProgress);
}
@ -165,6 +169,12 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
ponySleep();
}
if (attributes.isHorsey) {
head.pivotY -= 3;
head.pivotZ -= 2;
head.pitch = 0.5F;
}
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;
leftArm.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT;
leftLeg.pivotY = FRONT_LEGS_Y;
rightLeg.pivotY = FRONT_LEGS_Y;
}
protected void ponySleep() {
@ -275,6 +282,9 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
leftArm.pivotZ = 2 - sin;
float legRPX = attributes.getMainInterpolator().interpolate("legOffset", cos - getLegOutset() - 0.001F, 2);
if (attributes.isHorsey) {
legRPX += 2;
}
rightArm.pivotX = -legRPX;
rightLeg.pivotX = -legRPX;
@ -285,8 +295,12 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
rightArm.yaw += body.yaw;
leftArm.yaw += body.yaw;
rightArm.pivotY = leftArm.pivotY = 8;
rightLeg.pivotZ = leftLeg.pivotZ = 11;
if (attributes.isHorsey) {
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) {
adjustBodyComponents(pitch, pivot);
neck.setPivot(NECK_X + pitch, pivot.y(), pivot.z());
if (!attributes.isHorsey) {
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) {
@ -541,16 +562,33 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
public void setVisible(boolean visible) {
super.setVisible(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));
}
@Override
public void transform(BodyPart part, MatrixStack stack) {
if (attributes.isHorsey) {
stack.translate(0, 0.1F, 0);
}
if (attributes.isSleeping || attributes.isRiptide) {
stack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
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);
}
}

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> {
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, 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<?>> GRYPHON = registerPlayer("gryphon", Race.GRYPHON, 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) {
return Mson.getInstance().registerModel(new Identifier("minelittlepony", name), constructor);
return new ModelKeyImpl<T>(new Identifier("minelittlepony", name), constructor);
}
@SuppressWarnings("unchecked")

View file

@ -12,9 +12,7 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.api.model.IModel;
import com.minelittlepony.client.model.armour.PonyArmourModel;
import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.mson.api.Mson;
import com.minelittlepony.mson.api.MsonModel;
import com.minelittlepony.mson.api.*;
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) {
this(
Mson.getInstance().registerModel(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/steve/" + name), tree -> modelFactory.apply(tree, false)),
new ModelKeyImpl<>(new Identifier("minelittlepony", "races/alex/" + name), tree -> modelFactory.apply(tree, true)),
rendererFactory,
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
public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) {
tail.resetTransform();
bodySwing *= 5;
@ -82,6 +83,11 @@ public class LionTail implements IPart {
tail4.roll += bend;
tail5.roll += bend;
tail6.roll += bend;
if (attributes.isHorsey) {
tail.pivotZ = 14;
tail.pivotY = 7;
}
}
@Override

View file

@ -33,5 +33,15 @@ public class PonyEars implements IPart, MsonModel {
public void setVisible(boolean visible, ModelAttributes attributes) {
right.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
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();
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.util.math.MathHelper;
import com.minelittlepony.api.model.IPart;
import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.*;
import com.minelittlepony.api.pony.meta.TailShape;
import com.minelittlepony.client.model.AbstractPonyModel;
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_SNEAKING_Z = 15;
private static final Pivot HORSEY_TAIL_PIVOT = new Pivot(0, 6, -6);
private ModelPart tail;
private AbstractPonyModel<?> model;
@ -90,7 +91,7 @@ public class PonyTail implements IPart, MsonModel {
tail.rotate(stack);
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();
@ -103,14 +104,20 @@ public class PonyTail implements IPart, MsonModel {
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) {
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.pivotZ = 0;
tree.render(stack, renderContext, overlayUv, lightUv, red, green, blue, alpha);
return;
}

View file

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

View file

@ -40,13 +40,13 @@ public class PonyRenderDispatcher {
/**
* 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 -> {
if (!r.isHuman()) {
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) {

View file

@ -6,7 +6,8 @@ public interface MathUtil {
interface Angles {
float
_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.frustrum": "Frustum checks",
"minelp.options.flappyelytras": "Flap Wings whilst Gliding",
"minelp.options.horsiemode": "Horsey Horse Mode",
"minelp.options.nofun": "Boring Mode",
"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)",

View file

@ -5,6 +5,7 @@
"y": 0,
"z": 0,
"ear_pronouncement": 0,
"ear_shortening": 0,
"ear_spread": 0,
"ear_spread_neg": [0, "-", "#ear_spread"]
},
@ -14,7 +15,7 @@
"pivot": ["#x", "#y", "#z"],
"rotate": [0, 0, "#ear_spread"],
"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": [-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],
"rotate": [0, 0, "#ear_spread_neg"],
"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": [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,
"z": 0,
"ear_pronouncement": 0,
"ear_shortening": 0,
"ear_spread": 0,
"ear_spread_neg": [0, "-", "#ear_spread"]
},
@ -14,7 +15,7 @@
"pivot": ["#x", "#y", "#z"],
"rotate": [0, 0, "#ear_spread"],
"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": {
@ -23,7 +24,7 @@
"mirror": [true, false, false],
"rotate": [0, 0, "#ear_spread_neg"],
"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": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"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" },
"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" },
"left_horn": {
"texture": {"u": 0, "v": 52},

View file

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

View file

@ -2,17 +2,28 @@
"parent": "minelittlepony:steve_pony",
"data": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"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"
},
"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": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": {
"implementation": "com.minelittlepony.client.model.part.PonySnout",
"data": "minelittlepony:components/beak"

View file

@ -2,10 +2,18 @@
"parent": "minelittlepony:races/steve/unicorn",
"data": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"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"
@ -30,7 +38,7 @@
},
"neck": {
"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 },
"rotate": [9, 0, 0],
"north": [-2, 1.199998, -2.8, 4, 4],
@ -38,10 +46,21 @@
"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]
},
"beard": {
"texture": { "u": 16, "v": 16 },
"pivot": [-4, 2, -2],
"rotate": [-29, 0, 0],
"rotate": [-20, 0, 0],
"cubes": [
{ "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",
"data": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"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"

View file

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

View file

@ -2,12 +2,26 @@
"parent": "minelittlepony:steve_pony",
"data": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"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" },
"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" }
}
},

View file

@ -1,18 +1,29 @@
{
"parent": "minelittlepony:steve_pony",
"locals": {
"head_pivot_y": -1.2,
"neck_dilate_y": 1.6
},
"data": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"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" },
"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": {
"texture": {"u": 56, "v": 32},
"rotate": [17, 0, 0],

View file

@ -9,32 +9,46 @@
"arm_depth": 4,
"arm_x": 0,
"arm_x_neg": ["#arm_x", "-", "#arm_width"],
"arm_z": [2, "-", "#arm_depth"],
"arm_z": ["#arm_depth", "/", -2],
"arm_rotation_x": 0,
"arm_rotation_x_neg": [0, "-", "#arm_rotation_x"],
"arm_rotation_y": 8,
"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": {
"head": {
"pivot": [ 0, "#head_pivot_y", 0 ],
"dilate": ["#head_elongation", "#head_elongation", 0],
"cubes": [
{ "from": [-4, -6, -6], "size": [ 8, 8, 8] }
],
"children": {
"nose": {
"dilate": [-1, 0, -1],
"cubes": [
{ "from": [-4, -6, -13], "size": [ 8, 8, 8] }
]
},
"snout": {
"implementation": "com.minelittlepony.client.model.part.PonySnout",
"data": "minelittlepony:components/snout"
},
"ears": {
"implementation": "com.minelittlepony.client.model.part.PonyEars",
"data": "minelittlepony:components/ears"
"data": "minelittlepony:components/ears",
"locals": {
"ear_shortening": "#global_ear_shortening"
}
}
}
},
"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 }
@ -161,13 +175,26 @@
},
"neck": {
"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 },
"rotate": [9, 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],
"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]
}
}
},
"jacket": {
"texture": { "u": 24, "v": 0 },

View file

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