    001    package net.minecraft.entity.ai;
    002
    003    import net.minecraft.entity.EntityLiving;
    004    import net.minecraft.entity.passive.EntityTameable;
    005    import net.minecraft.pathfinding.PathNavigate;
    006    import net.minecraft.util.MathHelper;
    007    import net.minecraft.world.World;
    008
    009    public 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 var1 = this.thePet.getOwner();
    038
    039            if (var1 == null)
    040            {
    041                return false;
    042            }
    043            else if (this.thePet.isSitting())
    044            {
    045                return false;
    046            }
    047            else if (this.thePet.getDistanceSqToEntity(var1) < (double)(this.minDist * this.minDist))
    048            {
    049                return false;
    050            }
    051            else
    052            {
    053                this.theOwner = var1;
    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 var1 = MathHelper.floor_double(this.theOwner.posX) - 2;
    104                            int var2 = MathHelper.floor_double(this.theOwner.posZ) - 2;
    105                            int var3 = MathHelper.floor_double(this.theOwner.boundingBox.minY);
    106
    107                            for (int var4 = 0; var4 <= 4; ++var4)
    108                            {
    109                                for (int var5 = 0; var5 <= 4; ++var5)
    110                                {
    111                                    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))
    112                                    {
    113                                        this.thePet.setLocationAndAngles((double)((float)(var1 + var4) + 0.5F), (double)var3, (double)((float)(var2 + var5) + 0.5F), this.thePet.rotationYaw, this.thePet.rotationPitch);
    114                                        this.petPathfinder.clearPathEntity();
    115                                        return;
    116                                    }
    117                                }
    118                            }
    119                        }
    120                    }
    121                }
    122            }
    123        }
    124    }