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 }