001package net.minecraft.entity.ai;
002
003import java.util.ArrayList;
004import java.util.Iterator;
005import java.util.List;
006import net.minecraft.entity.EntityCreature;
007import net.minecraft.pathfinding.PathEntity;
008import net.minecraft.util.MathHelper;
009import net.minecraft.util.Vec3;
010import net.minecraft.village.Village;
011import net.minecraft.village.VillageDoorInfo;
012
013public 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 village = 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 (village == null)
048            {
049                return false;
050            }
051            else
052            {
053                this.doorInfo = this.func_75412_a(village);
054
055                if (this.doorInfo == null)
056                {
057                    return false;
058                }
059                else
060                {
061                    boolean flag = 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(flag);
065
066                    if (this.entityPathNavigate != null)
067                    {
068                        return true;
069                    }
070                    else
071                    {
072                        Vec3 vec3 = 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 (vec3 == null)
075                        {
076                            return false;
077                        }
078                        else
079                        {
080                            this.theEntity.getNavigator().setBreakDoors(false);
081                            this.entityPathNavigate = this.theEntity.getNavigator().getPathToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord);
082                            this.theEntity.getNavigator().setBreakDoors(flag);
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 f = this.theEntity.width + 4.0F;
103            return this.theEntity.getDistanceSq((double)this.doorInfo.posX, (double)this.doorInfo.posY, (double)this.doorInfo.posZ) > (double)(f * f);
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 villagedoorinfo = null;
129        int i = Integer.MAX_VALUE;
130        List list = par1Village.getVillageDoorInfoList();
131        Iterator iterator = list.iterator();
132
133        while (iterator.hasNext())
134        {
135            VillageDoorInfo villagedoorinfo1 = (VillageDoorInfo)iterator.next();
136            int j = villagedoorinfo1.getDistanceSquared(MathHelper.floor_double(this.theEntity.posX), MathHelper.floor_double(this.theEntity.posY), MathHelper.floor_double(this.theEntity.posZ));
137
138            if (j < i && !this.func_75413_a(villagedoorinfo1))
139            {
140                villagedoorinfo = villagedoorinfo1;
141                i = j;
142            }
143        }
144
145        return villagedoorinfo;
146    }
147
148    private boolean func_75413_a(VillageDoorInfo par1VillageDoorInfo)
149    {
150        Iterator iterator = this.doorList.iterator();
151        VillageDoorInfo villagedoorinfo1;
152
153        do
154        {
155            if (!iterator.hasNext())
156            {
157                return false;
158            }
159
160            villagedoorinfo1 = (VillageDoorInfo)iterator.next();
161        }
162        while (par1VillageDoorInfo.posX != villagedoorinfo1.posX || par1VillageDoorInfo.posY != villagedoorinfo1.posY || par1VillageDoorInfo.posZ != villagedoorinfo1.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}