/**
Copyright (C) <2015> <coolAlias>
This file is part of coolAlias' Zelda Sword Skills Minecraft Mod; as such,
you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package zeldaswordskills.client.particle;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.particle.EntityDiggingFX;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/**
* This is an invisible particle that spawns a ring of Cyclone particles, which
* move along an axis while rotating around it.
*
* @author Hunternif
*/
@SideOnly(Side.CLIENT)
public class FXCycloneRing extends EntityFX {
public static final EntityDiggingFX.Factory factory = new EntityDiggingFX.Factory();
public static float ascendVelocity = 0.2f;
public static int puffsPerRing = 8;
public static float maxRingHeight = 4;
public static float baseAngleVelocity = 0.4f;
private EntityFX[] puffs;
private float dAngle;
private float yaw;
private float pitch;
private Vec3 axis;
private float ringHeight;
private float baseAngle;
public FXCycloneRing(World world, double x, double y, double z, double velX, double velY, double velZ,
float yaw, float pitch, float alpha, EffectRenderer renderer) {
super(world, x, y, z);
// Because the EntityFX constructor with velocities screws them up:
motionX = velX;
motionY = velY;
motionZ = velZ;
axis = new Vec3(0, 1, 0);
particleGravity = 0;
this.yaw = yaw;
this.pitch = pitch;
axis.rotatePitch(pitch);
axis.rotateYaw(yaw);
ringHeight = ascendVelocity; // starts just a bit off the ground
baseAngle = 0;
this.particleAlpha = alpha;
puffs = new EntityFX[puffsPerRing];
for (int i = 0; i < puffsPerRing; i++) {
if (Math.random() < 0.07) {
// Add *dust* of the block below instead of the smoke puff
int xInt = MathHelper.floor_double(x);
int yInt = MathHelper.floor_double(y) - 1;
int zInt = MathHelper.floor_double(z);
IBlockState state = world.getBlockState(new BlockPos(xInt, yInt, zInt));
if (state.getBlock() != Blocks.air) {
// The "y + 0.1" below is a workaround for the bug that digging
// particles stayed on the ground and didn't fly up for some reason.
// func_174845_l is the new applyColourModifier
puffs[i] = ((EntityDiggingFX) factory.getEntityFX(EnumParticleTypes.BLOCK_CRACK.getParticleID(), world, x, y+0.1, z, velX, velY, velZ, Block.getStateId(state))).func_174845_l().multipleParticleScaleBy(0.5f);
//puffs[i] = new EntityDiggingFX(world, x, y+0.1, z, velX, velY, velZ, state).applyColourMultiplier(xInt, yInt, zInt).multipleParticleScaleBy(0.5f);
renderer.addEffect(puffs[i]);
continue;
}
}
puffs[i] = new ParticleCyclone(world, x, y, z, velX, velY, velZ);
puffs[i].setAlphaF(particleAlpha);
renderer.addEffect(puffs[i]);
}
dAngle = 2 * (float)Math.PI / ((float) puffs.length);
}
@Override
public void setAlphaF(float alpha) {
super.setAlphaF(alpha);
for (int i = 0; i < puffs.length; i++) {
puffs[i].setAlphaF(alpha);
}
}
@Override
public void renderParticle(WorldRenderer renderer, Entity entity, float partialTick, float rotX, float rotXZ, float rotZ, float rotYZ, float rotXY) {}
@Override
public void onUpdate() {
//super.onUpdate();
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.posX += motionX;
this.posY += motionY;
this.posZ += motionZ;
float ringWidth = getWidthVSHeight(ringHeight);
for (int i = 0; i < puffs.length; i++) {
Vec3 vec = new Vec3(ringWidth, 0, 0);
vec.rotateYaw(baseAngle + ((float)i)*dAngle);
vec.rotatePitch(pitch);
vec.rotateYaw(yaw);
puffs[i].motionX = posX + motionX + vec.xCoord - puffs[i].posX;
puffs[i].motionY = posY + motionY + vec.yCoord - puffs[i].posY;
puffs[i].motionZ = posZ + motionZ + vec.zCoord - puffs[i].posZ;
}
if (axis != null) {
if (ringHeight < maxRingHeight) {
//motionX = axis.xCoord * ascendVelocity;
//motionY = axis.yCoord * ascendVelocity;
//motionZ = axis.zCoord * ascendVelocity;
//moveEntity(motionX, motionY, motionZ);
posX += axis.xCoord * ascendVelocity;
posY += axis.yCoord * ascendVelocity;
posZ += axis.zCoord * ascendVelocity;
ringHeight += ascendVelocity;
} else {
for (int i = 0; i < puffsPerRing; i++) {
puffs[i].setDead();
}
setDead();
}
}
baseAngle += baseAngleVelocity;
if (baseAngle > 2*Math.PI) {
baseAngle -= 2*Math.PI;
}
}
public static float getWidthVSHeight(float height) {
return height*0.2f + 0.15f;
}
}