/** * Copyright (c) 30/apr/2015 Davide Cossu & Matthew Albrecht. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser 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 com.minestellar.core.particles; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_GREATER; import static org.lwjgl.opengl.GL11.glAlphaFunc; import static org.lwjgl.opengl.GL11.glBlendFunc; import static org.lwjgl.opengl.GL11.glColor4f; import static org.lwjgl.opengl.GL11.glDepthMask; import static org.lwjgl.opengl.GL11.glDisable; import static org.lwjgl.opengl.GL11.glEnable; import net.minecraft.client.particle.EntityFX; import net.minecraft.client.renderer.Tessellator; import net.minecraft.world.World; import org.lwjgl.opengl.GL11; public class EntityLightningFX extends EntityFX { private int seconds; private float[] xCoords, yCoords, zCoords; private float endX, endY, endZ; /** * @param sections The number of different sections. The higher it is, the more lines there will be. */ public EntityLightningFX(World world, double x, double y, double z, int sections, int seconds) { super(world, x, y, z); this.seconds = seconds; xCoords = new float[sections]; yCoords = new float[sections]; zCoords = new float[sections]; for (int i = 0; i < sections; i++) { xCoords[i] = (float) (rand.nextFloat() + x); yCoords[i] = rand.nextFloat(); zCoords[i] = (float) (rand.nextFloat() + z); } noClip = true; } @Override public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7) { glDisable(GL11.GL_TEXTURE_2D); glDisable(GL11.GL_LIGHTING); glEnable(GL11.GL_BLEND); glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); glDepthMask(false); glAlphaFunc(GL_GREATER, 0.003921569F); glColor4f(particleRed, particleGreen, particleBlue, 0.8F); tessellator.startDrawing(3); float x = (float) (prevPosX + (posX - prevPosX) * partialTicks - interpPosX); float y = (float) (prevPosY + (posY - prevPosY) * partialTicks - interpPosY); float z = (float) (prevPosZ + (posZ - prevPosZ) * partialTicks - interpPosZ); { for (int i = 0; i < xCoords.length && i < yCoords.length && i < zCoords.length; i++) { tessellator.addVertex(xCoords[i] + x, yCoords[i] + y, zCoords[i] + z); } } tessellator.draw(); glEnable(GL11.GL_TEXTURE_2D); glEnable(GL11.GL_LIGHTING); glDisable(GL_BLEND); glDepthMask(true); glAlphaFunc(GL_GREATER, 0.1F); } @Override public void moveEntity(double motionX, double motionY, double motionZ) { super.moveEntity(motionX, motionY, motionZ); } @Override public void onUpdate() { setMaxAge(seconds * 20); this.prevPosX = this.posX; this.prevPosY = this.posY; this.prevPosZ = this.posZ; if (this.particleAge++ >= this.particleMaxAge) { this.setDead(); } this.motionX = calculateVelocityX(seconds * 20); this.motionY = calculateVelocityY(seconds * 20); this.motionZ = calculateVelocityZ(seconds * 20); this.moveEntity(this.motionX, this.motionY, this.motionZ); } /** * Sets the coordinates of the point at which the particle should arrive. */ public EntityLightningFX setArrivalCoords(float x, float y, float z) { this.endX = x; this.endY = y; this.endZ = z; return this; } /** * Calculates the <code>x</code> component of the velocity needed to get to the end position. * * @param time Time in in-game ticks. */ public float calculateVelocityX(int time) { return (float) ((this.endX - this.posX) / (time)); } /** * Calculates the <code>y</code> component of the velocity needed to get to the end position. * * @param time Time in in-game ticks. */ public float calculateVelocityY(int time) { float angle = (float) (Math.atan((this.endY - this.posY) / (this.endX - this.posX))); return (float) (calculateVelocityX(time) * Math.tan(angle)); } /** * Calculates the <code>z</code> component of the velocity needed to get to the end position. * * @param time Time in in-game ticks. */ public float calculateVelocityZ(int time) { return (float) ((this.endZ - this.posZ) / (time)); } @Override public boolean canBeCollidedWith() { return false; } @Override public boolean canBePushed() { return false; } @Override public int getFXLayer() { return 3; } public EntityLightningFX setMaxAge(int maxAge) { particleMaxAge = maxAge; return this; } public EntityLightningFX setGravity(float gravity) { particleGravity = gravity; return this; } public EntityLightningFX setScale(float scale) { particleScale = scale; return this; } public EntityLightningFX setColor(float r, float g, float b) { setRBGColorF(r, g, b); return this; } }