= this.particleMaxAge){
- this.setExpired();
- }
-
- // This is in radians per tick...
- double omega = Math.signum(speed) * ((Math.PI * 2) / 20 - speed / (20 * radius));
-
- // v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
- this.angle += omega;
-
- this.motionY -= 0.04D * (double)this.particleGravity;
- this.motionZ = radius * omega * Math.cos(angle);
- this.motionX = radius * omega * Math.sin(angle);
- this.move(motionX, motionY, motionZ);
-
- if(this.particleAge > this.particleMaxAge / 2){
- this.setAlphaF(
- 1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
- }
-
- }
-}
diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleScorch.java b/src/main/java/electroblob/wizardry/client/particle/ParticleScorch.java
new file mode 100644
index 00000000..3523cfa6
--- /dev/null
+++ b/src/main/java/electroblob/wizardry/client/particle/ParticleScorch.java
@@ -0,0 +1,70 @@
+package electroblob.wizardry.client.particle;
+
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.TextureStitchEvent;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+@SideOnly(Side.CLIENT)
+@Mod.EventBusSubscriber(Side.CLIENT)
+public class ParticleScorch extends ParticleWizardry {
+
+ private static final ResourceLocation[] TEXTURES = generateTextures("scorch", 8);
+
+ public ParticleScorch(World world, double x, double y, double z){
+
+ super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
+
+ this.particleGravity = 0;
+ this.setMaxAge(100 + rand.nextInt(40));
+ this.particleScale *= 2;
+ // Defaults to black (which looks like a 'normal' scorch mark)
+ this.setRBGColorF(0, 0, 0);
+ this.shaded = false;
+ }
+
+ @Override
+ public void setRBGColorF(float r, float g, float b){
+ super.setRBGColorF(r, g, b);
+ this.setFadeColour(0, 0, 0); // Scorch particles fade to black by default
+ }
+
+ @Override
+ public void onUpdate(){
+
+ super.onUpdate();
+
+ // Colour fading (scorch particles do this slightly differently)
+ float ageFraction = Math.min((float)this.particleAge / ((float)this.particleMaxAge * 0.5f), 1);
+ // No longer uses setRBGColorF because that method now also sets the initial values
+ this.particleRed = this.initialRed + (this.fadeRed - this.initialRed) * ageFraction;
+ this.particleGreen = this.initialGreen + (this.fadeGreen - this.initialGreen) * ageFraction;
+ this.particleBlue = this.initialBlue + (this.fadeBlue - this.initialBlue) * ageFraction;
+
+ // Fading
+ if(this.particleAge > this.particleMaxAge/2){
+ this.setAlphaF(1 - ((float)this.particleAge - (float)(this.particleMaxAge/2)) / (float)this.particleMaxAge);
+ }
+
+ EnumFacing facing = EnumFacing.fromAngle(yaw);
+ if(pitch == 90) facing = EnumFacing.UP;
+ if(pitch == -90) facing = EnumFacing.DOWN;
+
+ // Disappears if there is no block behind it (this is the same check used to spawn it)
+ if(!world.getBlockState(new BlockPos(posX, posY, posZ).offset(facing.getOpposite())).getMaterial().isSolid()){
+ this.setExpired();
+ }
+ }
+
+ @SubscribeEvent
+ public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
+ for(ResourceLocation texture : TEXTURES){
+ event.getMap().registerSprite(texture);
+ }
+ }
+}
diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleSnow.java b/src/main/java/electroblob/wizardry/client/particle/ParticleSnow.java
index a18ff4d9..e5de49f9 100644
--- a/src/main/java/electroblob/wizardry/client/particle/ParticleSnow.java
+++ b/src/main/java/electroblob/wizardry/client/particle/ParticleSnow.java
@@ -1,39 +1,36 @@
package electroblob.wizardry.client.particle;
-import electroblob.wizardry.Wizardry;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
+import net.minecraftforge.client.event.TextureStitchEvent;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
-public class ParticleSnow extends ParticleCustomTexture {
+@Mod.EventBusSubscriber(Side.CLIENT)
+public class ParticleSnow extends ParticleWizardry {
- private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
- "textures/particle/snow_particles.png");
+ private static final ResourceLocation[] TEXTURES = generateTextures("snow", 4);
public ParticleSnow(World world, double x, double y, double z){
- super(world, x, y, z);
- this.setParticleTextureIndex(rand.nextInt(8));
+
+ super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
+
this.setVelocity(0, -0.02, 0);
this.particleScale *= 0.6f;
this.particleGravity = 0;
this.canCollide = true;
- this.setLifetime(40 + rand.nextInt(10));
+ this.setMaxAge(40 + rand.nextInt(10));
+ // Produces a variety of light blues and whites
+ this.setRBGColorF(0.9f + 0.1f * world.rand.nextFloat(), 0.95f + 0.05f * world.rand.nextFloat(), 1);
}
- @Override
- public ResourceLocation getTexture(){
- return TEXTURE;
- }
-
- @Override
- protected int getXFrames(){
- return 4;
- }
-
- @Override
- protected int getYFrames(){
- return 4;
+ @SubscribeEvent
+ public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
+ for(ResourceLocation texture : TEXTURES){
+ event.getMap().registerSprite(texture);
+ }
}
}
diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleSpark.java b/src/main/java/electroblob/wizardry/client/particle/ParticleSpark.java
index a94103f1..5d879ad0 100644
--- a/src/main/java/electroblob/wizardry/client/particle/ParticleSpark.java
+++ b/src/main/java/electroblob/wizardry/client/particle/ParticleSpark.java
@@ -1,66 +1,55 @@
package electroblob.wizardry.client.particle;
-import org.lwjgl.opengl.GL11;
-
-import electroblob.wizardry.Wizardry;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
+import net.minecraftforge.client.event.TextureStitchEvent;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
-public class ParticleSpark extends ParticleCustomTexture {
+@Mod.EventBusSubscriber(Side.CLIENT)
+public class ParticleSpark extends ParticleWizardry {
- private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
- "textures/particle/lightning_particles.png");
+ // 8 different animation strips, 4 in each strip
+ private static final ResourceLocation[][] TEXTURES = generateTextures("lightning", 8, 4);
public ParticleSpark(World world, double x, double y, double z){
- super(world, x, y, z);
- // Multiplied by 4 because the index works slightly differently for spark particles.
- this.setParticleTextureIndex(rand.nextInt(8) * 4);
+
+ super(world, x, y, z, TEXTURES[world.rand.nextInt(TEXTURES.length)]);
+
this.particleScale *= 1.4f;
+ this.setRBGColorF(1, 1, 1);
this.shaded = false;
this.canCollide = false;
- this.setLifetime(3); // Lifetime defaults to 3 (and is very unlikely to be changed)
+ this.setMaxAge(3); // Lifetime defaults to 3 (and is very unlikely to be changed)
}
+
+ // May no longer be necessary, ParticleManager seems to enable blending now
- @Override
- public void onUpdate(){
- super.onUpdate();
- // Well this is handy! Looks like vanilla uses the texture index like this too.
- this.nextTextureIndexX();
- }
-
- @Override
- public ResourceLocation getTexture(){
- return TEXTURE;
- }
-
- @Override
- protected int getXFrames(){
- return 4;
- }
-
- @Override
- protected int getYFrames(){
- return 8;
- }
-
- @Override
- public void applyGLStateChanges(){
- GlStateManager.enableBlend();
- GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
- // TESTME: Are these two actually necessary?
- GlStateManager.disableLighting();
- OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
- }
-
- @Override
- public void undoGLStateChanges(){
- GlStateManager.disableBlend();
- GlStateManager.enableLighting();
+// @Override
+// public void applyGLStateChanges(){
+// GlStateManager.enableBlend();
+// GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+// // TESTME: Are these two actually necessary?
+// GlStateManager.disableLighting();
+// OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
+// }
+//
+// @Override
+// public void undoGLStateChanges(){
+// GlStateManager.disableBlend();
+// GlStateManager.enableLighting();
+// }
+
+ @SubscribeEvent
+ public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
+ for(ResourceLocation[] array : TEXTURES){
+ for(ResourceLocation texture : array){
+ event.getMap().registerSprite(texture);
+ }
+ }
}
}
diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleSparkle.java b/src/main/java/electroblob/wizardry/client/particle/ParticleSparkle.java
index f63bfcfb..4aa64a35 100644
--- a/src/main/java/electroblob/wizardry/client/particle/ParticleSparkle.java
+++ b/src/main/java/electroblob/wizardry/client/particle/ParticleSparkle.java
@@ -1,24 +1,23 @@
package electroblob.wizardry.client.particle;
-import electroblob.wizardry.Wizardry;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
+import net.minecraftforge.client.event.TextureStitchEvent;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
-public class ParticleSparkle extends ParticleCustomTexture {
+@Mod.EventBusSubscriber(Side.CLIENT)
+public class ParticleSparkle extends ParticleWizardry {
- private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
- "textures/particle/sparkle_particles.png");
-
- // Implementation of colour fading (perhaps these belong in ParticleWizardry?)
- private float initialRed;
- private float initialGreen;
- private float initialBlue;
+ private static final ResourceLocation[] TEXTURES = generateTextures("sparkle", 11);
public ParticleSparkle(World world, double x, double y, double z){
- super(world, x, y, z);
+
+ super(world, x, y, z, TEXTURES); // This time the textures are all one long animation
+
this.setRBGColorF(1, 1, 1);
this.particleMaxAge = 48 + this.rand.nextInt(12);
this.particleScale *= 0.75f;
@@ -27,30 +26,6 @@ public class ParticleSparkle extends ParticleCustomTexture {
this.shaded = false;
}
- // Overridden to set the initial colour values
- @Override
- public void setRBGColorF(float r, float g, float b){
- super.setRBGColorF(r, g, b);
- initialRed = r;
- initialGreen = g;
- initialBlue = b;
- }
-
- @Override
- public ResourceLocation getTexture(){
- return TEXTURE;
- }
-
- @Override
- protected int getXFrames(){
- return 4;
- }
-
- @Override
- protected int getYFrames(){
- return 4;
- }
-
@Override
public void onUpdate(){
@@ -58,24 +33,14 @@ public class ParticleSparkle extends ParticleCustomTexture {
// Fading
if(this.particleAge > this.particleMaxAge / 2){
- this.setAlphaF(
- 1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
+ this.setAlphaF(1 - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
+ }
+ }
+
+ @SubscribeEvent
+ public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
+ for(ResourceLocation texture : TEXTURES){
+ event.getMap().registerSprite(texture);
}
-
- // Colour fading
- float ageFraction = (float)this.particleAge / (float)this.particleMaxAge;
- // No longer uses setRBGColorF because that method now also sets the initial values
- this.particleRed = this.initialRed + (this.fadeRed - this.initialRed)*ageFraction;
- this.particleGreen = this.initialGreen + (this.fadeGreen - this.initialGreen)*ageFraction;
- this.particleBlue = this.initialBlue + (this.fadeBlue - this.initialBlue)*ageFraction;
-
- this.setParticleTextureIndex((this.particleAge * 11)/this.particleMaxAge);
}
-
- /* As a side note, I see a lot of magic mods with fancy-looking particle effects that really seem to 'glow'. It's
- * actually not that hard - you simply create a reasonably high-res texture with translucency and then set the
- * OpenGL blend function to something like SRC_ALPHA, SRC_ALPHA or ONE, ONE. The thing is... they're not very
- * Minecraft-y. I still maintain that part of wizardry's appeal is that it stays true to the game's pixelated charm,
- * rather than trying to make it something it's not. Still, the newer textures are much better than the defaults I
- * used to use. */
}
diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleTargeted.java b/src/main/java/electroblob/wizardry/client/particle/ParticleTargeted.java
new file mode 100644
index 00000000..80ce3e59
--- /dev/null
+++ b/src/main/java/electroblob/wizardry/client/particle/ParticleTargeted.java
@@ -0,0 +1,105 @@
+package electroblob.wizardry.client.particle;
+
+import javax.annotation.Nullable;
+
+import org.lwjgl.opengl.GL11;
+
+import electroblob.wizardry.Wizardry;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.World;
+
+/** Superclass for particles with a second target entity or target position. */
+public abstract class ParticleTargeted extends ParticleWizardry {
+
+ protected double targetX;
+ protected double targetY;
+ protected double targetZ;
+
+ /** The target this particle is linked to. The particle will stretch to touch this entity. */
+ @Nullable
+ protected Entity target = null;
+
+ public ParticleTargeted(World world, double x, double y, double z, ResourceLocation... textures){
+ super(world, x, y, z, textures);
+ }
+
+ @Override
+ public void setTargetPosition(double x, double y, double z){
+ this.targetX = x;
+ this.targetY = y;
+ this.targetZ = z;
+ }
+
+ @Override
+ public void setTargetEntity(Entity target){
+ this.target = target;
+ }
+
+ @Override
+ public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ, float rotationYZ,
+ float rotationXY, float rotationXZ){
+
+ if(this.target != null){
+ this.targetX = this.target.posX;
+ this.targetY = this.target.getEntityBoundingBox().minY + target.height/2;
+ this.targetZ = this.target.posZ;
+ }
+
+ if(Double.isNaN(targetX) || Double.isNaN(targetY) || Double.isNaN(targetZ)){
+ Wizardry.logger.warn("Attempted to render a targeted particle, but neither its target entity nor target"
+ + "position was set!");
+ return;
+ }
+
+ // I'm pretty sure these were always static.
+ interpPosX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * (double)partialTicks;
+ interpPosY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * (double)partialTicks;
+ interpPosZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * (double)partialTicks;
+
+ float x = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
+ float y = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
+ float z = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
+
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(x, y, z);
+
+ double dx = this.targetX - this.posX;
+ double dy = this.targetY - this.posY;
+ double dz = this.targetZ - this.posZ;
+
+ // The distance from origin to endpoint
+ double length = Math.sqrt(dx*dx+dy*dy+dz*dz);
+
+ // Math.atan2 computes within -180 to +180, rather than -90 to +90.
+ float yaw = (float)(180d/Math.PI * Math.atan2(dx, dz));
+ float pitch = (float)(180f/(float)Math.PI * Math.atan(-dy/Math.sqrt(dz*dz+dx*dx)));
+
+ GL11.glRotatef(yaw, 0, 1, 0);
+ GL11.glRotatef(pitch, 1, 0, 0);
+
+ Tessellator tessellator = Tessellator.getInstance();
+
+ this.draw(tessellator, length, partialTicks);
+
+ GlStateManager.popMatrix();
+ }
+
+ /** Called from {@link ParticleTargeted#renderParticle(BufferBuilder, Entity, float, float, float, float, float, float)},
+ * once the appropriate calculations and transformations have been applied, to actually render the particle. Subclasses
+ * override this instead of overriding {@code renderParticle} directly, and inside render the particle along
+ * the z-axis, starting at (0, 0, 0) - it will be translated and rotated automatically.
+ *
+ * N.B. Other than transformations, no GL state changes are applied; these should be done within this method.
+ *
+ * @param tessellator A reference to the tessellator, for convenience.
+ * @param length The distance from the origin to the endpoint for the particle being rendered; the particle should
+ * therefore be rendered between (0, 0, 0) and (0, 0, length) within this method.
+ * @param partialTicks The partial tick time.
+ */
+ protected abstract void draw(Tessellator tessellator, double length, float partialTicks);
+
+}
diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleWizardry.java b/src/main/java/electroblob/wizardry/client/particle/ParticleWizardry.java
index 607c4da5..62f96e7f 100644
--- a/src/main/java/electroblob/wizardry/client/particle/ParticleWizardry.java
+++ b/src/main/java/electroblob/wizardry/client/particle/ParticleWizardry.java
@@ -1,7 +1,20 @@
package electroblob.wizardry.client.particle;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nullable;
+
+import electroblob.wizardry.Wizardry;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.Particle;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
+import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -9,7 +22,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
* Abstract superclass for all of wizardry's particles. This replaces {@code ParticleCustomTexture} (the functionality of
* which is no longer necessary since wizardry now uses {@code TextureAtlasSprite}s to do the rendering), and fits into
* {@code ParticleBuilder} by exposing all the necessary variables through getters, allowing them to be set on the fly
- * rather than needing to be passed into the constructor.
+ * rather than needing to be passed into the constructor.
*
* The new system is as follows:
*
@@ -17,28 +30,94 @@ import net.minecraftforge.fml.relauncher.SideOnly;
* - Each particle class defines any relevant default values in its constructor, including velocity.
* - The particle builder then overwrites any other values that were set during building.
*
- * This beauty of this system is that there are never any redundant parameters when spawning particles. For example,
+ * This beauty of this system is that there are never any redundant parameters when spawning particles, since you can set
+ * as many or as few parameters as necessary - and in addition, common defaults don't need setting at all. For example,
* snow particles nearly always fall at the same speed, which can now be defined in the particle class and no longer
* needs to be defined when spawning the particle - but importantly, it can still be overridden if desired.
*
* @author Electroblob
- * @since Wizardry 4.2.0
+ * @since Wizardry 4.2.0
* @see electroblob.wizardry.util.ParticleBuilder ParticleBuilder
*/
@SideOnly(Side.CLIENT)
public abstract class ParticleWizardry extends Particle {
+ /** Implementation of animated particles using the TextureAtlasSprite system. Why vanilla doesn't support this I
+ * don't know, considering it too has animated particles. */
+ protected final TextureAtlasSprite[] sprites;
+
/** True if the particle is shaded, false if the particle always renders at full brightness. Defaults to false. */
protected boolean shaded = false;
-
- protected float fadeRed = 1;
- protected float fadeGreen = 1;
- protected float fadeBlue = 0;
- public ParticleWizardry(World world, double x, double y, double z){
+ protected float initialRed;
+ protected float initialGreen;
+ protected float initialBlue;
+
+ protected float fadeRed = 0;
+ protected float fadeGreen = 0;
+ protected float fadeBlue = 0;
+
+ protected float angle;
+ protected double radius = 0;
+ protected double speed = 0;
+
+ /** The entity this particle is linked to. The particle will move with this entity. */
+ @Nullable
+ protected Entity entity = null;
+ /** Coordinates of this particle relative to the linked entity. If the linked entity is null, these are not used. */
+ protected double relativeX, relativeY, relativeZ;
+ /** Velocity of this particle relative to the linked entity. The relative x and z velocities are also used when
+ * the particle has spin to move the centre of rotation. If the linked entity is null and the particle is not
+ * spinning, these are not used and will be {@code NaN}. */
+ protected double relativeMotionX = Double.NaN, relativeMotionY = Double.NaN, relativeMotionZ = Double.NaN;
+ // Note that roll (equivalent to rotating the texture) is effectively handled by particleAngle - although that is
+ // actually the rotation speed and not the angle itself.
+ /** The yaw angle this particle is facing, or {@code NaN} if this particle always faces the viewer (default behaviour). */
+ protected float yaw = Float.NaN;
+ /** The pitch angle this particle is facing, or {@code NaN} if this particle always faces the viewer (default behaviour). */
+ protected float pitch = Float.NaN;
+
+ /**
+ * Creates a new particle in the given world at the given position. All other parameters are set via the various
+ * setter methods ({@link electroblob.wizardry.util.ParticleBuilder ParticleBuilder} deals with all of that anyway).
+ * @param world The world in which to create the particle.
+ * @param x The x-coordinate at which to create the particle.
+ * @param y The y-coordinate at which to create the particle.
+ * @param z The z-coordinate at which to create the particle.
+ * @param textures One or more {@code ResourceLocation}s representing the texture(s) used by this particle. These
+ * must be registered as {@link TextureAtlasSprite}s using {@link TextureStitchEvent} or the textures will be
+ * missing. If more than one {@code ResourceLocation} is specified, the particle will be animated with each texture
+ * shown in order for an equal proportion of the particle's lifetime. If this argument is omitted (or a zero-length
+ * array is given), the particle will use the vanilla system instead (based on the X/Y texture indices).
+ */
+ public ParticleWizardry(World world, double x, double y, double z, ResourceLocation... textures){
+
super(world, x, y, z);
+
+ // Sets the relative coordinates in case they are needed
+ this.relativeX = x;
+ this.relativeY = y;
+ this.relativeZ = z;
+
+ // Deals with the textures
+ if(textures.length > 0){
+
+ sprites = Arrays.stream(textures).map(t -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(
+ t.toString())).collect(Collectors.toList()).toArray(new TextureAtlasSprite[0]);
+
+ this.setParticleTexture(sprites[0]);
+
+ }else{
+
+ sprites = new TextureAtlasSprite[0];
+ }
}
+ // ============================================== Parameter Setters ==============================================
+
+ // Setters for parameters that affect all particles - these are implemented in this class (although they may be
+ // reimplemented in subclasses)
+
/** Sets whether the particle should render at full brightness or not. True if the particle is shaded, false if
* the particle always renders at full brightness. Defaults to false.*/
public void setShaded(boolean shaded){
@@ -50,9 +129,9 @@ public abstract class ParticleWizardry extends Particle {
this.particleGravity = gravity ? 1 : 0;
}
- /** Sets this particle's lifetime in ticks.*/
- public void setLifetime(int lifetime){
- this.particleMaxAge = lifetime;
+ /** Sets this particle's collisions. True to enable block collisions, false to disable. Defaults to false.*/
+ public void setCollisions(boolean canCollide){
+ this.canCollide = canCollide;
}
/**
@@ -67,25 +146,252 @@ public abstract class ParticleWizardry extends Particle {
this.motionZ = vz;
}
+ /**
+ * Sets the spin parameters of the particle.
+ * @param radius The spin radius
+ * @param speed The spin speed in rotations per tick
+ */
+ public void setSpin(double radius, double speed){
+ this.radius = radius;
+ this.speed = speed * 2 * Math.PI; // Converts rotations per tick into radians per tick for the trig functions
+ this.angle = this.rand.nextFloat() * (float)Math.PI * 2; // Random start angle TODO: Perhaps this should be specified?
+ // Need to set the start position or the circle won't be centred on the correct position
+ this.relativeX = radius * -MathHelper.cos(angle);
+ this.relativeZ = radius * MathHelper.sin(angle);
+ this.setPosition(posX + relativeX, posY, posZ + relativeZ);
+ this.prevPosX = posX;
+ this.prevPosZ = posZ;
+ // Set these to the correct values
+ this.relativeMotionX = motionX;
+ this.relativeMotionY = motionY;
+ this.relativeMotionZ = motionZ;
+ }
+
+ /**
+ * Links this particle to the given entity. This will cause its position and velocity to be relative to the entity.
+ * @param entity The entity to link to.
+ */
+ public void setEntity(Entity entity){
+ this.entity = entity;
+ // Set these to the correct values
+ if(entity != null){
+ this.setPosition(this.entity.posX + relativeX, this.entity.getEntityBoundingBox().minY
+ + relativeY, this.entity.posZ + relativeZ);
+ this.prevPosX = this.posX;
+ this.prevPosY = this.posY;
+ this.prevPosZ = this.posZ;
+ this.relativeMotionX = motionX;
+ this.relativeMotionY = motionY;
+ this.relativeMotionZ = motionZ;
+ }
+ }
+
+ // Overridden to set the initial colour values
+ /**
+ * Sets the base colour of the particle. Note that this also sets the fade colour so that particles without a
+ * fade colour do not change colour at all; as such fade colour must be set after calling this method.
+ * @param r The red colour component
+ * @param g The green colour component
+ * @param b The blue colour component
+ */
+ @Override
+ public void setRBGColorF(float r, float g, float b){
+ super.setRBGColorF(r, g, b);
+ initialRed = r;
+ initialGreen = g;
+ initialBlue = b;
+ // If fade colour is not specified, it defaults to the main colour - this method is always called first
+ setFadeColour(r, g, b);
+ }
+
/**
* Sets the fade colour of the particle.
* @param r The red colour component
* @param g The green colour component
- * @param g The blue colour component
+ * @param b The blue colour component
*/
public void setFadeColour(float r, float g, float b){
this.fadeRed = r;
this.fadeGreen = g;
this.fadeBlue = b;
}
+
+ /**
+ * Sets the direction this particle faces. This will cause the particle to render facing the given direction.
+ * @param yaw The yaw angle of this particle in degrees, where 0 is [TODO south?].
+ * @param pitch The pitch angle of this particle in degrees, where 0 is horizontal.
+ */
+ public void setFacing(float yaw, float pitch){
+ this.yaw = yaw;
+ this.pitch = pitch;
+ }
+
+ // Setters for parameters that only affect some particles - these are unimplemented in this class because they
+ // doesn't make sense for most particles
+
+ /**
+ * Sets the target position for this particle. This will cause it to stretch to touch the given position,
+ * if supported.
+ * @param x The x-coordinate of the target position.
+ * @param y The y-coordinate of the target position.
+ * @param z The z-coordinate of the target position.
+ */
+ public void setTargetPosition(double x, double y, double z){
+ // Does nothing for normal particles since normal particles always render at a single point
+ }
+
+ /**
+ * Links this particle to the given target. This will cause it to stretch to touch the target, if supported.
+ * @param target The target to link to.
+ */
+ public void setTargetEntity(Entity target){
+ // Does nothing for normal particles since normal particles always render at a single point
+ }
+
+ // ============================================== Method Overrides ==============================================
+
+ @Override
+ public int getFXLayer(){
+ return sprites.length == 0 ? super.getFXLayer() : 1; // This has to be 1 for the TextureAtlasSprites to work
+ }
@Override
public int getBrightnessForRender(float partialTick){
return shaded ? super.getBrightnessForRender(partialTick) : 15728880;
}
+
+ /**
+ * Renders the particle. The mapping names given to the parameters in this method are very misleading; see below for
+ * details of what they actually do. (They're also in a strange order...)
+ * @param buffer The {@code BufferBuilder} object.
+ * @param viewer The entity whose viewpoint the particle is being rendered from; this should always be the
+ * client-side player.
+ * @param partialTicks The partial tick time.
+ * @param lookZ Equal to the cosine of {@code viewer.rotationYaw}. Will be -1 when facing north (negative Z), 0 when
+ * east/west, and +1 when facing south (positive Z). Independent of pitch.
+ * @param lookY Equal to the cosine of {@code viewer.rotationPitch}. Will be 1 when facing directly up or down, and 0
+ * when facing directly horizontally.
+ * @param lookX Equal to the sine of {@code viewer.rotationYaw}. Will be -1 when facing east (positive X), 0 when
+ * facing north/south, and +1 when facing west (negative X). Independent of pitch.
+ * @param lookXY Equal to {@code lookX} times the sine of {@code viewer.rotationPitch}. Will be 0 when facing directly horizontal.
+ * When facing directly up, will be equal to {@code -lookX}. When facing directly down, will be equal to {@code lookX}.
+ * @param lookYZ Equal to {@code -lookZ} times the sine of {@code viewer.rotationPitch}. Will be 0 when facing directly horizontal.
+ * When facing directly up, will be equal to {@code -lookZ}. When facing directly down, will be equal to {@code lookZ}.
+ */
+ @Override
+ public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float lookZ, float lookY,
+ float lookX, float lookXY, float lookYZ){
+
+ if(Float.isNaN(this.yaw) || Float.isNaN(this.pitch)){
+
+ // Normal behaviour (rotates to face the viewer)
+ super.renderParticle(buffer, viewer, partialTicks, lookZ, lookY, lookX, lookXY, lookYZ);
+
+ }else{
+
+ // Specific rotation
+
+ // Copied from ActiveRenderInfo; converts yaw and pitch into the weird parameters used by renderParticle.
+ // The 1st/3rd person distinction has been removed since this has nothing to do with the view angle.
+
+ float degToRadFactor = 0.017453292f; // Conversion from degrees to radians
+
+ float rotationX = MathHelper.cos(yaw * degToRadFactor);
+ float rotationZ = MathHelper.sin(yaw * degToRadFactor);
+ float rotationY = MathHelper.cos(pitch * degToRadFactor);
+ float rotationYZ = -rotationZ * MathHelper.sin(pitch * degToRadFactor);
+ float rotationXY = rotationX * MathHelper.sin(pitch * degToRadFactor);
+
+ super.renderParticle(buffer, viewer, partialTicks, rotationX, rotationY, rotationZ, rotationYZ, rotationXY);
+ }
+ }
+
+ @Override
+ public void onUpdate(){
- /** Simple particle factory interface which takes a world and a position and returns a particle. Used (via lambda
- * expressions) in the client proxy to link particle enum types to actual particle classes. */
+ super.onUpdate();
+
+ // If any of these values is NaN, the particle has neither an entity nor a spin
+ if(!Double.isNaN(relativeMotionX) && !Double.isNaN(relativeMotionY) && !Double.isNaN(relativeMotionZ)){
+
+ // This allows velocity changes from entity linking and spin to stack
+ double vx = relativeMotionX;
+ double vy = relativeMotionY;
+ double vz = relativeMotionZ;
+
+ // Entity linking
+ if(this.entity != null){
+
+ if(this.entity.isDead) this.setExpired();
+
+ this.setPosition(this.entity.posX + relativeX, this.entity.getEntityBoundingBox().minY + relativeY,
+ this.entity.posZ + relativeZ);
+ // Velocity is set so that the renderer will interpolate correctly between ticks
+ vx += this.entity.motionX;
+ vy += this.entity.motionY;
+ vz += this.entity.motionZ;
+ }
+
+ // Spin
+ if(radius > 0){
+ angle += speed;
+ vx += radius * speed * MathHelper.sin(angle);
+ vz += radius * speed * MathHelper.cos(angle);
+ }
+
+ this.relativeX += vx;
+ this.relativeY += vy;
+ this.relativeZ += vz;
+ }
+
+ // Colour fading
+ float ageFraction = (float)this.particleAge / (float)this.particleMaxAge;
+ // No longer uses setRBGColorF because that method now also sets the initial values
+ this.particleRed = this.initialRed + (this.fadeRed - this.initialRed) * ageFraction;
+ this.particleGreen = this.initialGreen + (this.fadeGreen - this.initialGreen) * ageFraction;
+ this.particleBlue = this.initialBlue + (this.fadeBlue - this.initialBlue) * ageFraction;
+
+ // Animation
+ if(sprites.length > 1){
+ // Math.min included for safety so the index cannot possibly exceed the length - 1 an cause an AIOOBE
+ // (which would probably otherwise happen if particleAge == particleMaxAge)
+ this.setParticleTexture(sprites[Math.min((int)(ageFraction * sprites.length), sprites.length - 1)]);
+ }
+ }
+
+ // =============================================== Helper Methods ===============================================
+
+ /** Static helper method that generates an array of n ResourceLocations using the particle file naming convention,
+ * which is the given stem plus an underscore plus the integer index. */
+ public static ResourceLocation[] generateTextures(String stem, int n){
+
+ ResourceLocation[] textures = new ResourceLocation[n];
+
+ for(int i=0; i {
-
- public RenderArc(RenderManager renderManager){
- super(renderManager);
- }
-
- @Override
- public void doRender(EntityArc arc, double x, double y, double z, float viewPitch, float viewYaw) {
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(x, y, z);
- GlStateManager.disableLighting();
- GlStateManager.enableBlend();
- GlStateManager.disableTexture2D();
- GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE);
- OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
-
- Tessellator tessellator = Tessellator.getInstance();
-
- /* Note: A lot of the maths here works on similar triangles and the ratios between them, avoiding too much
- * pythagoras and eliminating the need for any trig. Ratios are used for the positioning of the arc endpoints.
- * Ratios are usually used swapping x and z because the triangles are rotated through 90 degrees. */
-
- double dx = -x;
- double dy = -y;
- double dz = -z;
-
- if(arc.x1 != 0){
-
- dx = arc.x1 - arc.posX;
- dy = arc.y1 - arc.posY;
- dz = arc.z1 - arc.posZ;
-
- // The distance from origin to endpoint
- double arcLength = Math.sqrt(dx*dx+dy*dy+dz*dz);
-
- GL11.glTranslated(dx, dy, dz);
-
- // Math.atan2 computes within -180 to +180, rather than -90 to +90.
- float yaw = (float)(180d/Math.PI * Math.atan2(-dx, -dz));
- float pitch = (float)(180f/(float)Math.PI * Math.atan(dy/Math.sqrt(dz*dz+dx*dx)));
-
- GL11.glRotatef(yaw, 0, 1, 0);
- GL11.glRotatef(pitch, 1, 0, 0);
-
- // 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 = arc.freeEnd;
-
- // == To be extracted as constants later ==
- float thickness = 0.04f; // Half the width of the outermost layer
- double maxSegmentLength = 0.6; // Max length of a segment, obviously
- double minSegmentLength = 0.2; // Min length of a segment
- double vertexDither = 0.15; // Max deviation in x or y axis from the centreline
- int maxForkSegments = 3; // Max number of segments a fork can have
- float forkChance = 0.3f; // Chance (as a fraction) that a vertex will have a fork
- int updateTime = 1; // Number of ticks to wait before the arc changes shape again
-
- int numberOfSegments = (int)Math.round(arcLength/maxSegmentLength); // 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 random = new Random(arc.seed + arc.ticksExisted/updateTime);
-
- // numberOfSegments-1 because the last segment is handled separately.
- for(int i=0; i {
-
- private final ResourceLocation[] textures = new ResourceLocation[8];
- private float scale = 1.0f;
-
- public RenderLightningPulse(RenderManager renderManager, float scale){
- super(renderManager);
- for(int i = 0; i < textures.length; i++){
- textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_pulse_" + i + ".png");
- }
- this.scale = scale;
- }
-
- @Override
- public void doRender(EntityLightningPulse entity, double par2, double par4, double par6, float par8, float par9){
-
- GlStateManager.pushMatrix();
- GlStateManager.enableBlend();
- GlStateManager.disableLighting();
- OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
- GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
-
- float yOffset = 0;
-
- GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
-
- this.bindTexture(textures[entity.ticksExisted]);
- float f6 = 1.0F;
- float f7 = 0.5F;
- float f8 = 0.5F;
-
- GlStateManager.rotate(-90, 1, 0, 0);
-
- GlStateManager.scale(scale, scale, scale);
-
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder buffer = tessellator.getBuffer();
- buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
- buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
- buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
- buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
- buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
-
- tessellator.draw();
-
- GlStateManager.disableBlend();
- GlStateManager.enableLighting();
- GlStateManager.disableRescaleNormal();
- GlStateManager.popMatrix();
- }
-
- @Override
- protected ResourceLocation getEntityTexture(EntityLightningPulse entity){
- return null;
- }
-
-}
diff --git a/src/main/java/electroblob/wizardry/entity/EntityArc.java b/src/main/java/electroblob/wizardry/entity/EntityArc.java
deleted file mode 100644
index f3c729ae..00000000
--- a/src/main/java/electroblob/wizardry/entity/EntityArc.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package electroblob.wizardry.entity;
-
-import io.netty.buffer.ByteBuf;
-import net.minecraft.entity.Entity;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.world.World;
-import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
-
-public class EntityArc extends Entity implements IEntityAdditionalSpawnData {
-
- public double x1, y1, z1, x2, y2, z2;
- /** The number of ticks the arc lasts for before disappearing. */
- public int lifetime = 3;
- /** False if the arc is locked to an entity, true otherwise. False by default. */
- public boolean freeEnd = false;
- /** A random long value used by the renderer as a seed to generate its vertices from, ensuring they remain the same
- * across multiple frames. Not synced. */
- public final long seed;
-
- public EntityArc(World par1World){
- super(par1World);
- seed = this.rand.nextLong();
- this.ignoreFrustumCheck = true;
- }
-
- public void setEndpointCoords(double x1, double y1, double z1, double x2, double y2, double z2){
- this.x1 = x1;
- this.y1 = y1;
- this.z1 = z1;
- this.x2 = x2;
- this.y2 = y2;
- this.z2 = z2;
- this.setPosition(x2, y2, z2);
- }
-
- @Override
- public void onUpdate(){
- if(this.ticksExisted >= lifetime){
- this.setDead();
- }
- }
-
- protected void entityInit(){
- }
-
- @Override
- protected void readEntityFromNBT(NBTTagCompound nbttagcompound){
-
- }
-
- @Override
- protected void writeEntityToNBT(NBTTagCompound nbttagcompound){
- // Nothing needed here; arc is merely a graphic effect that only exists for a few ticks; as such there is no
- // need to save it.
- }
-
- @Override
- public boolean isInRangeToRenderDist(double distance){
- return true;
- }
-
- @Override
- public void writeSpawnData(ByteBuf data){
- data.writeDouble(this.x1);
- data.writeDouble(this.y1);
- data.writeDouble(this.z1);
- data.writeBoolean(freeEnd);
- }
-
- @Override
- public void readSpawnData(ByteBuf data){
- this.x1 = data.readDouble();
- this.y1 = data.readDouble();
- this.z1 = data.readDouble();
- this.freeEnd = data.readBoolean();
- }
-
-}
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java b/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java
index c45abe77..4d863e0f 100644
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java
+++ b/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java
@@ -53,24 +53,13 @@ public class EntityBlizzard extends EntityMagicConstruct {
if(!MagicDamage.isEntityImmune(DamageType.FROST, target))
target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 20, 0));
}
+
}else{
- for(int i=1; i<6; i++){
-
- float brightness = 0.5f + (rand.nextFloat() / 2);
-
- ParticleBuilder.create(Type.BLIZZARD)
- .pos(this.posX, this.posY + rand.nextDouble() * 3, this.posZ)
- .lifetime(100)
- .colour(brightness, brightness + 0.1f, 1.0f)
- .radius(rand.nextDouble() * 2.5d + 0.5d)
- .spawn(world);
-
- ParticleBuilder.create(Type.BLIZZARD)
- .pos(this.posX, this.posY + rand.nextDouble() * 3, this.posZ)
- .lifetime(100)
- .colour(1, 1, 1)
- .radius(rand.nextDouble() * 2.5d + 0.5d)
- .spawn(world);
+
+ for(int i=1; i<12; i++){
+ double speed = (rand.nextBoolean() ? 1 : -1) * 0.1 + 0.05 * rand.nextDouble();
+ ParticleBuilder.create(Type.SNOW).pos(this.posX, this.posY + rand.nextDouble() * 3, this.posZ).vel(0, 0, 0)
+ .time(100).scale(2).spin(rand.nextDouble() * 2.5 + 0.5, speed).spawn(world);
}
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java b/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java
index 6c40f523..7507cbca 100644
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java
+++ b/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java
@@ -53,7 +53,7 @@ public class EntityDecay extends EntityMagicConstruct {
ParticleBuilder.create(Type.DARK_MAGIC)
.pos(this.posX + radius * Math.cos(angle), this.posY, this.posZ + radius * Math.sin(angle))
- .colour(brightness, 0, brightness + 0.1f)
+ .clr(brightness, 0, brightness + 0.1f)
.spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java b/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java
index 7ad68328..2a1ab31d 100644
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java
+++ b/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java
@@ -66,8 +66,8 @@ public class EntityForcefield extends EntityMagicConstruct {
ParticleBuilder.create(Type.DUST)
.pos(this.posX + radius * Math.cos(yaw) * Math.cos(pitch), this.posY + 3 + radius * Math.sin(pitch),
this.posZ + radius * Math.sin(yaw) * Math.cos(pitch))
- .lifetime(48 + this.rand.nextInt(12))
- .colour(brightness, brightness, 1.0f).spawn(world);
+ .time(48 + this.rand.nextInt(12))
+ .clr(brightness, brightness, 1.0f).spawn(world);
}
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java b/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java
index 6f174d91..80bec470 100644
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java
+++ b/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java
@@ -3,7 +3,6 @@ package electroblob.wizardry.entity.construct;
import java.util.List;
import electroblob.wizardry.Wizardry;
-import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
@@ -98,24 +97,12 @@ public class EntityHammer extends EntityMagicConstruct {
if(this.isValidTarget(target)){
- if(!world.isRemote){
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(this.posX, this.posY + this.height - 0.1, this.posZ, target.posX,
- target.posY + target.height / 2, target.posZ);
- world.spawnEntity(arc);
- }else{
- // TODO: Move all the arc particle (and sound?) stuff into a method in WizardryUtilities
- for(int j=0; j<8; j++){
- ParticleBuilder.create(Type.SPARK)
- .pos(target.posX + world.rand.nextFloat() - 0.5,
- target.getEntityBoundingBox().minY + target.height / 2 + world.rand.nextFloat() * 2 - 1,
- target.posZ + world.rand.nextFloat() - 0.5)
- .spawn(world);
-
- world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + rand.nextFloat(),
- target.getEntityBoundingBox().minY + target.height / 2 + rand.nextFloat(),
- target.posZ + rand.nextFloat(), 0, 0, 0);
- }
+ if(world.isRemote){
+
+ ParticleBuilder.create(Type.LIGHTNING).pos(posX, posY + height - 0.1, posZ) .target(target).spawn(world);
+
+ ParticleBuilder.spawnShockParticles(world, target.posX,
+ target.getEntityBoundingBox().minY + target.height, target.posZ);
}
target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java b/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java
index 32e893f7..14406109 100644
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java
+++ b/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java
@@ -69,8 +69,8 @@ public class EntityHealAura extends EntityMagicConstruct {
ParticleBuilder.create(Type.SPARKLE)
.pos(this.posX + radius * Math.cos(angle), this.posY, this.posZ + radius * Math.sin(angle))
.vel(0, 0.05, 0)
- .lifetime(48 + this.rand.nextInt(12))
- .colour(1.0f, 1.0f, brightness)
+ .time(48 + this.rand.nextInt(12))
+ .clr(1.0f, 1.0f, brightness)
.spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningPulse.java b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningPulse.java
deleted file mode 100644
index b2d46ab5..00000000
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningPulse.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package electroblob.wizardry.entity.construct;
-
-import net.minecraft.world.World;
-
-@Deprecated // This needs changing into a particle
-public class EntityLightningPulse extends EntityMagicConstruct {
-
- public EntityLightningPulse(World world){
- super(world);
- this.setSize(6, 0.2f);
- }
-
- @Override
- public boolean canRenderOnFire(){
- return false;
- }
-
-}
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java
index 62dcea76..589cea82 100644
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java
+++ b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java
@@ -2,7 +2,6 @@ package electroblob.wizardry.entity.construct;
import java.util.List;
-import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
@@ -11,7 +10,6 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.DamageSource;
-import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
public class EntityLightningSigil extends EntityMagicConstruct {
@@ -65,25 +63,14 @@ public class EntityLightningSigil extends EntityMagicConstruct {
if(secondaryTarget != target && this.isValidTarget(secondaryTarget)){
- if(!world.isRemote){
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(target.posX, target.posY + target.height / 2, target.posZ,
- secondaryTarget.posX, secondaryTarget.posY + secondaryTarget.height / 2,
+ if(world.isRemote){
+
+ ParticleBuilder.create(Type.LIGHTNING).entity(target)
+ .pos(0, target.height/2, 0).target(secondaryTarget).spawn(world);
+
+ ParticleBuilder.spawnShockParticles(world, secondaryTarget.posX,
+ secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2,
secondaryTarget.posZ);
- world.spawnEntity(arc);
- }else{
- for(int k = 0; k < 8; k++){
- ParticleBuilder.create(Type.SPARK)
- .pos(secondaryTarget.posX + world.rand.nextFloat() - 0.5,
- secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2 + world.rand.nextFloat() * 2 - 1,
- secondaryTarget.posZ + world.rand.nextFloat() - 0.5)
- .spawn(world);
- world.spawnParticle(EnumParticleTypes.SMOKE_LARGE,
- secondaryTarget.posX + world.rand.nextFloat() - 0.5,
- secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2
- + world.rand.nextFloat() * 2 - 1,
- secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
- }
}
secondaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F,
diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java b/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java
index f53c2b54..a2c6248c 100644
--- a/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java
+++ b/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java
@@ -140,12 +140,14 @@ public class EntityTornado extends EntityMagicConstruct {
if(block.getMaterial() == Material.SNOW || block.getMaterial() == Material.CRAFTED_SNOW)
type = Type.SNOW;
- double yPos1 = rand.nextDouble() * 8;
- ParticleBuilder.create(type)
- .pos(this.posX + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d), this.posY + yPos1,
- this.posZ + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d))
- .lifetime(40 + rand.nextInt(10))
- .spawn(world);
+ if(type != null){
+ double yPos1 = rand.nextDouble() * 8;
+ ParticleBuilder.create(type)
+ .pos(this.posX + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d), this.posY + yPos1,
+ this.posZ + (rand.nextDouble() * 2 - 1) * (yPos1 / 3 + 0.5d))
+ .time(40 + rand.nextInt(10))
+ .spawn(world);
+ }
}
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java b/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java
index 38665937..1444d6f9 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java
@@ -41,14 +41,17 @@ public class EntityDecoy extends EntitySummonedCreature {
@Override
public void onDespawn(){
super.onDespawn();
- for(int i = 0; i < 20; i++){
- ParticleBuilder.create(Type.DUST)
- .pos(this.posX + (this.rand.nextDouble() - 0.5) * this.width, this.getEntityBoundingBox().minY
- + this.rand.nextDouble() * this.height, this.posZ + (this.rand.nextDouble() - 0.5) * this.width)
- .lifetime(40)
- .colour(0.2f, 1.0f, 0.8f)
- .shaded(true)
- .spawn(world);
+
+ if(world.isRemote){
+ for(int i = 0; i < 20; i++){
+ ParticleBuilder.create(Type.DUST)
+ .pos(this.posX + (this.rand.nextDouble() - 0.5) * this.width, this.getEntityBoundingBox().minY
+ + this.rand.nextDouble() * this.height, this.posZ + (this.rand.nextDouble() - 0.5) * this.width)
+ .time(40)
+ .clr(0.2f, 1.0f, 0.8f)
+ .shaded(true)
+ .spawn(world);
+ }
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java b/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java
index 00b4d2e2..356281ea 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java
@@ -221,7 +221,7 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
// 0.5F.
double y = (double)((float)this.posY - 0.5F + rand.nextFloat());
double z = (double)((float)this.posZ + rand.nextFloat() * 2 - 1.0F);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).colour(1, 1, 0.3f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).clr(1, 1, 0.3f).spawn(world);
}
}else{
if(this.getHealth() < 10){
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityIceGiant.java b/src/main/java/electroblob/wizardry/entity/living/EntityIceGiant.java
index 93e25d2b..8003f7f8 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityIceGiant.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityIceGiant.java
@@ -99,8 +99,8 @@ public class EntityIceGiant extends EntityIronGolem implements ISummonedCreature
if(this.world.isRemote){
for(int i = 0; i < 30; i++){
float brightness = 0.5f + (rand.nextFloat() / 2);
- ParticleBuilder.create(Type.SPARKLE, this).vel(0, -0.02, 0).lifetime(12 + rand.nextInt(8))
- .colour(brightness, brightness + 0.1f, 1.0f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, this).vel(0, -0.02, 0).time(12 + rand.nextInt(8))
+ .clr(brightness, brightness + 0.1f, 1.0f).spawn(world);
}
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java b/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java
index 3f2c07e1..5d9fee8b 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java
@@ -51,8 +51,8 @@ public class EntityIceWraith extends EntityBlazeMinion {
.pos(this.posX - 0.5d + rand.nextDouble(), this.posY + this.height / 2 - 0.5d + rand.nextDouble(),
this.posZ - 0.5d + rand.nextDouble())
.vel(0, 0.05f, 0)
- .lifetime(20 + rand.nextInt(10))
- .colour(brightness, brightness + 0.1f, 1.0f)
+ .time(20 + rand.nextInt(10))
+ .clr(brightness, brightness + 0.1f, 1.0f)
.spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java b/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java
index fb5364e8..a97c52af 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java
@@ -40,8 +40,8 @@ public class EntityLightningWraith extends EntityBlazeMinion {
if(this.world.isRemote){
for(int i = 0; i < 15; i++){
float brightness = 0.3f + (rand.nextFloat() / 2);
- ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).lifetime(20 + rand.nextInt(10))
- .colour(brightness, brightness + 0.2f, 1.0f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).time(20 + rand.nextInt(10))
+ .clr(brightness, brightness + 0.2f, 1.0f).spawn(world);
}
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java b/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java
index b182af36..d09a3326 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java
@@ -125,8 +125,8 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell
if(this.world.isRemote){
for(int i = 0; i < 15; i++){
float brightness = rand.nextFloat() * 0.4f;
- ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).lifetime(20 + rand.nextInt(10))
- .colour(brightness, 0.0f, brightness).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).time(20 + rand.nextInt(10))
+ .clr(brightness, 0.0f, brightness).spawn(world);
}
}
}
@@ -160,10 +160,10 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell
float brightness = rand.nextFloat() * 0.2f;
- ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).lifetime(20 + rand.nextInt(10))
- .colour(brightness, 0.0f, brightness).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, this).vel(0, 0.05, 0).time(20 + rand.nextInt(10))
+ .clr(brightness, 0.0f, brightness).spawn(world);
- ParticleBuilder.create(Type.DARK_MAGIC, this).colour(0.1f, 0.0f, 0.0f).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC, this).clr(0.1f, 0.0f, 0.0f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java b/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java
index b2a2c8fa..e0275389 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java
@@ -82,7 +82,7 @@ public class EntitySilverfishMinion extends EntitySilverfish implements ISummone
for(int i = 0; i < 15; i++){
ParticleBuilder.create(Type.DARK_MAGIC)
.pos(this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat())
- .colour(0.3f, 0.3f, 0.3f)
+ .clr(0.3f, 0.3f, 0.3f)
.spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java b/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java
index 23b7824b..328e988c 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java
@@ -110,7 +110,7 @@ public class EntitySpiderMinion extends EntityCaveSpider implements ISummonedCre
for(int i = 0; i < 15; i++){
ParticleBuilder.create(Type.DARK_MAGIC)
.pos(this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat())
- .colour(0.1f, 0.2f, 0.0f)
+ .clr(0.1f, 0.2f, 0.0f)
.spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java
index efd656d0..67284bde 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java
@@ -120,7 +120,7 @@ public class EntitySpiritHorse extends EntityHorse {
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).spawn(world);
}
}
@@ -158,7 +158,7 @@ public class EntitySpiritHorse extends EntityHorse {
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
- ParticleBuilder.create(Type.DUST).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
+ ParticleBuilder.create(Type.DUST).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
}
// Spirit horse disappears a short time after being dismounted.
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java
index db5c7ab3..f18601f9 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java
@@ -89,7 +89,7 @@ public class EntitySpiritWolf extends EntityWolf {
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).spawn(world);
}
}
@@ -103,7 +103,7 @@ public class EntitySpiritWolf extends EntityWolf {
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
- ParticleBuilder.create(Type.DUST).pos(x, y, z).colour(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
+ ParticleBuilder.create(Type.DUST).pos(x, y, z).clr(0.8f, 0.8f, 1.0f).shaded(true).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java b/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java
index 602a6941..29776335 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java
@@ -148,8 +148,9 @@ public class EntityStormElemental extends EntitySummonedCreature implements ISpe
float brightness = rand.nextFloat() * 0.2f;
double dy = this.rand.nextDouble() * (double)this.height;
- ParticleBuilder.create(Type.SPARKLE_ROTATING).pos(this.posX, this.posY + dy, this.posZ)
- .lifetime(20 + rand.nextInt(10)).colour(0, brightness, brightness).radius(0.2f + 0.5f * dy).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(this.posX, this.posY + dy, this.posZ)
+ .time(20 + rand.nextInt(10)).clr(0, brightness, brightness)//.entity(this)
+ .spin(0.2 + 0.5 * dy, 0.1 + 0.05 * world.rand.nextDouble()).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java
index 7214304e..1e71a7c2 100644
--- a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java
+++ b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java
@@ -310,7 +310,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
// 0.5F.
double y = (double)((float)this.posY - 0.5F + rand.nextFloat());
double z = (double)((float)this.posZ + rand.nextFloat() * 2 - 1.0F);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).colour(1, 1, 0.3f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1F, 0).clr(1, 1, 0.3f).spawn(world);
}
}else{
if(this.getHealth() < 10){
diff --git a/src/main/java/electroblob/wizardry/entity/living/ISummonedCreature.java b/src/main/java/electroblob/wizardry/entity/living/ISummonedCreature.java
index 1b6a0069..a3bbfcee 100644
--- a/src/main/java/electroblob/wizardry/entity/living/ISummonedCreature.java
+++ b/src/main/java/electroblob/wizardry/entity/living/ISummonedCreature.java
@@ -308,7 +308,7 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData {
if(this.hasParticleEffect() && thisEntity.world.isRemote && thisEntity.world.rand.nextInt(8) == 0)
ParticleBuilder.create(Type.DARK_MAGIC)
.pos(thisEntity.posX, thisEntity.posY + thisEntity.world.rand.nextDouble() * 1.5, thisEntity.posZ)
- .colour(0.1f, 0.0f, 0.0f)
+ .clr(0.1f, 0.0f, 0.0f)
.spawn(thisEntity.world);
}
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java
index 43e81c5e..d9aee1e5 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java
@@ -47,10 +47,10 @@ public class EntityDarknessOrb extends EntityMagicProjectile {
float brightness = rand.nextFloat() * 0.2f;
- ParticleBuilder.create(Type.SPARKLE, this).lifetime(20 + rand.nextInt(10))
- .colour(brightness, 0.0f, brightness).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, this).time(20 + rand.nextInt(10))
+ .clr(brightness, 0.0f, brightness).spawn(world);
- ParticleBuilder.create(Type.DARK_MAGIC, this).colour(0.1f, 0.0f, 0.0f).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC, this).clr(0.1f, 0.0f, 0.0f).spawn(world);
}
if(this.ticksExisted > 150){
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java
index 1ab9c0f0..146b0c4e 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java
@@ -36,7 +36,7 @@ public class EntityDart extends EntityMagicArrow {
@Override
public void tickInAir(){
if(this.world.isRemote){
- ParticleBuilder.create(Type.LEAF, this).lifetime(10 + rand.nextInt(5)).spawn(world);
+ ParticleBuilder.create(Type.LEAF, this).time(10 + rand.nextInt(5)).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java
index d6e207c5..32c42bf3 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java
@@ -39,16 +39,19 @@ public class EntityFirebomb extends EntityBomb {
// Particle effect
if(world.isRemote){
- this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
-
+ ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(1, 0.6f, 0)
+ .spawn(world);
+
for(int i = 0; i < 60 * blastMultiplier; i++){
ParticleBuilder.create(Type.MAGIC_FIRE, rand, posX, posY, posZ, 2*blastMultiplier, false)
- .lifetime(15 + rand.nextInt(5)).scale(2 + rand.nextFloat()).spawn(world);
+ .time(15 + rand.nextInt(5)).scale(2 + rand.nextFloat()).spawn(world);
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
- .colour(1.0f, 0.2f + rand.nextFloat() * 0.4f, 0.0f).spawn(world);
+ .clr(1.0f, 0.2f + rand.nextFloat() * 0.4f, 0.0f).spawn(world);
}
+
+ this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
}
if(!this.world.isRemote){
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java
index 89738294..8fcf251d 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java
@@ -1,6 +1,8 @@
package electroblob.wizardry.entity.projectile;
import electroblob.wizardry.util.MagicDamage.DamageType;
+import electroblob.wizardry.util.ParticleBuilder;
+import electroblob.wizardry.util.ParticleBuilder.Type;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.SoundEvents;
import net.minecraft.world.World;
@@ -15,6 +17,8 @@ public class EntityForceArrow extends EntityMagicArrow {
@Override
public void onEntityHit(EntityLivingBase entityHit){
this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F);
+ if(this.world.isRemote)
+ ParticleBuilder.create(Type.FLASH).pos(posX, posY, posZ).scale(1.3f).clr(0.75f, 1, 0.85f).spawn(world);
}
@Override
@@ -25,6 +29,13 @@ public class EntityForceArrow extends EntityMagicArrow {
@Override
public void onBlockHit(){
this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F);
+ if(this.world.isRemote){
+ // Gets a position slightly away from the block hit so the particle doesn't get cut in half by the block face
+ Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(0.15));
+ ParticleBuilder.create(Type.FLASH).pos(vec).scale(1.3f).clr(0.75f, 1, 0.85f).spawn(world);
+ vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(WizardryUtilities.ANTI_Z_FIGHTING_OFFSET));
+ ParticleBuilder.create(Type.SCORCH).pos(vec).face(hit.sideHit).clr(0, 1, 0.5f).spawn(world);
+ }
}
@Override
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java
index 5c554aa2..73373a40 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java
@@ -31,8 +31,8 @@ public class EntityForceOrb extends EntityBomb {
if(this.world.isRemote){
for(int j = 0; j < 20; j++){
float brightness = 0.5f + (rand.nextFloat() / 2);
- ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.25, true).lifetime(6)
- .colour(brightness, 1.0f, brightness + 0.2f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.25, true).time(6)
+ .clr(brightness, 1.0f, brightness + 0.2f).spawn(world);
}
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
}
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java
index 25282d28..1f35f8d6 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java
@@ -47,11 +47,11 @@ public class EntityIceCharge extends EntityBomb {
for(int i = 0; i < 30 * blastMultiplier; i++){
ParticleBuilder.create(Type.ICE, rand, this.posX, this.posY, this.posZ, 2 * blastMultiplier, false)
- .lifetime(35).gravity(true).spawn(world);
+ .time(35).gravity(true).spawn(world);
float brightness = 0.4f + rand.nextFloat() * 0.5f;
ParticleBuilder.create(Type.DARK_MAGIC, rand, this.posX, this.posY, this.posZ, 2 * blastMultiplier, false)
- .colour(brightness, brightness + 0.1f, 1.0f).spawn(world);
+ .clr(brightness, brightness + 0.1f, 1.0f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java
index 5666ca18..1863f343 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java
@@ -46,7 +46,7 @@ public class EntityIceLance extends EntityMagicArrow {
if(this.world.isRemote){
for(int j = 0; j < 10; j++){
ParticleBuilder.create(Type.ICE, this.rand, this.posX, this.posY, this.posZ, 0.5, true)
- .lifetime(20 + rand.nextInt(10)).gravity(true).spawn(world);
+ .time(20 + rand.nextInt(10)).gravity(true).spawn(world);
}
}
// Parameters for sound: sound event name, volume, pitch.
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java
index 936acacc..c4d42bfa 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java
@@ -41,9 +41,13 @@ public class EntityIceShard extends EntityMagicArrow {
public void onBlockHit(){
// Adds a particle effect when the ice shard hits a block.
if(this.world.isRemote){
+ // Gets a position slightly away from the block hit so the particle doesn't get cut in half by the block face
+ Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(0.15));
+ ParticleBuilder.create(Type.FLASH).pos(vec).clr(0.75f, 1, 1).spawn(world);
+
for(int j = 0; j < 10; j++){
ParticleBuilder.create(Type.ICE, this.rand, this.posX, this.posY, this.posZ, 0.5, true)
- .lifetime(20 + rand.nextInt(10)).gravity(true).spawn(world);
+ .time(20 + rand.nextInt(10)).gravity(true).spawn(world);
}
}
// Parameters for sound: sound event name, volume, pitch.
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java
index 8e5d38dc..63857276 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java
@@ -32,6 +32,12 @@ public class EntityLightningArrow extends EntityMagicArrow {
}
this.playSound(WizardrySounds.SPELL_SPARK, 1.0F, 1.0F);
+ @Override
+ public void onBlockHit(RayTraceResult hit){
+ if(this.world.isRemote){
+ Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(WizardryUtilities.ANTI_Z_FIGHTING_OFFSET));
+ ParticleBuilder.create(Type.SCORCH).pos(vec).face(hit.sideHit).clr(0.4f, 0.8f, 1).scale(0.6f).spawn(world);
+ }
}
@Override
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java
index bf2e5166..0485db50 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java
@@ -201,8 +201,10 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE
/** Called when the projectile hits an entity. Override to add potion effects and such like. */
protected void onEntityHit(EntityLivingBase entityHit){}
- /** Called when the projectile hits a block. Override to add sound effects and such like. */
- protected void onBlockHit(){}
+ /** Called when the projectile hits a block. Override to add sound effects and such like.
+ * @param hit A vector representing the exact coordinates of the hit; use this to centre particle effects, for
+ * example. */
+ protected void onBlockHit(RayTraceResult hit){}
@Override
public void onUpdate(){
@@ -390,7 +392,7 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE
this.inGround = true;
this.arrowShake = 7;
- this.onBlockHit();
+ this.onBlockHit(raytraceresult);
if(this.stuckInBlock.getMaterial() != Material.AIR){
this.stuckInBlock.getBlock().onEntityCollidedWithBlock(this.world, raytraceresult.getBlockPos(),
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java
index 60a3e60b..676ba719 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java
@@ -4,9 +4,14 @@ import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.SoundEvents;
+import net.minecraft.util.math.RayTraceResult;
+import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class EntityMagicMissile extends EntityMagicArrow {
+
+ /** The number of ticks the magic missile flies for before vanishing; effectively determines its range. */
+ private static final int LIFETIME = 12;
/** Creates a new magic missile in the given world. */
public EntityMagicMissile(World world){
@@ -26,25 +31,32 @@ public class EntityMagicMissile extends EntityMagicArrow {
}
@Override
- public void onBlockHit(){
- if(this.world.isRemote) spawnImpactParticles();
- }
-
- private void spawnImpactParticles(){
- ParticleBuilder.create(Type.FLASH).pos(posX, posY, posZ).colour(0.5f + rand.nextFloat()/2, 0.5f + rand.nextFloat()/2,
- 0.5f + rand.nextFloat()/2).spawn(world);
+ public void onBlockHit(RayTraceResult hit){
+ if(this.world.isRemote){
+ // Gets a position slightly away from the block hit so the particle doesn't get cut in half by the block face
+ Vec3d vec = hit.hitVec.add(new Vec3d(hit.sideHit.getDirectionVec()).scale(0.15));
+ ParticleBuilder.create(Type.FLASH).pos(vec).clr(1, 1, 0.65f).fade(0.85f, 0.5f, 0.8f).spawn(world);
+ }
}
@Override
public void tickInAir(){
- if(this.ticksExisted > 20){
+ if(this.ticksExisted > LIFETIME){
this.setDead();
}
if(this.world.isRemote){
- ParticleBuilder.create(Type.SPARKLE).pos(this.posX, this.posY, this.posZ).lifetime(20 + rand.nextInt(10))
- .colour(0.5f + (rand.nextFloat() / 2), 0.5f + (rand.nextFloat() / 2), 0.5f + (rand.nextFloat() / 2)).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
+ .time(20 + rand.nextInt(10)).spawn(world);
+
+ if(this.ticksExisted > 1){ // Don't spawn particles behind where it started!
+ double x = posX - motionX/2;
+ double y = posY - motionY/2;
+ double z = posZ - motionZ/2;
+ ParticleBuilder.create(Type.SPARKLE, rand, x, y, z, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
+ .time(20 + rand.nextInt(10)).spawn(world);
+ }
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java
index c2ae3d54..5dfd2f8e 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java
@@ -41,13 +41,17 @@ public class EntityPoisonBomb extends EntityBomb {
// Particle effect
if(world.isRemote){
+
+ ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier)
+ .clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
+
for(int i = 0; i < 60 * blastMultiplier; i++){
- ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 2*blastMultiplier, false).lifetime(35)
- .colour(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 2*blastMultiplier, false).time(35)
+ .clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
- .colour(0.2f + rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
+ .clr(0.2f + rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
}
// Spawning this after the other particles fixes the rendering colour bug. It's a bit of a cheat, but it
// works pretty well.
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java
index 61dcf727..e19592a6 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java
@@ -27,7 +27,11 @@ public class EntitySmokeBomb extends EntityBomb {
// Particle effect
if(world.isRemote){
+
+ ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(0, 0, 0).spawn(world);
+
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
+
for(int i = 0; i < 60 * blastMultiplier; i++){
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE,
@@ -37,7 +41,7 @@ public class EntitySmokeBomb extends EntityBomb {
float brightness = rand.nextFloat() * 0.3f;
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
- .colour(brightness, brightness, brightness).spawn(world);
+ .clr(brightness, brightness, brightness).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java
index 6b8a92b1..28ddbf8a 100644
--- a/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java
+++ b/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java
@@ -2,11 +2,11 @@ package electroblob.wizardry.entity.projectile;
import java.util.List;
-import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.ParticleBuilder;
+import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
@@ -65,19 +65,14 @@ public class EntitySparkBomb extends EntityBomb {
if(!this.world.isRemote){
- EntityArc arc = new EntityArc(this.world);
- arc.setEndpointCoords(this.posX, this.posY, this.posZ, target.posX, target.posY + target.height / 2,
- target.posZ);
- this.world.spawnEntity(arc);
-
- target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
+ target.playSound(WizardrySounds.ENTITY_SPARK_BOMB_CHAIN, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
target.attackEntityFrom(
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK),
5.0f * damageMultiplier);
}else{
- // Particle effect
+ ParticleBuilder.create(Type.LIGHTNING).pos(this.getPositionVector()).target(target).spawn(world);
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
}
}
diff --git a/src/main/java/electroblob/wizardry/potion/PotionFrost.java b/src/main/java/electroblob/wizardry/potion/PotionFrost.java
index 7cb709e2..2733ded4 100644
--- a/src/main/java/electroblob/wizardry/potion/PotionFrost.java
+++ b/src/main/java/electroblob/wizardry/potion/PotionFrost.java
@@ -40,7 +40,6 @@ public class PotionFrost extends Potion implements ICustomPotionParticles {
@Override
public void spawnCustomParticle(World world, double x, double y, double z){
- ParticleBuilder.create(Type.SNOW).pos(x, y, z).lifetime(15 + world.rand.nextInt(5)).spawn(world);
}
@Override
@@ -55,6 +54,7 @@ public class PotionFrost extends Potion implements ICustomPotionParticles {
public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha){
mc.renderEngine.bindTexture(ICON);
WizardryUtilities.drawTexturedRect(x + 3, y + 3, 0, 0, 18, 18, 18, 18);
+ ParticleBuilder.create(Type.SNOW).pos(x, y, z).time(15 + world.rand.nextInt(5)).spawn(world);
}
@SubscribeEvent
diff --git a/src/main/java/electroblob/wizardry/spell/Arc.java b/src/main/java/electroblob/wizardry/spell/Arc.java
index 296b3355..e543790d 100644
--- a/src/main/java/electroblob/wizardry/spell/Arc.java
+++ b/src/main/java/electroblob/wizardry/spell/Arc.java
@@ -30,11 +30,10 @@ public class Arc extends SpellRay {
if(WizardryUtilities.isLiving(target)){
- if(!world.isRemote){
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(caster.posX, caster.posY + 1, caster.posZ, target.posX, target.posY + target.height / 2, target.posZ);
- world.spawnEntity(arc);
- }else{
+ if(world.isRemote){
+ // Rather neatly, the entity can be set here and if it's null nothing will happen.
+ ParticleBuilder.create(Type.LIGHTNING).entity(caster)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
}
diff --git a/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java b/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java
index 650e1966..099943c5 100644
--- a/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java
+++ b/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java
@@ -60,7 +60,7 @@ public class ArcaneJammer extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.9f, 0.3f, 0.7f)
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(0.9f, 0.3f, 0.7f)
.spawn(world);
}
diff --git a/src/main/java/electroblob/wizardry/spell/Banish.java b/src/main/java/electroblob/wizardry/spell/Banish.java
index 469334a2..f1523866 100644
--- a/src/main/java/electroblob/wizardry/spell/Banish.java
+++ b/src/main/java/electroblob/wizardry/spell/Banish.java
@@ -89,7 +89,7 @@ public class Banish extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.2f, 0, 0.2f).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.2f, 0, 0.2f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/ChainLightning.java b/src/main/java/electroblob/wizardry/spell/ChainLightning.java
index ca23af59..8e6bfb72 100644
--- a/src/main/java/electroblob/wizardry/spell/ChainLightning.java
+++ b/src/main/java/electroblob/wizardry/spell/ChainLightning.java
@@ -102,12 +102,11 @@ public class ChainLightning extends SpellRay {
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
}
- if(!world.isRemote){
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(caster.posX, caster.getEntityBoundingBox().minY + caster.height / 2, caster.posZ,
- target.posX, target.getEntityBoundingBox().minY + target.height / 2, target.posZ);
- world.spawnEntity(arc);
- }else{
+ if(world.isRemote){
+
+ ParticleBuilder.create(Type.LIGHTNING).entity(caster)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
+
ParticleBuilder.spawnShockParticles(world, target.posX, target.getEntityBoundingBox().minY + target.height/2, target.posZ);
}
diff --git a/src/main/java/electroblob/wizardry/spell/Clairvoyance.java b/src/main/java/electroblob/wizardry/spell/Clairvoyance.java
index 6f74e00a..0b582f15 100644
--- a/src/main/java/electroblob/wizardry/spell/Clairvoyance.java
+++ b/src/main/java/electroblob/wizardry/spell/Clairvoyance.java
@@ -127,7 +127,7 @@ public class Clairvoyance extends Spell {
(nextPoint.x - point.x) / (float)PARTICLE_MOVEMENT_INTERVAL,
(nextPoint.y - point.y) / (float)PARTICLE_MOVEMENT_INTERVAL,
(nextPoint.z - point.z) / (float)PARTICLE_MOVEMENT_INTERVAL)
- .lifetime((int)(1800 * durationMultiplier)).colour(0, 1, 0.3f).spawn(world);
+ .time((int)(1800 * durationMultiplier)).clr(0, 1, 0.3f).spawn(world);
path.incrementPathIndex();
path.incrementPathIndex();
@@ -136,7 +136,7 @@ public class Clairvoyance extends Spell {
point = path.getFinalPathPoint();
ParticleBuilder.create(Type.PATH).pos(point.x + 0.5, point.y + 0.5, point.z + 0.5)
- .lifetime((int)(1800 * durationMultiplier)).colour(1, 1, 1).spawn(world);
+ .time((int)(1800 * durationMultiplier)).clr(1, 1, 1).spawn(world);
}
@SubscribeEvent
diff --git a/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java b/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java
index 4936395a..d6e73fb2 100644
--- a/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java
+++ b/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java
@@ -54,9 +54,9 @@ public class CurseOfSoulbinding extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.4f, 0, 0).spawn(world);
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(1, 0.8f, 1).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.4f, 0, 0).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0, 0).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(1, 0.8f, 1).spawn(world);
}
@SubscribeEvent
diff --git a/src/main/java/electroblob/wizardry/spell/Entrapment.java b/src/main/java/electroblob/wizardry/spell/Entrapment.java
index 2b7f8c30..931a230e 100644
--- a/src/main/java/electroblob/wizardry/spell/Entrapment.java
+++ b/src/main/java/electroblob/wizardry/spell/Entrapment.java
@@ -63,7 +63,7 @@ public class Entrapment extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.PORTAL, x, y - 0.5, z, 0, 0, 0);
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0, 0).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/FlamingWeapon.java b/src/main/java/electroblob/wizardry/spell/FlamingWeapon.java
index f157a8c2..1c940d4e 100644
--- a/src/main/java/electroblob/wizardry/spell/FlamingWeapon.java
+++ b/src/main/java/electroblob/wizardry/spell/FlamingWeapon.java
@@ -53,7 +53,7 @@ public class FlamingWeapon extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.9f, 0.7f, 1).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Flight.java b/src/main/java/electroblob/wizardry/spell/Flight.java
index 70183b00..eb36ceff 100644
--- a/src/main/java/electroblob/wizardry/spell/Flight.java
+++ b/src/main/java/electroblob/wizardry/spell/Flight.java
@@ -41,11 +41,11 @@ public class Flight extends Spell {
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(0.8f, 1, 0.5f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(0.8f, 1, 0.5f).spawn(world);
x = caster.posX - 1 + world.rand.nextDouble() * 2;
y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
z = caster.posZ - 1 + world.rand.nextDouble() * 2;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(1, 1, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(1, 1, 1).spawn(world);
}
if(ticksInUse % 24 == 0){
diff --git a/src/main/java/electroblob/wizardry/spell/FontOfMana.java b/src/main/java/electroblob/wizardry/spell/FontOfMana.java
index df6f46af..6963c42f 100644
--- a/src/main/java/electroblob/wizardry/spell/FontOfMana.java
+++ b/src/main/java/electroblob/wizardry/spell/FontOfMana.java
@@ -52,8 +52,8 @@ public class FontOfMana extends Spell {
double y = caster.getEntityBoundingBox().minY;
double z = caster.posZ + radius * Math.sin(angle);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).lifetime(50)
- .colour(1, 1 - hue, 0.6f + hue).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).time(50)
+ .clr(1, 1 - hue, 0.6f + hue).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/ForestsCurse.java b/src/main/java/electroblob/wizardry/spell/ForestsCurse.java
index e08bd145..0cd51ef4 100644
--- a/src/main/java/electroblob/wizardry/spell/ForestsCurse.java
+++ b/src/main/java/electroblob/wizardry/spell/ForestsCurse.java
@@ -50,13 +50,13 @@ public class ForestsCurse extends SpellAreaEffect {
float brightness = world.rand.nextFloat() / 4;
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).vel(0, -0.2, 0)
- .colour(0.05f + brightness, 0.2f + brightness, 0).spawn(world);
+ .clr(0.05f + brightness, 0.2f + brightness, 0).spawn(world);
brightness = world.rand.nextFloat() / 4;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.05, 0).lifetime(50)
- .colour(0.1f + brightness, 0.2f + brightness, 0).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.05, 0).time(50)
+ .clr(0.1f + brightness, 0.2f + brightness, 0).spawn(world);
- ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).lifetime(40 + world.rand.nextInt(12)).spawn(world);
+ ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).time(40 + world.rand.nextInt(12)).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Freeze.java b/src/main/java/electroblob/wizardry/spell/Freeze.java
index 48f19bb0..3347b566 100644
--- a/src/main/java/electroblob/wizardry/spell/Freeze.java
+++ b/src/main/java/electroblob/wizardry/spell/Freeze.java
@@ -87,8 +87,8 @@ public class Freeze extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = 0.5f + (world.rand.nextFloat() / 2);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8))
- .colour(brightness, brightness + 0.1f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8))
+ .clr(brightness, brightness + 0.1f, 1).spawn(world);
ParticleBuilder.create(Type.SNOW).pos(x, y, z).spawn(world);
}
diff --git a/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java b/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java
index e2792eb9..19b8a8bc 100644
--- a/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java
+++ b/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java
@@ -59,7 +59,7 @@ public class FreezingWeapon extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.9f, 0.7f, 1).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/FrostRay.java b/src/main/java/electroblob/wizardry/spell/FrostRay.java
index 1a360880..47c36b37 100644
--- a/src/main/java/electroblob/wizardry/spell/FrostRay.java
+++ b/src/main/java/electroblob/wizardry/spell/FrostRay.java
@@ -104,9 +104,9 @@ public class FrostRay extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = world.rand.nextFloat();
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12))
- .colour(0.4f + 0.6f * brightness, 0.6f + 0.4f*brightness, 1).spawn(world);
- ParticleBuilder.create(Type.SNOW).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12)).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(12))
+ .clr(0.4f + 0.6f * brightness, 0.6f + 0.4f*brightness, 1).spawn(world);
+ ParticleBuilder.create(Type.SNOW).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(12)).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Glide.java b/src/main/java/electroblob/wizardry/spell/Glide.java
index 0db03cca..7821c800 100644
--- a/src/main/java/electroblob/wizardry/spell/Glide.java
+++ b/src/main/java/electroblob/wizardry/spell/Glide.java
@@ -35,11 +35,11 @@ public class Glide extends Spell {
double x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
double z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(1, 1, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(1, 1, 1).spawn(world);
x = caster.posX - 0.25 + world.rand.nextDouble() / 2;
y = caster.getEntityBoundingBox().minY + world.rand.nextDouble();
z = caster.posZ - 0.25 + world.rand.nextDouble() / 2;
- ParticleBuilder.create(Type.LEAF).pos(x, y, z).lifetime(20).spawn(world);
+ ParticleBuilder.create(Type.LEAF).pos(x, y, z).time(20).spawn(world);
}
if(ticksInUse % 24 == 0){
diff --git a/src/main/java/electroblob/wizardry/spell/GroupHeal.java b/src/main/java/electroblob/wizardry/spell/GroupHeal.java
index 58030155..71593ec1 100644
--- a/src/main/java/electroblob/wizardry/spell/GroupHeal.java
+++ b/src/main/java/electroblob/wizardry/spell/GroupHeal.java
@@ -9,8 +9,8 @@ import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.entity.living.ISummonedCreature;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
-import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.ParticleBuilder;
+import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLivingBase;
@@ -49,10 +49,10 @@ public class GroupHeal extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(1, 1, 0.3f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(1, 1, 0.3f).spawn(world);
}
-
- Wizardry.proxy.spawnEntityParticle(world, caster, 15, 1, 1, 0.3f);
+
+ ParticleBuilder.create(Type.BUFF).entity(caster).clr(1, 1, 0.3f).spawn(world);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
@@ -78,10 +78,10 @@ public class GroupHeal extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(1, 1, 0.3f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(1, 1, 0.3f).spawn(world);
}
-
- Wizardry.proxy.spawnEntityParticle(world, caster, 15, 1, 1, 0.3f);
+
+ ParticleBuilder.create(Type.BUFF).entity(caster).clr(1, 1, 0.3f).spawn(world);
}
WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F,
diff --git a/src/main/java/electroblob/wizardry/spell/HealAlly.java b/src/main/java/electroblob/wizardry/spell/HealAlly.java
index f6ccdb65..e36ab8eb 100644
--- a/src/main/java/electroblob/wizardry/spell/HealAlly.java
+++ b/src/main/java/electroblob/wizardry/spell/HealAlly.java
@@ -41,10 +41,10 @@ public class HealAlly extends SpellRay {
double x1 = (double)((float)entity.posX + world.rand.nextFloat() * 2 - 1.0f);
double y1 = (double)((float)entity.getEntityBoundingBox().minY + entity.getEyeHeight() - 0.5f + world.rand.nextFloat());
double z1 = (double)((float)entity.posZ + world.rand.nextFloat() * 2 - 1.0f);
- ParticleBuilder.create(Type.SPARKLE).pos(x1, y1, z1).vel(0, 0.1F, 0).colour(r, g, b).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x1, y1, z1).vel(0, 0.1F, 0).clr(r, g, b).spawn(world);
}
-
- Wizardry.proxy.spawnEntityParticle(world, entity, 15, r, g, b);
+
+ ParticleBuilder.create(Type.BUFF).entity(caster).clr(r, g, b).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/IceStatue.java b/src/main/java/electroblob/wizardry/spell/IceStatue.java
index 2132ef16..9c5b1cfd 100644
--- a/src/main/java/electroblob/wizardry/spell/IceStatue.java
+++ b/src/main/java/electroblob/wizardry/spell/IceStatue.java
@@ -55,9 +55,9 @@ public class IceStatue extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = 0.5f + world.rand.nextFloat() * 0.5f;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8))
- .colour(brightness, brightness + 0.1f, 1.0f).spawn(world);
- ParticleBuilder.create(Type.SNOW).pos(x, y, z).lifetime(20 + world.rand.nextInt(10)).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8))
+ .clr(brightness, brightness + 0.1f, 1.0f).spawn(world);
+ ParticleBuilder.create(Type.SNOW).pos(x, y, z).time(20 + world.rand.nextInt(10)).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java b/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java
index caf3f92e..ec1178fd 100644
--- a/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java
+++ b/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java
@@ -68,7 +68,7 @@ public class ImbueWeapon extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.9f, 0.7f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.9f, 0.7f, 1).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Intimidate.java b/src/main/java/electroblob/wizardry/spell/Intimidate.java
index 2d8f6aa4..626c7210 100644
--- a/src/main/java/electroblob/wizardry/spell/Intimidate.java
+++ b/src/main/java/electroblob/wizardry/spell/Intimidate.java
@@ -68,7 +68,7 @@ public class Intimidate extends Spell {
double x = caster.posX - 1 + world.rand.nextDouble() * 2;
double y = caster.getEntityBoundingBox().minY + 1.5 + world.rand.nextDouble() * 0.5;
double z = caster.posZ - 1 + world.rand.nextDouble() * 2;
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.9f, 0.1f, 0).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.9f, 0.1f, 0).spawn(world);
}
}
WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERDRAGON_GROWL, 1.0f, 1.0f);
diff --git a/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java b/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java
index 859a5a90..425e7c3b 100644
--- a/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java
+++ b/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java
@@ -53,7 +53,7 @@ public class InvigoratingPresence extends Spell {
double y = caster.getEntityBoundingBox().minY;
double z = caster.posZ + radius * Math.sin(angle);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).lifetime(50).colour(1, 0.2f, 0.2f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.03, 0).time(50).clr(1, 0.2f, 0.2f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/InvokeWeather.java b/src/main/java/electroblob/wizardry/spell/InvokeWeather.java
index e2773b79..71ce3368 100644
--- a/src/main/java/electroblob/wizardry/spell/InvokeWeather.java
+++ b/src/main/java/electroblob/wizardry/spell/InvokeWeather.java
@@ -54,7 +54,7 @@ public class InvokeWeather extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.5f, 0.7f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.5f, 0.7f, 1).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Levitation.java b/src/main/java/electroblob/wizardry/spell/Levitation.java
index 34779ce6..60e16ab8 100644
--- a/src/main/java/electroblob/wizardry/spell/Levitation.java
+++ b/src/main/java/electroblob/wizardry/spell/Levitation.java
@@ -30,7 +30,7 @@ public class Levitation extends Spell {
double x = caster.posX - 0.25 + world.rand.nextDouble() * 0.5;
double y = caster.getEntityBoundingBox().minY;
double z = caster.posZ - 0.25 + world.rand.nextDouble() * 0.5;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).lifetime(15).colour(0.5f, 1, 0.7f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, -0.1, 0).time(15).clr(0.5f, 1, 0.7f).spawn(world);
}
if(ticksInUse % 24 == 0 && world.isRemote){
Wizardry.proxy.playMovingSound(caster, WizardrySounds.SPELL_LOOP_SPARKLE, 0.5f, 1, false);
diff --git a/src/main/java/electroblob/wizardry/spell/LifeDrain.java b/src/main/java/electroblob/wizardry/spell/LifeDrain.java
index 364b5890..b60109f9 100644
--- a/src/main/java/electroblob/wizardry/spell/LifeDrain.java
+++ b/src/main/java/electroblob/wizardry/spell/LifeDrain.java
@@ -89,10 +89,10 @@ public class LifeDrain extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
- if(world.rand.nextInt(5) == 0) ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
+ if(world.rand.nextInt(5) == 0) ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0, 0).spawn(world);
// This used to multiply the velocity by the distance from the caster
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(6))
- .colour(0.5f, 0, 0).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(6))
+ .clr(0.5f, 0, 0).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/LightningPulse.java b/src/main/java/electroblob/wizardry/spell/LightningPulse.java
index acd809d4..69c1543b 100644
--- a/src/main/java/electroblob/wizardry/spell/LightningPulse.java
+++ b/src/main/java/electroblob/wizardry/spell/LightningPulse.java
@@ -5,11 +5,12 @@ import java.util.List;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
-import electroblob.wizardry.entity.construct.EntityLightningPulse;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
+import electroblob.wizardry.util.ParticleBuilder;
+import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLivingBase;
@@ -72,14 +73,10 @@ public class LightningPulse extends Spell {
}
}
- if(!world.isRemote){
- // Surely neither of the commented lines would have done anything?
- EntityLightningPulse lightningpulse = new EntityLightningPulse(world);
- lightningpulse.setPosition(caster.posX, caster.getEntityBoundingBox().minY, caster.posZ);
- //lightningpulse.setCaster(caster);
- lightningpulse.lifetime = 7;
- //lightningpulse.damageMultiplier = modifiers.get(SpellModifiers.POTENCY);
- world.spawnEntity(lightningpulse);
+ if(world.isRemote){
+ ParticleBuilder.create(Type.LIGHTNING_PULSE).pos(caster.posX, caster.getEntityBoundingBox().minY
+ + WizardryUtilities.ANTI_Z_FIGHTING_OFFSET, caster.posZ)
+ .scale(modifiers.get(WizardryItems.blast_upgrade)).spawn(world);
}
caster.swingArm(hand);
diff --git a/src/main/java/electroblob/wizardry/spell/LightningRay.java b/src/main/java/electroblob/wizardry/spell/LightningRay.java
index de680000..3521b3d5 100644
--- a/src/main/java/electroblob/wizardry/spell/LightningRay.java
+++ b/src/main/java/electroblob/wizardry/spell/LightningRay.java
@@ -3,7 +3,6 @@ package electroblob.wizardry.spell;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
-import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
@@ -18,6 +17,7 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
@@ -71,23 +71,18 @@ public class LightningRay extends SpellRay {
BASE_DAMAGE * modifiers.get(SpellModifiers.POTENCY));
}
- if(!world.isRemote){
+ if(world.isRemote){
+
+ if(ticksInUse % 3 == 0) ParticleBuilder.create(Type.LIGHTNING).entity(caster)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
- if(ticksInUse % 2 == 0){
-
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ, target.posX,
- target.posY + target.height / 2, target.posZ);
- arc.lifetime = 1;
- world.spawnEntity(arc);
- }
-
- }else{
// Particle effect
for(int i=0; i<5; i++){
ParticleBuilder.create(Type.SPARK, target).spawn(world);
}
}
+
+ return true;
}
return false;
@@ -101,21 +96,15 @@ public class LightningRay extends SpellRay {
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// This is a nice example of when onMiss is used for more than just returning a boolean
- if(!world.isRemote){
+ if(world.isRemote && ticksInUse % 4 == 0){
- if(ticksInUse % 2 == 0){
-
- double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
-
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
- caster.posX + caster.getLookVec().x * freeRange,
- caster.posY + caster.getEyeHeight() + caster.getLookVec().y * freeRange,
- caster.posZ + caster.getLookVec().z * freeRange);
- arc.lifetime = 1;
- world.spawnEntity(arc);
-
- }
+ if(caster != null) origin = origin.subtract(0, Y_OFFSET, 0);
+
+ double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
+ Vec3d endpoint = origin.add(direction.scale(freeRange));
+
+ ParticleBuilder.create(Type.LIGHTNING).entity(caster)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(endpoint).spawn(world);
}
return true;
diff --git a/src/main/java/electroblob/wizardry/spell/LightningWeb.java b/src/main/java/electroblob/wizardry/spell/LightningWeb.java
index 72b2cc67..8f5f1256 100644
--- a/src/main/java/electroblob/wizardry/spell/LightningWeb.java
+++ b/src/main/java/electroblob/wizardry/spell/LightningWeb.java
@@ -5,7 +5,6 @@ import java.util.List;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
-import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
@@ -20,6 +19,7 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
@@ -119,19 +119,20 @@ public class LightningWeb extends SpellRay {
@Override
protected boolean onMiss(World world, EntityLivingBase caster, int ticksInUse, SpellModifiers modifiers){
// This is a nice example of when onMiss is used for more than just returning a boolean
- if(!world.isRemote){
+ if(world.isRemote){
+
+ if(caster != null) origin = origin.subtract(0, Y_OFFSET, 0);
+
+ double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
+ Vec3d endpoint = origin.add(direction.scale(freeRange));
+
+ ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f, 1)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(endpoint).spawn(world);
if(ticksInUse % 2 == 0){
-
- double freeRange = 0.8 * baseRange; // The arc does not reach full range when it has a free end
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ,
- caster.posX + caster.getLookVec().x * freeRange,
- caster.posY + caster.getEyeHeight() + caster.getLookVec().y * freeRange,
- caster.posZ + caster.getLookVec().z * freeRange);
- arc.lifetime = 1;
- world.spawnEntity(arc);
+ ParticleBuilder.create(Type.LIGHTNING).entity(caster)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(endpoint).spawn(world);
}
}
@@ -150,17 +151,16 @@ public class LightningWeb extends SpellRay {
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), damage);
}
- if(!world.isRemote){
- // Arc entity spawning
- if(ticksInUse % 2 == 0){
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(origin.posX, origin.posY + 1.2, origin.posZ, target.posX,
- target.posY + target.height / 2, target.posZ);
- arc.lifetime = 1;
- world.spawnEntity(arc);
- }
+ if(world.isRemote){
- }else{
+ ParticleBuilder.create(Type.BEAM).entity(caster).clr(0.2f, 0.6f, 1)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
+
+ if(ticksInUse % 3 == 0){
+ ParticleBuilder.create(Type.LIGHTNING).entity(caster)
+ .pos(caster != null ? origin.subtract(caster.getPositionVector()) : origin).target(target).spawn(world);
+ }
+
// Particle effect
for(int i=0; i<5; i++){
ParticleBuilder.create(Type.SPARK, target).spawn(world);
diff --git a/src/main/java/electroblob/wizardry/spell/Metamorphosis.java b/src/main/java/electroblob/wizardry/spell/Metamorphosis.java
index 56ec9107..174e28ef 100644
--- a/src/main/java/electroblob/wizardry/spell/Metamorphosis.java
+++ b/src/main/java/electroblob/wizardry/spell/Metamorphosis.java
@@ -34,6 +34,7 @@ import net.minecraft.entity.passive.EntityPig;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class Metamorphosis extends SpellRay {
@@ -111,7 +112,7 @@ public class Metamorphosis extends SpellRay {
}else{
for(int i=0; i<5; i++){
- ParticleBuilder.create(Type.DARK_MAGIC).pos(xPos, yPos, zPos).colour(0.1f, 0, 0).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(xPos, yPos, zPos).clr(0.1f, 0, 0).spawn(world);
}
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/MindControl.java b/src/main/java/electroblob/wizardry/spell/MindControl.java
index 96c4cccd..0c10155b 100644
--- a/src/main/java/electroblob/wizardry/spell/MindControl.java
+++ b/src/main/java/electroblob/wizardry/spell/MindControl.java
@@ -76,10 +76,10 @@ public class MindControl extends SpellRay {
for(int i=0; i<10; i++){
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
- .colour(0.8f, 0.2f, 1.0f).spawn(world);
+ .clr(0.8f, 0.2f, 1.0f).spawn(world);
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
- .colour(0.2f, 0.04f, 0.25f).spawn(world);
+ .clr(0.2f, 0.04f, 0.25f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/MindTrick.java b/src/main/java/electroblob/wizardry/spell/MindTrick.java
index 0bf6b2fa..739d585f 100644
--- a/src/main/java/electroblob/wizardry/spell/MindTrick.java
+++ b/src/main/java/electroblob/wizardry/spell/MindTrick.java
@@ -57,7 +57,7 @@ public class MindTrick extends SpellRay {
for(int i=0; i<10; i++){
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, target.posX,
target.getEntityBoundingBox().minY + target.getEyeHeight(), target.posZ, 0.25, false)
- .colour(0.8f, 0.2f, 1.0f).spawn(world);
+ .clr(0.8f, 0.2f, 1.0f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Petrify.java b/src/main/java/electroblob/wizardry/spell/Petrify.java
index bdbaba16..757d9f29 100644
--- a/src/main/java/electroblob/wizardry/spell/Petrify.java
+++ b/src/main/java/electroblob/wizardry/spell/Petrify.java
@@ -53,8 +53,8 @@ public class Petrify extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.2f, 0.2f, 0.2f).spawn(world);
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0.1f, 0.1f).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(0.2f, 0.2f, 0.2f).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0.1f, 0.1f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java b/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java
index f9f87a10..e1d71f41 100644
--- a/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java
+++ b/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java
@@ -58,12 +58,12 @@ public class PlagueOfDarkness extends Spell {
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
ParticleBuilder.create(Type.DARK_MAGIC).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
- .vel(particleX - caster.posX, 0, particleZ - caster.posZ).colour(0.1f, 0, 0).spawn(world);
+ .vel(particleX - caster.posX, 0, particleZ - caster.posZ).clr(0.1f, 0, 0).spawn(world);
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
- .vel(particleX - caster.posX, 0, particleZ - caster.posZ).lifetime(30).colour(0.1f, 0, 0.05f).spawn(world);
+ .vel(particleX - caster.posX, 0, particleZ - caster.posZ).time(30).clr(0.1f, 0, 0.05f).spawn(world);
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
diff --git a/src/main/java/electroblob/wizardry/spell/Poison.java b/src/main/java/electroblob/wizardry/spell/Poison.java
index 0a81900e..057f0f2c 100644
--- a/src/main/java/electroblob/wizardry/spell/Poison.java
+++ b/src/main/java/electroblob/wizardry/spell/Poison.java
@@ -68,8 +68,8 @@ public class Poison extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.3f, 0.7f, 0).spawn(world);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.1f, 0.4f, 0).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.3f, 0.7f, 0).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(0.1f, 0.4f, 0).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Shockwave.java b/src/main/java/electroblob/wizardry/spell/Shockwave.java
index 52bf90a8..5b970204 100644
--- a/src/main/java/electroblob/wizardry/spell/Shockwave.java
+++ b/src/main/java/electroblob/wizardry/spell/Shockwave.java
@@ -78,12 +78,12 @@ public class Shockwave extends Spell {
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
- .vel(particleX - caster.posX, 0, particleZ - caster.posZ).lifetime(30).colour(0.8f, 0.8f, 1).spawn(world);
+ .vel(particleX - caster.posX, 0, particleZ - caster.posZ).time(30).clr(0.8f, 0.8f, 1).spawn(world);
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
ParticleBuilder.create(Type.SPARKLE).pos(particleX, caster.getEntityBoundingBox().minY, particleZ)
- .vel(particleX - caster.posX, 0, particleZ - caster.posZ).lifetime(30).colour(0.9f, 0.9f, 0.9f).spawn(world);
+ .vel(particleX - caster.posX, 0, particleZ - caster.posZ).time(30).clr(0.9f, 0.9f, 0.9f).spawn(world);
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
diff --git a/src/main/java/electroblob/wizardry/spell/Slime.java b/src/main/java/electroblob/wizardry/spell/Slime.java
index 4b04b83d..b972686b 100644
--- a/src/main/java/electroblob/wizardry/spell/Slime.java
+++ b/src/main/java/electroblob/wizardry/spell/Slime.java
@@ -87,7 +87,7 @@ public class Slime extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
world.spawnParticle(EnumParticleTypes.SLIME, x, y, z, 0, 0, 0);
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.2f, 0.8f, 0.1f).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.2f, 0.8f, 0.1f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Snare.java b/src/main/java/electroblob/wizardry/spell/Snare.java
index d7e64753..fa2259ea 100644
--- a/src/main/java/electroblob/wizardry/spell/Snare.java
+++ b/src/main/java/electroblob/wizardry/spell/Snare.java
@@ -54,9 +54,9 @@ public class Snare extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = world.rand.nextFloat() * 0.25f;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(20 + world.rand.nextInt(8))
- .colour(brightness, brightness + 0.1f, 0).spawn(world);
- ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).lifetime(40 + world.rand.nextInt(10)).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(20 + world.rand.nextInt(8))
+ .clr(brightness, brightness + 0.1f, 0).spawn(world);
+ ParticleBuilder.create(Type.LEAF).pos(x, y, z).vel(0, -0.01, 0).time(40 + world.rand.nextInt(10)).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/SpellBuff.java b/src/main/java/electroblob/wizardry/spell/SpellBuff.java
index 0c91c08f..f4277c69 100644
--- a/src/main/java/electroblob/wizardry/spell/SpellBuff.java
+++ b/src/main/java/electroblob/wizardry/spell/SpellBuff.java
@@ -144,10 +144,10 @@ public class SpellBuff extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(r, g, b).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(r, g, b).spawn(world);
}
- Wizardry.proxy.spawnEntityParticle(world, caster, 15, r, g, b);
+ ParticleBuilder.create(Type.BUFF).entity(caster).clr(r, g, b).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/SpellConjuration.java b/src/main/java/electroblob/wizardry/spell/SpellConjuration.java
index 9dd9d068..c339932a 100644
--- a/src/main/java/electroblob/wizardry/spell/SpellConjuration.java
+++ b/src/main/java/electroblob/wizardry/spell/SpellConjuration.java
@@ -94,7 +94,7 @@ public class SpellConjuration extends Spell {
double x = caster.posX + world.rand.nextDouble() * 2 - 1;
double y = caster.getEntityBoundingBox().minY + caster.getEyeHeight() - 0.5 + world.rand.nextDouble();
double z = caster.posZ + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.7f, 0.9f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.7f, 0.9f, 1).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java b/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java
index 1fee0dab..5166d9ba 100644
--- a/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java
+++ b/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java
@@ -39,7 +39,7 @@ public class SummonIronGolem extends Spell {
double x = pos.getX() + world.rand.nextDouble() * 2 - 1;
double y = pos.getY() + 0.5 + world.rand.nextDouble();
double z = pos.getZ() + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).colour(0.6f, 0.6f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.6f, 0.6f, 1).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java b/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java
index e168d3b8..3be56349 100644
--- a/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java
+++ b/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java
@@ -39,7 +39,7 @@ public class SummonSnowGolem extends Spell {
double x = pos.getX() + world.rand.nextDouble() * 2 - 1;
double y = pos.getY() + 0.5 + world.rand.nextDouble();
double z = pos.getZ() + world.rand.nextDouble() * 2 - 1;
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).colour(0.6f, 0.6f, 1).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(0, 0.1, 0).clr(0.6f, 0.6f, 1).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Thunderstorm.java b/src/main/java/electroblob/wizardry/spell/Thunderstorm.java
index a96d65ea..06ca648b 100644
--- a/src/main/java/electroblob/wizardry/spell/Thunderstorm.java
+++ b/src/main/java/electroblob/wizardry/spell/Thunderstorm.java
@@ -5,12 +5,12 @@ import java.util.List;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.constants.SpellType;
import electroblob.wizardry.constants.Tier;
-import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.ParticleBuilder;
+import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLiving;
@@ -72,12 +72,10 @@ public class Thunderstorm extends Spell {
if(WizardryUtilities.isValidTarget(caster, secondaryTarget)){
- if(!world.isRemote){
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(x, y + 1, z, secondaryTarget.posX,
- secondaryTarget.posY + secondaryTarget.height / 2, secondaryTarget.posZ);
- world.spawnEntity(arc);
- }else{
+ if(world.isRemote){
+
+ ParticleBuilder.create(Type.LIGHTNING).pos(x, y, z).target(secondaryTarget).spawn(world);
+
ParticleBuilder.spawnShockParticles(world, secondaryTarget.posX,
secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height / 2,
secondaryTarget.posZ);
@@ -102,14 +100,9 @@ public class Thunderstorm extends Spell {
if(!secondaryTargets.contains(tertiaryTarget)
&& WizardryUtilities.isValidTarget(caster, tertiaryTarget)){
- if(!world.isRemote){
- EntityArc arc = new EntityArc(world);
- arc.setEndpointCoords(secondaryTarget.posX,
- secondaryTarget.posY + secondaryTarget.height / 2, secondaryTarget.posZ,
- tertiaryTarget.posX, tertiaryTarget.posY + tertiaryTarget.height / 2,
- tertiaryTarget.posZ);
- world.spawnEntity(arc);
- }else{
+ if(world.isRemote){
+ ParticleBuilder.create(Type.LIGHTNING).entity(secondaryTarget)
+ .pos(0, secondaryTarget.height/2, 0).target(tertiaryTarget).spawn(world);
ParticleBuilder.spawnShockParticles(world, tertiaryTarget.posX,
tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height / 2,
tertiaryTarget.posZ);
diff --git a/src/main/java/electroblob/wizardry/spell/WallOfFrost.java b/src/main/java/electroblob/wizardry/spell/WallOfFrost.java
index 37a55b55..1ab2670d 100644
--- a/src/main/java/electroblob/wizardry/spell/WallOfFrost.java
+++ b/src/main/java/electroblob/wizardry/spell/WallOfFrost.java
@@ -129,9 +129,9 @@ public class WallOfFrost extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
float brightness = world.rand.nextFloat();
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12))
- .colour(0.4f + 0.6f * brightness, 0.6f + 0.4f*brightness, 1).spawn(world);
- ParticleBuilder.create(Type.SNOW).pos(x, y, z).vel(vx, vy, vz).lifetime(8 + world.rand.nextInt(12)).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(12))
+ .clr(0.4f + 0.6f * brightness, 0.6f + 0.4f*brightness, 1).spawn(world);
+ ParticleBuilder.create(Type.SNOW).pos(x, y, z).vel(vx, vy, vz).time(8 + world.rand.nextInt(12)).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/spell/Wither.java b/src/main/java/electroblob/wizardry/spell/Wither.java
index 3cacf432..54d260fb 100644
--- a/src/main/java/electroblob/wizardry/spell/Wither.java
+++ b/src/main/java/electroblob/wizardry/spell/Wither.java
@@ -64,8 +64,8 @@ public class Wither extends SpellRay {
@Override
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
- ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).colour(0.1f, 0, 0).spawn(world);
- ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).lifetime(12 + world.rand.nextInt(8)).colour(0.1f, 0, 0.05f).spawn(world);
+ ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.1f, 0, 0).spawn(world);
+ ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).time(12 + world.rand.nextInt(8)).clr(0.1f, 0, 0.05f).spawn(world);
}
}
diff --git a/src/main/java/electroblob/wizardry/util/ParticleBuilder.java b/src/main/java/electroblob/wizardry/util/ParticleBuilder.java
index 839dc831..eb78c50b 100644
--- a/src/main/java/electroblob/wizardry/util/ParticleBuilder.java
+++ b/src/main/java/electroblob/wizardry/util/ParticleBuilder.java
@@ -4,6 +4,7 @@ import java.util.Random;
import electroblob.wizardry.Wizardry;
import net.minecraft.entity.Entity;
+import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
@@ -13,17 +14,14 @@ import net.minecraft.world.World;
* "Don't waste time spawning particles manually - let {@code ParticleBuilder} do the work for you!"
*
* Singleton class that builds wizardry particles. This is an alternative (and neater, I think) solution to using varargs.
- * All building methods are chainable, so particles can be created using only one line of code (This is similar to the
- * BufferBuilder system). The number of different combinations of parameters now required for the various particle
+ * All building methods are chainable, so particles can be created using only one line of code, similar to the
+ * {@code BufferBuilder} system. The number of different combinations of parameters now required for the various particle
* types in wizardry made the method overloads in the proxies very cumbersome and inevitably resulted in redundant
* parameters, which made the code messy and hard to read. Those methods have now been removed.
*
- * It also goes without saying that this class should only ever be used client-side. Attempting to spawn particles
- * on the server side will not work and will print a warning to the console.
- *
* {@link ParticleBuilder#instance} retrieves the static instance of the particle builder. Use
* {@link ParticleBuilder#particle(Type)} to start building a particle, or alternatively use the static
- * convenience version {@link ParticleBuilder#create(Type)}. Use {@link ParticleBuilder#spawn()}
+ * convenience version {@link ParticleBuilder#create(Type)}. Use {@link ParticleBuilder#spawn(World)}
* to finish building and spawn the particle. Between these two, a variety of parameters can be set using the various
* setter methods (see individual method descriptions for more details). These, along with {@code ParticleBuilder.particle(...)},
* return the particle builder instance, allowing them to be chained together to spawn particles using a single line of code.
@@ -32,10 +30,16 @@ import net.minecraft.world.World;
*
* For example, a typical call to the particle builder might look something like this:
*
- * ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).colour(r, g, b).spawn(world);
+ * ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).clr(r, g, b).spawn(world);
+ *
+ * It also goes without saying that this class should only ever be used client-side. Attempting to spawn particles
+ * on the server side will not work and will print a warning to the console.
* @author Electroblob
* @since Wizardry 4.2
*/
+/* This isn't strictly a builder class in the traditional sense, because rather than returning the built object at the
+ * end, it sends it to be processed instead and returns nothing. It's also lazy, see the comment about builder variables
+ * below. */
public final class ParticleBuilder {
/** The static instance of the particle builder. */
@@ -53,11 +57,16 @@ public final class ParticleBuilder {
private float r, g, b;
private float fr, fg, fb;
private double radius;
+ private double rpt;
private int lifetime;
private boolean gravity;
private boolean shaded;
+ private boolean collide;
private float scale;
private Entity entity;
+ private float yaw, pitch;
+ private double tx, ty, tz;
+ private Entity target;
/** Enum constants representing the different types of particle added by wizardry. As of 4.2.0, this has been moved
* from its own file {@code WizardryParticleType} to inside {@link ParticleBuilder}. This allowed its name to be
@@ -67,33 +76,33 @@ public final class ParticleBuilder {
*
* Individual constants have comments detailing their corresponding default parameters. A range of values indicates
* randomness. */
- public static enum Type {
- @Deprecated BLIZZARD,
+ public enum Type {
+ /** 3D-rendered light-beam particle.
Defaults:
Lifetime: 1 tick
Colour: white */ BEAM,
+ /** Helical animated 'buffing' particle.
Defaults:
Lifetime: 15 ticks
+ *
Velocity: (0, 0.27, 0)
Colour: white */ BUFF,
/** Spiral particle, like potions.
Defaults:
Lifetime: 8-40 ticks
Colour: white */ DARK_MAGIC,
/** Single pixel particle.
Defaults:
Lifetime: 16-80 ticks
Colour: white */ DUST,
- /** Rapid flash, like fireworks.
Defaults:
Lifetime: 4 ticks
Colour: white */ FLASH,
+ /** Rapid flash, like fireworks.
Defaults:
Lifetime: 6 ticks
Colour: white */ FLASH,
/** Small shard of ice.
Defaults:
Lifetime: 8-40 ticks
Gravity: true */ ICE,
/** Single leaf.
Defaults:
Lifetime: 10-15 ticks
Velocity: (0, -0.03, 0)
*
Colour: green/brown */ LEAF,
+ /** 3D-rendered lightning particle.
Defaults:
Lifetime: 3 ticks
Colour: blue */ LIGHTNING,
+ /** 2D lightning effect, normally on the ground.
Defaults:
Lifetime: 7 ticks
+ *
Facing: up */ LIGHTNING_PULSE,
/** Bubble that doesn't burst in air.
Defaults:
Lifetime: 8-40 ticks */ MAGIC_BUBBLE,
/** Scaleable, moving flame.
Defaults:
Lifetime: 8-40 ticks
*/ MAGIC_FIRE,
/** Soft-edged round particle.
Defaults:
Lifetime: 8-40 ticks
Colour: white */ PATH,
+ /** Scorch mark.
Defaults:
Lifetime: 100-140 ticks
Colour: black
Fade: black */ SCORCH,
/** Snowflake particle.
Defaults:
Lifetime: 40-50 ticks
Velocity: (0, -0.02, 0) */ SNOW,
/** Animated lightning particle.
Defaults:
Lifetime: 3 ticks */ SPARK,
- /** Animated sparkle particle.
Defaults:
Lifetime: 48-60 ticks
Colour: white */ SPARKLE,
- @Deprecated SPARKLE_ROTATING
+ /** Animated sparkle particle.
Defaults:
Lifetime: 48-60 ticks
Colour: white */ SPARKLE
}
private ParticleBuilder(){
reset();
}
- // Convenience methods
-
- // These may seem to go against the whole point of this class, but of course they return the ParticleBuilder instance
- // so anything else can still be chained onto them - centralising commonly-used particle spawning patterns without
- // losing any of the flexibility of the particle builder. In addition, callers of these methods are still free to
- // change any of the parameters that were set within them afterwards.
+ // ============================================= Core builder methods =============================================
/**
* Starts building a particle of the given type. Static convenience version of
@@ -106,11 +115,406 @@ public final class ParticleBuilder {
return ParticleBuilder.instance.particle(type);
}
+ /**
+ * Starts building a particle of the given type.
+ * @param type The type of particle to build
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is already building.
+ */
+ public ParticleBuilder particle(Type type){
+ if(building) throw new IllegalStateException("Already Building! Particle being built: " + getCurrentParticleString());
+ this.type = type;
+ this.building = true;
+ return this;
+ }
+
+ /** Gets a readable string representation of the current builder parameters; used in error messages. */
+ private String getCurrentParticleString(){
+ return String.format("[ Type: %s, Position: (%s, %s, %s), Velocity: (%s, %s, %s), Colour: (%s, %s, %s), "
+ + "Fade Colour: (%s, %s, %s), Radius: %s, Revs/tick: %s, Lifetime: %s, Gravity: %s, Shaded: %s,"
+ + "Scale: %s, Entity: %s ]",
+ type, x, y, z, vx, vy, vz, r, g, b, fr, fg, fb, radius, rpt, lifetime, gravity, shaded, scale, entity);
+ }
+
+ /**
+ * Sets the position of the particle being built. If unspecified, this defaults to the origin (0, 0, 0). If an entity
+ * is specified using {@link ParticleBuilder#entity(Entity)}, this will be relative to that entity's position.
+ *
+ * Affects: All particle types
+ * @param x The x coordinate to set
+ * @param y The y coordinate to set
+ * @param z The z coordinate to set
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder pos(double x, double y, double z){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ return this;
+ }
+
+ /**
+ * Sets the position of the particle being built. This is a vector-based alternative to {@link ParticleBuilder#pos(
+ * double, double, double)}, allowing for even more concise code when a vector is available.
+ *
+ * Affects: All particle types
+ * @param pos A vector representing the coordinates of the particle to be built.
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder pos(Vec3d pos){
+ return pos(pos.x, pos.y, pos.z);
+ }
+
+ /**
+ * Sets the velocity of the particle being built. If unspecified, this defaults to the particle's default velocity,
+ * specified within its constructor.
+ *
+ * Affects: All particle types except {@link Type#DUST DUST}
+ * @param vx The x velocity to set
+ * @param vy The y velocity to set
+ * @param vz The z velocity to set
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder vel(double vx, double vy, double vz){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.vx = vx;
+ this.vy = vy;
+ this.vz = vz;
+ return this;
+ }
+
+ /**
+ * Sets the velocity of the particle being built. This is a vector-based alternative to {@link ParticleBuilder#vel(
+ * double, double, double)}, allowing for even more concise code when a vector is available.
+ *
+ * Affects: All particle types
+ * @param vel A vector representing the velocity of the particle to be built.
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder vel(Vec3d vel){
+ return vel(vel.x, vel.y, vel.z);
+ }
+
+ /**
+ * Sets the colour of the particle being built. If unspecified, this defaults to the particle's default colour,
+ * specified within its constructor.
+ *
+ * Affects: {@link Type#DARK_MAGIC DARK_MAGIC}, {@link Type#DUST DUST}, {@link Type#FLASH FLASH},
+ * {@link Type#LEAF LEAF}, {@link Type#PATH PATH}, {@link Type#SPARKLE SPARKLE}
+ * @param r The red colour component to set; will be clamped to between 0 and 1
+ * @param g The green colour component to set; will be clamped to between 0 and 1
+ * @param b The blue colour component to set; will be clamped to between 0 and 1
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder clr(float r, float g, float b){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.r = MathHelper.clamp(r, 0, 1);
+ this.g = MathHelper.clamp(g, 0, 1);
+ this.b = MathHelper.clamp(b, 0, 1);
+ return this;
+ }
+
+ /**
+ * Sets the fade colour of the particle being built. If unspecified, this defaults to the whatever the particle's base
+ * colour is.
+ *
+ * Affects: {@link Type#DARK_MAGIC DARK_MAGIC}, {@link Type#DUST DUST}, {@link Type#FLASH FLASH},
+ * {@link Type#LEAF LEAF}, {@link Type#PATH PATH}, {@link Type#SPARKLE SPARKLE}
+ * @param r The red colour component to set; will be clamped to between 0 and 1
+ * @param g The green colour component to set; will be clamped to between 0 and 1
+ * @param b The blue colour component to set; will be clamped to between 0 and 1
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder fade(float r, float g, float b){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.fr = MathHelper.clamp(r, 0, 1);
+ this.fg = MathHelper.clamp(g, 0, 1);
+ this.fb = MathHelper.clamp(b, 0, 1);
+ return this;
+ }
+
+ /**
+ * Sets the scale of the particle being built. If unspecified, this defaults to 1.
+ *
+ * Affects: All particle types
+ * @param scale The scale to set, as a multiple of the particle's default scale
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder scale(float scale){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.scale = scale;
+ return this;
+ }
+
+ /**
+ * Sets the lifetime of the particle being built. If unspecified, this defaults to the particle's default lifetime,
+ * specified within its constructor.
+ *
+ * Affects: All particle types
+ * @param lifetime The lifetime to set in ticks
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder time(int lifetime){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.lifetime = lifetime;
+ return this;
+ }
+
+ /**
+ * Sets the spin parameters of the particle being built. If unspecified, these both default to 0.
+ *
+ * Affects: All particle types
+ * @param radius The rotation radius to set
+ * @param speed The rotation speed to set, in revolutions per tick
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder spin(double radius, double speed){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.radius = radius;
+ this.rpt = speed;
+ return this;
+ }
+
+ /**
+ * Sets the gravity of the particle being built. If unspecified, this defaults to false.
+ *
+ * Affects: {@link Type#ICE ICE}, {@link Type#SPARKLE SPARKLE}
+ * @param gravity True to enable gravity for the particle, false to disable
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder gravity(boolean gravity){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.gravity = gravity;
+ return this;
+ }
+
+ /**
+ * Sets the shading of the particle being built. If unspecified, this defaults to false.
+ *
+ * Affects: All particle types
+ * @param shaded True to enable shading for the particle, false for full brightness
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder shaded(boolean shaded){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.shaded = shaded;
+ return this;
+ }
+
+ /**
+ * Sets the collisions of the particle being built. If unspecified, this defaults to false.
+ *
+ * Affects: All particle types
+ * @param collide True to enable block collisions for the particle, false to disable
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder collide(boolean collide){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.collide = collide;
+ return this;
+ }
+
+ /**
+ * Sets the entity of the particle being built. This will cause the particle to move with the given entity, and will
+ * make the position specified using {@link ParticleBuilder#pos(double, double, double)} relative to that
+ * entity's position.
+ *
+ * Affects: All particle types
+ * @param entity The entity to set (passing in null will do nothing but will not cause any problems, so for the sake
+ * of conciseness it is not necessary to perform a null check on the passed-in argument)
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder entity(Entity entity){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.entity = entity;
+ return this;
+ }
+
+ /**
+ * Sets the rotation of the particle being built. If unspecified, the particle will use the default behaviour and
+ * rotate to face the viewer.
+ *
+ * Affects: All particle types
+ * @param yaw The yaw angle to set in degrees, where 0 is south.
+ * @param pitch The pitch angle to set in degrees, where 0 is horizontal.
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder face(float yaw, float pitch){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.yaw = yaw;
+ this.pitch = pitch;
+ return this;
+ }
+
+ /**
+ * Sets the rotation of the particle being built. This is an {@code EnumFacing}-based alternative to {@link
+ * ParticleBuilder#face(float, float)} which sets the yaw and pitch to the appropriate angles for the given facing.
+ * For example, if the given facing is {@code NORTH}, the particle will render parallel to the north face of blocks.
+ *
+ * Affects: All particle types
+ * @param direction The {@code EnumFacing} direction to set.
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder face(EnumFacing direction){
+ return face(direction.getHorizontalAngle(), direction.getAxis().isVertical() ? direction.getAxisDirection().getOffset() * 90 : 0);
+ }
+
+ /**
+ * Sets the target of the particle being built. This will cause the particle to stretch to touch the given position.
+ *
+ * Affects:
+ * @param x The target x-coordinate to set
+ * @param y The target y-coordinate to set
+ * @param z The target z-coordinate to set
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder target(double x, double y, double z){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.tx = x;
+ this.ty = y;
+ this.tz = z;
+ return this;
+ }
+
+ /**
+ * Sets the target of the particle being built. This is a vector-based alternative to {@link ParticleBuilder#
+ * target(double, double, double)}, allowing for even more concise code when a vector is available.
+ *
+ * Affects: All particle types
+ * @param pos A vector representing the target position of the particle to be built.
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder target(Vec3d pos){
+ return target(pos.x, pos.y, pos.z);
+ }
+
+ /**
+ * Sets the target of the particle being built. This will cause the particle to stretch to touch the given entity.
+ *
+ * Affects:
+ * @param target The entity to set
+ * @return The particle builder instance, allowing other methods to be chained onto this one
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public ParticleBuilder target(Entity target){
+ if(!building) throw new IllegalStateException("Not building yet!");
+ this.target = target;
+ return this;
+ }
+
+ /**
+ * Spawns the particle that has been built and resets the particle builder.
+ * @param world The world in which to spawn the particle
+ * @throws IllegalStateException if the particle builder is not yet building.
+ */
+ public void spawn(World world){
+
+ if(!building) throw new IllegalStateException("Not building yet!");
+
+ if(y < 0 && entity == null) Wizardry.logger.warn("Spawning particle below y = 0 - are you sure the position/entity"
+ + "has been set correctly?");
+
+ if(!world.isRemote){
+ Wizardry.logger.warn("ParticleBuilder.spawn(...) called on the server side! ParticleBuilder has prevented a "
+ + "server crash, but calling it on the server will do nothing. Consider adding a world.isRemote check.");
+ // Must stop here because the line after this if statement would crash the server!
+ reset();
+ return;
+ }
+
+ electroblob.wizardry.client.particle.ParticleWizardry particle = Wizardry.proxy.createParticle(type, world, x, y, z);
+
+ if(particle == null){
+ reset();
+ return;
+ }
+
+ // Anything with an if statement here allows default values to be set in particle constructors
+ particle.multipleParticleScaleBy(scale);
+ if(!Double.isNaN(vx) && !Double.isNaN(vy) && !Double.isNaN(vz)) particle.setVelocity(vx, vy, vz);
+ if(r >= 0 && g >= 0 && b >= 0) particle.setRBGColorF(r, g, b);
+ if(fr >= 0 && fg >= 0 && fb >= 0)particle.setFadeColour(fr, fg, fb);
+ if(lifetime >= 0) particle.setMaxAge(lifetime);
+ particle.setGravity(gravity);
+ particle.setShaded(shaded);
+ particle.setCollisions(collide);
+ if(radius > 0) particle.setSpin(radius, rpt);
+ particle.setEntity(entity);
+ if(!Float.isNaN(yaw) && !Float.isNaN(pitch)) particle.setFacing(yaw, pitch);
+ particle.setTargetPosition(tx, ty, tz);
+ particle.setTargetEntity(target);
+
+ net.minecraft.client.Minecraft.getMinecraft().effectRenderer.addEffect(particle);
+
+ reset();
+ }
+
+ /** Resets the state of the particle builder and resets all the builder variables to their default values. */
+ private void reset(){
+ building = false;
+ type = null;
+ x = 0;
+ y = 0;
+ z = 0;
+ // NaN indicates the velocity was not set (can't use -1 since it could very reasonably be -1)
+ // For all other values -1 indicates the value was not set
+ vx = Double.NaN;
+ vy = Double.NaN;
+ vz = Double.NaN;
+ r = -1;
+ g = -1;
+ b = -1;
+ fr = -1;
+ fg = -1;
+ fb = -1;
+ radius = 0;
+ rpt = 0;
+ lifetime = -1;
+ gravity = false;
+ shaded = false;
+ collide = false;
+ scale = 1;
+ entity = null;
+ yaw = Float.NaN;
+ pitch = Float.NaN;
+ tx = Double.NaN;
+ ty = Double.NaN;
+ tz = Double.NaN;
+ target = null;
+ }
+
+ // ============================================== Convenience methods ==============================================
+
+ // These may seem to go against the whole point of this class, but of course they return the ParticleBuilder instance
+ // so anything else can still be chained onto them - centralising commonly-used particle spawning patterns without
+ // losing any of the flexibility of the particle builder. In addition, callers of these methods are still free to
+ // change any of the parameters that were set within them afterwards.
+
/**
* Starts building a particle of the given type and positions it randomly within the given entity's bounding box.
* Equivalent to calling {@code ParticleBuilder.create(type).pos(...)}; users should chain any additional builder
* methods onto this one and finish with {@code .spawn(world)} as normal.
* Used extensively with summoned creatures; makes code much neater and more concise.
+ *
+ * N.B. this does not cause the particle to move with the given entity.
* @param type The type of particle to build
* @param entity The entity to position the particle at
* @return The particle builder instance, allowing other methods to be chained onto this one
@@ -152,276 +556,6 @@ public final class ParticleBuilder {
return ParticleBuilder.instance.particle(type).pos(px, py, pz);
}
- // Core builder methods
-
- /**
- * Starts building a particle of the given type.
- * @param type The type of particle to build
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is already building.
- */
- public ParticleBuilder particle(Type type){
- if(building) throw new IllegalStateException("Already building!");
- this.type = type;
- this.building = true;
- return this;
- }
-
- /**
- * Sets the position of the particle being built. If unspecified, this defaults to the origin (0, 0, 0).
- *
- * Affects: All particle types
- * @param x The x coordinate to set
- * @param y The y coordinate to set
- * @param z The z coordinate to set
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder pos(double x, double y, double z){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.x = x;
- this.y = y;
- this.z = z;
- return this;
- }
-
- /**
- * Sets the position of the particle being built. This is a vector-based alternative to {@link ParticleBuilder#pos(
- * double, double, double)}, allowing for even more concise code when a vector is available.
- *
- * Affects: All particle types
- * @param pos A vector representing the coordinates of the particle to be built.
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder pos(Vec3d pos){
- return pos(pos.x, pos.y, pos.z);
- }
-
- /**
- * Sets the velocity of the particle being built. If unspecified, this defaults to the particle's default velocity,
- * specified within its constructor.
- *
- * Affects: All particle types except {@link Type#DUST DUST}
- * @param x The x coordinate to set
- * @param y The y coordinate to set
- * @param z The z coordinate to set
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder vel(double vx, double vy, double vz){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.vx = vx;
- this.vy = vy;
- this.vz = vz;
- return this;
- }
-
- /**
- * Sets the velocity of the particle being built. This is a vector-based alternative to {@link ParticleBuilder#vel(
- * double, double, double)}, allowing for even more concise code when a vector is available.
- *
- * Affects: All particle types
- * @param vel A vector representing the velocity of the particle to be built.
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder vel(Vec3d vel){
- return vel(vel.x, vel.y, vel.z);
- }
-
- /**
- * Sets the colour of the particle being built. If unspecified, this defaults to the particle's default colour,
- * specified within its constructor.
- *
- * Affects: {@link Type#DARK_MAGIC DARK_MAGIC}, {@link Type#DUST DUST}, {@link Type#FLASH FLASH},
- * {@link Type#PATH PATH}, {@link Type#SPARKLE SPARKLE}
- * @param r The red colour component to set; will be clamped to between 0 and 1
- * @param g The green colour component to set; will be clamped to between 0 and 1
- * @param b The blue colour component to set; will be clamped to between 0 and 1
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder colour(float r, float g, float b){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.r = MathHelper.clamp(r, 0, 1);
- this.g = MathHelper.clamp(g, 0, 1);
- this.b = MathHelper.clamp(b, 0, 1);
- return this;
- }
-
- /**
- * Sets the fade colour of the particle being built. If unspecified, this defaults to the whatever the particle's base
- * colour is.
- *
- * Affects: {@link Type#DUST DUST}, {@link Type#PATH PATH}, {@link Type#SPARKLE SPARKLE}
- * @param r The red colour component to set; will be clamped to between 0 and 1
- * @param g The green colour component to set; will be clamped to between 0 and 1
- * @param b The blue colour component to set; will be clamped to between 0 and 1
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder fade(float r, float g, float b){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.fr = MathHelper.clamp(r, 0, 1);
- this.fg = MathHelper.clamp(g, 0, 1);
- this.fb = MathHelper.clamp(b, 0, 1);
- return this;
- }
-
- /**
- * Sets the scale of the particle being built. If unspecified, this defaults to 1.
- *
- * Affects: All particle types
- * @param scale The scale to set, as a multiple of the particle's default scale
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder scale(float scale){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.scale = scale;
- return this;
- }
-
- /**
- * Sets the lifetime of the particle being built. If unspecified, this defaults to the particle's default lifetime,
- * specified within its constructor.
- *
- * Affects: All particle types
- * @param lifetime The lifetime to set in ticks
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder lifetime(int lifetime){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.lifetime = lifetime;
- return this;
- }
-
- /**
- * Sets the rotation radius of the particle being built. If unspecified, this defaults to 0.
- *
- * Affects: All particle types
- * @param radius The rotation radius to set
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder radius(double radius){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.radius = radius;
- return this;
- }
-
- /**
- * Sets the gravity of the particle being built. If unspecified, this defaults to false.
- *
- * Affects: {@link Type#ICE ICE}, {@link Type#SPARKLE SPARKLE}
- * @param gravity True to enable gravity for the particle, false to disable
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder gravity(boolean gravity){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.gravity = gravity;
- return this;
- }
-
- /**
- * Sets the shading of the particle being built. If unspecified, this defaults to false.
- *
- * Affects: All particle types
- * @param shaded True to enable shading for the particle, false for full brightness
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder shaded(boolean shaded){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.shaded = shaded;
- return this;
- }
-
- /**
- * Sets the entity of the particle being built. This must be specified for entity-linked particles.
- * @param entity The entity to set
- * @return The particle builder instance, allowing other methods to be chained onto this one
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public ParticleBuilder entity(Entity entity){
- if(!building) throw new IllegalStateException("Not building yet!");
- this.entity = entity;
- return this;
- }
-
- /**
- * Spawns the particle that has been built and resets the particle builder.
- * @param world The world in which to spawn the particle
- * @throws IllegalStateException if the particle builder is not yet building.
- */
- public void spawn(World world){
-
- if(!building) throw new IllegalStateException("Not building yet!");
-
- if(y < 0 && entity == null) Wizardry.logger.warn("Spawning particle below y = 0 - are you sure the position/entity"
- + "has been set correctly?");
-
- if(!world.isRemote){
- Wizardry.logger.warn("ParticleBuilder.spawn(...) called on the server side! ParticleBuilder has prevented a"
- + "server crash, but calling it on the server will do nothing. Consider adding a world.isRemote check.");
- // Must stop here because the line after this if statement would crash the server!
- reset();
- return;
- }
-
- electroblob.wizardry.client.particle.ParticleWizardry particle = Wizardry.proxy.createParticle(type, world, x, y, z);
-
- if(particle == null){
- reset();
- return;
- }
-
- particle.multipleParticleScaleBy(scale);
- if(!Double.isNaN(vx) && !Double.isNaN(vy) && !Double.isNaN(vz)) particle.setVelocity(vx, vy, vz);
- if(r >= 0 && g >= 0 && b >= 0) particle.setRBGColorF(r, g, b);
- if(fr >= 0 && fg >= 0 && fb >= 0){
- particle.setFadeColour(fr, fg, fb);
- }else{
- particle.setFadeColour(r, g, b); // If fade colour was unspecified, it defaults to the main colour
- }
- if(lifetime >= 0) particle.setLifetime(lifetime);
- particle.setGravity(gravity);
- particle.setShaded(shaded);
-
- net.minecraft.client.Minecraft.getMinecraft().effectRenderer.addEffect(particle);
-
- reset();
- }
-
- /** Resets the state of the particle builder and resets all the builder variables to their default values. */
- private void reset(){
- building = false;
- type = null;
- x = 0;
- y = 0;
- z = 0;
- // NaN indicates the velocity was not set (can't use -1 since it could very reasonably be -1)
- // For all other values -1 indicates the value was not set
- vx = Double.NaN;
- vy = Double.NaN;
- vz = Double.NaN;
- r = -1;
- g = -1;
- b = -1;
- fr = -1;
- fg = -1;
- fb = -1;
- radius = 0;
- lifetime = -1;
- gravity = false;
- shaded = false;
- scale = 1;
- entity = null;
- }
-
// Methods for spawning specific effects (similar to the FX playing methods with the ids in RenderGlobal)
/** Spawns spark and large smoke particles (8 of each) within a 1x1x1 volume centred on the given position. */
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_0.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_0.png
new file mode 100644
index 00000000..531b56b5
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_1.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_1.png
new file mode 100644
index 00000000..285df2cc
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_2.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_2.png
new file mode 100644
index 00000000..44c63a7b
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_3.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_3.png
new file mode 100644
index 00000000..b12745e9
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_4.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_4.png
new file mode 100644
index 00000000..389abbd7
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_4.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_5.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_5.png
new file mode 100644
index 00000000..e1bdc75d
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_5.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_6.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_6.png
new file mode 100644
index 00000000..c597f415
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_6.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_7.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_7.png
new file mode 100644
index 00000000..b09a66b4
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/ice_7.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/ice_particles.png b/src/main/resources/assets/ebwizardry/textures/particle/ice_particles.png
deleted file mode 100644
index 96c99ead..00000000
Binary files a/src/main/resources/assets/ebwizardry/textures/particle/ice_particles.png and /dev/null differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_0.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_0.png
new file mode 100644
index 00000000..6c1dabf2
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_1.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_1.png
new file mode 100644
index 00000000..990fba4b
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_10.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_10.png
new file mode 100644
index 00000000..bdc4dc43
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_10.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_11.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_11.png
new file mode 100644
index 00000000..9a6e4d9c
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_11.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_12.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_12.png
new file mode 100644
index 00000000..abc96674
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_12.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_13.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_13.png
new file mode 100644
index 00000000..85124935
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_13.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_14.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_14.png
new file mode 100644
index 00000000..50a9fc70
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_14.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_15.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_15.png
new file mode 100644
index 00000000..8eea8be9
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_15.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_2.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_2.png
new file mode 100644
index 00000000..f9804dc0
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_3.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_3.png
new file mode 100644
index 00000000..d2a7c3c6
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_4.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_4.png
new file mode 100644
index 00000000..7b39ed23
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_4.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_5.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_5.png
new file mode 100644
index 00000000..1aa1c430
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_5.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_6.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_6.png
new file mode 100644
index 00000000..834799fc
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_6.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_7.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_7.png
new file mode 100644
index 00000000..e0a4a796
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_7.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_8.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_8.png
new file mode 100644
index 00000000..399d3a9a
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_8.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_9.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_9.png
new file mode 100644
index 00000000..29c3868d
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/leaf_9.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/leaf_particles.png b/src/main/resources/assets/ebwizardry/textures/particle/leaf_particles.png
deleted file mode 100644
index 627b30ef..00000000
Binary files a/src/main/resources/assets/ebwizardry/textures/particle/leaf_particles.png and /dev/null differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_0.png
new file mode 100644
index 00000000..e8961570
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_1.png
new file mode 100644
index 00000000..d27a4235
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_2.png
new file mode 100644
index 00000000..ac92d34b
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_3.png
new file mode 100644
index 00000000..b78a86ff
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_0_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_0.png
new file mode 100644
index 00000000..60d2e3d2
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_1.png
new file mode 100644
index 00000000..0d98efd6
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_2.png
new file mode 100644
index 00000000..19d23ff3
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_3.png
new file mode 100644
index 00000000..ab8dbf03
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_1_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_0.png
new file mode 100644
index 00000000..4b189159
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_1.png
new file mode 100644
index 00000000..224c39a8
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_2.png
new file mode 100644
index 00000000..bc914ecc
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_3.png
new file mode 100644
index 00000000..b2d2c942
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_2_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_0.png
new file mode 100644
index 00000000..3b33edd7
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_1.png
new file mode 100644
index 00000000..bd62e1ca
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_2.png
new file mode 100644
index 00000000..e5c306fa
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_3.png
new file mode 100644
index 00000000..ee15f872
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_3_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_0.png
new file mode 100644
index 00000000..b5d0830b
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_1.png
new file mode 100644
index 00000000..96304d15
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_2.png
new file mode 100644
index 00000000..36a82906
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_3.png
new file mode 100644
index 00000000..a185c530
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_4_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_0.png
new file mode 100644
index 00000000..3b9dd28b
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_1.png
new file mode 100644
index 00000000..6607b21f
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_2.png
new file mode 100644
index 00000000..706d10a1
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_3.png
new file mode 100644
index 00000000..4a67952b
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_5_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_0.png
new file mode 100644
index 00000000..07ac3f77
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_1.png
new file mode 100644
index 00000000..c7a7d874
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_2.png
new file mode 100644
index 00000000..3dddd174
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_3.png
new file mode 100644
index 00000000..e84fbc4d
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_6_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_0.png
new file mode 100644
index 00000000..7bc98d4e
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_1.png
new file mode 100644
index 00000000..5ec85410
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_2.png
new file mode 100644
index 00000000..249ea1fc
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_3.png
new file mode 100644
index 00000000..a7e8abb6
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/lightning_7_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/lightning_particles.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_particles.png
deleted file mode 100644
index 94dc49c5..00000000
Binary files a/src/main/resources/assets/ebwizardry/textures/particle/lightning_particles.png and /dev/null differ
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_0.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_0.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_0.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_0.png
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_1.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_1.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_1.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_1.png
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_2.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_2.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_2.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_2.png
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_3.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_3.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_3.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_3.png
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_4.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_4.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_4.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_4.png
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_5.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_5.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_5.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_5.png
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_6.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_6.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_6.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_6.png
diff --git a/src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_7.png b/src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_7.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/entity/lightning_pulse_7.png
rename to src/main/resources/assets/ebwizardry/textures/particle/lightning_pulse_7.png
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/path_particles.png b/src/main/resources/assets/ebwizardry/textures/particle/path.png
similarity index 100%
rename from src/main/resources/assets/ebwizardry/textures/particle/path_particles.png
rename to src/main/resources/assets/ebwizardry/textures/particle/path.png
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_0.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_0.png
new file mode 100644
index 00000000..b2d2a22d
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_1.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_1.png
new file mode 100644
index 00000000..7eba17d2
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_2.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_2.png
new file mode 100644
index 00000000..8a908c43
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_3.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_3.png
new file mode 100644
index 00000000..7f09067a
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_4.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_4.png
new file mode 100644
index 00000000..65765f7b
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_4.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_5.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_5.png
new file mode 100644
index 00000000..904c7093
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_5.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_6.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_6.png
new file mode 100644
index 00000000..454b064c
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_6.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/scorch_7.png b/src/main/resources/assets/ebwizardry/textures/particle/scorch_7.png
new file mode 100644
index 00000000..547fc6ef
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/scorch_7.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/snow_0.png b/src/main/resources/assets/ebwizardry/textures/particle/snow_0.png
new file mode 100644
index 00000000..53ed7b63
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/snow_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/snow_1.png b/src/main/resources/assets/ebwizardry/textures/particle/snow_1.png
new file mode 100644
index 00000000..6d792d6d
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/snow_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/snow_2.png b/src/main/resources/assets/ebwizardry/textures/particle/snow_2.png
new file mode 100644
index 00000000..6e8d60a1
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/snow_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/snow_3.png b/src/main/resources/assets/ebwizardry/textures/particle/snow_3.png
new file mode 100644
index 00000000..3f6a9c91
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/snow_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/snow_particles.png b/src/main/resources/assets/ebwizardry/textures/particle/snow_particles.png
deleted file mode 100644
index 9d636de1..00000000
Binary files a/src/main/resources/assets/ebwizardry/textures/particle/snow_particles.png and /dev/null differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_0.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_0.png
new file mode 100644
index 00000000..be4ee4f1
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_0.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_1.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_1.png
new file mode 100644
index 00000000..5264ba88
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_1.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_10.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_10.png
new file mode 100644
index 00000000..74f32788
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_10.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_2.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_2.png
new file mode 100644
index 00000000..8db620f5
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_2.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_3.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_3.png
new file mode 100644
index 00000000..dcad4910
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_3.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_4.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_4.png
new file mode 100644
index 00000000..9f2104b4
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_4.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_5.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_5.png
new file mode 100644
index 00000000..9783e657
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_5.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_6.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_6.png
new file mode 100644
index 00000000..985abad9
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_6.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_7.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_7.png
new file mode 100644
index 00000000..041dccff
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_7.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_8.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_8.png
new file mode 100644
index 00000000..4da926fe
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_8.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_9.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_9.png
new file mode 100644
index 00000000..f11b9688
Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_9.png differ
diff --git a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_particles.png b/src/main/resources/assets/ebwizardry/textures/particle/sparkle_particles.png
deleted file mode 100644
index d767eac3..00000000
Binary files a/src/main/resources/assets/ebwizardry/textures/particle/sparkle_particles.png and /dev/null differ