diff --git a/src/api b/src/api index 1bff2eddf..33e471871 160000 --- a/src/api +++ b/src/api @@ -1 +1 @@ -Subproject commit 1bff2eddfe7bf44d91d8f2dfdc775db78e893fd7 +Subproject commit 33e471871aa20949718d515977c10983c827b014 diff --git a/src/main/java/noppes/npcs/AnimationData.java b/src/main/java/noppes/npcs/AnimationData.java index 4c4f88967..828e1a873 100644 --- a/src/main/java/noppes/npcs/AnimationData.java +++ b/src/main/java/noppes/npcs/AnimationData.java @@ -1,39 +1,90 @@ package noppes.npcs; + +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.api.handler.data.IAnimationData; +import noppes.npcs.api.handler.data.IAnimation; import noppes.npcs.constants.EnumPacketClient; +import noppes.npcs.controllers.data.Animation; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.EntityNPCInterface; -public class AnimationData extends AnimationDataShared { - public EntityNPCInterface npc; +public class AnimationData implements IAnimationData { + //Server-side: DataDisplay, PlayerData + //Client-side: DataDisplay, EntityPlayer + public Object parent; - public boolean whileStanding = true; - public boolean whileAttacking = false; - public boolean whileMoving = false; + public Animation animation; + public boolean allowAnimation = false; - public AnimationData(EntityNPCInterface npc, Object parent){ - super(parent); - this.npc = npc; + public AnimationData(Object parent){ + this.parent = parent; } - // CHANGE to CHECK IF PARENT IS NPC LOUIS - @Override public void updateClient() { - Server.sendToAll(EnumPacketClient.PLAYER_UPDATE_MODEL_DATA, ((PlayerData) parent).player.getCommandSenderName(), this.writeToNBT(new NBTTagCompound())); + if (parent instanceof PlayerData) { + NBTTagCompound compound = new NBTTagCompound(); + this.writeToNBT(compound); + compound.setTag("Animation",this.animation.writeToNBT()); + Server.sendToAll(EnumPacketClient.UPDATE_ANIMATIONS, compound, ((PlayerData) parent).player.getCommandSenderName()); + } else if (parent instanceof DataDisplay) { + NBTTagCompound compound = new NBTTagCompound(); + this.writeToNBT(compound); + compound.setTag("Animation",this.animation.writeToNBT()); + compound.setInteger("EntityId",((DataDisplay) parent).npc.getEntityId()); + Server.sendAssociatedData(((DataDisplay) parent).npc, EnumPacketClient.UPDATE_ANIMATIONS, compound); + } } public boolean isActive() { - if (!this.allowAnimation) + if (!this.allowAnimation || this.animation == null || this.animation.currentFrame == this.animation.frames.size()) return false; - if(!npc.isEntityAlive()) - return false; + if (this.parent instanceof DataDisplay) { + EntityNPCInterface npc = ((DataDisplay)this.parent).npc; + if (!npc.isEntityAlive()) + return false; - if(whileAttacking && npc.isAttacking() || whileMoving && npc.isWalking() || whileStanding && !npc.isWalking()) - return true; + return animation.whileAttacking && npc.isAttacking() || animation.whileMoving && npc.isWalking() || animation.whileStanding && !npc.isWalking(); + } else { + EntityPlayer player; + if (this.parent instanceof PlayerData) { + player = ((PlayerData) this.parent).player; + } else { + player = (EntityPlayer) this.parent; + } + if (!player.isEntityAlive()) + return false; - return false; + boolean moving = Math.sqrt(player.motionX*player.motionX + player.motionY*player.motionY + player.motionZ*player.motionZ) != 0.0D; + + return animation.whileAttacking && player.getLastAttackerTime() - player.ticksExisted < 20 || animation.whileMoving && moving || animation.whileStanding && !moving; + } } + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + compound.setBoolean("PuppetEnabled", allowAnimation); + return compound; + } + + public void readFromNBT(NBTTagCompound compound) { + this.allowAnimation = compound.getBoolean("PuppetEnabled"); + } + + public void setEnabled(boolean enabled) { + this.allowAnimation = enabled; + } + + public boolean enabled() { + return this.allowAnimation; + } + + public void setAnimation(IAnimation animation) { + this.animation = (Animation) animation; + } + + public IAnimation getAnimation() { + return animation; + } } diff --git a/src/main/java/noppes/npcs/AnimationDataShared.java b/src/main/java/noppes/npcs/AnimationDataShared.java deleted file mode 100644 index 3ac098a90..000000000 --- a/src/main/java/noppes/npcs/AnimationDataShared.java +++ /dev/null @@ -1,265 +0,0 @@ -package noppes.npcs; - - -import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.api.handler.IPlayerModelData; -import noppes.npcs.constants.EnumPacketClient; -import noppes.npcs.controllers.data.PlayerData; - -public class AnimationDataShared implements IPlayerModelData { - public Object parent; - - public AnimationPartConfig head = new AnimationPartConfig(); - public AnimationPartConfig larm = new AnimationPartConfig(); - public AnimationPartConfig rarm = new AnimationPartConfig(); - public AnimationPartConfig body = new AnimationPartConfig(); - public AnimationPartConfig lleg = new AnimationPartConfig(); - public AnimationPartConfig rleg = new AnimationPartConfig(); - - public boolean allowAnimation = false; - - // Full Model Animation - public boolean enableFullModel = true; - - public float rotationX, rotationY, rotationZ; - public boolean rotationEnabledX, rotationEnabledY, rotationEnabledZ; - public boolean fullAnimate = false; - public float animRate = 1.0F; - public boolean fullAngles; - public boolean interpolate; - - //Client-sided use - public float modelRotPartialTicks; - public float[] modelRotations = {0,0,0}; - - public AnimationDataShared(Object parent){ - this.parent = parent; - } - - public void updateClient() { - Server.sendToAll(EnumPacketClient.PLAYER_UPDATE_MODEL_DATA, ((PlayerData) parent).player.getCommandSenderName(), this.writeToNBT(new NBTTagCompound())); - } - - // SWITCH TO IAnimatePart - public AnimationPartConfig getPart(int part) { - switch (part) { - case 0: - return this.head; - case 1: - return this.body; - case 2: - return this.larm; - case 3: - return this.rarm; - case 4: - return this.lleg; - case 5: - return this.rleg; - } - return null; - } - - public NBTTagCompound writeToNBT(NBTTagCompound compound) { - - compound.setBoolean("PuppetEnabled", allowAnimation); - - // ALWAYS SAVE allowAnimation - if(allowAnimation){ - // GROUP INTO ANIMATION TAG - - compound.setTag("PuppetHead", head.writeNBT()); - compound.setTag("PuppetLArm", larm.writeNBT()); - compound.setTag("PuppetRArm", rarm.writeNBT()); - compound.setTag("PuppetBody", body.writeNBT()); - compound.setTag("PuppetLLeg", lleg.writeNBT()); - compound.setTag("PuppetRLeg", rleg.writeNBT()); - - // GROUP THIS INTO "PuppetFullModel" - compound.setBoolean("PuppetFullModelEnabled", enableFullModel); - if(enableFullModel){ - compound.setFloat("PuppetRotationX",rotationX); - compound.setFloat("PuppetRotationY",rotationY); - compound.setFloat("PuppetRotationZ",rotationZ); - compound.setBoolean("PuppetRotationEnabledX",rotationEnabledX); - compound.setBoolean("PuppetRotationEnabledY",rotationEnabledY); - compound.setBoolean("PuppetRotationEnabledZ",rotationEnabledZ); - - compound.setBoolean("PuppetFullAngles", fullAngles); - compound.setBoolean("PuppetInterpolate", interpolate); - compound.setBoolean("PuppetAnimate", fullAnimate); - compound.setFloat("PuppetAnimSpeed", animRate); - } - } - - return compound; - } - - public void readFromNBT(NBTTagCompound compound) { - allowAnimation = compound.getBoolean("PuppetEnabled"); - if(allowAnimation) { - head.readNBT(compound.getCompoundTag("PuppetHead")); - larm.readNBT(compound.getCompoundTag("PuppetLArm")); - rarm.readNBT(compound.getCompoundTag("PuppetRArm")); - body.readNBT(compound.getCompoundTag("PuppetBody")); - lleg.readNBT(compound.getCompoundTag("PuppetLLeg")); - rleg.readNBT(compound.getCompoundTag("PuppetRLeg")); - - enableFullModel = compound.getBoolean("PuppetFullModelEnabled"); - if (enableFullModel) { - rotationX = compound.getFloat("PuppetRotationX"); - rotationY = compound.getFloat("PuppetRotationY"); - rotationZ = compound.getFloat("PuppetRotationZ"); - rotationEnabledX = compound.getBoolean("PuppetRotationEnabledX"); - rotationEnabledY = compound.getBoolean("PuppetRotationEnabledY"); - rotationEnabledZ = compound.getBoolean("PuppetRotationEnabledZ"); - - fullAngles = compound.getBoolean("PuppetFullAngles"); - if (!compound.hasKey("PuppetInterpolate")) { - interpolate = true; - } else { - interpolate = compound.getBoolean("PuppetInterpolate"); - } - fullAnimate = compound.getBoolean("PuppetAnimate"); - animRate = compound.getFloat("PuppetAnimSpeed"); - } - } - else { - // IF HAS ANIMATION TAG - // REMOVE IT! - } - } - - public void setEnabled(boolean enabled) { - this.allowAnimation = enabled; - } - - public boolean enabled() { - return this.allowAnimation; - } - - public void setAnimated(boolean animated) { - this.fullAnimate = animated; - } - - public boolean isAnimated() { - return this.fullAnimate; - } - - public void setInterpolated(boolean interpolate) { - this.interpolate = interpolate; - } - - public boolean isInterpolated() { - return this.interpolate; - } - - public void setFullAngles(boolean limit) { - fullAngles = limit; - } - - public boolean fullAngles() { - return fullAngles; - } - - public void setAnimRate(float animRate) { - if (animRate < 0) - animRate = 0; - this.animRate = animRate; - } - - public float getAnimRate() { - return this.animRate; - } - - public void setRotation(float rotationX, float rotationY, float rotationZ) { - this.setRotationX(rotationX); - this.setRotationY(rotationY); - this.setRotationZ(rotationZ); - } - - public void setRotationX(float rotationX) { - this.rotationX = rotationX; - } - - public void setRotationY(float rotationY) { - this.rotationY = rotationY; - } - - public void setRotationZ(float rotationZ) { - this.rotationZ = rotationZ; - } - - public float getRotationX() { - return rotationX; - } - - public float getRotationY() { - return rotationY; - } - - public float getRotationZ() { - return rotationZ; - } - - public void setRotationEnabled(boolean enabledX, boolean enabledY, boolean enabledZ) { - this.setRotationEnabledX(enabledX); - this.setRotationEnabledY(enabledY); - this.setRotationEnabledZ(enabledZ); - } - - public void setRotationEnabledX(boolean enabled) { - this.rotationEnabledX = enabled; - } - - public void setRotationEnabledY(boolean enabled) { - this.rotationEnabledY = enabled; - } - - public void setRotationEnabledZ(boolean enabled) { - this.rotationEnabledZ = enabled; - } - - public boolean rotationEnabledX() { - return rotationEnabledX; - } - - public boolean rotationEnabledY() { - return rotationEnabledY; - } - - public boolean rotationEnabledZ() { - return rotationEnabledZ; - } - - public void allEnabled(boolean enabled) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setEnabled(enabled); - } - } - - public void allAnimated(boolean animated) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setAnimated(animated); - } - } - - public void allInterpolated(boolean interpolate) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setAnimated(interpolate); - } - } - - public void allFullAngles(boolean fullAngles) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setFullAngles(fullAngles); - } - } - - public void allAnimRate(float animRate) { - if (animRate < 0) - animRate = 0; - for (int i = 0; i < 6; i++) { - this.getPart(i).setAnimRate(animRate); - } - } -} diff --git a/src/main/java/noppes/npcs/AnimationPartConfig.java b/src/main/java/noppes/npcs/AnimationPartConfig.java deleted file mode 100644 index ee76ff97a..000000000 --- a/src/main/java/noppes/npcs/AnimationPartConfig.java +++ /dev/null @@ -1,168 +0,0 @@ -package noppes.npcs; - -import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.api.handler.data.IModelPart; - -public class AnimationPartConfig implements IModelPart { - public float rotationX = 0f, rotationY = 0f, rotationZ = 0f; - public float pivotX = 0f, pivotY = 0f, pivotZ = 0f; - - public boolean enablePart = false; - public boolean fullAngles = false; - public boolean animate = false; - public float animRate = 1.0F; - public boolean interpolate = true; - - // vvv Client-sided use vvv - public float[] prevRotations = new float[]{0, 0, 0}; - public float[] prevPivots = new float[]{0, 0, 0}; - public float partialRotationTick = 0f; - public float partialPivotTick = 0f; - // ^^^ Client-sided use ^^^ - - public NBTTagCompound writeNBT() { - NBTTagCompound compound = new NBTTagCompound(); - compound.setBoolean("EnablePart", enablePart); - if(enablePart){ - compound.setFloat("RotationX", rotationX); - compound.setFloat("RotationY", rotationY); - compound.setFloat("RotationZ", rotationZ); - compound.setFloat("PivotX", pivotX); - compound.setFloat("PivotY", pivotY); - compound.setFloat("PivotZ", pivotZ); - - compound.setBoolean("PuppetFullAngles", fullAngles); - - compound.setBoolean("PuppetInterpolate", interpolate); - compound.setBoolean("PuppetAnimate", animate); - compound.setFloat("PuppetAnimSpeed", animRate); - } - return compound; - } - - public void readNBT(NBTTagCompound compound) { - enablePart = compound.getBoolean("EnablePart"); - if(enablePart){ - rotationX = compound.getFloat("RotationX"); - rotationY = compound.getFloat("RotationY"); - rotationZ = compound.getFloat("RotationZ"); - pivotX = compound.getFloat("PivotX"); - pivotY = compound.getFloat("PivotY"); - pivotZ = compound.getFloat("PivotZ"); - - fullAngles = compound.getBoolean("PuppetFullAngles"); - - if (!compound.hasKey("PuppetInterpolate")) { - interpolate = true; - } else { - interpolate = compound.getBoolean("PuppetInterpolate"); - } - animate = compound.getBoolean("PuppetAnimate"); - animRate = compound.getFloat("PuppetAnimSpeed"); - } - } - - public void setEnabled(boolean enabled) { - this.enablePart = enabled; - } - - public boolean isEnabled() { - return this.enablePart; - } - - public void setAnimated(boolean animated) { - this.animate = animated; - } - - public boolean isAnimated() { - return this.animate; - } - - public void setInterpolated(boolean interpolate) { - this.interpolate = interpolate; - } - - public boolean isInterpolated() { - return this.interpolate; - } - - public void setFullAngles(boolean fullAngles) { - this.fullAngles = fullAngles; - } - - public boolean fullAngles() { - return this.fullAngles; - } - - public void setAnimRate(float animRate) { - this.animRate = animRate; - } - - public float getAnimRate() { - return this.animRate; - } - - public void setRotation(float rotationX, float rotationY, float rotationZ) { - this.setRotationX(rotationX); - this.setRotationY(rotationY); - this.setRotationZ(rotationZ); - } - - public void setRotationX(float rotation) { - float f = rotation / 360f - 0.5f; - this.rotationX = f; - } - - public void setRotationY(float rotation) { - float f = rotation / 360f - 0.5f; - this.rotationY = f; - } - - public void setRotationZ(float rotation) { - float f = rotation / 360f - 0.5f; - this.rotationZ = f; - } - - public float getRotationX() { - return this.rotationX; - } - - public float getRotationY() { - return this.rotationY; - } - - public float getRotationZ() { - return this.rotationZ; - } - - public void setOffset(float offsetX, float offsetY, float offsetZ) { - this.setOffsetX(offsetX); - this.setOffsetY(offsetY); - this.setOffsetZ(offsetZ); - } - - public void setOffsetX(float offset) { - this.pivotX = offset; - } - - public void setOffsetY(float offset) { - this.pivotY = offset; - } - - public void setOffsetZ(float offset) { - this.pivotZ = offset; - } - - public float getOffsetX() { - return this.pivotX; - } - - public float getOffsetY() { - return this.pivotY; - } - - public float getOffsetZ() { - return this.pivotZ; - } - -} diff --git a/src/main/java/noppes/npcs/DataDisplay.java b/src/main/java/noppes/npcs/DataDisplay.java index 9e982c8f3..62e157b23 100644 --- a/src/main/java/noppes/npcs/DataDisplay.java +++ b/src/main/java/noppes/npcs/DataDisplay.java @@ -65,7 +65,7 @@ public class DataDisplay { markovGeneratorId = new Random().nextInt(CustomNpcs.MARKOV_GENERATOR.length-1); skinOverlayData = new DataSkinOverlays(npc); name = getRandomName(); - animationData = new AnimationData(npc,this); + animationData = new AnimationData(this); } public String getRandomName() { diff --git a/src/main/java/noppes/npcs/client/Client.java b/src/main/java/noppes/npcs/client/Client.java index 6bc3459f0..a239016ac 100644 --- a/src/main/java/noppes/npcs/client/Client.java +++ b/src/main/java/noppes/npcs/client/Client.java @@ -3,7 +3,7 @@ package noppes.npcs.client; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import noppes.npcs.AnimationDataShared; +import noppes.npcs.AnimationData; import noppes.npcs.CustomNpcs; import noppes.npcs.Server; import noppes.npcs.client.gui.OverlayQuestTracking; @@ -19,7 +19,7 @@ public class Client { public static OverlayQuestTracking questTrackingOverlay = null; public static HashMap customOverlays = new HashMap<>(); public static HashMap> skinOverlays = new HashMap<>(); - public static HashMap playerModelData = new HashMap<>(); + public static HashMap playerAnimations = new HashMap<>(); public static void sendData(EnumPacketServer enu, Object... obs) { ByteBuf buffer = Unpooled.buffer(); diff --git a/src/main/java/noppes/npcs/client/ClientEventHandler.java b/src/main/java/noppes/npcs/client/ClientEventHandler.java index 04205a812..b1ac4a4c1 100644 --- a/src/main/java/noppes/npcs/client/ClientEventHandler.java +++ b/src/main/java/noppes/npcs/client/ClientEventHandler.java @@ -6,8 +6,11 @@ import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RendererLivingEntity; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.client.event.*; +import net.minecraftforge.event.entity.living.LivingEvent; +import noppes.npcs.AnimationData; import noppes.npcs.client.gui.customoverlay.OverlayCustom; import noppes.npcs.client.renderer.RenderCNPCPlayer; +import noppes.npcs.controllers.data.Animation; import noppes.npcs.entity.EntityNPCInterface; import java.util.ArrayList; @@ -70,8 +73,36 @@ public class ClientEventHandler { @SubscribeEvent public void onRenderEntity(RenderLivingEvent.Post event) { + AnimationData data = null; if (event.entity instanceof EntityNPCInterface) { - ClientEventHandler.renderingNpc = null; + data = ClientEventHandler.renderingNpc.display.animationData; + } else if (event.entity instanceof EntityPlayer && Client.playerAnimations.containsKey(event.entity.getUniqueID())) { + data = Client.playerAnimations.get(event.entity.getUniqueID()); + } + + if (data != null && data.isActive()) { + Animation animation = data.animation; + if (animation.renderTicks && data.isActive()) { + animation.increaseTime(); + } + } + ClientEventHandler.renderingNpc = null; + } + + @SubscribeEvent + public void onUpdateEntity(LivingEvent.LivingUpdateEvent event) { + AnimationData data = null; + if (event.entity instanceof EntityNPCInterface) { + data = ((EntityNPCInterface)event.entity).display.animationData; + } else if (event.entity instanceof EntityPlayer && Client.playerAnimations.containsKey(event.entity.getUniqueID())) { + data = Client.playerAnimations.get(event.entity.getUniqueID()); + } + + if (data != null && data.isActive()) { + Animation animation = data.animation; + if (!animation.renderTicks && data.isActive()) { + animation.increaseTime(); + } } } diff --git a/src/main/java/noppes/npcs/client/NoppesUtil.java b/src/main/java/noppes/npcs/client/NoppesUtil.java index 19450b1d9..3388be541 100644 --- a/src/main/java/noppes/npcs/client/NoppesUtil.java +++ b/src/main/java/noppes/npcs/client/NoppesUtil.java @@ -12,7 +12,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Util; import net.minecraft.world.World; -import noppes.npcs.AnimationDataShared; +import noppes.npcs.AnimationData; import noppes.npcs.CustomNpcs; import noppes.npcs.Server; import noppes.npcs.client.fx.CustomFX; @@ -88,19 +88,6 @@ public class NoppesUtil { Client.skinOverlays.put(player.getUniqueID(), skinOverlays); } - public static void updatePlayerModelData(EntityPlayer player, NBTTagCompound compound) { - AnimationDataShared data; - if (!Client.playerModelData.containsKey(player.getUniqueID())) { - data = new AnimationDataShared(null); - data.readFromNBT(compound); - data.modelRotations = new float[]{data.rotationX, data.rotationY, data.rotationZ}; - } else { - data = Client.playerModelData.get(player.getUniqueID()); - data.readFromNBT(compound); - } - Client.playerModelData.put(player.getUniqueID(), data); - } - public static void spawnScriptedParticle(EntityPlayer player, ByteBuf buffer){ Minecraft minecraft = Minecraft.getMinecraft(); diff --git a/src/main/java/noppes/npcs/client/PacketHandlerClient.java b/src/main/java/noppes/npcs/client/PacketHandlerClient.java index 517fbc77a..e577c84f3 100644 --- a/src/main/java/noppes/npcs/client/PacketHandlerClient.java +++ b/src/main/java/noppes/npcs/client/PacketHandlerClient.java @@ -31,6 +31,7 @@ import noppes.npcs.config.ConfigClient; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.controllers.RecipeController; +import noppes.npcs.controllers.data.Animation; import noppes.npcs.controllers.data.RecipeCarpentry; import noppes.npcs.entity.EntityDialogNpc; import noppes.npcs.entity.EntityNPCInterface; @@ -289,11 +290,31 @@ public class PacketHandlerClient extends PacketHandlerServer{ NoppesUtil.updateSkinOverlayData(sendingPlayer, compound); } } - else if(type == EnumPacketClient.PLAYER_UPDATE_MODEL_DATA) { - EntityPlayer sendingPlayer = Minecraft.getMinecraft().theWorld.getPlayerEntityByName(Server.readString(buffer)); + else if(type == EnumPacketClient.UPDATE_ANIMATIONS) { NBTTagCompound compound = Server.readNBT(buffer); - if (sendingPlayer != null) { - NoppesUtil.updatePlayerModelData(sendingPlayer, compound); + if (compound.hasKey("EntityId")) { + Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(compound.getInteger("EntityId")); + if (entity instanceof EntityNPCInterface) { + AnimationData data = ((EntityNPCInterface) entity).display.animationData; + data.readFromNBT(compound); + if (data.animation == null) { + data.animation = new Animation(); + } + data.animation.readFromNBT(compound.getCompoundTag("Animation")); + } + } else { + EntityPlayer sendingPlayer = Minecraft.getMinecraft().theWorld.getPlayerEntityByName(Server.readString(buffer)); + if (sendingPlayer != null) { + AnimationData data; + if (!Client.playerAnimations.containsKey(player.getUniqueID())) { + data = new AnimationData(player); + data.readFromNBT(compound.getCompoundTag("Animation")); + } else { + data = Client.playerAnimations.get(player.getUniqueID()); + data.readFromNBT(compound.getCompoundTag("Animation")); + } + Client.playerAnimations.put(player.getUniqueID(), data); + } } } else if(type == EnumPacketClient.DISABLE_MOUSE_INPUT) { diff --git a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcPuppet.java b/src/main/java/noppes/npcs/client/gui/roles/GuiNpcPuppet.java deleted file mode 100644 index 617e0e840..000000000 --- a/src/main/java/noppes/npcs/client/gui/roles/GuiNpcPuppet.java +++ /dev/null @@ -1,234 +0,0 @@ -package noppes.npcs.client.gui.roles; - -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.nbt.NBTTagCompound; -import noppes.npcs.AnimationData; -import noppes.npcs.AnimationPartConfig; -import noppes.npcs.client.Client; -import noppes.npcs.client.gui.util.*; -import noppes.npcs.constants.EnumPacketServer; -import noppes.npcs.entity.EntityCustomNpc; - -public class GuiNpcPuppet extends GuiModelInterface implements ISliderListener, ITextfieldListener { - - private GuiScreen parent; - private int type = 6; - private AnimationData job; - private AnimationPartConfig part; - - private GuiNpcSlider rotateX; - private GuiNpcSlider rotateY; - private GuiNpcSlider rotateZ; - - public GuiNpcPuppet(GuiScreen parent, EntityCustomNpc npc){ - super(npc); - this.parent = parent; - this.xOffset = 100; - ySize = 230; - job = npc.display.animationData; - } - - @Override - public void initGui() { - super.initGui(); - - int y = guiTop; - addLabel(new GuiNpcLabel(26, "gui.settings", guiLeft + 55, y + 5, 0xFFFFFF)); - if(type == 6){ - addButton(new GuiNpcButton(30, guiLeft + 120, y += 14, 60, 20, new String[]{"gui.yes", "gui.no"}, job.whileStanding?0:1)); - addLabel(new GuiNpcLabel(30, "puppet.standing", guiLeft + 30, y + 5, 0xFFFFFF)); - addButton(new GuiNpcButton(31, guiLeft + 120, y += 22, 60, 20, new String[]{"gui.yes", "gui.no"}, job.whileMoving?0:1)); - addLabel(new GuiNpcLabel(31, "puppet.walking", guiLeft + 30, y + 5, 0xFFFFFF)); - addButton(new GuiNpcButton(32, guiLeft + 120, y += 22, 60, 20, new String[]{"gui.yes", "gui.no"}, job.whileAttacking?0:1)); - addLabel(new GuiNpcLabel(32, "puppet.attacking", guiLeft + 30, y + 5, 0xFFFFFF)); - - y += 24; - } - else{ - addButton(new GuiNpcButton(6, guiLeft + 110, y , 60, 20, "selectServer.edit")); - y += 24; - } - - addLabel(new GuiNpcLabel(20, "model.head", guiLeft + 55, y + 5, 0xFFFFFF)); - if(type == 0){ - y += drawSlider(y, job.head); - } - else{ - addButton(new GuiNpcButton(0, guiLeft + 110, y , 60, 20, "selectServer.edit")); - y += 24; - } - - addLabel(new GuiNpcLabel(21, "model.body", guiLeft + 55, y + 5, 0xFFFFFF)); - if(type == 1){ - y += drawSlider(y, job.body); - } - else{ - addButton(new GuiNpcButton(1, guiLeft + 110, y , 60, 20, "selectServer.edit")); - y += 24; - } - - addLabel(new GuiNpcLabel(22, "model.larm", guiLeft + 55, y + 5, 0xFFFFFF)); - if(type == 2){ - y += drawSlider(y, job.larm); - } - else{ - addButton(new GuiNpcButton(2, guiLeft + 110, y , 60, 20, "selectServer.edit")); - y += 24; - } - - addLabel(new GuiNpcLabel(23, "model.rarm", guiLeft + 55, y + 5, 0xFFFFFF)); - if(type == 3){ - y += drawSlider(y, job.rarm); - } - else{ - addButton(new GuiNpcButton(3, guiLeft + 110, y , 60, 20, "selectServer.edit")); - y += 24; - } - - addLabel(new GuiNpcLabel(24, "model.lleg", guiLeft + 55, y + 5, 0xFFFFFF)); - if(type == 4){ - y += drawSlider(y, job.lleg);; - } - else{ - addButton(new GuiNpcButton(4, guiLeft + 110, y , 60, 20, "selectServer.edit")); - y += 24; - } - - addLabel(new GuiNpcLabel(25, "model.rleg", guiLeft + 55, y + 5, 0xFFFFFF)); - if(type == 5){ - y += drawSlider(y, job.rleg);; - } - else{ - addButton(new GuiNpcButton(5, guiLeft + 110, y , 60, 20, "selectServer.edit")); - y += 24; - } - - } - - private float drawSlider(int y, AnimationPartConfig config){ - part = config; - addButton(new GuiNpcButton(29, guiLeft + 100, y , 80, 20, new String[]{"gui.enabled","gui.disabled"}, !config.enablePart?1:0)); - y += 22; - addLabel(new GuiNpcLabel(10, "X", guiLeft, y + 5, 0xFFFFFF)); - rotateX = new GuiNpcSlider(this, 10, guiLeft + 50, y, config.rotationX + 0.5f); - addSlider(rotateX); - addButton(new GuiNpcButton(170, guiLeft + 8, y, 40, 20, "Reset")); - y += 22; - addLabel(new GuiNpcLabel(11, "Y", guiLeft, y + 5, 0xFFFFFF)); - rotateY = new GuiNpcSlider(this, 11, guiLeft + 50, y, config.rotationY + 0.5f); - addSlider(rotateY); - addButton(new GuiNpcButton(171, guiLeft + 8, y, 40, 20, "Reset")); - y += 22; - addLabel(new GuiNpcLabel(12, "Z", guiLeft, y + 5, 0xFFFFFF)); - rotateZ = new GuiNpcSlider(this, 12, guiLeft + 50, y, config.rotationZ + 0.5f); - addSlider(rotateZ); - addButton(new GuiNpcButton(172, guiLeft + 8, y, 40, 20, "Reset")); - - addTextField(new GuiNpcTextField(15, this, guiLeft + 60, y += 22, 40, 20, "" + config.pivotX)); - addLabel(new GuiNpcLabel(15, "puppet.pivotX", guiLeft, y + 5, 0xFFFFFF)); - getTextField(15).floatsOnly = true; - getTextField(15).setMinMaxDefaultFloat(-Float.MAX_VALUE,Float.MAX_VALUE,0); - - addTextField(new GuiNpcTextField(16, this, guiLeft + 60, y += 22, 40, 20, "" + config.pivotY)); - addLabel(new GuiNpcLabel(16, "puppet.pivotY", guiLeft, y + 5, 0xFFFFFF)); - getTextField(16).floatsOnly = true; - getTextField(16).setMinMaxDefaultFloat(-Float.MAX_VALUE,Float.MAX_VALUE,0); - - addTextField(new GuiNpcTextField(17, this, guiLeft + 60, y += 22, 40, 20, "" + config.pivotZ)); - addLabel(new GuiNpcLabel(17, "puppet.pivotZ", guiLeft, y + 5, 0xFFFFFF)); - getTextField(17).floatsOnly = true; - getTextField(17).setMinMaxDefaultFloat(-Float.MAX_VALUE,Float.MAX_VALUE,0); - - return 160; - } - - - @Override - protected void actionPerformed(GuiButton btn) { - super.actionPerformed(btn); - if(btn.id < 7){ - type = btn.id; - initGui(); - } - if(!(btn instanceof GuiNpcButton)) - return; - - GuiNpcButton button = (GuiNpcButton) btn; - if(btn.id == 29){ - part.enablePart = button.getValue() == 0; - } - if(btn.id == 30){ - job.whileStanding = button.getValue() == 0; - } - if(btn.id == 31){ - job.whileMoving = button.getValue() == 0; - } - if(btn.id == 32){ - job.whileAttacking = button.getValue() == 0; - } - if(btn.id == 170 || btn.id == 171 || btn.id == 172){ - if(btn.id == 170){ - part.rotationX = 0.0f; - rotateX.sliderValue = 0.5f; - int percent = (int) ((rotateX.sliderValue) * 360); - rotateX.setString(percent + "%"); - } - else if(btn.id == 171){ - part.rotationY = 0.0f; - rotateY.sliderValue = 0.5f; - int percent = (int) ((rotateY.sliderValue) * 360); - rotateY.setString(percent + "%"); - } - else{ - part.rotationZ = 0.0f; - rotateZ.sliderValue = 0.5f; - int percent = (int) ((rotateZ.sliderValue) * 360); - rotateZ.setString(percent + "%"); - } - npc.updateHitbox(); - } - } - - @Override - public void unFocused(GuiNpcTextField textfield) { - if(textfield.id == 15) { - part.pivotX = textfield.getFloat(); - } - if(textfield.id == 16) { - part.pivotY = textfield.getFloat(); - } - if(textfield.id == 17) { - part.pivotZ = textfield.getFloat(); - } - } - - @Override - public void close(){ - this.mc.displayGuiScreen(parent); - Client.sendData(EnumPacketServer.JobSave, job.writeToNBT(new NBTTagCompound())); - } - - @Override - public void mouseDragged(GuiNpcSlider slider) { - int percent = (int) ((slider.sliderValue) * 360); - slider.setString(percent + "%"); - - if(slider.id == 10) - part.rotationX = slider.sliderValue - 0.5f; - if(slider.id == 11) - part.rotationY = slider.sliderValue - 0.5f; - if(slider.id == 12) - part.rotationZ = slider.sliderValue - 0.5f; - npc.updateHitbox(); - } - - @Override - public void mousePressed(GuiNpcSlider slider) { - - } - - @Override - public void mouseReleased(GuiNpcSlider slider) { - } -} diff --git a/src/main/java/noppes/npcs/client/model/ModelMPM.java b/src/main/java/noppes/npcs/client/model/ModelMPM.java index cb8db1427..f308e5336 100644 --- a/src/main/java/noppes/npcs/client/model/ModelMPM.java +++ b/src/main/java/noppes/npcs/client/model/ModelMPM.java @@ -11,6 +11,8 @@ import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import noppes.npcs.*; import noppes.npcs.api.ISkinOverlay; +import noppes.npcs.api.handler.data.IFramePart; +import noppes.npcs.client.ClientEventHandler; import noppes.npcs.client.model.animation.AniCrawling; import noppes.npcs.client.model.animation.AniHug; import noppes.npcs.client.model.part.*; @@ -18,10 +20,15 @@ import noppes.npcs.client.model.util.ModelPartInterface; import noppes.npcs.client.model.util.ModelScaleRenderer; import noppes.npcs.client.renderer.RenderNPCInterface; import noppes.npcs.constants.EnumAnimation; +import noppes.npcs.constants.EnumAnimationPart; +import noppes.npcs.controllers.data.Animation; +import noppes.npcs.controllers.data.Frame; +import noppes.npcs.controllers.data.FramePart; import noppes.npcs.controllers.data.SkinOverlay; import noppes.npcs.entity.EntityCustomNpc; import org.lwjgl.opengl.GL11; +import java.util.HashMap; import java.util.Random; import static noppes.npcs.client.ClientProxy.bindTexture; @@ -562,14 +569,31 @@ public class ModelMPM extends ModelNPCMale{ this.bipedBody.rotateAngleX = 0.5F / npc.modelData.body.scaleY; } - AnimationData job = npc.display.animationData; - if (job.isActive()) { - AnimationPartConfig[] partConfigs = new AnimationPartConfig[]{job.head,job.body,job.larm,job.rarm,job.lleg,job.rleg}; - ModelRenderer[] mainModelParts = new ModelRenderer[]{bipedHead,bipedBody,bipedLeftArm,bipedRightArm,bipedLeftLeg,bipedRightLeg}; + AnimationData animationData = npc.display.animationData; + if (animationData.isActive()) { + Animation animation = animationData.animation; + Frame frame = animation.frames.get(animation.currentFrame); - for (int i = 0; i < partConfigs.length; i++) { - if (partConfigs[i].enablePart) { - this.setInterpolatedAngles(mainModelParts[i],partConfigs[i]); + HashMap animPartToModel = new HashMap<>(); + animPartToModel.put(EnumAnimationPart.HEAD,bipedHead); + animPartToModel.put(EnumAnimationPart.BODY,bipedBody); + animPartToModel.put(EnumAnimationPart.LEFT_ARM,bipedLeftArm); + animPartToModel.put(EnumAnimationPart.RIGHT_ARM,bipedRightArm); + animPartToModel.put(EnumAnimationPart.LEFT_LEG,bipedLeftLeg); + animPartToModel.put(EnumAnimationPart.RIGHT_LEG,bipedRightLeg); + + FramePart[] frameParts = frame.frameParts.values().toArray(new FramePart[0]); + for (FramePart part : frameParts) { + if (part != null) { + if (part.part != EnumAnimationPart.FULL_MODEL) { + ModelRenderer modelRenderer = animPartToModel.get(part.part); + part.interpolateAngles(); + modelRenderer.rotateAngleX = part.prevRotations[0]; + modelRenderer.rotateAngleY = part.prevRotations[1]; + modelRenderer.rotateAngleZ = part.prevRotations[2]; + } else { + part.interpolateAngles(); + } } } @@ -611,78 +635,31 @@ public class ModelMPM extends ModelNPCMale{ -MathHelper.sin(this.bipedBody.rotateAngleY) * 2.0F + MathHelper.sin(this.bipedBody.rotateAngleX) * MathHelper.cos(this.bipedBody.rotateAngleY) * 12.0F; - for (int i = 0; i < partConfigs.length; i++) { - if (partConfigs[i].enablePart) { - this.addInterpolatedOffset(mainModelParts[i],partConfigs[i]); + frameParts = frame.frameParts.values().toArray(new FramePart[0]); + for (FramePart part : frameParts) { + if (part != null) { + if (part.part != EnumAnimationPart.FULL_MODEL) { + ModelRenderer modelRenderer = animPartToModel.get(part.part); + part.interpolateOffset(); + modelRenderer.rotationPointX += part.prevPivots[0]; + modelRenderer.rotationPointY += part.prevPivots[1]; + modelRenderer.rotationPointZ += part.prevPivots[2]; + } else { + part.interpolateOffset(); + } } } - } - } - public void setInterpolatedAngles(ModelRenderer renderer, AnimationPartConfig modelPart) { - renderer.rotateAngleX = modelPart.prevRotations[0]; - renderer.rotateAngleY = modelPart.prevRotations[1]; - renderer.rotateAngleZ = modelPart.prevRotations[2]; - - float pi = (float) Math.PI * (modelPart.fullAngles ? 2 : 1); - if (!modelPart.animate) { - renderer.rotateAngleX = modelPart.rotationX * pi; - renderer.rotateAngleY = modelPart.rotationY * pi; - renderer.rotateAngleZ = modelPart.rotationZ * pi; - } else { - if (modelPart.interpolate) { - renderer.rotateAngleX = (modelPart.rotationX * pi - renderer.rotateAngleX) * modelPart.animRate / 10f + renderer.rotateAngleX; - renderer.rotateAngleY = (modelPart.rotationY * pi - renderer.rotateAngleY) * modelPart.animRate / 10f + renderer.rotateAngleY; - renderer.rotateAngleZ = (modelPart.rotationZ * pi - renderer.rotateAngleZ) * modelPart.animRate / 10f + renderer.rotateAngleZ; - } else { - int directionX = Float.compare(modelPart.rotationX * pi, renderer.rotateAngleX); - renderer.rotateAngleX += directionX * modelPart.animRate / 10f; - renderer.rotateAngleX = directionX == 1 ? - Math.min(modelPart.rotationX * pi,renderer.rotateAngleX) : Math.max(modelPart.rotationX * pi,renderer.rotateAngleX); - int directionY = Float.compare(modelPart.rotationY * pi, renderer.rotateAngleY); - renderer.rotateAngleY += directionY * modelPart.animRate / 10f; - renderer.rotateAngleY = directionY == 1 ? - Math.min(modelPart.rotationY * pi,renderer.rotateAngleY) : Math.max(modelPart.rotationY * pi,renderer.rotateAngleY); - int directionZ = Float.compare(modelPart.rotationZ * pi, renderer.rotateAngleZ); - renderer.rotateAngleZ += directionZ * modelPart.animRate / 10f; - renderer.rotateAngleZ = directionZ == 1 ? - Math.min(modelPart.rotationZ * pi,renderer.rotateAngleZ) : Math.max(modelPart.rotationZ * pi,renderer.rotateAngleZ); - } - } - modelPart.prevRotations = new float[]{renderer.rotateAngleX,renderer.rotateAngleY,renderer.rotateAngleZ}; - } - - public void addInterpolatedOffset(ModelRenderer renderer, AnimationPartConfig modelPart) { - if (!modelPart.animate) { - renderer.rotationPointX += modelPart.pivotX; - renderer.rotationPointY += modelPart.pivotY; - renderer.rotationPointZ += modelPart.pivotZ; - } else { - renderer.rotationPointX += modelPart.prevPivots[0]; - renderer.rotationPointY += modelPart.prevPivots[1]; - renderer.rotationPointZ += modelPart.prevPivots[2]; - if (modelPart.interpolate) { - modelPart.prevPivots[0] = (modelPart.pivotX - modelPart.prevPivots[0]) * modelPart.animRate / 10f + modelPart.prevPivots[0]; - modelPart.prevPivots[1] = (modelPart.pivotY - modelPart.prevPivots[1]) * modelPart.animRate / 10f + modelPart.prevPivots[1]; - modelPart.prevPivots[2] = (modelPart.pivotZ - modelPart.prevPivots[2]) * modelPart.animRate / 10f + modelPart.prevPivots[2]; - } else { - int directionX = Float.compare(modelPart.pivotX, modelPart.prevPivots[0]); - modelPart.prevPivots[0] += directionX * modelPart.animRate / 10f; - modelPart.prevPivots[0] = directionX == 1 ? - Math.min(modelPart.pivotX,modelPart.prevPivots[0]) : Math.max(modelPart.pivotX,modelPart.prevPivots[0]); - int directionY = Float.compare(modelPart.pivotY, modelPart.prevPivots[1]); - modelPart.prevPivots[1] += directionY * modelPart.animRate / 10f; - modelPart.prevPivots[1] = directionY == 1 ? - Math.min(modelPart.pivotY,modelPart.prevPivots[1]) : Math.max(modelPart.pivotY,modelPart.prevPivots[1]); - int directionZ = Float.compare(modelPart.pivotZ, modelPart.prevPivots[2]); - modelPart.prevPivots[2] += directionZ * modelPart.animRate / 10f; - modelPart.prevPivots[2] = directionZ == 1 ? - Math.min(modelPart.pivotZ,modelPart.prevPivots[2]) : Math.max(modelPart.pivotZ,modelPart.prevPivots[2]); + if (frame.frameParts.containsKey(EnumAnimationPart.FULL_MODEL)) { + FramePart part = frame.frameParts.get(EnumAnimationPart.FULL_MODEL); + GL11.glTranslatef(part.prevPivots[0],part.prevPivots[1],part.prevPivots[2]); + GL11.glRotatef(part.prevRotations[0],1,0,0); + GL11.glRotatef(part.prevRotations[1],0,1,0); + GL11.glRotatef(part.prevRotations[2],0,0,1); } } } - public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) { if(entityModel != null){ diff --git a/src/main/java/noppes/npcs/constants/EnumAnimationPart.java b/src/main/java/noppes/npcs/constants/EnumAnimationPart.java index c9192ee7c..d0a8fa919 100644 --- a/src/main/java/noppes/npcs/constants/EnumAnimationPart.java +++ b/src/main/java/noppes/npcs/constants/EnumAnimationPart.java @@ -1,11 +1,16 @@ package noppes.npcs.constants; public enum EnumAnimationPart { - HEAD, - BODY, - RIGHT_ARM, - LEFT_ARM, - RIGHT_LEG, - LEFT_LEG, - FULL_MODEL; + HEAD(0), + BODY(1), + RIGHT_ARM(2), + LEFT_ARM(3), + RIGHT_LEG(4), + LEFT_LEG(5), + FULL_MODEL(6); + + public int id; + EnumAnimationPart(int id) { + this.id = id; + } } diff --git a/src/main/java/noppes/npcs/constants/EnumPacketClient.java b/src/main/java/noppes/npcs/constants/EnumPacketClient.java index 7cf806707..60fbe6ee6 100644 --- a/src/main/java/noppes/npcs/constants/EnumPacketClient.java +++ b/src/main/java/noppes/npcs/constants/EnumPacketClient.java @@ -39,7 +39,7 @@ public enum EnumPacketClient { SWING_PLAYER_ARM, UPDATE_ITEM, PLAYER_UPDATE_SKIN_OVERLAYS, - PLAYER_UPDATE_MODEL_DATA, + UPDATE_ANIMATIONS, OVERLAY_QUEST_TRACKING, DISABLE_MOUSE_INPUT, PLAY_SOUND_TO, diff --git a/src/main/java/noppes/npcs/controllers/data/Animation.java b/src/main/java/noppes/npcs/controllers/data/Animation.java index fa1f01929..ebbb6aab0 100644 --- a/src/main/java/noppes/npcs/controllers/data/Animation.java +++ b/src/main/java/noppes/npcs/controllers/data/Animation.java @@ -2,67 +2,169 @@ package noppes.npcs.controllers.data; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import noppes.npcs.api.handler.data.IAnimation; +import noppes.npcs.api.handler.data.IFrame; +import noppes.npcs.constants.EnumAnimationPart; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; -public class Animation { +public class Animation implements IAnimation { public ArrayList frames = new ArrayList(); + public int currentFrame = 0; + public int currentFrameTime = 0; + public int id = 0; public String name; public float speed = 1.0F; - public boolean smooth = false; + public byte smooth = 0; + public boolean renderTicks = false; // If true, MC ticks are used. If false, render ticks are used. + + public boolean whileStanding = true; + public boolean whileAttacking = true; + public boolean whileMoving = true; public Animation(){} - public Animation(ArrayList parts, String name){ - this.frames = parts; + public Animation(String name){ this.name = name; } - public Animation(ArrayList parts, String name, float speed, boolean smooth){ - this.frames = parts; + public Animation(String name, float speed, byte smooth){ this.name = name; this.speed = speed; this.smooth = smooth; } - public ArrayList getFrames() { - return frames; + public IFrame currentFrame() { + return currentFrame < frames.size() ? frames.get(currentFrame) : null; + } + + public IFrame[] getFrames() { + return frames.toArray(new Frame[0]); + } + + public IAnimation setFrames(IFrame[] frames) { + this.clearFrames(); + for (IFrame frame : frames) { + this.frames.add((Frame) frame); + } + return this; + } + + public IAnimation clearFrames() { + this.frames.clear(); + return this; + } + + public IAnimation addFrame(IFrame frame) { + this.frames.add((Frame) frame); + return this; + } + + public IAnimation addFrame(int index, IFrame frame) { + this.frames.add(index, (Frame) frame); + return this; + } + + public IAnimation removeFrame(IFrame frame) { + this.frames.remove((Frame) frame); + return this; } public int getId() { return id; } + public IAnimation setName(String name) { + this.name = name; + return this; + } + public String getName() { - return name; + return this.name; + } + + public IAnimation setSpeed(float speed) { + this.speed = speed; + return this; } public float getSpeed() { - return speed; + return this.speed; } - public boolean isSmooth() { - return smooth; + public IAnimation setSmooth(byte smooth) { + this.smooth = smooth; + return this; + } + + public byte isSmooth() { + 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; + } + + public boolean doWhileStanding() { + return this.whileStanding; + } + + public IAnimation doWhileMoving(boolean whileMoving) { + this.whileMoving = whileMoving; + return this; + } + + public boolean doWhileMoving() { + return this.whileMoving; + } + + public IAnimation doWhileAttacking(boolean whileAttacking) { + this.whileAttacking = whileAttacking; + return this; + } + + public boolean doWhileAttacking() { + return this.whileAttacking; } public void readFromNBT(NBTTagCompound compound){ name = compound.getString("Name"); id = compound.getInteger("ID"); speed = compound.getFloat("Speed"); - smooth = compound.getBoolean("Smooth"); + smooth = compound.getByte("Smooth"); + + renderTicks = compound.getBoolean("RenderTicks"); + currentFrame = compound.getInteger("CurrentFrame"); ArrayList frames = new ArrayList(); NBTTagList list = compound.getTagList("Frames", 10); for (int i = 0; i < list.tagCount(); i++) { NBTTagCompound item = list.getCompoundTagAt(i); Frame frame = new Frame(); + frame.parent = this; frame.readFromNBT(item); frames.add(frame); } this.frames = frames; + + this.whileStanding = compound.getBoolean("WhileStanding"); + this.whileMoving = compound.getBoolean("WhileWalking"); + this.whileAttacking = compound.getBoolean("WhileAttacking"); } public NBTTagCompound writeToNBT(){ @@ -70,7 +172,10 @@ public class Animation { compound.setString("Name", name); compound.setInteger("ID", id); compound.setFloat("Speed", speed); - compound.setBoolean("Smooth", smooth); + compound.setByte("Smooth", smooth); + + compound.setBoolean("RenderTicks", renderTicks); + compound.setInteger("CurrentFrame", currentFrame); NBTTagList list = new NBTTagList(); for(Frame frame : frames){ @@ -78,7 +183,28 @@ public class Animation { list.appendTag(item); } compound.setTag("Frames", list); + + compound.setBoolean("WhileStanding", whileStanding); + compound.setBoolean("WhileWalking", whileMoving); + compound.setBoolean("WhileAttacking", whileAttacking); return compound; } + public void increaseTime() { + this.currentFrameTime++; + if (this.currentFrameTime == this.currentFrame().getDuration()) { + Frame prevFrame = (Frame) this.currentFrame(); + this.currentFrameTime = 0; + this.currentFrame++; + if (this.currentFrame < this.frames.size()) { + Frame nextFrame = this.frames.get(this.currentFrame); + for (EnumAnimationPart part : EnumAnimationPart.values()) { + if (prevFrame.frameParts.containsKey(part) && nextFrame.frameParts.containsKey(part)) { + nextFrame.frameParts.get(part).prevRotations = prevFrame.frameParts.get(part).prevRotations; + nextFrame.frameParts.get(part).prevPivots = prevFrame.frameParts.get(part).prevPivots; + } + } + } + } + } } diff --git a/src/main/java/noppes/npcs/controllers/data/Frame.java b/src/main/java/noppes/npcs/controllers/data/Frame.java index 76395d2a9..122c5e7e5 100644 --- a/src/main/java/noppes/npcs/controllers/data/Frame.java +++ b/src/main/java/noppes/npcs/controllers/data/Frame.java @@ -2,71 +2,101 @@ package noppes.npcs.controllers.data; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import noppes.npcs.api.handler.data.IFrame; +import noppes.npcs.api.handler.data.IFramePart; +import noppes.npcs.constants.EnumAnimationPart; -import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; -public class Frame { - - public ArrayList frameParts = new ArrayList(); +public class Frame implements IFrame { + public Animation parent; + public HashMap frameParts = new HashMap<>(); public int duration = 0; boolean customized = false; public float speed = 1.0F; - public boolean smooth = false; + public byte smooth = 0; public Frame(){} - public Frame(ArrayList parts, int duration){ - this.frameParts = parts; + public Frame(int duration) { this.duration = duration; } - public Frame(ArrayList parts, int duration, float speed, boolean smooth){ - this.frameParts = parts; + public Frame(int duration, float speed, byte smooth) { this.duration = duration; this.speed = speed; this.smooth = smooth; this.customized = true; } - public ArrayList getFrameParts() { + public HashMap getFrameMap() { return frameParts; } - public void setFrameParts(ArrayList frameParts) { - this.frameParts = frameParts; + public IFramePart[] getParts() { + return frameParts.values().toArray(new IFramePart[0]); + } + + public IFrame addPart(IFramePart partConfig) { + this.frameParts.put(((FramePart)partConfig).getPart(),(FramePart) partConfig); + return this; + } + + public IFrame removePart(String partName) { + try { + this.frameParts.remove(EnumAnimationPart.valueOf(partName)); + } catch (IllegalArgumentException ignored) {} + return this; + } + + public IFrame removePart(int partId) { + for (EnumAnimationPart part : EnumAnimationPart.values()) { + this.frameParts.remove(part); + } + return this; + } + + public IFrame clearParts() { + frameParts.clear(); + return this; } public int getDuration() { return duration; } - public void setDuration(int duration) { + public IFrame setDuration(int duration) { this.duration = duration; + return this; } public boolean isCustomized() { return customized; } - public void setCustomized(boolean customized) { + public IFrame setCustomized(boolean customized) { this.customized = customized; + return this; } public float getSpeed() { return speed; } - public void setSpeed(float speed) { + public IFrame setSpeed(float speed) { this.speed = speed; + return this; } - public boolean isSmooth() { + public byte smoothType() { return smooth; } - public void setSmooth(boolean smooth) { + public IFrame setSmooth(byte smooth) { this.smooth = smooth; + return this; } public void readFromNBT(NBTTagCompound compound){ @@ -79,16 +109,25 @@ public class Frame { } if(compound.hasKey("Smooth")){ customized = true; - smooth = compound.getBoolean("Smooth"); + smooth = compound.getByte("Smooth"); } - ArrayList frameParts = new ArrayList(); + if (!customized) { + this.speed = parent.speed; + this.smooth = parent.smooth; + } + + HashMap frameParts = new HashMap<>(); NBTTagList list = compound.getTagList("FrameParts", 10); for (int i = 0; i < list.tagCount(); i++) { NBTTagCompound item = list.getCompoundTagAt(i); FramePart framePart = new FramePart(); framePart.readFromNBT(item); - frameParts.add(framePart); + if (!framePart.customized) { + framePart.smooth = this.smooth; + framePart.speed = this.speed; + } + frameParts.put(framePart.part,framePart); } this.frameParts = frameParts; } @@ -98,11 +137,11 @@ public class Frame { compound.setInteger("Duration", duration); if(customized){ compound.setFloat("Speed", speed); - compound.setBoolean("Smooth", smooth); + compound.setByte("Smooth", smooth); } NBTTagList list = new NBTTagList(); - for(FramePart framePart : frameParts){ + for(FramePart framePart : frameParts.values()){ NBTTagCompound item = framePart.writeToNBT(); list.appendTag(item); } diff --git a/src/main/java/noppes/npcs/controllers/data/FramePart.java b/src/main/java/noppes/npcs/controllers/data/FramePart.java index c4df784db..eff2ec773 100644 --- a/src/main/java/noppes/npcs/controllers/data/FramePart.java +++ b/src/main/java/noppes/npcs/controllers/data/FramePart.java @@ -1,9 +1,13 @@ package noppes.npcs.controllers.data; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.api.handler.data.IFramePart; +import noppes.npcs.client.ClientEventHandler; import noppes.npcs.constants.EnumAnimationPart; -public class FramePart { +public class FramePart implements IFramePart { public EnumAnimationPart part; public int[] rotation = {0, 0, 0}; @@ -12,7 +16,14 @@ public class FramePart { boolean customized = false; public float speed = 1.0F; - public boolean smooth = false; + //0 - Interpolated, 1 - Linear, 2 - None + public byte smooth = 0; + + //Client-sided fields (unsaved) + public float[] prevRotations = {0,0,0}; + public float[] prevPivots = {0,0,0}; + public float partialRotationTick; + public float partialPivotTick; public FramePart(){} @@ -20,67 +31,82 @@ public class FramePart { this.part = part; } - public FramePart(EnumAnimationPart part, int[] rotation, int[] pivot){ - this.part = part; - this.rotation = rotation; - this.pivot = pivot; - } - - public FramePart(EnumAnimationPart part, int[] rotation, int[] pivot, float speed, boolean smooth){ - this.part = part; - this.rotation = rotation; - this.pivot = pivot; - this.speed = speed; - this.smooth = smooth; - this.customized = true; - } - public EnumAnimationPart getPart() { return part; } + public String getName() { + return part.name(); + } + + public int getPartId() { + return part.id; + } + public void setPart(EnumAnimationPart part) { this.part = part; } - public int[] getRotation() { + public IFramePart setPart(String name) { + try { + this.setPart(EnumAnimationPart.valueOf(name)); + } catch (IllegalArgumentException ignored) {} + return this; + } + + public IFramePart setPart(int partId) { + for (EnumAnimationPart enumPart : EnumAnimationPart.values()) { + if (enumPart.id == partId) { + this.setPart(enumPart); + break; + } + } + return this; + } + + public int[] getRotations() { return rotation; } - public void setRotation(int[] rotation) { + public IFramePart setRotations(int[] rotation) { this.rotation = rotation; + return this; } - public int[] getPivot() { + public int[] getPivots() { return pivot; } - public void setPivot(int[] pivot) { + public IFramePart setPivots(int[] pivot) { this.pivot = pivot; + return this; } public boolean isCustomized() { return customized; } - public void setCustomized(boolean customized) { + public IFramePart setCustomized(boolean customized) { this.customized = customized; + return this; } public float getSpeed() { return speed; } - public void setSpeed(float speed) { + public IFramePart setSpeed(float speed) { this.speed = speed; + return this; } - public boolean isSmooth() { + public byte isSmooth() { return smooth; } - public void setSmooth(boolean smooth) { + public IFramePart setSmooth(byte smooth) { this.smooth = smooth; + return this; } public void readFromNBT(NBTTagCompound compound){ @@ -95,7 +121,7 @@ public class FramePart { } if(compound.hasKey("Smooth")){ customized = true; - smooth = compound.getBoolean("Smooth"); + smooth = compound.getByte("Smooth"); } } @@ -107,9 +133,68 @@ public class FramePart { if(customized){ compound.setFloat("Speed", speed); - compound.setBoolean("Smooth", smooth); + compound.setByte("Smooth", smooth); } return compound; } + + @SideOnly(Side.CLIENT) + public void interpolateAngles() { + float pi = (float) Math.PI / 180; + if (this.smooth == 2) { + this.prevRotations[0] = this.rotation[0] * pi; + this.prevRotations[1] = this.rotation[1] * pi; + this.prevRotations[2] = this.rotation[2] * pi; + } else if (this.partialRotationTick != ClientEventHandler.partialRenderTick) { + this.partialRotationTick = ClientEventHandler.partialRenderTick; + if (this.smooth == 0) { + this.prevRotations[0] = (this.rotation[0] * pi - this.prevRotations[0]) * Math.abs(this.speed) / 10f + this.prevRotations[0]; + this.prevRotations[1] = (this.rotation[1] * pi - this.prevRotations[1]) * Math.abs(this.speed) / 10f + this.prevRotations[1]; + this.prevRotations[2] = (this.rotation[2] * pi - this.prevRotations[2]) * Math.abs(this.speed) / 10f + this.prevRotations[2]; + } else { + int directionX = Float.compare(this.rotation[0] * pi, this.prevRotations[0]); + this.prevRotations[0] += directionX * this.speed / 10f; + this.prevRotations[0] = directionX == 1 ? + Math.min(this.rotation[0] * pi, this.prevRotations[0]) : Math.max(this.rotation[0] * pi, this.prevRotations[0]); + int directionY = Float.compare(this.rotation[1] * pi, this.prevRotations[1]); + this.prevRotations[1] += directionY * this.speed / 10f; + this.prevRotations[1] = directionY == 1 ? + Math.min(this.rotation[1] * pi, this.prevRotations[1]) : Math.max(this.rotation[1] * pi, this.prevRotations[1]); + int directionZ = Float.compare(this.rotation[2] * pi, this.prevRotations[2]); + this.prevRotations[2] += directionZ * this.speed / 10f; + this.prevRotations[2] = directionZ == 1 ? + Math.min(this.rotation[2] * pi, this.prevRotations[2]) : Math.max(this.rotation[2] * pi, this.prevRotations[2]); + } + } + } + + @SideOnly(Side.CLIENT) + public void interpolateOffset() { + if (this.smooth == 2) { + this.prevPivots[0] = this.pivot[0]; + this.prevPivots[1] = this.pivot[1]; + this.prevPivots[2] = this.pivot[2]; + } else if (this.partialPivotTick != ClientEventHandler.partialRenderTick) { + this.partialPivotTick = ClientEventHandler.partialRenderTick; + if (this.smooth == 0) { + this.prevPivots[0] = (this.pivot[0] - this.prevPivots[0]) * Math.abs(this.speed) / 10f + this.prevPivots[0]; + this.prevPivots[1] = (this.pivot[1] - this.prevPivots[1]) * Math.abs(this.speed) / 10f + this.prevPivots[1]; + this.prevPivots[2] = (this.pivot[2] - this.prevPivots[2]) * Math.abs(this.speed) / 10f + this.prevPivots[2]; + } else { + int directionX = Float.compare(this.pivot[0], this.prevPivots[0]); + this.prevPivots[0] += directionX * this.speed / 10f; + this.prevPivots[0] = directionX == 1 ? + Math.min(this.pivot[0],this.prevPivots[0]) : Math.max(this.pivot[0],this.prevPivots[0]); + int directionY = Float.compare(this.pivot[1], this.prevPivots[1]); + this.prevPivots[1] += directionY * this.speed / 10f; + this.prevPivots[1] = directionY == 1 ? + Math.min(this.pivot[1],this.prevPivots[1]) : Math.max(this.pivot[1],this.prevPivots[1]); + int directionZ = Float.compare(this.pivot[2], this.prevPivots[2]); + this.prevPivots[2] += directionZ * this.speed / 10f; + this.prevPivots[2] = directionZ == 1 ? + Math.min(this.pivot[2],this.prevPivots[2]) : Math.max(this.pivot[2],this.prevPivots[2]); + } + } + } } diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerData.java b/src/main/java/noppes/npcs/controllers/data/PlayerData.java index ab6da4b99..a91ff6d1b 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerData.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerData.java @@ -6,7 +6,7 @@ import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; -import noppes.npcs.AnimationDataShared; +import noppes.npcs.AnimationData; import noppes.npcs.CustomNpcs; import noppes.npcs.LogWriter; import noppes.npcs.api.entity.ICustomNpc; @@ -32,7 +32,7 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { public PlayerFactionData factionData = new PlayerFactionData(this); public PlayerItemGiverData itemgiverData = new PlayerItemGiverData(this); public PlayerMailData mailData = new PlayerMailData(this); - public AnimationDataShared modelData = new AnimationDataShared(this); + public AnimationData animationData = new AnimationData(this); public DataTimers timers = new DataTimers(this); public DataSkinOverlays skinOverlays = new DataSkinOverlays(this); @@ -82,7 +82,7 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { mailData.loadNBTData(data); timers.readFromNBT(data); skinOverlays.readFromNBT(data); - modelData.readFromNBT(data); + animationData.readFromNBT(data); if(player != null){ playername = player.getCommandSenderName(); @@ -120,7 +120,7 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { mailData.saveNBTData(compound); timers.writeToNBT(compound); skinOverlays.writeToNBT(compound); - modelData.writeToNBT(compound); + animationData.writeToNBT(compound); compound.setString("PlayerName", playername); compound.setString("UUID", uuid); @@ -302,10 +302,6 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { return mailData; } - public IPlayerModelData getModelData() { - return modelData; - } - public void save() { PlayerDataController.instance.savePlayerData(this); } diff --git a/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java index d79fa2c68..dc7a3d9c9 100644 --- a/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java +++ b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java @@ -5,11 +5,11 @@ import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import noppes.npcs.AnimationData; -import noppes.npcs.AnimationDataShared; -import noppes.npcs.AnimationPartConfig; import noppes.npcs.client.Client; import noppes.npcs.client.ClientEventHandler; -import noppes.npcs.client.renderer.RenderCustomNpc; +import noppes.npcs.constants.EnumAnimationPart; +import noppes.npcs.controllers.data.Frame; +import noppes.npcs.controllers.data.FramePart; import org.lwjgl.opengl.GL11; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -38,9 +38,7 @@ public abstract class MixinModelRenderer { @Shadow public List childModels; @Shadow abstract void compileDisplayList(float p_78788_1_); - HashMap modelNameMap = new HashMap<>(); - String partName = ""; - HashMap partNames = new HashMap<>(); + HashMap partNames = new HashMap<>(); /** * @author Someone @@ -50,7 +48,7 @@ public abstract class MixinModelRenderer { @SideOnly(Side.CLIENT) public void render(float p_78785_1_) { - AnimationPartConfig currentPart = null; + FramePart currentPart = null; if (partNames.isEmpty()) { String[] headNames = new String[]{"field_78116_c","bipedHead","bipedHeadwear","head","Head","bipedHeadAll", @@ -61,47 +59,28 @@ public abstract class MixinModelRenderer { String[] llegNames = new String[]{"field_78124_i","bipedLeftLeg","LL","leftleg","LegL","Leg1L","LegL1"}; String[] rlegNames = new String[]{"field_78123_h","bipedRightLeg","RL","rightleg","LegR","Leg1R","LegR1"}; - partNames.put("head", headNames); - partNames.put("body", bodyNames); - partNames.put("larm", larmNames); - partNames.put("rarm", rarmNames); - partNames.put("lleg", llegNames); - partNames.put("rleg", rlegNames); + partNames.put(EnumAnimationPart.HEAD, headNames); + partNames.put(EnumAnimationPart.BODY, bodyNames); + partNames.put(EnumAnimationPart.LEFT_ARM, larmNames); + partNames.put(EnumAnimationPart.RIGHT_ARM, rarmNames); + partNames.put(EnumAnimationPart.LEFT_LEG, llegNames); + partNames.put(EnumAnimationPart.RIGHT_LEG, rlegNames); } - if (ClientEventHandler.renderingPlayer != null && Client.playerModelData.containsKey(ClientEventHandler.renderingPlayer.getUniqueID())) { - AnimationDataShared modelData = Client.playerModelData.get(ClientEventHandler.renderingPlayer.getUniqueID()); - AnimationPartConfig[] partConfigs = new AnimationPartConfig[]{modelData.head, modelData.body, modelData.larm, modelData.rarm, modelData.lleg, modelData.rleg}; - this.partName = this.getPartName((ModelRenderer) (Object) this, this.partNames); - this.setModelParts(modelData); - if (modelData.enabled()) { - for (AnimationPartConfig modelPart : partConfigs) { - if (this.isPart(modelNameMap, modelPart, this.partName)) { - this.rotateAngleX = modelPart.prevRotations[0]; - this.rotateAngleY = modelPart.prevRotations[1]; - this.rotateAngleZ = modelPart.prevRotations[2]; - this.addInterpolatedOffset(modelPart); - this.addInterpolatedAngles(modelPart); - modelPart.prevRotations = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; - break; - } - } - } + + AnimationData animData = null; + if (ClientEventHandler.renderingPlayer != null && Client.playerAnimations.containsKey(ClientEventHandler.renderingPlayer.getUniqueID())) { + animData = Client.playerAnimations.get(ClientEventHandler.renderingPlayer.getUniqueID()); } else if (ClientEventHandler.renderingNpc != null) { - AnimationData modelData = ClientEventHandler.renderingNpc.display.animationData; - AnimationPartConfig[] partConfigs = new AnimationPartConfig[]{modelData.head, modelData.body, modelData.larm, modelData.rarm, modelData.lleg, modelData.rleg}; - this.partName = this.getPartName((ModelRenderer) (Object) this, this.partNames); - this.setModelParts(modelData); - if (RenderCustomNpc.entity != null) { - if (modelData.isActive()) { - for (AnimationPartConfig modelPart : partConfigs) { - if (this.isPart(modelNameMap,modelPart,this.partName)) { - currentPart = modelPart; - this.addInterpolatedOffset(modelPart); - this.addInterpolatedAngles(modelPart); - break; - } - } - } + animData = ClientEventHandler.renderingNpc.display.animationData; + } + if (animData != null && animData.isActive()) { + EnumAnimationPart partType; + Frame frame = (Frame) animData.animation.currentFrame(); + partType = this.getPartName((ModelRenderer) (Object) this, this.partNames); + if (frame.frameParts.containsKey(partType)) { + currentPart = frame.frameParts.get(partType); + currentPart.interpolateOffset(); + currentPart.interpolateAngles(); } } @@ -114,13 +93,16 @@ public abstract class MixinModelRenderer { this.compileDisplayList(p_78785_1_); } + float[] prevPivots = new float[]{this.rotationPointX,this.rotationPointY,this.rotationPointZ}; + float[] prevRotations = new float[]{this.rotateAngleX,this.rotateAngleY,this.rotateAngleZ}; + if (currentPart != null) { this.rotationPointX += currentPart.prevPivots[0]; this.rotationPointY += currentPart.prevPivots[1]; this.rotationPointZ += currentPart.prevPivots[2]; - this.rotateAngleX += currentPart.prevRotations[0]; - this.rotateAngleY += currentPart.prevRotations[1]; - this.rotateAngleZ += currentPart.prevRotations[2]; + this.rotateAngleX = currentPart.prevRotations[0]; + this.rotateAngleY = currentPart.prevRotations[1]; + this.rotateAngleZ = currentPart.prevRotations[2]; } GL11.glTranslatef(this.offsetX, this.offsetY, this.offsetZ); int i; @@ -189,146 +171,23 @@ public abstract class MixinModelRenderer { } if (currentPart != null) { - this.rotationPointX -= currentPart.prevPivots[0]; - this.rotationPointY -= currentPart.prevPivots[1]; - this.rotationPointZ -= currentPart.prevPivots[2]; - this.rotateAngleX -= currentPart.prevRotations[0]; - this.rotateAngleY -= currentPart.prevRotations[1]; - this.rotateAngleZ -= currentPart.prevRotations[2]; + this.rotationPointX = prevPivots[0]; + this.rotationPointY = prevPivots[1]; + this.rotationPointZ = prevPivots[2]; + this.rotateAngleX = prevRotations[0]; + this.rotateAngleY = prevRotations[1]; + this.rotateAngleZ = prevRotations[2]; } } } } - - - - - public void addInterpolatedAngles(AnimationPartConfig modelPart) { - if (modelPart == null) { - return; - } - - float pi = (float) Math.PI * (modelPart.fullAngles ? 2 : 1); - if (ClientEventHandler.renderingNpc != null) { - if (!modelPart.animate) { - modelPart.prevRotations[0] = modelPart.rotationX * pi; - modelPart.prevRotations[1] = modelPart.rotationY * pi; - modelPart.prevRotations[2] = modelPart.rotationZ * pi; - } else if (modelPart.partialRotationTick != ClientEventHandler.partialRenderTick) { - modelPart.partialRotationTick = ClientEventHandler.partialRenderTick; - if (modelPart.interpolate) { - modelPart.prevRotations[0] = (modelPart.rotationX * pi - modelPart.prevRotations[0]) * Math.abs(modelPart.animRate) / 10f + modelPart.prevRotations[0]; - modelPart.prevRotations[1] = (modelPart.rotationY * pi - modelPart.prevRotations[1]) * Math.abs(modelPart.animRate) / 10f + modelPart.prevRotations[1]; - modelPart.prevRotations[2] = (modelPart.rotationZ * pi - modelPart.prevRotations[2]) * Math.abs(modelPart.animRate) / 10f + modelPart.prevRotations[2]; - } else { - int directionX = Float.compare(modelPart.rotationX * pi, modelPart.prevRotations[0]); - modelPart.prevRotations[0] += directionX * modelPart.animRate / 10f; - modelPart.prevRotations[0] = directionX == 1 ? - Math.min(modelPart.rotationX * pi, modelPart.prevRotations[0]) : Math.max(modelPart.rotationX * pi, modelPart.prevRotations[0]); - int directionY = Float.compare(modelPart.rotationY * pi, modelPart.prevRotations[1]); - modelPart.prevRotations[1] += directionY * modelPart.animRate / 10f; - modelPart.prevRotations[1] = directionY == 1 ? - Math.min(modelPart.rotationY * pi, modelPart.prevRotations[1]) : Math.max(modelPart.rotationY * pi, modelPart.prevRotations[1]); - int directionZ = Float.compare(modelPart.rotationZ * pi, modelPart.prevRotations[2]); - modelPart.prevRotations[2] += directionZ * modelPart.animRate / 10f; - modelPart.prevRotations[2] = directionZ == 1 ? - Math.min(modelPart.rotationZ * pi, modelPart.prevRotations[2]) : Math.max(modelPart.rotationZ * pi, modelPart.prevRotations[2]); - } - } - } else { - if (!modelPart.animate) { - this.rotateAngleX = modelPart.rotationX * pi; - this.rotateAngleY = modelPart.rotationY * pi; - this.rotateAngleZ = modelPart.rotationZ * pi; - } else if (modelPart.partialRotationTick != ClientEventHandler.partialRenderTick) { - modelPart.partialRotationTick = ClientEventHandler.partialRenderTick; - if (modelPart.interpolate) { - if (modelPart.rotationX * pi - this.rotateAngleX != 0) - this.rotateAngleX = (modelPart.rotationX * pi - this.rotateAngleX) * Math.abs(modelPart.animRate) / 10f + this.rotateAngleX; - if (modelPart.rotationY * pi - this.rotateAngleY != 0) - this.rotateAngleY = (modelPart.rotationY * pi - this.rotateAngleY) * Math.abs(modelPart.animRate) / 10f + this.rotateAngleY; - if (modelPart.rotationZ * pi - this.rotateAngleZ != 0) - this.rotateAngleZ = (modelPart.rotationZ * pi - this.rotateAngleZ) * Math.abs(modelPart.animRate) / 10f + this.rotateAngleZ; - } else { - int directionX = Float.compare(modelPart.rotationX * pi, this.rotateAngleX); - this.rotateAngleX += directionX * Math.abs(modelPart.animRate) / 10f; - this.rotateAngleX = directionX == 1 ? - Math.min(modelPart.rotationX * pi, this.rotateAngleX) : Math.max(modelPart.rotationX * pi, this.rotateAngleX); - int directionY = Float.compare(modelPart.rotationY * pi, this.rotateAngleY); - this.rotateAngleY += directionY * Math.abs(modelPart.animRate) / 10f; - this.rotateAngleY = directionY == 1 ? - Math.min(modelPart.rotationY * pi, this.rotateAngleY) : Math.max(modelPart.rotationY * pi, this.rotateAngleY); - int directionZ = Float.compare(modelPart.rotationZ * pi, this.rotateAngleZ); - this.rotateAngleZ += directionZ * Math.abs(modelPart.animRate) / 10f; - this.rotateAngleZ = directionZ == 1 ? - Math.min(modelPart.rotationZ * pi, this.rotateAngleZ) : Math.max(modelPart.rotationZ * pi, this.rotateAngleZ); - } - } - } - } - - public void addInterpolatedOffset(AnimationPartConfig modelPart) { - if (modelPart == null) { - return; - } - - if (!modelPart.animate) { - modelPart.prevPivots[0] = modelPart.pivotX; - modelPart.prevPivots[1] = modelPart.pivotY; - modelPart.prevPivots[2] = modelPart.pivotZ; - } else if (modelPart.partialPivotTick != ClientEventHandler.partialRenderTick) { - modelPart.partialPivotTick = ClientEventHandler.partialRenderTick; - if (modelPart.interpolate) { - modelPart.prevPivots[0] = (modelPart.pivotX - modelPart.prevPivots[0]) * Math.abs(modelPart.animRate) / 10f + modelPart.prevPivots[0]; - modelPart.prevPivots[1] = (modelPart.pivotY - modelPart.prevPivots[1]) * Math.abs(modelPart.animRate) / 10f + modelPart.prevPivots[1]; - modelPart.prevPivots[2] = (modelPart.pivotZ - modelPart.prevPivots[2]) * Math.abs(modelPart.animRate) / 10f + modelPart.prevPivots[2]; - } else { - int directionX = Float.compare(modelPart.pivotX, modelPart.prevPivots[0]); - modelPart.prevPivots[0] += directionX * modelPart.animRate / 10f; - modelPart.prevPivots[0] = directionX == 1 ? - Math.min(modelPart.pivotX,modelPart.prevPivots[0]) : Math.max(modelPart.pivotX,modelPart.prevPivots[0]); - int directionY = Float.compare(modelPart.pivotY, modelPart.prevPivots[1]); - modelPart.prevPivots[1] += directionY * modelPart.animRate / 10f; - modelPart.prevPivots[1] = directionY == 1 ? - Math.min(modelPart.pivotY,modelPart.prevPivots[1]) : Math.max(modelPart.pivotY,modelPart.prevPivots[1]); - int directionZ = Float.compare(modelPart.pivotZ, modelPart.prevPivots[2]); - modelPart.prevPivots[2] += directionZ * modelPart.animRate / 10f; - modelPart.prevPivots[2] = directionZ == 1 ? - Math.min(modelPart.pivotZ,modelPart.prevPivots[2]) : Math.max(modelPart.pivotZ,modelPart.prevPivots[2]); - } - } - } - - public void setModelParts(Object modelData) { - if (modelData instanceof AnimationDataShared) { - modelNameMap.put(((AnimationDataShared) modelData).head, "head"); - modelNameMap.put(((AnimationDataShared) modelData).body, "body"); - modelNameMap.put(((AnimationDataShared) modelData).rarm, "rarm"); - modelNameMap.put(((AnimationDataShared) modelData).larm, "larm"); - modelNameMap.put(((AnimationDataShared) modelData).rleg, "rleg"); - modelNameMap.put(((AnimationDataShared) modelData).lleg, "lleg"); - } - if (modelData instanceof AnimationData) { - modelNameMap.put(((AnimationData) modelData).head, "head"); - modelNameMap.put(((AnimationData) modelData).body, "body"); - modelNameMap.put(((AnimationData) modelData).rarm, "rarm"); - modelNameMap.put(((AnimationData) modelData).larm, "larm"); - modelNameMap.put(((AnimationData) modelData).rleg, "rleg"); - modelNameMap.put(((AnimationData) modelData).lleg, "lleg"); - } - } - - public boolean isPart(HashMap modelNameMap, AnimationPartConfig puppetPart, String partName) { - return puppetPart.enablePart && partName.equals(modelNameMap.get(puppetPart)); - } - - public String getPartName(ModelRenderer renderer, HashMap partNames) { + public EnumAnimationPart getPartName(ModelRenderer renderer, HashMap partNames) { Class RenderClass = renderer.baseModel.getClass(); Object model = renderer.baseModel; - String returnName = ""; + EnumAnimationPart type = null; - while (returnName.isEmpty()) { + while (type == null) { for (Field f : RenderClass.getDeclaredFields()) { f.setAccessible(true); try { @@ -340,14 +199,14 @@ public abstract class MixinModelRenderer { } } - for (Map.Entry entry : partNames.entrySet()) { + for (Map.Entry entry : partNames.entrySet()) { String[] names = entry.getValue(); for (String partName : names) { try { Field field = RenderClass.getDeclaredField(partName); field.setAccessible(true); if (renderer == field.get(model)) { - returnName = entry.getKey(); + type = entry.getKey(); break; } } catch (Exception ignored) { @@ -361,6 +220,6 @@ public abstract class MixinModelRenderer { RenderClass = RenderClass.getSuperclass(); } - return returnName; + return type; } } diff --git a/src/main/java/noppes/npcs/mixin/MixinRenderPlayer.java b/src/main/java/noppes/npcs/mixin/MixinRenderPlayer.java index d890e74f1..890152af1 100644 --- a/src/main/java/noppes/npcs/mixin/MixinRenderPlayer.java +++ b/src/main/java/noppes/npcs/mixin/MixinRenderPlayer.java @@ -4,9 +4,12 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.renderer.entity.RenderPlayer; -import noppes.npcs.AnimationDataShared; +import noppes.npcs.AnimationData; import noppes.npcs.client.Client; import noppes.npcs.client.ClientEventHandler; +import noppes.npcs.constants.EnumAnimationPart; +import noppes.npcs.controllers.data.Frame; +import noppes.npcs.controllers.data.FramePart; import org.lwjgl.opengl.GL11; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -20,47 +23,19 @@ public class MixinRenderPlayer { @Inject(method = "renderLivingAt", at = @At(value = "TAIL")) protected void modelDataRotations(AbstractClientPlayer p_77039_1_, double p_77039_2_, double p_77039_4_, double p_77039_6_, CallbackInfo callbackInfo) { - if (Client.playerModelData.containsKey(p_77039_1_.getUniqueID())) { - AnimationDataShared data = Client.playerModelData.get(p_77039_1_.getUniqueID()); - if (data.allowAnimation) { - this.setInterpolatedAngles(data); - if (data.rotationEnabledX) { - GL11.glRotatef(data.modelRotations[0], 1, 0, 0); + if (Client.playerAnimations.containsKey(p_77039_1_.getUniqueID())) { + AnimationData animData = Client.playerAnimations.get(p_77039_1_.getUniqueID()); + if (animData != null && animData.isActive()) { + Frame frame = (Frame) animData.animation.currentFrame(); + if (frame.frameParts.containsKey(EnumAnimationPart.FULL_MODEL)) { + FramePart part = frame.frameParts.get(EnumAnimationPart.FULL_MODEL); + part.interpolateOffset(); + part.interpolateAngles(); + GL11.glTranslatef(part.prevPivots[0], part.prevPivots[1], part.prevPivots[2]); + GL11.glRotatef(part.prevRotations[0], 1, 0, 0); + GL11.glRotatef(part.prevRotations[1], 0, 1, 0); + GL11.glRotatef(part.prevRotations[2], 0, 0, 1); } - if (data.rotationEnabledY) { - GL11.glRotatef(data.modelRotations[1], 0, 1, 0); - } - if (data.rotationEnabledZ) { - GL11.glRotatef(data.modelRotations[2], 0, 0, 1); - } - } - } - } - - public void setInterpolatedAngles(AnimationDataShared modelData) { - float pi = (float) Math.PI * (modelData.fullAngles ? 2 : 1); - if (!modelData.fullAnimate) { - modelData.modelRotations[0] = modelData.rotationX * pi; - modelData.modelRotations[1] = modelData.rotationY * pi; - modelData.modelRotations[2] = modelData.rotationZ * pi; - } else if (modelData.modelRotPartialTicks != ClientEventHandler.partialRenderTick) { - modelData.modelRotPartialTicks = ClientEventHandler.partialRenderTick; - if (modelData.rotationX - modelData.modelRotations[0] != 0 && modelData.rotationEnabledX) { - modelData.modelRotations[0] = (modelData.rotationX - modelData.modelRotations[0]) * modelData.animRate / 10f + modelData.modelRotations[0]; - } else { - modelData.modelRotations[0] = modelData.rotationX; - } - - if (modelData.rotationY - modelData.modelRotations[1] != 0 && modelData.rotationEnabledY) { - modelData.modelRotations[1] = (modelData.rotationY - modelData.modelRotations[1]) * modelData.animRate / 10f + modelData.modelRotations[1]; - } else { - modelData.modelRotations[1] = modelData.rotationY; - } - - if (modelData.rotationZ - modelData.modelRotations[2] != 0 && modelData.rotationEnabledZ) { - modelData.modelRotations[2] = (modelData.rotationZ - modelData.modelRotations[2]) * modelData.animRate /10f + modelData.modelRotations[2]; - } else { - modelData.modelRotations[2] = modelData.rotationZ; } } } diff --git a/src/main/java/noppes/npcs/scripted/NpcAPI.java b/src/main/java/noppes/npcs/scripted/NpcAPI.java index 4c622a365..9455878f2 100644 --- a/src/main/java/noppes/npcs/scripted/NpcAPI.java +++ b/src/main/java/noppes/npcs/scripted/NpcAPI.java @@ -38,12 +38,19 @@ import noppes.npcs.api.entity.IEntity; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.gui.ICustomGui; import noppes.npcs.api.handler.*; +import noppes.npcs.api.handler.data.IAnimation; +import noppes.npcs.api.handler.data.IFrame; +import noppes.npcs.api.handler.data.IFramePart; import noppes.npcs.api.handler.data.ISound; import noppes.npcs.api.item.IItemStack; import noppes.npcs.api.overlay.ICustomOverlay; import noppes.npcs.config.ConfigScript; +import noppes.npcs.constants.EnumAnimationPart; import noppes.npcs.containers.ContainerNpcInterface; import noppes.npcs.controllers.*; +import noppes.npcs.controllers.data.Animation; +import noppes.npcs.controllers.data.Frame; +import noppes.npcs.controllers.data.FramePart; import noppes.npcs.controllers.data.SkinOverlay; import noppes.npcs.entity.EntityCustomNpc; import noppes.npcs.entity.EntityNPCInterface; @@ -559,4 +566,69 @@ public class NpcAPI extends AbstractNpcAPI { public String ticksToTime(long ticks) { return this.millisToTime(ticks * 50); } + + public IAnimation createAnimation(String name) { + return new Animation(name); + } + + public IFrame createFrame(int duration) { + return new Frame(duration); + } + + public IFrame createFrame(int duration, float speed, byte smooth) { + return new Frame(duration,speed,smooth); + } + + public IFramePart createPart(String name) { + try { + return new FramePart(EnumAnimationPart.valueOf(name)); + } catch (IllegalArgumentException ignored) { + throw new CustomNPCsException("Invalid frame part name: " + name); + } + } + + public IFramePart createPart(String name, int[] rotation, int[] pivot) { + if (rotation.length != 3 || pivot.length != 3) { + throw new CustomNPCsException("Rotation and pivot arrays for frame parts must have a length of 3."); + } + + FramePart part = (FramePart) this.createPart(name); + part.setRotations(rotation); + part.setPivots(pivot); + return part; + } + + public IFramePart createPart(String name, int[] rotation, int[] pivot, float speed, byte smooth) { + FramePart part = (FramePart) this.createPart(name,rotation,pivot); + part.setSpeed(speed); + part.setSmooth(smooth); + return part; + } + + public IFramePart createPart(int partId) { + for (EnumAnimationPart part : EnumAnimationPart.values()) { + if (part.id == partId) { + return new FramePart(part); + } + } + throw new CustomNPCsException("Invalid frame part ID: " + partId); + } + + public IFramePart createPart(int partId, int[] rotation, int[] pivot) { + if (rotation.length != 3 || pivot.length != 3) { + throw new CustomNPCsException("Rotation and pivot arrays for frame parts must have a length of 3."); + } + + FramePart part = (FramePart) this.createPart(partId); + part.setRotations(rotation); + part.setPivots(pivot); + return part; + } + + public IFramePart createPart(int partId, int[] rotation, int[] pivot, float speed, byte smooth) { + FramePart part = (FramePart) this.createPart(partId,rotation,pivot); + part.setSpeed(speed); + part.setSmooth(smooth); + return part; + } } diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java index f58e1d1a1..8d10ff3e6 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptNpc.java @@ -8,10 +8,10 @@ import noppes.npcs.api.entity.ICustomNpc; import noppes.npcs.api.entity.IEntityLivingBase; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.handler.IOverlayHandler; +import noppes.npcs.api.handler.data.IAnimationData; import noppes.npcs.api.handler.data.IFaction; import noppes.npcs.api.item.IItemStack; import noppes.npcs.api.jobs.IJob; -import noppes.npcs.api.jobs.IJobPuppet; import noppes.npcs.api.roles.IRole; import noppes.npcs.config.ConfigMain; import noppes.npcs.constants.*; @@ -340,8 +340,8 @@ public class ScriptNpc extends ScriptLiving imp npc.reset(); } - public IJobPuppet getModelData() { - return new ScriptJobPuppet(npc); + public IAnimationData getAnimationData() { + return this.npc.display.animationData; } /** diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java b/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java index 1dac3368a..3e960a4a1 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptPlayer.java @@ -19,6 +19,7 @@ import noppes.npcs.api.entity.IEntity; import noppes.npcs.api.entity.IPlayer; import noppes.npcs.api.gui.ICustomGui; import noppes.npcs.api.handler.IOverlayHandler; +import noppes.npcs.api.handler.data.IAnimationData; import noppes.npcs.api.handler.data.IDialog; import noppes.npcs.api.handler.data.IQuest; import noppes.npcs.api.handler.data.ISound; @@ -760,6 +761,10 @@ public class ScriptPlayer extends ScriptLivingBase return this.getData().skinOverlays; } + public IAnimationData getAnimationData() { + return this.getData().animationData; + } + public IQuest[] getFinishedQuests() { PlayerQuestData data = this.getData().questData; List quests = new ArrayList(); diff --git a/src/main/java/noppes/npcs/scripted/roles/ScriptJobPuppet.java b/src/main/java/noppes/npcs/scripted/roles/ScriptJobPuppet.java deleted file mode 100644 index a30047f46..000000000 --- a/src/main/java/noppes/npcs/scripted/roles/ScriptJobPuppet.java +++ /dev/null @@ -1,143 +0,0 @@ -package noppes.npcs.scripted.roles; - -import noppes.npcs.AnimationData; -import noppes.npcs.api.handler.data.IModelPart; -import noppes.npcs.api.jobs.IJobPuppet; -import noppes.npcs.entity.EntityNPCInterface; -import noppes.npcs.scripted.constants.JobType; - -public class ScriptJobPuppet extends ScriptJobInterface implements IJobPuppet { - private AnimationData job; - public ScriptJobPuppet(EntityNPCInterface npc){ - super(npc); - this.job = npc.display.animationData; - } - - public void setEnabled(boolean enabled) { - this.job.allowAnimation = enabled; - } - - public boolean enabled() { - return this.job.allowAnimation; - } - - public IModelPart getPart(int part) { - switch (part) { - case 0: - return job.head; - case 1: - return job.body; - case 2: - return job.larm; - case 3: - return job.rarm; - case 4: - return job.lleg; - case 5: - return job.rleg; - } - return null; - } - - public void allEnabled(boolean enabled) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setEnabled(enabled); - } - } - - public void allAnimated(boolean animated) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setAnimated(animated); - } - } - - public void allInterpolated(boolean interpolate) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setInterpolated(interpolate); - } - } - - public void allFullAngles(boolean fullAngles) { - for (int i = 0; i < 6; i++) { - this.getPart(i).setFullAngles(fullAngles); - } - } - - public void allAnimRate(float animRate) { - if (animRate < 0) - animRate = 0; - for (int i = 0; i < 6; i++) { - this.getPart(i).setAnimRate(animRate); - } - } - - public void doWhileStanding(boolean whileStanding) { - this.job.whileStanding = whileStanding; - } - - public boolean doWhileStanding() { - return this.job.whileStanding; - } - - public void doWhileAttacking(boolean whileAttacking) { - this.job.whileAttacking = whileAttacking; - } - - public boolean doWhileAttacking() { - return this.job.whileAttacking; - } - - public void doWhileMoving(boolean whileMoving) { - this.job.whileMoving = whileMoving; - } - - public boolean doWhileMoving() { - return this.job.whileMoving; - } - - @Deprecated - public void setRotationX(int part, float rotation) { - this.getPart(part).setRotationX(rotation); - } - - @Deprecated - public void setRotationY(int part, float rotation) { - this.getPart(part).setRotationY(rotation); - } - - @Deprecated - public void setRotationZ(int part, float rotation) { - this.getPart(part).setRotationZ(rotation); - } - - @Deprecated - public float getRotationX(int part) { - return this.getPart(part).getRotationX(); - } - - @Deprecated - public float getRotationY(int part) { - return this.getPart(part).getRotationY(); - } - - @Deprecated - public float getRotationZ(int part) { - return this.getPart(part).getRotationZ(); - } - - @Deprecated - public boolean isEnabled(int part) { - return this.getPart(part).isEnabled(); - } - - @Deprecated - public void setEnabled(int part, boolean bo) { - this.getPart(part).setEnabled(bo); - } - - @Override - public int getType(){ - return JobType.PUPPET; - } - -}