package net.minecraft.entity.item;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class EntityBoat extends Entity
{
private boolean field_70279_a;
private double field_70276_b;
private int boatPosRotationIncrements;
private double boatX;
private double boatY;
private double boatZ;
private double boatYaw;
private double boatPitch;
@SideOnly(Side.CLIENT)
private double velocityX;
@SideOnly(Side.CLIENT)
private double velocityY;
@SideOnly(Side.CLIENT)
private double velocityZ;
public EntityBoat(World par1World)
{
super(par1World);
this.field_70279_a = true;
this.field_70276_b = 0.07D;
this.preventEntitySpawning = true;
this.setSize(1.5F, 0.6F);
this.yOffset = this.height / 2.0F;
}
/**
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
* prevent them from trampling crops
*/
protected boolean canTriggerWalking()
{
return false;
}
protected void entityInit()
{
this.dataWatcher.addObject(17, new Integer(0));
this.dataWatcher.addObject(18, new Integer(1));
this.dataWatcher.addObject(19, new Integer(0));
}
/**
* Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
* pushable on contact, like boats or minecarts.
*/
public AxisAlignedBB getCollisionBox(Entity par1Entity)
{
return par1Entity.boundingBox;
}
/**
* returns the bounding box for this entity
*/
public AxisAlignedBB getBoundingBox()
{
return this.boundingBox;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return true;
}
public EntityBoat(World par1World, double par2, double par4, double par6)
{
this(par1World);
this.setPosition(par2, par4 + (double)this.yOffset, par6);
this.motionX = 0.0D;
this.motionY = 0.0D;
this.motionZ = 0.0D;
this.prevPosX = par2;
this.prevPosY = par4;
this.prevPosZ = par6;
}
/**
* Returns the Y offset from the entity's position for any entity riding this one.
*/
public double getMountedYOffset()
{
return (double)this.height * 0.0D - 0.30000001192092896D;
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
{
if (this.isEntityInvulnerable())
{
return false;
}
else if (!this.worldObj.isRemote && !this.isDead)
{
this.setForwardDirection(-this.getForwardDirection());
this.setTimeSinceHit(10);
this.setDamageTaken(this.getDamageTaken() + par2 * 10);
this.setBeenAttacked();
if (par1DamageSource.getEntity() instanceof EntityPlayer && ((EntityPlayer)par1DamageSource.getEntity()).capabilities.isCreativeMode)
{
this.setDamageTaken(100);
}
if (this.getDamageTaken() > 40)
{
if (this.riddenByEntity != null)
{
this.riddenByEntity.mountEntity(this);
}
this.dropItemWithOffset(Item.boat.itemID, 1, 0.0F);
this.setDead();
}
return true;
}
else
{
return true;
}
}
@SideOnly(Side.CLIENT)
/**
* Setups the entity to do the hurt animation. Only used by packets in multiplayer.
*/
public void performHurtAnimation()
{
this.setForwardDirection(-this.getForwardDirection());
this.setTimeSinceHit(10);
this.setDamageTaken(this.getDamageTaken() * 11);
}
/**
* Returns true if other Entities should be prevented from moving through this Entity.
*/
public boolean canBeCollidedWith()
{
return !this.isDead;
}
@SideOnly(Side.CLIENT)
/**
* Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX,
* posY, posZ, yaw, pitch
*/
public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9)
{
if (this.field_70279_a)
{
this.boatPosRotationIncrements = par9 + 5;
}
else
{
double var10 = par1 - this.posX;
double var12 = par3 - this.posY;
double var14 = par5 - this.posZ;
double var16 = var10 * var10 + var12 * var12 + var14 * var14;
if (var16 <= 1.0D)
{
return;
}
this.boatPosRotationIncrements = 3;
}
this.boatX = par1;
this.boatY = par3;
this.boatZ = par5;
this.boatYaw = (double)par7;
this.boatPitch = (double)par8;
this.motionX = this.velocityX;
this.motionY = this.velocityY;
this.motionZ = this.velocityZ;
}
@SideOnly(Side.CLIENT)
/**
* Sets the velocity to the args. Args: x, y, z
*/
public void setVelocity(double par1, double par3, double par5)
{
this.velocityX = this.motionX = par1;
this.velocityY = this.motionY = par3;
this.velocityZ = this.motionZ = par5;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
super.onUpdate();
if (this.getTimeSinceHit() > 0)
{
this.setTimeSinceHit(this.getTimeSinceHit() - 1);
}
if (this.getDamageTaken() > 0)
{
this.setDamageTaken(this.getDamageTaken() - 1);
}
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
byte var1 = 5;
double var2 = 0.0D;
for (int var4 = 0; var4 < var1; ++var4)
{
double var5 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double)(var4 + 0) / (double)var1 - 0.125D;
double var7 = this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) * (double)(var4 + 1) / (double)var1 - 0.125D;
AxisAlignedBB var9 = AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(this.boundingBox.minX, var5, this.boundingBox.minZ, this.boundingBox.maxX, var7, this.boundingBox.maxZ);
if (this.worldObj.isAABBInMaterial(var9, Material.water))
{
var2 += 1.0D / (double)var1;
}
}
double var24 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
double var6;
double var8;
if (var24 > 0.26249999999999996D)
{
var6 = Math.cos((double)this.rotationYaw * Math.PI / 180.0D);
var8 = Math.sin((double)this.rotationYaw * Math.PI / 180.0D);
for (int var10 = 0; (double)var10 < 1.0D + var24 * 60.0D; ++var10)
{
double var11 = (double)(this.rand.nextFloat() * 2.0F - 1.0F);
double var13 = (double)(this.rand.nextInt(2) * 2 - 1) * 0.7D;
double var15;
double var17;
if (this.rand.nextBoolean())
{
var15 = this.posX - var6 * var11 * 0.8D + var8 * var13;
var17 = this.posZ - var8 * var11 * 0.8D - var6 * var13;
this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, this.motionZ);
}
else
{
var15 = this.posX + var6 + var8 * var11 * 0.7D;
var17 = this.posZ + var8 - var6 * var11 * 0.7D;
this.worldObj.spawnParticle("splash", var15, this.posY - 0.125D, var17, this.motionX, this.motionY, this.motionZ);
}
}
}
double var12;
double var26;
if (this.worldObj.isRemote && this.field_70279_a)
{
if (this.boatPosRotationIncrements > 0)
{
var6 = this.posX + (this.boatX - this.posX) / (double)this.boatPosRotationIncrements;
var8 = this.posY + (this.boatY - this.posY) / (double)this.boatPosRotationIncrements;
var26 = this.posZ + (this.boatZ - this.posZ) / (double)this.boatPosRotationIncrements;
var12 = MathHelper.wrapAngleTo180_double(this.boatYaw - (double)this.rotationYaw);
this.rotationYaw = (float)((double)this.rotationYaw + var12 / (double)this.boatPosRotationIncrements);
this.rotationPitch = (float)((double)this.rotationPitch + (this.boatPitch - (double)this.rotationPitch) / (double)this.boatPosRotationIncrements);
--this.boatPosRotationIncrements;
this.setPosition(var6, var8, var26);
this.setRotation(this.rotationYaw, this.rotationPitch);
}
else
{
var6 = this.posX + this.motionX;
var8 = this.posY + this.motionY;
var26 = this.posZ + this.motionZ;
this.setPosition(var6, var8, var26);
if (this.onGround)
{
this.motionX *= 0.5D;
this.motionY *= 0.5D;
this.motionZ *= 0.5D;
}
this.motionX *= 0.9900000095367432D;
this.motionY *= 0.949999988079071D;
this.motionZ *= 0.9900000095367432D;
}
}
else
{
if (var2 < 1.0D)
{
var6 = var2 * 2.0D - 1.0D;
this.motionY += 0.03999999910593033D * var6;
}
else
{
if (this.motionY < 0.0D)
{
this.motionY /= 2.0D;
}
this.motionY += 0.007000000216066837D;
}
if (this.riddenByEntity != null)
{
this.motionX += this.riddenByEntity.motionX * this.field_70276_b;
this.motionZ += this.riddenByEntity.motionZ * this.field_70276_b;
}
var6 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
if (var6 > 0.35D)
{
var8 = 0.35D / var6;
this.motionX *= var8;
this.motionZ *= var8;
var6 = 0.35D;
}
if (var6 > var24 && this.field_70276_b < 0.35D)
{
this.field_70276_b += (0.35D - this.field_70276_b) / 35.0D;
if (this.field_70276_b > 0.35D)
{
this.field_70276_b = 0.35D;
}
}
else
{
this.field_70276_b -= (this.field_70276_b - 0.07D) / 35.0D;
if (this.field_70276_b < 0.07D)
{
this.field_70276_b = 0.07D;
}
}
if (this.onGround)
{
this.motionX *= 0.5D;
this.motionY *= 0.5D;
this.motionZ *= 0.5D;
}
this.moveEntity(this.motionX, this.motionY, this.motionZ);
if (this.isCollidedHorizontally && var24 > 0.2D)
{
if (!this.worldObj.isRemote)
{
this.setDead();
int var25;
for (var25 = 0; var25 < 3; ++var25)
{
this.dropItemWithOffset(Block.planks.blockID, 1, 0.0F);
}
for (var25 = 0; var25 < 2; ++var25)
{
this.dropItemWithOffset(Item.stick.itemID, 1, 0.0F);
}
}
}
else
{
this.motionX *= 0.9900000095367432D;
this.motionY *= 0.949999988079071D;
this.motionZ *= 0.9900000095367432D;
}
this.rotationPitch = 0.0F;
var8 = (double)this.rotationYaw;
var26 = this.prevPosX - this.posX;
var12 = this.prevPosZ - this.posZ;
if (var26 * var26 + var12 * var12 > 0.001D)
{
var8 = (double)((float)(Math.atan2(var12, var26) * 180.0D / Math.PI));
}
double var14 = MathHelper.wrapAngleTo180_double(var8 - (double)this.rotationYaw);
if (var14 > 20.0D)
{
var14 = 20.0D;
}
if (var14 < -20.0D)
{
var14 = -20.0D;
}
this.rotationYaw = (float)((double)this.rotationYaw + var14);
this.setRotation(this.rotationYaw, this.rotationPitch);
if (!this.worldObj.isRemote)
{
List var16 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D));
int var27;
if (var16 != null && !var16.isEmpty())
{
for (var27 = 0; var27 < var16.size(); ++var27)
{
Entity var18 = (Entity)var16.get(var27);
if (var18 != this.riddenByEntity && var18.canBePushed() && var18 instanceof EntityBoat)
{
var18.applyEntityCollision(this);
}
}
}
for (var27 = 0; var27 < 4; ++var27)
{
int var28 = MathHelper.floor_double(this.posX + ((double)(var27 % 2) - 0.5D) * 0.8D);
int var19 = MathHelper.floor_double(this.posZ + ((double)(var27 / 2) - 0.5D) * 0.8D);
for (int var20 = 0; var20 < 2; ++var20)
{
int var21 = MathHelper.floor_double(this.posY) + var20;
int var22 = this.worldObj.getBlockId(var28, var21, var19);
int var23 = this.worldObj.getBlockMetadata(var28, var21, var19);
if (var22 == Block.snow.blockID)
{
this.worldObj.setBlockWithNotify(var28, var21, var19, 0);
}
else if (var22 == Block.waterlily.blockID)
{
Block.waterlily.dropBlockAsItemWithChance(this.worldObj, var28, var21, var19, var23, 0.3F, 0);
this.worldObj.setBlockWithNotify(var28, var21, var19, 0);
}
}
}
if (this.riddenByEntity != null && this.riddenByEntity.isDead)
{
this.riddenByEntity = null;
}
}
}
}
public void updateRiderPosition()
{
if (this.riddenByEntity != null)
{
double var1 = Math.cos((double)this.rotationYaw * Math.PI / 180.0D) * 0.4D;
double var3 = Math.sin((double)this.rotationYaw * Math.PI / 180.0D) * 0.4D;
this.riddenByEntity.setPosition(this.posX + var1, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ + var3);
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {}
/**
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
*/
public boolean interact(EntityPlayer par1EntityPlayer)
{
if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayer && this.riddenByEntity != par1EntityPlayer)
{
return true;
}
else
{
if (!this.worldObj.isRemote)
{
par1EntityPlayer.mountEntity(this);
}
return true;
}
}
/**
* Sets the damage taken from the last hit.
*/
public void setDamageTaken(int par1)
{
this.dataWatcher.updateObject(19, Integer.valueOf(par1));
}
@SideOnly(Side.CLIENT)
public float getShadowSize()
{
return 0.0F;
}
/**
* Gets the damage taken from the last hit.
*/
public int getDamageTaken()
{
return this.dataWatcher.getWatchableObjectInt(19);
}
/**
* Sets the time to count down from since the last time entity was hit.
*/
public void setTimeSinceHit(int par1)
{
this.dataWatcher.updateObject(17, Integer.valueOf(par1));
}
/**
* Gets the time since the last hit.
*/
public int getTimeSinceHit()
{
return this.dataWatcher.getWatchableObjectInt(17);
}
/**
* Sets the forward direction of the entity.
*/
public void setForwardDirection(int par1)
{
this.dataWatcher.updateObject(18, Integer.valueOf(par1));
}
/**
* Gets the forward direction of the entity.
*/
public int getForwardDirection()
{
return this.dataWatcher.getWatchableObjectInt(18);
}
@SideOnly(Side.CLIENT)
public void func_70270_d(boolean par1)
{
this.field_70279_a = par1;
}
}