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