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