    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}