    001    package net.minecraft.entity.item;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import net.minecraft.entity.Entity;
    006    import net.minecraft.item.Item;
    007    import net.minecraft.item.ItemStack;
    008    import net.minecraft.nbt.NBTTagCompound;
    009    import net.minecraft.util.MathHelper;
    010    import net.minecraft.world.World;
    011
    012    public class EntityEnderEye extends Entity
    013    {
    014        public int field_70226_a = 0;
    015
    016        /** 'x' location the eye should float towards. */
    017        private double targetX;
    018
    019        /** 'y' location the eye should float towards. */
    020        private double targetY;
    021
    022        /** 'z' location the eye should float towards. */
    023        private double targetZ;
    024        private int despawnTimer;
    025        private boolean shatterOrDrop;
    026
    027        public EntityEnderEye(World par1World)
    028        {
    029            super(par1World);
    030            this.setSize(0.25F, 0.25F);
    031        }
    032
    033        protected void entityInit() {}
    034
    035        @SideOnly(Side.CLIENT)
    036
    037        /**
    038         * Checks if the entity is in range to render by using the past in distance and comparing it to its average edge
    039         * length * 64 * renderDistanceWeight Args: distance
    040         */
    041        public boolean isInRangeToRenderDist(double par1)
    042        {
    043            double var3 = this.boundingBox.getAverageEdgeLength() * 4.0D;
    044            var3 *= 64.0D;
    045            return par1 < var3 * var3;
    046        }
    047
    048        public EntityEnderEye(World par1World, double par2, double par4, double par6)
    049        {
    050            super(par1World);
    051            this.despawnTimer = 0;
    052            this.setSize(0.25F, 0.25F);
    053            this.setPosition(par2, par4, par6);
    054            this.yOffset = 0.0F;
    055        }
    056
    057        /**
    058         * The location the eye should float/move towards. Currently used for moving towards the nearest stronghold. Args:
    059         * strongholdX, strongholdY, strongholdZ
    060         */
    061        public void moveTowards(double par1, int par3, double par4)
    062        {
    063            double var6 = par1 - this.posX;
    064            double var8 = par4 - this.posZ;
    065            float var10 = MathHelper.sqrt_double(var6 * var6 + var8 * var8);
    066
    067            if (var10 > 12.0F)
    068            {
    069                this.targetX = this.posX + var6 / (double)var10 * 12.0D;
    070                this.targetZ = this.posZ + var8 / (double)var10 * 12.0D;
    071                this.targetY = this.posY + 8.0D;
    072            }
    073            else
    074            {
    075                this.targetX = par1;
    076                this.targetY = (double)par3;
    077                this.targetZ = par4;
    078            }
    079
    080            this.despawnTimer = 0;
    081            this.shatterOrDrop = this.rand.nextInt(5) > 0;
    082        }
    083
    084        @SideOnly(Side.CLIENT)
    085
    086        /**
    087         * Sets the velocity to the args. Args: x, y, z
    088         */
    089        public void setVelocity(double par1, double par3, double par5)
    090        {
    091            this.motionX = par1;
    092            this.motionY = par3;
    093            this.motionZ = par5;
    094
    095            if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F)
    096            {
    097                float var7 = MathHelper.sqrt_double(par1 * par1 + par5 * par5);
    098                this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(par1, par5) * 180.0D / Math.PI);
    099                this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(par3, (double)var7) * 180.0D / Math.PI);
    100            }
    101        }
    102
    103        /**
    104         * Called to update the entity's position/logic.
    105         */
    106        public void onUpdate()
    107        {
    108            this.lastTickPosX = this.posX;
    109            this.lastTickPosY = this.posY;
    110            this.lastTickPosZ = this.posZ;
    111            super.onUpdate();
    112            this.posX += this.motionX;
    113            this.posY += this.motionY;
    114            this.posZ += this.motionZ;
    115            float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
    116            this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI);
    117
    118            for (this.rotationPitch = (float)(Math.atan2(this.motionY, (double)var1) * 180.0D / Math.PI); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F)
    119            {
    120                ;
    121            }
    122
    123            while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
    124            {
    125                this.prevRotationPitch += 360.0F;
    126            }
    127
    128            while (this.rotationYaw - this.prevRotationYaw < -180.0F)
    129            {
    130                this.prevRotationYaw -= 360.0F;
    131            }
    132
    133            while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
    134            {
    135                this.prevRotationYaw += 360.0F;
    136            }
    137
    138            this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F;
    139            this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;
    140
    141            if (!this.worldObj.isRemote)
    142            {
    143                double var2 = this.targetX - this.posX;
    144                double var4 = this.targetZ - this.posZ;
    145                float var6 = (float)Math.sqrt(var2 * var2 + var4 * var4);
    146                float var7 = (float)Math.atan2(var4, var2);
    147                double var8 = (double)var1 + (double)(var6 - var1) * 0.0025D;
    148
    149                if (var6 < 1.0F)
    150                {
    151                    var8 *= 0.8D;
    152                    this.motionY *= 0.8D;
    153                }
    154
    155                this.motionX = Math.cos((double)var7) * var8;
    156                this.motionZ = Math.sin((double)var7) * var8;
    157
    158                if (this.posY < this.targetY)
    159                {
    160                    this.motionY += (1.0D - this.motionY) * 0.014999999664723873D;
    161                }
    162                else
    163                {
    164                    this.motionY += (-1.0D - this.motionY) * 0.014999999664723873D;
    165                }
    166            }
    167
    168            float var10 = 0.25F;
    169
    170            if (this.isInWater())
    171            {
    172                for (int var3 = 0; var3 < 4; ++var3)
    173                {
    174                    this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double)var10, this.posY - this.motionY * (double)var10, this.posZ - this.motionZ * (double)var10, this.motionX, this.motionY, this.motionZ);
    175                }
    176            }
    177            else
    178            {
    179                this.worldObj.spawnParticle("portal", this.posX - this.motionX * (double)var10 + this.rand.nextDouble() * 0.6D - 0.3D, this.posY - this.motionY * (double)var10 - 0.5D, this.posZ - this.motionZ * (double)var10 + this.rand.nextDouble() * 0.6D - 0.3D, this.motionX, this.motionY, this.motionZ);
    180            }
    181
    182            if (!this.worldObj.isRemote)
    183            {
    184                this.setPosition(this.posX, this.posY, this.posZ);
    185                ++this.despawnTimer;
    186
    187                if (this.despawnTimer > 80 && !this.worldObj.isRemote)
    188                {
    189                    this.setDead();
    190
    191                    if (this.shatterOrDrop)
    192                    {
    193                        this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, new ItemStack(Item.eyeOfEnder)));
    194                    }
    195                    else
    196                    {
    197                        this.worldObj.playAuxSFX(2003, (int)Math.round(this.posX), (int)Math.round(this.posY), (int)Math.round(this.posZ), 0);
    198                    }
    199                }
    200            }
    201        }
    202
    203        /**
    204         * (abstract) Protected helper method to write subclass entity data to NBT.
    205         */
    206        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {}
    207
    208        /**
    209         * (abstract) Protected helper method to read subclass entity data from NBT.
    210         */
    211        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {}
    212
    213        @SideOnly(Side.CLIENT)
    214        public float getShadowSize()
    215        {
    216            return 0.0F;
    217        }
    218
    219        /**
    220         * Gets how bright this entity is.
    221         */
    222        public float getBrightness(float par1)
    223        {
    224            return 1.0F;
    225        }
    226
    227        @SideOnly(Side.CLIENT)
    228        public int getBrightnessForRender(float par1)
    229        {
    230            return 15728880;
    231        }
    232
    233        /**
    234         * If returns false, the item will not inflict any damage against entities.
    235         */
    236        public boolean canAttackWithItem()
    237        {
    238            return false;
    239        }
    240    }