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