From 799631eece3156fe8cbaadcf56effabb96dcdc7a Mon Sep 17 00:00:00 2001 From: luisc Date: Sat, 23 Mar 2024 23:34:01 -0500 Subject: [PATCH 01/32] 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; } From cf4e5f22b12222c3d0f4c3be6219ab39893bebe3 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 00:05:25 -0500 Subject: [PATCH 02/32] Changed animation and frame GUIs to be able to edit tick durations. --- .../npcs/client/gui/SubGuiAnimationFrame.java | 35 ++++++++++++------- .../client/gui/SubGuiAnimationOptions.java | 22 +++++++----- .../assets/customnpcs/lang/en_US.lang | 4 +-- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java index ce884f297..9518f0977 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java @@ -18,33 +18,38 @@ public class SubGuiAnimationFrame extends SubGuiInterface implements ITextfieldL // //customized - button, enables all the following options. this.addLabel(new GuiNpcLabel(10, "animation.customized", guiLeft + 5, guiTop + 16)); - this.addButton(new GuiNpcButton(10, guiLeft + 65, guiTop + 10, 30, 20, new String[]{"gui.yes", "gui.no"}, editingFrame.isCustomized() ? 0 : 1)); + this.addButton(new GuiNpcButton(10, guiLeft + 75, guiTop + 10, 30, 20, new String[]{"gui.yes", "gui.no"}, editingFrame.isCustomized() ? 0 : 1)); if (editingFrame.isCustomized()) { // //speed - textfield - this.addLabel(new GuiNpcLabel(11, "stats.speed", guiLeft + 5, guiTop + 36)); - this.addTextField(new GuiNpcTextField(11, this, guiLeft + 65, guiTop + 32, 30, 15, editingFrame.speed + "")); + this.addLabel(new GuiNpcLabel(11, "stats.speed", guiLeft + 5, guiTop + 42)); + this.addTextField(new GuiNpcTextField(11, this, guiLeft + 75, guiTop + 37, 30, 15, editingFrame.speed + "")); this.getTextField(11).floatsOnly = true; this.getTextField(11).setMinMaxDefaultFloat(0, Float.MAX_VALUE, 1.0F); // //smooth - button - this.addLabel(new GuiNpcLabel(12, "animation.smoothing", guiLeft + 5, guiTop + 58)); - this.addButton(new GuiNpcButton(12, guiLeft + 65, guiTop + 52, 60, 20, new String[]{"animation.smooth", "animation.linear", "gui.none"}, editingFrame.smooth)); + this.addLabel(new GuiNpcLabel(12, "animation.smoothing", guiLeft + 5, guiTop + 63)); + this.addButton(new GuiNpcButton(12, guiLeft + 75, guiTop + 55, 60, 20, new String[]{"animation.smooth", "animation.linear", "gui.none"}, editingFrame.smooth)); // - //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)); + //tick duration - textfield + this.addLabel(new GuiNpcLabel(13, "animation.tickDuration", guiLeft + 5, guiTop + 84)); + this.addTextField(new GuiNpcTextField(13, this, guiLeft + 75, guiTop + 79, 40, 15, editingFrame.tickDuration + "")); + this.getTextField(13).integersOnly = true; + this.getTextField(13).setMinMaxDefault(1, Integer.MAX_VALUE, 50); } } @Override protected void actionPerformed(GuiButton guibutton) { super.actionPerformed(guibutton); - int value = ((GuiNpcButton)guibutton).getValue(); + if (this.editingFrame == null) { + return; + } - if (guibutton.id == 10 && editingFrame != null) { + int value = ((GuiNpcButton)guibutton).getValue(); + if (guibutton.id == 10) { editingFrame.setCustomized(!editingFrame.isCustomized()); - } else if (guibutton.id == 12 && editingFrame != null) { + } else if (guibutton.id == 12) { editingFrame.smooth = (byte) value; } @@ -53,8 +58,14 @@ public class SubGuiAnimationFrame extends SubGuiInterface implements ITextfieldL @Override public void unFocused(GuiNpcTextField textfield) { - if (textfield.id == 11 && this.editingFrame != null) { + if (this.editingFrame == null) { + return; + } + + if (textfield.id == 11) { this.editingFrame.speed = textfield.getFloat(); + } else if (textfield.id == 13) { + this.editingFrame.tickDuration = textfield.getInteger(); } } } diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java index ece1dd0ea..1f3b7f0d1 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationOptions.java @@ -1,12 +1,10 @@ package noppes.npcs.client.gui; import net.minecraft.client.gui.GuiButton; -import noppes.npcs.client.gui.util.GuiNpcButton; -import noppes.npcs.client.gui.util.GuiNpcLabel; -import noppes.npcs.client.gui.util.SubGuiInterface; +import noppes.npcs.client.gui.util.*; import noppes.npcs.controllers.data.Animation; -public class SubGuiAnimationOptions extends SubGuiInterface { +public class SubGuiAnimationOptions extends SubGuiInterface implements ITextfieldListener { private final Animation animation; public SubGuiAnimationOptions(Animation animation) { @@ -19,7 +17,10 @@ public class SubGuiAnimationOptions extends SubGuiInterface { super.initGui(); // //ticks - button - this.addLabel(new GuiNpcLabel(10, "animation.tickType", guiLeft + 5, guiTop + 16)); + this.addLabel(new GuiNpcLabel(10, "animation.tickDuration", guiLeft + 5, guiTop + 16)); + this.addTextField(new GuiNpcTextField(10, this, guiLeft + 80, guiTop + 12, 40, 15, animation.tickDuration + "")); + this.getTextField(10).integersOnly = true; + this.getTextField(10).setMinMaxDefault(1, Integer.MAX_VALUE, 50); // //whileStanding - button this.addLabel(new GuiNpcLabel(11, "animation.whileStanding", guiLeft + 5, guiTop + 36)); @@ -39,9 +40,7 @@ public class SubGuiAnimationOptions extends SubGuiInterface { super.actionPerformed(guibutton); int value = ((GuiNpcButton)guibutton).getValue(); - if (guibutton.id == 10) { - - } else if (guibutton.id == 11) { + if (guibutton.id == 11) { animation.whileStanding = value == 0; } else if (guibutton.id == 12) { animation.whileAttacking = value == 0; @@ -51,4 +50,11 @@ public class SubGuiAnimationOptions extends SubGuiInterface { initGui(); } + + @Override + public void unFocused(GuiNpcTextField textfield) { + if (textfield.id == 10) { + animation.tickDuration = textfield.getInteger(); + } + } } diff --git a/src/main/resources/assets/customnpcs/lang/en_US.lang b/src/main/resources/assets/customnpcs/lang/en_US.lang index 5b3de0825..b56c4bf82 100644 --- a/src/main/resources/assets/customnpcs/lang/en_US.lang +++ b/src/main/resources/assets/customnpcs/lang/en_US.lang @@ -1167,9 +1167,7 @@ animation.smoothing=Smoothing animation.linear=Linear animation.smooth=Smooth animation.loop=Loop -animation.tickType=Tick Type -animation.mcTicks=MC Ticks -animation.renderTicks=Render Ticks +animation.tickDuration=Tick Duration animation.whileStanding=While Standing animation.whileAttacking=While Attacking animation.whileMoving=While Moving From 16c3395d8c53feac034fd34082d4e187ec06425b Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:14:11 -0500 Subject: [PATCH 03/32] Made animation threading compatible on the client & server side --- src/main/java/noppes/npcs/CommonProxy.java | 73 +++++++++++++++- .../npcs/client/ClientCacheHandler.java | 4 +- .../java/noppes/npcs/client/ClientProxy.java | 29 +------ .../npcs/controllers/data/Animation.java | 1 - .../npcs/controllers/data/AnimationData.java | 31 ++++--- .../java/noppes/npcs/util/MillisTimer.java | 86 +++++++++++++++++++ 6 files changed, 176 insertions(+), 48 deletions(-) create mode 100644 src/main/java/noppes/npcs/util/MillisTimer.java diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 067e2f1b3..3f0270f9d 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -1,7 +1,11 @@ package noppes.npcs; import cpw.mods.fml.common.network.IGuiHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.ModelBiped; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; @@ -14,19 +18,80 @@ import noppes.npcs.api.IWorld; import noppes.npcs.blocks.tiles.TileNpcContainer; 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.EntityNPCInterface; +import noppes.npcs.util.MillisTimer; + +import java.util.HashSet; public class CommonProxy implements IGuiHandler { - - public boolean newVersionAvailable = false; - public int revision = 1; + public static HashSet clientPlayingAnimations = new HashSet<>(); + public static HashSet serverPlayingAnimations = new HashSet<>(); + protected MillisTimer animationTimer = new MillisTimer(1000); + protected long totalTicks; public void load() { + this.createAnimationThread(); + CustomNpcs.Channel.register(new PacketHandlerServer()); CustomNpcs.ChannelPlayer.register(new PacketHandlerPlayer()); } + protected void createAnimationThread() { + Thread thread = (new Thread("Animation Thread") { public void run() { + while (true) { + if (!CustomNpcs.proxy.hasClient() || !Minecraft.getMinecraft().isGamePaused()) { + animationTimer.updateTimer(); + } + + HashSet playingAnimations = CustomNpcs.proxy.hasClient() ? clientPlayingAnimations : serverPlayingAnimations; + for (int i = 0; i < animationTimer.elapsedTicks; ++i) { + for (Animation animation : playingAnimations) { + if (animation.parent.isActive() && totalTicks % animation.currentFrame().tickDuration() == 0) { + animation.increaseTime(); + } + } + totalTicks++; + } + totalTicks %= 60 * 60 * 1000; + clientPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); + serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); + } + }}); + thread.setDaemon(true); + thread.start(); + } + + private boolean removeAnimation(Animation animation) { + if (animation.parent == null || animation.parent.animation != animation) return true; + + Entity entity = null; + if (animation.parent.parent instanceof DataDisplay) { + entity = ((DataDisplay)animation.parent.parent).npc; + } else { + if (animation.parent.parent instanceof PlayerData) { + entity = ((PlayerData) animation.parent.parent).player; + } else if (animation.parent.parent instanceof EntityPlayer) { + entity = (EntityPlayer) animation.parent.parent; + } + } + + if (entity == null) return true; + + if (CustomNpcs.proxy.hasClient()) { + return clientRemoveAnimation(entity); + } else { + return entity.worldObj == null || !entity.worldObj.loadedEntityList.contains(entity); + } + } + + @SideOnly(Side.CLIENT) + private boolean clientRemoveAnimation(Entity entity) { + return Minecraft.getMinecraft().currentScreen == null + && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity); + } + public PlayerData getPlayerData(EntityPlayer player) { return null; } @@ -166,4 +231,4 @@ public class CommonProxy implements IGuiHandler { public boolean isGUIOpen(){ return false; } -} \ No newline at end of file +} diff --git a/src/main/java/noppes/npcs/client/ClientCacheHandler.java b/src/main/java/noppes/npcs/client/ClientCacheHandler.java index 163cac820..bf9c920f4 100644 --- a/src/main/java/noppes/npcs/client/ClientCacheHandler.java +++ b/src/main/java/noppes/npcs/client/ClientCacheHandler.java @@ -1,6 +1,7 @@ package noppes.npcs.client; import net.minecraft.util.ResourceLocation; +import noppes.npcs.CommonProxy; import noppes.npcs.client.gui.OverlayQuestTracking; import noppes.npcs.client.gui.customoverlay.OverlayCustom; import noppes.npcs.client.renderer.ImageData; @@ -21,7 +22,6 @@ public class ClientCacheHandler { public static HashMap> skinOverlays = new HashMap<>(); public static HashMap playerAnimations = new HashMap<>(); - public static HashSet playingAnimations = new HashSet<>(); public static Party party; @@ -57,7 +57,7 @@ public class ClientCacheHandler { ClientCacheHandler.skinOverlays.clear(); ClientCacheHandler.playerAnimations.clear(); ClientCacheHandler.playerData.animationData.clearCache(); - ClientCacheHandler.playingAnimations.clear(); + CommonProxy.clientPlayingAnimations.clear(); } public static void clearSkinCache() { diff --git a/src/main/java/noppes/npcs/client/ClientProxy.java b/src/main/java/noppes/npcs/client/ClientProxy.java index 03fa6a542..d33558f3c 100644 --- a/src/main/java/noppes/npcs/client/ClientProxy.java +++ b/src/main/java/noppes/npcs/client/ClientProxy.java @@ -23,7 +23,6 @@ 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; @@ -60,7 +59,6 @@ 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; @@ -82,33 +80,8 @@ 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(); + this.createAnimationThread(); Font = new FontContainer(ConfigClient.FontType, ConfigClient.FontSize); createFolders(); diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 9bf83f34d..6754a3825 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -220,7 +220,6 @@ public class Animation implements IAnimation { return compound; } - @SideOnly(Side.CLIENT) public void increaseTime() { if (paused) return; diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 12dc2bbf0..3bfb538c5 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -9,6 +9,8 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; +import noppes.npcs.CommonProxy; +import noppes.npcs.CustomNpcs; import noppes.npcs.DataDisplay; import noppes.npcs.Server; import noppes.npcs.api.handler.data.IAnimation; @@ -56,6 +58,10 @@ public class AnimationData implements IAnimationData { 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) { + if (!CustomNpcs.proxy.hasClient()) { + CommonProxy.serverPlayingAnimations.add(this.animation); + } + List entities = sendingEntity.worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox( sendingEntity.posX - range, sendingEntity.posY - range, sendingEntity.posZ - range, sendingEntity.posX + range, sendingEntity.posY + range, sendingEntity.posZ + range)); @@ -153,18 +159,20 @@ public class AnimationData implements IAnimationData { } public void setAnimation(IAnimation animation) { - if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { - this.animation = (Animation) animation; - } else { - this.clientSetAnimation(animation); + Animation newAnim = null; + if (animation != null) { + newAnim = new Animation(); + newAnim.readFromNBT(((Animation) animation).writeToNBT()); + newAnim.parent = this; } - } - @SideOnly(Side.CLIENT) - private void clientSetAnimation(IAnimation animation) { - Animation newAnim = new Animation(); - newAnim.readFromNBT(((Animation) animation).writeToNBT()); - if (this.isActive() && !newAnim.frames.isEmpty()) { + if (CustomNpcs.proxy.hasClient() && newAnim != null) { + CommonProxy.clientPlayingAnimations.remove(this.animation); + CommonProxy.clientPlayingAnimations.add(newAnim); + } + this.animation = newAnim; + + if (this.isActive() && newAnim != null && !newAnim.frames.isEmpty()) { Frame frame = (Frame) this.animation.currentFrame(); if (frame != null) { Frame firstFrame = newAnim.frames.get(0); @@ -180,9 +188,6 @@ public class AnimationData implements IAnimationData { } } } - this.animation = newAnim; - newAnim.parent = this; - ClientCacheHandler.playingAnimations.add(newAnim); } public IAnimation getAnimation() { diff --git a/src/main/java/noppes/npcs/util/MillisTimer.java b/src/main/java/noppes/npcs/util/MillisTimer.java new file mode 100644 index 000000000..f149f548f --- /dev/null +++ b/src/main/java/noppes/npcs/util/MillisTimer.java @@ -0,0 +1,86 @@ +package noppes.npcs.util; + +import org.lwjgl.Sys; + +public class MillisTimer { + float ticksPerSecond; + private double lastHRTime; + public int elapsedTicks; + public float renderPartialTicks; + public float timerSpeed = 1.0F; + public float elapsedPartialTicks; + private long lastSyncSysClock; + private long lastSyncHRClock; + private long field_74285_i; + private double timeSyncAdjustment = 1.0D; + + public MillisTimer(float p_i1018_1_) + { + this.ticksPerSecond = p_i1018_1_; + this.lastSyncSysClock = this.getLastSyncSysClock(); + this.lastSyncHRClock = System.nanoTime() / 1000000L; + } + + /** + * Updates all fields of the Timer using the current time + */ + public void updateTimer() + { + long i = this.getLastSyncSysClock(); + long j = i - this.lastSyncSysClock; + long k = System.nanoTime() / 1000000L; + double d0 = (double)k / 1000.0D; + + if (j <= 1000L && j >= 0L) + { + this.field_74285_i += j; + + if (this.field_74285_i > 1000L) + { + long l = k - this.lastSyncHRClock; + double d1 = (double)this.field_74285_i / (double)l; + this.timeSyncAdjustment += (d1 - this.timeSyncAdjustment) * 0.20000000298023224D; + this.lastSyncHRClock = k; + this.field_74285_i = 0L; + } + + if (this.field_74285_i < 0L) + { + this.lastSyncHRClock = k; + } + } + else + { + this.lastHRTime = d0; + } + + this.lastSyncSysClock = i; + double d2 = (d0 - this.lastHRTime) * this.timeSyncAdjustment; + this.lastHRTime = d0; + + if (d2 < 0.0D) + { + d2 = 0.0D; + } + + if (d2 > 1.0D) + { + d2 = 1.0D; + } + + this.elapsedPartialTicks = (float)((double)this.elapsedPartialTicks + d2 * (double)this.timerSpeed * (double)this.ticksPerSecond); + this.elapsedTicks = (int)this.elapsedPartialTicks; + this.elapsedPartialTicks -= (float)this.elapsedTicks; + + if (this.elapsedTicks > 10) + { + this.elapsedTicks = 10; + } + + this.renderPartialTicks = this.elapsedPartialTicks; + } + + private long getLastSyncSysClock() { + return Sys.getTime() * 1000L / Sys.getTimerResolution(); + } +} From 59cd5b6fe6b62c3397d9e159e342507dc40b9eb5 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:16:24 -0500 Subject: [PATCH 04/32] modified removeAnimation lambda a bit --- src/main/java/noppes/npcs/CommonProxy.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 3f0270f9d..08510d08e 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -64,7 +64,9 @@ public class CommonProxy implements IGuiHandler { } private boolean removeAnimation(Animation animation) { - if (animation.parent == null || animation.parent.animation != animation) return true; + if (animation.currentFrame() == null || animation.parent == null || animation.parent.animation != animation) { + return true; + } Entity entity = null; if (animation.parent.parent instanceof DataDisplay) { From 3f3700af4f32f9d744356a86cca69c2596491c08 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:26:23 -0500 Subject: [PATCH 05/32] fixed concurrent exception thrown when removing animations from being ticked --- src/main/java/noppes/npcs/CommonProxy.java | 12 ++++++++---- .../noppes/npcs/controllers/data/AnimationData.java | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 08510d08e..bc49db973 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -23,11 +23,12 @@ import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.util.MillisTimer; +import java.util.ConcurrentModificationException; import java.util.HashSet; public class CommonProxy implements IGuiHandler { - public static HashSet clientPlayingAnimations = new HashSet<>(); - public static HashSet serverPlayingAnimations = new HashSet<>(); + public final static HashSet clientPlayingAnimations = new HashSet<>(); + public final static HashSet serverPlayingAnimations = new HashSet<>(); protected MillisTimer animationTimer = new MillisTimer(1000); protected long totalTicks; @@ -55,8 +56,11 @@ public class CommonProxy implements IGuiHandler { totalTicks++; } totalTicks %= 60 * 60 * 1000; - clientPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); - serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); + + try { + clientPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); + serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); + } catch (ConcurrentModificationException ignored) {} } }}); thread.setDaemon(true); diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 3bfb538c5..d89a56ae4 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -167,8 +167,10 @@ public class AnimationData implements IAnimationData { } if (CustomNpcs.proxy.hasClient() && newAnim != null) { - CommonProxy.clientPlayingAnimations.remove(this.animation); - CommonProxy.clientPlayingAnimations.add(newAnim); + synchronized (CommonProxy.clientPlayingAnimations) { + CommonProxy.clientPlayingAnimations.remove(this.animation); + CommonProxy.clientPlayingAnimations.add(newAnim); + } } this.animation = newAnim; From a1fa0564c3effb8ce12178506e37e85c8c6eaf42 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:29:19 -0500 Subject: [PATCH 06/32] removed synchronized block --- .../java/noppes/npcs/controllers/data/AnimationData.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index d89a56ae4..3bfb538c5 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -167,10 +167,8 @@ public class AnimationData implements IAnimationData { } if (CustomNpcs.proxy.hasClient() && newAnim != null) { - synchronized (CommonProxy.clientPlayingAnimations) { - CommonProxy.clientPlayingAnimations.remove(this.animation); - CommonProxy.clientPlayingAnimations.add(newAnim); - } + CommonProxy.clientPlayingAnimations.remove(this.animation); + CommonProxy.clientPlayingAnimations.add(newAnim); } this.animation = newAnim; From fab170a9c97e089474688d46832954bc4741f5cf Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:31:56 -0500 Subject: [PATCH 07/32] added tick duration read/write to nbt --- src/main/java/noppes/npcs/controllers/data/Animation.java | 2 ++ src/main/java/noppes/npcs/controllers/data/Frame.java | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 6754a3825..aafb8cdcf 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -182,6 +182,7 @@ public class Animation implements IAnimation { speed = compound.getFloat("Speed"); smooth = compound.getByte("Smooth"); loop = compound.getInteger("Loop"); + tickDuration = compound.getInteger("TickDuration"); ArrayList frames = new ArrayList(); NBTTagList list = compound.getTagList("Frames", 10); @@ -206,6 +207,7 @@ public class Animation implements IAnimation { compound.setFloat("Speed", speed); compound.setByte("Smooth", smooth); compound.setInteger("Loop",loop); + compound.setInteger("TickDuration", tickDuration); NBTTagList list = new NBTTagList(); for(Frame frame : frames){ diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index 22077bf1a..033ac6692 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -135,7 +135,10 @@ public class Frame implements IFrame { customized = true; smooth = compound.getByte("Smooth"); } - if(compound.hasKey("RenderTicks")){ + + if (compound.hasKey("TickDuration")) { + this.tickDuration = compound.getInteger("TickDuration"); + } else if(compound.hasKey("RenderTicks")){ customized = true; this.tickDuration = 20; } From b52b76128c8fffccfe0fd1e2c775f92d000ef194 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:36:13 -0500 Subject: [PATCH 08/32] Revert "added tick duration read/write to nbt" This reverts commit fab170a9c97e089474688d46832954bc4741f5cf. --- src/main/java/noppes/npcs/controllers/data/Animation.java | 2 -- src/main/java/noppes/npcs/controllers/data/Frame.java | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index aafb8cdcf..6754a3825 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -182,7 +182,6 @@ public class Animation implements IAnimation { speed = compound.getFloat("Speed"); smooth = compound.getByte("Smooth"); loop = compound.getInteger("Loop"); - tickDuration = compound.getInteger("TickDuration"); ArrayList frames = new ArrayList(); NBTTagList list = compound.getTagList("Frames", 10); @@ -207,7 +206,6 @@ public class Animation implements IAnimation { compound.setFloat("Speed", speed); compound.setByte("Smooth", smooth); compound.setInteger("Loop",loop); - compound.setInteger("TickDuration", tickDuration); NBTTagList list = new NBTTagList(); for(Frame frame : frames){ diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index 033ac6692..22077bf1a 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -135,10 +135,7 @@ public class Frame implements IFrame { customized = true; smooth = compound.getByte("Smooth"); } - - if (compound.hasKey("TickDuration")) { - this.tickDuration = compound.getInteger("TickDuration"); - } else if(compound.hasKey("RenderTicks")){ + if(compound.hasKey("RenderTicks")){ customized = true; this.tickDuration = 20; } From d1ca49fc3b17523726f7d3a6f0330fed1246bbcc Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:51:36 -0500 Subject: [PATCH 09/32] Made tick duration return the correct value for animating. --- src/main/java/noppes/npcs/CommonProxy.java | 3 ++- src/main/java/noppes/npcs/controllers/data/Frame.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index bc49db973..68c9db672 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -49,7 +49,8 @@ public class CommonProxy implements IGuiHandler { HashSet playingAnimations = CustomNpcs.proxy.hasClient() ? clientPlayingAnimations : serverPlayingAnimations; for (int i = 0; i < animationTimer.elapsedTicks; ++i) { for (Animation animation : playingAnimations) { - if (animation.parent.isActive() && totalTicks % animation.currentFrame().tickDuration() == 0) { + int tickDuration = animation.currentFrame().tickDuration(); + if (animation.parent.isActive() && totalTicks % tickDuration == 0) { animation.increaseTime(); } } diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index 22077bf1a..df810234b 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -77,7 +77,7 @@ public class Frame implements IFrame { } public int tickDuration() { - return this.tickDuration; + return !this.customized && this.parent != null ? this.parent.tickDuration : this.tickDuration; } public IFrame setTickDuration(int tickDuration) { From a564bcdb0ec067a9e5ecf384caacad5575404ba7 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 03:56:14 -0500 Subject: [PATCH 10/32] Added tick duration read/write nbt --- src/main/java/noppes/npcs/controllers/data/Animation.java | 7 +++++++ src/main/java/noppes/npcs/controllers/data/Frame.java | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 6754a3825..4e2ce3c8e 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -183,6 +183,12 @@ public class Animation implements IAnimation { smooth = compound.getByte("Smooth"); loop = compound.getInteger("Loop"); + if (compound.hasKey("TickDuration")) { + this.tickDuration = compound.getInteger("TickDuration"); + } else if(compound.hasKey("RenderTicks")){ + this.tickDuration = compound.getBoolean("RenderTicks") ? 20 : 50; + } + ArrayList frames = new ArrayList(); NBTTagList list = compound.getTagList("Frames", 10); for (int i = 0; i < list.tagCount(); i++) { @@ -206,6 +212,7 @@ public class Animation implements IAnimation { compound.setFloat("Speed", speed); compound.setByte("Smooth", smooth); compound.setInteger("Loop",loop); + compound.setInteger("TickDuration", tickDuration); NBTTagList list = new NBTTagList(); for(Frame frame : frames){ diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index df810234b..c59fd0ec8 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -135,9 +135,13 @@ public class Frame implements IFrame { customized = true; smooth = compound.getByte("Smooth"); } - if(compound.hasKey("RenderTicks")){ + + if (compound.hasKey("TickDuration")) { + customized = true; + this.tickDuration = compound.getInteger("TickDuration"); + } else if(compound.hasKey("RenderTicks")){ customized = true; - this.tickDuration = 20; + this.tickDuration = compound.getBoolean("RenderTicks") ? 20 : 50; } if (!customized) { From 61781710f1c57798e2259b0b3463da7f9f44be7b Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 17:03:58 -0500 Subject: [PATCH 11/32] Implemented animation events and made some event classes abstract. --- src/api | 2 +- src/main/java/noppes/npcs/EventHooks.java | 69 +++++++---- .../noppes/npcs/constants/EnumScriptType.java | 18 ++- .../npcs/controllers/data/Animation.java | 16 +++ .../npcs/controllers/data/AnimationData.java | 45 ++++++-- .../npcs/controllers/data/DataScript.java | 5 +- .../npcs/scripted/event/AnimationEvent.java | 108 ++++++++++++++++++ .../npcs/scripted/event/BlockEvent.java | 2 +- .../npcs/scripted/event/CustomGuiEvent.java | 2 +- .../npcs/scripted/event/CustomNPCsEvent.java | 6 +- .../npcs/scripted/event/DialogEvent.java | 2 +- .../npcs/scripted/event/FactionEvent.java | 2 +- .../noppes/npcs/scripted/event/ItemEvent.java | 2 +- .../noppes/npcs/scripted/event/NpcEvent.java | 2 +- .../npcs/scripted/event/PartyEvent.java | 2 +- .../npcs/scripted/event/PlayerEvent.java | 2 +- .../npcs/scripted/event/ProjectileEvent.java | 13 ++- .../npcs/scripted/event/QuestEvent.java | 2 +- 18 files changed, 254 insertions(+), 46 deletions(-) create mode 100644 src/main/java/noppes/npcs/scripted/event/AnimationEvent.java diff --git a/src/api b/src/api index 51d086285..cd180e452 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 51d086285ed004b4790869d5d35b493439ced7fd +Subproject commit cd180e4520d766f927fb954433fd7812155a501f diff --git a/src/main/java/noppes/npcs/EventHooks.java b/src/main/java/noppes/npcs/EventHooks.java index 5bb1dc4eb..5b63a426c 100644 --- a/src/main/java/noppes/npcs/EventHooks.java +++ b/src/main/java/noppes/npcs/EventHooks.java @@ -15,11 +15,12 @@ import net.minecraft.world.WorldServer; import net.minecraftforge.event.entity.EntityEvent; import net.minecraftforge.event.world.WorldEvent; import noppes.npcs.api.IWorld; -import noppes.npcs.api.entity.IEntity; -import noppes.npcs.api.entity.IPlayer; -import noppes.npcs.api.entity.IProjectile; +import noppes.npcs.api.entity.*; +import noppes.npcs.api.event.IAnimationEvent; import noppes.npcs.api.gui.ICustomGui; import noppes.npcs.api.gui.IItemSlot; +import noppes.npcs.api.handler.data.IAnimation; +import noppes.npcs.api.handler.data.IFrame; import noppes.npcs.api.item.IItemCustom; import noppes.npcs.api.item.IItemStack; import noppes.npcs.constants.EnumScriptType; @@ -119,7 +120,6 @@ public class EventHooks { return; noppes.npcs.scripted.event.NpcEvent.InitEvent event = new noppes.npcs.scripted.event.NpcEvent.InitEvent(npc.wrappedNPC); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.INIT, event); npc.script.callScript(EnumScriptType.INIT, event); NpcAPI.EVENT_BUS.post(event); npc.advanced.soulStoneInit = false; @@ -130,7 +130,6 @@ public class EventHooks { return; noppes.npcs.scripted.event.NpcEvent.UpdateEvent event = new noppes.npcs.scripted.event.NpcEvent.UpdateEvent(npc.wrappedNPC); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.TICK, event); npc.script.callScript(EnumScriptType.TICK, event); NpcAPI.EVENT_BUS.post(event); } @@ -140,7 +139,6 @@ public class EventHooks { return false; NpcEvent.DialogEvent event = new NpcEvent.DialogEvent(npc.wrappedNPC, player, dialogId, optionId, dialog); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.DIALOG, event); npc.script.callScript(EnumScriptType.DIALOG, event, "player", event.getPlayer(), "dialog", event.getDialogId(), "option", event.getOptionId(), "dialogObj", event.getDialog()); return NpcAPI.EVENT_BUS.post(event); @@ -151,7 +149,6 @@ public class EventHooks { return; NpcEvent.DialogClosedEvent event = new NpcEvent.DialogClosedEvent(npc.wrappedNPC, player, dialogId, optionId, dialog); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.DIALOG_CLOSE, event); npc.script.callScript(EnumScriptType.DIALOG_CLOSE, event, "player", event.getPlayer(), "dialog", event.getDialogId(), "option", event.getOptionId(), "dialogObj", event.getDialog()); NpcAPI.EVENT_BUS.post(event); @@ -162,7 +159,6 @@ public class EventHooks { return false; NpcEvent.InteractEvent event = new NpcEvent.InteractEvent(npc.wrappedNPC,player); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.INTERACT, event); boolean result = npc.script.callScript(EnumScriptType.INTERACT, event, "player", player); NpcAPI.EVENT_BUS.post(event); return result; @@ -172,7 +168,6 @@ public class EventHooks { if(npc == null || npc.wrappedNPC == null) return false; - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.ATTACK_MELEE, event); npc.script.callScript(EnumScriptType.ATTACK_MELEE, event, "target", event.target); npc.script.callScript(EnumScriptType.ATTACK, event, "target", event.target); return NpcAPI.EVENT_BUS.post(event); @@ -182,7 +177,6 @@ public class EventHooks { if(npc == null || npc.wrappedNPC == null) return false; - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.ATTACK_SWING, event); npc.script.callScript(EnumScriptType.ATTACK_SWING, event); return NpcAPI.EVENT_BUS.post(event); } @@ -191,7 +185,6 @@ public class EventHooks { if(npc == null || npc.wrappedNPC == null) return false; - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.RANGED_LAUNCHED, event); npc.script.callScript(EnumScriptType.RANGED_LAUNCHED, event, "target", event.target); npc.script.callScript(EnumScriptType.ATTACK, event, "target", event.target); return NpcAPI.EVENT_BUS.post(event); @@ -202,7 +195,6 @@ public class EventHooks { return; NpcEvent.KilledEntityEvent event = new NpcEvent.KilledEntityEvent(npc.wrappedNPC,entity); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.KILLS, event); npc.script.callScript(EnumScriptType.KILLS, event, "target", entity); NpcAPI.EVENT_BUS.post(event); } @@ -211,7 +203,6 @@ public class EventHooks { if(npc == null || npc.wrappedNPC == null) return false; - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.TARGET, event); npc.script.callScript(EnumScriptType.TARGET, event); return NpcAPI.EVENT_BUS.post(event); } @@ -221,7 +212,6 @@ public class EventHooks { return false; NpcEvent.TargetLostEvent event = new NpcEvent.TargetLostEvent(npc.wrappedNPC, prevtarget, newTarget); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.TARGET_LOST, event); npc.script.callScript(EnumScriptType.TARGET_LOST, event); return NpcAPI.EVENT_BUS.post(event); } @@ -231,7 +221,6 @@ public class EventHooks { return; NpcEvent.CollideEvent event = new NpcEvent.CollideEvent(npc.wrappedNPC,entity); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.COLLIDE, event); npc.script.callScript(EnumScriptType.COLLIDE, event, "entity", entity); NpcAPI.EVENT_BUS.post(event); } @@ -240,7 +229,6 @@ public class EventHooks { if(npc == null || npc.wrappedNPC == null) return false; - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.DAMAGED, event); npc.script.callScript(EnumScriptType.DAMAGED, event); return NpcAPI.EVENT_BUS.post(event); } @@ -249,7 +237,6 @@ public class EventHooks { if(npc == null || npc.wrappedNPC == null) return false; - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.KILLED, event); npc.script.callScript(EnumScriptType.KILLED, event); return NpcAPI.EVENT_BUS.post(event); } @@ -259,14 +246,12 @@ public class EventHooks { return; NpcEvent.TimerEvent event = new NpcEvent.TimerEvent(npc.wrappedNPC, id); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.TIMER, event); npc.script.callScript(EnumScriptType.TIMER, event); NpcAPI.EVENT_BUS.post(event); } public static void onProjectileTick(EntityProjectile projectile) { ProjectileEvent.UpdateEvent event = new ProjectileEvent.UpdateEvent((IProjectile) NpcAPI.Instance().getIEntity(projectile)); - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.PROJECTILE_TICK, event); for(ScriptContainer script : projectile.scripts) { if(script.isValid()) { script.run(EnumScriptType.PROJECTILE_TICK, event); @@ -284,7 +269,6 @@ public class EventHooks { } public static void onProjectileImpact(EntityProjectile projectile, ProjectileEvent.ImpactEvent event) { - ScriptController.Instance.globalNpcScripts.callScript(EnumScriptType.PROJECTILE_IMPACT, event); for(ScriptContainer script : projectile.scripts) { if(script.isValid()) { script.run(EnumScriptType.PROJECTILE_IMPACT, event); @@ -805,4 +789,49 @@ public class EventHooks { handler.callScript(EnumScriptType.PARTY_DISBAND, event); NpcAPI.EVENT_BUS.post(event); } + + private static boolean postAnimationEvent(IAnimationEvent event) { + IScriptHandler handler; + IAnimatable animatable = event.getAnimation().getParent().getEntity(); + if (animatable instanceof ICustomNpc) { + EntityNPCInterface npc = (EntityNPCInterface) ((ICustomNpc) animatable).getMCEntity(); + handler = npc.script; + } else { + handler = ScriptController.Instance.playerScripts; + } + + if (handler.isClient()) + return false; + + handler.callScript(event.getHookName(), (Event) event); + return NpcAPI.EVENT_BUS.post((Event) event); + } + + public static boolean onAnimationStarted(IAnimation animation) { + if (animation.getParent() == null || animation.getParent().getEntity() == null) { + return false; + } + return postAnimationEvent(new AnimationEvent.Started(animation)); + } + + public static void onAnimationEnded(IAnimation animation) { + if (animation.getParent() == null || animation.getParent().getEntity() == null) { + return; + } + postAnimationEvent(new AnimationEvent.Ended(animation)); + } + + public static void onAnimationFrameEntered(IAnimation animation, IFrame frame) { + if (frame == null || animation.getParent() == null || animation.getParent().getEntity() == null) { + return; + } + postAnimationEvent(new AnimationEvent.FrameEvent.Entered(animation, frame)); + } + + public static void onAnimationFrameExited(IAnimation animation, IFrame frame) { + if (frame == null || animation.getParent() == null || animation.getParent().getEntity() == null) { + return; + } + postAnimationEvent(new AnimationEvent.FrameEvent.Exited(animation, frame)); + } } diff --git a/src/main/java/noppes/npcs/constants/EnumScriptType.java b/src/main/java/noppes/npcs/constants/EnumScriptType.java index a8f233f47..fd968a716 100644 --- a/src/main/java/noppes/npcs/constants/EnumScriptType.java +++ b/src/main/java/noppes/npcs/constants/EnumScriptType.java @@ -99,13 +99,27 @@ public enum EnumScriptType { PARTY_INVITE("partyInvite"), PARTY_KICK("partyKick"), PARTY_LEAVE("partyLeave"), - PARTY_DISBAND("partyDisband"); + PARTY_DISBAND("partyDisband"), + + ANIMATION_START("animationStart"), + ANIMATION_END("animationEnd"), + ANIMATION_FRAME_ENTER("frameEnter"), + ANIMATION_FRAME_EXIT("frameExit"); public String function; public static EnumScriptType valueOfIgnoreCase(String channelName) { channelName = channelName.toUpperCase(); - return valueOf(channelName); + try { + return valueOf(channelName); + } catch (IllegalArgumentException exception) { + for (EnumScriptType value : EnumScriptType.values()) { + if (value.function.toUpperCase().equals(channelName)) { + return value; + } + } + throw exception; + } } private EnumScriptType(String function) { diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 4e2ce3c8e..0b9ae8fd7 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -1,10 +1,13 @@ 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.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import noppes.npcs.EventHooks; import noppes.npcs.api.handler.data.IAnimation; +import noppes.npcs.api.handler.data.IAnimationData; import noppes.npcs.api.handler.data.IFrame; import noppes.npcs.constants.EnumAnimationPart; import noppes.npcs.controllers.AnimationController; @@ -48,6 +51,10 @@ public class Animation implements IAnimation { this.id = id; } + public IAnimationData getParent() { + return this.parent; + } + public IFrame currentFrame() { return currentFrame < frames.size() ? frames.get(currentFrame) : null; } @@ -237,6 +244,8 @@ public class Animation implements IAnimation { this.currentFrameTime++; if (this.currentFrameTime == this.currentFrame().getDuration()) { + EventHooks.onAnimationFrameExited(this, this.currentFrame()); + Frame prevFrame = (Frame) this.currentFrame(); Frame nextFrame = null; this.currentFrameTime = 0; @@ -246,6 +255,13 @@ public class Animation implements IAnimation { } else if (this.loop >= 0 && this.loop < this.frames.size()) { this.currentFrame = this.loop; } + + if (this.currentFrame() != null) { + EventHooks.onAnimationFrameEntered(this, this.currentFrame()); + } else { + EventHooks.onAnimationEnded(this); + } + if (nextFrame != null) { for (EnumAnimationPart part : EnumAnimationPart.values()) { if (prevFrame.frameParts.containsKey(part) && nextFrame.frameParts.containsKey(part)) { diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 3bfb538c5..d8d4a07f7 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -2,24 +2,22 @@ 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; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; -import noppes.npcs.CommonProxy; -import noppes.npcs.CustomNpcs; -import noppes.npcs.DataDisplay; -import noppes.npcs.Server; +import noppes.npcs.*; +import noppes.npcs.api.entity.IAnimatable; +import noppes.npcs.api.entity.ICustomNpc; +import noppes.npcs.api.entity.IPlayer; 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; import noppes.npcs.entity.EntityNPCInterface; +import noppes.npcs.scripted.NpcAPI; import java.util.Arrays; import java.util.HashSet; @@ -34,6 +32,9 @@ public class AnimationData implements IAnimationData { public Animation animation; public boolean allowAnimation = false; + private Animation sentAnimation; + private boolean isClientAnimating; + private final HashSet cachedAnimationIDs = new HashSet<>(); //Client-side values @@ -50,6 +51,21 @@ public class AnimationData implements IAnimationData { } } + public IAnimatable getEntity() { + if (this.parent instanceof DataDisplay) { + EntityNPCInterface npc = ((DataDisplay)this.parent).npc; + return (ICustomNpc) NpcAPI.Instance().getIEntity(npc); + } else { + EntityPlayer player; + if (this.parent instanceof PlayerData) { + player = ((PlayerData) this.parent).player; + } else { + player = (EntityPlayer) this.parent; + } + return (IPlayer) NpcAPI.Instance().getIEntity(player); + } + } + public void updateClient() { this.updateClient(new EntityPlayer[0]); } @@ -58,6 +74,21 @@ public class AnimationData implements IAnimationData { 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) { + boolean prevIsClientAnimating = this.isClientAnimating && this.sentAnimation.currentFrame() != null; + this.isClientAnimating = this.allowAnimation && this.animation != null; + if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.sentAnimation)) { + EventHooks.onAnimationEnded(this.sentAnimation); + } + if (this.isClientAnimating) { + this.sentAnimation = this.animation; + } + + if (this.animation != null && this.allowAnimation) { + if (EventHooks.onAnimationStarted(this.animation)) + return; + EventHooks.onAnimationFrameEntered(this.animation, this.animation.currentFrame()); + } + if (!CustomNpcs.proxy.hasClient()) { CommonProxy.serverPlayingAnimations.add(this.animation); } diff --git a/src/main/java/noppes/npcs/controllers/data/DataScript.java b/src/main/java/noppes/npcs/controllers/data/DataScript.java index e2bd8688f..d567f11d2 100644 --- a/src/main/java/noppes/npcs/controllers/data/DataScript.java +++ b/src/main/java/noppes/npcs/controllers/data/DataScript.java @@ -236,13 +236,14 @@ public class DataScript implements INpcScriptHandler { @Override public void callScript(EnumScriptType type, Event event) { + ScriptController.Instance.globalNpcScripts.callScript(type, event); callScript(type, event, "$$IGNORED$$", null); } @Override public void callScript(String hookName, Event event) { try { - EnumScriptType enumScriptType = EnumScriptType.valueOf(hookName); + EnumScriptType enumScriptType = EnumScriptType.valueOfIgnoreCase(hookName); this.callScript(enumScriptType, event); } catch (IllegalArgumentException ignored) {} } @@ -305,4 +306,4 @@ public class DataScript implements INpcScriptHandler { public Collection getNPCScripts() { return this.scripts.values(); } -} \ No newline at end of file +} diff --git a/src/main/java/noppes/npcs/scripted/event/AnimationEvent.java b/src/main/java/noppes/npcs/scripted/event/AnimationEvent.java new file mode 100644 index 000000000..1690f8e57 --- /dev/null +++ b/src/main/java/noppes/npcs/scripted/event/AnimationEvent.java @@ -0,0 +1,108 @@ +package noppes.npcs.scripted.event; + +import cpw.mods.fml.common.eventhandler.Cancelable; +import noppes.npcs.api.entity.IAnimatable; +import noppes.npcs.api.event.IAnimationEvent; +import noppes.npcs.api.handler.data.IAnimation; +import noppes.npcs.api.handler.data.IAnimationData; +import noppes.npcs.api.handler.data.IFrame; +import noppes.npcs.constants.EnumScriptType; +import noppes.npcs.controllers.data.Animation; +import noppes.npcs.controllers.data.Frame; + +public abstract class AnimationEvent extends CustomNPCsEvent implements IAnimationEvent { + protected final IAnimation animation; + protected final IAnimationData animationData; + protected final IAnimatable entity; + + public AnimationEvent(IAnimation animation) { + this.animation = animation; + this.animationData = animation.getParent(); + this.entity = this.animationData.getEntity(); + } + + @Override + public IAnimation getAnimation() { + return this.animation; + } + + @Override + public IAnimationData getAnimationData() { + return this.animationData; + } + + @Override + public IAnimatable getEntity() { + return this.entity; + } + + @Cancelable + public static class Started extends AnimationEvent { + + public Started(IAnimation animation) { + super(animation); + } + + @Override + public String getHookName() { + return EnumScriptType.ANIMATION_START.function; + } + } + + public static class Ended extends AnimationEvent { + + public Ended(IAnimation animation) { + super(animation); + } + + @Override + public String getHookName() { + return EnumScriptType.ANIMATION_END.function; + } + } + + public static abstract class FrameEvent extends AnimationEvent implements IFrameEvent { + private final IFrame frame; + private final int index; + + public FrameEvent(IAnimation animation, IFrame frame) { + super(animation); + this.frame = frame; + this.index = ((Animation)this.getAnimation()).frames.indexOf((Frame) this.frame); + } + + @Override + public int getIndex() { + return this.index; + } + + @Override + public IFrame getFrame() { + return this.frame; + } + + public static class Entered extends FrameEvent { + + public Entered(IAnimation animation, IFrame frame) { + super(animation, frame); + } + + @Override + public String getHookName() { + return EnumScriptType.ANIMATION_FRAME_ENTER.function; + } + } + + public static class Exited extends FrameEvent { + + public Exited(IAnimation animation, IFrame frame) { + super(animation, frame); + } + + @Override + public String getHookName() { + return EnumScriptType.ANIMATION_FRAME_EXIT.function; + } + } + } +} diff --git a/src/main/java/noppes/npcs/scripted/event/BlockEvent.java b/src/main/java/noppes/npcs/scripted/event/BlockEvent.java index 3367a1699..48a03ec9e 100644 --- a/src/main/java/noppes/npcs/scripted/event/BlockEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/BlockEvent.java @@ -11,7 +11,7 @@ import noppes.npcs.api.event.IBlockEvent; import noppes.npcs.constants.EnumScriptType; import noppes.npcs.scripted.NpcAPI; -public class BlockEvent extends CustomNPCsEvent implements IBlockEvent { +public abstract class BlockEvent extends CustomNPCsEvent implements IBlockEvent { public IBlock block; public BlockEvent(IBlock block){ this.block = block; diff --git a/src/main/java/noppes/npcs/scripted/event/CustomGuiEvent.java b/src/main/java/noppes/npcs/scripted/event/CustomGuiEvent.java index 130a6657c..a62c02156 100644 --- a/src/main/java/noppes/npcs/scripted/event/CustomGuiEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/CustomGuiEvent.java @@ -10,7 +10,7 @@ import noppes.npcs.api.item.IItemStack; import noppes.npcs.constants.EnumScriptType; import noppes.npcs.scripted.NpcAPI; -public class CustomGuiEvent extends CustomNPCsEvent implements ICustomGuiEvent { +public abstract class CustomGuiEvent extends CustomNPCsEvent implements ICustomGuiEvent { public final IPlayer player; public final ICustomGui gui; diff --git a/src/main/java/noppes/npcs/scripted/event/CustomNPCsEvent.java b/src/main/java/noppes/npcs/scripted/event/CustomNPCsEvent.java index 0a0dfd2bb..2e77b5aff 100644 --- a/src/main/java/noppes/npcs/scripted/event/CustomNPCsEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/CustomNPCsEvent.java @@ -9,12 +9,10 @@ import noppes.npcs.api.event.ICustomNPCsEvent; import noppes.npcs.api.handler.data.INaturalSpawn; import noppes.npcs.constants.EnumScriptType; -public class CustomNPCsEvent extends Event implements ICustomNPCsEvent { +public abstract class CustomNPCsEvent extends Event implements ICustomNPCsEvent { public final AbstractNpcAPI API = AbstractNpcAPI.Instance(); - public String getHookName() { - return "CNPCEvent"; - } + public abstract String getHookName(); public CustomNPCsEvent() { } diff --git a/src/main/java/noppes/npcs/scripted/event/DialogEvent.java b/src/main/java/noppes/npcs/scripted/event/DialogEvent.java index 84ace0ee7..a3dfb671b 100644 --- a/src/main/java/noppes/npcs/scripted/event/DialogEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/DialogEvent.java @@ -6,7 +6,7 @@ import noppes.npcs.api.event.IDialogEvent; import noppes.npcs.api.handler.data.IDialog; import noppes.npcs.constants.EnumScriptType; -public class DialogEvent extends CustomNPCsEvent implements IDialogEvent { +public abstract class DialogEvent extends CustomNPCsEvent implements IDialogEvent { public final IDialog dialog; public final IPlayer player; diff --git a/src/main/java/noppes/npcs/scripted/event/FactionEvent.java b/src/main/java/noppes/npcs/scripted/event/FactionEvent.java index 2741b669b..ed0aca4a1 100644 --- a/src/main/java/noppes/npcs/scripted/event/FactionEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/FactionEvent.java @@ -6,7 +6,7 @@ import noppes.npcs.api.event.IFactionEvent; import noppes.npcs.api.handler.data.IFaction; import noppes.npcs.constants.EnumScriptType; -public class FactionEvent extends CustomNPCsEvent implements IFactionEvent { +public abstract class FactionEvent extends CustomNPCsEvent implements IFactionEvent { public final IFaction faction; public final IPlayer player; diff --git a/src/main/java/noppes/npcs/scripted/event/ItemEvent.java b/src/main/java/noppes/npcs/scripted/event/ItemEvent.java index 99e959814..8f90f8e94 100644 --- a/src/main/java/noppes/npcs/scripted/event/ItemEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/ItemEvent.java @@ -7,7 +7,7 @@ import noppes.npcs.api.event.IItemEvent; import noppes.npcs.api.item.IItemCustom; import noppes.npcs.constants.EnumScriptType; -public class ItemEvent extends CustomNPCsEvent implements IItemEvent { +public abstract class ItemEvent extends CustomNPCsEvent implements IItemEvent { public final IItemCustom item; public ItemEvent(IItemCustom item) { diff --git a/src/main/java/noppes/npcs/scripted/event/NpcEvent.java b/src/main/java/noppes/npcs/scripted/event/NpcEvent.java index 41c03b803..14c5e9b38 100644 --- a/src/main/java/noppes/npcs/scripted/event/NpcEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/NpcEvent.java @@ -20,7 +20,7 @@ import noppes.npcs.scripted.NpcAPI; import java.util.ArrayList; -public class NpcEvent extends CustomNPCsEvent implements INpcEvent { +public abstract class NpcEvent extends CustomNPCsEvent implements INpcEvent { public final ICustomNpc npc; public NpcEvent(ICustomNpc npc) { diff --git a/src/main/java/noppes/npcs/scripted/event/PartyEvent.java b/src/main/java/noppes/npcs/scripted/event/PartyEvent.java index d1df03e8d..adaacc81f 100644 --- a/src/main/java/noppes/npcs/scripted/event/PartyEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/PartyEvent.java @@ -7,7 +7,7 @@ import noppes.npcs.api.handler.data.IParty; import noppes.npcs.api.handler.data.IQuest; import noppes.npcs.constants.EnumScriptType; -public class PartyEvent extends CustomNPCsEvent implements IPartyEvent { +public abstract class PartyEvent extends CustomNPCsEvent implements IPartyEvent { public final IQuest quest; public final IParty party; diff --git a/src/main/java/noppes/npcs/scripted/event/PlayerEvent.java b/src/main/java/noppes/npcs/scripted/event/PlayerEvent.java index e181668ac..0a57d95a5 100644 --- a/src/main/java/noppes/npcs/scripted/event/PlayerEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/PlayerEvent.java @@ -18,7 +18,7 @@ import noppes.npcs.api.item.IItemStack; import noppes.npcs.constants.EnumScriptType; import noppes.npcs.scripted.NpcAPI; -public class PlayerEvent extends CustomNPCsEvent implements IPlayerEvent { +public abstract class PlayerEvent extends CustomNPCsEvent implements IPlayerEvent { public final IPlayer player; public PlayerEvent(IPlayer player) { diff --git a/src/main/java/noppes/npcs/scripted/event/ProjectileEvent.java b/src/main/java/noppes/npcs/scripted/event/ProjectileEvent.java index e485396b5..060edfbe7 100644 --- a/src/main/java/noppes/npcs/scripted/event/ProjectileEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/ProjectileEvent.java @@ -4,8 +4,9 @@ import noppes.npcs.api.IBlock; import noppes.npcs.api.entity.IEntity; import noppes.npcs.api.entity.IProjectile; import noppes.npcs.api.event.IProjectileEvent; +import noppes.npcs.constants.EnumScriptType; -public class ProjectileEvent extends CustomNPCsEvent implements IProjectileEvent { +public abstract class ProjectileEvent extends CustomNPCsEvent implements IProjectileEvent { public IProjectile projectile; public IEntity source; @@ -29,6 +30,11 @@ public class ProjectileEvent extends CustomNPCsEvent implements IProjectileEvent public UpdateEvent(IProjectile projectile) { super(projectile); } + + @Override + public String getHookName() { + return EnumScriptType.PROJECTILE_TICK.function; + } } /** @@ -62,5 +68,10 @@ public class ProjectileEvent extends CustomNPCsEvent implements IProjectileEvent return (IBlock) target; return null; } + + @Override + public String getHookName() { + return EnumScriptType.PROJECTILE_IMPACT.function; + } } } diff --git a/src/main/java/noppes/npcs/scripted/event/QuestEvent.java b/src/main/java/noppes/npcs/scripted/event/QuestEvent.java index 264e6f8c8..c5261f951 100644 --- a/src/main/java/noppes/npcs/scripted/event/QuestEvent.java +++ b/src/main/java/noppes/npcs/scripted/event/QuestEvent.java @@ -7,7 +7,7 @@ import noppes.npcs.api.handler.data.IQuest; import noppes.npcs.api.item.IItemStack; import noppes.npcs.constants.EnumScriptType; -public class QuestEvent extends CustomNPCsEvent implements IQuestEvent { +public abstract class QuestEvent extends CustomNPCsEvent implements IQuestEvent { public final IQuest quest; public final IPlayer player; From 978b0d55ec64a6b4400a6b55ea78c266b86c97ce Mon Sep 17 00:00:00 2001 From: Kam Date: Sun, 24 Mar 2024 19:13:46 -0400 Subject: [PATCH 12/32] Skin Overlays maintain glow / blend on changing URL --- .../noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java index 4b3eaf5fa..9f4c453bc 100644 --- a/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java +++ b/src/main/java/noppes/npcs/client/gui/mainmenu/GuiNpcDisplay.java @@ -127,7 +127,14 @@ public class GuiNpcDisplay extends GuiNPCInterface2 implements ITextfieldListene } else if(textfield.id == 9){ if (!textfield.getText().isEmpty()) { - npc.display.skinOverlayData.overlayList.put(0,new SkinOverlay(textfield.getText())); + boolean isGlow = true; + if(npc.display.skinOverlayData.has(0)) + isGlow = npc.display.skinOverlayData.overlayList.get(0).getGlow(); + + SkinOverlay skinOverlay = new SkinOverlay(textfield.getText()); + skinOverlay.setGlow(isGlow); + skinOverlay.setBlend(isGlow); + npc.display.skinOverlayData.overlayList.put(0, skinOverlay); } else { npc.display.skinOverlayData.overlayList.remove(0); } From a5ed14183e5bd6d19092a141f9e6bb4bbfc027e3 Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 18:55:03 -0500 Subject: [PATCH 13/32] Animations now continue where they should be when players rejoin a world/server. --- src/main/java/noppes/npcs/CommonProxy.java | 6 +- .../java/noppes/npcs/ServerEventsHandler.java | 24 ++++-- .../npcs/client/ClientCacheHandler.java | 1 - .../noppes/npcs/client/ClientTickHandler.java | 2 +- .../npcs/client/PacketHandlerClient.java | 9 ++- .../npcs/controllers/data/Animation.java | 35 ++++++--- .../npcs/controllers/data/AnimationData.java | 74 ++++++++++++++++--- 7 files changed, 117 insertions(+), 34 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 68c9db672..ebcb3ed1a 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -95,8 +95,10 @@ public class CommonProxy implements IGuiHandler { @SideOnly(Side.CLIENT) private boolean clientRemoveAnimation(Entity entity) { - return Minecraft.getMinecraft().currentScreen == null - && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity); + if (Minecraft.getMinecraft().currentScreen == null && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity)) { + return true; + } + return false; } public PlayerData getPlayerData(EntityPlayer player) { diff --git a/src/main/java/noppes/npcs/ServerEventsHandler.java b/src/main/java/noppes/npcs/ServerEventsHandler.java index ab7b67a5d..7742199d8 100644 --- a/src/main/java/noppes/npcs/ServerEventsHandler.java +++ b/src/main/java/noppes/npcs/ServerEventsHandler.java @@ -497,12 +497,24 @@ public class ServerEventsHandler { @SubscribeEvent public void playerTracking(PlayerEvent.StartTracking event){ - if(!(event.target instanceof EntityNPCInterface) || event.target.worldObj.isRemote) - return; + if (event.target.worldObj.isRemote) return; - MarkData data = MarkData.get((EntityNPCInterface) event.target); - if(data.marks.isEmpty()) - return; - Server.sendData((EntityPlayerMP)event.entityPlayer, EnumPacketClient.MARK_DATA, event.target.getEntityId(), data.getNBT()); + if(event.target instanceof EntityPlayerMP || event.target instanceof EntityNPCInterface) { + AnimationData animationData = AnimationData.getData(event.target); + if (animationData.isClientAnimating()) { + AnimationData playerAnimData = AnimationData.getData(event.entityPlayer); + Animation currentAnimation = animationData.currentClientAnimation; + NBTTagCompound compound = currentAnimation.writeToNBT(); + playerAnimData.viewAnimation(currentAnimation, animationData, compound, + animationData.isClientAnimating(), currentAnimation.currentFrame, currentAnimation.currentFrameTime); + } + + if (event.target instanceof EntityNPCInterface) { + MarkData data = MarkData.get((EntityNPCInterface) event.target); + if (data.marks.isEmpty()) + return; + Server.sendData((EntityPlayerMP) event.entityPlayer, EnumPacketClient.MARK_DATA, event.target.getEntityId(), data.getNBT()); + } + } } } diff --git a/src/main/java/noppes/npcs/client/ClientCacheHandler.java b/src/main/java/noppes/npcs/client/ClientCacheHandler.java index bf9c920f4..810cc4bf0 100644 --- a/src/main/java/noppes/npcs/client/ClientCacheHandler.java +++ b/src/main/java/noppes/npcs/client/ClientCacheHandler.java @@ -57,7 +57,6 @@ public class ClientCacheHandler { ClientCacheHandler.skinOverlays.clear(); ClientCacheHandler.playerAnimations.clear(); ClientCacheHandler.playerData.animationData.clearCache(); - CommonProxy.clientPlayingAnimations.clear(); } public static void clearSkinCache() { diff --git a/src/main/java/noppes/npcs/client/ClientTickHandler.java b/src/main/java/noppes/npcs/client/ClientTickHandler.java index 4be801a9b..a2f82b27e 100644 --- a/src/main/java/noppes/npcs/client/ClientTickHandler.java +++ b/src/main/java/noppes/npcs/client/ClientTickHandler.java @@ -32,7 +32,7 @@ public class ClientTickHandler{ @SubscribeEvent(priority = EventPriority.LOWEST) public void onClientTick(TickEvent.ClientTickEvent event){ Minecraft mc = Minecraft.getMinecraft(); - if ((this.prevWorld == null || mc.theWorld == null) && this.prevWorld != mc.theWorld) { + if (mc.theWorld != null && this.prevWorld != mc.theWorld) { ClientCacheHandler.clearCache(); this.prevWorld = mc.theWorld; } diff --git a/src/main/java/noppes/npcs/client/PacketHandlerClient.java b/src/main/java/noppes/npcs/client/PacketHandlerClient.java index b989406cb..d5137c903 100644 --- a/src/main/java/noppes/npcs/client/PacketHandlerClient.java +++ b/src/main/java/noppes/npcs/client/PacketHandlerClient.java @@ -375,8 +375,13 @@ public class PacketHandlerClient extends PacketHandlerServer{ } animationData.setAnimation(ClientCacheHandler.animationCache.get(animationId)); - animationData.readFromNBT(compound); - Client.sendData(EnumPacketServer.CacheAnimation, animationId); + animationData.viewReadFromNBT(compound); + + if (compound.hasKey("Frame")) { + animationData.animation.readFromNBT(compound.getCompoundTag("Animation")); + } else if (compound.hasKey("Animation")) { + 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 0b9ae8fd7..24c6a28c6 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -210,6 +210,9 @@ public class Animation implements IAnimation { this.whileStanding = compound.getBoolean("WhileStanding"); this.whileMoving = compound.getBoolean("WhileWalking"); this.whileAttacking = compound.getBoolean("WhileAttacking"); + + this.currentFrame = compound.getInteger("CurrentFrame"); + this.currentFrameTime = compound.getInteger("CurrentFrameTime"); } public NBTTagCompound writeToNBT(){ @@ -231,6 +234,9 @@ public class Animation implements IAnimation { compound.setBoolean("WhileStanding", whileStanding); compound.setBoolean("WhileWalking", whileMoving); compound.setBoolean("WhileAttacking", whileAttacking); + + compound.setInteger("CurrentFrame", currentFrame); + compound.setInteger("CurrentFrameTime", currentFrameTime); return compound; } @@ -277,16 +283,23 @@ public class Animation implements IAnimation { @SideOnly(Side.CLIENT) public void jumpToCurrentFrame() { - this.currentFrameTime = 0; - Frame frame = (Frame) this.currentFrame(); - if(frame != null){ - for (EnumAnimationPart part : EnumAnimationPart.values()) { - if(part != null){ - if (frame.frameParts.containsKey(part)) { - frame.frameParts.get(part).jumpToCurrentFrame(); - } - } - } - } + this.jumpToFrameAtTime(this.currentFrame, 0); } + + @SideOnly(Side.CLIENT) + public void jumpToFrameAtTime(int frameIndex, int time) { + this.currentFrame = frameIndex; + this.currentFrameTime = time; + + Frame frame = (Frame) this.currentFrame(); + if(frame != null){ + for (EnumAnimationPart part : EnumAnimationPart.values()) { + if(part != null){ + if (frame.frameParts.containsKey(part)) { + frame.frameParts.get(part).jumpToCurrentFrame(); + } + } + } + } + } } diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index d8d4a07f7..097c944c6 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -1,7 +1,7 @@ package noppes.npcs.controllers.data; -import cpw.mods.fml.common.FMLCommonHandler; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -10,6 +10,7 @@ import net.minecraft.util.AxisAlignedBB; import noppes.npcs.*; import noppes.npcs.api.entity.IAnimatable; import noppes.npcs.api.entity.ICustomNpc; +import noppes.npcs.api.entity.IEntity; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.handler.data.IAnimation; import noppes.npcs.api.handler.data.IAnimationData; @@ -32,7 +33,7 @@ public class AnimationData implements IAnimationData { public Animation animation; public boolean allowAnimation = false; - private Animation sentAnimation; + public Animation currentClientAnimation; private boolean isClientAnimating; private final HashSet cachedAnimationIDs = new HashSet<>(); @@ -51,6 +52,16 @@ public class AnimationData implements IAnimationData { } } + public static AnimationData getData(Entity entity) { + if (entity instanceof EntityPlayerMP) { + return PlayerData.get((EntityPlayer) entity).animationData; + } else if (entity instanceof EntityNPCInterface) { + return ((EntityNPCInterface)entity).display.animationData; + } else { + return null; + } + } + public IAnimatable getEntity() { if (this.parent instanceof DataDisplay) { EntityNPCInterface npc = ((DataDisplay)this.parent).npc; @@ -74,13 +85,13 @@ public class AnimationData implements IAnimationData { 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) { - boolean prevIsClientAnimating = this.isClientAnimating && this.sentAnimation.currentFrame() != null; + boolean prevIsClientAnimating = this.isClientAnimating && this.currentClientAnimation.currentFrame() != null; this.isClientAnimating = this.allowAnimation && this.animation != null; - if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.sentAnimation)) { - EventHooks.onAnimationEnded(this.sentAnimation); + if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.currentClientAnimation)) { + EventHooks.onAnimationEnded(this.currentClientAnimation); } if (this.isClientAnimating) { - this.sentAnimation = this.animation; + this.currentClientAnimation = this.animation; } if (this.animation != null && this.allowAnimation) { @@ -105,11 +116,15 @@ public class AnimationData implements IAnimationData { if (animationNBT == null && this.animation != null && !animationData.isCached(this.animation.getID())) { animationNBT = this.animation.writeToNBT(); } - animationData.viewAnimation(this.animation, sendingEntity, this, animationNBT); + animationData.viewAnimation(this.animation, this, animationNBT); } } } + public boolean isClientAnimating() { + return this.isClientAnimating; + } + public boolean isActive() { if (!this.allowAnimation || this.animation == null || this.animation.currentFrame == this.animation.frames.size() || animation.currentFrame() == null) return false; @@ -152,27 +167,63 @@ public class AnimationData implements IAnimationData { this.cachedAnimationIDs.clear(); } - public void viewAnimation(Animation animation, EntityLivingBase entity, AnimationData animationData, NBTTagCompound animationNBT) { - NBTTagCompound data = animationData.writeToNBT(new NBTTagCompound()); + public void viewAnimation(Animation animation, AnimationData animationData, NBTTagCompound animationNBT) { + this.viewAnimation(animation, animationData, animationNBT, animationData.allowAnimation, -1, -1); + } + + public void viewAnimation(Animation animation, AnimationData animationData, NBTTagCompound animationNBT, boolean enabled, int currentFrame, int time) { + boolean prevEnabled = animationData.allowAnimation; + animationData.allowAnimation = enabled; + NBTTagCompound data = animationData.viewWriteNBT(new NBTTagCompound()); + animationData.allowAnimation = prevEnabled; + + + if (animation != null && currentFrame >= 0 && currentFrame < animation.frames.size()) { + data.setInteger("Frame", currentFrame); + data.setInteger("Time", time); + } + if (animation != null) { - if (this.cachedAnimationIDs.contains(animation.getID())) { + if (this.cachedAnimationIDs.contains(animation.getID()) && !data.hasKey("Frame")) { data.setInteger("AnimationID", animation.getID()); } else { data.setTag("Animation", animationNBT); } } + + IAnimatable animatable = animationData.getEntity(); + Entity entity = ((IEntity) animatable).getMCEntity(); if (!(entity instanceof EntityPlayer)) { data.setInteger("EntityId", entity.getEntityId()); } + Server.sendData((EntityPlayerMP) ((PlayerData) parent).player, EnumPacketClient.UPDATE_ANIMATIONS, data, entity.getCommandSenderName()); } + public NBTTagCompound viewWriteNBT(NBTTagCompound compound) { + compound.setBoolean("AllowAnimation", allowAnimation); + return compound; + } + + public void viewReadFromNBT(NBTTagCompound compound) { + this.setEnabled(compound.getBoolean("AllowAnimation")); + } + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + if (this.currentClientAnimation != null) { + compound.setTag("CurrentAnimation", currentClientAnimation.writeToNBT()); + compound.setBoolean("IsClientAnimating", isClientAnimating); + } compound.setBoolean("AllowAnimation", allowAnimation); return compound; } public void readFromNBT(NBTTagCompound compound) { + if (compound.hasKey("CurrentAnimation")) { + this.currentClientAnimation = new Animation(); + this.currentClientAnimation.readFromNBT(compound.getCompoundTag("CurrentAnimation")); + this.isClientAnimating = compound.getBoolean("IsClientAnimating"); + } this.setEnabled(compound.getBoolean("AllowAnimation")); } @@ -194,11 +245,12 @@ public class AnimationData implements IAnimationData { if (animation != null) { newAnim = new Animation(); newAnim.readFromNBT(((Animation) animation).writeToNBT()); + newAnim.currentFrame = 0; + newAnim.currentFrameTime = 0; newAnim.parent = this; } if (CustomNpcs.proxy.hasClient() && newAnim != null) { - CommonProxy.clientPlayingAnimations.remove(this.animation); CommonProxy.clientPlayingAnimations.add(newAnim); } this.animation = newAnim; From fd4a6d0a2ccb284821a9bc8e23101da2ff37302a Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Sun, 24 Mar 2024 18:59:27 -0500 Subject: [PATCH 14/32] Revert "Animations now continue where they should be when players rejoin a world/server." This reverts commit a5ed14183e5bd6d19092a141f9e6bb4bbfc027e3. --- src/main/java/noppes/npcs/CommonProxy.java | 6 +- .../java/noppes/npcs/ServerEventsHandler.java | 24 ++---- .../npcs/client/ClientCacheHandler.java | 1 + .../noppes/npcs/client/ClientTickHandler.java | 2 +- .../npcs/client/PacketHandlerClient.java | 9 +-- .../npcs/controllers/data/Animation.java | 35 +++------ .../npcs/controllers/data/AnimationData.java | 74 +++---------------- 7 files changed, 34 insertions(+), 117 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index ebcb3ed1a..68c9db672 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -95,10 +95,8 @@ public class CommonProxy implements IGuiHandler { @SideOnly(Side.CLIENT) private boolean clientRemoveAnimation(Entity entity) { - if (Minecraft.getMinecraft().currentScreen == null && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity)) { - return true; - } - return false; + return Minecraft.getMinecraft().currentScreen == null + && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity); } public PlayerData getPlayerData(EntityPlayer player) { diff --git a/src/main/java/noppes/npcs/ServerEventsHandler.java b/src/main/java/noppes/npcs/ServerEventsHandler.java index 7742199d8..ab7b67a5d 100644 --- a/src/main/java/noppes/npcs/ServerEventsHandler.java +++ b/src/main/java/noppes/npcs/ServerEventsHandler.java @@ -497,24 +497,12 @@ public class ServerEventsHandler { @SubscribeEvent public void playerTracking(PlayerEvent.StartTracking event){ - if (event.target.worldObj.isRemote) return; + if(!(event.target instanceof EntityNPCInterface) || event.target.worldObj.isRemote) + return; - if(event.target instanceof EntityPlayerMP || event.target instanceof EntityNPCInterface) { - AnimationData animationData = AnimationData.getData(event.target); - if (animationData.isClientAnimating()) { - AnimationData playerAnimData = AnimationData.getData(event.entityPlayer); - Animation currentAnimation = animationData.currentClientAnimation; - NBTTagCompound compound = currentAnimation.writeToNBT(); - playerAnimData.viewAnimation(currentAnimation, animationData, compound, - animationData.isClientAnimating(), currentAnimation.currentFrame, currentAnimation.currentFrameTime); - } - - if (event.target instanceof EntityNPCInterface) { - MarkData data = MarkData.get((EntityNPCInterface) event.target); - if (data.marks.isEmpty()) - return; - Server.sendData((EntityPlayerMP) event.entityPlayer, EnumPacketClient.MARK_DATA, event.target.getEntityId(), data.getNBT()); - } - } + MarkData data = MarkData.get((EntityNPCInterface) event.target); + if(data.marks.isEmpty()) + return; + Server.sendData((EntityPlayerMP)event.entityPlayer, EnumPacketClient.MARK_DATA, event.target.getEntityId(), data.getNBT()); } } diff --git a/src/main/java/noppes/npcs/client/ClientCacheHandler.java b/src/main/java/noppes/npcs/client/ClientCacheHandler.java index 810cc4bf0..bf9c920f4 100644 --- a/src/main/java/noppes/npcs/client/ClientCacheHandler.java +++ b/src/main/java/noppes/npcs/client/ClientCacheHandler.java @@ -57,6 +57,7 @@ public class ClientCacheHandler { ClientCacheHandler.skinOverlays.clear(); ClientCacheHandler.playerAnimations.clear(); ClientCacheHandler.playerData.animationData.clearCache(); + CommonProxy.clientPlayingAnimations.clear(); } public static void clearSkinCache() { diff --git a/src/main/java/noppes/npcs/client/ClientTickHandler.java b/src/main/java/noppes/npcs/client/ClientTickHandler.java index a2f82b27e..4be801a9b 100644 --- a/src/main/java/noppes/npcs/client/ClientTickHandler.java +++ b/src/main/java/noppes/npcs/client/ClientTickHandler.java @@ -32,7 +32,7 @@ public class ClientTickHandler{ @SubscribeEvent(priority = EventPriority.LOWEST) public void onClientTick(TickEvent.ClientTickEvent event){ Minecraft mc = Minecraft.getMinecraft(); - if (mc.theWorld != null && this.prevWorld != mc.theWorld) { + if ((this.prevWorld == null || mc.theWorld == null) && this.prevWorld != mc.theWorld) { ClientCacheHandler.clearCache(); this.prevWorld = mc.theWorld; } diff --git a/src/main/java/noppes/npcs/client/PacketHandlerClient.java b/src/main/java/noppes/npcs/client/PacketHandlerClient.java index d5137c903..b989406cb 100644 --- a/src/main/java/noppes/npcs/client/PacketHandlerClient.java +++ b/src/main/java/noppes/npcs/client/PacketHandlerClient.java @@ -375,13 +375,8 @@ public class PacketHandlerClient extends PacketHandlerServer{ } animationData.setAnimation(ClientCacheHandler.animationCache.get(animationId)); - animationData.viewReadFromNBT(compound); - - if (compound.hasKey("Frame")) { - animationData.animation.readFromNBT(compound.getCompoundTag("Animation")); - } else if (compound.hasKey("Animation")) { - Client.sendData(EnumPacketServer.CacheAnimation, animationId); - } + animationData.readFromNBT(compound); + 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 24c6a28c6..0b9ae8fd7 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -210,9 +210,6 @@ public class Animation implements IAnimation { this.whileStanding = compound.getBoolean("WhileStanding"); this.whileMoving = compound.getBoolean("WhileWalking"); this.whileAttacking = compound.getBoolean("WhileAttacking"); - - this.currentFrame = compound.getInteger("CurrentFrame"); - this.currentFrameTime = compound.getInteger("CurrentFrameTime"); } public NBTTagCompound writeToNBT(){ @@ -234,9 +231,6 @@ public class Animation implements IAnimation { compound.setBoolean("WhileStanding", whileStanding); compound.setBoolean("WhileWalking", whileMoving); compound.setBoolean("WhileAttacking", whileAttacking); - - compound.setInteger("CurrentFrame", currentFrame); - compound.setInteger("CurrentFrameTime", currentFrameTime); return compound; } @@ -283,23 +277,16 @@ public class Animation implements IAnimation { @SideOnly(Side.CLIENT) public void jumpToCurrentFrame() { - this.jumpToFrameAtTime(this.currentFrame, 0); + this.currentFrameTime = 0; + Frame frame = (Frame) this.currentFrame(); + if(frame != null){ + for (EnumAnimationPart part : EnumAnimationPart.values()) { + if(part != null){ + if (frame.frameParts.containsKey(part)) { + frame.frameParts.get(part).jumpToCurrentFrame(); + } + } + } + } } - - @SideOnly(Side.CLIENT) - public void jumpToFrameAtTime(int frameIndex, int time) { - this.currentFrame = frameIndex; - this.currentFrameTime = time; - - Frame frame = (Frame) this.currentFrame(); - if(frame != null){ - for (EnumAnimationPart part : EnumAnimationPart.values()) { - if(part != null){ - if (frame.frameParts.containsKey(part)) { - frame.frameParts.get(part).jumpToCurrentFrame(); - } - } - } - } - } } diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 097c944c6..d8d4a07f7 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -1,7 +1,7 @@ package noppes.npcs.controllers.data; -import net.minecraft.entity.Entity; +import cpw.mods.fml.common.FMLCommonHandler; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -10,7 +10,6 @@ import net.minecraft.util.AxisAlignedBB; import noppes.npcs.*; import noppes.npcs.api.entity.IAnimatable; import noppes.npcs.api.entity.ICustomNpc; -import noppes.npcs.api.entity.IEntity; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.handler.data.IAnimation; import noppes.npcs.api.handler.data.IAnimationData; @@ -33,7 +32,7 @@ public class AnimationData implements IAnimationData { public Animation animation; public boolean allowAnimation = false; - public Animation currentClientAnimation; + private Animation sentAnimation; private boolean isClientAnimating; private final HashSet cachedAnimationIDs = new HashSet<>(); @@ -52,16 +51,6 @@ public class AnimationData implements IAnimationData { } } - public static AnimationData getData(Entity entity) { - if (entity instanceof EntityPlayerMP) { - return PlayerData.get((EntityPlayer) entity).animationData; - } else if (entity instanceof EntityNPCInterface) { - return ((EntityNPCInterface)entity).display.animationData; - } else { - return null; - } - } - public IAnimatable getEntity() { if (this.parent instanceof DataDisplay) { EntityNPCInterface npc = ((DataDisplay)this.parent).npc; @@ -85,13 +74,13 @@ public class AnimationData implements IAnimationData { 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) { - boolean prevIsClientAnimating = this.isClientAnimating && this.currentClientAnimation.currentFrame() != null; + boolean prevIsClientAnimating = this.isClientAnimating && this.sentAnimation.currentFrame() != null; this.isClientAnimating = this.allowAnimation && this.animation != null; - if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.currentClientAnimation)) { - EventHooks.onAnimationEnded(this.currentClientAnimation); + if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.sentAnimation)) { + EventHooks.onAnimationEnded(this.sentAnimation); } if (this.isClientAnimating) { - this.currentClientAnimation = this.animation; + this.sentAnimation = this.animation; } if (this.animation != null && this.allowAnimation) { @@ -116,15 +105,11 @@ public class AnimationData implements IAnimationData { if (animationNBT == null && this.animation != null && !animationData.isCached(this.animation.getID())) { animationNBT = this.animation.writeToNBT(); } - animationData.viewAnimation(this.animation, this, animationNBT); + animationData.viewAnimation(this.animation, sendingEntity, this, animationNBT); } } } - public boolean isClientAnimating() { - return this.isClientAnimating; - } - public boolean isActive() { if (!this.allowAnimation || this.animation == null || this.animation.currentFrame == this.animation.frames.size() || animation.currentFrame() == null) return false; @@ -167,63 +152,27 @@ public class AnimationData implements IAnimationData { this.cachedAnimationIDs.clear(); } - public void viewAnimation(Animation animation, AnimationData animationData, NBTTagCompound animationNBT) { - this.viewAnimation(animation, animationData, animationNBT, animationData.allowAnimation, -1, -1); - } - - public void viewAnimation(Animation animation, AnimationData animationData, NBTTagCompound animationNBT, boolean enabled, int currentFrame, int time) { - boolean prevEnabled = animationData.allowAnimation; - animationData.allowAnimation = enabled; - NBTTagCompound data = animationData.viewWriteNBT(new NBTTagCompound()); - animationData.allowAnimation = prevEnabled; - - - if (animation != null && currentFrame >= 0 && currentFrame < animation.frames.size()) { - data.setInteger("Frame", currentFrame); - data.setInteger("Time", time); - } - + public void viewAnimation(Animation animation, EntityLivingBase entity, AnimationData animationData, NBTTagCompound animationNBT) { + NBTTagCompound data = animationData.writeToNBT(new NBTTagCompound()); if (animation != null) { - if (this.cachedAnimationIDs.contains(animation.getID()) && !data.hasKey("Frame")) { + if (this.cachedAnimationIDs.contains(animation.getID())) { data.setInteger("AnimationID", animation.getID()); } else { data.setTag("Animation", animationNBT); } } - - IAnimatable animatable = animationData.getEntity(); - Entity entity = ((IEntity) animatable).getMCEntity(); if (!(entity instanceof EntityPlayer)) { data.setInteger("EntityId", entity.getEntityId()); } - Server.sendData((EntityPlayerMP) ((PlayerData) parent).player, EnumPacketClient.UPDATE_ANIMATIONS, data, entity.getCommandSenderName()); } - public NBTTagCompound viewWriteNBT(NBTTagCompound compound) { - compound.setBoolean("AllowAnimation", allowAnimation); - return compound; - } - - public void viewReadFromNBT(NBTTagCompound compound) { - this.setEnabled(compound.getBoolean("AllowAnimation")); - } - public NBTTagCompound writeToNBT(NBTTagCompound compound) { - if (this.currentClientAnimation != null) { - compound.setTag("CurrentAnimation", currentClientAnimation.writeToNBT()); - compound.setBoolean("IsClientAnimating", isClientAnimating); - } compound.setBoolean("AllowAnimation", allowAnimation); return compound; } public void readFromNBT(NBTTagCompound compound) { - if (compound.hasKey("CurrentAnimation")) { - this.currentClientAnimation = new Animation(); - this.currentClientAnimation.readFromNBT(compound.getCompoundTag("CurrentAnimation")); - this.isClientAnimating = compound.getBoolean("IsClientAnimating"); - } this.setEnabled(compound.getBoolean("AllowAnimation")); } @@ -245,12 +194,11 @@ public class AnimationData implements IAnimationData { if (animation != null) { newAnim = new Animation(); newAnim.readFromNBT(((Animation) animation).writeToNBT()); - newAnim.currentFrame = 0; - newAnim.currentFrameTime = 0; newAnim.parent = this; } if (CustomNpcs.proxy.hasClient() && newAnim != null) { + CommonProxy.clientPlayingAnimations.remove(this.animation); CommonProxy.clientPlayingAnimations.add(newAnim); } this.animation = newAnim; From 266a6515e543823c10047081b7d4226a63fa1bdd Mon Sep 17 00:00:00 2001 From: "Luis C.M" <42545778+c0508383@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:37:31 -0500 Subject: [PATCH 15/32] Fixed animations being stuck. Animations should now properly continue where they left off when a player rejoins a server/ singleplayer world. --- src/main/java/noppes/npcs/CommonProxy.java | 66 ++++++++----- .../java/noppes/npcs/ServerEventsHandler.java | 24 +++-- .../npcs/client/ClientCacheHandler.java | 1 - .../noppes/npcs/client/ClientTickHandler.java | 2 +- .../npcs/client/PacketHandlerClient.java | 10 +- .../npcs/controllers/data/Animation.java | 37 ++++--- .../npcs/controllers/data/AnimationData.java | 96 +++++++++++++++---- 7 files changed, 171 insertions(+), 65 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 68c9db672..5bf78ad28 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -1,5 +1,6 @@ package noppes.npcs; +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.network.IGuiHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -23,7 +24,6 @@ import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.util.MillisTimer; -import java.util.ConcurrentModificationException; import java.util.HashSet; public class CommonProxy implements IGuiHandler { @@ -42,34 +42,46 @@ public class CommonProxy implements IGuiHandler { protected void createAnimationThread() { Thread thread = (new Thread("Animation Thread") { public void run() { while (true) { - if (!CustomNpcs.proxy.hasClient() || !Minecraft.getMinecraft().isGamePaused()) { - animationTimer.updateTimer(); - } - - HashSet playingAnimations = CustomNpcs.proxy.hasClient() ? clientPlayingAnimations : serverPlayingAnimations; - for (int i = 0; i < animationTimer.elapsedTicks; ++i) { - for (Animation animation : playingAnimations) { - int tickDuration = animation.currentFrame().tickDuration(); - if (animation.parent.isActive() && totalTicks % tickDuration == 0) { - animation.increaseTime(); - } - } - totalTicks++; - } - totalTicks %= 60 * 60 * 1000; - try { - clientPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); - serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); - } catch (ConcurrentModificationException ignored) {} + if (!CustomNpcs.proxy.hasClient() || !Minecraft.getMinecraft().isGamePaused()) { + animationTimer.updateTimer(); + } + + for (int i = 0; i < animationTimer.elapsedTicks; ++i) { + updateAnimations(clientPlayingAnimations); + updateAnimations(serverPlayingAnimations); + totalTicks++; + } + totalTicks %= 60 * 60 * 1000; + + synchronized (clientPlayingAnimations) { + clientPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); + } + synchronized (serverPlayingAnimations) { + serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); + } + } catch (Exception ignored) { + //Must ignore exceptions in this thread so a single animation error doesn't break all animations. + } } }}); thread.setDaemon(true); thread.start(); } + private void updateAnimations(HashSet playingAnimations) { + for (Animation animation : playingAnimations) { + int tickDuration = animation.currentFrame().tickDuration(); + if ((animation.parent.isActive() + || animation.parent.animation == null && animation.parent.isActive(animation.parent.currentClientAnimation)) + && totalTicks % tickDuration == 0) { + animation.increaseTime(); + } + } + } + private boolean removeAnimation(Animation animation) { - if (animation.currentFrame() == null || animation.parent == null || animation.parent.animation != animation) { + if (animation.currentFrame() == null || animation.parent == null) { return true; } @@ -86,17 +98,19 @@ public class CommonProxy implements IGuiHandler { if (entity == null) return true; - if (CustomNpcs.proxy.hasClient()) { - return clientRemoveAnimation(entity); + if (entity.worldObj != null && entity.worldObj.isRemote) { + return animation.parent.animation != animation || clientRemoveAnimation(entity); } else { - return entity.worldObj == null || !entity.worldObj.loadedEntityList.contains(entity); + return animation.parent.animation != animation && animation.parent.currentClientAnimation != animation + || entity.worldObj == null || !entity.worldObj.loadedEntityList.contains(entity) + || CustomNpcs.getServer().isServerStopped(); } } @SideOnly(Side.CLIENT) private boolean clientRemoveAnimation(Entity entity) { - return Minecraft.getMinecraft().currentScreen == null - && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity); + return Minecraft.getMinecraft().theWorld == null + || Minecraft.getMinecraft().currentScreen == null && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity); } public PlayerData getPlayerData(EntityPlayer player) { diff --git a/src/main/java/noppes/npcs/ServerEventsHandler.java b/src/main/java/noppes/npcs/ServerEventsHandler.java index ab7b67a5d..7742199d8 100644 --- a/src/main/java/noppes/npcs/ServerEventsHandler.java +++ b/src/main/java/noppes/npcs/ServerEventsHandler.java @@ -497,12 +497,24 @@ public class ServerEventsHandler { @SubscribeEvent public void playerTracking(PlayerEvent.StartTracking event){ - if(!(event.target instanceof EntityNPCInterface) || event.target.worldObj.isRemote) - return; + if (event.target.worldObj.isRemote) return; - MarkData data = MarkData.get((EntityNPCInterface) event.target); - if(data.marks.isEmpty()) - return; - Server.sendData((EntityPlayerMP)event.entityPlayer, EnumPacketClient.MARK_DATA, event.target.getEntityId(), data.getNBT()); + if(event.target instanceof EntityPlayerMP || event.target instanceof EntityNPCInterface) { + AnimationData animationData = AnimationData.getData(event.target); + if (animationData.isClientAnimating()) { + AnimationData playerAnimData = AnimationData.getData(event.entityPlayer); + Animation currentAnimation = animationData.currentClientAnimation; + NBTTagCompound compound = currentAnimation.writeToNBT(); + playerAnimData.viewAnimation(currentAnimation, animationData, compound, + animationData.isClientAnimating(), currentAnimation.currentFrame, currentAnimation.currentFrameTime); + } + + if (event.target instanceof EntityNPCInterface) { + MarkData data = MarkData.get((EntityNPCInterface) event.target); + if (data.marks.isEmpty()) + return; + Server.sendData((EntityPlayerMP) event.entityPlayer, EnumPacketClient.MARK_DATA, event.target.getEntityId(), data.getNBT()); + } + } } } diff --git a/src/main/java/noppes/npcs/client/ClientCacheHandler.java b/src/main/java/noppes/npcs/client/ClientCacheHandler.java index bf9c920f4..810cc4bf0 100644 --- a/src/main/java/noppes/npcs/client/ClientCacheHandler.java +++ b/src/main/java/noppes/npcs/client/ClientCacheHandler.java @@ -57,7 +57,6 @@ public class ClientCacheHandler { ClientCacheHandler.skinOverlays.clear(); ClientCacheHandler.playerAnimations.clear(); ClientCacheHandler.playerData.animationData.clearCache(); - CommonProxy.clientPlayingAnimations.clear(); } public static void clearSkinCache() { diff --git a/src/main/java/noppes/npcs/client/ClientTickHandler.java b/src/main/java/noppes/npcs/client/ClientTickHandler.java index 4be801a9b..a2f82b27e 100644 --- a/src/main/java/noppes/npcs/client/ClientTickHandler.java +++ b/src/main/java/noppes/npcs/client/ClientTickHandler.java @@ -32,7 +32,7 @@ public class ClientTickHandler{ @SubscribeEvent(priority = EventPriority.LOWEST) public void onClientTick(TickEvent.ClientTickEvent event){ Minecraft mc = Minecraft.getMinecraft(); - if ((this.prevWorld == null || mc.theWorld == null) && this.prevWorld != mc.theWorld) { + if (mc.theWorld != null && this.prevWorld != mc.theWorld) { ClientCacheHandler.clearCache(); this.prevWorld = mc.theWorld; } diff --git a/src/main/java/noppes/npcs/client/PacketHandlerClient.java b/src/main/java/noppes/npcs/client/PacketHandlerClient.java index b989406cb..7c3ef866c 100644 --- a/src/main/java/noppes/npcs/client/PacketHandlerClient.java +++ b/src/main/java/noppes/npcs/client/PacketHandlerClient.java @@ -375,8 +375,14 @@ public class PacketHandlerClient extends PacketHandlerServer{ } animationData.setAnimation(ClientCacheHandler.animationCache.get(animationId)); - animationData.readFromNBT(compound); - Client.sendData(EnumPacketServer.CacheAnimation, animationId); + animationData.viewReadFromNBT(compound); + + if (compound.hasKey("Frame")) { + animationData.animation.readFromNBT(compound.getCompoundTag("Animation")); + animationData.animation.jumpToFrameAtTime(compound.getInteger("Frame"), compound.getInteger("Time")); + } else if (compound.hasKey("Animation")) { + 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 0b9ae8fd7..80fc28400 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -5,6 +5,8 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import noppes.npcs.CustomNpcs; +import noppes.npcs.DataDisplay; import noppes.npcs.EventHooks; import noppes.npcs.api.handler.data.IAnimation; import noppes.npcs.api.handler.data.IAnimationData; @@ -210,6 +212,9 @@ public class Animation implements IAnimation { this.whileStanding = compound.getBoolean("WhileStanding"); this.whileMoving = compound.getBoolean("WhileWalking"); this.whileAttacking = compound.getBoolean("WhileAttacking"); + + this.currentFrame = compound.getInteger("CurrentFrame"); + this.currentFrameTime = compound.getInteger("CurrentFrameTime"); } public NBTTagCompound writeToNBT(){ @@ -231,6 +236,9 @@ public class Animation implements IAnimation { compound.setBoolean("WhileStanding", whileStanding); compound.setBoolean("WhileWalking", whileMoving); compound.setBoolean("WhileAttacking", whileAttacking); + + compound.setInteger("CurrentFrame", currentFrame); + compound.setInteger("CurrentFrameTime", currentFrameTime); return compound; } @@ -277,16 +285,23 @@ public class Animation implements IAnimation { @SideOnly(Side.CLIENT) public void jumpToCurrentFrame() { - this.currentFrameTime = 0; - Frame frame = (Frame) this.currentFrame(); - if(frame != null){ - for (EnumAnimationPart part : EnumAnimationPart.values()) { - if(part != null){ - if (frame.frameParts.containsKey(part)) { - frame.frameParts.get(part).jumpToCurrentFrame(); - } - } - } - } + this.jumpToFrameAtTime(this.currentFrame, 0); } + + @SideOnly(Side.CLIENT) + public void jumpToFrameAtTime(int frameIndex, int time) { + this.currentFrame = frameIndex; + this.currentFrameTime = time; + + Frame frame = (Frame) this.currentFrame(); + if(frame != null){ + for (EnumAnimationPart part : EnumAnimationPart.values()) { + if(part != null){ + if (frame.frameParts.containsKey(part)) { + frame.frameParts.get(part).jumpToCurrentFrame(); + } + } + } + } + } } diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index d8d4a07f7..5a4e25834 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -1,7 +1,7 @@ package noppes.npcs.controllers.data; -import cpw.mods.fml.common.FMLCommonHandler; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -10,6 +10,7 @@ import net.minecraft.util.AxisAlignedBB; import noppes.npcs.*; import noppes.npcs.api.entity.IAnimatable; import noppes.npcs.api.entity.ICustomNpc; +import noppes.npcs.api.entity.IEntity; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.handler.data.IAnimation; import noppes.npcs.api.handler.data.IAnimationData; @@ -32,7 +33,7 @@ public class AnimationData implements IAnimationData { public Animation animation; public boolean allowAnimation = false; - private Animation sentAnimation; + public Animation currentClientAnimation; private boolean isClientAnimating; private final HashSet cachedAnimationIDs = new HashSet<>(); @@ -51,6 +52,16 @@ public class AnimationData implements IAnimationData { } } + public static AnimationData getData(Entity entity) { + if (entity instanceof EntityPlayerMP) { + return PlayerData.get((EntityPlayer) entity).animationData; + } else if (entity instanceof EntityNPCInterface) { + return ((EntityNPCInterface)entity).display.animationData; + } else { + return null; + } + } + public IAnimatable getEntity() { if (this.parent instanceof DataDisplay) { EntityNPCInterface npc = ((DataDisplay)this.parent).npc; @@ -74,13 +85,13 @@ public class AnimationData implements IAnimationData { 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) { - boolean prevIsClientAnimating = this.isClientAnimating && this.sentAnimation.currentFrame() != null; + boolean prevIsClientAnimating = this.isClientAnimating && this.currentClientAnimation.currentFrame() != null; this.isClientAnimating = this.allowAnimation && this.animation != null; - if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.sentAnimation)) { - EventHooks.onAnimationEnded(this.sentAnimation); + if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.currentClientAnimation)) { + EventHooks.onAnimationEnded(this.currentClientAnimation); } if (this.isClientAnimating) { - this.sentAnimation = this.animation; + this.currentClientAnimation = this.animation; } if (this.animation != null && this.allowAnimation) { @@ -89,10 +100,6 @@ public class AnimationData implements IAnimationData { EventHooks.onAnimationFrameEntered(this.animation, this.animation.currentFrame()); } - if (!CustomNpcs.proxy.hasClient()) { - CommonProxy.serverPlayingAnimations.add(this.animation); - } - List entities = sendingEntity.worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox( sendingEntity.posX - range, sendingEntity.posY - range, sendingEntity.posZ - range, sendingEntity.posX + range, sendingEntity.posY + range, sendingEntity.posZ + range)); @@ -105,13 +112,21 @@ public class AnimationData implements IAnimationData { if (animationNBT == null && this.animation != null && !animationData.isCached(this.animation.getID())) { animationNBT = this.animation.writeToNBT(); } - animationData.viewAnimation(this.animation, sendingEntity, this, animationNBT); + animationData.viewAnimation(this.animation, this, animationNBT); } } } + public boolean isClientAnimating() { + return this.isClientAnimating; + } + public boolean isActive() { - if (!this.allowAnimation || this.animation == null || this.animation.currentFrame == this.animation.frames.size() || animation.currentFrame() == null) + return this.isActive(this.animation); + } + + public boolean isActive(Animation animation) { + if (!this.allowAnimation || animation == null || animation.currentFrame == animation.frames.size() || animation.currentFrame() == null) return false; if (this.parent instanceof DataDisplay) { @@ -152,27 +167,69 @@ public class AnimationData implements IAnimationData { this.cachedAnimationIDs.clear(); } - public void viewAnimation(Animation animation, EntityLivingBase entity, AnimationData animationData, NBTTagCompound animationNBT) { - NBTTagCompound data = animationData.writeToNBT(new NBTTagCompound()); + public void viewAnimation(Animation animation, AnimationData animationData, NBTTagCompound animationNBT) { + this.viewAnimation(animation, animationData, animationNBT, animationData.allowAnimation, -1, -1); + } + + public void viewAnimation(Animation animation, AnimationData animationData, NBTTagCompound animationNBT, boolean enabled, int currentFrame, int time) { + boolean prevEnabled = animationData.allowAnimation; + animationData.allowAnimation = enabled; + NBTTagCompound data = animationData.viewWriteNBT(new NBTTagCompound()); + animationData.allowAnimation = prevEnabled; + + synchronized (CommonProxy.serverPlayingAnimations) { + if (animationData.animationEntity != null && !animationData.animationEntity.worldObj.isRemote) { + CommonProxy.serverPlayingAnimations.add(animation); + } + } + + if (animation != null && currentFrame >= 0 && currentFrame < animation.frames.size()) { + data.setInteger("Frame", currentFrame); + data.setInteger("Time", time); + } + if (animation != null) { - if (this.cachedAnimationIDs.contains(animation.getID())) { + if (this.cachedAnimationIDs.contains(animation.getID()) && !data.hasKey("Frame")) { data.setInteger("AnimationID", animation.getID()); } else { data.setTag("Animation", animationNBT); } } + + IAnimatable animatable = animationData.getEntity(); + Entity entity = ((IEntity) animatable).getMCEntity(); if (!(entity instanceof EntityPlayer)) { data.setInteger("EntityId", entity.getEntityId()); } + Server.sendData((EntityPlayerMP) ((PlayerData) parent).player, EnumPacketClient.UPDATE_ANIMATIONS, data, entity.getCommandSenderName()); } + public NBTTagCompound viewWriteNBT(NBTTagCompound compound) { + compound.setBoolean("AllowAnimation", allowAnimation); + return compound; + } + + public void viewReadFromNBT(NBTTagCompound compound) { + this.setEnabled(compound.getBoolean("AllowAnimation")); + } + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + if (this.currentClientAnimation != null) { + compound.setTag("CurrentAnimation", currentClientAnimation.writeToNBT()); + compound.setBoolean("IsClientAnimating", isClientAnimating); + } compound.setBoolean("AllowAnimation", allowAnimation); return compound; } public void readFromNBT(NBTTagCompound compound) { + if (compound.hasKey("CurrentAnimation")) { + this.currentClientAnimation = new Animation(); + this.currentClientAnimation.parent = this; + this.currentClientAnimation.readFromNBT(compound.getCompoundTag("CurrentAnimation")); + this.isClientAnimating = compound.getBoolean("IsClientAnimating"); + } this.setEnabled(compound.getBoolean("AllowAnimation")); } @@ -194,12 +251,15 @@ public class AnimationData implements IAnimationData { if (animation != null) { newAnim = new Animation(); newAnim.readFromNBT(((Animation) animation).writeToNBT()); + newAnim.currentFrame = 0; + newAnim.currentFrameTime = 0; newAnim.parent = this; } - if (CustomNpcs.proxy.hasClient() && newAnim != null) { - CommonProxy.clientPlayingAnimations.remove(this.animation); - CommonProxy.clientPlayingAnimations.add(newAnim); + synchronized (CommonProxy.clientPlayingAnimations) { + if (this.animationEntity != null && this.animationEntity.worldObj.isRemote && newAnim != null) { + CommonProxy.clientPlayingAnimations.add(newAnim); + } } this.animation = newAnim; From 84b65865a9ddcfa90fb8b10c8c06ea24ea3e9007 Mon Sep 17 00:00:00 2001 From: luisc Date: Mon, 1 Apr 2024 16:30:18 -0500 Subject: [PATCH 16/32] Implemented frame comments --- .../npcs/client/gui/SubGuiAnimationFrame.java | 5 +++++ .../java/noppes/npcs/controllers/data/Frame.java | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java index 9518f0977..62837a495 100644 --- a/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java +++ b/src/main/java/noppes/npcs/client/gui/SubGuiAnimationFrame.java @@ -37,6 +37,9 @@ public class SubGuiAnimationFrame extends SubGuiInterface implements ITextfieldL this.getTextField(13).integersOnly = true; this.getTextField(13).setMinMaxDefault(1, Integer.MAX_VALUE, 50); } + + this.addLabel(new GuiNpcLabel(14, "Comment", guiLeft + 5, guiTop + 106)); + this.addTextField(new GuiNpcTextField(14, this, guiLeft + 50, guiTop + 101, 120, 15, editingFrame.getComment())); } @Override @@ -66,6 +69,8 @@ public class SubGuiAnimationFrame extends SubGuiInterface implements ITextfieldL this.editingFrame.speed = textfield.getFloat(); } else if (textfield.id == 13) { this.editingFrame.tickDuration = textfield.getInteger(); + } else if (textfield.id == 14) { + this.editingFrame.setComment(textfield.getText()); } } } diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index c59fd0ec8..461d41d23 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -21,6 +21,7 @@ public class Frame implements IFrame { public byte smooth = 0; private int colorMarker = 0xFFFFFF; + private String comment = ""; public Frame(){} @@ -120,11 +121,22 @@ public class Frame implements IFrame { this.colorMarker = color; } + public String getComment() { + return this.comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + public void readFromNBT(NBTTagCompound compound){ duration = compound.getInteger("Duration"); if (compound.hasKey("ColorMarker")) { this.setColorMarker(compound.getInteger("ColorMarker")); } + if (compound.hasKey("Comment")) { + this.comment = compound.getString("Comment"); + } // Customized = TRUE if Speed or Smooth Exist if(compound.hasKey("Speed")){ @@ -169,6 +181,7 @@ public class Frame implements IFrame { NBTTagCompound compound = new NBTTagCompound(); compound.setInteger("Duration", duration); compound.setInteger("ColorMarker", this.colorMarker); + compound.setString("Comment", this.comment); if(customized){ compound.setFloat("Speed", speed); From 403b6c5d32e8801549ac2059e7ed8c6ff2fce8e3 Mon Sep 17 00:00:00 2001 From: luisc Date: Tue, 2 Apr 2024 15:19:27 -0500 Subject: [PATCH 17/32] Fixes to animations --- src/main/java/noppes/npcs/CommonProxy.java | 1 - .../npcs/controllers/data/AnimationData.java | 15 +++++++++++---- .../npcs/controllers/data/PlayerDataScript.java | 3 ++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 5bf78ad28..db8c14d8a 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -61,7 +61,6 @@ public class CommonProxy implements IGuiHandler { serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); } } catch (Exception ignored) { - //Must ignore exceptions in this thread so a single animation error doesn't break all animations. } } }}); diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index d965d3c74..0ddf23d92 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -63,9 +63,16 @@ public class AnimationData implements IAnimationData { } public IAnimatable getEntity() { + IEntity entity = NpcAPI.Instance().getIEntity(this.getMCEntity()); + if (entity instanceof IAnimatable) { + return (IAnimatable) entity; + } + return null; + } + + public EntityLivingBase getMCEntity() { if (this.parent instanceof DataDisplay) { - EntityNPCInterface npc = ((DataDisplay)this.parent).npc; - return (ICustomNpc) NpcAPI.Instance().getIEntity(npc); + return ((DataDisplay) this.parent).npc; } else { EntityPlayer player; if (this.parent instanceof PlayerData) { @@ -73,7 +80,7 @@ public class AnimationData implements IAnimationData { } else { player = (EntityPlayer) this.parent; } - return (IPlayer) NpcAPI.Instance().getIEntity(player); + return player; } } @@ -181,7 +188,7 @@ public class AnimationData implements IAnimationData { animationData.allowAnimation = prevEnabled; synchronized (CommonProxy.serverPlayingAnimations) { - if (animationData.animationEntity != null && !animationData.animationEntity.worldObj.isRemote) { + if (animationData.animationEntity != null && !animationData.animationEntity.worldObj.isRemote && animation != null) { CommonProxy.serverPlayingAnimations.add(animation); } } diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java b/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java index 85096dfe0..2f1b88478 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java @@ -1,6 +1,7 @@ package noppes.npcs.controllers.data; import com.google.common.base.Preconditions; +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.Event; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; @@ -97,7 +98,7 @@ public class PlayerDataScript implements INpcScriptHandler { } public boolean isClient() { - return this.player.isClientWorld(); + return FMLCommonHandler.instance().getEffectiveSide().isClient(); } public boolean getEnabled() { return ScriptController.Instance.playerScripts.enabled; From d2a189ac3add5b0643a3956ea1281d82a0e0ceda Mon Sep 17 00:00:00 2001 From: luisc Date: Tue, 2 Apr 2024 15:26:55 -0500 Subject: [PATCH 18/32] Fixes to servers not ticking animations correctly on the server-side. --- .../noppes/npcs/controllers/data/AnimationData.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 0ddf23d92..08e8d29f9 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -110,6 +110,13 @@ public class AnimationData implements IAnimationData { EventHooks.onAnimationFrameEntered(this.animation, this.animation.currentFrame()); } + synchronized (CommonProxy.serverPlayingAnimations) { + if (this.isClientAnimating && this.animationEntity != null && + !this.animationEntity.worldObj.isRemote && this.animation != null) { + CommonProxy.serverPlayingAnimations.add(this.animation); + } + } + List entities = sendingEntity.worldObj.getEntitiesWithinAABB(EntityPlayer.class, AxisAlignedBB.getBoundingBox( sendingEntity.posX - range, sendingEntity.posY - range, sendingEntity.posZ - range, sendingEntity.posX + range, sendingEntity.posY + range, sendingEntity.posZ + range)); @@ -187,12 +194,6 @@ public class AnimationData implements IAnimationData { NBTTagCompound data = animationData.viewWriteNBT(new NBTTagCompound()); animationData.allowAnimation = prevEnabled; - synchronized (CommonProxy.serverPlayingAnimations) { - if (animationData.animationEntity != null && !animationData.animationEntity.worldObj.isRemote && animation != null) { - CommonProxy.serverPlayingAnimations.add(animation); - } - } - if (animation != null && currentFrame >= 0 && currentFrame < animation.frames.size()) { data.setInteger("Frame", currentFrame); data.setInteger("Time", time); From e51198bab851520ac8bed3fd4a6071c83512a7b4 Mon Sep 17 00:00:00 2001 From: luisc Date: Tue, 2 Apr 2024 15:32:55 -0500 Subject: [PATCH 19/32] Fixed animation data not working on players. --- .../noppes/npcs/controllers/data/AnimationData.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 08e8d29f9..577f7cc6a 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -45,11 +45,7 @@ public class AnimationData implements IAnimationData { 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; - } + this.animationEntity = this.getMCEntity(); } public static AnimationData getData(Entity entity) { @@ -71,6 +67,10 @@ public class AnimationData implements IAnimationData { } public EntityLivingBase getMCEntity() { + if (this.animationEntity != null) { + return this.animationEntity; + } + if (this.parent instanceof DataDisplay) { return ((DataDisplay) this.parent).npc; } else { From 064c4123d6c99b309419e9b7ae06117e5c9321a1 Mon Sep 17 00:00:00 2001 From: luisc Date: Tue, 2 Apr 2024 16:03:57 -0500 Subject: [PATCH 20/32] More small fixes to animations and animation data. --- .../npcs/controllers/data/Animation.java | 2 +- .../npcs/controllers/data/AnimationData.java | 20 ++++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 80fc28400..29dd816e7 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -278,7 +278,7 @@ public class Animation implements IAnimation { } } } else if (this.parent != null && this.currentFrame > this.loop) { - this.parent.finishedTime = this.parent.animationEntity.getAge(); + this.parent.finishedTime = this.parent.getMCEntity().getAge(); } } } diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 577f7cc6a..112a461cf 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -39,13 +39,11 @@ 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; - this.animationEntity = this.getMCEntity(); } public static AnimationData getData(Entity entity) { @@ -67,20 +65,14 @@ public class AnimationData implements IAnimationData { } public EntityLivingBase getMCEntity() { - if (this.animationEntity != null) { - return this.animationEntity; - } - if (this.parent instanceof DataDisplay) { - return ((DataDisplay) this.parent).npc; + return ((DataDisplay) this.parent).npc; } else { - EntityPlayer player; if (this.parent instanceof PlayerData) { - player = ((PlayerData) this.parent).player; + return ((PlayerData) this.parent).player; } else { - player = (EntityPlayer) this.parent; + return (EntityPlayer) this.parent; } - return player; } } @@ -111,8 +103,8 @@ public class AnimationData implements IAnimationData { } synchronized (CommonProxy.serverPlayingAnimations) { - if (this.isClientAnimating && this.animationEntity != null && - !this.animationEntity.worldObj.isRemote && this.animation != null) { + if (this.isClientAnimating && this.getMCEntity() != null && + !this.getMCEntity().worldObj.isRemote && this.animation != null) { CommonProxy.serverPlayingAnimations.add(this.animation); } } @@ -268,7 +260,7 @@ public class AnimationData implements IAnimationData { } synchronized (CommonProxy.clientPlayingAnimations) { - if (this.animationEntity != null && this.animationEntity.worldObj.isRemote && newAnim != null) { + if (this.getMCEntity() != null && this.getMCEntity().worldObj.isRemote && newAnim != null) { CommonProxy.clientPlayingAnimations.add(newAnim); } } From f117e32fec89f2980fdb2d67160ec9417990e766 Mon Sep 17 00:00:00 2001 From: luisc Date: Tue, 2 Apr 2024 16:37:01 -0500 Subject: [PATCH 21/32] Made animation thread exceptions print stack traces. Might remove before release, since this has the potential to spam up server/client consoles. --- src/main/java/noppes/npcs/CommonProxy.java | 6 ++++-- .../java/noppes/npcs/controllers/data/PlayerDataScript.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index db8c14d8a..544467cc9 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -60,7 +60,8 @@ public class CommonProxy implements IGuiHandler { synchronized (serverPlayingAnimations) { serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); } - } catch (Exception ignored) { + } catch (Exception e) { + e.printStackTrace(); } } }}); @@ -100,7 +101,8 @@ public class CommonProxy implements IGuiHandler { if (entity.worldObj != null && entity.worldObj.isRemote) { return animation.parent.animation != animation || clientRemoveAnimation(entity); } else { - return animation.parent.animation != animation && animation.parent.currentClientAnimation != animation + return !animation.parent.isClientAnimating() + || animation.parent.animation != animation && animation.parent.currentClientAnimation != animation || entity.worldObj == null || !entity.worldObj.loadedEntityList.contains(entity) || CustomNpcs.getServer().isServerStopped(); } diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java b/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java index 2f1b88478..dbd618fa5 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerDataScript.java @@ -98,7 +98,7 @@ public class PlayerDataScript implements INpcScriptHandler { } public boolean isClient() { - return FMLCommonHandler.instance().getEffectiveSide().isClient(); + return false; } public boolean getEnabled() { return ScriptController.Instance.playerScripts.enabled; From 55cd639124e305251eb610586a55e4163ea288f6 Mon Sep 17 00:00:00 2001 From: luisc Date: Tue, 2 Apr 2024 18:16:46 -0500 Subject: [PATCH 22/32] Separated client and server ticks into two static variables --- src/main/java/noppes/npcs/CommonProxy.java | 39 +++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 544467cc9..5bfd6b54f 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -1,6 +1,5 @@ package noppes.npcs; -import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.network.IGuiHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -30,7 +29,8 @@ public class CommonProxy implements IGuiHandler { public final static HashSet clientPlayingAnimations = new HashSet<>(); public final static HashSet serverPlayingAnimations = new HashSet<>(); protected MillisTimer animationTimer = new MillisTimer(1000); - protected long totalTicks; + protected static long totalServerTicks; + protected static long totalClientTicks; public void load() { this.createAnimationThread(); @@ -48,11 +48,25 @@ public class CommonProxy implements IGuiHandler { } for (int i = 0; i < animationTimer.elapsedTicks; ++i) { - updateAnimations(clientPlayingAnimations); - updateAnimations(serverPlayingAnimations); - totalTicks++; + for (Animation animation : clientPlayingAnimations) { + int tickDuration = animation.currentFrame().tickDuration(); + if (updateAnimation(animation) && totalClientTicks % tickDuration == 0) { + animation.increaseTime(); + } + } + totalClientTicks++; + + for (Animation animation : serverPlayingAnimations) { + int tickDuration = animation.currentFrame().tickDuration(); + if (updateAnimation(animation) && totalServerTicks % tickDuration == 0) { + animation.increaseTime(); + } + } + totalServerTicks++; } - totalTicks %= 60 * 60 * 1000; + + totalClientTicks %= Long.MAX_VALUE; + totalServerTicks %= Long.MAX_VALUE; synchronized (clientPlayingAnimations) { clientPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); @@ -69,15 +83,10 @@ public class CommonProxy implements IGuiHandler { thread.start(); } - private void updateAnimations(HashSet playingAnimations) { - for (Animation animation : playingAnimations) { - int tickDuration = animation.currentFrame().tickDuration(); - if ((animation.parent.isActive() - || animation.parent.animation == null && animation.parent.isActive(animation.parent.currentClientAnimation)) - && totalTicks % tickDuration == 0) { - animation.increaseTime(); - } - } + private boolean updateAnimation(Animation animation) { + return animation.parent.isActive() + || animation.parent.animation == null + && animation.parent.isActive(animation.parent.currentClientAnimation); } private boolean removeAnimation(Animation animation) { From 0d9a26c58c1decb3065c27efa76ecb01b1368580 Mon Sep 17 00:00:00 2001 From: luisc Date: Wed, 3 Apr 2024 18:12:50 -0500 Subject: [PATCH 23/32] ==STILL SLIGHTLY BUGGED== Scripted blocks now render exactly like regular blocks in the world. --- .../noppes/npcs/blocks/BlockScripted.java | 6 ++- .../npcs/blocks/tiles/TileScripted.java | 17 ++++++- .../blocks/BlockScriptedRenderer.java | 47 +++++++++++++++---- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/main/java/noppes/npcs/blocks/BlockScripted.java b/src/main/java/noppes/npcs/blocks/BlockScripted.java index f1b4b9266..c34283704 100644 --- a/src/main/java/noppes/npcs/blocks/BlockScripted.java +++ b/src/main/java/noppes/npcs/blocks/BlockScripted.java @@ -25,6 +25,8 @@ import noppes.npcs.constants.EnumGuiType; import java.util.Random; public class BlockScripted extends BlockContainer { + + public int renderId = -1; public static final AxisAlignedBB AABB = AxisAlignedBB.getBoundingBox(0.001f, 0.001f, 0.001f, 0.998f, 0.998f, 0.998f); public static final AxisAlignedBB AABB_EMPTY = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0); @@ -109,12 +111,12 @@ public class BlockScripted extends BlockContainer { @Override public boolean canRenderInPass(int pass) { - return false; + return super.canRenderInPass(pass); } @Override public int getRenderType() { - return 0; + return renderId; } @Override public boolean isOpaqueCube() { diff --git a/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java b/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java index b2d3bf8b4..2628c494a 100644 --- a/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java +++ b/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java @@ -15,6 +15,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; import noppes.npcs.*; import noppes.npcs.api.IBlock; import noppes.npcs.api.block.ITextPlane; @@ -48,6 +49,7 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { public ItemStack itemModel = new ItemStack(CustomItems.scripted); public Block blockModel = null; + private int metadata; public boolean needsClientUpdate = false; @@ -68,6 +70,7 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { public TileEntity renderTile; public boolean renderTileErrored = true; + public boolean renderFullBlock = true; public ITickable renderTileUpdate = null; public TextPlane text1 = new TextPlane(); @@ -219,9 +222,14 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { EventHooks.onScriptBlockUpdate(this); ticksExisted = 0; if(needsClientUpdate){ - markDirty(); + worldObj.func_147451_t(xCoord, yCoord, zCoord); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - worldObj.notifyBlocksOfNeighborChange(xCoord,yCoord,zCoord,getBlockType(),3); + worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, CustomItems.scripted); + + Chunk chunk = worldObj.getChunkFromChunkCoords(xCoord >> 4, zCoord >> 4); + chunk.setBlockMetadata(xCoord & 15, yCoord, zCoord & 15, metadata); + blockMetadata = metadata; + needsClientUpdate = false; } } @@ -273,6 +281,11 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { if(NoppesUtilPlayer.compareItems(item, itemModel, false, false) && b != blockModel) return; + boolean blockChanged = b != blockModel; + int meta = item.getItemDamage(); + metadata = (meta == 0 || meta == metadata) && blockChanged ? metadata + 1 : meta; + this.blockMetadata = metadata; + itemModel = item; blockModel = b; needsClientUpdate = true; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java index 96aa40e7e..12e3a69fb 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java @@ -1,18 +1,18 @@ package noppes.npcs.client.renderer.blocks; +import cpw.mods.fml.client.registry.RenderingRegistry; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.entity.item.EntityItem; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.src.FMLRenderAccessLibrary; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; import net.minecraftforge.client.ForgeHooksClient; import noppes.npcs.CustomItems; import noppes.npcs.blocks.BlockScripted; @@ -28,6 +28,38 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ private static final RenderBlocks renderBlocks = new RenderBlocks(); private static final Random random = new Random(); + public BlockScriptedRenderer() { + ((BlockScripted) CustomItems.scripted).renderId = RenderingRegistry.getNextAvailableRenderId(); + RenderingRegistry.registerBlockHandler(this); + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + TileScripted tile = (TileScripted) world.getTileEntity(x, y, z); + Block blockModel = tile.blockModel; + + if (!overrideModel() && blockModel != null) { + GL11.glPushMatrix(); + GL11.glRotatef(tile.rotationY, 0, 1, 0); + GL11.glRotatef(tile.rotationX, 1, 0, 0); + GL11.glRotatef(tile.rotationZ, 0, 0, 1); + GL11.glScalef(tile.scaleX, tile.scaleY, tile.scaleZ); + if (blockModel != CustomItems.scripted) { + tile.renderFullBlock = renderer.renderBlockByRenderType(blockModel, x, y, z); + } else { + renderer.renderStandardBlock(blockModel, x, y, z); + tile.renderFullBlock = true; + } + GL11.glPopMatrix(); + } + + return true; + } + + public int getRenderId() { + return CustomItems.scripted.getRenderType(); + } + @Override public void renderTileEntityAt(TileEntity te, double x, double y, double z, float partialTicks) { TileScripted tile = (TileScripted) te; @@ -38,8 +70,7 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ GL11.glTranslatef((float) (x + 0.5), (float) y, (float) (z + 0.5)); if (overrideModel()) { GL11.glTranslatef(0, 0.5F, 0); - renderItem(te, new ItemStack(CustomItems.scripted)); - } else { + } else if (!tile.renderFullBlock) { GL11.glRotatef(tile.rotationY, 0, 1, 0); GL11.glRotatef(tile.rotationX, 1, 0, 0); GL11.glRotatef(tile.rotationZ, 0, 0, 1); @@ -166,7 +197,7 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ } @Override - public int getRenderId() { - return 0; + public boolean shouldRender3DInInventory(int modelId) { + return false; } } From 91167cbc7f5edc01fa5641ff0edd047f33cb6ced Mon Sep 17 00:00:00 2001 From: "Luis C.M." <42545778+c0508383@users.noreply.github.com> Date: Wed, 3 Apr 2024 21:32:03 -0500 Subject: [PATCH 24/32] reverted commit in animation events, moving to dev woops --- .../noppes/npcs/blocks/BlockScripted.java | 6 ++- .../npcs/blocks/tiles/TileScripted.java | 17 ++++++- .../blocks/BlockScriptedRenderer.java | 47 +++++++++++++++---- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/main/java/noppes/npcs/blocks/BlockScripted.java b/src/main/java/noppes/npcs/blocks/BlockScripted.java index f1b4b9266..c34283704 100644 --- a/src/main/java/noppes/npcs/blocks/BlockScripted.java +++ b/src/main/java/noppes/npcs/blocks/BlockScripted.java @@ -25,6 +25,8 @@ import noppes.npcs.constants.EnumGuiType; import java.util.Random; public class BlockScripted extends BlockContainer { + + public int renderId = -1; public static final AxisAlignedBB AABB = AxisAlignedBB.getBoundingBox(0.001f, 0.001f, 0.001f, 0.998f, 0.998f, 0.998f); public static final AxisAlignedBB AABB_EMPTY = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0); @@ -109,12 +111,12 @@ public class BlockScripted extends BlockContainer { @Override public boolean canRenderInPass(int pass) { - return false; + return super.canRenderInPass(pass); } @Override public int getRenderType() { - return 0; + return renderId; } @Override public boolean isOpaqueCube() { diff --git a/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java b/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java index b2d3bf8b4..2628c494a 100644 --- a/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java +++ b/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java @@ -15,6 +15,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; import noppes.npcs.*; import noppes.npcs.api.IBlock; import noppes.npcs.api.block.ITextPlane; @@ -48,6 +49,7 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { public ItemStack itemModel = new ItemStack(CustomItems.scripted); public Block blockModel = null; + private int metadata; public boolean needsClientUpdate = false; @@ -68,6 +70,7 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { public TileEntity renderTile; public boolean renderTileErrored = true; + public boolean renderFullBlock = true; public ITickable renderTileUpdate = null; public TextPlane text1 = new TextPlane(); @@ -219,9 +222,14 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { EventHooks.onScriptBlockUpdate(this); ticksExisted = 0; if(needsClientUpdate){ - markDirty(); + worldObj.func_147451_t(xCoord, yCoord, zCoord); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - worldObj.notifyBlocksOfNeighborChange(xCoord,yCoord,zCoord,getBlockType(),3); + worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, CustomItems.scripted); + + Chunk chunk = worldObj.getChunkFromChunkCoords(xCoord >> 4, zCoord >> 4); + chunk.setBlockMetadata(xCoord & 15, yCoord, zCoord & 15, metadata); + blockMetadata = metadata; + needsClientUpdate = false; } } @@ -273,6 +281,11 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { if(NoppesUtilPlayer.compareItems(item, itemModel, false, false) && b != blockModel) return; + boolean blockChanged = b != blockModel; + int meta = item.getItemDamage(); + metadata = (meta == 0 || meta == metadata) && blockChanged ? metadata + 1 : meta; + this.blockMetadata = metadata; + itemModel = item; blockModel = b; needsClientUpdate = true; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java index 96aa40e7e..12e3a69fb 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java @@ -1,18 +1,18 @@ package noppes.npcs.client.renderer.blocks; +import cpw.mods.fml.client.registry.RenderingRegistry; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.RenderBlocks; -import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.entity.item.EntityItem; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.src.FMLRenderAccessLibrary; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; import net.minecraftforge.client.ForgeHooksClient; import noppes.npcs.CustomItems; import noppes.npcs.blocks.BlockScripted; @@ -28,6 +28,38 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ private static final RenderBlocks renderBlocks = new RenderBlocks(); private static final Random random = new Random(); + public BlockScriptedRenderer() { + ((BlockScripted) CustomItems.scripted).renderId = RenderingRegistry.getNextAvailableRenderId(); + RenderingRegistry.registerBlockHandler(this); + } + + @Override + public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { + TileScripted tile = (TileScripted) world.getTileEntity(x, y, z); + Block blockModel = tile.blockModel; + + if (!overrideModel() && blockModel != null) { + GL11.glPushMatrix(); + GL11.glRotatef(tile.rotationY, 0, 1, 0); + GL11.glRotatef(tile.rotationX, 1, 0, 0); + GL11.glRotatef(tile.rotationZ, 0, 0, 1); + GL11.glScalef(tile.scaleX, tile.scaleY, tile.scaleZ); + if (blockModel != CustomItems.scripted) { + tile.renderFullBlock = renderer.renderBlockByRenderType(blockModel, x, y, z); + } else { + renderer.renderStandardBlock(blockModel, x, y, z); + tile.renderFullBlock = true; + } + GL11.glPopMatrix(); + } + + return true; + } + + public int getRenderId() { + return CustomItems.scripted.getRenderType(); + } + @Override public void renderTileEntityAt(TileEntity te, double x, double y, double z, float partialTicks) { TileScripted tile = (TileScripted) te; @@ -38,8 +70,7 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ GL11.glTranslatef((float) (x + 0.5), (float) y, (float) (z + 0.5)); if (overrideModel()) { GL11.glTranslatef(0, 0.5F, 0); - renderItem(te, new ItemStack(CustomItems.scripted)); - } else { + } else if (!tile.renderFullBlock) { GL11.glRotatef(tile.rotationY, 0, 1, 0); GL11.glRotatef(tile.rotationX, 1, 0, 0); GL11.glRotatef(tile.rotationZ, 0, 0, 1); @@ -166,7 +197,7 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ } @Override - public int getRenderId() { - return 0; + public boolean shouldRender3DInInventory(int modelId) { + return false; } } From 963393b7fe71b3dfff1057ac7aac3beb1e03d0e0 Mon Sep 17 00:00:00 2001 From: "Luis C.M." <42545778+c0508383@users.noreply.github.com> Date: Wed, 3 Apr 2024 21:33:08 -0500 Subject: [PATCH 25/32] Revert "==STILL SLIGHTLY BUGGED==" This reverts commit 0d9a26c58c1decb3065c27efa76ecb01b1368580. --- .../noppes/npcs/blocks/BlockScripted.java | 6 +-- .../npcs/blocks/tiles/TileScripted.java | 17 +------ .../blocks/BlockScriptedRenderer.java | 47 ++++--------------- 3 files changed, 12 insertions(+), 58 deletions(-) diff --git a/src/main/java/noppes/npcs/blocks/BlockScripted.java b/src/main/java/noppes/npcs/blocks/BlockScripted.java index c34283704..f1b4b9266 100644 --- a/src/main/java/noppes/npcs/blocks/BlockScripted.java +++ b/src/main/java/noppes/npcs/blocks/BlockScripted.java @@ -25,8 +25,6 @@ import noppes.npcs.constants.EnumGuiType; import java.util.Random; public class BlockScripted extends BlockContainer { - - public int renderId = -1; public static final AxisAlignedBB AABB = AxisAlignedBB.getBoundingBox(0.001f, 0.001f, 0.001f, 0.998f, 0.998f, 0.998f); public static final AxisAlignedBB AABB_EMPTY = AxisAlignedBB.getBoundingBox(0, 0, 0, 0, 0, 0); @@ -111,12 +109,12 @@ public class BlockScripted extends BlockContainer { @Override public boolean canRenderInPass(int pass) { - return super.canRenderInPass(pass); + return false; } @Override public int getRenderType() { - return renderId; + return 0; } @Override public boolean isOpaqueCube() { diff --git a/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java b/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java index 2628c494a..b2d3bf8b4 100644 --- a/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java +++ b/src/main/java/noppes/npcs/blocks/tiles/TileScripted.java @@ -15,7 +15,6 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; -import net.minecraft.world.chunk.Chunk; import noppes.npcs.*; import noppes.npcs.api.IBlock; import noppes.npcs.api.block.ITextPlane; @@ -49,7 +48,6 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { public ItemStack itemModel = new ItemStack(CustomItems.scripted); public Block blockModel = null; - private int metadata; public boolean needsClientUpdate = false; @@ -70,7 +68,6 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { public TileEntity renderTile; public boolean renderTileErrored = true; - public boolean renderFullBlock = true; public ITickable renderTileUpdate = null; public TextPlane text1 = new TextPlane(); @@ -222,14 +219,9 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { EventHooks.onScriptBlockUpdate(this); ticksExisted = 0; if(needsClientUpdate){ - worldObj.func_147451_t(xCoord, yCoord, zCoord); + markDirty(); worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); - worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, CustomItems.scripted); - - Chunk chunk = worldObj.getChunkFromChunkCoords(xCoord >> 4, zCoord >> 4); - chunk.setBlockMetadata(xCoord & 15, yCoord, zCoord & 15, metadata); - blockMetadata = metadata; - + worldObj.notifyBlocksOfNeighborChange(xCoord,yCoord,zCoord,getBlockType(),3); needsClientUpdate = false; } } @@ -281,11 +273,6 @@ public class TileScripted extends TileEntity implements IScriptBlockHandler { if(NoppesUtilPlayer.compareItems(item, itemModel, false, false) && b != blockModel) return; - boolean blockChanged = b != blockModel; - int meta = item.getItemDamage(); - metadata = (meta == 0 || meta == metadata) && blockChanged ? metadata + 1 : meta; - this.blockMetadata = metadata; - itemModel = item; blockModel = b; needsClientUpdate = true; diff --git a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java index 12e3a69fb..96aa40e7e 100644 --- a/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java +++ b/src/main/java/noppes/npcs/client/renderer/blocks/BlockScriptedRenderer.java @@ -1,18 +1,18 @@ package noppes.npcs.client.renderer.blocks; -import cpw.mods.fml.client.registry.RenderingRegistry; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.entity.item.EntityItem; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; -import net.minecraft.src.FMLRenderAccessLibrary; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; -import net.minecraft.world.IBlockAccess; import net.minecraftforge.client.ForgeHooksClient; import noppes.npcs.CustomItems; import noppes.npcs.blocks.BlockScripted; @@ -28,38 +28,6 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ private static final RenderBlocks renderBlocks = new RenderBlocks(); private static final Random random = new Random(); - public BlockScriptedRenderer() { - ((BlockScripted) CustomItems.scripted).renderId = RenderingRegistry.getNextAvailableRenderId(); - RenderingRegistry.registerBlockHandler(this); - } - - @Override - public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { - TileScripted tile = (TileScripted) world.getTileEntity(x, y, z); - Block blockModel = tile.blockModel; - - if (!overrideModel() && blockModel != null) { - GL11.glPushMatrix(); - GL11.glRotatef(tile.rotationY, 0, 1, 0); - GL11.glRotatef(tile.rotationX, 1, 0, 0); - GL11.glRotatef(tile.rotationZ, 0, 0, 1); - GL11.glScalef(tile.scaleX, tile.scaleY, tile.scaleZ); - if (blockModel != CustomItems.scripted) { - tile.renderFullBlock = renderer.renderBlockByRenderType(blockModel, x, y, z); - } else { - renderer.renderStandardBlock(blockModel, x, y, z); - tile.renderFullBlock = true; - } - GL11.glPopMatrix(); - } - - return true; - } - - public int getRenderId() { - return CustomItems.scripted.getRenderType(); - } - @Override public void renderTileEntityAt(TileEntity te, double x, double y, double z, float partialTicks) { TileScripted tile = (TileScripted) te; @@ -70,7 +38,8 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ GL11.glTranslatef((float) (x + 0.5), (float) y, (float) (z + 0.5)); if (overrideModel()) { GL11.glTranslatef(0, 0.5F, 0); - } else if (!tile.renderFullBlock) { + renderItem(te, new ItemStack(CustomItems.scripted)); + } else { GL11.glRotatef(tile.rotationY, 0, 1, 0); GL11.glRotatef(tile.rotationX, 1, 0, 0); GL11.glRotatef(tile.rotationZ, 0, 0, 1); @@ -197,7 +166,7 @@ public class BlockScriptedRenderer extends BlockRendererInterface{ } @Override - public boolean shouldRender3DInInventory(int modelId) { - return false; + public int getRenderId() { + return 0; } } From a07a33c06878b55d60318b45e1b08097ce334148 Mon Sep 17 00:00:00 2001 From: "Luis C.M." <42545778+c0508383@users.noreply.github.com> Date: Thu, 4 Apr 2024 22:36:11 -0500 Subject: [PATCH 26/32] Fixed animations not transitioning correctly when updating from a looping animation. --- src/main/java/noppes/npcs/controllers/data/Animation.java | 2 +- .../java/noppes/npcs/controllers/data/AnimationData.java | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 29dd816e7..5de123d88 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -251,7 +251,7 @@ public class Animation implements IAnimation { } this.currentFrameTime++; - if (this.currentFrameTime == this.currentFrame().getDuration()) { + if (this.currentFrame() != null && this.currentFrameTime == this.currentFrame().getDuration()) { EventHooks.onAnimationFrameExited(this, this.currentFrame()); Frame prevFrame = (Frame) this.currentFrame(); diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 112a461cf..ba7fde579 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -264,10 +264,13 @@ public class AnimationData implements IAnimationData { CommonProxy.clientPlayingAnimations.add(newAnim); } } + + Animation prevAnim = this.animation; this.animation = newAnim; - if (this.isActive() && newAnim != null && !newAnim.frames.isEmpty()) { - Frame frame = (Frame) this.animation.currentFrame(); + if (this.getMCEntity() != null && this.getMCEntity().worldObj.isRemote && + this.isActive() && prevAnim != null && newAnim != null && !newAnim.frames.isEmpty()) { + Frame frame = (Frame) prevAnim.currentFrame(); if (frame != null) { Frame firstFrame = newAnim.frames.get(0); for (Map.Entry entry : frame.frameParts.entrySet()) { From ae2edfd79f893e9f6b937796e4fcf0c62990015c Mon Sep 17 00:00:00 2001 From: luisc Date: Fri, 5 Apr 2024 13:14:37 -0500 Subject: [PATCH 27/32] Fixed animations not ticking correctly sometimes. --- src/main/java/noppes/npcs/CommonProxy.java | 60 +++++++++---------- .../npcs/controllers/data/Animation.java | 8 +++ .../npcs/controllers/data/AnimationData.java | 24 ++++++-- 3 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 5bfd6b54f..80bf89d78 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -19,6 +19,7 @@ import noppes.npcs.blocks.tiles.TileNpcContainer; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.containers.*; import noppes.npcs.controllers.data.Animation; +import noppes.npcs.controllers.data.AnimationData; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.util.MillisTimer; @@ -26,8 +27,8 @@ import noppes.npcs.util.MillisTimer; import java.util.HashSet; public class CommonProxy implements IGuiHandler { - public final static HashSet clientPlayingAnimations = new HashSet<>(); - public final static HashSet serverPlayingAnimations = new HashSet<>(); + public final static HashSet clientPlayingAnimations = new HashSet<>(); + public final static HashSet serverPlayingAnimations = new HashSet<>(); protected MillisTimer animationTimer = new MillisTimer(1000); protected static long totalServerTicks; protected static long totalClientTicks; @@ -48,18 +49,22 @@ public class CommonProxy implements IGuiHandler { } for (int i = 0; i < animationTimer.elapsedTicks; ++i) { - for (Animation animation : clientPlayingAnimations) { - int tickDuration = animation.currentFrame().tickDuration(); - if (updateAnimation(animation) && totalClientTicks % tickDuration == 0) { - animation.increaseTime(); + for (AnimationData data : clientPlayingAnimations) { + if (data.animation != null) { + int tickDuration = data.animation.currentFrame().tickDuration(); + if (totalClientTicks % tickDuration == 0) { + data.increaseTime(); + } } } totalClientTicks++; - for (Animation animation : serverPlayingAnimations) { - int tickDuration = animation.currentFrame().tickDuration(); - if (updateAnimation(animation) && totalServerTicks % tickDuration == 0) { - animation.increaseTime(); + for (AnimationData data : serverPlayingAnimations) { + if (data.animation != null) { + int tickDuration = data.animation.currentFrame().tickDuration(); + if (totalServerTicks % tickDuration == 0) { + data.increaseTime(); + } } } totalServerTicks++; @@ -83,44 +88,33 @@ public class CommonProxy implements IGuiHandler { thread.start(); } - private boolean updateAnimation(Animation animation) { - return animation.parent.isActive() - || animation.parent.animation == null - && animation.parent.isActive(animation.parent.currentClientAnimation); - } - - private boolean removeAnimation(Animation animation) { - if (animation.currentFrame() == null || animation.parent == null) { - return true; - } - + private boolean removeAnimation(AnimationData data) { Entity entity = null; - if (animation.parent.parent instanceof DataDisplay) { - entity = ((DataDisplay)animation.parent.parent).npc; + if (data.parent instanceof DataDisplay) { + entity = ((DataDisplay)data.parent).npc; } else { - if (animation.parent.parent instanceof PlayerData) { - entity = ((PlayerData) animation.parent.parent).player; - } else if (animation.parent.parent instanceof EntityPlayer) { - entity = (EntityPlayer) animation.parent.parent; + if (data.parent instanceof PlayerData) { + entity = ((PlayerData) data.parent).player; + } else if (data.parent instanceof EntityPlayer) { + entity = (EntityPlayer) data.parent; } } if (entity == null) return true; if (entity.worldObj != null && entity.worldObj.isRemote) { - return animation.parent.animation != animation || clientRemoveAnimation(entity); + return clientRemoveAnimation(entity); } else { - return !animation.parent.isClientAnimating() - || animation.parent.animation != animation && animation.parent.currentClientAnimation != animation - || entity.worldObj == null || !entity.worldObj.loadedEntityList.contains(entity) + return entity.worldObj == null || !entity.worldObj.loadedEntityList.contains(entity) || CustomNpcs.getServer().isServerStopped(); } } @SideOnly(Side.CLIENT) private boolean clientRemoveAnimation(Entity entity) { - return Minecraft.getMinecraft().theWorld == null - || Minecraft.getMinecraft().currentScreen == null && !Minecraft.getMinecraft().theWorld.loadedEntityList.contains(entity); + Minecraft mc = Minecraft.getMinecraft(); + return mc.theWorld == null + || mc.currentScreen == null && entity != mc.thePlayer && !mc.theWorld.loadedEntityList.contains(entity); } public PlayerData getPlayerData(EntityPlayer player) { diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 5de123d88..41f05c971 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -179,6 +179,14 @@ public class Animation implements IAnimation { id = newID; } + public long getTotalTime() { + long time = 0; + for (Frame frame : this.frames) { + time += (long) frame.duration * (frame.customized ? frame.tickDuration : this.tickDuration); + } + return time; + } + public void readFromNBT(NBTTagCompound compound){ if(compound.hasKey("ID")){ id = compound.getInteger("ID"); diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index ba7fde579..966789d9a 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -32,6 +32,7 @@ public class AnimationData implements IAnimationData { public Animation animation; public boolean allowAnimation = false; + public long animatingTime = 0; public Animation currentClientAnimation; private boolean isClientAnimating; @@ -93,6 +94,7 @@ public class AnimationData implements IAnimationData { EventHooks.onAnimationEnded(this.currentClientAnimation); } if (this.isClientAnimating) { + this.animatingTime = 0; this.currentClientAnimation = this.animation; } @@ -105,7 +107,7 @@ public class AnimationData implements IAnimationData { synchronized (CommonProxy.serverPlayingAnimations) { if (this.isClientAnimating && this.getMCEntity() != null && !this.getMCEntity().worldObj.isRemote && this.animation != null) { - CommonProxy.serverPlayingAnimations.add(this.animation); + CommonProxy.serverPlayingAnimations.add(this); } } @@ -160,6 +162,14 @@ public class AnimationData implements IAnimationData { } } + public void increaseTime() { + if (this.isActive()) { + this.animation.increaseTime(); + } else if (this.isActive(animation.parent.currentClientAnimation)) { + this.currentClientAnimation.increaseTime(); + } + } + public boolean isCached(int id) { return this.cachedAnimationIDs.contains(id); } @@ -259,9 +269,11 @@ public class AnimationData implements IAnimationData { newAnim.parent = this; } - synchronized (CommonProxy.clientPlayingAnimations) { - if (this.getMCEntity() != null && this.getMCEntity().worldObj.isRemote && newAnim != null) { - CommonProxy.clientPlayingAnimations.add(newAnim); + + if (this.getMCEntity() != null && this.getMCEntity().worldObj.isRemote && newAnim != null) { + this.animatingTime = 0; + synchronized (CommonProxy.clientPlayingAnimations) { + CommonProxy.clientPlayingAnimations.add(this); } } @@ -290,4 +302,8 @@ public class AnimationData implements IAnimationData { public IAnimation getAnimation() { return animation; } + + public long getAnimatingTime() { + return this.animatingTime; + } } From 8b3571339b3212445240f39556cb6e44e32c6ec9 Mon Sep 17 00:00:00 2001 From: luisc Date: Fri, 5 Apr 2024 13:14:57 -0500 Subject: [PATCH 28/32] Added animation functions --- src/api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api b/src/api index 0fe49c8b9..7f2167d3d 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 0fe49c8b924b359c92b1d41590b4f0de16f4d9ac +Subproject commit 7f2167d3d63ce907fe5f7cf71f209ae65253989a From 17c81c512f7807a60fbb022eb8987a78a5a74cd9 Mon Sep 17 00:00:00 2001 From: luisc Date: Fri, 5 Apr 2024 13:20:44 -0500 Subject: [PATCH 29/32] Added getAnimatingTime() function to AnimationData. --- .../noppes/npcs/controllers/data/Animation.java | 6 ++++-- .../npcs/controllers/data/AnimationData.java | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index 41f05c971..be05ef4e1 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -250,9 +250,9 @@ public class Animation implements IAnimation { return compound; } - public void increaseTime() { + public boolean increaseTime() { if (paused) - return; + return false; if (this.parent != null && this.currentFrame < this.frames.size()) { this.parent.finishedFrame = this.currentFrame; @@ -289,6 +289,8 @@ public class Animation implements IAnimation { this.parent.finishedTime = this.parent.getMCEntity().getAge(); } } + + return true; } @SideOnly(Side.CLIENT) diff --git a/src/main/java/noppes/npcs/controllers/data/AnimationData.java b/src/main/java/noppes/npcs/controllers/data/AnimationData.java index 966789d9a..a7d120672 100644 --- a/src/main/java/noppes/npcs/controllers/data/AnimationData.java +++ b/src/main/java/noppes/npcs/controllers/data/AnimationData.java @@ -88,13 +88,14 @@ public class AnimationData implements IAnimationData { if(sendingEntity.dimension != sendingEntity.worldObj.provider.dimensionId) sendingEntity.dimension = sendingEntity.worldObj.provider.dimensionId; + this.animatingTime = 0; + boolean prevIsClientAnimating = this.isClientAnimating && this.currentClientAnimation.currentFrame() != null; this.isClientAnimating = this.allowAnimation && this.animation != null; if (prevIsClientAnimating && (!this.isClientAnimating || this.animation != this.currentClientAnimation)) { EventHooks.onAnimationEnded(this.currentClientAnimation); } if (this.isClientAnimating) { - this.animatingTime = 0; this.currentClientAnimation = this.animation; } @@ -163,10 +164,18 @@ public class AnimationData implements IAnimationData { } public void increaseTime() { + Animation updateAnimation = null; if (this.isActive()) { - this.animation.increaseTime(); + updateAnimation = this.animation; } else if (this.isActive(animation.parent.currentClientAnimation)) { - this.currentClientAnimation.increaseTime(); + updateAnimation = this.currentClientAnimation; + } + + if (updateAnimation != null && updateAnimation.increaseTime()) { + Frame frame = (Frame) updateAnimation.currentFrame(); + if (frame != null) { + this.animatingTime += frame.customized ? frame.tickDuration : updateAnimation.tickDuration; + } } } From 3486686abe71658c5edc11162eb239d2e15be2d9 Mon Sep 17 00:00:00 2001 From: luisc Date: Fri, 5 Apr 2024 13:20:55 -0500 Subject: [PATCH 30/32] Added getAnimatingTime() function to AnimationData. --- src/api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api b/src/api index 7f2167d3d..34b708610 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 7f2167d3d63ce907fe5f7cf71f209ae65253989a +Subproject commit 34b7086104115b2ef5b42f7fab7922751cc74376 From 947c908667a35091e4fe8b1a0b13b7b5096cf3c7 Mon Sep 17 00:00:00 2001 From: luisc Date: Fri, 5 Apr 2024 13:28:41 -0500 Subject: [PATCH 31/32] Fixed null pointer exception when updating animation data. --- src/main/java/noppes/npcs/CommonProxy.java | 33 +++++++++++----------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index 80bf89d78..ca64ae444 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -20,10 +20,12 @@ import noppes.npcs.constants.EnumGuiType; import noppes.npcs.containers.*; import noppes.npcs.controllers.data.Animation; import noppes.npcs.controllers.data.AnimationData; +import noppes.npcs.controllers.data.Frame; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.util.MillisTimer; +import java.util.Collection; import java.util.HashSet; public class CommonProxy implements IGuiHandler { @@ -49,24 +51,10 @@ public class CommonProxy implements IGuiHandler { } for (int i = 0; i < animationTimer.elapsedTicks; ++i) { - for (AnimationData data : clientPlayingAnimations) { - if (data.animation != null) { - int tickDuration = data.animation.currentFrame().tickDuration(); - if (totalClientTicks % tickDuration == 0) { - data.increaseTime(); - } - } - } + updateData(totalClientTicks, clientPlayingAnimations); totalClientTicks++; - for (AnimationData data : serverPlayingAnimations) { - if (data.animation != null) { - int tickDuration = data.animation.currentFrame().tickDuration(); - if (totalServerTicks % tickDuration == 0) { - data.increaseTime(); - } - } - } + updateData(totalServerTicks, serverPlayingAnimations); totalServerTicks++; } @@ -88,6 +76,19 @@ public class CommonProxy implements IGuiHandler { thread.start(); } + private void updateData(long ticks, Collection animationData) { + for (AnimationData data : animationData) { + Frame frame = data.animation != null && data.animation.currentFrame() != null + ? (Frame) data.animation.currentFrame() : null; + if (frame != null) { + int tickDuration = frame.tickDuration(); + if (ticks % tickDuration == 0) { + data.increaseTime(); + } + } + } + } + private boolean removeAnimation(AnimationData data) { Entity entity = null; if (data.parent instanceof DataDisplay) { From 206755a343b0cf15cac5647e2b6edffb3b1e7476 Mon Sep 17 00:00:00 2001 From: "Luis C.M." <42545778+c0508383@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:10:50 -0500 Subject: [PATCH 32/32] Frames can now be copy/pasted in the animation editor, even working across animations. Copy with CTRL + C and paste with CTRL + V. --- src/main/java/noppes/npcs/CommonProxy.java | 6 ++- .../gui/global/GuiNPCEditAnimation.java | 53 +++++++++++++++---- .../noppes/npcs/controllers/data/Frame.java | 2 +- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/main/java/noppes/npcs/CommonProxy.java b/src/main/java/noppes/npcs/CommonProxy.java index ca64ae444..d814ccf86 100644 --- a/src/main/java/noppes/npcs/CommonProxy.java +++ b/src/main/java/noppes/npcs/CommonProxy.java @@ -18,7 +18,6 @@ import noppes.npcs.api.IWorld; import noppes.npcs.blocks.tiles.TileNpcContainer; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.containers.*; -import noppes.npcs.controllers.data.Animation; import noppes.npcs.controllers.data.AnimationData; import noppes.npcs.controllers.data.Frame; import noppes.npcs.controllers.data.PlayerData; @@ -26,6 +25,7 @@ import noppes.npcs.entity.EntityNPCInterface; import noppes.npcs.util.MillisTimer; import java.util.Collection; +import java.util.ConcurrentModificationException; import java.util.HashSet; public class CommonProxy implements IGuiHandler { @@ -68,7 +68,9 @@ public class CommonProxy implements IGuiHandler { serverPlayingAnimations.removeIf(CommonProxy.this::removeAnimation); } } catch (Exception e) { - e.printStackTrace(); + if (!(e instanceof ConcurrentModificationException)) { + e.printStackTrace(); + } } } }}); 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 9ad7e3157..6991e54be 100644 --- a/src/main/java/noppes/npcs/client/gui/global/GuiNPCEditAnimation.java +++ b/src/main/java/noppes/npcs/client/gui/global/GuiNPCEditAnimation.java @@ -3,7 +3,6 @@ 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; @@ -24,14 +23,16 @@ import java.util.Map; public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfieldListener, ISliderListener, ISubGuiListener { private final Animation animation; + private static int partEditMode; + private static int sliderSelection = 0; + private static Frame copiedFrame; + private EnumAnimationPart editingPart = EnumAnimationPart.HEAD; private int frameIndex = 0; public boolean playingAnimation = false; private Frame prevFrame; private final GuiScreen parent; private long prevTick; - private static int partEditMode; - private static int sliderSelection = 0; private final GuiNpcSlider[] rotationSliders = new GuiNpcSlider[3]; private final GuiNpcSlider[] pivotSliders = new GuiNpcSlider[3]; @@ -402,13 +403,7 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield AnimationData data = npc.display.animationData; if (guibutton.id == 11) { - if (frameIndex < animation.frames.size() - 1) { - animation.frames.add(frameIndex + 1, new Frame(10)); - } else { - animation.frames.add(new Frame(10)); - } - this.frameIndex = frameIndex + 1; - updateFrameSlider(); + this.addFrame(); } else if (guibutton.id == 12) { animation.frames.remove(frameIndex); updateFrameSlider(); @@ -502,6 +497,20 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield initGui(); } + private void addFrame() { + this.addFrame(new Frame(10)); + } + + private void addFrame(Frame frame) { + if (frameIndex < animation.frames.size() - 1) { + animation.frames.add(frameIndex + 1, frame); + } else { + animation.frames.add(frame); + } + this.frameIndex = frameIndex + 1; + updateFrameSlider(); + } + @Override public void drawScreen(int par1, int par2, float par3) { @@ -640,4 +649,28 @@ public class GuiNPCEditAnimation extends GuiModelInterface implements ITextfield editingFrame.setColorMarker(((SubGuiColorSelector) subgui).color); } } + + @Override + public void keyTyped(char par1, int par2) { + super.keyTyped(par1, par2); + + if (GuiScreen.isCtrlKeyDown() && par2 != 29 && !GuiNpcTextField.isFieldActive()) { + switch (par2) { + case 46: + if (this.editingFrame() != null) { + copiedFrame = this.editingFrame(); + } + break; + case 47: + if (copiedFrame != null) { + Frame frame = new Frame(10); + frame.parent = this.animation; + frame.readFromNBT(copiedFrame.writeToNBT()); + this.addFrame(frame); + this.initGui(); + } + break; + } + } + } } diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index 461d41d23..004d80c28 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -156,7 +156,7 @@ public class Frame implements IFrame { this.tickDuration = compound.getBoolean("RenderTicks") ? 20 : 50; } - if (!customized) { + if (!customized && parent != null) { this.speed = parent.speed; this.smooth = parent.smooth; this.tickDuration = parent.tickDuration;