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