blob: 8e122c138e93ebc8b5fc0f9c2b76ea22d3461632 [file] [log] [blame] [raw]
package mekanism.common.entity;
import java.util.List;
import mekanism.api.Coord4D;
import mekanism.api.Pos3D;
import mekanism.api.util.StackUtils;
import mekanism.common.util.MekanismUtils;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import io.netty.buffer.ByteBuf;
public class EntityFlame extends Entity implements IEntityAdditionalSpawnData
{
public static final int LIFESPAN = 80;
public static final int DAMAGE = 10;
public Entity owner = null;
public EntityFlame(World world)
{
super(world);
setSize(0.5F, 0.5F);
}
public EntityFlame(EntityPlayer player)
{
this(player.worldObj);
Pos3D playerPos = new Pos3D(player).translate(0, 1.6, 0);
Pos3D flameVec = new Pos3D(1, 1, 1);
flameVec.multiply(new Pos3D(player.getLook(90)));
flameVec.rotateYaw(6);
Pos3D mergedVec = playerPos.clone().translate(flameVec);
setPosition(mergedVec.xPos, mergedVec.yPos, mergedVec.zPos);
Pos3D motion = new Pos3D(0.4, 0.4, 0.4);
motion.multiply(new Pos3D(player.getLookVec()));
setHeading(motion);
motionX = motion.xPos;
motionY = motion.yPos;
motionZ = motion.zPos;
owner = player;
}
public void setHeading(Pos3D motion)
{
float d = MathHelper.sqrt_double((motion.xPos * motion.xPos) + (motion.zPos * motion.zPos));
prevRotationYaw = rotationYaw = (float)(Math.atan2(motion.xPos, motion.zPos) * 180.0D / Math.PI);
prevRotationPitch = rotationPitch = (float)(Math.atan2(motion.yPos, d) * 180.0D / Math.PI);
}
@Override
public void onUpdate()
{
if(isDead)
{
return;
}
ticksExisted++;
prevPosX = posX;
prevPosY = posY;
prevPosZ = posZ;
prevRotationPitch = rotationPitch;
prevRotationYaw = rotationYaw;
posX += motionX;
posY += motionY;
posZ += motionZ;
setPosition(posX, posY, posZ);
calculateVector();
if(ticksExisted > LIFESPAN)
{
setDead();
return;
}
}
private void calculateVector()
{
Vec3 localVec = Vec3.createVectorHelper(posX, posY, posZ);
Vec3 motionVec = Vec3.createVectorHelper(posX + motionX*2, posY + motionY*2, posZ + motionZ*2);
MovingObjectPosition mop = worldObj.func_147447_a(localVec, motionVec, true, false, false);
localVec = Vec3.createVectorHelper(posX, posY, posZ);
motionVec = Vec3.createVectorHelper(posX + motionX, posY + motionY, posZ + motionZ);
if(mop != null)
{
motionVec = Vec3.createVectorHelper(mop.hitVec.xCoord, mop.hitVec.yCoord, mop.hitVec.zCoord);
}
Entity entity = null;
List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.addCoord(motionX, motionY, motionZ).expand(1.0D, 1.0D, 1.0D));
double entityDist = 0.0D;
int i;
for(Entity entity1 : (List<Entity>)list)
{
if((entity1 instanceof EntityItem || entity1.canBeCollidedWith()) && entity1 != owner)
{
float boundsScale = 0.3F;
AxisAlignedBB newBounds = entity1.boundingBox.expand((double)boundsScale, (double)boundsScale, (double)boundsScale);
MovingObjectPosition movingobjectposition1 = newBounds.calculateIntercept(localVec, motionVec);
if(movingobjectposition1 != null)
{
double dist = localVec.distanceTo(movingobjectposition1.hitVec);
if(dist < entityDist || entityDist == 0)
{
entity = entity1;
entityDist = dist;
}
}
}
}
if(entity != null)
{
mop = new MovingObjectPosition(entity);
}
if(mop != null && mop.entityHit instanceof EntityPlayer)
{
EntityPlayer entityplayer = (EntityPlayer)mop.entityHit;
if(entityplayer.capabilities.disableDamage || owner instanceof EntityPlayer && !((EntityPlayer)owner).canAttackPlayer(entityplayer))
{
mop = null;
}
}
if(mop != null)
{
if(mop.entityHit != null && !mop.entityHit.isImmuneToFire())
{
if(mop.entityHit instanceof EntityItem)
{
if(mop.entityHit.ticksExisted > 80)
{
if(!smeltItem((EntityItem)mop.entityHit))
{
burn(mop.entityHit);
}
}
}
else {
burn(mop.entityHit);
}
}
else {
Block block = worldObj.getBlock(mop.blockX, mop.blockY, mop.blockZ);
int meta = worldObj.getBlockMetadata(mop.blockX, mop.blockY, mop.blockZ);
boolean fluid = MekanismUtils.isFluid(worldObj, mop.blockX, mop.blockY, mop.blockZ) || MekanismUtils.isDeadFluid(worldObj, mop.blockX, mop.blockY, mop.blockZ);
Coord4D sideCoord = new Coord4D(mop.blockX, mop.blockY, mop.blockZ, worldObj.provider.dimensionId).getFromSide(ForgeDirection.getOrientation(mop.sideHit));
if(!fluid && (sideCoord.isAirBlock(worldObj) || sideCoord.isReplaceable(worldObj)))
{
if(!smeltBlock(new Coord4D(mop.blockX, mop.blockY, mop.blockZ)))
{
if(!worldObj.isRemote)
{
worldObj.setBlock(sideCoord.xCoord, sideCoord.yCoord, sideCoord.zCoord, Blocks.fire);
}
}
}
if(fluid)
{
spawnParticlesAt(new Pos3D(this));
worldObj.playSoundAtEntity(this, "random.fizz", 1.0F, 1.0F);
}
}
setDead();
}
}
private boolean smeltItem(EntityItem item)
{
ItemStack result = FurnaceRecipes.smelting().getSmeltingResult(item.getEntityItem());
if(result != null)
{
item.setEntityItemStack(StackUtils.size(result, item.getEntityItem().stackSize));
item.ticksExisted = 0;
spawnParticlesAt(new Pos3D(item));
worldObj.playSoundAtEntity(item, "random.fizz", 1.0F, 1.0F);
return true;
}
return false;
}
private boolean smeltBlock(Coord4D block)
{
ItemStack stack = block.getStack(worldObj);
if(stack == null)
{
return false;
}
ItemStack result = FurnaceRecipes.smelting().getSmeltingResult(block.getStack(worldObj));
if(result != null)
{
if(!worldObj.isRemote)
{
Block b = block.getBlock(worldObj);
int meta = block.getMetadata(worldObj);
if(Block.getBlockFromItem(result.getItem()) != Blocks.air)
{
worldObj.setBlock(block.xCoord, block.yCoord, block.zCoord, Block.getBlockFromItem(result.getItem()), result.getItemDamage(), 3);
}
else {
worldObj.setBlockToAir(block.xCoord, block.yCoord, block.zCoord);
EntityItem item = new EntityItem(worldObj, block.xCoord + 0.5, block.yCoord + 0.5, block.zCoord + 0.5, result.copy());
item.motionX = 0;
item.motionY = 0;
item.motionZ = 0;
worldObj.spawnEntityInWorld(item);
}
worldObj.playAuxSFXAtEntity(null, 2001, block.xCoord, block.yCoord, block.zCoord, Block.getIdFromBlock(b) + (meta << 12));
}
spawnParticlesAt(new Pos3D(block).translate(0.5, 0.5, 0.5));
return true;
}
return false;
}
private void burn(Entity entity)
{
entity.setFire(20);
entity.attackEntityFrom(getFlamethrowerDamage(), DAMAGE);
}
private DamageSource getFlamethrowerDamage()
{
if(owner == null)
{
return DamageSource.causeThrownDamage(this, this);
}
else {
return DamageSource.causeThrownDamage(this, owner);
}
}
private void spawnParticlesAt(Pos3D pos)
{
for(int i = 0; i < 10; i++)
{
worldObj.spawnParticle("smoke", pos.xPos + (rand.nextFloat()-0.5), pos.yPos + (rand.nextFloat()-0.5), pos.zPos + (rand.nextFloat()-0.5), 0, 0, 0);
}
}
@Override
protected void entityInit() {}
@Override
protected void readEntityFromNBT(NBTTagCompound nbtTags) {}
@Override
protected void writeEntityToNBT(NBTTagCompound nbtTags) {}
@Override
public void writeSpawnData(ByteBuf dataStream) {}
@Override
public void readSpawnData(ByteBuf dataStream) {}
}