001    package net.minecraft.src;
002    
003    import java.util.List;
004    import java.util.Random;
005    
006    public abstract class ComponentVillage extends StructureComponent
007    {
008        /** The number of villagers that have been spawned in this component. */
009        private int villagersSpawned;
010        protected ComponentVillageStartPiece field_74897_k;
011    
012        protected ComponentVillage(ComponentVillageStartPiece par1ComponentVillageStartPiece, int par2)
013        {
014            super(par2);
015            this.field_74897_k = par1ComponentVillageStartPiece;
016        }
017    
018        /**
019         * Gets the next village component, with the bounding box shifted -1 in the X and Z direction.
020         */
021        protected StructureComponent getNextComponentNN(ComponentVillageStartPiece par1ComponentVillageStartPiece, List par2List, Random par3Random, int par4, int par5)
022        {
023            switch (this.coordBaseMode)
024            {
025                case 0:
026                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 1, this.getComponentType());
027                case 1:
028                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, 2, this.getComponentType());
029                case 2:
030                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.minX - 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 1, this.getComponentType());
031                case 3:
032                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.minZ - 1, 2, this.getComponentType());
033                default:
034                    return null;
035            }
036        }
037    
038        /**
039         * Gets the next village component, with the bounding box shifted +1 in the X and Z direction.
040         */
041        protected StructureComponent getNextComponentPP(ComponentVillageStartPiece par1ComponentVillageStartPiece, List par2List, Random par3Random, int par4, int par5)
042        {
043            switch (this.coordBaseMode)
044            {
045                case 0:
046                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 3, this.getComponentType());
047                case 1:
048                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, 0, this.getComponentType());
049                case 2:
050                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.maxX + 1, this.boundingBox.minY + par4, this.boundingBox.minZ + par5, 3, this.getComponentType());
051                case 3:
052                    return StructureVillagePieces.getNextStructureComponent(par1ComponentVillageStartPiece, par2List, par3Random, this.boundingBox.minX + par5, this.boundingBox.minY + par4, this.boundingBox.maxZ + 1, 0, this.getComponentType());
053                default:
054                    return null;
055            }
056        }
057    
058        /**
059         * Discover the y coordinate that will serve as the ground level of the supplied BoundingBox. (A median of all the
060         * levels in the BB's horizontal rectangle).
061         */
062        protected int getAverageGroundLevel(World par1World, StructureBoundingBox par2StructureBoundingBox)
063        {
064            int var3 = 0;
065            int var4 = 0;
066    
067            for (int var5 = this.boundingBox.minZ; var5 <= this.boundingBox.maxZ; ++var5)
068            {
069                for (int var6 = this.boundingBox.minX; var6 <= this.boundingBox.maxX; ++var6)
070                {
071                    if (par2StructureBoundingBox.isVecInside(var6, 64, var5))
072                    {
073                        var3 += Math.max(par1World.getTopSolidOrLiquidBlock(var6, var5), par1World.provider.getAverageGroundLevel());
074                        ++var4;
075                    }
076                }
077            }
078    
079            if (var4 == 0)
080            {
081                return -1;
082            }
083            else
084            {
085                return var3 / var4;
086            }
087        }
088    
089        protected static boolean canVillageGoDeeper(StructureBoundingBox par0StructureBoundingBox)
090        {
091            return par0StructureBoundingBox != null && par0StructureBoundingBox.minY > 10;
092        }
093    
094        /**
095         * Spawns a number of villagers in this component. Parameters: world, component bounding box, x offset, y offset, z
096         * offset, number of villagers
097         */
098        protected void spawnVillagers(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, int par4, int par5, int par6)
099        {
100            if (this.villagersSpawned < par6)
101            {
102                for (int var7 = this.villagersSpawned; var7 < par6; ++var7)
103                {
104                    int var8 = this.getXWithOffset(par3 + var7, par5);
105                    int var9 = this.getYWithOffset(par4);
106                    int var10 = this.getZWithOffset(par3 + var7, par5);
107    
108                    if (!par2StructureBoundingBox.isVecInside(var8, var9, var10))
109                    {
110                        break;
111                    }
112    
113                    ++this.villagersSpawned;
114                    EntityVillager var11 = new EntityVillager(par1World, this.getVillagerType(var7));
115                    var11.setLocationAndAngles((double)var8 + 0.5D, (double)var9, (double)var10 + 0.5D, 0.0F, 0.0F);
116                    par1World.spawnEntityInWorld(var11);
117                }
118            }
119        }
120    
121        /**
122         * Returns the villager type to spawn in this component, based on the number of villagers already spawned.
123         */
124        protected int getVillagerType(int par1)
125        {
126            return 0;
127        }
128    
129        protected int func_74890_d(int par1, int par2)
130        {
131            if (this.field_74897_k.field_74927_b)
132            {
133                if (par1 == Block.wood.blockID)
134                {
135                    return Block.sandStone.blockID;
136                }
137    
138                if (par1 == Block.cobblestone.blockID)
139                {
140                    return Block.sandStone.blockID;
141                }
142    
143                if (par1 == Block.planks.blockID)
144                {
145                    return Block.sandStone.blockID;
146                }
147    
148                if (par1 == Block.stairCompactPlanks.blockID)
149                {
150                    return Block.stairsSandStone.blockID;
151                }
152    
153                if (par1 == Block.stairCompactCobblestone.blockID)
154                {
155                    return Block.stairsSandStone.blockID;
156                }
157    
158                if (par1 == Block.gravel.blockID)
159                {
160                    return Block.sandStone.blockID;
161                }
162            }
163    
164            return par1;
165        }
166    
167        protected int func_74892_e(int par1, int par2)
168        {
169            if (this.field_74897_k.field_74927_b)
170            {
171                if (par1 == Block.wood.blockID)
172                {
173                    return 0;
174                }
175    
176                if (par1 == Block.cobblestone.blockID)
177                {
178                    return 0;
179                }
180    
181                if (par1 == Block.planks.blockID)
182                {
183                    return 2;
184                }
185            }
186    
187            return par2;
188        }
189    
190        /**
191         * current Position depends on currently set Coordinates mode, is computed here
192         */
193        protected void placeBlockAtCurrentPosition(World par1World, int par2, int par3, int par4, int par5, int par6, StructureBoundingBox par7StructureBoundingBox)
194        {
195            int var8 = this.func_74890_d(par2, par3);
196            int var9 = this.func_74892_e(par2, par3);
197            super.placeBlockAtCurrentPosition(par1World, var8, var9, par4, par5, par6, par7StructureBoundingBox);
198        }
199    
200        /**
201         * arguments: (World worldObj, StructureBoundingBox structBB, int minX, int minY, int minZ, int maxX, int maxY, int
202         * maxZ, int placeBlockId, int replaceBlockId, boolean alwaysreplace)
203         */
204        protected void fillWithBlocks(World par1World, StructureBoundingBox par2StructureBoundingBox, int par3, int par4, int par5, int par6, int par7, int par8, int par9, int par10, boolean par11)
205        {
206            int var12 = this.func_74890_d(par9, 0);
207            int var13 = this.func_74892_e(par9, 0);
208            int var14 = this.func_74890_d(par10, 0);
209            int var15 = this.func_74892_e(par10, 0);
210            super.func_74872_a(par1World, par2StructureBoundingBox, par3, par4, par5, par6, par7, par8, var12, var13, var14, var15, par11);
211        }
212    
213        /**
214         * Overwrites air and liquids from selected position downwards, stops at hitting anything else.
215         */
216        protected void fillCurrentPositionBlocksDownwards(World par1World, int par2, int par3, int par4, int par5, int par6, StructureBoundingBox par7StructureBoundingBox)
217        {
218            int var8 = this.func_74890_d(par2, par3);
219            int var9 = this.func_74892_e(par2, par3);
220            super.fillCurrentPositionBlocksDownwards(par1World, var8, var9, par4, par5, par6, par7StructureBoundingBox);
221        }
222    }