From 799631eece3156fe8cbaadcf56effabb96dcdc7a Mon Sep 17 00:00:00 2001 From: luisc Date: Sat, 23 Mar 2024 23:34:01 -0500 Subject: [PATCH] Removed "render ticks" tick type. Instead, animations and frames can define a tick speed measured in milliseconds. Animations/frames using MC tick type will be 50ms (1000ms/20), and render ticks 20ms. --- src/api | 2 +- .../npcs/client/ClientCacheHandler.java | 4 ++ .../npcs/client/ClientEventHandler.java | 26 ------------ .../java/noppes/npcs/client/ClientProxy.java | 29 ++++++++++++++ .../npcs/client/gui/SubGuiAnimationFrame.java | 8 ++-- .../client/gui/SubGuiAnimationOptions.java | 3 +- .../gui/global/GuiNPCEditAnimation.java | 15 +++---- .../gui/global/GuiNPCManageAnimations.java | 12 ++---- .../npcs/controllers/data/Animation.java | 24 +++++------ .../npcs/controllers/data/AnimationData.java | 40 +++++++++++-------- .../noppes/npcs/controllers/data/Frame.java | 29 +++++++------- 11 files changed, 97 insertions(+), 95 deletions(-) diff --git a/src/api b/src/api index 8acb2a25a..51d086285 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 8acb2a25a0cd85435d3b1e65f85dbd13cedf9813 +Subproject commit 51d086285ed004b4790869d5d35b493439ced7fd diff --git a/src/main/java/noppes/npcs/client/ClientCacheHandler.java b/src/main/java/noppes/npcs/client/ClientCacheHandler.java index 4314a83b8..163cac820 100644 --- a/src/main/java/noppes/npcs/client/ClientCacheHandler.java +++ b/src/main/java/noppes/npcs/client/ClientCacheHandler.java @@ -9,6 +9,7 @@ import noppes.npcs.controllers.data.*; import noppes.npcs.util.CacheHashMap; import java.util.HashMap; +import java.util.HashSet; import java.util.UUID; public class ClientCacheHandler { @@ -18,7 +19,9 @@ public class ClientCacheHandler { public static OverlayQuestTracking questTrackingOverlay = null; public static HashMap customOverlays = new HashMap<>(); public static HashMap> skinOverlays = new HashMap<>(); + public static HashMap playerAnimations = new HashMap<>(); + public static HashSet playingAnimations = new HashSet<>(); public static Party party; @@ -54,6 +57,7 @@ public class ClientCacheHandler { ClientCacheHandler.skinOverlays.clear(); ClientCacheHandler.playerAnimations.clear(); ClientCacheHandler.playerData.animationData.clearCache(); + ClientCacheHandler.playingAnimations.clear(); } public static void clearSkinCache() { diff --git a/src/main/java/noppes/npcs/client/ClientEventHandler.java b/src/main/java/noppes/npcs/client/ClientEventHandler.java index fbc842d3d..9a091508d 100644 --- a/src/main/java/noppes/npcs/client/ClientEventHandler.java +++ b/src/main/java/noppes/npcs/client/ClientEventHandler.java @@ -123,35 +123,9 @@ public class ClientEventHandler { ClientEventHandler.playerModel = null; } - if (data != null && data.isActive() && !Minecraft.getMinecraft().isGamePaused()) { - Animation animation = data.animation; - if (data.isActive() && animation.currentFrame().useRenderTicks()) { - animation.increaseTime(); - } - } - ClientEventHandler.renderingNpc = null; } - @SubscribeEvent - public void onUpdateEntity(LivingEvent.LivingUpdateEvent event) { - if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) { - AnimationData data = null; - if (event.entity instanceof EntityNPCInterface) { - data = ((EntityNPCInterface) event.entity).display.animationData; - } else if (event.entity instanceof EntityPlayer && ClientCacheHandler.playerAnimations.containsKey(event.entity.getUniqueID())) { - data = ClientCacheHandler.playerAnimations.get(event.entity.getUniqueID()); - } - - if (data != null && data.isActive()) { - Animation animation = data.animation; - if (data.isActive() && !animation.currentFrame().useRenderTicks()) { - animation.increaseTime(); - } - } - } - } - @SubscribeEvent public void onRenderPlayer(RenderPlayerEvent.Pre event) { ClientEventHandler.renderingPlayer = event.entityPlayer; diff --git a/src/main/java/noppes/npcs/client/ClientProxy.java b/src/main/java/noppes/npcs/client/ClientProxy.java index 175e15bc9..03fa6a542 100644 --- a/src/main/java/noppes/npcs/client/ClientProxy.java +++ b/src/main/java/noppes/npcs/client/ClientProxy.java @@ -23,6 +23,7 @@ import net.minecraft.stats.Achievement; import net.minecraft.util.ChatComponentText; import net.minecraft.util.ReportedException; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Timer; import net.minecraft.world.World; import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.common.MinecraftForge; @@ -59,6 +60,7 @@ import noppes.npcs.config.ConfigMain; import noppes.npcs.config.StringCache; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.containers.*; +import noppes.npcs.controllers.data.Animation; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.*; import noppes.npcs.entity.data.ModelData; @@ -80,7 +82,34 @@ public class ClientProxy extends CommonProxy { public static FontContainer Font; + private static Timer animationTimer = new Timer(1000); + private static long totalTicks; + public void load() { + Thread thread = (new Thread("Animation Thread") { public void run() { + while (true) { + if (!Minecraft.getMinecraft().isGamePaused()) { + animationTimer.updateTimer(); + } + + try { + for (int i = 0; i < animationTimer.elapsedTicks; ++i) { + for (Animation animation : ClientCacheHandler.playingAnimations) { + if (animation.parent.isActive() && totalTicks % animation.currentFrame().tickDuration() == 0) { + animation.increaseTime(); + } + } + totalTicks++; + } + totalTicks %= 60 * 60 * 1000; + ClientCacheHandler.playingAnimations.removeIf(animation -> + animation.parent.animation != animation || !animation.parent.isActive()); + } catch (Exception ignored) {} + } + }}); + thread.setDaemon(true); + thread.start(); + Font = new FontContainer(ConfigClient.FontType, ConfigClient.FontSize); createFolders(); CustomNpcs.Channel.register(new PacketHandlerClient()); diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java index f719b649b..ce884f297 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java @@ -6,12 +6,12 @@ import noppes.npcs.controllers.data.Frame; public class SubGuiAnimationFrame extends SubGuiInterface implements ITextfieldListener { private final Frame editingFrame; - + public SubGuiAnimationFrame(Frame editingFrame) { this.editingFrame = editingFrame; setBackground("smallbg.png"); } - + @Override public void initGui() { super.initGui(); @@ -33,7 +33,7 @@ public class SubGuiAnimationFrame extends SubGuiInterface implements ITextfieldL // //ticks - button this.addLabel(new GuiNpcLabel(13, "animation.tickType", guiLeft + 5, guiTop + 78)); - this.addButton(new GuiNpcButton(13, guiLeft + 65, guiTop + 72, 75, 20, new String[]{"animation.renderTicks", "animation.mcTicks"}, editingFrame.renderTicks ? 0 : 1)); + //this.addButton(new GuiNpcButton(13, guiLeft + 65, guiTop + 72, 75, 20, new String[]{"animation.renderTicks", "animation.mcTicks"}, editingFrame.renderTicks ? 0 : 1)); } } @@ -46,8 +46,6 @@ public class SubGuiAnimationFrame extends SubGuiInterface implements ITextfieldL editingFrame.setCustomized(!editingFrame.isCustomized()); } else if (guibutton.id == 12 && editingFrame != null) { editingFrame.smooth = (byte) value; - } else if (guibutton.id == 13 && editingFrame != null) { - editingFrame.renderTicks = value == 0; } initGui(); diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java index 4a0724644..ece1dd0ea 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java @@ -20,7 +20,6 @@ public class SubGuiAnimationOptions extends SubGuiInterface { // //ticks - button this.addLabel(new GuiNpcLabel(10, "animation.tickType", guiLeft + 5, guiTop + 16)); - this.addButton(new GuiNpcButton(10, guiLeft + 60, guiTop + 10, 75, 20, new String[]{"animation.renderTicks", "animation.mcTicks"}, animation.renderTicks ? 0 : 1)); // //whileStanding - button this.addLabel(new GuiNpcLabel(11, "animation.whileStanding", guiLeft + 5, guiTop + 36)); @@ -41,7 +40,7 @@ public class SubGuiAnimationOptions extends SubGuiInterface { int value = ((GuiNpcButton)guibutton).getValue(); if (guibutton.id == 10) { - animation.renderTicks = value == 0; + } else if (guibutton.id == 11) { animation.whileStanding = value == 0; } else if (guibutton.id == 12) { diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCEditAnimation.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCEditAnimation.java index 70c3a9470..9ad7e3157 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCEditAnimation.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCEditAnimation.java @@ -3,6 +3,7 @@ package noppes.npcs.client.gui.global; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import noppes.npcs.client.Client; +import noppes.npcs.client.ClientCacheHandler; import noppes.npcs.client.gui.SubGuiAnimationFrame; import noppes.npcs.client.gui.SubGuiAnimationOptions; import noppes.npcs.client.gui.SubGuiColorSelector; @@ -49,7 +50,7 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield this.animation = animation; AnimationData data = npc.display.animationData; - data.animation = animation; + data.setAnimation(animation); data.setEnabled(true); int bodyPartX = 280; @@ -92,9 +93,9 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield AnimationData data = npc.display.animationData; if (!playingAnimation) { - data.animation = new Animation(); + data.setAnimation(new Animation()); data.animation.smooth = animation.smooth; - data.animation.renderTicks = animation.renderTicks; + data.animation.tickDuration = 50; data.animation.loop = 0; if (editingFrame != null) { data.animation.frames.add(editingFrame); @@ -107,7 +108,7 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield if (!frame.isCustomized()) { frame.speed = animation.speed; frame.smooth = animation.smooth; - frame.renderTicks = animation.renderTicks; + frame.tickDuration = animation.tickDuration(); } for (Map.Entry entry : frame.frameParts.entrySet()) { FramePart part = entry.getValue(); @@ -475,7 +476,7 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield } } this.playingAnimation = true; - data.animation = animation; + data.setAnimation(this.animation); data.animation.paused = false; } else if (guibutton.id == 201) { data.animation.paused = true; @@ -510,12 +511,8 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield this.playingAnimation = false; initGui(); } else if (data.isActive()) { - Frame currentFrame = (Frame) data.animation.currentFrame(); long time = mc.theWorld.getTotalWorldTime(); if (time != prevTick) { - if (currentFrame != null && !currentFrame.renderTicks) { - data.animation.increaseTime(); - } GuiNpcLabel label = this.getLabel(213); if (label != null) { label.label += "."; diff --git a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageAnimations.java b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageAnimations.java index 3e27199e6..e59499288 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageAnimations.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCManageAnimations.java @@ -63,9 +63,9 @@ public class GuiNPCManageAnimations extends GuiModelInterface2 implements IScrol AnimationData data = npc.display.animationData; if (!playingAnimation) { - data.animation = new Animation(); + data.setAnimation(new Animation()); data.animation.smooth = animation.smooth; - data.animation.renderTicks = animation.renderTicks; + data.animation.tickDuration = 50; data.animation.loop = 0; if (this.animation.frames.size() > 0) { @@ -109,12 +109,8 @@ public class GuiNPCManageAnimations extends GuiModelInterface2 implements IScrol this.playingAnimation = false; initGui(); } else if (data.isActive()) { - Frame currentFrame = (Frame) data.animation.currentFrame(); long time = mc.theWorld.getTotalWorldTime(); if (time != prevTick) { - if (currentFrame != null && !currentFrame.renderTicks) { - data.animation.increaseTime(); - } GuiNpcLabel label = this.getLabel(94); if (label != null) { label.label += "."; @@ -185,7 +181,7 @@ public class GuiNPCManageAnimations extends GuiModelInterface2 implements IScrol } } this.playingAnimation = true; - data.animation = animation; + data.setAnimation(this.animation); data.animation.paused = false; } else if (guibutton.id == 92) { data.animation.paused = true; @@ -206,7 +202,7 @@ public class GuiNPCManageAnimations extends GuiModelInterface2 implements IScrol this.animation = new Animation(); animation.readFromNBT(compound); setSelected(animation.name); - npc.display.animationData.animation = animation; + npc.display.animationData.setAnimation(this.animation); this.playingAnimation = false; npc.display.animationData.animation.paused = false; initGui(); diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 569ff7614..9bf83f34d 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -24,7 +24,7 @@ public class Animation implements IAnimation { public float speed = 1.0F; public byte smooth = 0; public int loop = -1; //If greater than 0 and less than the amount of frames, the animation will begin looping when it reaches this frame. - public boolean renderTicks = false; // If true, MC ticks are used. If false, render ticks are used. + public int tickDuration = 50; public boolean whileStanding = true; public boolean whileAttacking = true; @@ -93,6 +93,15 @@ public class Animation implements IAnimation { return this.name; } + public int tickDuration() { + return this.tickDuration; + } + + public IAnimation setTickDuration(int tickDuration) { + this.tickDuration = tickDuration; + return this; + } + public IAnimation setSpeed(float speed) { this.speed = speed; return this; @@ -111,15 +120,6 @@ public class Animation implements IAnimation { return this.smooth; } - public IAnimation useRenderTicks(boolean renderTicks) { - this.renderTicks = renderTicks; - return this; - } - - public boolean useRenderTicks() { - return this.renderTicks; - } - public IAnimation doWhileStanding(boolean whileStanding) { this.whileStanding = whileStanding; return this; @@ -183,8 +183,6 @@ public class Animation implements IAnimation { smooth = compound.getByte("Smooth"); loop = compound.getInteger("Loop"); - renderTicks = compound.getBoolean("RenderTicks"); - ArrayList frames = new ArrayList(); NBTTagList list = compound.getTagList("Frames", 10); for (int i = 0; i < list.tagCount(); i++) { @@ -209,8 +207,6 @@ public class Animation implements IAnimation { compound.setByte("Smooth", smooth); compound.setInteger("Loop",loop); - compound.setBoolean("RenderTicks", renderTicks); - NBTTagList list = new NBTTagList(); for(Frame frame : frames){ NBTTagCompound item = frame.writeToNBT(); diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 3dcb76383..12dc2bbf0 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -3,6 +3,7 @@ package noppes.npcs.controllers.data; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -12,6 +13,7 @@ import noppes.npcs.DataDisplay; import noppes.npcs.Server; import noppes.npcs.api.handler.data.IAnimation; import noppes.npcs.api.handler.data.IAnimationData; +import noppes.npcs.client.ClientCacheHandler; import noppes.npcs.constants.EnumAnimationPart; import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.controllers.PlayerDataController; @@ -154,27 +156,33 @@ public class AnimationData implements IAnimationData { if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { this.animation = (Animation) animation; } else { - Animation newAnim = new Animation(); - newAnim.readFromNBT(((Animation) animation).writeToNBT()); - if (this.isActive() && !newAnim.frames.isEmpty()) { - Frame frame = (Frame) this.animation.currentFrame(); - if (frame != null) { - Frame firstFrame = newAnim.frames.get(0); - for (Map.Entry entry : frame.frameParts.entrySet()) { - if (firstFrame.frameParts.containsKey(entry.getKey())) { - FramePart prevFramePart = entry.getValue(); - FramePart newFramePart = firstFrame.frameParts.get(entry.getKey()); - for (int i = 0; i < 3; i++) { - newFramePart.prevPivots[i] = prevFramePart.prevPivots[i]; - newFramePart.prevRotations[i] = prevFramePart.prevRotations[i]; - } + this.clientSetAnimation(animation); + } + } + + @SideOnly(Side.CLIENT) + private void clientSetAnimation(IAnimation animation) { + Animation newAnim = new Animation(); + newAnim.readFromNBT(((Animation) animation).writeToNBT()); + if (this.isActive() && !newAnim.frames.isEmpty()) { + Frame frame = (Frame) this.animation.currentFrame(); + if (frame != null) { + Frame firstFrame = newAnim.frames.get(0); + for (Map.Entry entry : frame.frameParts.entrySet()) { + if (firstFrame.frameParts.containsKey(entry.getKey())) { + FramePart prevFramePart = entry.getValue(); + FramePart newFramePart = firstFrame.frameParts.get(entry.getKey()); + for (int i = 0; i < 3; i++) { + newFramePart.prevPivots[i] = prevFramePart.prevPivots[i]; + newFramePart.prevRotations[i] = prevFramePart.prevRotations[i]; } } } } - this.animation = newAnim; - newAnim.parent = this; } + this.animation = newAnim; + newAnim.parent = this; + ClientCacheHandler.playingAnimations.add(newAnim); } public IAnimation getAnimation() { diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index df80096bd..22077bf1a 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -14,10 +14,11 @@ public class Frame implements IFrame { public Animation parent; public HashMap frameParts = new HashMap<>(); public int duration = 0; + public int tickDuration = 50; + boolean customized = false; public float speed = 1.0F; public byte smooth = 0; - public boolean renderTicks = false; // If true, MC ticks are used. If false, render ticks are used. private int colorMarker = 0xFFFFFF; @@ -75,6 +76,15 @@ public class Frame implements IFrame { return this; } + public int tickDuration() { + return this.tickDuration; + } + + public IFrame setTickDuration(int tickDuration) { + this.tickDuration = tickDuration; + return this; + } + public boolean isCustomized() { return customized; } @@ -102,15 +112,6 @@ public class Frame implements IFrame { return this; } - public IFrame useRenderTicks(boolean renderTicks) { - this.renderTicks = renderTicks; - return this; - } - - public boolean useRenderTicks() { - return this.renderTicks; - } - public int getColorMarker() { return this.colorMarker; } @@ -136,13 +137,13 @@ public class Frame implements IFrame { } if(compound.hasKey("RenderTicks")){ customized = true; - renderTicks = compound.getBoolean("RenderTicks"); + this.tickDuration = 20; } if (!customized) { this.speed = parent.speed; this.smooth = parent.smooth; - this.renderTicks = parent.renderTicks; + this.tickDuration = parent.tickDuration; } HashMap frameParts = new HashMap<>(); @@ -168,7 +169,7 @@ public class Frame implements IFrame { if(customized){ compound.setFloat("Speed", speed); compound.setByte("Smooth", smooth); - compound.setBoolean("RenderTicks", renderTicks); + compound.setInteger("TickDuration", tickDuration); } NBTTagList list = new NBTTagList(); @@ -191,7 +192,7 @@ public class Frame implements IFrame { frame.customized = this.customized; frame.speed = this.speed; frame.smooth = this.smooth; - frame.renderTicks = this.renderTicks; + frame.tickDuration = this.tickDuration; frame.colorMarker = this.colorMarker; return frame; }