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