From 6988bad3603986528a088208d29f231739259436 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 26 Jun 2026 16:46:57 -0700 Subject: [PATCH 1/2] Honor Ore.blob() vein size in NewMaterialPopulator The blob size carried by each Ore was never read: BLOB_SIZE was hardcoded to 1 and the x/z loops shared a single offset, so every nether/end ore vein collapsed to a 1-4 block speck regardless of its configured size. pasteBlob now scatters o.blob() blocks around an independently-chosen centre, over a radius derived from the cube root of the vein size, bounded by the configured world depth and a max-attempts guard. The unused BLOB_SIZE constant is removed. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../populators/NewMaterialPopulator.java | 50 +++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java b/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java index 75e217f..5ccbef0 100644 --- a/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java +++ b/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java @@ -21,7 +21,6 @@ * @author tastybento */ public class NewMaterialPopulator extends BlockPopulator { - private static final int BLOB_SIZE = 1; private static final Map> ORES; static { @@ -105,21 +104,44 @@ public void populate(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, } } + /** + * Scatters a vein of {@code o.material()} around a random centre in this chunk. + * + *

The number of blocks placed is driven by {@link Ore#blob()} (the vein size), + * spread over a radius derived from the cube root of that size so a vein of N + * blocks occupies a roughly N-block volume instead of collapsing to a single + * point. The X, Z and Y offsets are chosen independently so veins are not pinned + * to the chunk diagonal.

+ */ private void pasteBlob(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, LimitedRegion limitedRegion, int y, Ore o) { - int offset = random.nextInt(16); - for (int x = Math.max(0, offset - BLOB_SIZE); x < Math.min(16, offset + BLOB_SIZE); x++) { - for (int z = Math.max(0, offset - BLOB_SIZE); z < Math.min(16, offset + BLOB_SIZE); z++) { - for (int yy = Math.max(worldInfo.getMinHeight() + 1, y - BLOB_SIZE); yy < Math - .min(worldInfo.getMaxHeight() - 1, y + BLOB_SIZE); yy++) { - Location location = Utils.getLocationFromChunkLocation(x, yy, z, chunkX, chunkZ); - if (!limitedRegion.isInRegion(location)) { - continue; - } - if (limitedRegion.getType(location).isSolid() && random.nextBoolean()) { - limitedRegion.setType(location, o.material()); - } - } + final int blobSize = Math.max(1, o.blob()); + // Half-extent of the vein: scales with the cube root of the requested size. + final int radius = Math.max(1, (int) Math.round(Math.cbrt(blobSize))); + final int worldHeight = Math.min(worldInfo.getMaxHeight(), this.worldDepth); + final int centreX = random.nextInt(16); + final int centreZ = random.nextInt(16); + + int placed = 0; + // Bound the attempts so a vein in a region with few solid blocks cannot loop forever. + final int maxAttempts = blobSize * 8; + for (int attempt = 0; placed < blobSize && attempt < maxAttempts; attempt++) { + int x = centreX + random.nextInt(2 * radius + 1) - radius; + int z = centreZ + random.nextInt(2 * radius + 1) - radius; + int yy = y + random.nextInt(2 * radius + 1) - radius; + if (x < 0 || x > 15 || z < 0 || z > 15) { + continue; + } + if (yy <= worldInfo.getMinHeight() || yy >= worldHeight - 1) { + continue; + } + Location location = Utils.getLocationFromChunkLocation(x, yy, z, chunkX, chunkZ); + if (!limitedRegion.isInRegion(location)) { + continue; + } + if (limitedRegion.getType(location).isSolid()) { + limitedRegion.setType(location, o.material()); + placed++; } } } From 083efd96c0182e4f2f8667411125fcc833a5d178 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 26 Jun 2026 17:28:58 -0700 Subject: [PATCH 2/2] Simplify pasteBlob loop to satisfy Sonar maintainability gate Replace the three guard 'continue' statements with combined boolean conditions so the loop has no break/continue, resolving the SonarCloud code smell on new_maintainability_rating. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../populators/NewMaterialPopulator.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java b/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java index 5ccbef0..fea66c1 100644 --- a/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java +++ b/src/main/java/world/bentobox/caveblock/generators/populators/NewMaterialPopulator.java @@ -129,19 +129,14 @@ private void pasteBlob(WorldInfo worldInfo, Random random, int chunkX, int chunk int x = centreX + random.nextInt(2 * radius + 1) - radius; int z = centreZ + random.nextInt(2 * radius + 1) - radius; int yy = y + random.nextInt(2 * radius + 1) - radius; - if (x < 0 || x > 15 || z < 0 || z > 15) { - continue; - } - if (yy <= worldInfo.getMinHeight() || yy >= worldHeight - 1) { - continue; - } - Location location = Utils.getLocationFromChunkLocation(x, yy, z, chunkX, chunkZ); - if (!limitedRegion.isInRegion(location)) { - continue; - } - if (limitedRegion.getType(location).isSolid()) { - limitedRegion.setType(location, o.material()); - placed++; + boolean inChunk = x >= 0 && x <= 15 && z >= 0 && z <= 15; + boolean inDepth = yy > worldInfo.getMinHeight() && yy < worldHeight - 1; + if (inChunk && inDepth) { + Location location = Utils.getLocationFromChunkLocation(x, yy, z, chunkX, chunkZ); + if (limitedRegion.isInRegion(location) && limitedRegion.getType(location).isSolid()) { + limitedRegion.setType(location, o.material()); + placed++; + } } } }