Work on flame vector calculation - still need to get it to catch blocks and entities on fire properly

This commit is contained in:
Aidan C. Brady 2014-07-19 02:34:07 -04:00
parent 497997d0e4
commit 87f92326f9
2 changed files with 207 additions and 20 deletions

View file

@ -5,6 +5,8 @@ import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
@ -165,10 +167,28 @@ public class Coord4D
return getFromSide(side, 1);
}
/**
* Creates and returns a new Coord4D translated to the defined offsets of the side by the defined amount.
* @param side - side to translate this Coord4D to
* @param amount - how far to translate this Coord4D
* @return translated Coord4D
*/
public Coord4D getFromSide(ForgeDirection side, int amount)
{
return new Coord4D(xCoord+(side.offsetX*amount), yCoord+(side.offsetY*amount), zCoord+(side.offsetZ*amount), dimensionId);
}
public ItemStack getStack(IBlockAccess world)
{
Block block = getBlock(world);
if(block == null || block == Blocks.air)
{
return null;
}
return new ItemStack(block, 1, getMetadata(world));
}
/**
* Returns a new Coord4D from a defined TileEntity's xCoord, yCoord and zCoord values.

View file

@ -1,26 +1,47 @@
package mekanism.common.entity;
import io.netty.buffer.ByteBuf;
import java.util.List;
import mekanism.api.Coord4D;
import mekanism.api.Pos3D;
import mekanism.common.util.StackUtils;
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 cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
public class EntityFlame extends Entity implements IEntityAdditionalSpawnData
{
public static final int LIFESPAN = 60;
public static final int DAMAGE = 4;
public DamageSource flamethrowerDamage = (new DamageSource("flamethrower")).setFireDamage().setProjectile();
public Entity owner = null;
public EntityFlame(World world)
{
super(world);
setSize(0.5F, 0.5F);
}
public EntityFlame(EntityPlayer player)
{
super(player.worldObj);
this(player.worldObj);
Pos3D playerPos = new Pos3D(player).translate(0, 1.6, 0);
Pos3D flameVec = new Pos3D(1, 1, 1);
@ -39,6 +60,8 @@ public class EntityFlame extends Entity implements IEntityAdditionalSpawnData
motionX = motion.xPos;
motionY = motion.yPos;
motionZ = motion.zPos;
owner = player;
}
public void setHeading(Pos3D motion)
@ -52,6 +75,11 @@ public class EntityFlame extends Entity implements IEntityAdditionalSpawnData
@Override
public void onUpdate()
{
if(isDead)
{
return;
}
ticksExisted++;
prevPosX = posX;
@ -65,40 +93,179 @@ public class EntityFlame extends Entity implements IEntityAdditionalSpawnData
posY += motionY;
posZ += motionZ;
if(rand.nextInt(4) == 0)
{
calculateVector();
}
if(ticksExisted > LIFESPAN)
{
setDead();
return;
}
}
@Override
protected void entityInit()
private void calculateVector()
{
Vec3 localVec = Vec3.createVectorHelper(posX, posY, posZ);
Vec3 motionVec = Vec3.createVectorHelper(posX + motionX, posY + motionY, posZ + motionZ);
MovingObjectPosition mop = worldObj.func_147447_a(localVec, motionVec, true, true, 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 || ticksExisted >= 5))
{
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)
{
if(mop.entityHit instanceof EntityItem)
{
if(mop.entityHit.ticksExisted > 40)
{
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);
smeltBlock(new Coord4D(mop.blockX, mop.blockY, mop.blockZ));
System.out.println(block);
}
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));
return true;
}
return false;
}
private boolean smeltBlock(Coord4D block)
{
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());
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(200);
entity.attackEntityFrom(flamethrowerDamage, DAMAGE);
}
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 readEntityFromNBT(NBTTagCompound nbtTags)
{
}
protected void entityInit() {}
@Override
protected void writeEntityToNBT(NBTTagCompound nbtTags)
{
}
protected void readEntityFromNBT(NBTTagCompound nbtTags) {}
@Override
public void writeSpawnData(ByteBuf dataStream)
{
}
protected void writeEntityToNBT(NBTTagCompound nbtTags) {}
@Override
public void readSpawnData(ByteBuf dataStream)
{
}
public void writeSpawnData(ByteBuf dataStream) {}
@Override
public void readSpawnData(ByteBuf dataStream) {}
}