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 }