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.func_82690_a(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.func_82689_b(var5);
365 var2.appendTag(var5);
366 }
367
368 par1NBTTagCompound.setTag("Villages", var2);
369 }
370 }