/** Copyright (C) <2015> <coolAlias> This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such, you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package zeldaswordskills.client.model; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.MathHelper; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import zeldaswordskills.entity.mobs.EntityDarknut; /** * * @author Model concept by TheRedMajora, re-coded and animated by coolAlias * */ @SideOnly(Side.CLIENT) public class ModelDarknut extends ModelBase implements IModelBiped { private ModelRenderer head; private ModelRenderer body; private ModelRenderer leftArm; private ModelRenderer rightArm; private ModelRenderer rightLeg; private ModelRenderer leftLeg; private ModelRenderer shoulderPlateRight; private ModelRenderer shoulderPlateLeft; private ModelRenderer upperArmor; private ModelRenderer lowerArmor; private ModelRenderer helmRightPlate; private ModelRenderer helmTopPlate; private ModelRenderer helmBackPlate; private ModelRenderer helmLeftPlate; private ModelRenderer cheekGuardLeft; private ModelRenderer noseGuard; private ModelRenderer cheekGuardRight; private ModelRenderer helmVisor; private ModelRenderer hornHolderLeft; private ModelRenderer hornLeft; private ModelRenderer hornRight; private ModelRenderer hornHolderRight; private ModelRenderer cape; /** Whether the model should be rendered holding an item in the left hand, and if that item is a block. */ private int heldItemLeft; /** Whether the model should be rendered holding an item in the right hand, and if that item is a block. */ private int heldItemRight; /** Regular attack animation, right arm rotation Z */ private static final float[] attackRotZ = { 0.2F, 0.45F, 0.75F, 1.0F, 0.75F, 0.45F, 0.2F, 0.0F, -0.2F}; private static final float[] powRotXR = { -2.5F, -1.5F, -1.0F, -0.5F, -0.4F }; private static final float[] powRotYR = { 0F, -0.1F, -0.2F, -0.2F, -0.2F }; private static final float[] powRotZR = { 0F, 0F, 0F, -0.25F, -0.5F }; private static final float[] powRotXL = { -2.0F, -1.4F, -1.0F, -0.6F, -0.4F }; private static final float[] powRotYL = { 1.0F, 0.9F, 0.8F, 0.5F, 0.2F }; private static final float[] powRotZL = { 0.0F, 0.15F, 0.3F, 0.45F, 0.5F }; public ModelDarknut() { textureWidth = 64; textureHeight = 64; head = new ModelRenderer(this, 0, 0); head.setTextureSize(textureWidth, textureHeight); head.addBox(-4F, -8F, -4F, 8, 8, 8); head.setRotationPoint(0F, 0F, 0F); setRotation(head, 0F, 0F, 0F); body = new ModelRenderer(this, 16, 16); body.setTextureSize(textureWidth, textureHeight); body.addBox(-4F, 0F, -2F, 8, 12, 4); body.setRotationPoint(0F, 0F, 0F); setRotation(body, 0F, 0F, 0F); rightArm = new ModelRenderer(this, 40, 16); rightArm.setTextureSize(textureWidth, textureHeight); rightArm.addBox(-3F, -2F, -2F, 4, 12, 4); rightArm.setRotationPoint(-5F, 2F, 0F); setRotation(rightArm, 0F, 0F, 0F); leftArm = new ModelRenderer(this, 40, 16); leftArm.mirror = true; leftArm.setTextureSize(textureWidth, textureHeight); leftArm.addBox(-1F, -2F, -2F, 4, 12, 4); leftArm.setRotationPoint(5F, 2F, 0F); setRotation(leftArm, 0F, 0F, 0F); rightLeg = new ModelRenderer(this, 0, 16); rightLeg.mirror = true; rightLeg.setTextureSize(textureWidth, textureHeight); rightLeg.addBox(-2F, 0F, -2F, 4, 12, 4); rightLeg.setRotationPoint(-2F, 12F, 0F); setRotation(rightLeg, 0F, 0F, 0F); leftLeg = new ModelRenderer(this, 0, 16); leftLeg.setTextureSize(textureWidth, textureHeight); leftLeg.addBox(-2F, 0F, -2F, 4, 12, 4); leftLeg.setRotationPoint(2F, 12F, 0F); setRotation(leftLeg, 0F, 0F, 0F); // ARMOR shoulderPlateRight = new ModelRenderer(this, 0, 58); shoulderPlateRight.setTextureSize(textureWidth, textureHeight); shoulderPlateRight.addBox(-5F, -2.5F, -2.5F, 6, 1, 5); shoulderPlateRight.setRotationPoint(-5F, 2F, 0F); setRotation(shoulderPlateRight, 0F, 0F, 0F); shoulderPlateLeft = new ModelRenderer(this, 0, 58); shoulderPlateLeft.mirror = true; shoulderPlateLeft.setTextureSize(textureWidth, textureHeight); shoulderPlateLeft.addBox(-1F, -2.5F, -2.5F, 6, 1, 5); shoulderPlateLeft.setRotationPoint(5F, 2F, 0F); setRotation(shoulderPlateLeft, 0F, 0F, 0F); upperArmor = new ModelRenderer(this, 0, 32); upperArmor.setTextureSize(textureWidth, textureHeight); upperArmor.addBox(-5F, -3.2F, -3F, 10, 7, 6); upperArmor.setRotationPoint(0F, 3F, 0F); setRotation(upperArmor, 0F, 0F, 0F); lowerArmor = new ModelRenderer(this, 0, 46); lowerArmor.setTextureSize(textureWidth, textureHeight); lowerArmor.addBox(-4.5F, -3.2F, -2.5F, 9, 6, 5); lowerArmor.setRotationPoint(0F, 10F, 0F); setRotation(lowerArmor, 0F, 0F, 0F); // HELMET helmBackPlate = new ModelRenderer(this, 0, 55); helmBackPlate.setTextureSize(textureWidth, textureHeight); helmBackPlate.addBox(-4.5F, -7.6F, 3.5F, 9, 8, 1); helmBackPlate.setRotationPoint(0F, 0F, 0F); setRotation(helmBackPlate, 0F, 0F, 0F); helmTopPlate = new ModelRenderer(this, 0, 54); helmTopPlate.setTextureSize(textureWidth, textureHeight); helmTopPlate.addBox(-4.5F, -7.6F, -4.5F, 9, 1, 9); helmTopPlate.setRotationPoint(0F, -1.0F, 0F); setRotation(helmTopPlate, 0F, 0F, 0F); helmBackPlate.addChild(helmTopPlate); helmRightPlate = new ModelRenderer(this, 0, 48); helmRightPlate.setTextureSize(textureWidth, textureHeight); helmRightPlate.addBox(-3.5F, -7.6F, -4.5F, 1, 8, 8); helmRightPlate.setRotationPoint(-1F, 0F, 0F); setRotation(helmRightPlate, 0F, 0F, 0F); helmBackPlate.addChild(helmRightPlate); helmLeftPlate = new ModelRenderer(this, 0, 48); helmLeftPlate.mirror = true; helmLeftPlate.setTextureSize(textureWidth, textureHeight); helmLeftPlate.addBox(2.5F, -7.6F, -4.5F, 1, 8, 8); helmLeftPlate.setRotationPoint(1F, 0F, 0F); setRotation(helmLeftPlate, 0F, 0F, 0F); helmBackPlate.addChild(helmLeftPlate); helmVisor = new ModelRenderer(this, 1, 62); helmVisor.setTextureSize(textureWidth, textureHeight); helmVisor.addBox(-3.5F, -6.6F, -4.5F, 7, 1, 1); helmVisor.setRotationPoint(0F, 0F, 0F); setRotation(helmVisor, 0F, 0F, 0F); helmTopPlate.addChild(helmVisor); noseGuard = new ModelRenderer(this, 46, 11); noseGuard.setTextureSize(textureWidth, textureHeight); noseGuard.addBox(-1F, -5.6F, -4.5F, 2, 4, 1); noseGuard.setRotationPoint(0F, 0F, 0F); setRotation(noseGuard, 0F, 0F, 0F); helmVisor.addChild(noseGuard); cheekGuardRight = new ModelRenderer(this, 32, 10); cheekGuardRight.setTextureSize(textureWidth, textureHeight); cheekGuardRight.addBox(-2.5F, -4.5F, -4.5F, 2, 5, 1); cheekGuardRight.setRotationPoint(0F, 0F, 0F); setRotation(cheekGuardRight, 0F, 0F, 0F); helmRightPlate.addChild(cheekGuardRight); cheekGuardLeft = new ModelRenderer(this, 32, 10); cheekGuardLeft.mirror = true; cheekGuardLeft.setTextureSize(textureWidth, textureHeight); cheekGuardLeft.addBox(0.5F, -4.5F, -4.5F, 2, 5, 1); cheekGuardLeft.setRotationPoint(0F, 0F, 0F); setRotation(cheekGuardLeft, 0F, 0F, 0F); helmLeftPlate.addChild(cheekGuardLeft); hornHolderRight = new ModelRenderer(this, 53, 0); hornHolderRight.setTextureSize(textureWidth, textureHeight); hornHolderRight.addBox(-5F, -6F, -1.5F, 2, 3, 3); hornHolderRight.setRotationPoint(0F, 0F, 0F); setRotation(hornHolderRight, 0F, 0F, 0F); helmRightPlate.addChild(hornHolderRight); hornHolderLeft = new ModelRenderer(this, 53, 0); hornHolderLeft.mirror = true; hornHolderLeft.setTextureSize(textureWidth, textureHeight); hornHolderLeft.addBox(3F, -6F, -1.5F, 2, 3, 3); hornHolderLeft.setRotationPoint(0F, 0F, 0F); setRotation(hornHolderLeft, 0F, 0F, 0F); helmLeftPlate.addChild(hornHolderLeft); hornRight = new ModelRenderer(this, 38, 0); hornRight.setTextureSize(textureWidth, textureHeight); hornRight.addBox(-10F, -5.5F, -1F, 5, 2, 2); hornRight.setRotationPoint(0F, 0F, 0F); hornRight.setRotationPoint(-1.5F, 1.75F, 0F); setRotation(hornRight, 0F, 0F, ((float) Math.PI / 8.0F)); hornHolderRight.addChild(hornRight); hornLeft = new ModelRenderer(this, 38, 0); hornLeft.mirror = true; hornLeft.setTextureSize(textureWidth, textureHeight); hornLeft.addBox(5F, -5.5F, -1F, 5, 2, 2); hornLeft.setRotationPoint(1.5F, 1.75F, 0F); setRotation(hornLeft, 0F, 0F, -((float) Math.PI / 8.0F)); hornHolderLeft.addChild(hornLeft); cape = new ModelRenderer(this, 32, 45); cape.addBox(-5F, 0F, 0F, 10, 16, 1); cape.setRotationPoint(0F, 0F, 3F); cape.setTextureSize(textureWidth, textureHeight); } @Override public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { super.render(entity, f, f1, f2, f3, f4, f5); setRotationAngles(f, f1, f2, f3, f4, f5, entity); head.render(f5); body.render(f5); leftArm.render(f5); rightArm.render(f5); rightLeg.render(f5); leftLeg.render(f5); renderArmor((EntityDarknut) entity, f, f1, f2, f3, f4, f5); } /** * Call to render the Darknut's armor, if it has not been removed */ private void renderArmor(EntityDarknut entity, float f, float f1, float f2, float f3, float f4, float f5) { if (entity.isArmored()) { shoulderPlateRight.render(f5); shoulderPlateLeft.render(f5); upperArmor.render(f5); lowerArmor.render(f5); helmBackPlate.render(f5); } if (entity.isWearingCape()) { cape.render(f5); } } private void setRotation(ModelRenderer model, float x, float y, float z) { model.rotateAngleX = x; model.rotateAngleY = y; model.rotateAngleZ = z; } @Override public void setLivingAnimations(EntityLivingBase entity, float par2, float par3, float partialTick) { setLivingAnimations((EntityDarknut) entity, par2, par3, partialTick); } private void setLivingAnimations(EntityDarknut entity, float par2, float par3, float partialTick) { int i = entity.attackTimer; int j = entity.chargeTimer; if (entity.isSpinning()) { rightArm.rotateAngleX = powRotXR[4]; rightArm.rotateAngleY = powRotYR[4]; rightArm.rotateAngleZ = powRotZR[4]; leftArm.rotateAngleX = powRotXL[4]; leftArm.rotateAngleY = powRotYL[4]; leftArm.rotateAngleZ = powRotZL[4]; } else if (i > 0 && entity.isPowerAttack) { // Start at array index 0 (top) and swing down, holding for a few ticks at end of swing i = (7 - i); if (i < 4) { // animation is 5 ticks total rightArm.rotateAngleX = powRotXR[i] + (partialTick * (powRotXR[i + 1] - powRotXR[i])); rightArm.rotateAngleY = powRotYR[i] + (partialTick * (powRotYR[i + 1] - powRotYR[i])); rightArm.rotateAngleZ = powRotZR[i] + (partialTick * (powRotZR[i + 1] - powRotZR[i])); leftArm.rotateAngleX = powRotXL[i] + (partialTick * (powRotXL[i + 1] - powRotXL[i])); leftArm.rotateAngleY = powRotYL[i] + (partialTick * (powRotYL[i + 1] - powRotYL[i])); leftArm.rotateAngleZ = powRotZL[i] + (partialTick * (powRotZL[i + 1] - powRotZL[i])); } else { // hold on last position for a few ticks rightArm.rotateAngleX = powRotXR[4]; rightArm.rotateAngleY = powRotYR[4]; rightArm.rotateAngleZ = powRotZR[4]; leftArm.rotateAngleX = powRotXL[4]; leftArm.rotateAngleY = powRotYL[4]; leftArm.rotateAngleZ = powRotZL[4]; } } else if (Math.abs(i) > 0) { int isLeft = (i > 0 ? 1 : -1); i = Math.abs(i); rightArm.rotateAngleX = MathHelper.clamp_float(-1.0F + 3.5F * getSwingAmount((float) i - partialTick, 10.0F), -4.5F, 1.5F); rightArm.rotateAngleY = 0.0F; rightArm.rotateAngleZ = isLeft * (attackRotZ[(i + 1) % 9] + (partialTick * (attackRotZ[i % 9] - attackRotZ[(i + 1) % 9]))); leftArm.rotateAngleX = 0.0F; leftArm.rotateAngleZ = 0.0F; } else if (j > 0) { int max = entity.getChargeTime() - 1; if (j == max) { i = 3; // start on next to last index and work backwards } else if (j == (max -1)) { i = 2; } else if (j == (max - 2)) { i = 1; } else { i = 0; } rightArm.rotateAngleX = (i == 0 ? -3.5F : powRotXR[i]); rightArm.rotateAngleY = powRotYR[i]; rightArm.rotateAngleZ = 0.0F; leftArm.rotateAngleX = powRotXL[i]; leftArm.rotateAngleY = powRotYL[i]; leftArm.rotateAngleZ = powRotZL[i]; } else { rightArm.rotateAngleZ = 0.0F; leftArm.rotateAngleZ = 0.0F; } } private float getSwingAmount(float f, float max) { return (Math.abs(f % max - max * 0.5F) - max * 0.25F) / (max * 0.25F); } @Override public void setRotationAngles(float f1, float f2, float f3, float f4, float f5, float f6, Entity entity) { super.setRotationAngles(f1, f2, f3, f4, f5, f6, entity); head.rotateAngleY = f4 / (180F / (float)Math.PI); head.rotateAngleX = f5 / (180F / (float)Math.PI); helmBackPlate.rotateAngleY = head.rotateAngleY; helmBackPlate.rotateAngleX = head.rotateAngleX; // only set arm angles if not currently animating EntityDarknut darknut = (EntityDarknut) entity; boolean adjustArms = (darknut.attackTimer == 0 && darknut.chargeTimer == 0 && !darknut.isSpinning()); if (adjustArms) { rightArm.rotateAngleX = MathHelper.cos(f1 * 0.6662F) * 2.0F * f2 * 0.5F; rightArm.rotateAngleZ = 0.0F; leftArm.rotateAngleX = MathHelper.cos(f1 * 0.6662F + (float) Math.PI) * 2.0F * f2 * 0.5F; leftArm.rotateAngleZ = 0.0F; rightArm.rotateAngleY = 0.0F; leftArm.rotateAngleY = 0.0F; } rightLeg.rotateAngleX = MathHelper.cos(f1 * 0.6662F) * 1.4F * f2; leftLeg.rotateAngleX = MathHelper.cos(f1 * 0.6662F + (float) Math.PI) * 1.4F * f2; rightLeg.rotateAngleY = 0.0F; leftLeg.rotateAngleY = 0.0F; if (heldItemLeft != 0) { leftArm.rotateAngleX = leftArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F) * (float) heldItemLeft; } if (heldItemRight != 0) { rightArm.rotateAngleX = rightArm.rotateAngleX * 0.5F - ((float) Math.PI / 10F) * (float) heldItemRight; } if (swingProgress > -9990.0F) { f6 = swingProgress; body.rotateAngleY = MathHelper.sin(MathHelper.sqrt_float(f6) * (float) Math.PI * 2.0F) * 0.2F; if (adjustArms) { rightArm.rotationPointZ = MathHelper.sin(body.rotateAngleY) * 5.0F; rightArm.rotationPointX = -MathHelper.cos(body.rotateAngleY) * 5.0F; leftArm.rotationPointZ = -MathHelper.sin(body.rotateAngleY) * 5.0F; leftArm.rotationPointX = MathHelper.cos(body.rotateAngleY) * 5.0F; rightArm.rotateAngleY += body.rotateAngleY; leftArm.rotateAngleY += body.rotateAngleY; leftArm.rotateAngleX += body.rotateAngleY; f6 = 1.0F - swingProgress; f6 *= f6; f6 *= f6; f6 = 1.0F - f6; float f7 = MathHelper.sin(f6 * (float) Math.PI); float f8 = MathHelper.sin(swingProgress * (float) Math.PI) * -(head.rotateAngleX - 0.7F) * 0.75F; rightArm.rotateAngleX = (float)((double) rightArm.rotateAngleX - ((double) f7 * 1.2D + (double) f8)); rightArm.rotateAngleY += body.rotateAngleY * 2.0F; // the following makes the arm rotate parallel to the body rightArm.rotateAngleZ = MathHelper.sin(swingProgress * (float) Math.PI) * -0.4F; } } if (adjustArms) { rightArm.rotateAngleZ += MathHelper.cos(f3 * 0.09F) * 0.05F + 0.05F; leftArm.rotateAngleZ -= MathHelper.cos(f3 * 0.09F) * 0.05F + 0.05F; rightArm.rotateAngleX += MathHelper.sin(f3 * 0.067F) * 0.05F; leftArm.rotateAngleX -= MathHelper.sin(f3 * 0.067F) * 0.05F; } // Always adjust shoulder plates to match arm angles shoulderPlateRight.rotateAngleX = rightArm.rotateAngleX; shoulderPlateRight.rotateAngleY = rightArm.rotateAngleY; shoulderPlateRight.rotateAngleZ = rightArm.rotateAngleZ; shoulderPlateLeft.rotateAngleX = leftArm.rotateAngleX; shoulderPlateLeft.rotateAngleY = leftArm.rotateAngleY; shoulderPlateLeft.rotateAngleZ = leftArm.rotateAngleZ; } /** * Copied from ModelBiped, called from LayerArmorBase */ @Override public void setModelAttributes(ModelBase model) { super.setModelAttributes(model); if (model instanceof ModelDarknut) { ModelDarknut modelbiped = (ModelDarknut) model; this.heldItemLeft = modelbiped.heldItemLeft; this.heldItemRight = modelbiped.heldItemRight; //this.isSneak = modelbiped.isSneak; //this.aimedBow = modelbiped.aimedBow; } } @Override public ModelRenderer getHeadModel() { return head; } @Override public void postRenderArm(boolean isRight, float scale) { if (isRight) { rightArm.postRender(scale); } else { leftArm.postRender(scale); } } @Override public void setHeldItemValue(boolean isRight, int heldValue) { if (isRight) { heldItemRight = heldValue; } else { heldItemLeft = heldValue; } } }