diff --git a/src/main/java/noppes/npcs/client/Client.java b/src/main/java/noppes/npcs/client/Client.java index d79da20e5..4db4d343c 100644 --- a/src/main/java/noppes/npcs/client/Client.java +++ b/src/main/java/noppes/npcs/client/Client.java @@ -14,12 +14,14 @@ import noppes.npcs.client.gui.OverlayQuestTracking; import noppes.npcs.client.gui.customoverlay.OverlayCustom; import noppes.npcs.constants.EnumPacketServer; import cpw.mods.fml.common.network.internal.FMLProxyPacket; +import noppes.npcs.controllers.data.PlayerModelData; import noppes.npcs.controllers.data.SkinOverlay; 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 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 4c3a01f7e..eeb4727c7 100644 --- a/src/main/java/noppes/npcs/client/ClientEventHandler.java +++ b/src/main/java/noppes/npcs/client/ClientEventHandler.java @@ -3,13 +3,14 @@ package noppes.npcs.client; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.RenderPlayer; import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.client.event.MouseEvent; -import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderHandEvent; -import net.minecraftforge.client.event.RenderPlayerEvent; +import net.minecraftforge.client.event.*; import noppes.npcs.client.gui.customoverlay.OverlayCustom; import noppes.npcs.client.renderer.RenderCNPCPlayer; +import noppes.npcs.controllers.data.PlayerModelData; +import noppes.npcs.roles.JobPuppet; +import org.lwjgl.opengl.GL11; import java.util.ArrayList; import java.util.HashMap; @@ -20,6 +21,10 @@ public class ClientEventHandler { public static HashMap disabledButtonTimes = new HashMap<>(); public static float partialHandTicks; + public static float partialRenderTick; + public static EntityPlayer renderingPlayer; + public static RenderPlayer renderer; + @SubscribeEvent public void onMouse(MouseEvent event) { if (Minecraft.getMinecraft().currentScreen != null) @@ -55,9 +60,71 @@ public class ClientEventHandler { } } + public void setInterpolatedAngles(PlayerModelData modelData) { + float pi = (float) Math.PI * (modelData.fullAngles ? 2 : 1); + if (!modelData.animate) { + 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; + } + } + } + + @SubscribeEvent + public void onRenderPlayer(RenderPlayerEvent.Pre event) { + EntityPlayer player = event.entityPlayer; + ClientEventHandler.renderingPlayer = player; + ClientEventHandler.renderer = event.renderer; + ClientEventHandler.partialRenderTick = event.partialRenderTick; + + if (Client.playerModelData.containsKey(player.getUniqueID())) { + PlayerModelData data = Client.playerModelData.get(player.getUniqueID()); + if (data.enabled()) { + GL11.glPushMatrix(); + this.setInterpolatedAngles(data); + if (data.rotationEnabledX) { + GL11.glRotatef(data.modelRotations[0], 1, 0, 0); + } + if (data.rotationEnabledY) { + GL11.glRotatef(data.modelRotations[1], 0, 1, 0); + } + if (data.rotationEnabledZ) { + GL11.glRotatef(data.modelRotations[2], 0, 0, 1); + } + } + } + } + @SubscribeEvent public void onRenderPlayer(RenderPlayerEvent.Post event) { - if (hasOverlays(event.entityPlayer)) { + EntityPlayer player = event.entityPlayer; + if (Client.playerModelData.containsKey(player.getUniqueID())) { + PlayerModelData data = Client.playerModelData.get(player.getUniqueID()); + if (data.enabled()) { + GL11.glPopMatrix(); + } + } + ClientEventHandler.renderingPlayer = null; + + if (hasOverlays(player)) { try { Class renderPlayerJBRA = Class.forName("JinRyuu.JBRA.RenderPlayerJBRA"); if (renderPlayerJBRA.isInstance(event.renderer)) @@ -66,18 +133,18 @@ public class ClientEventHandler { if (!(event.renderer instanceof RenderCNPCPlayer)) { renderCNPCPlayer.tempRenderPartialTicks = event.partialRenderTick; - double d0 = event.entityPlayer.lastTickPosX + (event.entityPlayer.posX - event.entityPlayer.lastTickPosX) * (double) event.partialRenderTick - RenderManager.renderPosX; - double d1 = event.entityPlayer.lastTickPosY + (event.entityPlayer.posY - event.entityPlayer.lastTickPosY) * (double) event.partialRenderTick - RenderManager.renderPosY; - double d2 = event.entityPlayer.lastTickPosZ + (event.entityPlayer.posZ - event.entityPlayer.lastTickPosZ) * (double) event.partialRenderTick - RenderManager.renderPosZ; - float f1 = event.entityPlayer.prevRotationYaw + (event.entityPlayer.rotationYaw - event.entityPlayer.prevRotationYaw) * event.partialRenderTick; + double d0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double) event.partialRenderTick - RenderManager.renderPosX; + double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) event.partialRenderTick - RenderManager.renderPosY; + double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) event.partialRenderTick - RenderManager.renderPosZ; + float f1 = player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw) * event.partialRenderTick; - if (Minecraft.getMinecraft().thePlayer.equals(event.entityPlayer)) { + if (Minecraft.getMinecraft().thePlayer.equals(player)) { d0 = 0; d1 = 0; d2 = 0; } - renderCNPCPlayer.doRender(event.entityPlayer, d0, d1, d2, f1, event.partialRenderTick); + renderCNPCPlayer.doRender(player, d0, d1, d2, f1, event.partialRenderTick); } } } diff --git a/src/main/java/noppes/npcs/client/NoppesUtil.java b/src/main/java/noppes/npcs/client/NoppesUtil.java index 7d1b4c1b5..2f07a5026 100644 --- a/src/main/java/noppes/npcs/client/NoppesUtil.java +++ b/src/main/java/noppes/npcs/client/NoppesUtil.java @@ -35,6 +35,7 @@ import noppes.npcs.constants.EnumPacketServer; import noppes.npcs.constants.EnumPlayerPacket; import noppes.npcs.controllers.data.Dialog; import noppes.npcs.controllers.DialogController; +import noppes.npcs.controllers.data.PlayerModelData; import noppes.npcs.controllers.data.Quest; import noppes.npcs.controllers.data.SkinOverlay; import noppes.npcs.entity.EntityNPCInterface; @@ -85,6 +86,19 @@ public class NoppesUtil { Client.skinOverlays.put(player.getUniqueID(), skinOverlays); } + public static void updatePlayerModelData(EntityPlayer player, NBTTagCompound compound) { + PlayerModelData data; + if (!Client.playerModelData.containsKey(player.getUniqueID())) { + data = new PlayerModelData(player); + 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 b3c1d2627..55484e3ff 100644 --- a/src/main/java/noppes/npcs/client/PacketHandlerClient.java +++ b/src/main/java/noppes/npcs/client/PacketHandlerClient.java @@ -292,6 +292,13 @@ 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)); + NBTTagCompound compound = Server.readNBT(buffer); + if (sendingPlayer != null) { + NoppesUtil.updatePlayerModelData(sendingPlayer, compound); + } + } else if(type == EnumPacketClient.DISABLE_MOUSE_INPUT) { long length = buffer.readLong(); try { diff --git a/src/main/java/noppes/npcs/constants/EnumPacketClient.java b/src/main/java/noppes/npcs/constants/EnumPacketClient.java index 1f6d16c59..7cf806707 100644 --- a/src/main/java/noppes/npcs/constants/EnumPacketClient.java +++ b/src/main/java/noppes/npcs/constants/EnumPacketClient.java @@ -39,6 +39,7 @@ public enum EnumPacketClient { SWING_PLAYER_ARM, UPDATE_ITEM, PLAYER_UPDATE_SKIN_OVERLAYS, + PLAYER_UPDATE_MODEL_DATA, OVERLAY_QUEST_TRACKING, DISABLE_MOUSE_INPUT, PLAY_SOUND_TO, diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerData.java b/src/main/java/noppes/npcs/controllers/data/PlayerData.java index 041f24fe2..2c87b7f61 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerData.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerData.java @@ -31,6 +31,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 PlayerModelData modelData = new PlayerModelData(this); public DataTimers timers = new DataTimers(this); public DataSkinOverlays skinOverlays = new DataSkinOverlays(this); @@ -80,6 +81,7 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { mailData.loadNBTData(data); timers.readFromNBT(data); skinOverlays.readFromNBT(data); + modelData.readFromNBT(data); if(player != null){ playername = player.getCommandSenderName(); @@ -117,6 +119,7 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { mailData.saveNBTData(compound); timers.writeToNBT(compound); skinOverlays.writeToNBT(compound); + modelData.writeToNBT(compound); compound.setString("PlayerName", playername); compound.setString("UUID", uuid); @@ -298,6 +301,10 @@ 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/controllers/data/PlayerModelData.java b/src/main/java/noppes/npcs/controllers/data/PlayerModelData.java new file mode 100644 index 000000000..45caeae11 --- /dev/null +++ b/src/main/java/noppes/npcs/controllers/data/PlayerModelData.java @@ -0,0 +1,499 @@ +package noppes.npcs.controllers.data; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import noppes.npcs.Server; +import noppes.npcs.api.handler.IPlayerModelData; +import noppes.npcs.constants.EnumPacketClient; +import noppes.npcs.roles.JobPuppet; + +public class PlayerModelData implements IPlayerModelData { + public PlayerData parent; + public final EntityPlayer player; + + public JobPuppet.PartConfig head = new JobPuppet.PartConfig(); + public JobPuppet.PartConfig larm = new JobPuppet.PartConfig(); + public JobPuppet.PartConfig rarm = new JobPuppet.PartConfig(); + public JobPuppet.PartConfig body = new JobPuppet.PartConfig(); + public JobPuppet.PartConfig lleg = new JobPuppet.PartConfig(); + public JobPuppet.PartConfig rleg = new JobPuppet.PartConfig(); + + public boolean enabled = false; + public boolean whileStanding = true; + public boolean whileAttacking = false; + public boolean whileMoving = false; + public boolean fullAngles = false; + + public float rotationX, rotationY, rotationZ; + public boolean rotationEnabledX, rotationEnabledY, rotationEnabledZ; + + public boolean animate = false; + public float animRate = 1.0F; + + //Client-sided use + public float modelRotPartialTicks; + public float[] modelRotations = {0,0,0}; + + public float[] bipedRotsHead = {0,0,0}; + public float[] bipedRotsBody = {0,0,0}; + public float[] bipedRotsLeftArm = {0,0,0}; + public float[] bipedRotsRightArm = {0,0,0}; + public float[] bipedRotsLeftLeg = {0,0,0}; + public float[] bipedRotsRightLeg = {0,0,0}; + + public PlayerModelData(PlayerData parent) { + this.parent = parent; + this.player = parent.player; + } + + public PlayerModelData(EntityPlayer player) { + this.player = player; + } + + public void updateClient() { + Server.sendToAll(EnumPacketClient.PLAYER_UPDATE_MODEL_DATA, ((PlayerData) parent).player.getCommandSenderName(), this.writeToNBT(new NBTTagCompound())); + } + + public NBTTagCompound writeToNBT(NBTTagCompound compound) { + 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()); + + compound.setBoolean("PuppetEnabled", enabled); + compound.setBoolean("PuppetStanding", whileStanding); + compound.setBoolean("PuppetAttacking", whileAttacking); + compound.setBoolean("PuppetMoving", whileMoving); + compound.setBoolean("PuppetFullAngles", fullAngles); + + 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("PuppetAnimate", animate); + compound.setFloat("PuppetAnimSpeed", animRate); + return compound; + } + + public void readFromNBT(NBTTagCompound compound) { + 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")); + + enabled = compound.getBoolean("PuppetEnabled"); + whileStanding = compound.getBoolean("PuppetStanding"); + whileAttacking = compound.getBoolean("PuppetAttacking"); + whileMoving = compound.getBoolean("PuppetMoving"); + fullAngles = compound.getBoolean("PuppetFullAngles"); + + rotationX = compound.getFloat("PuppetRotationX"); + rotationY = compound.getFloat("PuppetRotationY"); + rotationZ = compound.getFloat("PuppetRotationZ"); + rotationEnabledX = compound.getBoolean("PuppetRotationEnabledX"); + rotationEnabledY = compound.getBoolean("PuppetRotationEnabledY"); + rotationEnabledZ = compound.getBoolean("PuppetRotationEnabledZ"); + + animate = compound.getBoolean("PuppetAnimate"); + animRate = compound.getFloat("PuppetAnimSpeed"); + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean enabled() { + return this.enabled; + } + + public void setAnimated(boolean animated) { + this.animate = animated; + } + + public boolean isAnimated() { + return this.animate; + } + + public void setFullAngles(boolean limit) { + fullAngles = limit; + } + + public boolean fullAngles() { + return fullAngles; + } + + public void setAnimRate(float animRate) { + this.animRate = animRate; + } + + public float getAnimRate() { + return this.animRate; + } + + public void doWhileStanding(boolean whileStanding) { + this.whileStanding = whileStanding; + } + + public boolean doWhileStanding() { + return this.whileStanding; + } + + public void doWhileAttacking(boolean whileAttacking) { + this.whileAttacking = whileAttacking; + } + + public boolean doWhileAttacking() { + return this.whileAttacking; + } + + public void doWhileMoving(boolean whileMoving) { + this.whileMoving = whileMoving; + } + + public boolean doWhileMoving() { + return this.whileMoving; + } + + 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 setRotation(int part, float rotationX, float rotationY, float rotationZ) { + this.setRotationX(part,rotationX); + this.setRotationY(part,rotationY); + this.setRotationZ(part,rotationZ); + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @param rotation Rotation the of the body part + */ + public void setRotationX(int part, float rotation){ + float f = rotation / 360f - 0.5f; + + if(part == 0) + head.rotationX = f; + if(part == 1) + body.rotationX = f; + if(part == 2) + larm.rotationX = f; + if(part == 3) + rarm.rotationX = f; + if(part == 4) + lleg.rotationX = f; + if(part == 5) + rleg.rotationX = f; + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @param rotation Rotation the of the body part + */ + public void setRotationY(int part, float rotation){ + float f = rotation / 360f - 0.5f; + + if(part == 0) + head.rotationY = f; + if(part == 1) + body.rotationY = f; + if(part == 2) + larm.rotationY = f; + if(part == 3) + rarm.rotationY = f; + if(part == 4) + lleg.rotationY = f; + if(part == 5) + rleg.rotationY = f; + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @param rotation Rotation the of the body part + */ + public void setRotationZ(int part, float rotation){ + float f = rotation / 360f - 0.5f; + + if(part == 0) + head.rotationZ = f; + if(part == 1) + body.rotationZ = f; + if(part == 2) + larm.rotationZ = f; + if(part == 3) + rarm.rotationZ = f; + if(part == 4) + lleg.rotationZ = f; + if(part == 5) + rleg.rotationZ = f; + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @return Returns X rotation in degrees (0-360) + */ + public float getRotationX(int part){ + if(part == 0) + return head.rotationX; + if(part == 1) + return body.rotationX; + if(part == 2) + return larm.rotationX; + if(part == 3) + return rarm.rotationX; + if(part == 4) + return lleg.rotationX; + if(part == 5) + return rleg.rotationX; + return 0; + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @return Returns Y rotation in degrees (0-360) + */ + public float getRotationY(int part){ + if(part == 0) + return head.rotationY; + if(part == 1) + return body.rotationY; + if(part == 2) + return larm.rotationY; + if(part == 3) + return rarm.rotationY; + if(part == 4) + return lleg.rotationY; + if(part == 5) + return rleg.rotationY; + return 0; + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @return Returns Z rotation in degrees (0-360) + */ + public float getRotationZ(int part){ + if(part == 0) + return head.rotationZ; + if(part == 1) + return body.rotationZ; + if(part == 2) + return larm.rotationZ; + if(part == 3) + return rarm.rotationZ; + if(part == 4) + return lleg.rotationZ; + if(part == 5) + return rleg.rotationZ; + return 0; + } + + public void setOffset(int part, float offsetX, float offsetY, float offsetZ) { + this.setOffsetX(part,offsetX); + this.setOffsetY(part,offsetY); + this.setOffsetZ(part,offsetZ); + } + + public void setOffsetX(int part, float offset) { + if(part == 0) + head.pivotX = offset; + if(part == 1) + body.pivotX = offset; + if(part == 2) + larm.pivotX = offset; + if(part == 3) + rarm.pivotX = offset; + if(part == 4) + lleg.pivotX = offset; + if(part == 5) + rleg.pivotX = offset; + } + + public void setOffsetY(int part, float offset) { + if(part == 0) + head.pivotY = offset; + if(part == 1) + body.pivotY = offset; + if(part == 2) + larm.pivotY = offset; + if(part == 3) + rarm.pivotY = offset; + if(part == 4) + lleg.pivotY = offset; + if(part == 5) + rleg.pivotY = offset; + } + + public void setOffsetZ(int part, float offset) { + if(part == 0) + head.pivotZ = offset; + if(part == 1) + body.pivotZ = offset; + if(part == 2) + larm.pivotZ = offset; + if(part == 3) + rarm.pivotZ = offset; + if(part == 4) + lleg.pivotZ = offset; + if(part == 5) + rleg.pivotZ = offset; + } + + public float getOffsetX(int part) { + if(part == 0) + return head.pivotX; + if(part == 1) + return body.pivotX; + if(part == 2) + return larm.pivotX; + if(part == 3) + return rarm.pivotX; + if(part == 4) + return lleg.pivotX; + if(part == 5) + return rleg.pivotX; + return 0; + } + + public float getOffsetY(int part) { + if(part == 0) + return head.pivotY; + if(part == 1) + return body.pivotY; + if(part == 2) + return larm.pivotY; + if(part == 3) + return rarm.pivotY; + if(part == 4) + return lleg.pivotY; + if(part == 5) + return rleg.pivotY; + return 0; + } + + public float getOffsetZ(int part) { + if(part == 0) + return head.pivotZ; + if(part == 1) + return body.pivotZ; + if(part == 2) + return larm.pivotZ; + if(part == 3) + return rarm.pivotZ; + if(part == 4) + return lleg.pivotZ; + if(part == 5) + return rleg.pivotZ; + return 0; + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @return Returns whether or not the body part is enabled + */ + public boolean isEnabled(int part){ + if(part == 0) + return !head.disabled; + if(part == 1) + return !body.disabled; + if(part == 2) + return !larm.disabled; + if(part == 3) + return !rarm.disabled; + if(part == 4) + return !lleg.disabled; + if(part == 5) + return !rleg.disabled; + + return false; + } + + /** + * @since 1.7.10c + * @param part Body part (0:head, 1:body, 2:leftarm, 3:rightarm, 4:leftleg, 5:rightleg) + * @param bo Whether or not the body part is enabled + */ + public void setEnabled(int part, boolean bo){ + if(part == 0) + head.disabled = !bo; + if(part == 1) + body.disabled = !bo; + if(part == 2) + larm.disabled = !bo; + if(part == 3) + rarm.disabled = !bo; + if(part == 4) + lleg.disabled = !bo; + if(part == 5) + rleg.disabled = !bo; + } +} diff --git a/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java b/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java index 630444f5c..acd185268 100644 --- a/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java +++ b/src/main/java/noppes/npcs/mixin/CustomNPCsMixinPlugin.java @@ -36,6 +36,7 @@ public class CustomNPCsMixinPlugin implements IMixinConfigPlugin { if (CustomNpcs.EntityRendererMixin){ mixins.add("MixinEntityRenderer"); } + mixins.add("MixinModelRenderer"); return mixins; } diff --git a/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java new file mode 100644 index 000000000..59aa152e5 --- /dev/null +++ b/src/main/java/noppes/npcs/mixin/MixinModelRenderer.java @@ -0,0 +1,236 @@ +package noppes.npcs.mixin; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.util.MathHelper; +import noppes.npcs.client.Client; +import noppes.npcs.client.ClientEventHandler; +import noppes.npcs.controllers.data.PlayerModelData; +import noppes.npcs.roles.JobPuppet; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.HashMap; + +@Mixin(value = ModelRenderer.class) +public class MixinModelRenderer { + @Shadow public float rotationPointX; + @Shadow public float rotationPointY; + @Shadow public float rotationPointZ; + @Shadow public float rotateAngleX; + @Shadow public float rotateAngleY; + @Shadow public float rotateAngleZ; + + HashMap partNames = new HashMap<>(); + String partName = ""; + + @SideOnly(Side.CLIENT) + @Inject(method = "render", at = @At(value = "HEAD")) + private void puppetRotations(float p_78785_1_, CallbackInfo callbackInfo) + { + if (ClientEventHandler.renderingPlayer == null) { + return; + } + + if (!Client.playerModelData.containsKey(ClientEventHandler.renderingPlayer.getUniqueID())) { + return; + } + + this.partName = this.getPartName((ModelRenderer)(Object)this); + PlayerModelData modelData = Client.playerModelData.get(ClientEventHandler.renderingPlayer.getUniqueID()); + this.setModelParts(modelData); + if (modelData.enabled) { + if(isPart(modelData.head)){ + this.rotateAngleX = modelData.bipedRotsHead[0]; + this.rotateAngleY = modelData.bipedRotsHead[1]; + this.rotateAngleZ = modelData.bipedRotsHead[2]; + this.setInterpolatedAngles(modelData,modelData.head); + } + + if(isPart(modelData.body)){ + this.rotateAngleX = modelData.bipedRotsBody[0]; + this.rotateAngleY = modelData.bipedRotsBody[1]; + this.rotateAngleZ = modelData.bipedRotsBody[2]; + this.setInterpolatedAngles(modelData,modelData.body); + } + + if(isPart(modelData.larm)){ + this.rotateAngleX = modelData.bipedRotsLeftArm[0]; + this.rotateAngleY = modelData.bipedRotsLeftArm[1]; + this.rotateAngleZ = modelData.bipedRotsLeftArm[2]; + this.setInterpolatedAngles(modelData,modelData.larm); + } + + if(isPart(modelData.rarm)){ + this.rotateAngleX = modelData.bipedRotsRightArm[0]; + this.rotateAngleY = modelData.bipedRotsRightArm[1]; + this.rotateAngleZ = modelData.bipedRotsRightArm[2]; + this.setInterpolatedAngles(modelData,modelData.rarm); + } + + if(isPart(modelData.lleg)){ + this.rotateAngleX = modelData.bipedRotsLeftLeg[0]; + this.rotateAngleY = modelData.bipedRotsLeftLeg[1]; + this.rotateAngleZ = modelData.bipedRotsLeftLeg[2]; + this.setInterpolatedAngles(modelData,modelData.lleg); + } + + if(isPart(modelData.rleg)){ + this.rotateAngleX = modelData.bipedRotsRightLeg[0]; + this.rotateAngleY = modelData.bipedRotsRightLeg[1]; + this.rotateAngleZ = modelData.bipedRotsRightLeg[2]; + this.setInterpolatedAngles(modelData,modelData.rleg); + } + + if(isPart(modelData.head)){ + this.addInterpolatedOffset(modelData, modelData.head); + } + if(isPart(modelData.body)){ + this.addInterpolatedOffset(modelData, modelData.body); + } + if(isPart(modelData.larm)){ + this.addInterpolatedOffset(modelData, modelData.larm); + } + if(isPart(modelData.rarm)){ + this.addInterpolatedOffset(modelData, modelData.rarm); + } + if(isPart(modelData.lleg)){ + this.addInterpolatedOffset(modelData, modelData.lleg); + } + if(isPart(modelData.rleg)){ + this.addInterpolatedOffset(modelData, modelData.rleg); + } + + if(isPart(modelData.head)) { + modelData.bipedRotsHead = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + } + if(isPart(modelData.body)) { + modelData.bipedRotsBody = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + } + if(isPart(modelData.larm)) { + modelData.bipedRotsLeftArm = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + } + if(isPart(modelData.rarm)) { + modelData.bipedRotsRightArm = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + } + if(isPart(modelData.lleg)) { + modelData.bipedRotsLeftLeg = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + } + if(isPart(modelData.rleg)) { + modelData.bipedRotsRightLeg = new float[]{this.rotateAngleX, this.rotateAngleY, this.rotateAngleZ}; + } + } + } + + public String getPartName(ModelRenderer renderer) { + if (renderer == ((ModelBiped) ((ModelRenderer)renderer).baseModel).bipedHead + || renderer == ((ModelBiped) ((ModelRenderer)renderer).baseModel).bipedHeadwear) { + return "head"; + } + if (renderer == ((ModelBiped) ((ModelRenderer)renderer).baseModel).bipedBody) { + return "body"; + } + if (renderer == ((ModelBiped) ((ModelRenderer)renderer).baseModel).bipedRightArm) { + return "rarm"; + } + if (renderer == ((ModelBiped) ((ModelRenderer)renderer).baseModel).bipedLeftArm) { + return "larm"; + } + if (renderer == ((ModelBiped) ((ModelRenderer)renderer).baseModel).bipedRightLeg) { + return "rleg"; + } + if (renderer == ((ModelBiped) ((ModelRenderer)renderer).baseModel).bipedLeftLeg) { + return "lleg"; + } + + try { + Class ModelBipedBody = Class.forName("JinRyuu.JRMCore.entity.ModelBipedBody"); + Object m = renderer.baseModel; + + if (renderer == (ModelRenderer) ModelBipedBody.getField("bipedHeadwear").get(m) + || renderer == (ModelRenderer) ModelBipedBody.getField("bipedHead").get(m)) { + return "head"; + } + if (renderer == (ModelRenderer) ModelBipedBody.getField("B1").get(m) + || renderer == (ModelRenderer) ModelBipedBody.getField("bipedBody").get(m)) { + return "body"; + } + if (renderer == (ModelRenderer) ModelBipedBody.getField("RA").get(m) + || renderer == (ModelRenderer) ModelBipedBody.getField("bipedRightArm").get(m)) { + return "rarm"; + } + if (renderer == (ModelRenderer) ModelBipedBody.getField("LA").get(m) + || renderer == (ModelRenderer) ModelBipedBody.getField("bipedLeftArm").get(m)) { + return "larm"; + } + if (renderer == (ModelRenderer) ModelBipedBody.getField("RL").get(m) + || renderer == (ModelRenderer) ModelBipedBody.getField("bipedRightLeg").get(m)) { + return "rleg"; + } + if (renderer == (ModelRenderer) ModelBipedBody.getField("LL").get(m) + || renderer == (ModelRenderer) ModelBipedBody.getField("bipedLeftLeg").get(m)) { + return "lleg"; + } + } catch (Exception ignored) {} + + return ""; + } + + public boolean isPart(JobPuppet.PartConfig puppetPart) { + return !puppetPart.disabled && this.partName.equals(partNames.get(puppetPart)); + } + + public void setInterpolatedAngles(PlayerModelData modelData, JobPuppet.PartConfig puppetPart) { + float pi = (float) Math.PI * (modelData.fullAngles ? 2 : 1); + if (!modelData.animate) { + this.rotateAngleX = puppetPart.rotationX * pi; + this.rotateAngleY = puppetPart.rotationY * pi; + this.rotateAngleZ = puppetPart.rotationZ * pi; + } else if (puppetPart.partialRotationTick != ClientEventHandler.partialRenderTick) { + puppetPart.partialRotationTick = ClientEventHandler.partialRenderTick; + if (puppetPart.rotationX * pi - this.rotateAngleX != 0) + this.rotateAngleX = (puppetPart.rotationX * pi - this.rotateAngleX) * modelData.animRate /10f + this.rotateAngleX; + if (puppetPart.rotationY * pi - this.rotateAngleY != 0) + this.rotateAngleY = (puppetPart.rotationY * pi - this.rotateAngleY) * modelData.animRate /10f + this.rotateAngleY; + if (puppetPart.rotationZ * pi - this.rotateAngleZ != 0) + this.rotateAngleZ = (puppetPart.rotationZ * pi - this.rotateAngleZ) * modelData.animRate /10f + this.rotateAngleZ; + } + } + + public void addInterpolatedOffset(PlayerModelData modelData, JobPuppet.PartConfig puppetPart) { + if (!puppetPart.setOriginalPivot) { + puppetPart.setOriginalPivot = true; + puppetPart.originalPivotX = this.rotationPointX; + puppetPart.originalPivotY = this.rotationPointY; + puppetPart.originalPivotZ = this.rotationPointZ; + } + + if (!modelData.animate) { + this.rotationPointX = puppetPart.originalPivotX + puppetPart.pivotX; + this.rotationPointY = puppetPart.originalPivotY + puppetPart.pivotY; + this.rotationPointZ = puppetPart.originalPivotZ + puppetPart.pivotZ; + } else if (puppetPart.partialPivotTick != ClientEventHandler.partialRenderTick) { + puppetPart.partialPivotTick = ClientEventHandler.partialRenderTick; + puppetPart.destPivotX = (puppetPart.pivotX - puppetPart.destPivotX) * modelData.animRate /10f + puppetPart.destPivotX; + this.rotationPointX = puppetPart.originalPivotX + puppetPart.destPivotX; + puppetPart.destPivotY = (puppetPart.pivotY - puppetPart.destPivotY) * modelData.animRate /10f + puppetPart.destPivotY; + this.rotationPointY = puppetPart.originalPivotY + puppetPart.destPivotY; + puppetPart.destPivotZ = (puppetPart.pivotZ - puppetPart.destPivotZ) * modelData.animRate /10f + puppetPart.destPivotZ; + this.rotationPointZ = puppetPart.originalPivotZ + puppetPart.destPivotZ; + } + } + + public void setModelParts(PlayerModelData modelData) { + partNames.put(modelData.head,"head"); + partNames.put(modelData.body,"body"); + partNames.put(modelData.rarm,"rarm"); + partNames.put(modelData.larm,"larm"); + partNames.put(modelData.rleg,"rleg"); + partNames.put(modelData.lleg,"lleg"); + } +} diff --git a/src/main/java/noppes/npcs/roles/JobPuppet.java b/src/main/java/noppes/npcs/roles/JobPuppet.java index c7a180612..33026e6fa 100644 --- a/src/main/java/noppes/npcs/roles/JobPuppet.java +++ b/src/main/java/noppes/npcs/roles/JobPuppet.java @@ -101,7 +101,17 @@ public class JobPuppet extends JobInterface{ public float prevPivotX = 0f; public float prevPivotY = 0f; public float prevPivotZ = 0f; - + + public float partialRotationTick = 0f; + public float partialPivotTick = 0f; + public float destPivotX = 0f; + public float destPivotY = 0f; + public float destPivotZ = 0f; + public boolean setOriginalPivot = false; + public float originalPivotX = 0f; + public float originalPivotY = 0f; + public float originalPivotZ = 0f; + public boolean disabled = false; public NBTTagCompound writeNBT(){ diff --git a/src/main/resources/META-INF/customnpcs_at.cfg b/src/main/resources/META-INF/customnpcs_at.cfg index e34697ad4..aba827e00 100644 --- a/src/main/resources/META-INF/customnpcs_at.cfg +++ b/src/main/resources/META-INF/customnpcs_at.cfg @@ -1,2 +1,6 @@ +#RendererLivingEntity +public net.minecraft.client.renderer.entity.RendererLivingEntity field_77046_h # renderPassModel #EntityRenderer -public net.minecraft.client.renderer.EntityRenderer func_78476_b(FI)V # renderHand \ No newline at end of file +public net.minecraft.client.renderer.EntityRenderer func_78476_b(FI)V # renderHand +#ModelRenderer +public net.minecraft.client.model.ModelRenderer field_78810_s # baseModel \ No newline at end of file