From 0bc06316b6653378ebec5b62cf2a95e79cebc7c4 Mon Sep 17 00:00:00 2001 From: Trainguy Date: Fri, 13 Aug 2021 00:19:40 -0400 Subject: [PATCH] Reworking stored values - Removed part-transform-based variables - Added proper variables stored in LivingEntity - Fixed arms spreading apart when looking up or down while holding charged crossbow - Added rotation for Ghasts when flying up and down - Fixed player animations on servers for the most part, there's still noticable issues with sprint jumping and crossbow charging that still need to be worked out - Updated version to test5 --- gradle.properties | 2 +- .../access/LivingEntityAccess.java | 6 + .../mixin/MixinGhastRenderer.java | 20 +-- .../mixin/MixinLivingEntity.java | 79 ++++++++++++ .../mixin/MixinPlayerModel.java | 117 ++++++++---------- .../resources/animationoverhaul.mixins.json | 6 +- 6 files changed, 156 insertions(+), 74 deletions(-) create mode 100644 src/main/java/com/trainguy/animationoverhaul/access/LivingEntityAccess.java create mode 100644 src/main/java/com/trainguy/animationoverhaul/mixin/MixinLivingEntity.java diff --git a/gradle.properties b/gradle.properties index e0bd79c..4281fe4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.11.6 # Mod Properties - mod_version = 1.0-test1 + mod_version = 1.0-test5 maven_group = com.example archives_base_name = trainguys-animation-overhaul diff --git a/src/main/java/com/trainguy/animationoverhaul/access/LivingEntityAccess.java b/src/main/java/com/trainguy/animationoverhaul/access/LivingEntityAccess.java new file mode 100644 index 0000000..564f9d2 --- /dev/null +++ b/src/main/java/com/trainguy/animationoverhaul/access/LivingEntityAccess.java @@ -0,0 +1,6 @@ +package com.trainguy.animationoverhaul.access; + +public interface LivingEntityAccess { + float getAnimationVariable(String animationVariable); + void setAnimationVariable(String animationVariable, float newValue); +} diff --git a/src/main/java/com/trainguy/animationoverhaul/mixin/MixinGhastRenderer.java b/src/main/java/com/trainguy/animationoverhaul/mixin/MixinGhastRenderer.java index dedd91a..73228b2 100644 --- a/src/main/java/com/trainguy/animationoverhaul/mixin/MixinGhastRenderer.java +++ b/src/main/java/com/trainguy/animationoverhaul/mixin/MixinGhastRenderer.java @@ -2,16 +2,11 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; -import net.minecraft.client.model.EntityModel; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.EntityRenderer; -import net.minecraft.client.renderer.entity.EntityRendererProvider; +import com.trainguy.animationoverhaul.access.LivingEntityAccess; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.entity.GhastRenderer; -import net.minecraft.client.renderer.entity.RenderLayerParent; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.monster.Ghast; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; @@ -20,8 +15,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Random; - @Unique @Mixin(GhastRenderer.class) public class MixinGhastRenderer { @@ -39,6 +32,9 @@ private void overrideGhastTexture(Ghast ghast, CallbackInfoReturnable 0 && ghast.deathTime == 0){ float ghastHurtRotationCurve = Mth.sin((1 - ghastHurtTime / 10) * Mth.PI * 2) * (1 - (1 - ghastHurtTime / 10)) * 25; @@ -48,6 +44,12 @@ private void overrideGhastRenderer(Ghast ghast, PoseStack poseStack, float f, Ca poseStack.mulPose(Vector3f.XP.rotationDegrees(Mth.sin((ghast.tickCount + f) / 12 - 1.5F) * 10)); poseStack.mulPose(Vector3f.ZP.rotationDegrees(Mth.sin((ghast.tickCount + f) / 20) * 10)); poseStack.scale(4.5F, 4.5F, 4.5F); + + float currentVerticalMovementRotation = ((LivingEntityAccess)ghast).getAnimationVariable("verticalMovementRotation"); + currentVerticalMovementRotation = ghast.getDeltaMovement().y >= 0 ? Mth.clamp(currentVerticalMovementRotation - 2 * delta, -25, 25) : Mth.clamp(currentVerticalMovementRotation + 2 * delta, -25, 25); + ((LivingEntityAccess)ghast).setAnimationVariable("verticalMovementRotation", currentVerticalMovementRotation); + poseStack.mulPose(Vector3f.XP.rotationDegrees(currentVerticalMovementRotation)); + ci.cancel(); } } diff --git a/src/main/java/com/trainguy/animationoverhaul/mixin/MixinLivingEntity.java b/src/main/java/com/trainguy/animationoverhaul/mixin/MixinLivingEntity.java new file mode 100644 index 0000000..e487a32 --- /dev/null +++ b/src/main/java/com/trainguy/animationoverhaul/mixin/MixinLivingEntity.java @@ -0,0 +1,79 @@ +package com.trainguy.animationoverhaul.mixin; + +import com.trainguy.animationoverhaul.access.LivingEntityAccess; +import net.minecraft.world.entity.LivingEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Unique +@Mixin(LivingEntity.class) +public abstract class MixinLivingEntity implements LivingEntityAccess { + public float crouchAmount; + public float inAirAmount; + public float kneelAmount; + public float verticalMovementRotation; + public float sprintAmount; + + public float leftArmItemPoseAmount; + public float rightArmItemPoseAmount; + + public float leftArmBowPoseAmount; + public float rightArmBowPoseAmount; + + public float leftArmSpearPoseAmount; + public float rightArmSpearPoseAmount; + + public float leftArmCrossbowPoseAmount; + public float rightArmCrossbowPoseAmount; + + public float leftArmShieldPoseAmount; + public float rightArmShieldPoseAmount; + + public float leftArmSpyglassPoseAmount; + public float rightArmSpyglassPoseAmount; + + public float getAnimationVariable(String variableType){ + return switch (variableType) { + case "crouchAmount" -> crouchAmount; + case "inAirAmount" -> inAirAmount; + case "kneelAmount" -> kneelAmount; + case "sprintAmount" -> sprintAmount; + case "verticalMovementRotation" -> verticalMovementRotation; + case "leftArmItemPoseAmount" -> leftArmItemPoseAmount; + case "rightArmItemPoseAmount" -> rightArmItemPoseAmount; + case "leftArmBowPoseAmount" -> leftArmBowPoseAmount; + case "rightArmBowPoseAmount" -> rightArmBowPoseAmount; + case "leftArmSpearPoseAmount" -> leftArmSpearPoseAmount; + case "rightArmSpearPoseAmount" -> rightArmSpearPoseAmount; + case "leftArmCrossbowPoseAmount" -> leftArmCrossbowPoseAmount; + case "rightArmCrossbowPoseAmount" -> rightArmCrossbowPoseAmount; + case "leftArmShieldPoseAmount" -> leftArmShieldPoseAmount; + case "rightArmShieldPoseAmount" -> rightArmShieldPoseAmount; + case "leftArmSpyglassPoseAmount" -> leftArmSpyglassPoseAmount; + case "rightArmSpyglassPoseAmount" -> rightArmSpyglassPoseAmount; + default -> 0; + }; + } + public void setAnimationVariable(String variableType, float newValue){ + switch (variableType) { + case "crouchAmount" -> crouchAmount = newValue; + case "inAirAmount" -> inAirAmount = newValue; + case "kneelAmount" -> kneelAmount = newValue; + case "sprintAmount" -> sprintAmount = newValue; + case "verticalMovementRotation" -> verticalMovementRotation = newValue; + case "leftArmItemPoseAmount" -> leftArmItemPoseAmount = newValue; + case "rightArmItemPoseAmount" -> rightArmItemPoseAmount = newValue; + case "leftArmBowPoseAmount" -> leftArmBowPoseAmount = newValue; + case "rightArmBowPoseAmount" -> rightArmBowPoseAmount = newValue; + case "leftArmSpearPoseAmount" -> leftArmSpearPoseAmount = newValue; + case "rightArmSpearPoseAmount" -> rightArmSpearPoseAmount = newValue; + case "leftArmCrossbowPoseAmount" -> leftArmCrossbowPoseAmount = newValue; + case "rightArmCrossbowPoseAmount" -> rightArmCrossbowPoseAmount = newValue; + case "leftArmShieldPoseAmount" -> leftArmShieldPoseAmount = newValue; + case "rightArmShieldPoseAmount" -> rightArmShieldPoseAmount = newValue; + case "leftArmSpyglassPoseAmount" -> leftArmSpyglassPoseAmount = newValue; + case "rightArmSpyglassPoseAmount" -> rightArmSpyglassPoseAmount = newValue; + default -> System.out.println("Invalid variable type: " + variableType); + } + } +} diff --git a/src/main/java/com/trainguy/animationoverhaul/mixin/MixinPlayerModel.java b/src/main/java/com/trainguy/animationoverhaul/mixin/MixinPlayerModel.java index 150a9b1..1df86c9 100644 --- a/src/main/java/com/trainguy/animationoverhaul/mixin/MixinPlayerModel.java +++ b/src/main/java/com/trainguy/animationoverhaul/mixin/MixinPlayerModel.java @@ -1,8 +1,13 @@ package com.trainguy.animationoverhaul.mixin; +import com.trainguy.animationoverhaul.access.LivingEntityAccess; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.EntityType; @@ -19,51 +24,34 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.List; - @Unique +@Environment(EnvType.CLIENT) @Mixin(PlayerModel.class) -public class MixinPlayerModel extends HumanoidModel { - @Shadow @Final private List parts; +public abstract class MixinPlayerModel extends HumanoidModel { @Shadow @Final public ModelPart leftPants; @Shadow @Final public ModelPart rightPants; @Shadow @Final public ModelPart leftSleeve; @Shadow @Final public ModelPart rightSleeve; @Shadow @Final public ModelPart jacket; @Shadow @Final private ModelPart cloak; - private float tick = 0; - //private float crouchAmountLinear = 0; - //private float crouchAmount = 0; - //private float sprintAmountLinear = 0; - //private float sprintAmount = 0; - //private float directionShift = 0; - //private boolean movingForward = true; public MixinPlayerModel(ModelPart modelPart) { super(modelPart); } - // unused old code - private void tick(T livingEntity, float delta, float speed){ - //this.crouchAmountLinear = this.crouching ? Math.min(this.crouchAmountLinear + 0.25F * delta, 1) : Math.max(this.crouchAmountLinear - 0.25F * delta, 0); - //this.crouchAmount = this.crouching ? Mth.sqrt(Mth.cos((float) (this.crouchAmountLinear * Math.PI * 0.5F - Math.PI * 0.5F))) : 1 - Mth.sqrt(Mth.cos((float) (this.crouchAmountLinear * Math.PI * 0.5F))); - //this.sprintAmountLinear = speed > 0.9 ? Math.min(this.sprintAmountLinear + 0.0625F * delta, 1) : Math.max(this.sprintAmountLinear - 0.125F * delta, 0); - //this.sprintAmount = speed > 0.9 ? Mth.sqrt(Mth.cos((float) (this.sprintAmountLinear * Math.PI * 0.5F - Math.PI * 0.5F))) : 1 - Mth.sqrt(Mth.cos((float) (this.sprintAmountLinear * Math.PI * 0.5F))); - //this.directionShift = !this.movingForward ? Math.min(this.directionShift + 0.25F * delta, 1) : Math.max(this.directionShift - 0.25F * delta, 0); - } - @Inject(method = "setupAnim", at = @At("HEAD"), cancellable = true) private void animPlayerModel(T livingEntity, float f, float g, float h, float i, float j, CallbackInfo ci){ + // TODO: Rewrite bow and crossbow logic + // Make it so this only applies to player animations, not mobs that use player animations as a base. if(livingEntity.getType() != EntityType.PLAYER){ super.setupAnim(livingEntity, f, g, h, i, j); return; } + float directionShift = 0; - float previousTick = this.tick; - this.tick = h; - float delta = this.tick - previousTick; + float delta = Minecraft.getInstance().getDeltaFrameTime(); float tickDifference = (float) (h - Math.floor(h)); // Slow down the limb speed if the entity is a baby @@ -71,63 +59,64 @@ private void animPlayerModel(T livingEntity, float f, float g, float h, float i, f /= 2; } - // basically the way this works is i store different variables outlined below in the unused transforms of different - // model parts, because i can't think of any other ways to store variables like this per-entity. it stores it mostly in - // linear 0-1 float variables by moving the model part between 0.0 and 0.05 on the X axis which is visually undetectable. - - // body.x kneel done - // hat.x falling done - // leftArm.x L item/block done - // rightArm.x R item/block done - // jacket.x spear throw - // rightSleeve.x bow pull done - // leftSleeve.x crossbow hold - // rightLeg.x spyglass - // leftLeg.x shield - // rightPants.x - // Right arm item/block arm pose - this.rightArm.x = this.rightArmPose == ArmPose.BLOCK || this.rightArmPose == ArmPose.ITEM ? Mth.clamp(this.rightArm.x + 0.0125F * delta, 0.0F - 5, 0.05F - 5) : Mth.clamp(this.rightArm.x - 0.0125F * delta, 0.0F - 5, 0.05F - 5); - float rightArmItemPoseAmount = Mth.sin(((this.rightArm.x + 5) * 20) * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F; + float entityRightArmItemPoseAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("rightArmItemPoseAmount"); + float currentRightArmItemPoseAmount = this.rightArmPose == ArmPose.BLOCK || this.rightArmPose == ArmPose.ITEM ? Mth.clamp(entityRightArmItemPoseAmount + 0.25F * delta, 0.0F, 1.0F) : Mth.clamp(entityRightArmItemPoseAmount - 0.25F * delta, 0.0F, 1.0F); + float rightArmItemPoseAmount = Mth.sin(currentRightArmItemPoseAmount * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F; + ((LivingEntityAccess)livingEntity).setAnimationVariable("rightArmItemPoseAmount", currentRightArmItemPoseAmount); - // Left arm item/block arm pose - this.leftArm.x = this.leftArmPose == ArmPose.BLOCK || this.leftArmPose == ArmPose.ITEM ? Mth.clamp(this.leftArm.x + 0.0125F * delta, 0.0F + 5, 0.05F + 5) : Mth.clamp(this.leftArm.x - 0.0125F * delta, 0.0F + 5, 0.05F + 5); - float leftArmItemPoseAmount = Mth.sin(((this.leftArm.x - 5) * 20) * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F; + // Right arm item/block arm pose + float entityLeftArmItemPoseAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("leftArmItemPoseAmount"); + float currentLeftArmItemPoseAmount = this.leftArmPose == ArmPose.BLOCK || this.leftArmPose == ArmPose.ITEM ? Mth.clamp(entityLeftArmItemPoseAmount + 0.25F * delta, 0.0F, 1.0F) : Mth.clamp(entityLeftArmItemPoseAmount - 0.25F * delta, 0.0F, 1.0F); + float leftArmItemPoseAmount = Mth.sin(currentLeftArmItemPoseAmount * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F; + ((LivingEntityAccess)livingEntity).setAnimationVariable("leftArmItemPoseAmount", currentLeftArmItemPoseAmount); // Bow pull boolean usingBow = this.rightArmPose == ArmPose.BOW_AND_ARROW || this.leftArmPose == ArmPose.BOW_AND_ARROW; - this.rightSleeve.x = usingBow ? Mth.clamp(this.rightSleeve.x + 0.002F * delta, 0.0F - 5, 0.05F - 5) : Mth.clamp(this.rightSleeve.x - 0.005F * delta, 0.0F - 5, 0.05F - 5); - float bowLinear = (this.rightSleeve.x + 5) * 20; - float bowHoldingAmount = usingBow ? bowLinear < 0.25 ? Mth.sin(bowLinear * Mth.PI * 4 - Mth.PI * 0.5F) * 0.5F + 0.5F : 1 : bowLinear < 0.5 ? Mth.sin(bowLinear * Mth.PI * 2 - Mth.PI * 0.5F) * 0.5F + 0.5F : 1; - float bowPullAmount = usingBow ? (float) (Mth.cos(Mth.sqrt(bowLinear) * Mth.PI * 2) * -0.5 + 0.5) : bowLinear < 0.5 ? Mth.sin(bowLinear * Mth.PI * 2 - Mth.PI * 0.5F) * 0.5F + 0.5F : 1; + float entityBowPoseAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("leftArmBowPoseAmount"); + float currentBowPoseAmount = usingBow ? Mth.clamp(entityBowPoseAmount + 0.04F * delta, 0.0F, 1.0F) : Mth.clamp(entityBowPoseAmount - 0.1F * delta, 0.0F, 1.0F); + float bowHoldingAmount = usingBow ? currentBowPoseAmount < 0.25 ? Mth.sin(currentBowPoseAmount * Mth.PI * 4 - Mth.PI * 0.5F) * 0.5F + 0.5F : 1 : currentBowPoseAmount < 0.5 ? Mth.sin(currentBowPoseAmount * Mth.PI * 2 - Mth.PI * 0.5F) * 0.5F + 0.5F : 1; + float bowPullAmount = usingBow ? (float) (Mth.cos(Mth.sqrt(currentBowPoseAmount) * Mth.PI * 2) * -0.5 + 0.5) : currentBowPoseAmount < 0.5 ? Mth.sin(currentBowPoseAmount * Mth.PI * 2 - Mth.PI * 0.5F) * 0.5F + 0.5F : 1; + ((LivingEntityAccess)livingEntity).setAnimationVariable("leftArmBowPoseAmount", currentBowPoseAmount); // Crouch variable - this.head.x = livingEntity.isCrouching() ? Mth.clamp(this.head.x + 0.0125F * delta, 0.0F, 0.05F) : Mth.clamp(this.head.x - 0.0125F * delta, 0.0F, 0.05F); - //float crouchAmount = livingEntity.isCrouching() ? Mth.sqrt(Mth.cos((float) (this.head.x * 20 * Math.PI * 0.5F - Math.PI * 0.5F))) : 1 - Mth.sqrt(Mth.cos((float) (this.head.x * 20 * Math.PI * 0.5F))); - float crouchAmount = Mth.sin(((this.head.x) * 20) * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F;; + float entityCrouchAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("crouchAmount"); + float currentEntityCrouchAmount = livingEntity.isCrouching() ? Mth.clamp(entityCrouchAmount + 0.125F, 0.0F, 1.0F) : Mth.clamp(entityCrouchAmount - 0.125F, 0.0F, 1.0F); + float crouchAmount = Mth.sin((currentEntityCrouchAmount) * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F; + ((LivingEntityAccess)livingEntity).setAnimationVariable("crouchAmount", currentEntityCrouchAmount); // Crossbow Holding + float entityCrossbowPoseAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("leftArmCrossbowPoseAmount"); boolean holdingOrChargingCrossbow = (livingEntity.getTicksUsingItem() > 0 && livingEntity.getUseItem().getUseAnimation() == UseAnim.CROSSBOW) || this.rightArmPose == ArmPose.CROSSBOW_HOLD || this.leftArmPose == ArmPose.CROSSBOW_HOLD; boolean holdingUnloadedCrossbow = (livingEntity.getTicksUsingItem() == 0 && ((livingEntity.getMainHandItem().getUseAnimation() == UseAnim.CROSSBOW && !CrossbowItem.isCharged(livingEntity.getMainHandItem())) || (livingEntity.getOffhandItem().getUseAnimation() == UseAnim.CROSSBOW && !CrossbowItem.isCharged(livingEntity.getOffhandItem())))); - this.leftSleeve.x = holdingOrChargingCrossbow ? Mth.clamp(this.leftSleeve.x + 0.0125F * delta, 0.0F + 5, 0.05F + 5) : holdingUnloadedCrossbow ? Mth.clamp(this.leftSleeve.x - 0.00625F * delta, 0.0F + 5, 0.05F + 5) : Mth.clamp(this.leftSleeve.x - 0.0125F * delta, 0.0F + 5, 0.05F + 5); - float crossbowHoldAmount = !holdingUnloadedCrossbow ? Mth.sin(((this.leftSleeve.x - 5) * 20) * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F : Mth.sin(((this.leftSleeve.x - 5) * 20) * Mth.PI * 1.25F - Mth.PI * 0.5F) * 0.6F + 0.6F; - + float currentCrossbowAmount = holdingOrChargingCrossbow ? Mth.clamp(entityCrossbowPoseAmount + 0.25F * delta, 0.0F, 1.0F) : holdingUnloadedCrossbow ? Mth.clamp(entityCrossbowPoseAmount - 0.125F * delta, 0.0F, 1.0F) : Mth.clamp(entityCrossbowPoseAmount - 0.25F * delta, 0.0F, 1.0F); + float crossbowHoldAmount = !holdingUnloadedCrossbow ? Mth.sin(currentCrossbowAmount * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F : Mth.sin(currentCrossbowAmount * Mth.PI * 1.25F - Mth.PI * 0.5F) * 0.6F + 0.6F; + ((LivingEntityAccess)livingEntity).setAnimationVariable("leftArmCrossbowPoseAmount", currentCrossbowAmount); // Simple sprint - float sprintAmount = Mth.clamp(7.69F * (g - 0.87F), 0, 1); + float entitySprintAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("sprintAmount"); + float currentSprintAmount = g > 0.9 ? Mth.clamp(entitySprintAmount + 0.0625F * delta, 0.0F, 1.0F) : Mth.clamp(entitySprintAmount - 0.125F * delta, 0.0F, 1.0F); + float sprintAmount = Mth.sin(currentSprintAmount * Mth.PI - Mth.PI * 0.5F) * 0.5F + 0.5F; + ((LivingEntityAccess)livingEntity).setAnimationVariable("sprintAmount", currentSprintAmount); // When the player hits the ground after being in the air, start the hit ground animation - if(this.hat.x > 0.0F && (livingEntity.isOnGround() || livingEntity.onClimbable())){ - this.body.x = Mth.clamp(this.hat.x * 2, 0, 0.05F); + float entityInAirAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("inAirAmount"); + float entityKneelAmount = ((LivingEntityAccess)livingEntity).getAnimationVariable("kneelAmount"); + float currentKneelAmount; + if(entityInAirAmount > 0.0F && (livingEntity.isOnGround() || livingEntity.onClimbable())){ + entityKneelAmount = Mth.clamp(entityInAirAmount * 2, 0.0F, 1.0F); } // Get the in air and kneel values - this.body.x = Mth.clamp(this.body.x - 0.004F * delta, 0.0F, 0.05F); - this.hat.x = !livingEntity.isOnGround() && !livingEntity.onClimbable() && !livingEntity.isSwimming() && !livingEntity.isPassenger() ? Mth.clamp(this.hat.x + 0.0025F * delta, 0.0F, 0.05F) : 0; - float inAirAmount = livingEntity.isOnGround() || livingEntity.onClimbable() || livingEntity.isSwimming() || livingEntity.isPassenger() ? 0 : Mth.clamp(this.hat.x * 20, 0, 1); - float kneelAmount = 2 - Mth.sqrt(Mth.cos((float) (this.body.x * 20 * Math.PI * 0.5F))) * 2; + currentKneelAmount = Mth.clamp(entityKneelAmount - 0.125F * delta, 0.0F, 1.0F); + float currentInAirAmount = !livingEntity.isOnGround() && !livingEntity.onClimbable() && !livingEntity.isSwimming() && !livingEntity.isPassenger() ? Mth.clamp(entityInAirAmount + 0.05F * delta, 0.0F, 1.0F) : 0; + float inAirAmount = livingEntity.isOnGround() || livingEntity.onClimbable() || livingEntity.isSwimming() || livingEntity.isPassenger() ? 0 : Mth.clamp(currentInAirAmount, 0, 1); + float kneelAmount = 2 - Mth.sqrt(Mth.cos((float) (currentKneelAmount * Math.PI * 0.5F))) * 2; sprintAmount *= (1 - inAirAmount); + ((LivingEntityAccess)livingEntity).setAnimationVariable("inAirAmount", currentInAirAmount); + ((LivingEntityAccess)livingEntity).setAnimationVariable("kneelAmount", currentKneelAmount); // Get the look angle and delta movement to determine whether the character is moving forwards or backwards + // TODO: this breaks when strafing, may need to re-evaluate my approach for this if(g > 0.1){ if((livingEntity.getLookAngle().x > 0 && livingEntity.getDeltaMovement().x < 0) || (livingEntity.getLookAngle().x < 0 && livingEntity.getDeltaMovement().x > 0) || (livingEntity.getLookAngle().z > 0 && livingEntity.getDeltaMovement().z < 0) || (livingEntity.getLookAngle().z < 0 && livingEntity.getDeltaMovement().z > 0)){ directionShift = 1; @@ -153,8 +142,8 @@ private void animPlayerModel(T livingEntity, float f, float g, float h, float i, float bodyBob = livingEntity.isOnGround() ? (float) ( ((Mth.abs(Mth.sin(f * limbMotionMultiplier - Mth.PI / 4) * 1) * -1 + 1F) * Mth.clamp(g, 0, 0.25) * 4 * (sprintAmount + 1))): 0; float rightLegLift = livingEntity.isOnGround() ? (float) ((Math.min(Mth.sin(f * limbMotionMultiplier + Mth.PI * directionShift) * -3, 0) + 1) * Mth.clamp(g, 0, 0.25) * 4): 0; float leftLegLift = livingEntity.isOnGround() ? (float) ((Math.min(Mth.sin(f * limbMotionMultiplier + Mth.PI + Mth.PI * directionShift) * -3, 0) + 1) * Mth.clamp(g, 0, 0.25) * 4): 0; - float limbRotation = (float) ((Mth.cos(f * limbMotionMultiplier)) * 1.1F * g) * (1 - inAirAmount); - float inverseLimbRotation = (float) ((Mth.cos(f * limbMotionMultiplier + Mth.PI)) * 1.1F * g) * (1 - inAirAmount); + float limbRotation = ((Mth.cos(f * limbMotionMultiplier)) * 1.1F * g) * (1 - inAirAmount); + float inverseLimbRotation = ((Mth.cos(f * limbMotionMultiplier + Mth.PI)) * 1.1F * g) * (1 - inAirAmount); float limbForwardMotion = Mth.cos(f * limbMotionMultiplier) * 2.0F * g * (1 - inAirAmount); float inverseLimbForwardMotion = Mth.cos(f * limbMotionMultiplier + Mth.PI) * 2.0F * g * (1 - inAirAmount); @@ -294,6 +283,7 @@ private void animPlayerModel(T livingEntity, float f, float g, float h, float i, this.leftArm.yRot = Mth.lerp(bowHoldingAmount, this.leftArm.yRot,0.1F + this.head.yRot + 0.4F); this.rightArm.xRot = Mth.lerp(bowHoldingAmount, this.rightArm.xRot, -1.5707964F + this.head.xRot); this.leftArm.xRot = Mth.lerp(bowHoldingAmount, this.leftArm.xRot, -1.5707964F + this.head.xRot); + this.rightArm.zRot = Mth.lerp(bowHoldingAmount, this.rightArm.zRot, 0); this.leftArm.zRot = Mth.lerp(bowHoldingAmount, this.leftArm.zRot, this.head.xRot * 0.5F); @@ -308,6 +298,7 @@ private void animPlayerModel(T livingEntity, float f, float g, float h, float i, this.leftArm.yRot = Mth.lerp(bowHoldingAmount, this.leftArm.yRot,0.1F + this.head.yRot); this.rightArm.xRot = Mth.lerp(bowHoldingAmount, this.rightArm.xRot, -1.5707964F + this.head.xRot); this.leftArm.xRot = Mth.lerp(bowHoldingAmount, this.leftArm.xRot, -1.5707964F + this.head.xRot); + this.leftArm.zRot = Mth.lerp(bowHoldingAmount, this.leftArm.zRot, 0); this.rightArm.zRot = Mth.lerp(bowHoldingAmount, this.rightArm.zRot, this.head.xRot * -0.5F); @@ -333,6 +324,8 @@ private void animPlayerModel(T livingEntity, float f, float g, float h, float i, secondaryArm.yRot = Mth.lerp(crossbowHoldAmount, secondaryArm.yRot, (holdingCrossbowInRightHand ? 0.6F : -0.6F) + this.head.yRot); primaryArm.xRot = Mth.lerp(crossbowHoldAmount, primaryArm.xRot, -1.5707964F + this.head.xRot + 0.1F + crossbowArmBob); secondaryArm.xRot = Mth.lerp(crossbowHoldAmount, secondaryArm.xRot, -1.5F + this.head.xRot + crossbowArmBob); + primaryArm.zRot = Mth.lerp(crossbowHoldAmount, primaryArm.zRot, 0); + secondaryArm.zRot = Mth.lerp(crossbowHoldAmount, secondaryArm.zRot, this.head.xRot * (holdingCrossbowInRightHand ? 0.4F : -0.4F)); // Crossbow pull logic if(holdingOrChargingCrossbow){ if(livingEntity.getTicksUsingItem() > 0){ diff --git a/src/main/resources/animationoverhaul.mixins.json b/src/main/resources/animationoverhaul.mixins.json index 77519b7..5e7d0ad 100644 --- a/src/main/resources/animationoverhaul.mixins.json +++ b/src/main/resources/animationoverhaul.mixins.json @@ -3,10 +3,12 @@ "minVersion": "0.8", "package": "com.trainguy.animationoverhaul.mixin", "compatibilityLevel": "JAVA_16", - "mixins": [], + "mixins": [ + ], "client": [ "MixinGhastRenderer", - "MixinPlayerModel" + "MixinPlayerModel", + "MixinLivingEntity" ], "injectors": { "defaultRequire": 1