void genTrees(int chunkX, int chunkZ) { int triesTrees = (int)treeSupplier.treeGenProps.treesPerChunk.nextFloat(); int dx, dz, x, z; Block block; while (triesTrees > 0) { triesTrees--; dx = rnd.Next(chunksize); dz = rnd.Next(chunksize); x = dx + chunkX * chunksize; z = dz + chunkZ * chunksize; int y = heightmap[dz * chunksize + dx]; if (y <= 0 || y >= worldheight - 15) { continue; } tmpPos.Set(x, y, z); block = blockAccessor.GetBlock(tmpPos); if (block.Fertility == 0) { continue; } // Place according to forest value float treeDensity = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, (float)dx / chunksize, (float)dz / chunksize); int climate = GameMath.BiLerpRgbColor((float)dx / chunksize, (float)dz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight); float shrubChance = GameMath.BiLerp(shrubUpLeft, shrubUpRight, shrubBotLeft, shrubBotRight, (float)dx / chunksize, (float)dz / chunksize); float treeDensityNormalized = treeDensity / 255f; // 1 in 400 chance to always spawn a tree // otherwise go by tree density using a quadratic drop off to create clearer forest edges if (rnd.NextDouble() > Math.Max(0.0025, treeDensityNormalized * treeDensityNormalized)) { continue; } TreeGenForClimate treegenParams = treeSupplier.GetRandomTreeGenForClimate(climate, (int)treeDensity, y); if (treegenParams != null) { bool canGen = true; for (int i = 0; i < structuresIntersectingChunk.Count; i++) { if (structuresIntersectingChunk[i].Location.Contains(tmpPos)) { canGen = false; break; } } if (!canGen) { continue; } if (blockAccessor.GetBlock(tmpPos.X, tmpPos.Y, tmpPos.Z).Replaceable >= 6000) { tmpPos.Y--; } treegenParams.treeGen.GrowTree( blockAccessor, tmpPos, treegenParams.size, treegenParams.vinesGrowthChance, treeDensityNormalized ); } } }
void genTrees(int chunkX, int chunkZ) { int climate = GameMath.BiLerpRgbColor((float)0.5f, (float)0.5f, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight); float wetrel = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, heightmap[(chunksize / 2) * chunksize + chunksize / 2]) / 255f; float dryrel = 1 - wetrel; float drypenalty = 1 - GameMath.Clamp(2f * (dryrel - 0.5f), 0, 0.8f); // Reduce tree generation by up to 70% in low rain places float wetboost = 1 + 3 * Math.Max(0, wetrel - 0.75f); int triesTrees = (int)(treeSupplier.treeGenProps.treesPerChunk.nextFloat() * drypenalty * wetboost); int dx, dz, x, z; Block block; while (triesTrees > 0) { triesTrees--; dx = rnd.NextInt(chunksize); dz = rnd.NextInt(chunksize); x = dx + chunkX * chunksize; z = dz + chunkZ * chunksize; int y = heightmap[dz * chunksize + dx]; if (y <= 0 || y >= worldheight - 15) { continue; } tmpPos.Set(x, y, z); block = blockAccessor.GetBlock(tmpPos); if (block.Fertility == 0) { continue; } // Place according to forest value float treeDensity = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, (float)dx / chunksize, (float)dz / chunksize); climate = GameMath.BiLerpRgbColor((float)dx / chunksize, (float)dz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight); //float shrubChance = GameMath.BiLerp(shrubUpLeft, shrubUpRight, shrubBotLeft, shrubBotRight, (float)dx / chunksize, (float)dz / chunksize); treeDensity = GameMath.Clamp(treeDensity + forestMod * 255, 0, 255); float treeDensityNormalized = treeDensity / 255f; // 1 in 400 chance to always spawn a tree // otherwise go by tree density using a quadratic drop off to create clearer forest edges if (rnd.NextDouble() > Math.Max(0.0025, treeDensityNormalized * treeDensityNormalized) || forestMod <= -1) { continue; } TreeGenForClimate treegenParams = treeSupplier.GetRandomTreeGenForClimate(climate, (int)treeDensity, y); if (treegenParams != null) { bool canGen = true; for (int i = 0; i < structuresIntersectingChunk.Count; i++) { if (structuresIntersectingChunk[i].Location.Contains(tmpPos)) { canGen = false; break; } } if (!canGen) { continue; } if (blockAccessor.GetBlock(tmpPos.X, tmpPos.Y, tmpPos.Z).Replaceable >= 6000) { tmpPos.Y--; } treegenParams.treeGen.GrowTree( blockAccessor, tmpPos, treegenParams.size, treegenParams.vinesGrowthChance ); } } }