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 extends WorldSavedData 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(String par1Str) 021 { 022 super(par1Str); 023 } 024 025 public VillageCollection(World par1World) 026 { 027 super("villages"); 028 this.worldObj = par1World; 029 this.markDirty(); 030 } 031 032 public void func_82566_a(World par1World) 033 { 034 this.worldObj = par1World; 035 Iterator var2 = this.villageList.iterator(); 036 037 while (var2.hasNext()) 038 { 039 Village var3 = (Village)var2.next(); 040 var3.func_82691_a(par1World); 041 } 042 } 043 044 /** 045 * This is a black hole. You can add data to this list through a public interface, but you can't query that 046 * information in any way and it's not used internally either. 047 */ 048 public void addVillagerPosition(int par1, int par2, int par3) 049 { 050 if (this.villagerPositionsList.size() <= 64) 051 { 052 if (!this.isVillagerPositionPresent(par1, par2, par3)) 053 { 054 this.villagerPositionsList.add(new ChunkCoordinates(par1, par2, par3)); 055 } 056 } 057 } 058 059 /** 060 * Runs a single tick for the village collection 061 */ 062 public void tick() 063 { 064 ++this.tickCounter; 065 Iterator var1 = this.villageList.iterator(); 066 067 while (var1.hasNext()) 068 { 069 Village var2 = (Village)var1.next(); 070 var2.tick(this.tickCounter); 071 } 072 073 this.removeAnnihilatedVillages(); 074 this.dropOldestVillagerPosition(); 075 this.addNewDoorsToVillageOrCreateVillage(); 076 077 if (this.tickCounter % 400 == 0) 078 { 079 this.markDirty(); 080 } 081 } 082 083 private void removeAnnihilatedVillages() 084 { 085 Iterator var1 = this.villageList.iterator(); 086 087 while (var1.hasNext()) 088 { 089 Village var2 = (Village)var1.next(); 090 091 if (var2.isAnnihilated()) 092 { 093 var1.remove(); 094 this.markDirty(); 095 } 096 } 097 } 098 099 /** 100 * Get a list of villages. 101 */ 102 public List getVillageList() 103 { 104 return this.villageList; 105 } 106 107 /** 108 * Finds the nearest village, but only the given coordinates are withing it's bounding box plus the given the 109 * distance. 110 */ 111 public Village findNearestVillage(int par1, int par2, int par3, int par4) 112 { 113 Village var5 = null; 114 float var6 = Float.MAX_VALUE; 115 Iterator var7 = this.villageList.iterator(); 116 117 while (var7.hasNext()) 118 { 119 Village var8 = (Village)var7.next(); 120 float var9 = var8.getCenter().getDistanceSquared(par1, par2, par3); 121 122 if (var9 < var6) 123 { 124 int var10 = par4 + var8.getVillageRadius(); 125 126 if (var9 <= (float)(var10 * var10)) 127 { 128 var5 = var8; 129 var6 = var9; 130 } 131 } 132 } 133 134 return var5; 135 } 136 137 private void dropOldestVillagerPosition() 138 { 139 if (!this.villagerPositionsList.isEmpty()) 140 { 141 this.addUnassignedWoodenDoorsAroundToNewDoorsList((ChunkCoordinates)this.villagerPositionsList.remove(0)); 142 } 143 } 144 145 private void addNewDoorsToVillageOrCreateVillage() 146 { 147 int var1 = 0; 148 149 while (var1 < this.newDoors.size()) 150 { 151 VillageDoorInfo var2 = (VillageDoorInfo)this.newDoors.get(var1); 152 boolean var3 = false; 153 Iterator var4 = this.villageList.iterator(); 154 155 while (true) 156 { 157 if (var4.hasNext()) 158 { 159 Village var5 = (Village)var4.next(); 160 int var6 = (int)var5.getCenter().getDistanceSquared(var2.posX, var2.posY, var2.posZ); 161 int var7 = 32 + var5.getVillageRadius(); 162 163 if (var6 > var7 * var7) 164 { 165 continue; 166 } 167 168 var5.addVillageDoorInfo(var2); 169 var3 = true; 170 } 171 172 if (!var3) 173 { 174 Village var8 = new Village(this.worldObj); 175 var8.addVillageDoorInfo(var2); 176 this.villageList.add(var8); 177 this.markDirty(); 178 } 179 180 ++var1; 181 break; 182 } 183 } 184 185 this.newDoors.clear(); 186 } 187 188 private void addUnassignedWoodenDoorsAroundToNewDoorsList(ChunkCoordinates par1ChunkCoordinates) 189 { 190 byte var2 = 16; 191 byte var3 = 4; 192 byte var4 = 16; 193 194 for (int var5 = par1ChunkCoordinates.posX - var2; var5 < par1ChunkCoordinates.posX + var2; ++var5) 195 { 196 for (int var6 = par1ChunkCoordinates.posY - var3; var6 < par1ChunkCoordinates.posY + var3; ++var6) 197 { 198 for (int var7 = par1ChunkCoordinates.posZ - var4; var7 < par1ChunkCoordinates.posZ + var4; ++var7) 199 { 200 if (this.isWoodenDoorAt(var5, var6, var7)) 201 { 202 VillageDoorInfo var8 = this.getVillageDoorAt(var5, var6, var7); 203 204 if (var8 == null) 205 { 206 this.addDoorToNewListIfAppropriate(var5, var6, var7); 207 } 208 else 209 { 210 var8.lastActivityTimestamp = this.tickCounter; 211 } 212 } 213 } 214 } 215 } 216 } 217 218 private VillageDoorInfo getVillageDoorAt(int par1, int par2, int par3) 219 { 220 Iterator var4 = this.newDoors.iterator(); 221 VillageDoorInfo var5; 222 223 do 224 { 225 if (!var4.hasNext()) 226 { 227 var4 = this.villageList.iterator(); 228 VillageDoorInfo var6; 229 230 do 231 { 232 if (!var4.hasNext()) 233 { 234 return null; 235 } 236 237 Village var7 = (Village)var4.next(); 238 var6 = var7.getVillageDoorAt(par1, par2, par3); 239 } 240 while (var6 == null); 241 242 return var6; 243 } 244 245 var5 = (VillageDoorInfo)var4.next(); 246 } 247 while (var5.posX != par1 || var5.posZ != par3 || Math.abs(var5.posY - par2) > 1); 248 249 return var5; 250 } 251 252 private void addDoorToNewListIfAppropriate(int par1, int par2, int par3) 253 { 254 int var4 = ((BlockDoor)Block.doorWood).getDoorOrientation(this.worldObj, par1, par2, par3); 255 int var5; 256 int var6; 257 258 if (var4 != 0 && var4 != 2) 259 { 260 var5 = 0; 261 262 for (var6 = -5; var6 < 0; ++var6) 263 { 264 if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) 265 { 266 --var5; 267 } 268 } 269 270 for (var6 = 1; var6 <= 5; ++var6) 271 { 272 if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) 273 { 274 ++var5; 275 } 276 } 277 278 if (var5 != 0) 279 { 280 this.newDoors.add(new VillageDoorInfo(par1, par2, par3, 0, var5 > 0 ? -2 : 2, this.tickCounter)); 281 } 282 } 283 else 284 { 285 var5 = 0; 286 287 for (var6 = -5; var6 < 0; ++var6) 288 { 289 if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) 290 { 291 --var5; 292 } 293 } 294 295 for (var6 = 1; var6 <= 5; ++var6) 296 { 297 if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) 298 { 299 ++var5; 300 } 301 } 302 303 if (var5 != 0) 304 { 305 this.newDoors.add(new VillageDoorInfo(par1, par2, par3, var5 > 0 ? -2 : 2, 0, this.tickCounter)); 306 } 307 } 308 } 309 310 private boolean isVillagerPositionPresent(int par1, int par2, int par3) 311 { 312 Iterator var4 = this.villagerPositionsList.iterator(); 313 ChunkCoordinates var5; 314 315 do 316 { 317 if (!var4.hasNext()) 318 { 319 return false; 320 } 321 322 var5 = (ChunkCoordinates)var4.next(); 323 } 324 while (var5.posX != par1 || var5.posY != par2 || var5.posZ != par3); 325 326 return true; 327 } 328 329 private boolean isWoodenDoorAt(int par1, int par2, int par3) 330 { 331 int var4 = this.worldObj.getBlockId(par1, par2, par3); 332 return var4 == Block.doorWood.blockID; 333 } 334 335 /** 336 * reads in data from the NBTTagCompound into this MapDataBase 337 */ 338 public void readFromNBT(NBTTagCompound par1NBTTagCompound) 339 { 340 this.tickCounter = par1NBTTagCompound.getInteger("Tick"); 341 NBTTagList var2 = par1NBTTagCompound.getTagList("Villages"); 342 343 for (int var3 = 0; var3 < var2.tagCount(); ++var3) 344 { 345 NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3); 346 Village var5 = new Village(); 347 var5.readVillageDataFromNBT(var4); 348 this.villageList.add(var5); 349 } 350 } 351 352 /** 353 * write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities 354 */ 355 public void writeToNBT(NBTTagCompound par1NBTTagCompound) 356 { 357 par1NBTTagCompound.setInteger("Tick", this.tickCounter); 358 NBTTagList var2 = new NBTTagList("Villages"); 359 Iterator var3 = this.villageList.iterator(); 360 361 while (var3.hasNext()) 362 { 363 Village var4 = (Village)var3.next(); 364 NBTTagCompound var5 = new NBTTagCompound("Village"); 365 var4.writeVillageDataToNBT(var5); 366 var2.appendTag(var5); 367 } 368 369 par1NBTTagCompound.setTag("Villages", var2); 370 } 371 }