It's ALIVE!

This commit is contained in:
Sollace 2019-11-26 23:55:39 +02:00
parent ed7f922403
commit 145d8f41a3
29 changed files with 492 additions and 175 deletions

View file

@ -5,10 +5,10 @@ import java.util.function.Function;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.minelittlepony.client.model.IPonyModel; import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.client.model.PlayerModelKey;
import com.minelittlepony.client.model.entity.race.PlayerModels; import com.minelittlepony.client.model.entity.race.PlayerModels;
import com.minelittlepony.client.render.LevitatingItemRenderer; import com.minelittlepony.client.render.LevitatingItemRenderer;
import com.minelittlepony.client.render.entity.MobRenderers; import com.minelittlepony.client.render.entity.MobRenderers;
import com.minelittlepony.client.render.entity.RenderPonyPlayer;
import com.minelittlepony.client.render.IPonyRender; import com.minelittlepony.client.render.IPonyRender;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -16,11 +16,9 @@ import javax.annotation.Nullable;
import com.minelittlepony.common.mixin.MixinEntityRenderDispatcher; import com.minelittlepony.common.mixin.MixinEntityRenderDispatcher;
import com.minelittlepony.mson.api.Mson; import com.minelittlepony.mson.api.Mson;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer; import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
@ -62,14 +60,11 @@ public class PonyRenderManager {
} }
private void addPlayerSkin(EntityRenderDispatcher manager, boolean slimArms, PlayerModels playerModel) { private void addPlayerSkin(EntityRenderDispatcher manager, boolean slimArms, PlayerModels playerModel) {
RenderPonyPlayer renderer = playerModel.createRenderer(manager, slimArms);
addPlayerRenderer(playerModel.getId(slimArms), renderer); PlayerModelKey<?, ?>.Key key = playerModel.getModelKey().getKey(slimArms);
} String id = playerModel.getId(slimArms);
private static void addPlayerRenderer(String modelType, PlayerEntityRenderer renderer) { Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer(id, key.getFactory());
EntityRenderDispatcher mx = MinecraftClient.getInstance().getEntityRenderManager();
((MixinEntityRenderDispatcher)mx).getPlayerRenderers().put(modelType, renderer);
} }
/** /**
@ -95,20 +90,6 @@ public class PonyRenderManager {
} }
} }
@Deprecated
public <T extends Entity, V extends T> void switchRenderer(boolean state, EntityType<V> type, EntityRendererRegistry.Factory factory) {
if (state) {
if (!renderMap.containsKey(type)) {
renderMap.put(type, ((MixinEntityRenderDispatcher)MinecraftClient.getInstance().getEntityRenderManager()).getEntityRenderers().get(type));
}
EntityRendererRegistry.INSTANCE.register(type, factory);
} else {
if (renderMap.containsKey(type)) {
EntityRendererRegistry.INSTANCE.register(type, (m, c) -> renderMap.get(type));
}
}
}
public LevitatingItemRenderer getMagicRenderer() { public LevitatingItemRenderer getMagicRenderer() {
return magicRenderer; return magicRenderer;
} }

View file

@ -2,8 +2,8 @@ package com.minelittlepony.client.hdskins;
import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.ModelWrapper; import com.minelittlepony.client.model.ModelWrapper;
import com.minelittlepony.client.model.entity.race.PlayerModels;
import com.minelittlepony.client.render.IPonyRender; import com.minelittlepony.client.render.IPonyRender;
import com.minelittlepony.client.render.RenderPony; import com.minelittlepony.client.render.RenderPony;
import com.minelittlepony.client.render.entity.feature.LayerGear; import com.minelittlepony.client.render.entity.feature.LayerGear;
@ -12,10 +12,10 @@ import com.minelittlepony.client.render.entity.feature.LayerPonyArmor;
import com.minelittlepony.client.render.entity.feature.LayerPonyElytra; import com.minelittlepony.client.render.entity.feature.LayerPonyElytra;
import com.minelittlepony.hdskins.dummy.DummyPlayerRenderer; import com.minelittlepony.hdskins.dummy.DummyPlayerRenderer;
import com.minelittlepony.hdskins.profile.SkinType; import com.minelittlepony.hdskins.profile.SkinType;
import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.pony.IPony; import com.minelittlepony.pony.IPony;
import com.minelittlepony.pony.meta.Race; import com.minelittlepony.pony.meta.Race;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
@ -28,18 +28,18 @@ class DummyPonyRenderer extends DummyPlayerRenderer<DummyPony, ClientPonyModel<D
protected final RenderPony<DummyPony, ClientPonyModel<DummyPony>> renderPony = new RenderPony<>(this); protected final RenderPony<DummyPony, ClientPonyModel<DummyPony>> renderPony = new RenderPony<>(this);
public DummyPonyRenderer(EntityRenderDispatcher manager, EntityRendererRegistry.Context context) { @SuppressWarnings("unchecked")
super(manager, context); public DummyPonyRenderer(EntityRenderDispatcher manager) {
super(manager, null);
addFeature(new LayerGear<>(this)); addFeature(new LayerGear<>(this));
renderPony.setPonyModel((ModelKey<ClientPonyModel<DummyPony>>)(Object)ModelType.EARTH_PONY.getKey(false));
renderPony.setSkipBlend(); renderPony.setSkipBlend();
} }
private ModelWrapper<DummyPony, ClientPonyModel<DummyPony>> playerModel;
@Override @Override
public ModelWrapper<DummyPony, ClientPonyModel<DummyPony>> getModelWrapper() { public ModelWrapper<DummyPony, ClientPonyModel<DummyPony>> getModelWrapper() {
return playerModel; return renderPony.playerModel;
} }
@Override @Override
@ -78,12 +78,11 @@ class DummyPonyRenderer extends DummyPlayerRenderer<DummyPony, ClientPonyModel<D
boolean canWet = playermodel.wet && (loc == playermodel.getTextures().getBlankSkin(SkinType.SKIN) || race == Race.SEAPONY); boolean canWet = playermodel.wet && (loc == playermodel.getTextures().getBlankSkin(SkinType.SKIN) || race == Race.SEAPONY);
playerModel = canWet ? PlayerModels.SEAPONY.getWrappedModel(slim) : PlayerModels.forRace(thePony.getRace(true)).getWrappedModel(slim);
playerModel.apply(thePony.getMetadata());
renderPony.setPonyModel(playerModel); @SuppressWarnings("unchecked")
ModelKey<? extends ClientPonyModel<DummyPony>> key = (ModelKey<? extends ClientPonyModel<DummyPony>>)(canWet ? ModelType.SEA_PONY.getKey(slim) : ModelType.getPlayerModel(thePony.getRace(true)).getKey(slim));
return playerModel.getBody(); return renderPony.setPonyModel(key).apply(thePony.getMetadata()).getBody();
} }
@Override @Override

View file

@ -5,8 +5,8 @@ import com.minelittlepony.client.SkinsProxy;
import com.minelittlepony.common.event.ClientReadyCallback; import com.minelittlepony.common.event.ClientReadyCallback;
import com.minelittlepony.hdskins.SkinCacheClearCallback; import com.minelittlepony.hdskins.SkinCacheClearCallback;
import com.minelittlepony.hdskins.dummy.DummyPlayer; import com.minelittlepony.hdskins.dummy.DummyPlayer;
import com.minelittlepony.mson.api.Mson;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import com.minelittlepony.client.pony.PonyManager; import com.minelittlepony.client.pony.PonyManager;
@ -23,7 +23,7 @@ class MineLPHDSkins {
ClientReadyCallback.EVENT.register(this::postInit); ClientReadyCallback.EVENT.register(this::postInit);
// Preview on the select skin gui // Preview on the select skin gui
EntityRendererRegistry.INSTANCE.register(DummyPlayer.TYPE, DummyPonyRenderer::new); Mson.getInstance().getEntityRendererRegistry().registerEntityRenderer(DummyPlayer.TYPE, DummyPonyRenderer::new);
} }
private void postInit(MinecraftClient minecraft) { private void postInit(MinecraftClient minecraft) {

View file

@ -1,6 +1,7 @@
package com.minelittlepony.client.model; package com.minelittlepony.client.model;
import net.minecraft.client.model.Model; import net.minecraft.client.model.Model;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.VexEntity; import net.minecraft.entity.mob.VexEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -16,17 +17,28 @@ import com.minelittlepony.client.model.entity.ModelZombiePony;
import com.minelittlepony.client.model.entity.ModelZombieVillagerPony; import com.minelittlepony.client.model.entity.ModelZombieVillagerPony;
import com.minelittlepony.client.model.entity.race.ModelAlicorn; import com.minelittlepony.client.model.entity.race.ModelAlicorn;
import com.minelittlepony.client.model.entity.race.ModelChangeling; import com.minelittlepony.client.model.entity.race.ModelChangeling;
import com.minelittlepony.client.model.entity.race.ModelEarthPony;
import com.minelittlepony.client.model.entity.race.ModelPegasus; import com.minelittlepony.client.model.entity.race.ModelPegasus;
import com.minelittlepony.client.model.entity.race.ModelUnicorn; import com.minelittlepony.client.model.entity.race.ModelUnicorn;
import com.minelittlepony.client.model.entity.race.ModelZebra; import com.minelittlepony.client.model.entity.race.ModelZebra;
import com.minelittlepony.client.render.entity.RenderPonyPlayer;
import com.minelittlepony.client.render.entity.RenderSeaponyPlayer;
import com.minelittlepony.mson.api.ModelKey; import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.mson.api.Mson; import com.minelittlepony.mson.api.Mson;
import com.minelittlepony.mson.api.MsonModel; import com.minelittlepony.mson.api.MsonModel;
import com.minelittlepony.pony.meta.Race;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
public final class ModelType { public final class ModelType {
private static final Map<Race, PlayerModelKey<?, ?>> PLAYER_MODELS = new HashMap<>();
public static final ModelKey<ModelVillagerPony<?>> VILLAGER = register("villager", ModelVillagerPony::new); public static final ModelKey<ModelVillagerPony<?>> VILLAGER = register("villager", ModelVillagerPony::new);
public static final ModelKey<ModelWitchPony> WITCH = register("witch", ModelWitchPony::new); public static final ModelKey<ModelWitchPony> WITCH = register("witch", ModelWitchPony::new);
public static final ModelKey<ModelZombiePony<?>> ZOMBIE = register("zombie", ModelZombiePony::new); public static final ModelKey<ModelZombiePony<?>> ZOMBIE = register("zombie", ModelZombiePony::new);
@ -38,20 +50,39 @@ public final class ModelType {
public static final ModelKey<ModelEnderStallion> ENDERMAN = register("enderman", ModelEnderStallion::new); public static final ModelKey<ModelEnderStallion> ENDERMAN = register("enderman", ModelEnderStallion::new);
public static final ModelKey<ModelBreezie<VexEntity>> BREEZIE = register("breezie", ModelBreezie::new); public static final ModelKey<ModelBreezie<VexEntity>> BREEZIE = register("breezie", ModelBreezie::new);
public static final PlayerModelKey<ModelAlicorn<?>> ALICORN = registerPlayer("alicorn", ModelAlicorn::new); public static final PlayerModelKey<?, ModelAlicorn<?>> ALICORN = registerPlayer("alicorn", Race.ALICORN, ModelAlicorn::new);
public static final PlayerModelKey<ModelUnicorn<?>> UNICORN = registerPlayer("unicorn", ModelUnicorn::new); public static final PlayerModelKey<?, ModelUnicorn<?>> UNICORN = registerPlayer("unicorn", Race.UNICORN, ModelUnicorn::new);
public static final PlayerModelKey<ModelPegasus<?>> PEGASUS = registerPlayer("pegasus", ModelPegasus::new); public static final PlayerModelKey<?, ModelUnicorn<?>> KIRIN = registerPlayer("kirin", Race.KIRIN, ModelUnicorn::new);
public static final PlayerModelKey<ModelPegasus<?>> BAT_PONY = registerPlayer("batpony", ModelPegasus::new); public static final PlayerModelKey<?, ModelPegasus<?>> PEGASUS = registerPlayer("pegasus", Race.PEGASUS, ModelPegasus::new);
public static final PlayerModelKey<ModelChangeling<?>> CHANGELING = registerPlayer("changeling", ModelChangeling::new); public static final PlayerModelKey<?, ModelPegasus<?>> GRYPHON = registerPlayer("gryphon", Race.GRYPHON, ModelPegasus::new);
public static final PlayerModelKey<ModelZebra<?>> ZEBRA = registerPlayer("zebra", ModelZebra::new); public static final PlayerModelKey<?, ModelPegasus<?>> HIPPOGRIFF = registerPlayer("hippogriff", Race.HIPPOGRIFF, ModelPegasus::new);
public static final PlayerModelKey<?, ModelEarthPony<?>> EARTH_PONY = registerPlayer("earth_pony", Race.EARTH, ModelEarthPony::new);
public static final PlayerModelKey<?, ModelEarthPony<?>> SEA_PONY = registerPlayer("sea_pony", Race.SEAPONY, ModelEarthPony::new, RenderSeaponyPlayer::new);
public static final PlayerModelKey<?, ModelPegasus<?>> BAT_PONY = registerPlayer("bat_pony", Race.BATPONY, ModelPegasus::new);
public static final PlayerModelKey<?, ModelChangeling<?>> CHANGELING = registerPlayer("changeling", Race.CHANGELING, ModelChangeling::new);
public static final PlayerModelKey<?, ModelChangeling<?>> CHANGEDLING = registerPlayer("reformed_changeling", Race.CHANGEDLING, ModelChangeling::new);
public static final PlayerModelKey<?, ModelZebra<?>> ZEBRA = registerPlayer("zebra", Race.ZEBRA, ModelZebra::new);
static <T extends Model & MsonModel> PlayerModelKey<T> registerPlayer(String name, Function<Boolean, T> constructor) { static <E extends LivingEntity, T extends Model & MsonModel> PlayerModelKey<E, T> registerPlayer(String name, Race race, Function<Boolean, T> constructor) {
return new PlayerModelKey<>(new Identifier("minelittlepony", "races/" + name), constructor); return registerPlayer(name, race, constructor, RenderPonyPlayer::new);
}
@SuppressWarnings("unchecked")
static <E extends LivingEntity, T extends Model & MsonModel> PlayerModelKey<E, T> registerPlayer(String name, Race race, Function<Boolean, T> constructor, PlayerModelKey.RendererFactory rendererFactory) {
return (PlayerModelKey<E, T>)PLAYER_MODELS.computeIfAbsent(race, r -> {
return new PlayerModelKey<>(new Identifier("minelittlepony", "races/" + name), constructor, rendererFactory);
});
} }
static <T extends Model & MsonModel> ModelKey<T> register(String name, Supplier<T> constructor) { static <T extends Model & MsonModel> ModelKey<T> register(String name, Supplier<T> constructor) {
return Mson.getInstance().registerModel(new Identifier("minelittlepony", name), constructor); return Mson.getInstance().registerModel(new Identifier("minelittlepony", name), constructor);
} }
@SuppressWarnings("unchecked")
@Nullable
public static <E extends LivingEntity, T extends Model & MsonModel> PlayerModelKey<E, T> getPlayerModel(Race race) {
return (PlayerModelKey<E, T>)PLAYER_MODELS.get(race);
}
public static void bootstrap() {}; public static void bootstrap() {};
} }

View file

@ -39,8 +39,9 @@ public class ModelWrapper<T extends LivingEntity, M extends IModel> implements I
} }
@Override @Override
public void apply(IPonyData meta) { public ModelWrapper<T, M> apply(IPonyData meta) {
body.apply(meta); body.apply(meta);
armor.apply(meta); armor.apply(meta);
return this;
} }
} }

View file

@ -1,6 +1,10 @@
package com.minelittlepony.client.model; package com.minelittlepony.client.model;
import net.minecraft.client.model.Model; import net.minecraft.client.model.Model;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import com.minelittlepony.mson.api.ModelKey; import com.minelittlepony.mson.api.ModelKey;
@ -9,29 +13,32 @@ import com.minelittlepony.mson.api.MsonModel;
import java.util.function.Function; import java.util.function.Function;
public class PlayerModelKey<T extends Model & MsonModel> { public class PlayerModelKey<T extends LivingEntity, M extends Model & MsonModel> {
private final ModelKey<T> key; private final ModelKey<M> key;
private boolean slim; private boolean slim;
public final ModelKey<T> steveKey; private final Key steveKey;
public final ModelKey<T> alexKey; private final Key alexKey;
PlayerModelKey(Identifier id, Function<Boolean, T> factory) { private final RendererFactory rendererFactory;
PlayerModelKey(Identifier id, Function<Boolean, M> factory, RendererFactory rendererFactory) {
this.key = Mson.getInstance().registerModel(id, () -> factory.apply(slim)); this.key = Mson.getInstance().registerModel(id, () -> factory.apply(slim));
this.rendererFactory = rendererFactory;
steveKey = new Key(false); steveKey = new Key(false);
alexKey = new Key(true); alexKey = new Key(true);
} }
public T createModel(boolean slimArms) { public Key getKey(boolean slimArms) {
return (slimArms ? alexKey : steveKey).createModel(); return slimArms ? alexKey : steveKey;
} }
private class Key implements ModelKey<T> { public class Key implements ModelKey<M> {
private final boolean slim; final boolean slim;
public Key(boolean slim) { public Key(boolean slim) {
this.slim = slim; this.slim = slim;
@ -43,10 +50,18 @@ public class PlayerModelKey<T extends Model & MsonModel> {
} }
@Override @Override
public T createModel() { public M createModel() {
PlayerModelKey.this.slim = this.slim; PlayerModelKey.this.slim = this.slim;
return key.createModel(); return key.createModel();
} }
@SuppressWarnings("unchecked")
public Function<EntityRenderDispatcher, PlayerEntityRenderer> getFactory() {
return d -> rendererFactory.create(d, slim, (ModelKey<? extends ClientPonyModel<AbstractClientPlayerEntity>>)this);
}
}
public interface RendererFactory {
PlayerEntityRenderer create(EntityRenderDispatcher dispatcher, boolean slim, ModelKey<? extends ClientPonyModel<AbstractClientPlayerEntity>> key);
} }
} }

View file

@ -19,9 +19,10 @@ public class ArmourWrapper<T extends LivingEntity> implements IEquestrianArmour<
} }
@Override @Override
public void apply(IPonyData meta) { public ArmourWrapper<T> apply(IPonyData meta) {
outerLayer.apply(meta); outerLayer.apply(meta);
innerLayer.apply(meta); innerLayer.apply(meta);
return this;
} }
@Override @Override

View file

@ -1,41 +1,27 @@
package com.minelittlepony.client.model.entity.race; package com.minelittlepony.client.model.entity.race;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.minelittlepony.client.model.ModelWrapper; import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.entity.ModelSeapony; import com.minelittlepony.client.model.PlayerModelKey;
import com.minelittlepony.client.render.entity.RenderPonyPlayer;
import com.minelittlepony.client.render.entity.RenderSeaponyPlayer;
import com.minelittlepony.model.IModel;
import com.minelittlepony.pony.meta.Race; import com.minelittlepony.pony.meta.Race;
import javax.annotation.Nullable;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.entity.LivingEntity;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
public enum PlayerModels { public enum PlayerModels {
/** /**
* The default non-pony model. This is typically handled my the vanilla renderer. * The default non-pony model. This is typically handled my the vanilla renderer.
*/ */
DEFAULT("default", "slim", Race.HUMAN, ModelEarthPony::new), DEFAULT("default", "slim", Race.HUMAN),
EARTHPONY(Race.EARTH, ModelEarthPony::new), EARTHPONY(Race.EARTH),
PEGASUS(Race.PEGASUS, ModelPegasus::new), PEGASUS(Race.PEGASUS),
BATPONY(Race.BATPONY, ModelPegasus::new), BATPONY(Race.BATPONY),
UNICORN(Race.UNICORN, ModelUnicorn::new), UNICORN(Race.UNICORN),
ALICORN(Race.ALICORN, ModelAlicorn::new), ALICORN(Race.ALICORN),
CHANGELING(Race.CHANGELING, ModelChangeling::new), CHANGELING(Race.CHANGELING),
ZEBRA(Race.ZEBRA, ModelZebra::new), ZEBRA(Race.ZEBRA),
SEAPONY(Race.SEAPONY, ModelSeapony::new) { SEAPONY(Race.SEAPONY);
@Override
public RenderPonyPlayer createRenderer(EntityRenderDispatcher manager, boolean slimArms) {
return new RenderSeaponyPlayer(manager, slimArms, PlayerModels.UNICORN.getWrappedModel(slimArms), getWrappedModel(slimArms));
}
};
public static final List<PlayerModels> registry = Arrays.asList(values()); public static final List<PlayerModels> registry = Arrays.asList(values());
private static final Map<Race, PlayerModels> raceModelsMap = Maps.newEnumMap(Race.class); private static final Map<Race, PlayerModels> raceModelsMap = Maps.newEnumMap(Race.class);
@ -46,71 +32,34 @@ public enum PlayerModels {
} }
} }
private final Function<Boolean, IModel> resolver; private final String normal;
private final String slim;
private final PendingModel normal;
private final PendingModel slim;
private final Race race; private final Race race;
PlayerModels(Race race, Function<Boolean, IModel> resolver) { PlayerModels(Race race) {
normal = new PendingModel(name().toLowerCase()); normal = name().toLowerCase();
slim = new PendingModel("slim" + normal.key); slim = "slim" + normal;
this.resolver = resolver;
this.race = race; this.race = race;
} }
PlayerModels(String normalKey, String slimKey, Race race, Function<Boolean, IModel> resolver) { PlayerModels(String normalKey, String slimKey, Race race) {
normal = new PendingModel(normalKey); normal = normalKey;
slim = new PendingModel(slimKey); slim = slimKey;
this.resolver = resolver;
this.race = race; this.race = race;
} }
@Deprecated public PlayerModelKey<?, ?> getModelKey() {
public PendingModel getPendingModel(boolean isSlim) { return ModelType.getPlayerModel(race);
return isSlim ? slim : normal;
}
@Deprecated
public <T extends LivingEntity, M extends IModel> ModelWrapper<T, M> getWrappedModel(boolean isSlim) {
return getPendingModel(isSlim).getWrappedModel(isSlim);
} }
public String getId(boolean isSlim) { public String getId(boolean isSlim) {
return getPendingModel(isSlim).key; return isSlim ? slim : normal;
}
public RenderPonyPlayer createRenderer(EntityRenderDispatcher manager, boolean slimArms) {
return new RenderPonyPlayer(manager, getWrappedModel(slimArms));
} }
public static PlayerModels forRace(Race race) { public static PlayerModels forRace(Race race) {
return raceModelsMap.getOrDefault(race.getAlias(), DEFAULT); return raceModelsMap.getOrDefault(race.getAlias(), DEFAULT);
} }
@Deprecated
private final class PendingModel {
@Nullable
private ModelWrapper<?, IModel> model;
private final String key;
PendingModel(String key) {
this.key = key;
}
@SuppressWarnings("unchecked")
public <T extends LivingEntity, M extends IModel> ModelWrapper<T, M> getWrappedModel(boolean isSlim) {
if (model == null) {
model = new ModelWrapper<>(resolver.apply(isSlim));
}
return (ModelWrapper<T, M>)model;
}
}
} }

