package blusunrize.immersiveengineering.common.entities;
import blusunrize.immersiveengineering.api.tool.BulletHandler;
import blusunrize.immersiveengineering.api.tool.BulletHandler.IBullet;
import blusunrize.immersiveengineering.common.util.EnergyHelper;
import blusunrize.immersiveengineering.common.util.IEAchievements;
import blusunrize.immersiveengineering.common.util.IESounds;
import blusunrize.immersiveengineering.common.util.Utils;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.math.*;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.List;
public class EntityRevolvershot extends Entity
{
private int xTile = -1;
private int yTile = -1;
private int zTile = -1;
private Block inTile;
private int inData;
private boolean inGround;
public EntityLivingBase shootingEntity;
private int ticksInGround;
private int ticksInAir;
private int tickLimit=40;
String bulletType;
public boolean bulletElectro = false;
public ItemStack bulletPotion = null;
private static final DataParameter<String> dataMarker_shooter = EntityDataManager.createKey(EntityRevolvershot.class, DataSerializers.STRING);
public EntityRevolvershot(World world)
{
super(world);
this.setSize(.125f,.125f);
}
public EntityRevolvershot(World world, double x, double y, double z, double ax, double ay, double az, IBullet type)
{
super(world);
this.setSize(0.125F, 0.125F);
this.setLocationAndAngles(x, y, z, this.rotationYaw, this.rotationPitch);
this.setPosition(x, y, z);
this.bulletType = BulletHandler.findRegistryName(type);
}
public EntityRevolvershot(World world, EntityLivingBase living, double ax, double ay, double az, IBullet type, ItemStack stack)
{
this(world, living, ax, ay, az, BulletHandler.findRegistryName(type),stack);
}
public EntityRevolvershot(World world, EntityLivingBase living, double ax, double ay, double az, String type, ItemStack stack)
{
super(world);
this.shootingEntity = living;
setShooterSynced();
this.setSize(0.125F, 0.125F);
this.setLocationAndAngles(living.posX+ax, living.posY+living.getEyeHeight()+ay, living.posZ+az, living.rotationYaw, living.rotationPitch);
this.setPosition(this.posX, this.posY, this.posZ);
// this.yOffset = 0.0F;
this.motionX = this.motionY = this.motionZ = 0.0D;
this.bulletType = type;
}
public void setTickLimit(int limit)
{
this.tickLimit=limit;
}
@SideOnly(Side.CLIENT)
@Override
public boolean isInRangeToRenderDist(double p_70112_1_)
{
double d1 = this.getEntityBoundingBox().getAverageEdgeLength() * 4.0D;
d1 *= 64.0D;
return p_70112_1_ < d1 * d1;
}
@Override
protected void entityInit()
{
this.dataManager.register(dataMarker_shooter, "");
}
public void setShooterSynced()
{
this.dataManager.set(dataMarker_shooter, this.shootingEntity.getName());
}
public EntityLivingBase getShooterSynced()
{
return this.worldObj.getPlayerEntityByName(this.dataManager.get(dataMarker_shooter));
}
public Entity getShooter()
{
return shootingEntity;
}
@Override
public void onUpdate()
{
if(this.getShooter() == null && this.worldObj.isRemote)
this.shootingEntity = getShooterSynced();
if(!this.worldObj.isRemote && (this.shootingEntity != null && this.shootingEntity.isDead))
this.setDead();
else
{
BlockPos blockpos = new BlockPos(this.xTile, this.yTile, this.zTile);
IBlockState iblockstate = this.worldObj.getBlockState(blockpos);
Block block = iblockstate.getBlock();
if(iblockstate.getMaterial() != Material.AIR)
{
AxisAlignedBB axisalignedbb = iblockstate.getCollisionBoundingBox(this.worldObj, blockpos);
if (axisalignedbb != null && axisalignedbb.isVecInside(new Vec3d(this.posX, this.posY, this.posZ)))
{
this.inGround = true;
}
}
super.onUpdate();
if(this.inGround)
{
int j = block.getMetaFromState(iblockstate);
if(block==this.inTile && j==this.inData)
{
++this.ticksInGround;
if (this.ticksInGround >= 1200)
{
this.setDead();
}
}
else
{
this.inGround = false;
this.motionX *= (double)(this.rand.nextFloat() * 0.2F);
this.motionY *= (double)(this.rand.nextFloat() * 0.2F);
this.motionZ *= (double)(this.rand.nextFloat() * 0.2F);
this.ticksInGround = 0;
this.ticksInAir = 0;
}
}
else
++this.ticksInAir;
if(ticksInAir>=tickLimit)
{
this.onExpire();
this.setDead();
return;
}
Vec3d vec3 = new Vec3d(this.posX, this.posY, this.posZ);
Vec3d vec31 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
RayTraceResult movingobjectposition = this.worldObj.rayTraceBlocks(vec3, vec31);
vec3 = new Vec3d(this.posX, this.posY, this.posZ);
vec31 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
if (movingobjectposition != null)
vec31 = new Vec3d(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord);
Entity entity = null;
List<Entity> list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D));
double d0 = 0.0D;
for (int i = 0; i < list.size(); ++i)
{
Entity entity1 = list.get(i);
if (entity1.canBeCollidedWith() && (!entity1.isEntityEqual(this.shootingEntity)))
{
float f = 0.3F;
AxisAlignedBB axisalignedbb = entity1.getEntityBoundingBox().expand((double)f, (double)f, (double)f);
RayTraceResult movingobjectposition1 = axisalignedbb.calculateIntercept(vec3, vec31);
if (movingobjectposition1 != null)
{
double d1 = vec3.distanceTo(movingobjectposition1.hitVec);
if (d1 < d0 || d0 == 0.0D)
{
entity = entity1;
d0 = d1;
}
}
}
}
if (entity != null)
movingobjectposition = new RayTraceResult(entity);
if (movingobjectposition != null)
this.onImpact(movingobjectposition);
this.posX += this.motionX;
this.posY += this.motionY;
this.posZ += this.motionZ;
float f1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
this.rotationYaw = (float)(Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) + 90.0F;
for (this.rotationPitch = (float)(Math.atan2((double)f1, this.motionY) * 180.0D / Math.PI) - 90.0F; this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F);
while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
this.prevRotationPitch += 360.0F;
while (this.rotationYaw - this.prevRotationYaw < -180.0F)
this.prevRotationYaw -= 360.0F;
while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
this.prevRotationYaw += 360.0F;
this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F;
this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;
if (this.isInWater())
{
for (int j = 0; j < 4; ++j)
{
float f3 = 0.25F;
this.worldObj.spawnParticle(EnumParticleTypes.WATER_BUBBLE, this.posX - this.motionX * (double)f3, this.posY - this.motionY * (double)f3, this.posZ - this.motionZ * (double)f3, this.motionX, this.motionY, this.motionZ);
}
}
if(ticksExisted%4==0)
this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
this.setPosition(this.posX, this.posY, this.posZ);
}
}
protected void onImpact(RayTraceResult mop)
{
boolean headshot = false;
if(mop.entityHit instanceof EntityLivingBase)
headshot = Utils.isVecInEntityHead((EntityLivingBase) mop.entityHit, new Vec3d(posX, posY, posZ));
if(this.bulletType != null)
{
IBullet bullet = BulletHandler.getBullet(bulletType);
if(bullet != null)
bullet.onHitTarget(worldObj, mop, this.shootingEntity, this, headshot);
if(headshot && mop.entityHit instanceof EntityAgeable && ((EntityAgeable)mop.entityHit).isChild())
{
if(this.shootingEntity instanceof EntityPlayer)
((EntityPlayer)this.shootingEntity).addStat(IEAchievements.secret_birthdayParty);
this.playSound(IESounds.birthdayParty, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
}
}
if(!this.worldObj.isRemote)
{
// if(bulletType==3)
// worldObj.createExplosion(shootingEntity, posX, posY, posZ, 2, false);
this.secondaryImpact(mop);
}
this.setDead();
}
public void secondaryImpact(RayTraceResult mop)
{
if(bulletElectro && mop.entityHit instanceof EntityLivingBase)
{
IBullet bullet = BulletHandler.getBullet(bulletType);
float percentualDrain = .15f/(bullet==null?1:bullet.getProjectileCount(shootingEntity instanceof EntityPlayer?(EntityPlayer)this.shootingEntity:null));
((EntityLivingBase)mop.entityHit).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS,15,4));
for(EntityEquipmentSlot slot : EntityEquipmentSlot.values())
{
ItemStack stack = ((EntityLivingBase)mop.entityHit).getItemStackFromSlot(slot);
if(EnergyHelper.isFluxItem(stack) && EnergyHelper.getEnergyStored(stack)>0)
{
int drain = (int)Math.max(EnergyHelper.getEnergyStored(stack),EnergyHelper.getMaxEnergyStored(stack)*percentualDrain);
int hasDrained = 0;
while(hasDrained<drain)
{
int actualDrain = EnergyHelper.forceExtractFlux(stack, drain, false);
if(actualDrain<=0)
break;
hasDrained += actualDrain;
}
}
}
}
// if(bulletType==6)
// {
// Vec3d v = new Vec3d(-motionX, -motionY, -motionZ);
// int split = 6;
// for(int i=0; i<split; i++)
// {
// float angle = i * (360f/split);
// Matrix4 matrix = new Matrix4();
// matrix.rotate(angle, v.xCoord,v.yCoord,v.zCoord);
// Vec3d vecDir = new Vec3d(0, 1, 0);
// vecDir = matrix.apply(vecDir);
//
// EntityWolfpackShot bullet = new EntityWolfpackShot(worldObj, this.shootingEntity, vecDir.xCoord*1.5,vecDir.yCoord*1.5,vecDir.zCoord*1.5, this.bulletType, null);
// if(mop.entityHit instanceof EntityLivingBase)
// bullet.targetOverride = (EntityLivingBase)mop.entityHit;
// bullet.setPosition(posX+vecDir.xCoord, posY+vecDir.yCoord, posZ+vecDir.zCoord);
// bullet.motionX = vecDir.xCoord*.375;
// bullet.motionY = vecDir.yCoord*.375;
// bullet.motionZ = vecDir.zCoord*.375;
// worldObj.spawnEntityInWorld(bullet);
// }
// }
// if(bulletType==8 && bulletPotion!=null && bulletPotion.getItem() instanceof ItemPotion)
// {
// PotionType potionType = PotionUtils.getPotionFromItem(bulletPotion);
// List<PotionEffect> effects = PotionUtils.getEffectsFromStack(bulletPotion);
// if(effects!=null)
// if(bulletPotion.getItem() instanceof ItemLingeringPotion)
// {
// EntityAreaEffectCloud entityareaeffectcloud = new EntityAreaEffectCloud(this.worldObj, this.posX, this.posY, this.posZ);
// entityareaeffectcloud.setOwner(shootingEntity);
// entityareaeffectcloud.setRadius(3.0F);
// entityareaeffectcloud.setRadiusOnUse(-0.5F);
// entityareaeffectcloud.setWaitTime(10);
// entityareaeffectcloud.setRadiusPerTick(-entityareaeffectcloud.getRadius() / (float)entityareaeffectcloud.getDuration());
// entityareaeffectcloud.setPotion(potionType);
// for(PotionEffect potioneffect : effects)
// entityareaeffectcloud.addEffect(new PotionEffect(potioneffect.getPotion(), potioneffect.getDuration(), potioneffect.getAmplifier()));
// this.worldObj.spawnEntityInWorld(entityareaeffectcloud);
// }
// else if(bulletPotion.getItem() instanceof ItemSplashPotion)
// {
// List<EntityLivingBase> livingEntities = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, this.getEntityBoundingBox().expand(4.0D, 2.0D, 4.0D));
// if(livingEntities!=null && !livingEntities.isEmpty())
// for(EntityLivingBase living : livingEntities)
// if(living.canBeHitWithPotion())
// {
// double dist = this.getDistanceSqToEntity(living);
// if(dist<16D)
// {
// double dist2 = 1-Math.sqrt(dist)/4D;
// if(living == mop.entityHit)
// dist2 = 1D;
// for(PotionEffect p : effects)
// if(p.getPotion().isInstant())
// p.getPotion().affectEntity(this, this.shootingEntity, living, p.getAmplifier(), dist2);
// else
// {
// int j = (int)(dist2*p.getDuration()+.5D);
// if(j>20)
// living.addPotionEffect(new PotionEffect(p.getPotion(),j, p.getAmplifier()));
// }
// }
// }
//
// }
// else if(mop.entityHit instanceof EntityLivingBase)
// for(PotionEffect p : effects)
// {
// if(p.getDuration()<1)
// p = new PotionEffect(p.getPotion(),1);
// ((EntityLivingBase)mop.entityHit).addPotionEffect(p);
// }
// worldObj.playEvent(2002, new BlockPos(this), PotionType.getID(potionType));
// }
}
public void onExpire()
{
}
protected float getMotionFactor()
{
return 0.95F;
}
@Override
// public void writeToNBT(NBTTagCompound nbt)
protected void writeEntityToNBT(NBTTagCompound nbt)
{
// super.writeToNBT(nbt);
nbt.setShort("xTile", (short)this.xTile);
nbt.setShort("yTile", (short)this.yTile);
nbt.setShort("zTile", (short)this.zTile);
nbt.setByte("inTile", (byte)Block.getIdFromBlock(this.inTile));
nbt.setInteger("inData", this.inData);
nbt.setByte("inGround", (byte)(this.inGround ? 1 : 0));
nbt.setTag("direction", this.newDoubleNBTList(this.motionX, this.motionY, this.motionZ));
nbt.setString("bulletType", this.bulletType);
if(bulletPotion!=null)
nbt.setTag("bulletPotion", bulletPotion.writeToNBT(new NBTTagCompound()));
if(this.shootingEntity!=null)
nbt.setString("shootingEntity", this.shootingEntity.getName());
}
@Override
// public void readFromNBT(NBTTagCompound nbt)
protected void readEntityFromNBT(NBTTagCompound nbt)
{
// super.readFromNBT(nbt);
this.xTile = nbt.getShort("xTile");
this.yTile = nbt.getShort("yTile");
this.zTile = nbt.getShort("zTile");
this.inTile = Block.getBlockById(nbt.getByte("inTile") & 255);
this.inData = nbt.getInteger("inData");
this.inGround = nbt.getByte("inGround") == 1;
this.bulletType = nbt.getString("bulletType");
if(nbt.hasKey("bulletPotion"))
this.bulletPotion= ItemStack.loadItemStackFromNBT(nbt.getCompoundTag("bulletPotion"));
if (nbt.hasKey("direction", 9))
{
NBTTagList nbttaglist = nbt.getTagList("direction", 6);
this.motionX = nbttaglist.getFloatAt(0);
this.motionY = nbttaglist.getFloatAt(1);
this.motionZ = nbttaglist.getFloatAt(2);
}
else
{
this.setDead();
}
if(this.worldObj!=null)
this.shootingEntity = this.worldObj.getPlayerEntityByName(nbt.getString("shootingEntity"));
}
@Override
public float getCollisionBorderSize()
{
return 1.0F;
}
@Override
public float getBrightness(float p_70013_1_)
{
return 1.0F;
}
@SideOnly(Side.CLIENT)
@Override
public int getBrightnessForRender(float p_70070_1_)
{
return 15728880;
}
@Override
public boolean canBeCollidedWith()
{
return false;
}
@Override
public boolean attackEntityFrom(DamageSource p_70097_1_, float p_70097_2_)
{
return false;
}
}