package electroblob.wizardry.client.particle; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.world.World; import org.lwjgl.opengl.GL11; public class ParticleLightning extends ParticleTargeted { /** Half the width of the outermost layer. */ private static final float THICKNESS = 0.04f; /** Maximum length of a segment. */ private static final double MAX_SEGMENT_LENGTH = 0.6; /** Minimum length of a segment. */ private static final double MIN_SEGMENT_LENGTH = 0.2; /** Maximum deviation (in x or y, as drawn before transformations) from the centreline. */ private static final double VERTEX_JITTER = 0.15; /** Maximum number of segments a fork can have before ending. */ private static final int MAX_FORK_SEGMENTS = 3; /** Probability (as a fraction) that a vertex will have a fork. */ private static final float FORK_CHANCE = 0.3f; /** Number of ticks to wait before the arc changes shape again. */ private static final int UPDATE_PERIOD = 1; public ParticleLightning(World world, double x, double y, double z){ super(world, x, y, z); // Does not have a texture! seed = this.rand.nextLong(); this.setRBGColorF(0.2f, 0.6f, 1); // Default blue colour this.setMaxAge(3); this.particleScale = 1; } @Override public boolean shouldDisableDepth(){ return true; } @Override public int getFXLayer(){ return 3; } @Override protected void draw(Tessellator tessellator, double length, float partialTicks){ GlStateManager.disableLighting(); GlStateManager.enableBlend(); GlStateManager.disableTexture2D(); GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); // The direction of the arc drawn by the tessellator is always along the z axis and is rotated to the // correct orientation, that way there isn't a ton of trigonometry and the code is way neater. boolean freeEnd = this.target == null; int numberOfSegments = (int)Math.round(length/MAX_SEGMENT_LENGTH); // Number of segments for(int layer=0; layer<3; layer++){ double px=0, py=0, pz=0; // Creates a random from the arc's seed field + the number of ticks it has existed/the update period. // By using a seed, we can ensure the vertex positions and forks are identical a) for each layer, even // though they are rendered sequentially, and b) across many frames (and ticks, if updateTime > 1). random.setSeed(this.seed + this.particleAge/UPDATE_PERIOD); // numberOfSegments-1 because the last segment is handled separately. for(int i=0; i