View file

@ -5,6 +5,7 @@ import com.minelittlepony.client.PonyRenderManager;
import com.minelittlepony.client.model.IPonyModel; import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.client.model.ModelWrapper; import com.minelittlepony.client.model.ModelWrapper;
import com.minelittlepony.client.transform.PonyPosture; import com.minelittlepony.client.transform.PonyPosture;
import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.pony.IPony; import com.minelittlepony.pony.IPony;
import com.minelittlepony.util.math.MathUtil; import com.minelittlepony.util.math.MathUtil;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor; import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
@ -132,10 +133,10 @@ public class RenderPony<T extends LivingEntity, M extends EntityModel<T> & IPony
return playerModel.getBody(); return playerModel.getBody();
} }
public M setPonyModel(ModelWrapper<T, M> model) { public ModelWrapper<T, M> setPonyModel(ModelKey<? extends M> model) {
playerModel = model; playerModel = new ModelWrapper<>(model.createModel());
return getModel(); return playerModel;
} }
public void updateMetadata(Identifier texture) { public void updateMetadata(Identifier texture) {

View file

@ -38,7 +38,7 @@ public abstract class RenderPonyMob<T extends MobEntity, M extends EntityModel<T
public RenderPonyMob(EntityRenderDispatcher manager, ModelKey<? super M> key) { public RenderPonyMob(EntityRenderDispatcher manager, ModelKey<? super M> key) {
super(manager, (M)key.createModel(), 0.5F); super(manager, (M)key.createModel(), 0.5F);
this.model = renderPony.setPonyModel(new ModelWrapper<>(model)); this.model = renderPony.setPonyModel((ModelKey<M>)key).getBody();
addLayers(); addLayers();
} }

View file

@ -16,6 +16,7 @@ import com.minelittlepony.client.render.entity.feature.LayerPonyCape;
import com.minelittlepony.client.render.entity.feature.LayerPonyCustomHead; import com.minelittlepony.client.render.entity.feature.LayerPonyCustomHead;
import com.minelittlepony.client.render.entity.feature.LayerPonyElytra; import com.minelittlepony.client.render.entity.feature.LayerPonyElytra;
import com.minelittlepony.model.gear.IGear; import com.minelittlepony.model.gear.IGear;
import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.pony.IPony; import com.minelittlepony.pony.IPony;
import com.minelittlepony.pony.meta.Race; import com.minelittlepony.pony.meta.Race;
@ -38,10 +39,10 @@ public class RenderPonyPlayer extends PlayerEntityRenderer implements IPonyRende
protected final RenderPony<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> renderPony = new RenderPony<>(this); protected final RenderPony<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> renderPony = new RenderPony<>(this);
public RenderPonyPlayer(EntityRenderDispatcher manager, ModelWrapper<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> model) { public RenderPonyPlayer(EntityRenderDispatcher manager, boolean slim, ModelKey<? extends ClientPonyModel<AbstractClientPlayerEntity>> key) {
super(manager, false); super(manager, slim);
this.model = renderPony.setPonyModel(model); this.model = renderPony.setPonyModel(key).getBody();
addLayers(); addLayers();
} }

View file

@ -13,7 +13,7 @@ public class RenderPonyTrader extends RenderPonyMob.Caster<WanderingTraderEntity
public static final Identifier TEXTURE = new Identifier("minelittlepony", "textures/entity/wandering_trader_pony.png"); public static final Identifier TEXTURE = new Identifier("minelittlepony", "textures/entity/wandering_trader_pony.png");
public RenderPonyTrader(EntityRenderDispatcher manager) { public RenderPonyTrader(EntityRenderDispatcher manager) {
super(manager, ModelType.ALICORN.steveKey); super(manager, ModelType.ALICORN.getKey(false));
} }
@Override @Override

View file

@ -1,8 +1,10 @@
package com.minelittlepony.client.render.entity; package com.minelittlepony.client.render.entity;
import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.ModelWrapper; import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.pony.IPony; import com.minelittlepony.pony.IPony;
import com.minelittlepony.pony.meta.Race;
import com.minelittlepony.util.math.MathUtil; import com.minelittlepony.util.math.MathUtil;
import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.AbstractClientPlayerEntity;
@ -11,16 +13,14 @@ import net.minecraft.particle.ParticleTypes;
public class RenderSeaponyPlayer extends RenderPonyPlayer { public class RenderSeaponyPlayer extends RenderPonyPlayer {
protected final ModelWrapper<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> seapony; protected final ModelKey<? extends ClientPonyModel<AbstractClientPlayerEntity>> seapony;
protected final ModelWrapper<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> normalPony; protected final ModelKey<? extends ClientPonyModel<AbstractClientPlayerEntity>> normalPony;
public RenderSeaponyPlayer(EntityRenderDispatcher manager, boolean useSmallArms, public RenderSeaponyPlayer(EntityRenderDispatcher manager, boolean slim, ModelKey<? extends ClientPonyModel<AbstractClientPlayerEntity>> key) {
ModelWrapper<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> model, super(manager, slim, key);
ModelWrapper<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>> alternate) {
super(manager, model);
seapony = alternate; seapony = ModelType.<AbstractClientPlayerEntity, ClientPonyModel<AbstractClientPlayerEntity>>getPlayerModel(Race.UNICORN).getKey(slim);
normalPony = model; normalPony = key;
} }
@Override @Override
@ -29,7 +29,7 @@ public class RenderSeaponyPlayer extends RenderPonyPlayer {
boolean wet = pony.isPartiallySubmerged(player); boolean wet = pony.isPartiallySubmerged(player);
model = renderPony.setPonyModel(wet ? seapony : normalPony); model = renderPony.setPonyModel(wet ? seapony : normalPony).getBody();
float state = wet ? 100 : 0; float state = wet ? 100 : 0;
float interpolated = pony.getMetadata().getInterpolator(player.getUuid()).interpolate("seapony_state", state, 5); float interpolated = pony.getMetadata().getInterpolator(player.getUuid()).interpolate("seapony_state", state, 5);

View file

@ -1,6 +1,7 @@
package com.minelittlepony.client.render.entity.feature; package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.client.model.IPonyModel; import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.client.model.ModelWrapper;
import com.minelittlepony.client.render.IPonyRender; import com.minelittlepony.client.render.IPonyRender;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
@ -42,11 +43,7 @@ public abstract class AbstractPonyLayer<T extends LivingEntity, M extends Entity
return (C)context; return (C)context;
} }
public M getPlayerModel() { public ModelWrapper<T, M> getModelWrapper() {
return getContext().getModelWrapper().getBody(); return getContext().getModelWrapper();
}
public M getMainModel() {
return getContext().getModel();
} }
} }

View file

@ -24,8 +24,11 @@ public class LayerDJPon3Head<T extends AbstractClientPlayerEntity, M extends Ent
public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
if ("deadmau5".equals(entity.getName().getString())) { if ("deadmau5".equals(entity.getName().getString())) {
stack.push(); stack.push();
getPlayerModel().transform(BodyPart.HEAD, stack);
getPlayerModel().getHead().rotate(stack); M body = getModelWrapper().getBody();
body.transform(BodyPart.HEAD, stack);
body.getHead().rotate(stack);
stack.scale(1.3333334F, 1.3333334F, 1.3333334F); stack.scale(1.3333334F, 1.3333334F, 1.3333334F);
stack.translate(0, 0.3F, 0); stack.translate(0, 0.3F, 0);

View file

@ -51,7 +51,7 @@ public class LayerGear<T extends LivingEntity, M extends EntityModel<T> & IPonyM
return; return;
} }
M model = getPlayerModel(); M model = getModelWrapper().getBody();
Map<BodyPart, Float> renderStackingOffsets = new HashMap<>(); Map<BodyPart, Float> renderStackingOffsets = new HashMap<>();

View file

@ -14,8 +14,6 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Arm; import net.minecraft.util.Arm;
import static com.mojang.blaze3d.platform.GlStateManager.*;
public class LayerHeldPonyItem<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyLayer<T, M> { public class LayerHeldPonyItem<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyLayer<T, M> {
public LayerHeldPonyItem(IPonyRender<T, M> livingPony) { public LayerHeldPonyItem(IPonyRender<T, M> livingPony) {
@ -56,11 +54,11 @@ public class LayerHeldPonyItem<T extends LivingEntity, M extends EntityModel<T>
private void renderHeldItem(T entity, ItemStack drop, ModelTransformation.Type transform, Arm arm, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) { private void renderHeldItem(T entity, ItemStack drop, ModelTransformation.Type transform, Arm arm, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
if (!drop.isEmpty()) { if (!drop.isEmpty()) {
pushMatrix(); stack.push();
renderArm(arm, stack); renderArm(arm, stack);
if (getMainModel().getAttributes().isCrouching) { if (getModel().getAttributes().isCrouching) {
translatef(0, 0.2F, 0); stack.translate(0, 0.2F, 0);
} }
float left = arm == Arm.LEFT ? 1 : -1; float left = arm == Arm.LEFT ? 1 : -1;
@ -77,7 +75,7 @@ public class LayerHeldPonyItem<T extends LivingEntity, M extends EntityModel<T>
MinecraftClient.getInstance().getFirstPersonRenderer().renderItem(entity, drop, transform, arm == Arm.LEFT, stack, renderContext, lightUv); MinecraftClient.getInstance().getFirstPersonRenderer().renderItem(entity, drop, transform, arm == Arm.LEFT, stack, renderContext, lightUv);
postItemRender(entity, drop, transform, arm, stack, renderContext); postItemRender(entity, drop, transform, arm, stack, renderContext);
popMatrix(); stack.pop();
} }
} }

View file

@ -55,8 +55,9 @@ public class LayerPonyElytra<T extends LivingEntity, M extends EntityModel<T> &
} }
protected void preRenderCallback(MatrixStack stack) { protected void preRenderCallback(MatrixStack stack) {
stack.translate(0, getPlayerModel().getRiderYOffset(), 0.125F); M body = getModelWrapper().getBody();
getPlayerModel().transform(BodyPart.BODY, stack); stack.translate(0, body.getRiderYOffset(), 0.125F);
body.transform(BodyPart.BODY, stack);
} }
protected EntityModel<T> getElytraModel() { protected EntityModel<T> getElytraModel() {

View file

@ -6,5 +6,5 @@ public interface IModelWrapper {
/** /**
* Updates metadata values to this wrapper's contained models. * Updates metadata values to this wrapper's contained models.
*/ */
void apply(IPonyData meta); IModelWrapper apply(IPonyData meta);
} }

View file

@ -16,7 +16,7 @@ public enum Race implements ITriggerPixelMapped<Race> {
CHANGELING (0x282b29, true, true), CHANGELING (0x282b29, true, true),
ZEBRA (0xd0cccf, false, false), ZEBRA (0xd0cccf, false, false),
CHANGEDLING (0xcaed5a, CHANGELING), CHANGEDLING (0xcaed5a, CHANGELING),
GRIFFIN (0xae9145, PEGASUS), GRYPHON (0xae9145, PEGASUS),
HIPPOGRIFF (0xd6ddac, PEGASUS), HIPPOGRIFF (0xd6ddac, PEGASUS),
KIRIN (0xfa88af, UNICORN), KIRIN (0xfa88af, UNICORN),
BATPONY (0xeeeeee, true, false), BATPONY (0xeeeeee, true, false),

View file

@ -1,8 +0,0 @@
{
"parent": "minelittlepony:steve_pony",
"locals": {
"arm_width": 3,
"arm_rotation_x": 2,
"arm_rotation_y": 8.5
}
}

View file

@ -0,0 +1,335 @@
{
"parent": "mson:steve",
"texture": {
"w": 64, "h": 64
},
"locals": {
"arm_length": 12,
"arm_width": 4,
"arm_depth": 4,
"arm_x": 0,
"arm_x_neg": ["#arm_x", "-", "#arm_width"],
"arm_z": [2, "-", "#arm_depth"],
"arm_rotation_x": 3,
"arm_rotation_x_neg": [0, "-", "#arm_rotation_x"],
"arm_rotation_y": 8
},
"head": {
"offset": [ 0, -1, -2 ],
"center": [ 0, 0, -2 ],
"cubes": [
{ "from": [-4, -4, -4], "size": [ 8, 8, 8] }
],
"children": [
{
"type": "mson:slot",
"name": "snout",
"implementation": "com.minelittlepony.client.model.part.PonySnout",
"content": "minelittlepony:components/snout"
},
{
"type": "mson:slot",
"name": "ears",
"implementation": "com.minelittlepony.client.model.part.PonyEars",
"content": "minelittlepony:components/ears"
}
]
},
"helmet": {
"texture": { "u": 32, "v": 0 },
"offset": [ 0, -1, -2 ],
"center": [ 0, 0, -2 ],
"cubes": [
{ "from": [-4, -4, -4], "size": [ 8, 8, 8], "stretch": 0.5 }
]
},
"torso": {
"texture": { "u": 16, "v": 16 },
"cubes": [
{ "from": [-4, 4, -2], "size": [ 8, 8, 4] }
]
},
"upper_torso": {
"texture": { "u": 24, "v": 0 },
"offset": [ 0, 8, 6 ],
"cubes": [
{
"type": "mson:plane", "__comment": "body sides",
"texture": { "u": 24, "v": 0 },
"face": "east",
"position": [ 4, -4, -4 ], "size": [ 8, 8 ]
},
{
"type": "mson:plane", "__comment": "body sides",
"texture": { "u": 24, "v": 0 },
"mirror": [ false, false, true ],
"face": "west",
"position": [ -4, -4, -4 ], "size": [ 8, 8 ]
},
{
"type": "mson:plane", "__comment": "cutie mark",
"texture": { "u": 4, "v": 0 },
"face": "east",
"position": [ 4, -4, 4 ], "size": [ 8, 4 ]
},
{
"type": "mson:plane", "__comment": "cutie mark",
"texture": { "u": 4, "v": 0 },
"mirror": [ false, false, true ],
"face": "east",
"position": [ -4, -4, 4 ], "size": [ 8, 4 ]
},
{
"type": "mson:plane", "__comment": "stomach",
"texture": { "u": 56, "v": 0 },
"face": "down",
"position": [ -4, 4, -4 ],
"size": [ 8, 8 ]
},
{
"type": "mson:plane", "__comment": "butt",
"texture": { "u": 36, "v": 16 },
"face": "south",
"position": [ -4, -4, 8 ], "size": [ 8, 4 ]
},
{
"type": "mson:plane", "__comment": "butt",
"texture": { "u": 36, "v": 16 },
"face": "south",
"position": [ -4, 0, 8 ],
"size": [ 8, 4 ]
},
{
"type": "mson:plane", "__comment": "butt",
"texture": { "u": 36, "v": 16 },
"face": "down",
"position": [ -4, 4, 4 ], "size": [ 8, 4 ]
},
{
"type": "mson:plane", "__comment": "back",
"texture": { "u": 32, "v": 20 },
"mirror": [ false, false, true ],
"face": "up",
"position": [ -4, -4, -4 ], "size": [ 8, 12 ]
}
],
"children": [
{
"type": "mson:planar",
"texture": { "u": 32, "v": 0 },
"rotate": [0.5, 0, 0],
"up": [-1, 2, 2, 2, 6],
"down": [-1, 4, 2, 2, 6],
"east": [ 1, 2, 2, 2, 6],
"south":[-1, 2, 8, 2, 2],
"cubes": [
{
"type": "mson:plane",
"mirror": [ false, false, true ],
"face": "west",
"position": [ -1, -2, -2 ], "size": [ 2, 6 ]
}
]
}
]
},
"neck": {
"type": "mson:planar",
"texture": { "u": 0, "v": 16 },
"rotate": [0.166, 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": 16, "v": 32 },
"cubes": [
{ "from": [-4, 0, -2], "size": [ 8, 12, 4], "stretch": 0.25 },
{ "from": [-4, 4, -2], "size": [ 8, 8, 4 ], "stretch": 0.25 }
]
},
"saddle": {
"texture": { "u": 24, "v": 0 },
"offset": [0, 8, 6],
"cubes": [
{
"type": "mson:plane", "__comment": "body sides a",
"texture": { "u": 12, "v": 32 },
"face": "east",
"position": [ 4, -4, -4 ], "size": [ 4, 8 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "body sides a",
"texture": { "u": 12, "v": 32 },
"mirror": [ false, false, true ],
"face": "west",
"position": [ -4, -4, -4 ], "size": [ 4, 8 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "body sides b",
"texture": { "u": 12, "v": 48 },
"face": "east",
"position": [ 4, 0, -4 ], "size": [ 4, 8 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "body sides b",
"mirror": [ false, false, true ],
"texture": { "u": 12, "v": 48 },
"face": "west",
"position": [ -4, 0, -4 ], "size": [ 4, 8 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "qt mark a",
"texture": { "u": 0, "v": 32 },
"face": "east",
"position": [ 4, -4, 4 ], "size": [ 4, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "qt mark a",
"mirror": [ false, false, true ],
"texture": { "u": 0, "v": 32 },
"face": "west",
"position": [ -4, -4, 4 ], "size": [ 4, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "qt mark b",
"texture": { "u": 0, "v": 48 },
"face": "east",
"position": [ 4, 0, 4 ], "size": [ 4, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "qt mark b",
"texture": { "u": 0, "v": 48 },
"face": "west",
"position": [ -4, 0, 4 ], "size": [ 4, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "stomach a",
"texture": { "u": 28, "v": 48 },
"face": "down",
"position": [ -4, 4, -4 ], "size": [ 8, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "stomach b",
"texture": { "u": 44, "v": 48 },
"face": "down",
"position": [ -4, 4, 0 ], "size": [ 8, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "stomach c",
"texture": { "u": 36, "v": 32 },
"face": "down",
"position": [ -4, 4, 4 ], "size": [ 8, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "butt",
"texture": { "u": 36, "v": 32 },
"face": "south",
"position": [ -4, -4, 8 ], "size": [ 8, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "butt",
"texture": { "u": 36, "v": 32 },
"face": "south",
"position": [ -4, 0, 8 ], "size": [ 8, 4 ], "stretch": 0.25
},
{
"type": "mson:plane", "__comment": "back",
"texture": { "u": 32, "v": 36 },
"face": "up",
"position": [ -4, -4, -4 ], "size": [ 8, 12 ], "stretch": 0.25
}
]
},
"tail": {
"type": "mson:slot",
"name": "tail",
"implementation": "com.minelittlepony.client.model.part.PonyTail",
"content": "minelittlepony:components/tail"
},
"right_arm": {
"center": ["#arm_rotation_x_neg", "#arm_rotation_y", 0],
"texture": { "u": 40, "v": 16 },
"cubes": [
{
"from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ]
}
]
},
"left_arm": {
"center": ["#arm_rotation_x", "#arm_rotation_y", 0],
"texture": { "u": 32, "v": 48 },
"cubes": [
{
"from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ]
}
]
},
"right_leg": {
"center": ["#arm_rotation_x_neg", 0, 0],
"texture": { "u": 0, "v": 16 },
"cubes": [
{
"from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ]
}
]
},
"left_leg": {
"center": ["#arm_rotation_x", 0, 0],
"texture": { "u": 16, "v": 48 },
"cubes": [
{
"from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ]
}
]
},
"right_sleeve": {
"center": ["#arm_rotation_x_neg", "#arm_rotation_y", 0],
"texture": { "u": 40, "v": 32 },
"cubes": [
{
"from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"stretch": 0.25
}
]
},
"left_sleeve": {
"center": ["#arm_rotation_x", "#arm_rotation_y", 0],
"texture": { "u": 48, "v": 48 },
"cubes": [
{
"from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"stretch": 0.25
}
]
},
"right_pant_leg": {
"center": ["#arm_rotation_x_neg", 0, 0],
"texture": { "u": 0, "v": 32 },
"cubes": [
{
"from": [ "#arm_x_neg", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"stretch": 0.25
}
]
},
"left_pant_leg": {
"center": ["#arm_rotation_x", 0, 0],
"texture": { "u": 0, "v": 48 },
"cubes": [
{
"from": [ "#arm_x", 4, "#arm_z"],
"size": [ "#arm_width", "#arm_length", "#arm_depth" ],
"stretch": 0.25
}
]
}
}

View file

@ -1,3 +1,3 @@
{ {
"parent": "minelittlepony:seapony" "parent": "minelittlepony:races/sea_pony"
} }

View file

@ -0,0 +1,3 @@
{
"parent": "minelittlepony:steve_pony"
}

View file

@ -0,0 +1,3 @@
{
"parent": "minelittlepony:races/pegasus"
}

View file

@ -0,0 +1,3 @@
{
"parent": "minelittlepony:races/pegasus"
}

View file

@ -0,0 +1,3 @@
{
"parent": "minelittlepony:races/unicorn"
}