001    package net.minecraft.src;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    import java.util.List;
006    
007    public class EntityAIMoveThroughVillage extends EntityAIBase
008    {
009        private EntityCreature theEntity;
010        private float movementSpeed;
011        private PathEntity field_75419_c;
012        private VillageDoorInfo doorInfo;
013        private boolean isNocturnal;
014        private List doorList = new ArrayList();
015    
016        public EntityAIMoveThroughVillage(EntityCreature par1EntityCreature, float par2, boolean par3)
017        {
018            this.theEntity = par1EntityCreature;
019            this.movementSpeed = par2;
020            this.isNocturnal = par3;
021            this.setMutexBits(1);
022        }
023    
024        /**
025         * Returns whether the EntityAIBase should begin execution.
026         */
027        public boolean shouldExecute()
028        {
029            this.func_75414_f();
030    
031            if (this.isNocturnal && this.theEntity.worldObj.isDaytime())
032            {
033                return false;
034            }
035            else
036            {
037                Village var1 = this.theEntity.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.theEntity.posX), MathHelper.floor_double(this.theEntity.posY), MathHelper.floor_double(this.theEntity.posZ), 0);
038    
039                if (var1 == null)
040                {
041                    return false;
042                }
043                else
044                {
045                    this.doorInfo = this.func_75412_a(var1);
046    
047                    if (this.doorInfo == null)
048                    {
049                        return false;
050                    }
051                    else
052                    {
053                        boolean var2 = this.theEntity.getNavigator().getCanBreakDoors();
054                        this.theEntity.getNavigator().setBreakDoors(false);
055                        this.field_75419_c = this.theEntity.getNavigator().getPathToXYZ((double)this.doorInfo.posX, (double)this.doorInfo.posY, (double)this.doorInfo.posZ);
056                        this.theEntity.getNavigator().setBreakDoors(var2);
057    
058                        if (this.field_75419_c != null)
059                        {
060                            return true;
061                        }
062                        else
063                        {
064                            Vec3 var3 = RandomPositionGenerator.findRandomTargetBlockTowards(this.theEntity, 10, 7, Vec3.getVec3Pool().getVecFromPool((double)this.doorInfo.posX, (double)this.doorInfo.posY, (double)this.doorInfo.posZ));
065    
066                            if (var3 == null)
067                            {
068                                return false;
069                            }
070                            else
071                            {
072                                this.theEntity.getNavigator().setBreakDoors(false);
073                                this.field_75419_c = this.theEntity.getNavigator().getPathToXYZ(var3.xCoord, var3.yCoord, var3.zCoord);
074                                this.theEntity.getNavigator().setBreakDoors(var2);
075                                return this.field_75419_c != null;
076                            }
077                        }
078                    }
079                }
080            }
081        }
082    
083        /**
084         * Returns whether an in-progress EntityAIBase should continue executing
085         */
086        public boolean continueExecuting()
087        {
088            if (this.theEntity.getNavigator().noPath())
089            {
090                return false;
091            }
092            else
093            {
094                float var1 = this.theEntity.width + 4.0F;
095                return this.theEntity.getDistanceSq((double)this.doorInfo.posX, (double)this.doorInfo.posY, (double)this.doorInfo.posZ) > (double)(var1 * var1);
096            }
097        }
098    
099        /**
100         * Execute a one shot task or start executing a continuous task
101         */
102        public void startExecuting()
103        {
104            this.theEntity.getNavigator().setPath(this.field_75419_c, this.movementSpeed);
105        }
106    
107        /**
108         * Resets the task
109         */
110        public void resetTask()
111        {
112            if (this.theEntity.getNavigator().noPath() || this.theEntity.getDistanceSq((double)this.doorInfo.posX, (double)this.doorInfo.posY, (double)this.doorInfo.posZ) < 16.0D)
113            {
114                this.doorList.add(this.doorInfo);
115            }
116        }
117    
118        private VillageDoorInfo func_75412_a(Village par1Village)
119        {
120            VillageDoorInfo var2 = null;
121            int var3 = Integer.MAX_VALUE;
122            List var4 = par1Village.getVillageDoorInfoList();
123            Iterator var5 = var4.iterator();
124    
125            while (var5.hasNext())
126            {
127                VillageDoorInfo var6 = (VillageDoorInfo)var5.next();
128                int var7 = var6.getDistanceSquared(MathHelper.floor_double(this.theEntity.posX), MathHelper.floor_double(this.theEntity.posY), MathHelper.floor_double(this.theEntity.posZ));
129    
130                if (var7 < var3 && !this.func_75413_a(var6))
131                {
132                    var2 = var6;
133                    var3 = var7;
134                }
135            }
136    
137            return var2;
138        }
139    
140        private boolean func_75413_a(VillageDoorInfo par1VillageDoorInfo)
141        {
142            Iterator var2 = this.doorList.iterator();
143            VillageDoorInfo var3;
144    
145            do
146            {
147                if (!var2.hasNext())
148                {
149                    return false;
150                }
151    
152                var3 = (VillageDoorInfo)var2.next();
153            }
154            while (par1VillageDoorInfo.posX != var3.posX || par1VillageDoorInfo.posY != var3.posY || par1VillageDoorInfo.posZ != var3.posZ);
155    
156            return true;
157        }
158    
159        private void func_75414_f()
160        {
161            if (this.doorList.size() > 15)
162            {
163                this.doorList.remove(0);
164            }
165        }
166    }