The great particle refactoring part 2: Splitting and Streamlining!

- Splits all particle textures into individual files intead of sprite sheets
- Replaces arc and lightning pulse entities with particles
- Pulls particle code up to the general ParticleWizardry so behaviours such as spin can be applied to all particle types
- Renames a few ParticleBuilder methods for conciseness.
- Adds a few new particle effects to various spells and entities, with a slight tweak to EntityMagicArrow#onBlockHit to facilitate impact effects
This commit is contained in:
Electroblob77
2019-01-01 21:40:04 +00:00
parent ad363c64af
commit b374f71533
201 changed files with 1682 additions and 1551 deletions
@@ -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){
@@ -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);
}
}
@@ -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){
@@ -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
@@ -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);
}
@@ -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);
}
}
@@ -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.
@@ -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.
@@ -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
@@ -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(),
@@ -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);
}
}
}
@@ -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.
@@ -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);
}
}
@@ -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);
}
}