    001package net.minecraft.entity.ai;
    002
    003import net.minecraft.entity.EntityLiving;
    004import net.minecraft.entity.passive.EntityTameable;
    005import net.minecraft.pathfinding.PathNavigate;
    006import net.minecraft.util.MathHelper;
    007import net.minecraft.world.World;
    008
    009public class EntityAIFollowOwner extends EntityAIBase
    010{
    011    private EntityTameable thePet;
    012    private EntityLiving theOwner;
    013    World theWorld;
    014    private float field_75336_f;
    015    private PathNavigate petPathfinder;
    016    private int field_75343_h;
    017    float maxDist;
    018    float minDist;
    019    private boolean field_75344_i;
    020
    021    public EntityAIFollowOwner(EntityTameable par1EntityTameable, float par2, float par3, float par4)
    022    {
    023        this.thePet = par1EntityTameable;
    024        this.theWorld = par1EntityTameable.worldObj;
    025        this.field_75336_f = par2;
    026        this.petPathfinder = par1EntityTameable.getNavigator();
    027        this.minDist = par3;
    028        this.maxDist = par4;
    029        this.setMutexBits(3);
    030    }
    031
    032    /**
    033     * Returns whether the EntityAIBase should begin execution.
    034     */
    035    public boolean shouldExecute()
    036    {
    037        EntityLiving entityliving = this.thePet.getOwner();
    038
    039        if (entityliving == null)
    040        {
    041            return false;
    042        }
    043        else if (this.thePet.isSitting())
    044        {
    045            return false;
    046        }
    047        else if (this.thePet.getDistanceSqToEntity(entityliving) < (double)(this.minDist * this.minDist))
    048        {
    049            return false;
    050        }
    051        else
    052        {
    053            this.theOwner = entityliving;
    054            return true;
    055        }
    056    }
    057
    058    /**
    059     * Returns whether an in-progress EntityAIBase should continue executing
    060     */
    061    public boolean continueExecuting()
    062    {
    063        return !this.petPathfinder.noPath() && this.thePet.getDistanceSqToEntity(this.theOwner) > (double)(this.maxDist * this.maxDist) && !this.thePet.isSitting();
    064    }
    065
    066    /**
    067     * Execute a one shot task or start executing a continuous task
    068     */
    069    public void startExecuting()
    070    {
    071        this.field_75343_h = 0;
    072        this.field_75344_i = this.thePet.getNavigator().getAvoidsWater();
    073        this.thePet.getNavigator().setAvoidsWater(false);
    074    }
    075
    076    /**
    077     * Resets the task
    078     */
    079    public void resetTask()
    080    {
    081        this.theOwner = null;
    082        this.petPathfinder.clearPathEntity();
    083        this.thePet.getNavigator().setAvoidsWater(this.field_75344_i);
    084    }
    085
    086    /**
    087     * Updates the task
    088     */
    089    public void updateTask()
    090    {
    091        this.thePet.getLookHelper().setLookPositionWithEntity(this.theOwner, 10.0F, (float)this.thePet.getVerticalFaceSpeed());
    092
    093        if (!this.thePet.isSitting())
    094        {
    095            if (--this.field_75343_h <= 0)
    096            {
    097                this.field_75343_h = 10;
    098
    099                if (!this.petPathfinder.tryMoveToEntityLiving(this.theOwner, this.field_75336_f))
    100                {
    101                    if (this.thePet.getDistanceSqToEntity(this.theOwner) >= 144.0D)
    102                    {
    103                        int i = MathHelper.floor_double(this.theOwner.posX) - 2;
    104                        int j = MathHelper.floor_double(this.theOwner.posZ) - 2;
    105                        int k = MathHelper.floor_double(this.theOwner.boundingBox.minY);
    106
    107                        for (int l = 0; l <= 4; ++l)
    108                        {
    109                            for (int i1 = 0; i1 <= 4; ++i1)
    110                            {
    111                                if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.theWorld.doesBlockHaveSolidTopSurface(i + l, k - 1, j + i1) && !this.theWorld.isBlockNormalCube(i + l, k, j + i1) && !this.theWorld.isBlockNormalCube(i + l, k + 1, j + i1))
    112                                {
    113                                    this.thePet.setLocationAndAngles((double)((float)(i + l) + 0.5F), (double)k, (double)((float)(j + i1) + 0.5F), this.thePet.rotationYaw, this.thePet.rotationPitch);
    114                                    this.petPathfinder.clearPathEntity();
    115                                    return;
    116                                }
    117                            }
    118                        }
    119                    }
    120                }
    121            }
    122        }
    123    }
    124}