001package net.minecraft.world.gen; 002 003import java.util.Random; 004import net.minecraft.block.Block; 005import net.minecraft.util.MathHelper; 006import net.minecraft.world.World; 007 008public class MapGenCaves extends MapGenBase 009{ 010 /** 011 * Generates a larger initial cave node than usual. Called 25% of the time. 012 */ 013 protected void generateLargeCaveNode(long par1, int par3, int par4, byte[] par5ArrayOfByte, double par6, double par8, double par10) 014 { 015 this.generateCaveNode(par1, par3, par4, par5ArrayOfByte, par6, par8, par10, 1.0F + this.rand.nextFloat() * 6.0F, 0.0F, 0.0F, -1, -1, 0.5D); 016 } 017 018 /** 019 * Generates a node in the current cave system recursion tree. 020 */ 021 protected void generateCaveNode(long par1, int par3, int par4, byte[] par5ArrayOfByte, double par6, double par8, double par10, float par12, float par13, float par14, int par15, int par16, double par17) 022 { 023 double d4 = (double)(par3 * 16 + 8); 024 double d5 = (double)(par4 * 16 + 8); 025 float f3 = 0.0F; 026 float f4 = 0.0F; 027 Random random = new Random(par1); 028 029 if (par16 <= 0) 030 { 031 int j1 = this.range * 16 - 16; 032 par16 = j1 - random.nextInt(j1 / 4); 033 } 034 035 boolean flag = false; 036 037 if (par15 == -1) 038 { 039 par15 = par16 / 2; 040 flag = true; 041 } 042 043 int k1 = random.nextInt(par16 / 2) + par16 / 4; 044 045 for (boolean flag1 = random.nextInt(6) == 0; par15 < par16; ++par15) 046 { 047 double d6 = 1.5D + (double)(MathHelper.sin((float)par15 * (float)Math.PI / (float)par16) * par12 * 1.0F); 048 double d7 = d6 * par17; 049 float f5 = MathHelper.cos(par14); 050 float f6 = MathHelper.sin(par14); 051 par6 += (double)(MathHelper.cos(par13) * f5); 052 par8 += (double)f6; 053 par10 += (double)(MathHelper.sin(par13) * f5); 054 055 if (flag1) 056 { 057 par14 *= 0.92F; 058 } 059 else 060 { 061 par14 *= 0.7F; 062 } 063 064 par14 += f4 * 0.1F; 065 par13 += f3 * 0.1F; 066 f4 *= 0.9F; 067 f3 *= 0.75F; 068 f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0F; 069 f3 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0F; 070 071 if (!flag && par15 == k1 && par12 > 1.0F && par16 > 0) 072 { 073 this.generateCaveNode(random.nextLong(), par3, par4, par5ArrayOfByte, par6, par8, par10, random.nextFloat() * 0.5F + 0.5F, par13 - ((float)Math.PI / 2F), par14 / 3.0F, par15, par16, 1.0D); 074 this.generateCaveNode(random.nextLong(), par3, par4, par5ArrayOfByte, par6, par8, par10, random.nextFloat() * 0.5F + 0.5F, par13 + ((float)Math.PI / 2F), par14 / 3.0F, par15, par16, 1.0D); 075 return; 076 } 077 078 if (flag || random.nextInt(4) != 0) 079 { 080 double d8 = par6 - d4; 081 double d9 = par10 - d5; 082 double d10 = (double)(par16 - par15); 083 double d11 = (double)(par12 + 2.0F + 16.0F); 084 085 if (d8 * d8 + d9 * d9 - d10 * d10 > d11 * d11) 086 { 087 return; 088 } 089 090 if (par6 >= d4 - 16.0D - d6 * 2.0D && par10 >= d5 - 16.0D - d6 * 2.0D && par6 <= d4 + 16.0D + d6 * 2.0D && par10 <= d5 + 16.0D + d6 * 2.0D) 091 { 092 int l1 = MathHelper.floor_double(par6 - d6) - par3 * 16 - 1; 093 int i2 = MathHelper.floor_double(par6 + d6) - par3 * 16 + 1; 094 int j2 = MathHelper.floor_double(par8 - d7) - 1; 095 int k2 = MathHelper.floor_double(par8 + d7) + 1; 096 int l2 = MathHelper.floor_double(par10 - d6) - par4 * 16 - 1; 097 int i3 = MathHelper.floor_double(par10 + d6) - par4 * 16 + 1; 098 099 if (l1 < 0) 100 { 101 l1 = 0; 102 } 103 104 if (i2 > 16) 105 { 106 i2 = 16; 107 } 108 109 if (j2 < 1) 110 { 111 j2 = 1; 112 } 113 114 if (k2 > 120) 115 { 116 k2 = 120; 117 } 118 119 if (l2 < 0) 120 { 121 l2 = 0; 122 } 123 124 if (i3 > 16) 125 { 126 i3 = 16; 127 } 128 129 boolean flag2 = false; 130 int j3; 131 int k3; 132 133 for (j3 = l1; !flag2 && j3 < i2; ++j3) 134 { 135 for (int l3 = l2; !flag2 && l3 < i3; ++l3) 136 { 137 for (int i4 = k2 + 1; !flag2 && i4 >= j2 - 1; --i4) 138 { 139 k3 = (j3 * 16 + l3) * 128 + i4; 140 141 if (i4 >= 0 && i4 < 128) 142 { 143 if (par5ArrayOfByte[k3] == Block.waterMoving.blockID || par5ArrayOfByte[k3] == Block.waterStill.blockID) 144 { 145 flag2 = true; 146 } 147 148 if (i4 != j2 - 1 && j3 != l1 && j3 != i2 - 1 && l3 != l2 && l3 != i3 - 1) 149 { 150 i4 = j2; 151 } 152 } 153 } 154 } 155 } 156 157 if (!flag2) 158 { 159 for (j3 = l1; j3 < i2; ++j3) 160 { 161 double d12 = ((double)(j3 + par3 * 16) + 0.5D - par6) / d6; 162 163 for (k3 = l2; k3 < i3; ++k3) 164 { 165 double d13 = ((double)(k3 + par4 * 16) + 0.5D - par10) / d6; 166 int j4 = (j3 * 16 + k3) * 128 + k2; 167 boolean flag3 = false; 168 169 if (d12 * d12 + d13 * d13 < 1.0D) 170 { 171 for (int k4 = k2 - 1; k4 >= j2; --k4) 172 { 173 double d14 = ((double)k4 + 0.5D - par8) / d7; 174 175 if (d14 > -0.7D && d12 * d12 + d14 * d14 + d13 * d13 < 1.0D) 176 { 177 byte b0 = par5ArrayOfByte[j4]; 178 179 if (b0 == Block.grass.blockID) 180 { 181 flag3 = true; 182 } 183 184 if (b0 == Block.stone.blockID || b0 == Block.dirt.blockID || b0 == Block.grass.blockID) 185 { 186 if (k4 < 10) 187 { 188 par5ArrayOfByte[j4] = (byte)Block.lavaMoving.blockID; 189 } 190 else 191 { 192 par5ArrayOfByte[j4] = 0; 193 194 if (flag3 && par5ArrayOfByte[j4 - 1] == Block.dirt.blockID) 195 { 196 par5ArrayOfByte[j4 - 1] = this.worldObj.getBiomeGenForCoords(j3 + par3 * 16, k3 + par4 * 16).topBlock; 197 } 198 } 199 } 200 } 201 202 --j4; 203 } 204 } 205 } 206 } 207 208 if (flag) 209 { 210 break; 211 } 212 } 213 } 214 } 215 } 216 } 217 218 /** 219 * Recursively called by generate() (generate) and optionally by itself. 220 */ 221 protected void recursiveGenerate(World par1World, int par2, int par3, int par4, int par5, byte[] par6ArrayOfByte) 222 { 223 int i1 = this.rand.nextInt(this.rand.nextInt(this.rand.nextInt(40) + 1) + 1); 224 225 if (this.rand.nextInt(15) != 0) 226 { 227 i1 = 0; 228 } 229 230 for (int j1 = 0; j1 < i1; ++j1) 231 { 232 double d0 = (double)(par2 * 16 + this.rand.nextInt(16)); 233 double d1 = (double)this.rand.nextInt(this.rand.nextInt(120) + 8); 234 double d2 = (double)(par3 * 16 + this.rand.nextInt(16)); 235 int k1 = 1; 236 237 if (this.rand.nextInt(4) == 0) 238 { 239 this.generateLargeCaveNode(this.rand.nextLong(), par4, par5, par6ArrayOfByte, d0, d1, d2); 240 k1 += this.rand.nextInt(4); 241 } 242 243 for (int l1 = 0; l1 < k1; ++l1) 244 { 245 float f = this.rand.nextFloat() * (float)Math.PI * 2.0F; 246 float f1 = (this.rand.nextFloat() - 0.5F) * 2.0F / 8.0F; 247 float f2 = this.rand.nextFloat() * 2.0F + this.rand.nextFloat(); 248 249 if (this.rand.nextInt(10) == 0) 250 { 251 f2 *= this.rand.nextFloat() * this.rand.nextFloat() * 3.0F + 1.0F; 252 } 253 254 this.generateCaveNode(this.rand.nextLong(), par4, par5, par6ArrayOfByte, d0, d1, d2, f2, f, f1, 0, 0, 1.0D); 255 } 256 } 257 } 258}