001 package net.minecraft.src;
002
003 import java.util.HashMap;
004 import java.util.Iterator;
005 import java.util.List;
006 import java.util.Map;
007 import java.util.Random;
008
009 public abstract class MapGenStructure extends MapGenBase
010 {
011 /**
012 * Used to store a list of all structures that have been recursively generated. Used so that during recursive
013 * generation, the structure generator can avoid generating structures that intersect ones that have already been
014 * placed.
015 */
016 protected Map structureMap = new HashMap();
017
018 /**
019 * Recursively called by generate() (generate) and optionally by itself.
020 */
021 protected void recursiveGenerate(World par1World, int par2, int par3, int par4, int par5, byte[] par6ArrayOfByte)
022 {
023 if (!this.structureMap.containsKey(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par2, par3))))
024 {
025 this.rand.nextInt();
026
027 if (this.canSpawnStructureAtCoords(par2, par3))
028 {
029 StructureStart var7 = this.getStructureStart(par2, par3);
030 this.structureMap.put(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par2, par3)), var7);
031 }
032 }
033 }
034
035 /**
036 * Generates structures in specified chunk next to existing structures. Does *not* generate StructureStarts.
037 */
038 public boolean generateStructuresInChunk(World par1World, Random par2Random, int par3, int par4)
039 {
040 int var5 = (par3 << 4) + 8;
041 int var6 = (par4 << 4) + 8;
042 boolean var7 = false;
043 Iterator var8 = this.structureMap.values().iterator();
044
045 while (var8.hasNext())
046 {
047 StructureStart var9 = (StructureStart)var8.next();
048
049 if (var9.isSizeableStructure() && var9.getBoundingBox().intersectsWith(var5, var6, var5 + 15, var6 + 15))
050 {
051 var9.generateStructure(par1World, par2Random, new StructureBoundingBox(var5, var6, var5 + 15, var6 + 15));
052 var7 = true;
053 }
054 }
055
056 return var7;
057 }
058
059 /**
060 * Returns true if the structure generator has generated a structure located at the given position tuple.
061 */
062 public boolean hasStructureAt(int par1, int par2, int par3)
063 {
064 Iterator var4 = this.structureMap.values().iterator();
065
066 while (var4.hasNext())
067 {
068 StructureStart var5 = (StructureStart)var4.next();
069
070 if (var5.isSizeableStructure() && var5.getBoundingBox().intersectsWith(par1, par3, par1, par3))
071 {
072 Iterator var6 = var5.getComponents().iterator();
073
074 while (var6.hasNext())
075 {
076 StructureComponent var7 = (StructureComponent)var6.next();
077
078 if (var7.getBoundingBox().isVecInside(par1, par2, par3))
079 {
080 return true;
081 }
082 }
083 }
084 }
085
086 return false;
087 }
088
089 public ChunkPosition getNearestInstance(World par1World, int par2, int par3, int par4)
090 {
091 this.worldObj = par1World;
092 this.rand.setSeed(par1World.getSeed());
093 long var5 = this.rand.nextLong();
094 long var7 = this.rand.nextLong();
095 long var9 = (long)(par2 >> 4) * var5;
096 long var11 = (long)(par4 >> 4) * var7;
097 this.rand.setSeed(var9 ^ var11 ^ par1World.getSeed());
098 this.recursiveGenerate(par1World, par2 >> 4, par4 >> 4, 0, 0, (byte[])null);
099 double var13 = Double.MAX_VALUE;
100 ChunkPosition var15 = null;
101 Iterator var16 = this.structureMap.values().iterator();
102 ChunkPosition var19;
103 int var21;
104 int var20;
105 double var23;
106 int var22;
107
108 while (var16.hasNext())
109 {
110 StructureStart var17 = (StructureStart)var16.next();
111
112 if (var17.isSizeableStructure())
113 {
114 StructureComponent var18 = (StructureComponent)var17.getComponents().get(0);
115 var19 = var18.getCenter();
116 var20 = var19.x - par2;
117 var21 = var19.y - par3;
118 var22 = var19.z - par4;
119 var23 = (double)(var20 + var20 * var21 * var21 + var22 * var22);
120
121 if (var23 < var13)
122 {
123 var13 = var23;
124 var15 = var19;
125 }
126 }
127 }
128
129 if (var15 != null)
130 {
131 return var15;
132 }
133 else
134 {
135 List var25 = this.getCoordList();
136
137 if (var25 != null)
138 {
139 ChunkPosition var26 = null;
140 Iterator var27 = var25.iterator();
141
142 while (var27.hasNext())
143 {
144 var19 = (ChunkPosition)var27.next();
145 var20 = var19.x - par2;
146 var21 = var19.y - par3;
147 var22 = var19.z - par4;
148 var23 = (double)(var20 + var20 * var21 * var21 + var22 * var22);
149
150 if (var23 < var13)
151 {
152 var13 = var23;
153 var26 = var19;
154 }
155 }
156
157 return var26;
158 }
159 else
160 {
161 return null;
162 }
163 }
164 }
165
166 /**
167 * Returns a list of other locations at which the structure generation has been run, or null if not relevant to this
168 * structure generator.
169 */
170 protected List getCoordList()
171 {
172 return null;
173 }
174
175 protected abstract boolean canSpawnStructureAtCoords(int var1, int var2);
176
177 protected abstract StructureStart getStructureStart(int var1, int var2);
178 }