    001    package net.minecraft.src;
    002
    003    import java.util.Calendar;
    004
    005    public class EntityBat extends EntityAmbientCreature
    006    {
    007        private ChunkCoordinates field_82237_a;
    008
    009        public EntityBat(World par1World)
    010        {
    011            super(par1World);
    012            this.texture = "/mob/bat.png";
    013            this.setSize(0.5F, 0.9F);
    014            this.func_82236_f(true);
    015        }
    016
    017        protected void entityInit()
    018        {
    019            super.entityInit();
    020            this.dataWatcher.addObject(16, new Byte((byte)0));
    021        }
    022
    023        /**
    024         * Returns the volume for the sounds this mob makes.
    025         */
    026        protected float getSoundVolume()
    027        {
    028            return 0.1F;
    029        }
    030
    031        /**
    032         * Returns the sound this mob makes while it's alive.
    033         */
    034        protected String getLivingSound()
    035        {
    036            return "mob.bat.idle";
    037        }
    038
    039        /**
    040         * Returns the sound this mob makes when it is hurt.
    041         */
    042        protected String getHurtSound()
    043        {
    044            return "mob.bat.hurt";
    045        }
    046
    047        /**
    048         * Returns the sound this mob makes on death.
    049         */
    050        protected String getDeathSound()
    051        {
    052            return "mob.bat.death";
    053        }
    054
    055        public int getMaxHealth()
    056        {
    057            return 6;
    058        }
    059
    060        public boolean func_82235_h()
    061        {
    062            return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0;
    063        }
    064
    065        public void func_82236_f(boolean par1)
    066        {
    067            byte var2 = this.dataWatcher.getWatchableObjectByte(16);
    068
    069            if (par1)
    070            {
    071                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 | 1)));
    072            }
    073            else
    074            {
    075                this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var2 & -2)));
    076            }
    077        }
    078
    079        /**
    080         * Returns true if the newer Entity AI code should be run
    081         */
    082        protected boolean isAIEnabled()
    083        {
    084            return true;
    085        }
    086
    087        /**
    088         * Called to update the entity's position/logic.
    089         */
    090        public void onUpdate()
    091        {
    092            super.onUpdate();
    093
    094            if (this.func_82235_h())
    095            {
    096                this.motionX = this.motionY = this.motionZ = 0.0D;
    097                this.posY = (double)MathHelper.floor_double(this.posY) + 1.0D - (double)this.height;
    098            }
    099            else
    100            {
    101                this.motionY *= 0.6000000238418579D;
    102            }
    103        }
    104
    105        protected void updateAITasks()
    106        {
    107            super.updateAITasks();
    108
    109            if (this.func_82235_h())
    110            {
    111                if (!this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), (int)this.posY + 1, MathHelper.floor_double(this.posZ)))
    112                {
    113                    this.func_82236_f(false);
    114                    this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1015, (int)this.posX, (int)this.posY, (int)this.posZ, 0);
    115                }
    116                else
    117                {
    118                    if (this.rand.nextInt(200) == 0)
    119                    {
    120                        this.rotationYawHead = (float)this.rand.nextInt(360);
    121                    }
    122
    123                    if (this.worldObj.getClosestPlayerToEntity(this, 4.0D) != null)
    124                    {
    125                        this.func_82236_f(false);
    126                        this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1015, (int)this.posX, (int)this.posY, (int)this.posZ, 0);
    127                    }
    128                }
    129            }
    130            else
    131            {
    132                if (this.field_82237_a != null && (!this.worldObj.isAirBlock(this.field_82237_a.posX, this.field_82237_a.posY, this.field_82237_a.posZ) || this.field_82237_a.posY < 1))
    133                {
    134                    this.field_82237_a = null;
    135                }
    136
    137                if (this.field_82237_a == null || this.rand.nextInt(30) == 0 || this.field_82237_a.getDistanceSquared((int)this.posX, (int)this.posY, (int)this.posZ) < 4.0F)
    138                {
    139                    this.field_82237_a = new ChunkCoordinates((int)this.posX + this.rand.nextInt(7) - this.rand.nextInt(7), (int)this.posY + this.rand.nextInt(6) - 2, (int)this.posZ + this.rand.nextInt(7) - this.rand.nextInt(7));
    140                }
    141
    142                double var1 = (double)this.field_82237_a.posX + 0.5D - this.posX;
    143                double var3 = (double)this.field_82237_a.posY + 0.1D - this.posY;
    144                double var5 = (double)this.field_82237_a.posZ + 0.5D - this.posZ;
    145                this.motionX += (Math.signum(var1) * 0.5D - this.motionX) * 0.10000000149011612D;
    146                this.motionY += (Math.signum(var3) * 0.699999988079071D - this.motionY) * 0.10000000149011612D;
    147                this.motionZ += (Math.signum(var5) * 0.5D - this.motionZ) * 0.10000000149011612D;
    148                float var7 = (float)(Math.atan2(this.motionZ, this.motionX) * 180.0D / Math.PI) - 90.0F;
    149                float var8 = MathHelper.wrapAngleTo180_float(var7 - this.rotationYaw);
    150                this.moveForward = 0.5F;
    151                this.rotationYaw += var8;
    152
    153                if (this.rand.nextInt(100) == 0 && this.worldObj.isBlockNormalCube(MathHelper.floor_double(this.posX), (int)this.posY + 1, MathHelper.floor_double(this.posZ)))
    154                {
    155                    this.func_82236_f(true);
    156                }
    157            }
    158        }
    159
    160        /**
    161         * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
    162         * prevent them from trampling crops
    163         */
    164        protected boolean canTriggerWalking()
    165        {
    166            return false;
    167        }
    168
    169        /**
    170         * Called when the mob is falling. Calculates and applies fall damage.
    171         */
    172        protected void fall(float par1) {}
    173
    174        /**
    175         * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance
    176         * and deal fall damage if landing on the ground.  Args: distanceFallenThisTick, onGround
    177         */
    178        protected void updateFallState(double par1, boolean par3) {}
    179
    180        public boolean func_82144_au()
    181        {
    182            return true;
    183        }
    184
    185        /**
    186         * Called when the entity is attacked.
    187         */
    188        public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    189        {
    190            if (!this.worldObj.isRemote && this.func_82235_h())
    191            {
    192                this.func_82236_f(false);
    193            }
    194
    195            return super.attackEntityFrom(par1DamageSource, par2);
    196        }
    197
    198        /**
    199         * (abstract) Protected helper method to read subclass entity data from NBT.
    200         */
    201        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    202        {
    203            super.readEntityFromNBT(par1NBTTagCompound);
    204            this.dataWatcher.updateObject(16, Byte.valueOf(par1NBTTagCompound.getByte("BatFlags")));
    205        }
    206
    207        /**
    208         * (abstract) Protected helper method to write subclass entity data to NBT.
    209         */
    210        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    211        {
    212            super.writeEntityToNBT(par1NBTTagCompound);
    213            par1NBTTagCompound.setByte("BatFlags", this.dataWatcher.getWatchableObjectByte(16));
    214        }
    215
    216        /**
    217         * Checks if the entity's current position is a valid location to spawn this entity.
    218         */
    219        public boolean getCanSpawnHere()
    220        {
    221            int var1 = MathHelper.floor_double(this.boundingBox.minY);
    222
    223            if (var1 >= 63)
    224            {
    225                return false;
    226            }
    227            else
    228            {
    229                int var2 = MathHelper.floor_double(this.posX);
    230                int var3 = MathHelper.floor_double(this.posZ);
    231                int var4 = this.worldObj.getBlockLightValue(var2, var1, var3);
    232                byte var5 = 4;
    233                Calendar var6 = this.worldObj.func_83015_S();
    234
    235                if ((var6.get(2) + 1 != 10 || var6.get(5) < 20) && (var6.get(2) + 1 != 11 || var6.get(5) > 3))
    236                {
    237                    if (this.rand.nextBoolean())
    238                    {
    239                        return false;
    240                    }
    241                }
    242                else
    243                {
    244                    var5 = 7;
    245                }
    246
    247                return var4 > this.rand.nextInt(var5) ? false : super.getCanSpawnHere();
    248            }
    249        }
    250
    251        public void func_82163_bD() {}
    252    }