mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Add climbing animations in first person mode and fixed changeling's climbing animations not playing. Fixes #164
This commit is contained in:
parent
27051ec13f
commit
b8a0167ff7
5 changed files with 159 additions and 30 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<E extends LivingEntity> implements AccessoryFeatureRenderer.Feature<E> {
|
||||
|
@ -67,7 +68,7 @@ public class HeldEntityFeatureRenderer<E extends LivingEntity> 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);
|
||||
|
|
|
@ -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,15 +210,25 @@ public class PlayerPoser {
|
|||
float pitch = MathHelper.clamp(3F * saw, 1, 2);
|
||||
float yaw = 0.5F * saw;
|
||||
|
||||
if (context == Context.THIRD_PERSON) {
|
||||
if (ponyRace.isEquine()) {
|
||||
rearUp(matrices, model, saw);
|
||||
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);
|
||||
|
@ -180,6 +236,29 @@ public class PlayerPoser {
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -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<Animation> {
|
||||
|
@ -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),
|
||||
|
|
|
@ -146,10 +146,16 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, 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<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
}
|
||||
|
||||
if (getAnimation().isOf(Animation.NONE) || (getAnimation().isOf(Animation.NONE) && canhangHere)) {
|
||||
if (canhangHere) {
|
||||
setAnimation(Animation.ARMS_UP, Recipient.HUMAN);
|
||||
setAnimation(Animation.HANG, Recipient.ANYONE);
|
||||
} else if (distanceClimbed > 1.5) {
|
||||
setAnimation(Animation.CLIMB, Recipient.HUMAN);
|
||||
}
|
||||
setAnimation(Animation.CLIMB, Recipient.ANYONE);
|
||||
}
|
||||
} else {
|
||||
distanceClimbed = 0;
|
||||
|
@ -484,16 +488,21 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in a new issue