diff --git a/src/main/java/noppes/npcs/AnimationData.java b/src/main/java/noppes/npcs/AnimationData.java index 719f5a34a..d7f9d7f97 100644 --- a/src/main/java/noppes/npcs/AnimationData.java +++ b/src/main/java/noppes/npcs/AnimationData.java @@ -5,11 +5,15 @@ 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.EnumAnimationPart; import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.controllers.data.Animation; +import noppes.npcs.controllers.data.FramePart; import noppes.npcs.controllers.data.PlayerData; import noppes.npcs.entity.EntityNPCInterface; +import java.util.HashMap; + public class AnimationData implements IAnimationData { //Server-side: DataDisplay, PlayerData //Client-side: DataDisplay, EntityPlayer @@ -18,6 +22,9 @@ public class AnimationData implements IAnimationData { public Animation animation; public boolean allowAnimation = false; + //client-sided use only + public HashMap originalPivots = new HashMap<>(); + public AnimationData(Object parent){ this.parent = parent; } diff --git a/src/main/java/noppes/npcs/client/ClientEventHandler.java b/src/main/java/noppes/npcs/client/ClientEventHandler.java index b1ac4a4c1..3a6db2a91 100644 --- a/src/main/java/noppes/npcs/client/ClientEventHandler.java +++ b/src/main/java/noppes/npcs/client/ClientEventHandler.java @@ -10,6 +10,7 @@ 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.constants.EnumAnimationPart; import noppes.npcs.controllers.data.Animation; import noppes.npcs.entity.EntityNPCInterface; @@ -25,6 +26,7 @@ public class ClientEventHandler { public static float partialRenderTick; public static EntityNPCInterface renderingNpc; public static EntityPlayer renderingPlayer; + public static HashMap partNames = new HashMap<>(); public static RendererLivingEntity renderer; @SubscribeEvent diff --git a/src/main/java/noppes/npcs/controllers/data/FramePart.java b/src/main/java/noppes/npcs/controllers/data/FramePart.java index eff2ec773..d9bddd31f 100644 --- a/src/main/java/noppes/npcs/controllers/data/FramePart.java +++ b/src/main/java/noppes/npcs/controllers/data/FramePart.java @@ -10,8 +10,8 @@ import noppes.npcs.constants.EnumAnimationPart; public class FramePart implements IFramePart { public EnumAnimationPart part; - public int[] rotation = {0, 0, 0}; - public int[] pivot = {0, 0, 0}; + public float[] rotation = {0, 0, 0}; + public float[] pivot = {0, 0, 0}; boolean customized = false; @@ -24,6 +24,8 @@ public class FramePart implements IFramePart { public float[] prevPivots = {0,0,0}; public float partialRotationTick; public float partialPivotTick; + public float[] originalRotations = {0,0,0}; + public float[] originalPivots = {0,0,0}; public FramePart(){} @@ -64,20 +66,20 @@ public class FramePart implements IFramePart { return this; } - public int[] getRotations() { + public float[] getRotations() { return rotation; } - public IFramePart setRotations(int[] rotation) { + public IFramePart setRotations(float[] rotation) { this.rotation = rotation; return this; } - public int[] getPivots() { + public float[] getPivots() { return pivot; } - public IFramePart setPivots(int[] pivot) { + public IFramePart setPivots(float[] pivot) { this.pivot = pivot; return this; } @@ -111,8 +113,12 @@ public class FramePart implements IFramePart { public void readFromNBT(NBTTagCompound compound){ part = EnumAnimationPart.valueOf(compound.getString("Part")); - rotation = compound.getIntArray("Rotation"); - pivot = compound.getIntArray("Pivot"); + for (int i = 0; i < 3; i++) { + rotation[0] = compound.getFloat("Rotation" + i); + } + for (int i = 0; i < 3; i++) { + pivot[0] = compound.getFloat("Pivot" + i); + } // Customized = TRUE if Speed or Smooth Exist if(compound.hasKey("Speed")){ @@ -128,8 +134,12 @@ public class FramePart implements IFramePart { public NBTTagCompound writeToNBT(){ NBTTagCompound compound = new NBTTagCompound(); compound.setString("Part", part.toString()); - compound.setIntArray("Rotation", rotation); - compound.setIntArray("Pivot", pivot); + for (int i = 0; i < 3; i++) { + compound.setFloat("Rotation" + i, rotation[i]); + } + for (int i = 0; i < 3; i++) { + compound.setFloat("Pivot" + i, rotation[i]); + } if(customized){ compound.setFloat("Speed", speed); diff --git a/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java index dc7a3d9c9..62efd9339 100644 --- a/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java +++ b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java @@ -3,6 +3,7 @@ package noppes.npcs.mixin; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelRenderer; import noppes.npcs.AnimationData; import noppes.npcs.client.Client; @@ -19,6 +20,7 @@ import java.lang.reflect.Field; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; @Mixin(value = ModelRenderer.class) public abstract class MixinModelRenderer { @@ -38,8 +40,6 @@ public abstract class MixinModelRenderer { @Shadow public List childModels; @Shadow abstract void compileDisplayList(float p_78788_1_); - HashMap partNames = new HashMap<>(); - /** * @author Someone * @reason Because we need it @@ -48,42 +48,6 @@ public abstract class MixinModelRenderer { @SideOnly(Side.CLIENT) public void render(float p_78785_1_) { - FramePart currentPart = null; - - if (partNames.isEmpty()) { - String[] headNames = new String[]{"field_78116_c","bipedHead","bipedHeadwear","head","Head","bipedHeadAll", - "bipedHeadg","bipedHeadt","bipedHeadgh","bipedHeadv","bipedHeadb","bipedHeadt2"}; - String[] bodyNames = new String[]{"field_78115_e","bipedBody","B1","body","UpperBody","Body1","BodyBase"}; - String[] larmNames = new String[]{"field_78113_g","bipedLeftArm","LA","leftarm","ArmL","Arm1L","ArmL1"}; - String[] rarmNames = new String[]{"field_78112_f","bipedRightArm","RA","rightarm","ArmR","Arm1R","ArmR1"}; - 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(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); - } - - 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) { - 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(); - } - } - if (!this.isHidden) { if (this.showModel) @@ -93,8 +57,69 @@ 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 (ClientEventHandler.renderingPlayer != null && Client.playerAnimations.containsKey(ClientEventHandler.renderingPlayer.getUniqueID())) { + AnimationData animData = Client.playerAnimations.get(ClientEventHandler.renderingPlayer.getUniqueID()); + EnumAnimationPart partType = this.getPlayerPartType((ModelRenderer) (Object) this); + if (partType != null && animData != null) { + if (animData.isActive()) { + Frame frame = (Frame) animData.animation.currentFrame(); + if (frame.frameParts.containsKey(partType)) { + FramePart part = frame.frameParts.get(partType); + if (!animData.originalPivots.containsKey(part.part)) { + FramePart originalPart = new FramePart(part.part); + originalPart.originalRotations = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + originalPart.originalPivots = new float[]{this.rotationPointX, this.rotationPointY, this.rotationPointZ}; + animData.originalPivots.put(part.part, originalPart); + } else { + this.rotateAngleX = animData.originalPivots.get(part.part).prevRotations[0]; + this.rotateAngleY = animData.originalPivots.get(part.part).prevRotations[1]; + this.rotateAngleZ = animData.originalPivots.get(part.part).prevRotations[2]; + } + FramePart originalPart = animData.originalPivots.get(part.part); + part.interpolateAngles(); + part.interpolateOffset(); + this.rotationPointX = originalPart.originalPivots[0] + part.prevPivots[0]; + this.rotationPointY = originalPart.originalPivots[1] + part.prevPivots[1]; + this.rotationPointZ = originalPart.originalPivots[2] + part.prevPivots[2]; + this.rotateAngleX = part.prevRotations[0]; + this.rotateAngleY = part.prevRotations[1]; + this.rotateAngleZ = part.prevRotations[2]; + animData.originalPivots.get(part.part).prevRotations = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + } + } else if (animData.originalPivots.containsKey(partType)) { + this.rotateAngleX = animData.originalPivots.get(partType).originalRotations[0]; + this.rotateAngleY = animData.originalPivots.get(partType).originalRotations[1]; + this.rotateAngleZ = animData.originalPivots.get(partType).originalRotations[2]; + this.rotationPointX = animData.originalPivots.get(partType).originalPivots[0]; + this.rotationPointY = animData.originalPivots.get(partType).originalPivots[1]; + this.rotationPointZ = animData.originalPivots.get(partType).originalPivots[2]; + animData.originalPivots.remove(partType); + } + } + } + + float prevPointX = this.rotationPointX; + float prevPointY = this.rotationPointY; + float prevPointZ = this.rotationPointZ; + float prevAngleX = this.rotateAngleX; + float prevAngleY = this.rotateAngleY; + float prevAngleZ = this.rotateAngleZ; + + FramePart currentPart = null; + AnimationData animData = null; + EnumAnimationPart partType = null; + if (ClientEventHandler.renderingNpc != null) { + animData = ClientEventHandler.renderingNpc.display.animationData; + partType = this.getPartType((ModelRenderer) (Object) this, ClientEventHandler.partNames); + } + if (partType != null && animData != null && animData.isActive()) { + Frame frame = (Frame) animData.animation.currentFrame(); + if (frame.frameParts.containsKey(partType)) { + currentPart = frame.frameParts.get(partType); + currentPart.interpolateOffset(); + currentPart.interpolateAngles(); + } + } if (currentPart != null) { this.rotationPointX += currentPart.prevPivots[0]; @@ -170,19 +195,56 @@ public abstract class MixinModelRenderer { GL11.glPopMatrix(); } - if (currentPart != null) { - this.rotationPointX = prevPivots[0]; - this.rotationPointY = prevPivots[1]; - this.rotationPointZ = prevPivots[2]; - this.rotateAngleX = prevRotations[0]; - this.rotateAngleY = prevRotations[1]; - this.rotateAngleZ = prevRotations[2]; - } + this.rotationPointX = prevPointX; + this.rotationPointY = prevPointY; + this.rotationPointZ = prevPointZ; + this.rotateAngleX = prevAngleX; + this.rotateAngleY = prevAngleY; + this.rotateAngleZ = prevAngleZ; } } } - public EnumAnimationPart getPartName(ModelRenderer renderer, HashMap partNames) { + public EnumAnimationPart getPlayerPartType(ModelRenderer renderer) { + if (renderer == ((ModelBiped) renderer.baseModel).bipedHead + || renderer == ((ModelBiped) renderer.baseModel).bipedHeadwear) { + return EnumAnimationPart.HEAD; + } + if (renderer == ((ModelBiped) renderer.baseModel).bipedBody) { + return EnumAnimationPart.BODY; + } + if (renderer == ((ModelBiped) renderer.baseModel).bipedRightArm) { + return EnumAnimationPart.RIGHT_ARM; + } + if (renderer == ((ModelBiped) renderer.baseModel).bipedLeftArm) { + return EnumAnimationPart.LEFT_ARM; + } + if (renderer == ((ModelBiped) renderer.baseModel).bipedRightLeg) { + return EnumAnimationPart.RIGHT_LEG; + } + if (renderer == ((ModelBiped) renderer.baseModel).bipedLeftLeg) { + return EnumAnimationPart.LEFT_LEG; + } + + try { + Class ModelBipedBody = Class.forName("JinRyuu.JRMCore.entity.ModelBipedBody"); + Object m = renderer.baseModel; + Set> entrySet = ClientEventHandler.partNames.entrySet(); + for (Map.Entry entry : entrySet) { + for (String s : entry.getValue()) { + try { + if (renderer == ModelBipedBody.getField(s).get(m)) { + return entry.getKey(); + } + } catch (NoSuchFieldException | SecurityException | IllegalAccessException ignored) {} + } + } + } catch (ClassNotFoundException ignored) {} + + return null; + } + + public EnumAnimationPart getPartType(ModelRenderer renderer, HashMap partNames) { Class RenderClass = renderer.baseModel.getClass(); Object model = renderer.baseModel; EnumAnimationPart type = null; diff --git a/src/main/java/noppes/npcs/scripted/NpcAPI.java b/src/main/java/noppes/npcs/scripted/NpcAPI.java index 9455878f2..35747b202 100644 --- a/src/main/java/noppes/npcs/scripted/NpcAPI.java +++ b/src/main/java/noppes/npcs/scripted/NpcAPI.java @@ -587,7 +587,7 @@ public class NpcAPI extends AbstractNpcAPI { } } - public IFramePart createPart(String name, int[] rotation, int[] pivot) { + public IFramePart createPart(String name, float[] rotation, float[] pivot) { if (rotation.length != 3 || pivot.length != 3) { throw new CustomNPCsException("Rotation and pivot arrays for frame parts must have a length of 3."); } @@ -598,7 +598,7 @@ public class NpcAPI extends AbstractNpcAPI { return part; } - public IFramePart createPart(String name, int[] rotation, int[] pivot, float speed, byte smooth) { + public IFramePart createPart(String name, float[] rotation, float[] pivot, float speed, byte smooth) { FramePart part = (FramePart) this.createPart(name,rotation,pivot); part.setSpeed(speed); part.setSmooth(smooth); @@ -614,7 +614,7 @@ public class NpcAPI extends AbstractNpcAPI { throw new CustomNPCsException("Invalid frame part ID: " + partId); } - public IFramePart createPart(int partId, int[] rotation, int[] pivot) { + public IFramePart createPart(int partId, float[] rotation, float[] pivot) { if (rotation.length != 3 || pivot.length != 3) { throw new CustomNPCsException("Rotation and pivot arrays for frame parts must have a length of 3."); } @@ -625,7 +625,7 @@ public class NpcAPI extends AbstractNpcAPI { return part; } - public IFramePart createPart(int partId, int[] rotation, int[] pivot, float speed, byte smooth) { + public IFramePart createPart(int partId, float[] rotation, float[] pivot, float speed, byte smooth) { FramePart part = (FramePart) this.createPart(partId,rotation,pivot); part.setSpeed(speed); part.setSmooth(smooth);