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 VillageCollection 008 { 009 private World worldObj; 010 011 /** 012 * This is a black hole. You can add data to this list through a public interface, but you can't query that 013 * information in any way and it's not used internally either. 014 */ 015 private final List villagerPositionsList = new ArrayList(); 016 private final List newDoors = new ArrayList(); 017 private final List villageList = new ArrayList(); 018 private int tickCounter = 0; 019 020 public VillageCollection(World par1World) 021 { 022 this.worldObj = par1World; 023 } 024 025 /** 026 * This is a black hole. You can add data to this list through a public interface, but you can't query that 027 * information in any way and it's not used internally either. 028 */ 029 public void addVillagerPosition(int par1, int par2, int par3) 030 { 031 if (this.villagerPositionsList.size() <= 64) 032 { 033 if (!this.isVillagerPositionPresent(par1, par2, par3)) 034 { 035 this.villagerPositionsList.add(new ChunkCoordinates(par1, par2, par3)); 036 } 037 } 038 } 039 040 /** 041 * Runs a single tick for the village collection 042 */ 043 public void tick() 044 { 045 ++this.tickCounter; 046 Iterator var1 = this.villageList.iterator(); 047 048 while (var1.hasNext()) 049 { 050 Village var2 = (Village)var1.next(); 051 var2.tick(this.tickCounter); 052 } 053 054 this.removeAnnihilatedVillages(); 055 this.dropOldestVillagerPosition(); 056 this.addNewDoorsToVillageOrCreateVillage(); 057 } 058 059 private void removeAnnihilatedVillages() 060 { 061 Iterator var1 = this.villageList.iterator(); 062 063 while (var1.hasNext()) 064 { 065 Village var2 = (Village)var1.next(); 066 067 if (var2.isAnnihilated()) 068 { 069 var1.remove(); 070 } 071 } 072 } 073 074 /** 075 * Get a list of villages. 076 */ 077 public List getVillageList() 078 { 079 return this.villageList; 080 } 081 082 /** 083 * Finds the nearest village, but only the given coordinates are withing it's bounding box plus the given the 084 * distance. 085 */ 086 public Village findNearestVillage(int par1, int par2, int par3, int par4) 087 { 088 Village var5 = null; 089 float var6 = Float.MAX_VALUE; 090 Iterator var7 = this.villageList.iterator(); 091 092 while (var7.hasNext()) 093 { 094 Village var8 = (Village)var7.next(); 095 float var9 = var8.getCenter().getDistanceSquared(par1, par2, par3); 096 097 if (var9 < var6) 098 { 099 int var10 = par4 + var8.getVillageRadius(); 100 101 if (var9 <= (float)(var10 * var10)) 102 { 103 var5 = var8; 104 var6 = var9; 105 } 106 } 107 } 108 109 return var5; 110 } 111 112 private void dropOldestVillagerPosition() 113 { 114 if (!this.villagerPositionsList.isEmpty()) 115 { 116 this.addUnassignedWoodenDoorsAroundToNewDoorsList((ChunkCoordinates)this.villagerPositionsList.remove(0)); 117 } 118 } 119 120 private void addNewDoorsToVillageOrCreateVillage() 121 { 122 Iterator var1 = this.newDoors.iterator(); 123 124 while (var1.hasNext()) 125 { 126 VillageDoorInfo var2 = (VillageDoorInfo)var1.next(); 127 boolean var3 = false; 128 Iterator var4 = this.villageList.iterator(); 129 130 while (true) 131 { 132 if (var4.hasNext()) 133 { 134 Village var5 = (Village)var4.next(); 135 int var6 = (int)var5.getCenter().getDistanceSquared(var2.posX, var2.posY, var2.posZ); 136 int var7 = 32 + var5.getVillageRadius(); 137 138 if (var6 > var7 * var7) 139 { 140 continue; 141 } 142 143 var5.addVillageDoorInfo(var2); 144 var3 = true; 145 } 146 147 if (!var3) 148 { 149 Village var8 = new Village(this.worldObj); 150 var8.addVillageDoorInfo(var2); 151 this.villageList.add(var8); 152 } 153 154 break; 155 } 156 } 157 158 this.newDoors.clear(); 159 } 160 161 private void addUnassignedWoodenDoorsAroundToNewDoorsList(ChunkCoordinates par1ChunkCoordinates) 162 { 163 byte var2 = 16; 164 byte var3 = 4; 165 byte var4 = 16; 166 167 for (int var5 = par1ChunkCoordinates.posX - var2; var5 < par1ChunkCoordinates.posX + var2; ++var5) 168 { 169 for (int var6 = par1ChunkCoordinates.posY - var3; var6 < par1ChunkCoordinates.posY + var3; ++var6) 170 { 171 for (int var7 = par1ChunkCoordinates.posZ - var4; var7 < par1ChunkCoordinates.posZ + var4; ++var7) 172 { 173 if (this.isWoodenDoorAt(var5, var6, var7)) 174 { 175 VillageDoorInfo var8 = this.getVillageDoorAt(var5, var6, var7); 176 177 if (var8 == null) 178 { 179 this.addDoorToNewListIfAppropriate(var5, var6, var7); 180 } 181 else 182 { 183 var8.lastActivityTimestamp = this.tickCounter; 184 } 185 } 186 } 187 } 188 } 189 } 190 191 private VillageDoorInfo getVillageDoorAt(int par1, int par2, int par3) 192 { 193 Iterator var4 = this.newDoors.iterator(); 194 VillageDoorInfo var5; 195 196 do 197 { 198 if (!var4.hasNext()) 199 { 200 var4 = this.villageList.iterator(); 201 VillageDoorInfo var6; 202 203 do 204 { 205 if (!var4.hasNext()) 206 { 207 return null; 208 } 209 210 Village var7 = (Village)var4.next(); 211 var6 = var7.getVillageDoorAt(par1, par2, par3); 212 } 213 while (var6 == null); 214 215 return var6; 216 } 217 218 var5 = (VillageDoorInfo)var4.next(); 219 } 220 while (var5.posX != par1 || var5.posZ != par3 || Math.abs(var5.posY - par2) > 1); 221 222 return var5; 223 } 224 225 private void addDoorToNewListIfAppropriate(int par1, int par2, int par3) 226 { 227 int var4 = ((BlockDoor)Block.doorWood).getDoorOrientation(this.worldObj, par1, par2, par3); 228 int var5; 229 int var6; 230 231 if (var4 != 0 && var4 != 2) 232 { 233 var5 = 0; 234 235 for (var6 = -5; var6 < 0; ++var6) 236 { 237 if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) 238 { 239 --var5; 240 } 241 } 242 243 for (var6 = 1; var6 <= 5; ++var6) 244 { 245 if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) 246 { 247 ++var5; 248 } 249 } 250 251 if (var5 != 0) 252 { 253 this.newDoors.add(new VillageDoorInfo(par1, par2, par3, 0, var5 > 0 ? -2 : 2, this.tickCounter)); 254 } 255 } 256 else 257 { 258 var5 = 0; 259 260 for (var6 = -5; var6 < 0; ++var6) 261 { 262 if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) 263 { 264 --var5; 265 } 266 } 267 268 for (var6 = 1; var6 <= 5; ++var6) 269 { 270 if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) 271 { 272 ++var5; 273 } 274 } 275 276 if (var5 != 0) 277 { 278 this.newDoors.add(new VillageDoorInfo(par1, par2, par3, var5 > 0 ? -2 : 2, 0, this.tickCounter)); 279 } 280 } 281 } 282 283 private boolean isVillagerPositionPresent(int par1, int par2, int par3) 284 { 285 Iterator var4 = this.villagerPositionsList.iterator(); 286 ChunkCoordinates var5; 287 288 do 289 { 290 if (!var4.hasNext()) 291 { 292 return false; 293 } 294 295 var5 = (ChunkCoordinates)var4.next(); 296 } 297 while (var5.posX != par1 || var5.posY != par2 || var5.posZ != par3); 298 299 return true; 300 } 301 302 private boolean isWoodenDoorAt(int par1, int par2, int par3) 303 { 304 int var4 = this.worldObj.getBlockId(par1, par2, par3); 305 return var4 == Block.doorWood.blockID; 306 } 307 }