diff --git a/src/main/java/com/minelittlepony/unicopia/client/FirstPersonRendererOverrides.java b/src/main/java/com/minelittlepony/unicopia/client/FirstPersonRendererOverrides.java index 11a2cc18..b3b00c53 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/FirstPersonRendererOverrides.java +++ b/src/main/java/com/minelittlepony/unicopia/client/FirstPersonRendererOverrides.java @@ -2,15 +2,18 @@ package com.minelittlepony.unicopia.client; import java.util.Optional; +import com.google.common.base.MoreObjects; import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer; import com.minelittlepony.unicopia.entity.player.Pony; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.item.HeldItemRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Arm; +import net.minecraft.util.Hand; public class FirstPersonRendererOverrides { public static final FirstPersonRendererOverrides INSTANCE = new FirstPersonRendererOverrides(); @@ -21,12 +24,35 @@ public class FirstPersonRendererOverrides { public boolean beforeRenderHands(ArmRenderer sender, float tickDelta, MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers, ClientPlayerEntity player, int light) { var root = AccessoryFeatureRenderer.FeatureRoot.of(player); - return root != null && root.getAccessories().beforeRenderArms(sender, tickDelta, matrices, vertexConsumers, player, light); + boolean cancelled = root != null && root.getAccessories().beforeRenderArms(sender, tickDelta, matrices, vertexConsumers, player, light); + + if (cancelled) { + return true; + } + + if (Pony.of(player).getAnimation().renderBothArms()) { + float swingProgress = player.getHandSwingProgress(MinecraftClient.getInstance().getTickDelta()); + + Hand hand = MoreObjects.firstNonNull(player.preferredHand, Hand.MAIN_HAND); + + if (player.getMainHandStack().isEmpty()) { + matrices.push(); + sender.invokeRenderArmHoldingItem(matrices, vertexConsumers, light, 1 - sender.getEquipProgress(Hand.MAIN_HAND, tickDelta), hand == Hand.MAIN_HAND ? swingProgress : 0, player.getMainArm()); + matrices.pop(); + } + + if (player.getOffHandStack().isEmpty()) { + matrices.push(); + sender.invokeRenderArmHoldingItem(matrices, vertexConsumers, light, 1 - sender.getEquipProgress(Hand.OFF_HAND, tickDelta), hand == Hand.OFF_HAND ? swingProgress : 0, player.getMainArm().getOpposite()); + matrices.pop(); + } + } + return false; } public interface ArmRenderer { void invokeRenderArmHoldingItem(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, Arm arm); - float getEquipProgress(float tickDelta); + float getEquipProgress(Hand hand, float tickDelta); } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/HeldEntityFeatureRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/HeldEntityFeatureRenderer.java index 2ea66898..28957cf7 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/HeldEntityFeatureRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/HeldEntityFeatureRenderer.java @@ -18,6 +18,7 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.util.Arm; +import net.minecraft.util.Hand; import net.minecraft.util.math.*; public class HeldEntityFeatureRenderer implements AccessoryFeatureRenderer.Feature { @@ -67,7 +68,7 @@ public class HeldEntityFeatureRenderer implements Access renderCarriedEntity(passenger.asEntity(), matrices, vertexConsumers, light, tickDelta); matrices.pop(); - float equipProgress = 1 - sender.getEquipProgress(tickDelta); + float equipProgress = 1 - sender.getEquipProgress(Hand.MAIN_HAND, tickDelta); matrices.push(); sender.invokeRenderArmHoldingItem(matrices, vertexConsumers, light, equipProgress, swingProgress, Arm.LEFT); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java b/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java index 2f68ecbc..ec3b17bb 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java @@ -33,6 +33,7 @@ public class PlayerPoser { public void applyPosing(MatrixStack matrices, PlayerEntity player, BipedEntityModel model, Context context) { Pony pony = Pony.of(player); + float tickDelta = MinecraftClient.getInstance().getTickDelta(); float progress = pony.getAnimationProgress(MinecraftClient.getInstance().getTickDelta()); AnimationInstance animation = pony.getAnimation(); Race ponyRace = MineLPDelegate.getInstance().getPlayerPonyRace(player); @@ -130,6 +131,51 @@ public class PlayerPoser { break; } + case HANG: { + float saw = MathHelper.sin(player.limbAnimator.getPos()); + + float pitch = 0.8F * saw; + + float basePitch = 3.25F; + + if (context == Context.THIRD_PERSON) { + + if (ponyRace.isEquine()) { + rearUp(matrices, model, 1); + model.head.pitch += 0.8F; + basePitch = 2.25F; + } + + rotateArm(model.leftArm, basePitch - pitch, -0.3F, 0); + rotateArm(model.rightArm, basePitch + pitch, 0.3F, 0); + + rotateArm(model.leftLeg, 0, 0.1F, 0); + rotateArm(model.rightLeg, 0, -0.1F, 0); + } else { + pitch *= 0.5F; + + float x = ponyRace.isEquine() ? 9 : 10; + float y = ponyRace.isEquine() ? -3 : -1; + float z = ponyRace.isEquine() ? -8 : -6; + + float cameraPitch = player.getPitch(tickDelta) * MathHelper.RADIANS_PER_DEGREE; + + rotateArm(model.leftArm, 0, 0, -0.4F + pitch); + rotateArm(model.rightArm, 0, 0, 0.4F + pitch); + + model.leftArm.pivotX += x; + model.leftArm.pivotY += y; + model.leftArm.pivotZ += z; + model.leftArm.roll -= cameraPitch; + + + model.rightArm.pivotX -= x; + model.rightArm.pivotY += y; + model.rightArm.pivotZ += z; + model.rightArm.roll += cameraPitch; + } + break; + } case ARMS_UP: { float saw = AnimationUtil.seesaw(progress); @@ -138,14 +184,14 @@ public class PlayerPoser { if (ponyRace.isEquine()) { rearUp(matrices, model, saw); - pitch = saw * 2F; model.head.pitch += saw * 0.5F; + pitch = saw * 2F; } if (liftLeftArm) { rotateArm(model.leftArm, pitch, -yaw, yaw); } else if (ponyRace.isEquine()) { - model.leftArm.pitch += saw / 4F; + model.leftArm.pitch -= saw / 4F; model.leftArm.roll -= saw / 4F; } @@ -164,23 +210,56 @@ public class PlayerPoser { float pitch = MathHelper.clamp(3F * saw, 1, 2); float yaw = 0.5F * saw; - if (ponyRace.isEquine()) { - rearUp(matrices, model, saw); - pitch = saw * 2F; - model.head.pitch += saw * 0.5F; + if (context == Context.THIRD_PERSON) { + if (ponyRace.isEquine()) { + rearUp(matrices, model, 1); + pitch = saw * 2F; + model.head.pitch += saw * 0.5F; + + rotateArm(model.leftArm, pitch, -yaw, yaw / 2F); + rotateArm(model.rightLeg, pitch / 2F, yaw, 0); + + saw = AnimationUtil.seesaw(progress + 0.5F); + yaw = 0.5F * -saw; + + rotateArm(model.rightArm, pitch, yaw, -yaw / 2F); + rotateArm(model.leftLeg, pitch / 2F, -yaw, 0); + + } else { + rotateArm(model.leftArm, pitch, -yaw, yaw / 2F); + rotateArm(model.rightLeg, pitch / 2F, yaw, 0); + + saw = AnimationUtil.seesaw((progress + 0.5F) % 1); + + pitch = MathHelper.clamp(3F * saw, 1, 2) * (ponyRace.isEquine() ? 2 : 1); + yaw = 0.5F * saw; + + rotateArm(model.rightArm, pitch, yaw, -yaw / 2F); + rotateArm(model.leftLeg, pitch / 2F, -yaw, 0); + } + } else { + //saw = MathHelper.sin(progress * 2); + float x = ponyRace.isEquine() ? 9 : 0; + float y = ponyRace.isEquine() ? -3 : 0; + float z = ponyRace.isEquine() ? -8 : -2; + + float cameraPitch = player.getPitch(tickDelta) * MathHelper.RADIANS_PER_DEGREE; + pitch = MathHelper.sin((progress * 2) * MathHelper.PI) * 0.6F; + + rotateArm(model.leftArm, 0, 0, pitch); + rotateArm(model.rightArm, 0, 0, pitch); + + model.leftArm.pivotX += x; + model.leftArm.pivotY += y; + model.leftArm.pivotZ += z; + model.leftArm.roll -= cameraPitch; + + model.rightArm.pivotX -= x; + model.rightArm.pivotY += y; + model.rightArm.pivotZ += z; + model.rightArm.roll += cameraPitch; } - rotateArm(model.leftArm, pitch, -yaw, yaw / 2F); - rotateArm(model.rightLeg, pitch / 2F, yaw, 0); - - saw = AnimationUtil.seesaw((progress + 0.5F) % 1); - - pitch = MathHelper.clamp(3F * saw, 1, 2) * (ponyRace.isEquine() ? 2 : 1); - yaw = 0.5F * saw; - - rotateArm(model.rightArm, pitch, yaw, -yaw / 2F); - rotateArm(model.leftLeg, pitch / 2F, -yaw, 0); - break; } case WAVE_ONE: @@ -324,6 +403,10 @@ public class PlayerPoser { public boolean canPlay(boolean isPony) { return !isOf(Animation.NONE) && (recipient == Animation.Recipient.ANYONE || isPony == (recipient == Animation.Recipient.PONY)); } + + public boolean renderBothArms() { + return isOf(Animation.HANG) || isOf(Animation.CLIMB); + } } public enum Animation implements CommandArgumentEnum { @@ -335,6 +418,7 @@ public class PlayerPoser { WAVE_TWO(USounds.ENTITY_PLAYER_WHISTLE, 20), KICK(USounds.ENTITY_PLAYER_KICK, 5), CLIMB(20), + HANG(20), STOMP(5), WIGGLE_NOSE(6), SPREAD_WINGS(6), diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index caf75543..d2075aa3 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -146,10 +146,16 @@ public class Pony extends Living implements Copyable, Update } public void setAnimation(Animation animation, Animation.Recipient recipient) { + if (getAnimation().isOf(animation) && animationDuration > 0) { + return; + } setAnimation(new AnimationInstance(animation, recipient), animation.getDuration()); } public void setAnimation(Animation animation, Animation.Recipient recipient, int duration) { + if (getAnimation().isOf(animation) && animationDuration > 0) { + return; + } setAnimation(new AnimationInstance(animation, recipient), duration); } @@ -420,12 +426,10 @@ public class Pony extends Living implements Copyable, Update } } - if (getAnimation().isOf(Animation.NONE) || (getAnimation().isOf(Animation.NONE) && canhangHere)) { - if (canhangHere) { - setAnimation(Animation.ARMS_UP, Recipient.HUMAN); - } else if (distanceClimbed > 1.5) { - setAnimation(Animation.CLIMB, Recipient.HUMAN); - } + if (canhangHere) { + setAnimation(Animation.HANG, Recipient.ANYONE); + } else if (distanceClimbed > 1.5) { + setAnimation(Animation.CLIMB, Recipient.ANYONE); } } else { distanceClimbed = 0; @@ -484,16 +488,21 @@ public class Pony extends Living implements Copyable, Update private void updateAnimations() { if (distanceClimbed > 0 - && ((animation.isOf(Animation.CLIMB) && entity.isSneaky()) || (animation.isOf(Animation.ARMS_UP) && isHanging())) + && ((animation.isOf(Animation.CLIMB) && entity.isSneaky()) || animation.isOf(Animation.HANG)) && entity.getClimbingPos().isPresent() && entity.getVelocity().length() < 0.08F) { - if (animation.isOf(Animation.ARMS_UP)) { + if (animation.renderBothArms()) { animationDuration = 2; } return; } if (animationDuration > 0 && --animationDuration <= 0) { + + if (animation.renderBothArms() && distanceClimbed > 0) { + return; + } + setAnimation(AnimationInstance.NONE); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinHeldItemRenderer.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinHeldItemRenderer.java index 8ace2c63..fe9c5439 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinHeldItemRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinHeldItemRenderer.java @@ -16,6 +16,7 @@ import net.minecraft.client.render.item.HeldItemRenderer; import net.minecraft.client.render.item.HeldItemRenderer.HandRenderType; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Arm; +import net.minecraft.util.Hand; import net.minecraft.util.math.MathHelper; @Mixin(HeldItemRenderer.class) @@ -25,13 +26,21 @@ abstract class MixinHeldItemRenderer implements FirstPersonRendererOverrides.Arm @Shadow private float prevEquipProgressMainHand; + @Shadow + private float equipProgressOffHand; + @Shadow + private float prevEquipProgressOffHand; + @Override @Invoker("renderArmHoldingItem") public abstract void invokeRenderArmHoldingItem(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, Arm arm); @Override - public float getEquipProgress(float tickDelta) { - return MathHelper.lerp(tickDelta, prevEquipProgressMainHand, equipProgressMainHand); + public float getEquipProgress(Hand hand, float tickDelta) { + return MathHelper.lerp(tickDelta, + hand == Hand.MAIN_HAND ? prevEquipProgressMainHand : prevEquipProgressOffHand, + hand == Hand.MAIN_HAND ? equipProgressMainHand : equipProgressOffHand + ); } @Inject(