From bc089a4e141bc719544f29cd4c0331c82e817b81 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:25:40 -0600 Subject: [PATCH] If the animation data is disabled for players, their last frame of animation will gradually interpolate back to the player's vanilla animations. --- .../npcs/client/PacketHandlerClient.java | 15 +++++--- .../npcs/controllers/data/Animation.java | 9 ++++- .../npcs/controllers/data/AnimationData.java | 26 ++++++++++++-- .../noppes/npcs/mixin/MixinModelRenderer.java | 36 ++++++++++++++----- 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/main/java/noppes/npcs/client/PacketHandlerClient.java b/src/main/java/noppes/npcs/client/PacketHandlerClient.java index ae96b4fa6..61a4ba4c3 100644 --- a/src/main/java/noppes/npcs/client/PacketHandlerClient.java +++ b/src/main/java/noppes/npcs/client/PacketHandlerClient.java @@ -309,7 +309,9 @@ public class PacketHandlerClient extends PacketHandlerServer{ } else { EntityPlayer sendingPlayer = Minecraft.getMinecraft().theWorld.getPlayerEntityByName(Server.readString(buffer)); if (sendingPlayer != null) { - ClientCacheHandler.playerAnimations.put(sendingPlayer.getUniqueID(), new AnimationData(sendingPlayer)); + if (!ClientCacheHandler.playerAnimations.containsKey(sendingPlayer.getUniqueID())) { + ClientCacheHandler.playerAnimations.put(sendingPlayer.getUniqueID(), new AnimationData(sendingPlayer)); + } animationData = ClientCacheHandler.playerAnimations.get(sendingPlayer.getUniqueID()); } } @@ -326,10 +328,13 @@ public class PacketHandlerClient extends PacketHandlerServer{ animationId = animation.getID(); } - Animation animation = new Animation(); - animation.readFromNBT(ClientCacheHandler.animationCache.get(animationId).writeToNBT()); - animationData.animation = animation; - Client.sendData(EnumPacketServer.CacheAnimation, animationId); + if (animationData.allowAnimation) { + Animation animation = new Animation(); + animation.readFromNBT(ClientCacheHandler.animationCache.get(animationId).writeToNBT()); + animationData.animation = animation; + animation.parent = animationData; + Client.sendData(EnumPacketServer.CacheAnimation, animationId); + } } } else if(type == EnumPacketClient.DISABLE_MOUSE_INPUT) { diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 0950ee42d..be4e6262c 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -2,6 +2,7 @@ package noppes.npcs.controllers.data; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import noppes.npcs.api.handler.data.IAnimation; @@ -13,7 +14,7 @@ import java.util.ArrayList; public class Animation implements IAnimation { - + public AnimationData parent; //Client-sided only public int id = -1; // Only for internal usage public ArrayList frames = new ArrayList<>(); @@ -229,6 +230,10 @@ public class Animation implements IAnimation { if (paused) return; + if (this.parent != null && this.currentFrame < this.frames.size()) { + this.parent.finishedFrame = this.currentFrame; + } + this.currentFrameTime++; if (this.currentFrameTime == this.currentFrame().getDuration()) { Frame prevFrame = (Frame) this.currentFrame(); @@ -247,6 +252,8 @@ public class Animation implements IAnimation { nextFrame.frameParts.get(part).prevPivots = prevFrame.frameParts.get(part).prevPivots; } } + } else if (this.parent != null && this.currentFrame > this.loop) { + this.parent.finishedTime = this.parent.animationEntity.getAge(); } } } diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index b4110fd1b..72d08ff16 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -14,6 +14,7 @@ import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.entity.EntityNPCInterface; +import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -27,11 +28,25 @@ public class AnimationData implements IAnimationData { private final HashSet cachedAnimationIDs = new HashSet<>(); + //Client-side values + public EntityLivingBase animationEntity; + public int finishedTime = -1; + public int finishedFrame = -1; + public AnimationData(Object parent){ this.parent = parent; + if (parent instanceof DataDisplay) { + this.animationEntity = ((DataDisplay) parent).npc; + } else if (parent instanceof EntityPlayer) { + this.animationEntity = (EntityLivingBase) parent; + } } public void updateClient() { + this.updateClient(new EntityPlayer[0]); + } + + public void updateClient(EntityPlayer... excludedPlayers) { EntityLivingBase sendingEntity = parent instanceof PlayerData ? ((PlayerData) parent).player : parent instanceof DataDisplay ? ((DataDisplay) parent).npc : null; float range = parent instanceof PlayerData ? 160 : 60; if (sendingEntity != null) { @@ -40,6 +55,8 @@ public class AnimationData implements IAnimationData { sendingEntity.posX - range, sendingEntity.posY - range, sendingEntity.posZ - range, sendingEntity.posX + range, sendingEntity.posY + range, sendingEntity.posZ + range)); + entities.removeIf(player -> Arrays.stream(excludedPlayers).anyMatch(exp -> player == exp)); + NBTTagCompound animationNBT = null; for (EntityPlayer player : entities) { AnimationData animationData = PlayerDataController.Instance.getPlayerData(player).animationData; @@ -110,11 +127,16 @@ public class AnimationData implements IAnimationData { } public void readFromNBT(NBTTagCompound compound) { - this.allowAnimation = compound.getBoolean("AllowAnimation"); + this.setEnabled(compound.getBoolean("AllowAnimation")); } public void setEnabled(boolean enabled) { - this.allowAnimation = enabled; + if (this.allowAnimation != enabled) { + this.allowAnimation = enabled; + if (this.parent instanceof EntityPlayer) { + this.finishedTime = enabled ? -1 : ((EntityPlayer) this.parent).getAge(); + } + } } public boolean enabled() { diff --git a/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java index 41accf7fa..ff9e21cf1 100644 --- a/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java +++ b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java @@ -5,6 +5,7 @@ import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelRenderer; +import noppes.npcs.controllers.data.Animation; import noppes.npcs.controllers.data.AnimationData; import noppes.npcs.client.ClientCacheHandler; import noppes.npcs.client.ClientEventHandler; @@ -123,7 +124,9 @@ public abstract class MixinModelRenderer { } catch (Exception ignored){} - if (partType != null && animData != null) { + if (partType != null && animData != null && animData.animation != null) { + boolean animDataActive = animData.isActive(); + if (!ClientEventHandler.originalValues.containsKey((ModelRenderer) (Object) this)) { FramePart part = new FramePart(); part.pivot = new float[]{prevPointX, prevPointY, prevPointZ}; @@ -131,23 +134,38 @@ public abstract class MixinModelRenderer { ClientEventHandler.originalValues.put((ModelRenderer) (Object) this, part); } FramePart originalPart = ClientEventHandler.originalValues.get((ModelRenderer) (Object) this); - if (animData.isActive()) { - Frame frame = (Frame) animData.animation.currentFrame(); - if (frame.frameParts.containsKey(partType)) { - FramePart part = frame.frameParts.get(partType); - if (partType == mainPartType) { + Frame frame = (Frame) animData.animation.currentFrame(); + if (!animDataActive && animData.finishedFrame >= 0 && animData.finishedFrame < animData.animation.frames.size()) { + frame = animData.animation.frames.get(animData.finishedFrame); + } + + if (frame != null && frame.frameParts.containsKey(partType)) { + FramePart part = frame.frameParts.get(partType); + if (partType == mainPartType) { + if (animDataActive) { part.interpolateAngles(); part.interpolateOffset(); + } else { + float speed = 0.4F; + part.prevPivots[0] = part.prevPivots[0] * (1.0F - speed); + part.prevPivots[1] = part.prevPivots[1] * (1.0F - speed); + part.prevPivots[2] = part.prevPivots[2] * (1.0F - speed); + part.prevRotations[0] = part.prevRotations[0] * (1.0F - speed) + (this.rotateAngleX * speed); + part.prevRotations[1] = part.prevRotations[1] * (1.0F - speed) + (this.rotateAngleY * speed); + part.prevRotations[2] = part.prevRotations[2] * (1.0F - speed) + (this.rotateAngleZ * speed); + } + + if (animDataActive || (ClientEventHandler.renderingPlayer.getAge() - animData.finishedTime < 20)) { this.rotationPointX = originalPart.pivot[0] + part.prevPivots[0]; this.rotationPointY = originalPart.pivot[1] + part.prevPivots[1]; this.rotationPointZ = originalPart.pivot[2] + part.prevPivots[2]; this.rotateAngleX = part.prevRotations[0]; this.rotateAngleY = part.prevRotations[1]; this.rotateAngleZ = part.prevRotations[2]; - } else { - currentPart = part; - this.rotateAngleZ += part.prevRotations[2]; } + } else { + currentPart = part; + this.rotateAngleZ += part.prevRotations[2]; } } }