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 Iterator var1 = this.newDoors.iterator(); 148 149 while (var1.hasNext()) 150 { 151 VillageDoorInfo var2 = (VillageDoorInfo)var1.next(); 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 break; 181 } 182 } 183 184 this.newDoors.clear(); 185 } 186 187 private void addUnassignedWoodenDoorsAroundToNewDoorsList(ChunkCoordinates par1ChunkCoordinates) 188 { 189 byte var2 = 16; 190 byte var3 = 4; 191 byte var4 = 16; 192 193 for (int var5 = par1ChunkCoordinates.posX - var2; var5 < par1ChunkCoordinates.posX + var2; ++var5) 194 { 195 for (int var6 = par1ChunkCoordinates.posY - var3; var6 < par1ChunkCoordinates.posY + var3; ++var6) 196 { 197 for (int var7 = par1ChunkCoordinates.posZ - var4; var7 < par1ChunkCoordinates.posZ + var4; ++var7) 198 { 199 if (this.isWoodenDoorAt(var5, var6, var7)) 200 { 201 VillageDoorInfo var8 = this.getVillageDoorAt(var5, var6, var7); 202 203 if (var8 == null) 204 { 205 this.addDoorToNewListIfAppropriate(var5, var6, var7); 206 } 207 else 208 { 209 var8.lastActivityTimestamp = this.tickCounter; 210 } 211 } 212 } 213 } 214 } 215 } 216 217 private VillageDoorInfo getVillageDoorAt(int par1, int par2, int par3) 218 { 219 Iterator var4 = this.newDoors.iterator(); 220 VillageDoorInfo var5; 221 222 do 223 { 224 if (!var4.hasNext()) 225 { 226 var4 = this.villageList.iterator(); 227 VillageDoorInfo var6; 228 229 do 230 { 231 if (!var4.hasNext()) 232 { 233 return null; 234 } 235 236 Village var7 = (Village)var4.next(); 237 var6 = var7.getVillageDoorAt(par1, par2, par3); 238 } 239 while (var6 == null); 240 241 return var6; 242 } 243 244 var5 = (VillageDoorInfo)var4.next(); 245 } 246 while (var5.posX != par1 || var5.posZ != par3 || Math.abs(var5.posY - par2) > 1); 247 248 return var5; 249 } 250 251 private void addDoorToNewListIfAppropriate(int par1, int par2, int par3) 252 { 253 int var4 = ((BlockDoor)Block.doorWood).getDoorOrientation(this.worldObj, par1, par2, par3); 254 int var5; 255 int var6; 256 257 if (var4 != 0 && var4 != 2) 258 { 259 var5 = 0; 260 261 for (var6 = -5; var6 < 0; ++var6) 262 { 263 if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) 264 { 265 --var5; 266 } 267 } 268 269 for (var6 = 1; var6 <= 5; ++var6) 270 { 271 if (this.worldObj.canBlockSeeTheSky(par1, par2, par3 + var6)) 272 { 273 ++var5; 274 } 275 } 276 277 if (var5 != 0) 278 { 279 this.newDoors.add(new VillageDoorInfo(par1, par2, par3, 0, var5 > 0 ? -2 : 2, this.tickCounter)); 280 } 281 } 282 else 283 { 284 var5 = 0; 285 286 for (var6 = -5; var6 < 0; ++var6) 287 { 288 if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) 289 { 290 --var5; 291 } 292 } 293 294 for (var6 = 1; var6 <= 5; ++var6) 295 { 296 if (this.worldObj.canBlockSeeTheSky(par1 + var6, par2, par3)) 297 { 298 ++var5; 299 } 300 } 301 302 if (var5 != 0) 303 { 304 this.newDoors.add(new VillageDoorInfo(par1, par2, par3, var5 > 0 ? -2 : 2, 0, this.tickCounter)); 305 } 306 } 307 } 308 309 private boolean isVillagerPositionPresent(int par1, int par2, int par3) 310 { 311 Iterator var4 = this.villagerPositionsList.iterator(); 312 ChunkCoordinates var5; 313 314 do 315 { 316 if (!var4.hasNext()) 317 { 318 return false; 319 } 320 321 var5 = (ChunkCoordinates)var4.next(); 322 } 323 while (var5.posX != par1 || var5.posY != par2 || var5.posZ != par3); 324 325 return true; 326 } 327 328 private boolean isWoodenDoorAt(int par1, int par2, int par3) 329 { 330 int var4 = this.worldObj.getBlockId(par1, par2, par3); 331 return var4 == Block.doorWood.blockID; 332 } 333 334 /** 335 * reads in data from the NBTTagCompound into this MapDataBase 336 */ 337 public void readFromNBT(NBTTagCompound par1NBTTagCompound) 338 { 339 this.tickCounter = par1NBTTagCompound.getInteger("Tick"); 340 NBTTagList var2 = par1NBTTagCompound.getTagList("Villages"); 341 342 for (int var3 = 0; var3 < var2.tagCount(); ++var3) 343 { 344 NBTTagCompound var4 = (NBTTagCompound)var2.tagAt(var3); 345 Village var5 = new Village(); 346 var5.readVillageDataFromNBT(var4); 347 this.villageList.add(var5); 348 } 349 } 350 351 /** 352 * write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities 353 */ 354 public void writeToNBT(NBTTagCompound par1NBTTagCompound) 355 { 356 par1NBTTagCompound.setInteger("Tick", this.tickCounter); 357 NBTTagList var2 = new NBTTagList("Villages"); 358 Iterator var3 = this.villageList.iterator(); 359 360 while (var3.hasNext()) 361 { 362 Village var4 = (Village)var3.next(); 363 NBTTagCompound var5 = new NBTTagCompound("Village"); 364 var4.writeVillageDataToNBT(var5); 365 var2.appendTag(var5); 366 } 367 368 par1NBTTagCompound.setTag("Villages", var2); 369 } 370 }