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}