The great particle refactoring part 1: Introducing ParticleBuilder!

Adds ParticleBuilder to replace the particle spawning methods in the proxies, and changes all particle spawning to use the builder except for in the spell classes, which are to be reorganised first.
This commit is contained in:
Electroblob
2018-06-05 21:13:41 +01:00
parent 466b3bbc27
commit d91a3e056a
119 changed files with 722 additions and 972 deletions
@@ -11,15 +11,14 @@ public class ParticleBlizzard extends ParticleSnow {
private double radius;
private double speed;
public ParticleBlizzard(World world, int maxAge, double originX, double originZ, double radius, double yPos){
super(world, 0, 0, 0, 0, 0, 0, maxAge);
public ParticleBlizzard(World world, double ox, double y, double oz){
super(world, ox, y, oz);
this.angle = this.rand.nextDouble() * Math.PI * 2;
double x = originX - Math.cos(angle) * radius;
double z = originZ + radius * Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
double x = ox - Math.cos(angle) * radius;
double z = oz + radius * Math.sin(angle);
this.setPosition(x, y, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosY = y;
this.prevPosZ = z;
if(rand.nextBoolean()){
speed = rand.nextDouble() * 2 + 1;
@@ -29,12 +28,6 @@ public class ParticleBlizzard extends ParticleSnow {
this.multipleParticleScaleBy(1.5f);
}
@Override
public void init(){
super.init();
this.fullBrightness = true;
}
// @Override
// public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float
// rotationZ, float rotationYZ, float rotationXY, float rotationXZ){
@@ -13,43 +13,14 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/**
* Abstract superclass for all particles that use custom textures. This is intended to centralise as much code as
* possible; all subclasses need to do is to define the texture to use, how the frames are arranged (and which to
* choose), and any properties like gravity and collisions.
*
* @author Electroblob
* @since Wizardry 1.2
*/
@SideOnly(Side.CLIENT)
public abstract class ParticleCustomTexture extends Particle {
@Deprecated
public abstract class ParticleCustomTexture extends ParticleWizardry {
/** True if the particle always renders at full brightness. Defaults to false. */
protected boolean fullBrightness = false;
public ParticleCustomTexture(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz);
this.motionX = vx;
this.motionY = vy;
this.motionZ = vz;
this.init();
public ParticleCustomTexture(World world, double x, double y, double z){
super(world, x, y, z);
}
public ParticleCustomTexture(World world, double x, double y, double z, double vx, double vy, double vz,
int maxAge){
this(world, x, y, z, vx, vy, vz);
this.particleMaxAge = maxAge;
}
/**
* Called from both constructors to set constants, avoiding duplicate code. Common fields to set here include:
* particleScale, particleGravity, canCollide, fullBrightness and setting the texture index.
*/
public abstract void init();
/**
* Returns a ResourceLocation for the particle's texture sheet. Do not create a new ResourceLocation in this method,
* only return a constant.
@@ -83,59 +54,6 @@ public abstract class ParticleCustomTexture extends Particle {
this.particleTextureIndexY = index / getYFrames();
}
// Overridden to fix the bug with vanilla that makes particles frictionless. (y != y... seriously, Mojang?)
// TESTME: Probably no longer necessary.
// @Override
// public void move(double x, double y, double z){
//
// double d0 = y;
//
// if (this.canCollide)
// {
// List<AxisAlignedBB> list = this.world.getCollisionBoxes((Entity)null, this.getBoundingBox().addCoord(x, y, z));
//
// for (AxisAlignedBB axisalignedbb : list)
// {
// y = axisalignedbb.calculateYOffset(this.getBoundingBox(), y);
// }
//
// this.setBoundingBox(this.getBoundingBox().offset(0.0D, y, 0.0D));
//
// for (AxisAlignedBB axisalignedbb1 : list)
// {
// x = axisalignedbb1.calculateXOffset(this.getBoundingBox(), x);
// }
//
// this.setBoundingBox(this.getBoundingBox().offset(x, 0.0D, 0.0D));
//
// for (AxisAlignedBB axisalignedbb2 : list)
// {
// z = axisalignedbb2.calculateZOffset(this.getBoundingBox(), z);
// }
//
// this.setBoundingBox(this.getBoundingBox().offset(0.0D, 0.0D, z));
// }
// else
// {
// this.setBoundingBox(this.getBoundingBox().offset(x, y, z));
// }
//
// this.resetPositionToBB();
// this.onGround = d0 != y && d0 < 0.0D;
//
// /* Can never be true! - But this doesn't seem to make any difference anyway.
// if (x != x)
// {
// this.motionX = 0.0D;
// }
//
// if (z != z)
// {
// this.motionZ = 0.0D;
// }
// */
// }
// Overridden to bind the new texture. I think this can be done with TextureAtlasSprite, but this works as it is
// so I'm not changing it for the time being.
@Override
@@ -211,9 +129,4 @@ public abstract class ParticleCustomTexture extends Particle {
*/
public void undoGLStateChanges(){
}
@Override
public int getBrightnessForRender(float partialTick){
return fullBrightness ? 15728880 : super.getBrightnessForRender(partialTick);
}
}
@@ -1,6 +1,5 @@
package electroblob.wizardry.client.particle;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
@@ -8,20 +7,16 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleDarkMagic extends Particle {
public class ParticleDarkMagic extends ParticleWizardry {
/** Base spell texture index */
private int baseSpellTextureIndex = 128;
public ParticleDarkMagic(World par1World, double par2, double par4, double par6, double par8, double par10,
double par12, float r, float g, float b){
super(par1World, par2, par4, par6, par8, par10, par12);
public ParticleDarkMagic(World world, double x, double y, double z){
super(world, x, y, z);
this.motionY *= 0.20000000298023224D;
this.particleRed = r;
this.particleGreen = g;
this.particleBlue = b;
this.setRBGColorF(1, 1, 1);
this.particleScale *= 0.75F;
this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D));
this.canCollide = true;
@@ -43,9 +38,7 @@ public class ParticleDarkMagic extends Particle {
super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ);
}
/**
* Called to update the entity's position/logic.
*/
@Override
public void onUpdate(){
this.prevPosX = this.posX;
this.prevPosY = this.posY;
@@ -1,34 +1,25 @@
package electroblob.wizardry.client.particle;
import net.minecraft.client.particle.Particle;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleDust extends Particle {
public class ParticleDust extends ParticleWizardry {
private final boolean shaded;
public ParticleDust(World par1World, double x, double y, double z, double par8, double par10, double par12, float r,
float g, float b, boolean shaded){
super(par1World, x, y, z, par8, par10, par12);
this.particleRed = r;
this.particleGreen = g;
this.particleBlue = b;
public ParticleDust(World world, double x, double y, double z){
super(world, x, y, z);
this.setParticleTextureIndex(0);
this.setSize(0.01F, 0.01F);
// Defaults
this.particleScale *= this.rand.nextFloat() + 0.2F;
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
this.particleMaxAge = (int)(16.0D / (Math.random() * 0.8D + 0.2D));
this.shaded = shaded;
this.setRBGColorF(1, 1, 1);
}
/**
* Called to update the entity's position/logic.
*/
@Override
public void onUpdate(){
this.prevPosX = this.posX;
this.prevPosY = this.posY;
@@ -39,10 +30,4 @@ public class ParticleDust extends Particle {
this.setExpired();
}
}
@Override
public int getBrightnessForRender(float par1){
return shaded ? super.getBrightnessForRender(par1) : 15728880;
}
/* @Override public float getBrightness(float par1) { return shaded ? super.getBrightness(par1) : 1.0F; } */
}
@@ -9,26 +9,20 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleIce extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/ice_particles.png");
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/ice_particles.png");
public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz);
}
public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge);
}
@Override
public void init(){
public ParticleIce(World world, double x, double y, double z){
super(world, x, y, z);
this.setParticleTextureIndex(rand.nextInt(8));
this.particleScale *= 0.75f;
this.particleGravity = 1;
this.canCollide = true;
this.fullBrightness = true;
// Defaults
this.particleScale *= 0.75f;
this.setGravity(true);
this.shaded = false;
}
@Override
public ResourceLocation getTexture(){
return TEXTURE;
@@ -12,16 +12,10 @@ public class ParticleLeaf extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/leaf_particles.png");
public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz);
}
public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge);
}
@Override
public void init(){
public ParticleLeaf(World world, double x, double y, double z){
super(world, x, y, z);
this.setVelocity(0, -0.03, 0);
this.setLifetime(10 + rand.nextInt(5));
this.setParticleTextureIndex(rand.nextInt(16));
this.particleScale *= 1.4f;
this.particleGravity = 0;
@@ -8,24 +8,21 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleMagicFlame extends Particle {
public class ParticleMagicFlame extends ParticleWizardry {
/** The scale of the flame particle */
private float flameScale;
public ParticleMagicFlame(World par1World, double par2, double par4, double par6, double par8, double par10,
double par12, int maxAge, float scale){
super(par1World, par2, par4, par6, par8, par10, par12);
this.motionX = this.motionX * 0.009999999776482582D + par8;
this.motionY = this.motionY * 0.009999999776482582D + par10;
this.motionZ = this.motionZ * 0.009999999776482582D + par12;
this.flameScale = scale;
this.particleRed = this.particleGreen = this.particleBlue = 1.0F;
if(maxAge == 0){
this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D));
}else{
this.particleMaxAge = maxAge;
}
public ParticleMagicFlame(World world, double x, double y, double z){
super(world, x, y, z);
// Not sure what these did but they sure as heck won't do anything now...
// TESTME: If it looks the same as before, delete these.
// this.motionX = this.motionX * 0.009999999776482582D + par8;
// this.motionY = this.motionY * 0.009999999776482582D + par10;
// this.motionZ = this.motionZ * 0.009999999776482582D + par12;
this.flameScale = 1 + world.rand.nextFloat();
this.setRBGColorF(1, 1, 1);
this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D));
// IDEA: Make the particles for ray spells collide properly and not spawn on the other side of stuff.
this.canCollide = false;
this.setParticleTextureIndex(48);
@@ -43,4 +40,10 @@ public class ParticleMagicFlame extends Particle {
public int getBrightnessForRender(float par1){
return 256;
}
@Override
public Particle multipleParticleScaleBy(float scale){
this.flameScale *= scale;
return super.multipleParticleScaleBy(scale);
}
}
@@ -19,32 +19,20 @@ public class ParticlePath extends ParticleCustomTexture {
private final double originX, originY, originZ;
public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b){
super(world, x, y, z, vx, vy, vz);
this.setRBGColorF(r, g, b);
public ParticlePath(World world, double x, double y, double z){
super(world, x, y, z);
this.originX = x;
this.originY = y;
this.originZ = z;
}
public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge);
this.setRBGColorF(r, g, b);
this.originX = x;
this.originY = y;
this.originZ = z;
}
@Override
public void init(){
this.setParticleTextureIndex(0);
// Set to a constant to remove the randomness from Particle.
this.particleScale = 1.25f;
this.particleGravity = 0;
this.fullBrightness = true;
this.shaded = false;
this.canCollide = false;
this.setRBGColorF(1, 1, 1);
}
@Override
@@ -11,16 +11,15 @@ public class ParticleRotatingSparkle extends ParticleSparkle {
private double radius;
private double speed;
public ParticleRotatingSparkle(World world, int maxAge, double originX, double originZ, double radius, double yPos,
float r, float g, float b){
super(world, 0, 0, 0, 0, 0, 0, r, g, b, maxAge);
public ParticleRotatingSparkle(World world, double ox, double y, double oz){
super(world, ox, y, oz);
this.angle = this.rand.nextDouble() * Math.PI * 2;
double x = originX - Math.cos(angle) * radius;
double z = originZ + radius * Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
double x = ox - Math.cos(angle) * radius;
double z = oz + radius * Math.sin(angle);
this.radius = 1; // TODO: Find a suitable default value
this.setPosition(x, y, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosY = y;
this.prevPosZ = z;
if(rand.nextBoolean()){
speed = rand.nextDouble() * 2 + 1;
@@ -12,22 +12,16 @@ public class ParticleSnow extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/snow_particles.png");
public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz);
}
public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge);
}
@Override
public void init(){
public ParticleSnow(World world, double x, double y, double z){
super(world, x, y, z);
this.setParticleTextureIndex(rand.nextInt(8));
this.setVelocity(0, -0.02, 0);
this.particleScale *= 0.6f;
this.particleGravity = 0;
this.canCollide = true;
this.setLifetime(40 + rand.nextInt(10));
}
@Override
public ResourceLocation getTexture(){
return TEXTURE;
@@ -16,18 +16,14 @@ public class ParticleSpark extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/lightning_particles.png");
public ParticleSpark(World world, double x, double y, double z, double vx, double vy, double vz){
// Max age is always 3.
super(world, x, y, z, vx, vy, vz, 3);
}
@Override
public void init(){
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);
this.particleScale *= 1.4f;
this.fullBrightness = true;
this.shaded = false;
this.canCollide = false;
this.setLifetime(3); // Lifetime defaults to 3 (and is very unlikely to be changed)
}
@Override
@@ -9,66 +9,33 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleSparkle extends ParticleCustomTexture {
/* I have now figured out what particle factories are for: they separate out the individual uses of the varargs
* parameter in spawnParticle so they are kept with the particle class. For my purposes, it would be easier to do
* that in the particle spawning method itself. */
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/sparkle_particles.png");
// NOTE: Uncomment once 2.1.0 is released
// private final float initialRed;
// private final float initialGreen;
// private final float initialBlue;
// Implementation of colour fading (perhaps these belong in ParticleWizardry?)
private float initialRed;
private float initialGreen;
private float initialBlue;
// TODO: Assign these via the constructors, as part of the refactoring for particle parameters.
// NOTE: Uncomment once 2.1.0 is released
// private final float fadeRed = 1;
// private final float fadeGreen = 1;
// private final float fadeBlue = 0;
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b){
super(world, x, y, z, vx, vy, vz);
this.setRBGColorF(r, g, b);
// NOTE: Uncomment once 2.1.0 is released
// initialRed = r;
// initialGreen = g;
// initialBlue = b;
public ParticleSparkle(World world, double x, double y, double z){
super(world, x, y, z);
this.setRBGColorF(1, 1, 1);
this.particleMaxAge = 48 + this.rand.nextInt(12);
}
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge);
this.setRBGColorF(r, g, b);
// NOTE: Uncomment once 2.1.0 is released
// initialRed = r;
// initialGreen = g;
// initialBlue = b;
}
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b, boolean doGravity){
this(world, x, y, z, vx, vy, vz, r, g, b);
this.particleGravity = doGravity ? 1 : 0;
}
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b, int maxAge, boolean doGravity){
this(world, x, y, z, vx, vy, vz, r, g, b, maxAge);
this.particleGravity = doGravity ? 1 : 0;
}
@Override
public void init(){
this.setParticleTextureIndex(rand.nextInt(16));
this.particleScale *= 0.75f;
this.particleGravity = 0;
this.canCollide = false;
this.fullBrightness = true;
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;
@@ -88,17 +55,20 @@ public class ParticleSparkle extends ParticleCustomTexture {
public void onUpdate(){
super.onUpdate();
// Fading
if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
}
// Colour fading TODO Uncomment once 2.1.0 is released
// float ageFraction = (float)this.particleAge / (float)this.particleMaxAge;
// this.setRBGColorF(this.initialRed + (this.fadeRed - this.initialRed)*ageFraction,
// this.initialGreen + (this.fadeGreen - this.initialGreen)*ageFraction,
// this.initialBlue + (this.fadeBlue - this.initialBlue)*ageFraction);
// 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);
}