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 }