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
@@ -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();
}
}
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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);
}
}
}
@@ -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);
@@ -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);
}
}
@@ -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;
}
}
@@ -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,
@@ -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);
}
}
}
}
@@ -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);
}
}
}
@@ -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){
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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.
@@ -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);
}
}
@@ -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);
}
}
@@ -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){
@@ -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);
}
@@ -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);
}
}