void genPatches(int chunkX, int chunkZ, bool postPass) { int dx, dz, x, z; Block block; int mapsizeY = blockAccessor.MapSizeY; var mapregion = sapi?.WorldManager.GetMapRegion((chunkX * chunksize) / regionSize, (chunkZ * chunksize) / regionSize); for (int i = 0; i < bpc.PatchesNonTree.Length; i++) { BlockPatch blockPatch = bpc.PatchesNonTree[i]; if (blockPatch.PostPass != postPass) { continue; } float chance = blockPatch.Chance * bpc.ChanceMultiplier.nextFloat(); while (chance-- > rnd.NextDouble()) { 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); // Place according to forest value float forestRel = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, (float)dx / chunksize, (float)dz / chunksize) / 255f; forestRel = GameMath.Clamp(forestRel + forestMod, 0, 1); float shrubRel = GameMath.BiLerp(shrubUpLeft, shrubUpRight, shrubBotLeft, shrubBotRight, (float)dx / chunksize, (float)dz / chunksize) / 255f; shrubRel = GameMath.Clamp(shrubRel + shrubMod, 0, 1); int climate = GameMath.BiLerpRgbColor((float)dx / chunksize, (float)dz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight); if (bpc.IsPatchSuitableAt(blockPatch, block, mapsizeY, climate, y, forestRel, shrubRel)) { if (blockPatch.MapCode != null && rnd.NextInt(255) > GetPatchDensity(blockPatch.MapCode, x, z, mapregion)) { continue; } int firstBlockId = 0; bool found = true; if (blockPatch.BlocksByRockType != null) { found = false; int dy = 1; while (dy < 5 && y - dy > 0) { string lastCodePart = blockAccessor.GetBlock(x, y - dy, z).LastCodePart(); if (RockBlockIdsByType.TryGetValue(lastCodePart, out firstBlockId)) { found = true; break; } dy++; } } if (found) { blockPatch.Generate(blockAccessor, rnd, x, y, z, firstBlockId); } } } } }
void genPatches(int chunkX, int chunkZ) { int dx, dz, x, z; Block block; for (int i = 0; i < bpc.Patches.Length; i++) { BlockPatch blockPatch = bpc.Patches[i]; if (!blockPatch.PrePass) { continue; } float chance = blockPatch.Chance * bpc.ChanceMultiplier.nextFloat(); while (chance-- > rnd.NextDouble()) { 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); // Place according to forest value int climate = GameMath.BiLerpRgbColor((float)dx / chunksize, (float)dz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight); if (bpc.IsPatchSuitableAt(blockPatch, block, api.WorldManager, climate, y, 0)) { int firstBlockId = 0; bool found = true; if (blockPatch.BlocksByRockType != null) { found = false; int dy = 1; while (dy < 5 && y - dy > 0) { string lastCodePart = blockAccessor.GetBlock(x, y - dy, z).LastCodePart(); if (RockBlockIdsByType.TryGetValue(lastCodePart, out firstBlockId)) { found = true; break; } dy++; } } if (found) { blockPatch.Generate(blockAccessor, rnd, x, y, z, firstBlockId); } } } } }
private void GenPatches(IBlockAccessor blockAccessor, BlockPos pos, float forestNess, EnumTreeType treetype, LCGRandom rnd) { var bpc = genPatchesSystem.bpc; int radius = 5; int worldheight = blockAccessor.MapSizeY; int cnt = underTreePatches?.Count ?? 0; for (int i = 0; i < cnt; i++) { BlockPatch bPatch = underTreePatches[i]; if (bPatch.TreeType != EnumTreeType.Any && bPatch.TreeType != treetype) { continue; } float chance = 0.003f * forestNess * bPatch.Chance * bpc.ChanceMultiplier.nextFloat(); //if (bPatch.blockCodes[0].Path.Contains("mushroom")) chance *= 20; - for debugging while (chance-- > rnd.NextDouble()) { int dx = rnd.NextInt(2 * radius) - radius; int dz = rnd.NextInt(2 * radius) - radius; tmpPos.Set(pos.X + dx, 0, pos.Z + dz); int y = blockAccessor.GetTerrainMapheightAt(tmpPos); if (y <= 0 || y >= worldheight - 8) { continue; } tmpPos.Y = y; var climate = blockAccessor.GetClimateAt(tmpPos, EnumGetClimateMode.WorldGenValues); if (climate == null) { continue; } if (bpc.IsPatchSuitableUnderTree(bPatch, worldheight, climate, y)) { int regionX = pos.X / blockAccessor.RegionSize; int regionZ = pos.Z / blockAccessor.RegionSize; if (bPatch.MapCode != null && rnd.NextInt(255) > genPatchesSystem.GetPatchDensity(bPatch.MapCode, tmpPos.X, tmpPos.Z, blockAccessor.GetMapRegion(regionX, regionZ))) { continue; } int firstBlockId = 0; bool found = true; if (bPatch.BlocksByRockType != null) { found = false; int dy = 1; while (dy < 5 && y - dy > 0) { string lastCodePart = blockAccessor.GetBlock(tmpPos.X, y - dy, tmpPos.Z).LastCodePart(); if (genPatchesSystem.RockBlockIdsByType.TryGetValue(lastCodePart, out firstBlockId)) { found = true; break; } dy++; } } if (found) { bPatch.Generate(blockAccessor, rnd, tmpPos.X, tmpPos.Y, tmpPos.Z, firstBlockId); } } } } cnt = onTreePatches?.Count ?? 0; for (int i = 0; i < cnt; i++) { BlockPatch blockPatch = onTreePatches[i]; float chance = 3 * forestNess * blockPatch.Chance * bpc.ChanceMultiplier.nextFloat(); while (chance-- > rnd.NextDouble()) { int dx = 1 - rnd.NextInt(2) * 2; int dy = rnd.NextInt(5); int dz = 1 - rnd.NextInt(2) * 2; tmpPos.Set(pos.X + dx, pos.Y + dy, pos.Z + dz); var block = api.GetBlock(tmpPos); if (block.Id != 0) { continue; } BlockFacing facing = null; for (int j = 0; j < 4; j++) { var f = BlockFacing.HORIZONTALS[j]; var nblock = api.GetBlock(tmpPos.X + f.Normali.X, tmpPos.Y, tmpPos.Z + f.Normali.Z); if (nblock is BlockLog && nblock.Variant["type"] != "resin") { facing = f; break; } } if (facing == null) { break; } var climate = blockAccessor.GetClimateAt(tmpPos, EnumGetClimateMode.WorldGenValues); if (climate == null) { continue; } if (bpc.IsPatchSuitableUnderTree(blockPatch, worldheight, climate, tmpPos.Y)) { int regionX = pos.X / blockAccessor.RegionSize; int regionZ = pos.Z / blockAccessor.RegionSize; if (blockPatch.MapCode != null && rnd.NextInt(255) > genPatchesSystem.GetPatchDensity(blockPatch.MapCode, tmpPos.X, tmpPos.Z, blockAccessor.GetMapRegion(regionX, regionZ))) { continue; } int index = rnd.NextInt(blockPatch.Blocks.Length); blockPatch.Blocks[index].TryPlaceBlockForWorldGen(blockAccessor, tmpPos, facing, rnd); } } } }