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    }