package minefantasy.entity;
import java.util.Iterator;
import java.util.List;
import minefantasy.api.weapon.EntityDamageSourceBomb;
import minefantasy.item.ItemListMF;
import minefantasy.item.ItemBombMF;
import minefantasy.system.CombatManager;
import minefantasy.system.cfg;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.IProjectile;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSourceIndirect;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
/**
*
* @author Anonymous Productions
*
* Sources are provided for educational reasons.
* though small bits of code, or methods can be used in your own creations.
*/
public class EntityBombThrown extends EntityThrowableBounce implements IBomb
{
private int ticksRemaining = 60;
private float bounce = 0.8F;
private EntityLivingBase thrower;
public EntityBombThrown(World world)
{
super(world);
}
public EntityBombThrown(World world, EntityLivingBase entity)
{
super(world, entity);
thrower = entity;
}
public EntityBombThrown(World world, EntityLivingBase entity, int fuse, int id)
{
this(world, entity);
setID(id);
this.ticksRemaining = fuse;
}
@Override
protected float getGravityVelocity()
{
return 0.15F;
}
public EntityBombThrown(World world, double x, double y, double z, int fuse)
{
super(world, x, y, z);
this.ticksRemaining = fuse;
}
public EntityBombThrown(World world, EntityLivingBase shooter, EntityLivingBase target, float power, float precision)
{
super(world, shooter);
this.renderDistanceWeight = 10.0D;
this.thrower = shooter;
this.posY = shooter.posY + (double)shooter.getEyeHeight() - 0.10000000149011612D;
double var6 = target.posX - shooter.posX;
double var8 = target.posY + (double)target.getEyeHeight() - (0.699999988079071D / 0.2F * getArc()) - this.posY;
double var10 = target.posZ - shooter.posZ;
double var12 = (double)MathHelper.sqrt_double(var6 * var6 + var10 * var10);
if (var12 >= 1.0E-7D)
{
float var14 = (float)(Math.atan2(var10, var6) * 180.0D / Math.PI) - 90.0F;
float var15 = (float)(-(Math.atan2(var8, var12) * 180.0D / Math.PI));
double var16 = var6 / var12;
double var18 = var10 / var12;
this.setLocationAndAngles(shooter.posX + var16, this.posY, shooter.posZ + var18, var14, var15);
this.yOffset = 0.0F;
float var20 = (float)var12 * getArc();
this.setThrowableHeading(var6, var8 + (double)var20, var10, power, precision);
}
}
private float getArc() {
return this.getGravityVelocity()*4;
}
/**
* sets the bomb to be shrapnel
*/
public EntityBombThrown shrapnel()
{
setID(0);
return this;
}
@Override
public void entityInit()
{
super.entityInit();
dataWatcher.addObject(2, (byte)0);
dataWatcher.addObject(3, 1);
dataWatcher.addObject(4, 0);
}
public boolean getIsShrapnel()
{
return dataWatcher.getWatchableObjectByte(2) == 0 ? false : true;
}
@Override
public void onUpdate()
{
this.worldObj.spawnParticle("smoke", posX, posY, posZ, -motionX, -motionY, -motionZ);
super.onUpdate();
this.ticksRemaining --;
if(ticksRemaining <= 0)
{
this.explode(new MovingObjectPosition(this));
}
}
public void writeEntityToNBT(NBTTagCompound nbt)
{
nbt.setFloat("Bounce", bounce);
nbt.setInteger("Ticks", ticksRemaining);
nbt.setInteger("ID", getID());
}
public void readEntityFromNBT(NBTTagCompound nbt)
{
setID(nbt.getInteger("ID"));
bounce = nbt.getFloat("Bounce");
ticksRemaining = nbt.getInteger("Ticks");
}
@Override
public void explode(MovingObjectPosition pos)
{
worldObj.playSoundAtEntity(this, "random.explode", 0.3F, 10F - 5F);
worldObj.createExplosion(this, posX, posY, posZ, 0, false);
if (!this.worldObj.isRemote)
{
double area = 4.0D;
AxisAlignedBB var3 = this.boundingBox.expand(area, area/2, area);
List var4 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, var3);
if (var4 != null && !var4.isEmpty())
{
Iterator var5 = var4.iterator();
while (var5.hasNext())
{
Entity var6 = (Entity)var5.next();
double var7 = this.getDistanceSqToEntity(var6);
double radius = getRadius();
if (var7 < radius)
{
applyEffects(var6);
int dam = getDamage();
if(var7 < radius/2)
{
double sc = (radius/2)-var7;
if(sc < 0)sc = 0;
if(sc > (radius/2))sc = (radius);
dam *= (1 + (0.5D / (radius/2) * sc));
}
if(!(var6 instanceof EntityItem))
{
DamageSource source = causeBombDamage(this, this);
if(thrower != null)
{
source = causeBombDamage(this, thrower);
}
source.setExplosion();
if(this.canEntityBeSeen(var6))
var6.attackEntityFrom(source, dam);
}
}
}
}
if(getID() == 0)
{
for(int shards = 0; shards < 32 ; shards ++)
{
EntityShrapnel shrapnel = new EntityShrapnel(thrower, worldObj, posX, posY+0.5F, posZ);
shrapnel.canBePickedUp = 0;
shrapnel.ticksExisted = 20;
float range = 0.6F;
shrapnel.setVelocity((rand.nextDouble()-0.5)*range, (rand.nextDouble())*(range/2), (rand.nextDouble()-0.5)*range);
shrapnel.setDamage(5);
worldObj.spawnEntityInWorld(shrapnel);
}
}
if(getID() == 1)//FIRE
{
this.startFire(pos);
}
this.setDead();
}
}
private void applyEffects(Entity hit)
{
EntityLivingBase live = null;
if(hit instanceof EntityLivingBase)
{
live = (EntityLivingBase)hit;
}
if(getID() == 1)//FIRE
{
hit.setFire(20);
}
if(getID() == 2 && live != null)//POISON
{
live.addPotionEffect(new PotionEffect(Potion.poison.id, 100, 0));
}
if(getID() == 3 && live != null)//CONCUSSION
{
live.addPotionEffect(new PotionEffect(Potion.confusion.id, 400, 1));
live.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 400, 1));
}
}
private double getRadius()
{
return 16.0D;
}
private int getDamage()
{
switch(getID())
{
case 0://SHRAPNEL
return 18;
case 1://FIRE
return 4;
case 2://POISON
return 4;
case 3://CONCUSSION
return 4;
}
return 4;
}
/**
* 0 = SHRAPNEL
* 1 = FIRE
* 2 = POISON
* 3 = CONCUSSION
*/
private int getID()
{
return dataWatcher.getWatchableObjectInt(4);
}
/**
* 0 = SHRAPNEL
* 1 = FIRE
* 2 = POISON
* 3 = CONCUSSION
*/
public EntityBombThrown setID(int id)
{
dataWatcher.updateObject(4, id);
return this;
}
@Override
public float getResistance()
{
return bounce;
}
@Override
public int getFuseTime()
{
return 30;
}
@Override
public void bounce(MovingObjectPosition pos)
{
super.bounce(pos);
if(bounce > 0)
this.bounce -= 0.1F;
}
@Override
public Icon getIcon()
{
if(getID() >= ItemBombMF.icons.length)
{
return ItemBombMF.icons[ItemBombMF.icons.length-1];
}
return ItemBombMF.icons[getID()];
}
public boolean canBeCollidedWith()
{
return !this.isDead;
}
@Override
public boolean shouldBreakBlock(Block block)
{
return false;
}
public static DamageSource causeBombDamage(Entity bomb, Entity user)
{
return (new EntityDamageSourceBomb(bomb, user)).setProjectile();
}
public boolean canEntityBeSeen(Entity entity)
{
return this.worldObj.clip(this.worldObj.getWorldVec3Pool().getVecFromPool(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ), this.worldObj.getWorldVec3Pool().getVecFromPool(entity.posX, entity.posY + (double)entity.getEyeHeight(), entity.posZ)) == null;
}
private void startFire(MovingObjectPosition pos)
{
if(cfg.disableFirebomb)return;
if (!this.worldObj.isRemote)
{
if (worldObj.isAirBlock((int) posX, (int) posY, (int) posZ))
{
worldObj.setBlock((int) posX, (int) posY, (int) posZ, Block.fire.blockID, 0, 3);
}
int r = 3;
for (int x = -r; x < r; x++)
{
for (int y = -r; y < r; y++)
{
for (int z = -r; z < r; z++)
{
if (rand.nextInt(5) == 0 && worldObj.isAirBlock((int) posX + x, (int) posY + y, (int) posZ + z))
{
worldObj.setBlock((int) posX + x, (int) posY + y, (int) posZ + z, Block.fire.blockID, 0, 3);
}
}
}
}
}
}
}