diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java index bebcfb9b..82d784f4 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java @@ -1,23 +1,36 @@ package com.minelittlepony.unicopia.client.render; +import javax.annotation.Nullable; + +import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; +import com.minelittlepony.unicopia.entity.behaviour.VirtualEntity; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.model.Model; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.LivingEntityRenderer; +import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.Vector3f; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; public class WorldRenderDelegate { - public static final WorldRenderDelegate INSTANCE = new WorldRenderDelegate(); - public void beforeEntityRender(Pony pony, MatrixStack matrices, double x, double y, double z) { + public boolean onEntityRender(EntityRenderDispatcher dispatcher, Pony pony, + double x, double y, double z, float yaw, + float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) { matrices.push(); - Entity entity = pony.getOwner(); + Entity owner = pony.getOwner(); boolean negative = pony.getPhysics().isGravityNegative(); @@ -27,14 +40,18 @@ public class WorldRenderDelegate { if (negative) { matrices.translate(x, y, z); - matrices.translate(0, entity.getHeight(), 0); + matrices.translate(0, owner.getHeight(), 0); matrices.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(roll)); matrices.translate(-x, -y, -z); - flipAngles(entity); + flipAngles(owner); } else { matrices.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(roll)); } + + return pony.getSpellOrEmpty(DisguiseSpell.class, true) + .map(effect -> renderDisguise(dispatcher, pony, effect, x, y, z, tickDelta, matrices, vertexConsumers, light)) + .orElse(false); } public void afterEntityRender(Pony pony, MatrixStack matrices) { @@ -46,6 +63,54 @@ public class WorldRenderDelegate { } } + public boolean renderDisguise(EntityRenderDispatcher dispatcher, Pony pony, DisguiseSpell effect, + double x, double y, double z, + float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) { + effect.update(pony, false); + + VirtualEntity ve = effect.getDisguise(); + Entity e = ve.getAppearance(); + + if (e != null) { + if (ve.isAxisAligned() && (x != 0 || y != 0 || z != 0)) { + Vec3d cam = MinecraftClient.getInstance().gameRenderer.getCamera().getPos(); + + x = MathHelper.lerp(tickDelta, e.lastRenderX, e.getX()) - cam.x; + y = MathHelper.lerp(tickDelta, e.lastRenderY, e.getY()) - cam.y; + z = MathHelper.lerp(tickDelta, e.lastRenderZ, e.getZ()) - cam.z; + } + + BipedEntityModel model = getBipedModel(dispatcher, e); + + if (model != null) { + model.sneaking = e.isSneaking(); + } + + dispatcher.render(e, x, y, z, e.yaw, tickDelta, matrices, vertexConsumers, light); + + if (model != null) { + model.sneaking = false; + } + + afterEntityRender(pony, matrices); + return true; + } + + return false; + } + + @Nullable + private BipedEntityModel getBipedModel(EntityRenderDispatcher dispatcher, Entity entity) { + EntityRenderer renderer = dispatcher.getRenderer(entity); + if (renderer instanceof LivingEntityRenderer) { + Model m = ((LivingEntityRenderer) renderer).getModel(); + if (m instanceof BipedEntityModel) { + return (BipedEntityModel)m; + } + } + return null; + } + private void flipAngles(Entity entity) { if (!MinecraftClient.getInstance().options.getPerspective().isFirstPerson()) { entity.prevYaw *= -1; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java index ea882a17..2b7e7f3b 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinEntityRenderDispatcher.java @@ -5,18 +5,14 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell; import com.minelittlepony.unicopia.client.render.WorldRenderDelegate; import com.minelittlepony.unicopia.entity.player.Pony; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; @Mixin(EntityRenderDispatcher.class) abstract class MixinEntityRenderDispatcher { @@ -25,45 +21,17 @@ abstract class MixinEntityRenderDispatcher { @Inject(method = RENDER, at = @At("HEAD"), cancellable = true) private void beforeRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) { - if (!(entity instanceof PlayerEntity)) { return; } - Pony pony = Pony.of((PlayerEntity)entity); - - WorldRenderDelegate.INSTANCE.beforeEntityRender(pony, matrices, x, y, z); - - DisguiseSpell effect = pony.getSpell(DisguiseSpell.class, true); - - if (effect == null || effect.isDead()) { - return; - } - - effect.update(pony, false); - - Entity e = effect.getDisguise(); - - if (e != null) { + if (WorldRenderDelegate.INSTANCE.onEntityRender((EntityRenderDispatcher)(Object)this, Pony.of((PlayerEntity)entity), x, y, z, yaw, tickDelta, matrices, vertexConsumers, light)) { info.cancel(); - - if (DisguiseSpell.isAttachedEntity(e) && (x != 0 || y != 0 || z != 0)) { - Vec3d cam = MinecraftClient.getInstance().gameRenderer.getCamera().getPos(); - - x = MathHelper.lerp(tickDelta, e.lastRenderX, e.getX()) - cam.x; - y = MathHelper.lerp(tickDelta, e.lastRenderY, e.getY()) - cam.y; - z = MathHelper.lerp(tickDelta, e.lastRenderZ, e.getZ()) - cam.z; - - } - - ((EntityRenderDispatcher)(Object)this).render(e, x, y, z, e.yaw, tickDelta, matrices, vertexConsumers, light); - WorldRenderDelegate.INSTANCE.afterEntityRender(Pony.of((PlayerEntity)entity), matrices); } } @Inject(method = RENDER, at = @At("RETURN")) private void afterRender(E entity, double x, double y, double z, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo info) { - if (!(entity instanceof PlayerEntity)) { return; }