public void genBlockColumn(IServerChunk[] chunks, int chunkX, int chunkZ, int lx, int lz) { int surfaceY = heightMap[lz * chunksize + lx]; int ylower = 1; int yupper = surfaceY; strataThickness = 0; WeightedIndex[] indices = map[ chunkInRegionX + lx * lerpMapInv, chunkInRegionZ + lz * lerpMapInv ]; rockGroupMaxThickness[0] = rockGroupMaxThickness[1] = rockGroupMaxThickness[2] = rockGroupMaxThickness[3] = 0; rockGroupCurrentThickness[0] = rockGroupCurrentThickness[1] = rockGroupCurrentThickness[2] = rockGroupCurrentThickness[3] = 0; for (int i = 0; i < indices.Length; i++) { float w = indices[i].Weight; GeologicProvinceVariant var = provinces.Variants[indices[i].Index]; rockGroupMaxThickness[0] += var.RockStrataIndexed[0].MaxThickness * w; rockGroupMaxThickness[1] += var.RockStrataIndexed[1].MaxThickness * w; rockGroupMaxThickness[2] += var.RockStrataIndexed[2].MaxThickness * w; rockGroupMaxThickness[3] += var.RockStrataIndexed[3].MaxThickness * w; } float distx = (float)distort2dx.Noise(chunkX * chunksize + lx, chunkZ * chunksize + lz); float distz = (float)distort2dz.Noise(chunkX * chunksize + lx, chunkZ * chunksize + lz); rockStrataId = -1; while (ylower <= yupper) { if (--strataThickness <= 0) { rockStrataId++; if (rockStrataId >= strata.Variants.Length) { break; } stratum = strata.Variants[rockStrataId]; rockMap = mapChunk.MapRegion.RockStrata[rockStrataId]; step = (float)rockMap.InnerSize / regionChunkSize; grp = (int)stratum.RockGroup; float thicknessDistort = GameMath.Clamp((distx + distz) / 30, 0.9f, 1.1f); float allowedThickness = rockGroupMaxThickness[grp] * thicknessDistort - rockGroupCurrentThickness[grp]; strataThickness = Math.Min(allowedThickness, rockMap.GetIntLerpedCorrectly(rdx * step + step * (float)(lx + distx) / chunksize, rdz * step + step * (float)(lz + distz) / chunksize)); strataThickness -= (stratum.RockGroup == EnumRockGroup.Sedimentary) ? Math.Max(0, yupper - TerraGenConfig.seaLevel) * 0.5f : 0; if (strataThickness < 2) { strataThickness = -1; continue; } } rockGroupCurrentThickness[grp]++; if (stratum.GenDir == EnumStratumGenDir.BottomUp) { int chunkY = ylower / chunksize; int lY = ylower - chunkY * chunksize; int localIndex3D = (chunksize * lY + lz) * chunksize + lx; if (chunks[chunkY].Blocks[localIndex3D] == rockBlockId) { chunks[chunkY].Blocks[localIndex3D] = stratum.BlockId; } ylower++; } else { int chunkY = yupper / chunksize; int lY = yupper - chunkY * chunksize; int localIndex3D = (chunksize * lY + lz) * chunksize + lx; if (chunks[chunkY].Blocks[localIndex3D] == rockBlockId) { chunks[chunkY].Blocks[localIndex3D] = stratum.BlockId; } yupper--; } } }