diff --git a/src/main/java/com/minelittlepony/PonyRenderManager.java b/src/main/java/com/minelittlepony/PonyRenderManager.java index 6b3fe77c..4d6e58b4 100644 --- a/src/main/java/com/minelittlepony/PonyRenderManager.java +++ b/src/main/java/com/minelittlepony/PonyRenderManager.java @@ -4,6 +4,7 @@ import java.util.Map; import com.google.common.collect.Maps; import com.minelittlepony.mixin.MixinRenderManager; +import com.minelittlepony.ducks.IRenderPony; import com.minelittlepony.hdskins.gui.EntityPonyModel; import com.minelittlepony.hdskins.gui.RenderPonyModel; import com.minelittlepony.model.player.PlayerModels; @@ -12,9 +13,14 @@ import com.minelittlepony.render.player.RenderPonyPlayer; import com.minelittlepony.render.ponies.MobRenderers; import com.mumfrey.liteloader.util.ModUtilities; +import javax.annotation.Nullable; + +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderLivingBase; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; /** * Render manager responsible for replacing and restoring entity renderers when the client settings change. @@ -88,4 +94,16 @@ public class PonyRenderManager { public LevitatingItemRenderer getMagicRenderer() { return magicRenderer; } + + @SuppressWarnings("unchecked") + @Nullable + public & IRenderPony> R getPonyRenderer(T entity) { + Render renderer = Minecraft.getMinecraft().getRenderManager().getEntityRenderObject(entity); + + if (renderer instanceof RenderLivingBase && renderer instanceof IRenderPony) { + return (R)(Object)renderer; + } + + return null; + } } diff --git a/src/main/java/com/minelittlepony/ducks/IRenderPony.java b/src/main/java/com/minelittlepony/ducks/IRenderPony.java index 78b58168..6e84f6d5 100644 --- a/src/main/java/com/minelittlepony/ducks/IRenderPony.java +++ b/src/main/java/com/minelittlepony/ducks/IRenderPony.java @@ -2,7 +2,10 @@ package com.minelittlepony.ducks; import com.minelittlepony.model.ModelWrapper; import com.minelittlepony.pony.data.IPony; +import com.minelittlepony.render.RenderPony; +import com.minelittlepony.util.math.MathUtil; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.EntityLivingBase; /** @@ -16,4 +19,19 @@ public interface IRenderPony { ModelWrapper getModelWrapper(); IPony getEntityPony(T entity); + + RenderPony getInternalRenderer(); + + /** + * Called by riders to have their transportation adjust their position. + */ + default void translateRider(T entity, IPony entityPony, EntityLivingBase passenger, IPony passengerPony, float ticks) { + if (!passengerPony.getRace(false).isHuman()) { + float yaw = MathUtil.interpolateDegress(entity.prevRenderYawOffset, entity.renderYawOffset, ticks); + + GlStateManager.translate(0, 0, 0.8F); + + getInternalRenderer().applyPostureRiding(entity, entity.ticksExisted + ticks, yaw, ticks); + } + } } diff --git a/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java b/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java index b06a92b9..61519be8 100644 --- a/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java +++ b/src/main/java/com/minelittlepony/hdskins/gui/RenderPonyModel.java @@ -111,4 +111,9 @@ public class RenderPonyModel extends RenderPlayerModel implemen } }; } + + @Override + public RenderPony getInternalRenderer() { + return renderPony; + } } diff --git a/src/main/java/com/minelittlepony/render/RenderPony.java b/src/main/java/com/minelittlepony/render/RenderPony.java index 59d63246..1bc4b98e 100644 --- a/src/main/java/com/minelittlepony/render/RenderPony.java +++ b/src/main/java/com/minelittlepony/render/RenderPony.java @@ -1,5 +1,6 @@ package com.minelittlepony.render; +import com.minelittlepony.MineLittlePony; import com.minelittlepony.ducks.IRenderPony; import com.minelittlepony.model.AbstractPonyModel; import com.minelittlepony.model.ModelWrapper; @@ -7,6 +8,7 @@ import com.minelittlepony.pony.data.IPony; import com.minelittlepony.transform.PonyPosture; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; public class RenderPony { @@ -41,6 +43,25 @@ public class RenderPony { float s = getScaleFactor(); GlStateManager.scale(s, s, s); enableModelRenderProfile(); + + if (entity.isRiding()) { + Entity ridingEntity = entity.getRidingEntity(); + + if (ridingEntity instanceof EntityLivingBase) { + + IRenderPony renderer = MineLittlePony.getInstance().getRenderManager().getPonyRenderer((EntityLivingBase)ridingEntity); + + if (renderer != null) { + // negate vanilla translations so the rider begins at the ridees feet. + GlStateManager.translate(0, entity.getYOffset() + ridingEntity.getMountedYOffset(), 0); + + @SuppressWarnings("unchecked") + IPony riderPony = renderer.getEntityPony((EntityLivingBase)ridingEntity); + + renderer.translateRider((EntityLivingBase)ridingEntity, riderPony, entity, pony, ticks); + } + } + } } @SuppressWarnings("unchecked") @@ -54,6 +75,18 @@ public class RenderPony { } } + @SuppressWarnings("unchecked") + public void applyPostureRiding(T player, float pitch, float yaw, float ticks) { + PonyPosture posture = getPosture(player); + if (posture != null && posture.applies(player)) { + double motionX = player.posX - player.prevPosX; + double motionY = player.onGround ? 0 : player.posY - player.prevPosY; + double motionZ = player.posZ - player.prevPosZ; + + ((PonyPosture)posture).transform(ponyModel, player, motionX, -motionY, motionZ, pitch, yaw, ticks); + } + } + private PonyPosture getPosture(T entity) { if (entity.isElytraFlying()) { return PonyPosture.ELYTRA; diff --git a/src/main/java/com/minelittlepony/render/RenderPonyMob.java b/src/main/java/com/minelittlepony/render/RenderPonyMob.java index 074c30e0..cd885297 100644 --- a/src/main/java/com/minelittlepony/render/RenderPonyMob.java +++ b/src/main/java/com/minelittlepony/render/RenderPonyMob.java @@ -11,6 +11,7 @@ import com.minelittlepony.render.layer.LayerPonyArmor; import com.minelittlepony.render.layer.LayerPonyCustomHead; import com.minelittlepony.render.layer.LayerPonyElytra; import com.voxelmodpack.hdskins.HDSkinManager; + import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderLiving; import net.minecraft.client.renderer.entity.RenderManager; @@ -92,6 +93,11 @@ public abstract class RenderPonyMob extends RenderLiving return HDSkinManager.INSTANCE.getConvertedSkin(getTexture(entity)); } + @Override + public RenderPony getInternalRenderer() { + return renderPony; + } + protected abstract ResourceLocation getTexture(T entity); public abstract static class Proxy extends RenderPonyMob { diff --git a/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java b/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java index 2a42d091..62c09b02 100644 --- a/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java +++ b/src/main/java/com/minelittlepony/render/player/RenderPonyPlayer.java @@ -138,4 +138,8 @@ public class RenderPonyPlayer extends RenderPlayer implements IRenderPony getInternalRenderer() { + return renderPony; + } } diff --git a/src/main/java/com/minelittlepony/util/math/MathUtil.java b/src/main/java/com/minelittlepony/util/math/MathUtil.java index 2836b01b..e0925eee 100644 --- a/src/main/java/com/minelittlepony/util/math/MathUtil.java +++ b/src/main/java/com/minelittlepony/util/math/MathUtil.java @@ -16,4 +16,13 @@ public class MathUtil { return angle; } + + public static float interpolateDegress(float prev, float current, float partialTicks) { + float difference = current - prev; + + while (difference < -180) difference += 360; + while (difference >= 180) difference -= 360; + + return prev + partialTicks * difference; + } }