package net.minecraft.village; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import net.minecraft.block.BlockDoor; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.ChunkCoordinates; import net.minecraft.world.World; import net.minecraft.world.WorldSavedData; public class VillageCollection extends WorldSavedData { private World worldObj; /** * This is a black hole. You can add data to this list through a public interface, but you can't query that * information in any way and it's not used internally either. */ private final List villagerPositionsList = new ArrayList(); private final List newDoors = new ArrayList(); private final List villageList = new ArrayList(); private int tickCounter; private static final String __OBFID = "CL_00001635"; public VillageCollection(String p_i1677_1_) { super(p_i1677_1_); } public VillageCollection(World p_i1678_1_) { super("villages"); this.worldObj = p_i1678_1_; this.markDirty(); } public void func_82566_a(World p_82566_1_) { this.worldObj = p_82566_1_; Iterator iterator = this.villageList.iterator(); while (iterator.hasNext()) { Village village = (Village)iterator.next(); village.func_82691_a(p_82566_1_); } } /** * This is a black hole. You can add data to this list through a public interface, but you can't query that * information in any way and it's not used internally either. */ public void addVillagerPosition(int p_75551_1_, int p_75551_2_, int p_75551_3_) { if (this.villagerPositionsList.size() <= 64) { if (!this.isVillagerPositionPresent(p_75551_1_, p_75551_2_, p_75551_3_)) { this.villagerPositionsList.add(new ChunkCoordinates(p_75551_1_, p_75551_2_, p_75551_3_)); } } } /** * Runs a single tick for the village collection */ public void tick() { ++this.tickCounter; Iterator iterator = this.villageList.iterator(); while (iterator.hasNext()) { Village village = (Village)iterator.next(); village.tick(this.tickCounter); } this.removeAnnihilatedVillages(); this.dropOldestVillagerPosition(); this.addNewDoorsToVillageOrCreateVillage(); if (this.tickCounter % 400 == 0) { this.markDirty(); } } private void removeAnnihilatedVillages() { Iterator iterator = this.villageList.iterator(); while (iterator.hasNext()) { Village village = (Village)iterator.next(); if (village.isAnnihilated()) { iterator.remove(); this.markDirty(); } } } /** * Get a list of villages. */ public List getVillageList() { return this.villageList; } /** * Finds the nearest village, but only the given coordinates are withing it's bounding box plus the given the * distance. */ public Village findNearestVillage(int p_75550_1_, int p_75550_2_, int p_75550_3_, int p_75550_4_) { Village village = null; float f = Float.MAX_VALUE; Iterator iterator = this.villageList.iterator(); while (iterator.hasNext()) { Village village1 = (Village)iterator.next(); float f1 = village1.getCenter().getDistanceSquared(p_75550_1_, p_75550_2_, p_75550_3_); if (f1 < f) { float f2 = (float)(p_75550_4_ + village1.getVillageRadius()); if (f1 <= f2 * f2) { village = village1; f = f1; } } } return village; } private void dropOldestVillagerPosition() { if (!this.villagerPositionsList.isEmpty()) { this.addUnassignedWoodenDoorsAroundToNewDoorsList((ChunkCoordinates)this.villagerPositionsList.remove(0)); } } private void addNewDoorsToVillageOrCreateVillage() { int i = 0; while (i < this.newDoors.size()) { VillageDoorInfo villagedoorinfo = (VillageDoorInfo)this.newDoors.get(i); boolean flag = false; Iterator iterator = this.villageList.iterator(); while (true) { if (iterator.hasNext()) { Village village = (Village)iterator.next(); int j = (int)village.getCenter().getDistanceSquared(villagedoorinfo.posX, villagedoorinfo.posY, villagedoorinfo.posZ); float k = 32f + village.getVillageRadius(); //BugFix: Avoid int wrapping if (j > k * k) { continue; } village.addVillageDoorInfo(villagedoorinfo); flag = true; } if (!flag) { Village village1 = new Village(this.worldObj); village1.addVillageDoorInfo(villagedoorinfo); this.villageList.add(village1); this.markDirty(); } ++i; break; } } this.newDoors.clear(); } private void addUnassignedWoodenDoorsAroundToNewDoorsList(ChunkCoordinates p_75546_1_) { byte b0 = 16; byte b1 = 4; byte b2 = 16; for (int i = p_75546_1_.posX - b0; i < p_75546_1_.posX + b0; ++i) { for (int j = p_75546_1_.posY - b1; j < p_75546_1_.posY + b1; ++j) { for (int k = p_75546_1_.posZ - b2; k < p_75546_1_.posZ + b2; ++k) { if (this.isWoodenDoorAt(i, j, k)) { VillageDoorInfo villagedoorinfo = this.getVillageDoorAt(i, j, k); if (villagedoorinfo == null) { this.addDoorToNewListIfAppropriate(i, j, k); } else { villagedoorinfo.lastActivityTimestamp = this.tickCounter; } } } } } } private VillageDoorInfo getVillageDoorAt(int p_75547_1_, int p_75547_2_, int p_75547_3_) { Iterator iterator = this.newDoors.iterator(); VillageDoorInfo villagedoorinfo; do { if (!iterator.hasNext()) { iterator = this.villageList.iterator(); VillageDoorInfo villagedoorinfo1; do { if (!iterator.hasNext()) { return null; } Village village = (Village)iterator.next(); villagedoorinfo1 = village.getVillageDoorAt(p_75547_1_, p_75547_2_, p_75547_3_); } while (villagedoorinfo1 == null); return villagedoorinfo1; } villagedoorinfo = (VillageDoorInfo)iterator.next(); } while (villagedoorinfo.posX != p_75547_1_ || villagedoorinfo.posZ != p_75547_3_ || Math.abs(villagedoorinfo.posY - p_75547_2_) > 1); return villagedoorinfo; } private void addDoorToNewListIfAppropriate(int p_75542_1_, int p_75542_2_, int p_75542_3_) { int l = ((BlockDoor)Blocks.wooden_door).func_150013_e(this.worldObj, p_75542_1_, p_75542_2_, p_75542_3_); int i1; int j1; if (l != 0 && l != 2) { i1 = 0; for (j1 = -5; j1 < 0; ++j1) { if (this.worldObj.canBlockSeeTheSky(p_75542_1_, p_75542_2_, p_75542_3_ + j1)) { --i1; } } for (j1 = 1; j1 <= 5; ++j1) { if (this.worldObj.canBlockSeeTheSky(p_75542_1_, p_75542_2_, p_75542_3_ + j1)) { ++i1; } } if (i1 != 0) { this.newDoors.add(new VillageDoorInfo(p_75542_1_, p_75542_2_, p_75542_3_, 0, i1 > 0 ? -2 : 2, this.tickCounter)); } } else { i1 = 0; for (j1 = -5; j1 < 0; ++j1) { if (this.worldObj.canBlockSeeTheSky(p_75542_1_ + j1, p_75542_2_, p_75542_3_)) { --i1; } } for (j1 = 1; j1 <= 5; ++j1) { if (this.worldObj.canBlockSeeTheSky(p_75542_1_ + j1, p_75542_2_, p_75542_3_)) { ++i1; } } if (i1 != 0) { this.newDoors.add(new VillageDoorInfo(p_75542_1_, p_75542_2_, p_75542_3_, i1 > 0 ? -2 : 2, 0, this.tickCounter)); } } } private boolean isVillagerPositionPresent(int p_75548_1_, int p_75548_2_, int p_75548_3_) { Iterator iterator = this.villagerPositionsList.iterator(); ChunkCoordinates chunkcoordinates; do { if (!iterator.hasNext()) { return false; } chunkcoordinates = (ChunkCoordinates)iterator.next(); } while (chunkcoordinates.posX != p_75548_1_ || chunkcoordinates.posY != p_75548_2_ || chunkcoordinates.posZ != p_75548_3_); return true; } private boolean isWoodenDoorAt(int p_75541_1_, int p_75541_2_, int p_75541_3_) { return this.worldObj.getBlock(p_75541_1_, p_75541_2_, p_75541_3_) == Blocks.wooden_door; } /** * reads in data from the NBTTagCompound into this MapDataBase */ public void readFromNBT(NBTTagCompound p_76184_1_) { this.tickCounter = p_76184_1_.getInteger("Tick"); NBTTagList nbttaglist = p_76184_1_.getTagList("Villages", 10); for (int i = 0; i < nbttaglist.tagCount(); ++i) { NBTTagCompound nbttagcompound1 = nbttaglist.getCompoundTagAt(i); Village village = new Village(); village.readVillageDataFromNBT(nbttagcompound1); this.villageList.add(village); } } /** * write data to NBTTagCompound from this MapDataBase, similar to Entities and TileEntities */ public void writeToNBT(NBTTagCompound p_76187_1_) { p_76187_1_.setInteger("Tick", this.tickCounter); NBTTagList nbttaglist = new NBTTagList(); Iterator iterator = this.villageList.iterator(); while (iterator.hasNext()) { Village village = (Village)iterator.next(); NBTTagCompound nbttagcompound1 = new NBTTagCompound(); village.writeVillageDataToNBT(nbttagcompound1); nbttaglist.appendTag(nbttagcompound1); } p_76187_1_.setTag("Villages", nbttaglist); } }