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 }