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}