* Move player rendering to make use of the build in skinMap

* Remove reflection
* Use the interface (IPonyData) not the class
This commit is contained in:
Sollace 2018-04-24 14:55:32 +02:00
parent 694db391bb
commit fbb40134e2
38 changed files with 542 additions and 492 deletions

View file

@ -6,5 +6,15 @@ import net.minecraft.client.resources.data.IMetadataSection;
* Dummy interface so gson won't go crazy * Dummy interface so gson won't go crazy
*/ */
public interface IPonyData extends IMetadataSection { public interface IPonyData extends IMetadataSection {
PonyRace getRace();
TailLengths getTail();
PonyGender getGender();
PonySize getSize();
int getGlowColor();
boolean hasMagic();
} }

View file

@ -2,9 +2,8 @@ package com.minelittlepony;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.minelittlepony.gui.PonySettingPanel; import com.minelittlepony.gui.PonySettingPanel;
import com.minelittlepony.hdskins.gui.EntityPonyModel;
import com.minelittlepony.hdskins.gui.GuiSkinsMineLP; import com.minelittlepony.hdskins.gui.GuiSkinsMineLP;
import com.minelittlepony.hdskins.gui.RenderPonyModel; import com.minelittlepony.model.PlayerModels;
import com.minelittlepony.renderer.RenderPonyEvoker; import com.minelittlepony.renderer.RenderPonyEvoker;
import com.minelittlepony.renderer.RenderPonyIllusionIllager; import com.minelittlepony.renderer.RenderPonyIllusionIllager;
import com.minelittlepony.renderer.RenderPonyPigman; import com.minelittlepony.renderer.RenderPonyPigman;
@ -14,6 +13,7 @@ import com.minelittlepony.renderer.RenderPonyVillager;
import com.minelittlepony.renderer.RenderPonyVindicator; import com.minelittlepony.renderer.RenderPonyVindicator;
import com.minelittlepony.renderer.RenderPonyZombie; import com.minelittlepony.renderer.RenderPonyZombie;
import com.minelittlepony.renderer.RenderPonyZombieVillager; import com.minelittlepony.renderer.RenderPonyZombieVillager;
import com.minelittlepony.renderer.player.RenderPonyPlayer;
import com.mumfrey.liteloader.core.LiteLoader; import com.mumfrey.liteloader.core.LiteLoader;
import com.mumfrey.liteloader.util.ModUtilities; import com.mumfrey.liteloader.util.ModUtilities;
import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.HDSkinManager;
@ -49,7 +49,6 @@ public class MineLittlePony {
public static final Logger logger = LogManager.getLogger("MineLittlePony"); public static final Logger logger = LogManager.getLogger("MineLittlePony");
public static final String MOD_NAME = "Mine Little Pony"; public static final String MOD_NAME = "Mine Little Pony";
public static final String MOD_VERSION = "@VERSION@"; public static final String MOD_VERSION = "@VERSION@";
@ -98,7 +97,9 @@ public class MineLittlePony {
RenderManager rm = minecraft.getRenderManager(); RenderManager rm = minecraft.getRenderManager();
this.saveCurrentRenderers(rm); this.saveCurrentRenderers(rm);
ModUtilities.addRenderer(EntityPonyModel.class, new RenderPonyModel(rm)); //ModUtilities.addRenderer(EntityPonyModel.class, new RenderPonyModel(rm));
this.initialisePlayerRenderers(rm);
this.initializeMobRenderers(rm); this.initializeMobRenderers(rm);
} }
@ -131,11 +132,15 @@ public class MineLittlePony {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T extends Entity> Render<T> getRenderer(Class<T> cl) { private <T extends Entity> Render<T> getRenderer(Class<T> cl) {
Render<T> render = (Render<T>) this.renderMap.get(cl); Render<T> render = (Render<T>) this.renderMap.get(cl);
if (render == null) if (render == null) throw new MissingRendererException(cl);
throw new MissingRendererException(cl);
return render; return render;
} }
public void initialisePlayerRenderers(RenderManager rm) {
new RenderPonyPlayer(rm, false, PlayerModels.PONY);
new RenderPonyPlayer(rm, true, PlayerModels.PONY);
}
public void initializeMobRenderers(RenderManager rm) { public void initializeMobRenderers(RenderManager rm) {
if (this.config.villagers) { if (this.config.villagers) {
ModUtilities.addRenderer(EntityVillager.class, new RenderPonyVillager(rm)); ModUtilities.addRenderer(EntityVillager.class, new RenderPonyVillager(rm));
@ -209,7 +214,7 @@ public class MineLittlePony {
} }
public PonyManager getManager() { public PonyManager getManager() {
return this.ponyManager; return ponyManager;
} }
public static PonyConfig getConfig() { public static PonyConfig getConfig() {

View file

@ -1,14 +1,11 @@
package com.minelittlepony; package com.minelittlepony;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.minelittlepony.model.PMAPI; import com.minelittlepony.ducks.IDownloadImageData;
import com.minelittlepony.model.PlayerModel; import com.minelittlepony.model.PlayerModel;
import com.minelittlepony.util.PonyFields;
import com.voxelmodpack.hdskins.DynamicTextureImage; import com.voxelmodpack.hdskins.DynamicTextureImage;
import com.voxelmodpack.hdskins.ThreadDownloadImageETag; import com.voxelmodpack.hdskins.ThreadDownloadImageETag;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.ThreadDownloadImageData;
import net.minecraft.client.renderer.texture.ITextureObject; import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResource;
@ -27,45 +24,30 @@ import javax.annotation.concurrent.Immutable;
public class Pony { public class Pony {
private static final AtomicInteger ponyCount = new AtomicInteger(); private static final AtomicInteger ponyCount = new AtomicInteger();
private final int ponyId = ponyCount.getAndIncrement(); private final int ponyId = ponyCount.getAndIncrement();
private final ResourceLocation texture; private final ResourceLocation texture;
private final PonyData metadata; private final IPonyData metadata;
public Pony(AbstractClientPlayer player) { private final boolean smallArms;
this.texture = player.getLocationSkin();
public Pony(ResourceLocation resource, boolean slim) {
this.texture = resource;
this.metadata = this.checkSkin(this.texture); this.metadata = this.checkSkin(this.texture);
this.smallArms = slim;
MineLittlePony.logger.debug("+ Initialising new pony #{} for player {} ({}) with resource location {}.",
this.ponyId, player.getName(), player.getUniqueID(), this.texture);
} }
public Pony(ResourceLocation resourceLocation) { private IPonyData checkSkin(ResourceLocation textureResourceLocation) {
this(resourceLocation, null); IPonyData data = checkPonyMeta(textureResourceLocation);
} if (data != null) return data;
public Pony(ResourceLocation aTextureResourceLocation, @Nullable PonyData meta) { BufferedImage skinImage = this.getBufferedImage(textureResourceLocation);
this.texture = aTextureResourceLocation; return this.checkSkin(skinImage);
this.metadata = meta != null ? meta : this.checkSkin(this.texture);
MineLittlePony.logger.debug("+ Initialising new pony #{} with resource location {}.", this.ponyId, this.texture);
}
private PonyData checkSkin(ResourceLocation textureResourceLocation) {
PonyData data = checkPonyMeta(textureResourceLocation);
if (data == null) {
BufferedImage skinImage = this.getBufferedImage(textureResourceLocation);
if (skinImage != null) {
data = this.checkSkin(skinImage);
} else {
data = new PonyData();
}
}
return data;
} }
@Nullable @Nullable
private PonyData checkPonyMeta(ResourceLocation location) { private IPonyData checkPonyMeta(ResourceLocation location) {
try { try {
IResource res = Minecraft.getMinecraft().getResourceManager().getResource(location); IResource res = Minecraft.getMinecraft().getResourceManager().getResource(location);
if (res.hasMetadata()) { if (res.hasMetadata()) {
@ -83,85 +65,61 @@ public class Pony {
} }
@Nullable @Nullable
private BufferedImage getBufferedImage(@Nonnull ResourceLocation textureResourceLocation) { private BufferedImage getBufferedImage(@Nonnull ResourceLocation resource) {
BufferedImage skinImage = null;
try { try {
IResource skin = Minecraft.getMinecraft().getResourceManager().getResource(textureResourceLocation); IResource skin = Minecraft.getMinecraft().getResourceManager().getResource(resource);
skinImage = TextureUtil.readBufferedImage(skin.getInputStream()); BufferedImage skinImage = TextureUtil.readBufferedImage(skin.getInputStream());
MineLittlePony.logger.debug("Obtained skin from resource location {}", textureResourceLocation); MineLittlePony.logger.debug("Obtained skin from resource location {}", resource);
// this.checkSkin(skinImage);
} catch (IOException e) {
try { return skinImage;
ITextureObject e2 = Minecraft.getMinecraft().getTextureManager().getTexture(textureResourceLocation); } catch (IOException ignored) { }
if (e2 instanceof ThreadDownloadImageData) {
skinImage = PonyFields.downloadedImage.get((ThreadDownloadImageData) e2); try {
if (skinImage != null) { ITextureObject e2 = Minecraft.getMinecraft().getTextureManager().getTexture(resource);
MineLittlePony.logger.debug("Successfully reflected downloadedImage from texture object", e);
// this.checkSkin(skinImage);
}
} else if (e2 instanceof ThreadDownloadImageETag) {
skinImage = ((ThreadDownloadImageETag) e2).getBufferedImage();
} else if (e2 instanceof DynamicTextureImage) {
skinImage = ((DynamicTextureImage) e2).getImage();
}
} catch (Exception ignored) {
if (e2 instanceof IDownloadImageData) {
return ((IDownloadImageData) e2).getBufferedImage();
} else if (e2 instanceof ThreadDownloadImageETag) {
return ((ThreadDownloadImageETag) e2).getBufferedImage();
} else if (e2 instanceof DynamicTextureImage) {
return ((DynamicTextureImage) e2).getImage();
} }
} } catch (Exception ignored) { }
return skinImage; return null;
} }
private PonyData checkSkin(BufferedImage bufferedimage) { private IPonyData checkSkin(BufferedImage bufferedimage) {
if (bufferedimage == null) return new PonyData();
MineLittlePony.logger.debug("\tStart skin check for pony #{} with image {}.", this.ponyId, bufferedimage); MineLittlePony.logger.debug("\tStart skin check for pony #{} with image {}.", this.ponyId, bufferedimage);
return PonyData.parse(bufferedimage); return PonyData.parse(bufferedimage);
} }
public boolean isPegasusFlying(EntityPlayer player) { public boolean isPegasusFlying(EntityPlayer player) {
//noinspection SimplifiableIfStatement //noinspection SimplifiableIfStatement
if (!this.metadata.getRace().hasWings()) { if (!getRace(false).hasWings()) return false;
return false;
}
return player.capabilities.isFlying || !(player.onGround || player.isRiding() || player.isOnLadder() || player.isInWater() || player.isElytraFlying()); return player.capabilities.isFlying || !(player.onGround || player.isRiding() || player.isOnLadder() || player.isInWater() || player.isElytraFlying());
} }
public PlayerModel getModel(boolean ignorePony, boolean smallArms) { public PlayerModel getModel(boolean ignorePony) {
boolean is_a_pony = false; return getRace(ignorePony).getModel().getModel(smallArms);
switch (ignorePony ? PonyLevel.BOTH : MineLittlePony.getConfig().getPonyLevel()) { }
case HUMANS:
is_a_pony = false;
break;
case BOTH:
is_a_pony = metadata.getRace() != PonyRace.HUMAN;
break;
case PONIES:
is_a_pony = true;
}
PlayerModel model; public PonyRace getRace(boolean ignorePony) {
if (is_a_pony) { return metadata.getRace().getEffectiveRace(MineLittlePony.getConfig().getPonyLevel(ignorePony));
model = smallArms ? PMAPI.ponySmall : PMAPI.pony;
} else {
model = smallArms ? PMAPI.humanSmall : PMAPI.human;
}
return model;
} }
public ResourceLocation getTexture() { public ResourceLocation getTexture() {
return this.texture; return texture;
} }
public PonyData getMetadata() { public IPonyData getMetadata() {
return metadata; return metadata;
} }
@Override @Override
public String toString() { public String toString() {
return MoreObjects.toStringHelper(this) return MoreObjects.toStringHelper(this).add("texture", texture).add("metadata", metadata).toString();
.add("texture", texture)
.add("metadata", metadata)
.toString();
} }
} }

View file

@ -8,30 +8,23 @@ import com.mumfrey.liteloader.modconfig.ExposableOptions;
@ExposableOptions(filename = "minelittlepony", strategy = ConfigStrategy.Unversioned) @ExposableOptions(filename = "minelittlepony", strategy = ConfigStrategy.Unversioned)
public class PonyConfig implements Exposable { public class PonyConfig implements Exposable {
@Expose @Expose private PonyLevel ponylevel = PonyLevel.PONIES;
private PonyLevel ponylevel = PonyLevel.PONIES; @Expose public boolean sizes = true;
@Expose @Expose public boolean snuzzles = true;
public boolean sizes = true; @Expose public boolean hd = true;
@Expose @Expose public boolean showscale = true;
public boolean snuzzles = true; @Expose public boolean villagers = true;
@Expose @Expose public boolean zombies = true;
public boolean hd = true; @Expose public boolean pigzombies = true;
@Expose @Expose public boolean skeletons = true;
public boolean showscale = true; @Expose public boolean illagers = true;
@Expose
public boolean villagers = true; public PonyLevel getPonyLevel(boolean ignorePony) {
@Expose return ignorePony ? PonyLevel.BOTH : getPonyLevel();
public boolean zombies = true; }
@Expose
public boolean pigzombies = true;
@Expose
public boolean skeletons = true;
@Expose
public boolean illagers = true;
public PonyLevel getPonyLevel() { public PonyLevel getPonyLevel() {
if (ponylevel == null) if (ponylevel == null) ponylevel = PonyLevel.PONIES;
ponylevel = PonyLevel.PONIES;
return ponylevel; return ponylevel;
} }

View file

@ -50,26 +50,32 @@ public class PonyData implements IPonyData {
this.glowColor = glowColor; this.glowColor = glowColor;
} }
@Override
public PonyRace getRace() { public PonyRace getRace() {
return race; return race;
} }
@Override
public TailLengths getTail() { public TailLengths getTail() {
return tailSize; return tailSize;
} }
@Override
public PonyGender getGender() { public PonyGender getGender() {
return gender; return gender;
} }
@Override
public PonySize getSize() { public PonySize getSize() {
return MineLittlePony.getConfig().sizes ? size : PonySize.NORMAL; return MineLittlePony.getConfig().sizes ? size : PonySize.NORMAL;
} }
@Override
public int getGlowColor() { public int getGlowColor() {
return glowColor; return glowColor;
} }
@Override
public boolean hasMagic() { public boolean hasMagic() {
return this.race != null && this.race.hasHorn() && this.glowColor != 0; return this.race != null && this.race.hasHorn() && this.glowColor != 0;
} }
@ -85,7 +91,7 @@ public class PonyData implements IPonyData {
.toString(); .toString();
} }
static PonyData parse(BufferedImage image) { static IPonyData parse(BufferedImage image) {
int racePx = TriggerPixels.RACE.readColor(image); int racePx = TriggerPixels.RACE.readColor(image);
PonyRace race = RACE_COLORS.getOrDefault(racePx, PonyRace.HUMAN); PonyRace race = RACE_COLORS.getOrDefault(racePx, PonyRace.HUMAN);

View file

@ -4,7 +4,9 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.minelittlepony.ducks.IPlayerInfo;
import com.minelittlepony.model.PMAPI; import com.minelittlepony.model.PMAPI;
import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManager;
@ -32,8 +34,9 @@ public class PonyManager implements IResourceManagerReloadListener {
private PonyConfig config; private PonyConfig config;
private Map<ResourceLocation, Pony> poniesCache = Maps.newHashMap(); private Map<ResourceLocation, Pony>
private Map<ResourceLocation, Pony> backgroudPoniesCache = Maps.newHashMap(); poniesCache = Maps.newHashMap(),
backgroudPoniesCache = Maps.newHashMap();
public PonyManager(PonyConfig config) { public PonyManager(PonyConfig config) {
this.config = config; this.config = config;
@ -46,23 +49,27 @@ public class PonyManager implements IResourceManagerReloadListener {
MineLittlePony.logger.info("Done initializing models."); MineLittlePony.logger.info("Done initializing models.");
} }
public Pony getPony(ResourceLocation skinResourceLocation, boolean slim) {
return poniesCache.computeIfAbsent(skinResourceLocation, res -> new Pony(res, slim));
}
// TODO: Slim arms
public Pony getPony(ResourceLocation skinResourceLocation) { public Pony getPony(ResourceLocation skinResourceLocation) {
return this.poniesCache.computeIfAbsent(skinResourceLocation, Pony::new); return getPony(skinResourceLocation, false);
} }
public Pony getPony(AbstractClientPlayer player) { public Pony getPony(AbstractClientPlayer player) {
Pony myLittlePony = getPony(player.getLocationSkin(), IPlayerInfo.getPlayerInfo(player).usesSlimArms());
Pony myLittlePony = this.poniesCache.computeIfAbsent(player.getLocationSkin(), res -> new Pony(player)); if (config.getPonyLevel() == PonyLevel.PONIES && myLittlePony.getMetadata().getRace().isHuman()) {
return this.getPonyFromBackgroundResourceRegistry(player);
if (config.getPonyLevel() == PonyLevel.PONIES && myLittlePony.getMetadata().getRace() == PonyRace.HUMAN) {
myLittlePony = this.getPonyFromBackgroundResourceRegistry(player);
} }
return myLittlePony; return myLittlePony;
} }
public Pony removePony(ResourceLocation location) { public Pony removePony(ResourceLocation location) {
return this.poniesCache.remove(location); return poniesCache.remove(location);
} }
private ResourceLocation getBackgroundPonyResource(UUID id) { private ResourceLocation getBackgroundPonyResource(UUID id) {
@ -78,22 +85,12 @@ public class PonyManager implements IResourceManagerReloadListener {
} }
private Pony getPonyFromBackgroundResourceRegistry(AbstractClientPlayer player) { private Pony getPonyFromBackgroundResourceRegistry(AbstractClientPlayer player) {
ResourceLocation textureResourceLocation; return backgroudPoniesCache.computeIfAbsent(getDefaultPonyResource(player), res -> new Pony(res, false));
if (player.isUser()) { }
textureResourceLocation = getDefaultSkin(player.getUniqueID());
} else {
textureResourceLocation = this.getBackgroundPonyResource(player.getUniqueID());
}
Pony myLittlePony; private ResourceLocation getDefaultPonyResource(AbstractClientPlayer player) {
if (!this.backgroudPoniesCache.containsKey(textureResourceLocation)) { if (player.isUser()) return getDefaultSkin(player.getUniqueID());
myLittlePony = new Pony(textureResourceLocation); return getBackgroundPonyResource(player.getUniqueID());
this.backgroudPoniesCache.put(textureResourceLocation, myLittlePony);
} else {
myLittlePony = this.backgroudPoniesCache.get(textureResourceLocation);
}
return myLittlePony;
} }
@Override @Override

View file

@ -1,24 +1,28 @@
package com.minelittlepony; package com.minelittlepony;
import com.minelittlepony.model.PlayerModels;
public enum PonyRace { public enum PonyRace {
HUMAN(false, false), HUMAN(PlayerModels.HUMAN, false, false),
EARTH(false, false), EARTH(PlayerModels.PONY,false, false),
PEGASUS(true, false), PEGASUS(PlayerModels.PONY, true, false),
UNICORN(false, true), UNICORN(PlayerModels.PONY, false, true),
ALICORN(true, true), ALICORN(PlayerModels.PONY, true, true),
CHANGELING(true, true), CHANGELING(PlayerModels.PONY, true, true),
ZEBRA(false, false), ZEBRA(PlayerModels.PONY, false, false),
REFORMED_CHANGELING(true, true), REFORMED_CHANGELING(PlayerModels.PONY, true, true),
GRIFFIN(true, false), GRIFFIN(PlayerModels.PONY, true, false),
HIPPOGRIFF(true, false); HIPPOGRIFF(PlayerModels.PONY, true, false);
private boolean wings; private boolean wings, horn;
private boolean horn;
PonyRace(boolean wings, boolean horn) { private PlayerModels model;
PonyRace(PlayerModels model, boolean wings, boolean horn) {
this.wings = wings; this.wings = wings;
this.horn = horn; this.horn = horn;
this.model = model;
} }
public boolean hasHorn() { public boolean hasHorn() {
@ -28,4 +32,17 @@ public enum PonyRace {
public boolean hasWings() { public boolean hasWings() {
return wings; return wings;
} }
public boolean isHuman() {
return this == HUMAN;
}
public PlayerModels getModel() {
return model;
}
public PonyRace getEffectiveRace(PonyLevel level) {
if (level == PonyLevel.HUMANS) return HUMAN;
return this;
}
} }

View file

@ -1,8 +1,23 @@
package com.minelittlepony; package com.minelittlepony;
public enum PonySize { public enum PonySize {
NORMAL, NORMAL(0.4f, 1f),
LARGE, LARGE(0.5f, 0.8f),
FOAL, FOAL(0.25f, 0.8f),
TALL TALL(0.45f, 1f);
private float shadowSize, scale;
PonySize(float shadowSz, float scaleF) {
shadowSize = shadowSz;
scale = scaleF;
}
public float getShadowSize() {
return shadowSize;
}
public float getScaleFactor() {
return scale;
}
} }

View file

@ -0,0 +1,7 @@
package com.minelittlepony.ducks;
import java.awt.image.BufferedImage;
public interface IDownloadImageData {
BufferedImage getBufferedImage();
}

View file

@ -0,0 +1,16 @@
package com.minelittlepony.ducks;
import com.minelittlepony.Pony;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
public interface IPlayerInfo {
Pony getPony();
boolean usesSlimArms();
public static IPlayerInfo getPlayerInfo(AbstractClientPlayer player) {
return (IPlayerInfo)Minecraft.getMinecraft().getConnection().getPlayerInfo(player.getUniqueID());
}
}

View file

@ -0,0 +1,7 @@
package com.minelittlepony.ducks;
import net.minecraft.client.renderer.entity.RenderPlayer;
public interface IRenderManager {
void addPlayerSkin(String key, RenderPlayer render);
}

View file

@ -4,5 +4,5 @@ import com.minelittlepony.model.PlayerModel;
public interface IRenderPony { public interface IRenderPony {
PlayerModel getPony(); PlayerModel getPlayerModel();
} }

View file

@ -26,14 +26,14 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> {
@Override @Override
public ModelPlayer getEntityModel(EntityPonyModel playermodel) { public ModelPlayer getEntityModel(EntityPonyModel playermodel) {
ResourceLocation loc = this.getEntityTexture(playermodel); ResourceLocation loc = getEntityTexture(playermodel);
if (loc == null) { if (loc == null) {
return super.getEntityModel(playermodel); return super.getEntityModel(playermodel);
} }
Pony thePony = MineLittlePony.getInstance().getManager().getPony(loc); Pony thePony = MineLittlePony.getInstance().getManager().getPony(loc);
// TODO small arms PlayerModel pm = thePony.getModel(true);
PlayerModel pm = thePony.getModel(true, false);
pm.apply(thePony.getMetadata()); pm.apply(thePony.getMetadata());
return pm.getModel(); return pm.getModel();
@ -46,8 +46,7 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> {
return new AbstractPonyLayer<EntityLivingBase>(this, elytra) { return new AbstractPonyLayer<EntityLivingBase>(this, elytra) {
@Override @Override
public void doPonyRender(EntityLivingBase entityBase, float swing, float swingAmount, float ticks, float age, float yaw, float head, public void doPonyRender(EntityLivingBase entityBase, float swing, float swingAmount, float ticks, float age, float yaw, float head, float scale) {
float scale) {
EntityPonyModel entity = (EntityPonyModel) entityBase; EntityPonyModel entity = (EntityPonyModel) entityBase;

View file

@ -0,0 +1,46 @@
package com.minelittlepony.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.Pony;
import com.minelittlepony.ducks.IPlayerInfo;
import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.util.ResourceLocation;
@Mixin(NetworkPlayerInfo.class)
public abstract class MixinNetworkPlayerInfo implements IPlayerInfo {
@Shadow
private String skinType;
@Shadow
public abstract ResourceLocation getLocationSkin();
@Inject(method = "getSkinType()Ljava/lang/String;", at = @At("RETURN"))
private void getSkinType(CallbackInfoReturnable<String> info) {
ResourceLocation skin = getLocationSkin();
if (skin != null) {
info.setReturnValue(getPony(skin).getRace(false).getModel().getId(usesSlimArms()));
}
}
protected Pony getPony(ResourceLocation skin) {
return MineLittlePony.getInstance().getManager().getPony(skin, usesSlimArms());
}
@Override
public Pony getPony() {
return getPony(getLocationSkin());
}
@Override
public boolean usesSlimArms() {
return skinType == "slim";
}
}

View file

@ -0,0 +1,22 @@
package com.minelittlepony.mixin;
import java.util.Map;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import com.minelittlepony.ducks.IRenderManager;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderPlayer;
@Mixin(RenderManager.class)
public abstract class MixinRenderManager implements IRenderManager {
@Shadow @Final
private Map<String, RenderPlayer> skinMap;
public void addPlayerSkin(String key, RenderPlayer render) {
skinMap.put(key, render);
}
}

View file

@ -1,261 +0,0 @@
package com.minelittlepony.mixin;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.Pony;
import com.minelittlepony.PonyRace;
import com.minelittlepony.PonySize;
import com.minelittlepony.ducks.IRenderPony;
import com.minelittlepony.model.PMAPI;
import com.minelittlepony.model.PlayerModel;
import com.minelittlepony.model.pony.ModelHumanPlayer;
import com.minelittlepony.model.pony.ModelPlayerPony;
import com.minelittlepony.renderer.layer.LayerEntityOnPonyShoulder;
import com.minelittlepony.renderer.layer.LayerHeldPonyItem;
import com.minelittlepony.renderer.layer.LayerPonyArmor;
import com.minelittlepony.renderer.layer.LayerPonyCape;
import com.minelittlepony.renderer.layer.LayerPonyCustomHead;
import com.minelittlepony.renderer.layer.LayerPonyElytra;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.model.ModelPlayer;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.client.renderer.entity.layers.LayerArrow;
import net.minecraft.util.ResourceLocation;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(RenderPlayer.class)
public abstract class MixinRenderPlayer extends RenderLivingBase<AbstractClientPlayer> implements IRenderPony {
@Shadow
@Final
private boolean smallArms;
private PlayerModel playerModel;
private Pony thePony;
@SuppressWarnings("ConstantConditions")
private MixinRenderPlayer(RenderManager renderManager) {
super(renderManager, null, 0.5F);
}
@Inject(
method = "<init>(Lnet/minecraft/client/renderer/entity/RenderManager;Z)V",
at = @At("RETURN"))
private void init(RenderManager renderManager, boolean useSmallArms, CallbackInfo ci) {
this.playerModel = smallArms ? PMAPI.ponySmall : PMAPI.pony;
this.mainModel = this.playerModel.getModel();
this.layerRenderers.clear();
this.addLayer(new LayerPonyArmor(this));
this.addLayer(new LayerHeldPonyItem(this));
this.addLayer(new LayerArrow(this));
this.addLayer(new LayerPonyCape(this));
this.addLayer(new LayerPonyCustomHead(this));
this.addLayer(new LayerPonyElytra(this));
this.addLayer(new LayerEntityOnPonyShoulder(renderManager, this));
}
@Inject(
method = "doRender(Lnet/minecraft/client/entity/AbstractClientPlayer;DDDFF)V",
at = @At("HEAD"))
private void onDoRender(AbstractClientPlayer player, double x, double y, double z, float yaw, float partialTicks, CallbackInfo ci) {
updateModel(player);
this.playerModel.getModel().isSneak = player.isSneaking();
this.playerModel.getModel().isFlying = thePony.isPegasusFlying(player);
this.playerModel.getModel().isSleeping = player.isPlayerSleeping();
if (MineLittlePony.getConfig().showscale && this.playerModel.getModel().metadata.getRace() != PonyRace.HUMAN) {
PonySize size = thePony.getMetadata().getSize();
if (size == PonySize.FOAL) {
this.shadowSize = 0.25F;
} else if (size == PonySize.NORMAL) {
this.shadowSize = 0.4F;
} else if (size == PonySize.TALL) {
this.shadowSize = 0.45F;
} else {
this.shadowSize = 0.5F;
}
} else {
this.shadowSize = 0.5F;
}
}
@Inject(
method = "renderLivingAt(Lnet/minecraft/client/entity/AbstractClientPlayer;DDD)V",
at = @At("RETURN"))
private void setupPlayerScale(AbstractClientPlayer player, double xPosition, double yPosition, double zPosition, CallbackInfo ci) {
if (MineLittlePony.getConfig().showscale && !(playerModel.getModel() instanceof ModelHumanPlayer)) {
PonySize size = thePony.getMetadata().getSize();
if (size == PonySize.LARGE) {
GlStateManager.scale(0.9F, 0.9F, 0.9F);
} else if (size == PonySize.NORMAL || size == PonySize.FOAL) {
GlStateManager.scale(0.8F, 0.8F, 0.8F);
}
}
}
@Inject(
method = "renderRightArm(Lnet/minecraft/client/entity/AbstractClientPlayer;)V",
at = @At("HEAD"))
private void onRenderRightArm(AbstractClientPlayer player, CallbackInfo ci) {
updateModel(player);
bindEntityTexture(player);
}
@Inject(
method = "renderLeftArm(Lnet/minecraft/client/entity/AbstractClientPlayer;)V",
at = @At("HEAD"))
private void onRenderLeftArm(AbstractClientPlayer player, CallbackInfo ci) {
updateModel(player);
bindEntityTexture(player);
}
@Redirect(
method = "renderLeftArm(Lnet/minecraft/client/entity/AbstractClientPlayer;)V",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/model/ModelPlayer;bipedLeftArm:Lnet/minecraft/client/model/ModelRenderer;",
opcode = Opcodes.GETFIELD),
require = 2)
private ModelRenderer redirectLeftArm(ModelPlayer mr) {
return this.playerModel.getModel().steveLeftArm;
}
@Redirect(
method = "renderLeftArm(Lnet/minecraft/client/entity/AbstractClientPlayer;)V",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/model/ModelPlayer;bipedLeftArmwear:Lnet/minecraft/client/model/ModelRenderer;",
opcode = Opcodes.GETFIELD),
require = 2)
private ModelRenderer redirectLeftArmwear(ModelPlayer mr) {
return this.playerModel.getModel().steveLeftArmwear;
}
@Redirect(
method = "renderRightArm(Lnet/minecraft/client/entity/AbstractClientPlayer;)V",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/model/ModelPlayer;bipedRightArm:Lnet/minecraft/client/model/ModelRenderer;",
opcode = Opcodes.GETFIELD),
require = 2)
private ModelRenderer redirectRightArm(ModelPlayer mr) {
return this.playerModel.getModel().steveRightArm;
}
@Redirect(
method = "renderRightArm(Lnet/minecraft/client/entity/AbstractClientPlayer;)V",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/model/ModelPlayer;bipedRightArmwear:Lnet/minecraft/client/model/ModelRenderer;",
opcode = Opcodes.GETFIELD),
require = 2)
private ModelRenderer redirectRightArmwear(ModelPlayer mr) {
return this.playerModel.getModel().steveRightArmwear;
}
@Inject(
method = "applyRotations(Lnet/minecraft/client/entity/AbstractClientPlayer;FFF)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/entity/RenderLivingBase;"
+ "applyRotations(Lnet/minecraft/entity/EntityLivingBase;FFF)V",
ordinal = 1,
shift = Shift.AFTER))
private void onRotateCorpse(AbstractClientPlayer player, float yaw, float pitch, float ticks, CallbackInfo ci) {
if (this.mainModel instanceof ModelPlayerPony) {
// require arms to be stretched out (sorry mud ponies, no flight
// skills for you)
if (!((ModelPlayerPony) this.mainModel).rainboom) {
this.playerModel.getModel().motionPitch = 0;
return;
}
double motionX = player.posX - player.prevPosX;
double motionY = player.posY - player.prevPosY;
double motionZ = player.posZ - player.prevPosZ;
if (player.onGround) {
motionY = 0;
}
double dist = Math.sqrt(motionX * motionX + motionZ * motionZ);
double angle = Math.atan2(motionY, dist);
if (!player.capabilities.isFlying) {
if (angle > 0) {
angle = 0;
} else {
angle /= 2;
}
}
if (angle > Math.PI / 3) {
angle = Math.PI / 3;
}
if (angle < -Math.PI / 3) {
angle = -Math.PI / 3;
}
this.playerModel.getModel().motionPitch = (float) Math.toDegrees(angle);
GlStateManager.rotate((float) Math.toDegrees(angle), 1F, 0F, 0F);
}
}
@Redirect(
method = "applyRotations(Lnet/minecraft/client/entity/AbstractClientPlayer;FFF)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/renderer/GlStateManager;rotate(FFFF)V",
ordinal = 3))
private void rotateRedirect(float f1, float f2, float f3, float f4) {
boolean isPony = this.playerModel.getModel() instanceof ModelPlayerPony;
if (isPony) {
f1 += 90;
}
GlStateManager.rotate(f1, f2, f3, f4);
if (isPony) {
GlStateManager.translate(0, -1, 0);
}
}
private void updateModel(AbstractClientPlayer player) {
this.thePony = MineLittlePony.getInstance().getManager().getPony(player);
this.playerModel = this.getModel(player);
this.mainModel = this.playerModel.getModel();
this.playerModel.apply(thePony.getMetadata());
}
@Redirect(
method = "getEntityTexture(Lnet/minecraft/client/entity/AbstractClientPlayer;)Lnet/minecraft/util/ResourceLocation;",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/AbstractClientPlayer;getLocationSkin()Lnet/minecraft/util/ResourceLocation;"))
private ResourceLocation redirectEntityTexture(AbstractClientPlayer player) {
Pony thePony = MineLittlePony.getInstance().getManager().getPony(player);
return thePony.getTexture();
}
private PlayerModel getModel(AbstractClientPlayer player) {
ResourceLocation skin = getEntityTexture(player);
Pony thePony = MineLittlePony.getInstance().getManager().getPony(skin);
return thePony.getModel(false, this.smallArms);
}
@Override
public PlayerModel getPony() {
return this.playerModel;
}
}

View file

@ -0,0 +1,23 @@
package com.minelittlepony.mixin;
import java.awt.image.BufferedImage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import com.minelittlepony.ducks.IDownloadImageData;
import net.minecraft.client.renderer.ThreadDownloadImageData;
import net.minecraft.client.renderer.texture.SimpleTexture;
import net.minecraft.util.ResourceLocation;
@Mixin(ThreadDownloadImageData.class)
public abstract class MixinThreadDownloadImageData extends SimpleTexture implements IDownloadImageData {
private MixinThreadDownloadImageData(ResourceLocation textureResourceLocation) {
super(textureResourceLocation);
}
@Accessor("bufferedImage")
public abstract BufferedImage getBufferedImage();
}

View file

@ -1,13 +1,13 @@
package com.minelittlepony.model; package com.minelittlepony.model;
import com.minelittlepony.PonyData; import com.minelittlepony.IPonyData;
public abstract class AbstractArmor { public abstract class AbstractArmor {
public AbstractPonyModel modelArmorChestplate; public AbstractPonyModel modelArmorChestplate;
public AbstractPonyModel modelArmor; public AbstractPonyModel modelArmor;
public void apply(PonyData meta) { public void apply(IPonyData meta) {
modelArmorChestplate.metadata = meta; modelArmorChestplate.metadata = meta;
modelArmor.metadata = meta; modelArmor.metadata = meta;
} }

View file

@ -1,8 +1,10 @@
package com.minelittlepony.model; package com.minelittlepony.model;
import com.minelittlepony.IPonyData;
import com.minelittlepony.PonyData; import com.minelittlepony.PonyData;
import com.minelittlepony.PonySize; import com.minelittlepony.PonySize;
import com.minelittlepony.model.pony.ModelPlayerPony; import com.minelittlepony.model.pony.ModelPlayerPony;
import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelPlayer; import net.minecraft.client.model.ModelPlayer;
import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.model.ModelRenderer;
@ -28,7 +30,7 @@ public abstract class AbstractPonyModel extends ModelPlayer {
public boolean isFlying; public boolean isFlying;
public boolean isSleeping; public boolean isSleeping;
public PonyData metadata = new PonyData(); public IPonyData metadata = new PonyData();
public float motionPitch; public float motionPitch;

View file

@ -17,12 +17,14 @@ public final class PMAPI {
public static final PlayerModel pony = new PlayerModel(new ModelPlayerPony(false)).setArmor(new PonyArmors()); public static final PlayerModel pony = new PlayerModel(new ModelPlayerPony(false)).setArmor(new PonyArmors());
public static final PlayerModel ponySmall = new PlayerModel(new ModelPlayerPony(true)).setArmor(new PonyArmors()); public static final PlayerModel ponySmall = new PlayerModel(new ModelPlayerPony(true)).setArmor(new PonyArmors());
public static final PlayerModel human = new PlayerModel(new ModelHumanPlayer(false)).setArmor(new HumanArmors());
public static final PlayerModel humanSmall = new PlayerModel(new ModelHumanPlayer(true)).setArmor(new HumanArmors());
public static final PlayerModel zombie = new PlayerModel(new ModelZombiePony()).setArmor(new ZombiePonyArmors()); public static final PlayerModel zombie = new PlayerModel(new ModelZombiePony()).setArmor(new ZombiePonyArmors());
public static final PlayerModel skeleton = new PlayerModel(new ModelSkeletonPony()).setArmor(new SkeletonPonyArmors()); public static final PlayerModel skeleton = new PlayerModel(new ModelSkeletonPony()).setArmor(new SkeletonPonyArmors());
public static final PlayerModel villager = new PlayerModel(new ModelVillagerPony()).setArmor(new PonyArmors()); public static final PlayerModel villager = new PlayerModel(new ModelVillagerPony()).setArmor(new PonyArmors());
public static final PlayerModel illager = new PlayerModel(new ModelIllagerPony()).setArmor(new PonyArmors()); public static final PlayerModel illager = new PlayerModel(new ModelIllagerPony()).setArmor(new PonyArmors());
public static final PlayerModel human = new PlayerModel(new ModelHumanPlayer(false)).setArmor(new HumanArmors());
public static final PlayerModel humanSmall = new PlayerModel(new ModelHumanPlayer(true)).setArmor(new HumanArmors());
public static void init() { public static void init() {
for (Field field : PMAPI.class.getFields()) { for (Field field : PMAPI.class.getFields()) {

View file

@ -5,25 +5,19 @@ import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
// TODO: Break this down into ModelWing (one for each side)
public class PegasusWings extends ModelBase implements PonyModelConstants { public class PegasusWings extends ModelBase implements PonyModelConstants {
private final AbstractPonyModel pony; private final AbstractPonyModel pony;
public ModelRenderer[] leftWing; public ModelRenderer[] leftWing = new ModelRenderer[3], rightWing = new ModelRenderer[3],
public ModelRenderer[] rightWing; leftWingExt = new ModelRenderer[6], rightWingExt = new ModelRenderer[6];
public ModelRenderer[] leftWingExt;
public ModelRenderer[] rightWingExt;
public PegasusWings(AbstractPonyModel pony, float yOffset, float stretch) { public PegasusWings(AbstractPonyModel pony, float yOffset, float stretch) {
this.pony = pony; this.pony = pony;
this.leftWing = new ModelRenderer[3]; // TODO: Don't add the model to the pony if you're just going to remove it again.
this.rightWing = new ModelRenderer[3];
this.leftWingExt = new ModelRenderer[6];
this.rightWingExt = new ModelRenderer[6];
for (int i = 0; i < leftWing.length; i++) { for (int i = 0; i < leftWing.length; i++) {
this.leftWing[i] = new ModelRenderer(pony, 56, 32); this.leftWing[i] = new ModelRenderer(pony, 56, 32);
this.pony.boxList.remove(this.leftWing[i]); this.pony.boxList.remove(this.leftWing[i]);
@ -46,21 +40,27 @@ public class PegasusWings extends ModelBase implements PonyModelConstants {
this.leftWing[0].addBox(4.0F, 5.0F, 2.0F, 2, 6, 2, stretch); this.leftWing[0].addBox(4.0F, 5.0F, 2.0F, 2, 6, 2, stretch);
this.leftWing[0].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); this.leftWing[0].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z);
this.leftWing[0].rotateAngleX = ROTATE_90; this.leftWing[0].rotateAngleX = ROTATE_90;
this.leftWing[1].addBox(4.0F, 5.0F, 4.0F, 2, 8, 2, stretch); this.leftWing[1].addBox(4.0F, 5.0F, 4.0F, 2, 8, 2, stretch);
this.leftWing[1].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); this.leftWing[1].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z);
this.leftWing[1].rotateAngleX = ROTATE_90; this.leftWing[1].rotateAngleX = ROTATE_90;
this.leftWing[2].addBox(4.0F, 5.0F, 6.0F, 2, 6, 2, stretch); this.leftWing[2].addBox(4.0F, 5.0F, 6.0F, 2, 6, 2, stretch);
this.leftWing[2].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); this.leftWing[2].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z);
this.leftWing[2].rotateAngleX = ROTATE_90; this.leftWing[2].rotateAngleX = ROTATE_90;
this.rightWing[0].addBox(-6.0F, 5.0F, 2.0F, 2, 6, 2, stretch); this.rightWing[0].addBox(-6.0F, 5.0F, 2.0F, 2, 6, 2, stretch);
this.rightWing[0].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); this.rightWing[0].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z);
this.rightWing[0].rotateAngleX = ROTATE_90; this.rightWing[0].rotateAngleX = ROTATE_90;
this.rightWing[1].addBox(-6.0F, 5.0F, 4.0F, 2, 8, 2, stretch); this.rightWing[1].addBox(-6.0F, 5.0F, 4.0F, 2, 8, 2, stretch);
this.rightWing[1].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); this.rightWing[1].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z);
this.rightWing[1].rotateAngleX = ROTATE_90; this.rightWing[1].rotateAngleX = ROTATE_90;
this.rightWing[2].addBox(-6.0F, 5.0F, 6.0F, 2, 6, 2, stretch); this.rightWing[2].addBox(-6.0F, 5.0F, 6.0F, 2, 6, 2, stretch);
this.rightWing[2].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); this.rightWing[2].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z);
this.rightWing[2].rotateAngleX = ROTATE_90; this.rightWing[2].rotateAngleX = ROTATE_90;
this.leftWingExt[0].addBox(-0.5F, 6.0F, 0.0F, 1, 8, 2, stretch + 0.1F); this.leftWingExt[0].addBox(-0.5F, 6.0F, 0.0F, 1, 8, 2, stretch + 0.1F);
this.leftWingExt[0].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, LEFT_WING_EXT_RP_Z); this.leftWingExt[0].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, LEFT_WING_EXT_RP_Z);
this.leftWingExt[1].addBox(-0.5F, -1.2F, -0.2F, 1, 8, 2, stretch - 0.2F); this.leftWingExt[1].addBox(-0.5F, -1.2F, -0.2F, 1, 8, 2, stretch - 0.2F);
@ -163,19 +163,20 @@ public class PegasusWings extends ModelBase implements PonyModelConstants {
this.rightWingExt[i].rotateAngleZ = RIGHT_WING_ROTATE_ANGLE_Z_SNEAK; this.rightWingExt[i].rotateAngleZ = RIGHT_WING_ROTATE_ANGLE_Z_SNEAK;
} }
} }
// TODO: Combine each wing into one ModelRenderer with multiple boxes, not multiple ModelRenderers each with one box.
private void unsneak(float tick) { private void unsneak(float tick) {
if (pony.isFlying) { if (pony.isFlying) {
float WingRotateAngleZ = MathHelper.sin(tick * 0.536F) * 1.0F; float WingRotateAngleZ = (MathHelper.sin(tick * 0.536F) * 1.0F) + ROTATE_270 + 0.4F;
for (ModelRenderer aLeftWingExt : this.leftWingExt) { for (ModelRenderer aLeftWingExt : this.leftWingExt) {
aLeftWingExt.rotateAngleX = EXT_WING_ROTATE_ANGLE_X; aLeftWingExt.rotateAngleX = EXT_WING_ROTATE_ANGLE_X;
aLeftWingExt.rotateAngleZ = -WingRotateAngleZ - ROTATE_270 - 0.4F; aLeftWingExt.rotateAngleZ = -WingRotateAngleZ;
} }
for (ModelRenderer aRightWingExt : this.rightWingExt) { for (ModelRenderer aRightWingExt : this.rightWingExt) {
aRightWingExt.rotateAngleX = EXT_WING_ROTATE_ANGLE_X; aRightWingExt.rotateAngleX = EXT_WING_ROTATE_ANGLE_X;
aRightWingExt.rotateAngleZ = WingRotateAngleZ + ROTATE_270 + 0.4F; aRightWingExt.rotateAngleZ = WingRotateAngleZ;
} }
} }
} }

View file

@ -1,6 +1,6 @@
package com.minelittlepony.model; package com.minelittlepony.model;
import com.minelittlepony.PonyData; import com.minelittlepony.IPonyData;
public class PlayerModel { public class PlayerModel {
@ -31,7 +31,7 @@ public class PlayerModel {
return armor; return armor;
} }
public void apply(PonyData meta) { public void apply(IPonyData meta) {
model.metadata = meta; model.metadata = meta;
armor.apply(meta); armor.apply(meta);
} }

View file

@ -0,0 +1,27 @@
package com.minelittlepony.model;
public class PlayerModels {
public static final PlayerModels
HUMAN = new PlayerModels("default", "slim", PMAPI.human, PMAPI.humanSmall),
PONY = new PlayerModels("pony", "slimpony", PMAPI.pony, PMAPI.ponySmall);
private final PlayerModel normal, slim;
private final String normalKey, slimKey;
public PlayerModels(String normalKey, String slimKey, PlayerModel normal, PlayerModel slim) {
this.normalKey = normalKey;
this.slimKey = slimKey;
this.normal = normal;
this.slim = slim;
}
public PlayerModel getModel(boolean slim) {
return slim ? this.slim : this.normal;
}
public String getId(boolean useSlimArms) {
return useSlimArms ? slimKey : normalKey;
}
}

View file

@ -1,6 +1,6 @@
package com.minelittlepony.model; package com.minelittlepony.model;
import com.minelittlepony.PonyData; import com.minelittlepony.IPonyData;
import com.minelittlepony.renderer.HornGlowRenderer; import com.minelittlepony.renderer.HornGlowRenderer;
import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.model.ModelRenderer;
@ -37,7 +37,7 @@ public class UnicornHorn extends ModelBase implements PonyModelConstants {
@Override @Override
public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { public void render(Entity entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
PonyData data = pony.metadata; IPonyData data = pony.metadata;
if (data.getRace().hasHorn()) { if (data.getRace().hasHorn()) {
this.horn.render(scale); this.horn.render(scale);

View file

@ -5,3 +5,5 @@ package com.minelittlepony.model;
import mcp.MethodsReturnNonnullByDefault; import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
// TODO: Class/Enum/Interface names are inconsistent.

View file

@ -5,3 +5,5 @@ package com.minelittlepony;
import mcp.MethodsReturnNonnullByDefault; import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
// TODO: Code style is inconsistent

View file

@ -66,7 +66,7 @@ public abstract class RenderPonyMob<T extends EntityLiving> extends RenderLiving
} }
@Override @Override
public PlayerModel getPony() { public PlayerModel getPlayerModel() {
return playerModel; return playerModel;
} }

View file

@ -26,8 +26,8 @@ public class RenderPonySkeleton<Skeleton extends AbstractSkeleton> extends Rende
this.addLayer(new LayerBipedArmor(this) { this.addLayer(new LayerBipedArmor(this) {
@Override @Override
protected void initArmor() { protected void initArmor() {
this.modelLeggings = getPony().getArmor().modelArmor; this.modelLeggings = getPlayerModel().getArmor().modelArmor;
this.modelArmor = getPony().getArmor().modelArmorChestplate; this.modelArmor = getPlayerModel().getArmor().modelArmorChestplate;
} }
}); });
} }

View file

@ -1,11 +1,12 @@
package com.minelittlepony.renderer.layer; package com.minelittlepony.renderer.layer;
import com.minelittlepony.PonyData; import com.minelittlepony.IPonyData;
import com.minelittlepony.ducks.IRenderItem; import com.minelittlepony.ducks.IRenderItem;
import com.minelittlepony.ducks.IRenderPony; import com.minelittlepony.ducks.IRenderPony;
import com.minelittlepony.model.AbstractPonyModel; import com.minelittlepony.model.AbstractPonyModel;
import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.BodyPart;
import com.minelittlepony.model.pony.ModelPlayerPony; import com.minelittlepony.model.pony.ModelPlayerPony;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelBiped;
@ -81,7 +82,7 @@ public class LayerHeldPonyItem extends AbstractPonyLayer<EntityLivingBase> {
Minecraft.getMinecraft().getItemRenderer().renderItemSide(entity, drop, transform, isLeft); Minecraft.getMinecraft().getItemRenderer().renderItemSide(entity, drop, transform, isLeft);
if (isUnicorn) { if (isUnicorn) {
PonyData metadata = ((AbstractPonyModel) this.getRenderer().getMainModel()).metadata; IPonyData metadata = ((AbstractPonyModel) this.getRenderer().getMainModel()).metadata;
this.renderItemGlow(entity, drop, transform, hand, metadata.getGlowColor()); this.renderItemGlow(entity, drop, transform, hand, metadata.getGlowColor());
} }
GlStateManager.popMatrix(); GlStateManager.popMatrix();
@ -93,7 +94,7 @@ public class LayerHeldPonyItem extends AbstractPonyLayer<EntityLivingBase> {
} }
protected void translateToHand(EnumHandSide hand) { protected void translateToHand(EnumHandSide hand) {
AbstractPonyModel thePony = ((IRenderPony) this.getRenderer()).getPony().getModel(); AbstractPonyModel thePony = ((IRenderPony) this.getRenderer()).getPlayerModel().getModel();
if (thePony.metadata.hasMagic()) { if (thePony.metadata.hasMagic()) {
ModelPlayerPony playerModel = (ModelPlayerPony) thePony; ModelPlayerPony playerModel = (ModelPlayerPony) thePony;
ModelRenderer unicornarm = hand == EnumHandSide.LEFT ? playerModel.unicornArmLeft : playerModel.unicornArmRight; ModelRenderer unicornarm = hand == EnumHandSide.LEFT ? playerModel.unicornArmLeft : playerModel.unicornArmRight;

View file

@ -40,7 +40,7 @@ public class LayerPonyArmor extends AbstractPonyLayer<EntityLivingBase> {
@Override @Override
public void doPonyRender(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float ticks, float ageInTicks, float netHeadYaw, float headPitch, float scale) { public void doPonyRender(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float ticks, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
pony = ((IRenderPony) getRenderer()).getPony(); pony = ((IRenderPony) getRenderer()).getPlayerModel();
renderArmor(entity, limbSwing, limbSwingAmount, ticks, ageInTicks, netHeadYaw, headPitch, scale, EntityEquipmentSlot.FEET); renderArmor(entity, limbSwing, limbSwingAmount, ticks, ageInTicks, netHeadYaw, headPitch, scale, EntityEquipmentSlot.FEET);
renderArmor(entity, limbSwing, limbSwingAmount, ticks, ageInTicks, netHeadYaw, headPitch, scale, EntityEquipmentSlot.LEGS); renderArmor(entity, limbSwing, limbSwingAmount, ticks, ageInTicks, netHeadYaw, headPitch, scale, EntityEquipmentSlot.LEGS);
renderArmor(entity, limbSwing, limbSwingAmount, ticks, ageInTicks, netHeadYaw, headPitch, scale, EntityEquipmentSlot.CHEST); renderArmor(entity, limbSwing, limbSwingAmount, ticks, ageInTicks, netHeadYaw, headPitch, scale, EntityEquipmentSlot.CHEST);

View file

@ -24,7 +24,7 @@ public class LayerPonyCape extends AbstractPonyLayer<AbstractClientPlayer> {
@Override @Override
public void doPonyRender(@Nonnull AbstractClientPlayer clientPlayer, float p2, float p3, float ticks, float p5, float p6, float p7, float scale) { public void doPonyRender(@Nonnull AbstractClientPlayer clientPlayer, float p2, float p3, float ticks, float p5, float p6, float p7, float scale) {
PlayerModel model = ((IRenderPony) getRenderer()).getPony(); PlayerModel model = ((IRenderPony) getRenderer()).getPlayerModel();
if (clientPlayer.hasPlayerInfo() && !clientPlayer.isInvisible() if (clientPlayer.hasPlayerInfo() && !clientPlayer.isInvisible()
&& clientPlayer.isWearing(EnumPlayerModelParts.CAPE) && clientPlayer.getLocationCape() != null && clientPlayer.isWearing(EnumPlayerModelParts.CAPE) && clientPlayer.getLocationCape() != null
&& clientPlayer.getItemStackFromSlot(EntityEquipmentSlot.CHEST).getItem() != Items.ELYTRA) { && clientPlayer.getItemStackFromSlot(EntityEquipmentSlot.CHEST).getItem() != Items.ELYTRA) {

View file

@ -98,7 +98,7 @@ public class LayerPonyCustomHead implements LayerRenderer<EntityLivingBase> {
} }
private PlayerModel getModel() { private PlayerModel getModel() {
return ((IRenderPony) renderer).getPony(); return ((IRenderPony) renderer).getPlayerModel();
} }
@Override @Override

View file

@ -30,7 +30,7 @@ public class LayerPonyElytra extends AbstractPonyLayer<EntityLivingBase> {
@Override @Override
public void doPonyRender(@Nonnull EntityLivingBase entity, float swing, float swingAmount, float ticks, float age, float yaw, float head, float scale) { public void doPonyRender(@Nonnull EntityLivingBase entity, float swing, float swingAmount, float ticks, float age, float yaw, float head, float scale) {
AbstractPonyModel model = ((IRenderPony) this.getRenderer()).getPony().getModel(); AbstractPonyModel model = ((IRenderPony) this.getRenderer()).getPlayerModel().getModel();
ItemStack itemstack = entity.getItemStackFromSlot(EntityEquipmentSlot.CHEST); ItemStack itemstack = entity.getItemStackFromSlot(EntityEquipmentSlot.CHEST);

View file

@ -0,0 +1,158 @@
package com.minelittlepony.renderer.player;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.Pony;
import com.minelittlepony.ducks.IRenderManager;
import com.minelittlepony.ducks.IRenderPony;
import com.minelittlepony.model.AbstractPonyModel;
import com.minelittlepony.model.PlayerModel;
import com.minelittlepony.model.PlayerModels;
import com.minelittlepony.model.pony.ModelPlayerPony;
import com.minelittlepony.renderer.layer.LayerEntityOnPonyShoulder;
import com.minelittlepony.renderer.layer.LayerHeldPonyItem;
import com.minelittlepony.renderer.layer.LayerPonyArmor;
import com.minelittlepony.renderer.layer.LayerPonyCape;
import com.minelittlepony.renderer.layer.LayerPonyCustomHead;
import com.minelittlepony.renderer.layer.LayerPonyElytra;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.client.renderer.entity.layers.LayerArrow;
public abstract class RenderPonyBase extends RenderPlayer implements IRenderPony {
protected final boolean smallArms;
private PlayerModel playerModel;
private AbstractPonyModel ponyModel;
private Pony pony;
public RenderPonyBase(RenderManager manager, boolean useSmallArms, PlayerModels model) {
super(manager, useSmallArms);
smallArms = useSmallArms;
setPlayerModel(model.getModel(useSmallArms));
layerRenderers.clear();
addExtraLayers();
((IRenderManager)manager).addPlayerSkin(model.getId(useSmallArms), this);
}
protected void addExtraLayers() {
addLayer(new LayerPonyArmor(this));
addLayer(new LayerHeldPonyItem(this));
addLayer(new LayerArrow(this));
addLayer(new LayerPonyCape(this));
addLayer(new LayerPonyCustomHead(this));
addLayer(new LayerPonyElytra(this));
addLayer(new LayerEntityOnPonyShoulder(renderManager, this));
}
@Override
protected void renderLivingAt(AbstractClientPlayer player, double x, double y, double z) {
float s = getScaleFactor();
GlStateManager.scale(s, s, s);
super.renderLivingAt(player, x, y, z);
}
@Override
public void doRender(AbstractClientPlayer player, double x, double y, double z, float entityYaw, float partialTicks) {
updateModel(player);
ponyModel.isSneak = player.isSneaking();
ponyModel.isSleeping = player.isPlayerSleeping();
ponyModel.isFlying = pony.isPegasusFlying(player);
shadowSize = getPonyShadowScale();
super.doRender(player, x, y, z, entityYaw, partialTicks);
}
@Override
public void renderRightArm(AbstractClientPlayer player) {
updateModel(player);
super.renderRightArm(player);
}
@Override
public void renderLeftArm(AbstractClientPlayer player) {
updateModel(player);
super.renderLeftArm(player);
}
@Override
protected void applyRotations(AbstractClientPlayer player, float yaw, float pitch, float ticks) {
super.applyRotations(player, yaw, pitch, ticks);
if (player.isElytraFlying()) {
transformFlying(player, yaw, pitch, ticks);
return;
}
if (player.isEntityAlive() && player.isPlayerSleeping()) return;
// require arms to be stretched out (sorry mud ponies, no flight skills for you)
if (!((ModelPlayerPony) ponyModel).rainboom) {
ponyModel.motionPitch = 0;
return;
}
double motionX = player.posX - player.prevPosX;
double motionY = player.posY - player.prevPosY;
double motionZ = player.posZ - player.prevPosZ;
if (player.onGround) {
motionY = 0;
}
double dist = Math.sqrt(motionX * motionX + motionZ * motionZ);
double angle = Math.atan2(motionY, dist);
if (!player.capabilities.isFlying) {
if (angle > 0) {
angle = 0;
} else {
angle /= 2;
}
}
if (angle > Math.PI / 3) angle = Math.PI / 3;
if (angle < -Math.PI / 3) angle = -Math.PI / 3;
ponyModel.motionPitch = (float) Math.toDegrees(angle);
GlStateManager.rotate((float) Math.toDegrees(angle), 1, 0, 0);
}
@Override
public AbstractPonyModel getMainModel() {
return (AbstractPonyModel)super.getMainModel();
}
@Override
public PlayerModel getPlayerModel() {
return playerModel;
}
protected void setPlayerModel(PlayerModel model) {
playerModel = model;
mainModel = ponyModel = playerModel.getModel();
}
protected void updateModel(AbstractClientPlayer player) {
pony = MineLittlePony.getInstance().getManager().getPony(player);
playerModel.apply(pony.getMetadata());
}
public Pony getPony() {
return pony;
}
protected abstract float getPonyShadowScale();
protected abstract float getScaleFactor();
protected abstract void transformFlying(AbstractClientPlayer player, float yaw, float pitch, float ticks);
}

View file

@ -0,0 +1,31 @@
package com.minelittlepony.renderer.player;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.model.PlayerModels;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderManager;
public class RenderPonyPlayer extends RenderPonyBase {
public RenderPonyPlayer(RenderManager renderManager, boolean useSmallArms, PlayerModels model) {
super(renderManager, useSmallArms, model);
}
@Override
protected float getPonyShadowScale() {
if (!MineLittlePony.getConfig().showscale) return .5f;
return getPony().getMetadata().getSize().getShadowSize();
}
@Override
protected float getScaleFactor() {
return getPony().getMetadata().getSize().getScaleFactor();
}
@Override
protected void transformFlying(AbstractClientPlayer player, float yaw, float pitch, float ticks) {
GlStateManager.rotate(90, 1, 0, 0);
GlStateManager.translate(0, -1, 0);
}
}

View file

@ -1,30 +0,0 @@
package com.minelittlepony.util;
import com.mumfrey.liteloader.core.runtime.Obf;
import com.mumfrey.liteloader.util.PrivateFields;
import net.minecraft.client.renderer.ThreadDownloadImageData;
import java.awt.image.BufferedImage;
public class PonyFields<P, T> extends PrivateFields<P, T> {
public static final PrivateFields<ThreadDownloadImageData, BufferedImage> downloadedImage = field(ThreadDownloadImageData.class, PonyObf.downloadedImage);
protected PonyFields(Class<P> owner, Obf obf) {
super(owner, obf);
}
private static <P, T> PrivateFields<P, T> field(Class<P> c, Obf o) {
return new PonyFields<>(c, o);
}
private static class PonyObf extends Obf {
public static Obf downloadedImage = new PonyObf("field_110560_d", "l", "bufferedImage");
protected PonyObf(String seargeName, String obfName, String mcpName) {
super(seargeName, obfName, mcpName);
}
}
}

View file

@ -1,7 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package com.minelittlepony.util;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -5,7 +5,8 @@
"refmap": "minelp.mixin.refmap.json", "refmap": "minelp.mixin.refmap.json",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [ "mixins": [
"MixinRenderPlayer", "MixinThreadDownloadImageData",
"MixinNetworkPlayerInfo",
"MixinRenderItem" "MixinRenderItem"
] ]
} }