    001    package net.minecraft.src;
    002
    003    public class EntityAIOcelotSit extends EntityAIBase
    004    {
    005        private final EntityOcelot theOcelot;
    006        private final float field_75404_b;
    007
    008        /** Tracks for how long the task has been executing */
    009        private int currentTick = 0;
    010        private int field_75402_d = 0;
    011
    012        /** For how long the Ocelot should be sitting */
    013        private int maxSittingTicks = 0;
    014
    015        /** X Coordinate of a nearby sitable block */
    016        private int sitableBlockX = 0;
    017
    018        /** Y Coordinate of a nearby sitable block */
    019        private int sitableBlockY = 0;
    020
    021        /** Z Coordinate of a nearby sitable block */
    022        private int sitableBlockZ = 0;
    023
    024        public EntityAIOcelotSit(EntityOcelot par1EntityOcelot, float par2)
    025        {
    026            this.theOcelot = par1EntityOcelot;
    027            this.field_75404_b = par2;
    028            this.setMutexBits(5);
    029        }
    030
    031        /**
    032         * Returns whether the EntityAIBase should begin execution.
    033         */
    034        public boolean shouldExecute()
    035        {
    036            return this.theOcelot.isTamed() && !this.theOcelot.isSitting() && this.theOcelot.getRNG().nextDouble() <= 0.006500000134110451D && this.getNearbySitableBlockDistance();
    037        }
    038
    039        /**
    040         * Returns whether an in-progress EntityAIBase should continue executing
    041         */
    042        public boolean continueExecuting()
    043        {
    044            return this.currentTick <= this.maxSittingTicks && this.field_75402_d <= 60 && this.isSittableBlock(this.theOcelot.worldObj, this.sitableBlockX, this.sitableBlockY, this.sitableBlockZ);
    045        }
    046
    047        /**
    048         * Execute a one shot task or start executing a continuous task
    049         */
    050        public void startExecuting()
    051        {
    052            this.theOcelot.getNavigator().tryMoveToXYZ((double)((float)this.sitableBlockX) + 0.5D, (double)(this.sitableBlockY + 1), (double)((float)this.sitableBlockZ) + 0.5D, this.field_75404_b);
    053            this.currentTick = 0;
    054            this.field_75402_d = 0;
    055            this.maxSittingTicks = this.theOcelot.getRNG().nextInt(this.theOcelot.getRNG().nextInt(1200) + 1200) + 1200;
    056            this.theOcelot.func_70907_r().setSitting(false);
    057        }
    058
    059        /**
    060         * Resets the task
    061         */
    062        public void resetTask()
    063        {
    064            this.theOcelot.setSitting(false);
    065        }
    066
    067        /**
    068         * Updates the task
    069         */
    070        public void updateTask()
    071        {
    072            ++this.currentTick;
    073            this.theOcelot.func_70907_r().setSitting(false);
    074
    075            if (this.theOcelot.getDistanceSq((double)this.sitableBlockX, (double)(this.sitableBlockY + 1), (double)this.sitableBlockZ) > 1.0D)
    076            {
    077                this.theOcelot.setSitting(false);
    078                this.theOcelot.getNavigator().tryMoveToXYZ((double)((float)this.sitableBlockX) + 0.5D, (double)(this.sitableBlockY + 1), (double)((float)this.sitableBlockZ) + 0.5D, this.field_75404_b);
    079                ++this.field_75402_d;
    080            }
    081            else if (!this.theOcelot.isSitting())
    082            {
    083                this.theOcelot.setSitting(true);
    084            }
    085            else
    086            {
    087                --this.field_75402_d;
    088            }
    089        }
    090
    091        /**
    092         * Searches for a block to sit on within a 8 block range, returns 0 if none found
    093         */
    094        protected boolean getNearbySitableBlockDistance()
    095        {
    096            int var1 = (int)this.theOcelot.posY;
    097            double var2 = 2.147483647E9D;
    098
    099            for (int var4 = (int)this.theOcelot.posX - 8; (double)var4 < this.theOcelot.posX + 8.0D; ++var4)
    100            {
    101                for (int var5 = (int)this.theOcelot.posZ - 8; (double)var5 < this.theOcelot.posZ + 8.0D; ++var5)
    102                {
    103                    if (this.isSittableBlock(this.theOcelot.worldObj, var4, var1, var5) && this.theOcelot.worldObj.isAirBlock(var4, var1 + 1, var5))
    104                    {
    105                        double var6 = this.theOcelot.getDistanceSq((double)var4, (double)var1, (double)var5);
    106
    107                        if (var6 < var2)
    108                        {
    109                            this.sitableBlockX = var4;
    110                            this.sitableBlockY = var1;
    111                            this.sitableBlockZ = var5;
    112                            var2 = var6;
    113                        }
    114                    }
    115                }
    116            }
    117
    118            return var2 < 2.147483647E9D;
    119        }
    120
    121        /**
    122         * Determines wheter the Ocelot wants to sit on the block at given coordinate
    123         */
    124        protected boolean isSittableBlock(World par1World, int par2, int par3, int par4)
    125        {
    126            int var5 = par1World.getBlockId(par2, par3, par4);
    127            int var6 = par1World.getBlockMetadata(par2, par3, par4);
    128
    129            if (var5 == Block.chest.blockID)
    130            {
    131                TileEntityChest var7 = (TileEntityChest)par1World.getBlockTileEntity(par2, par3, par4);
    132
    133                if (var7.numUsingPlayers < 1)
    134                {
    135                    return true;
    136                }
    137            }
    138            else
    139            {
    140                if (var5 == Block.stoneOvenActive.blockID)
    141                {
    142                    return true;
    143                }
    144
    145                if (var5 == Block.bed.blockID && !BlockBed.isBlockHeadOfBed(var6))
    146                {
    147                    return true;
    148                }
    149            }
    150
    151            return false;
    152        }
    153    }