Fixed featurette edge cases

- Fan coral tips follow the existing top of each occupied column
- Large secondary leaf weights preserve their authored proportions
- Zero ore thresholds skip noise sampling and block generation
- Regressions cover fan silhouettes, weighted leaf choices, and ore cutoffs
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-06 03:56:26 -04:00
1 parent 420148fcc7
commit ce431b524e
6 files changed
+186 -9

No files matched your search

@@ -58,7 +58,7 @@ public class IrisOreGenerator {
}
public PlatformBlockState generate(int x, int y, int z, RNG rng, IrisData data) {
if (!range.contains(y)) {
if (threshold <= 0 || !range.contains(y)) {
return null;
}
@@ -88,16 +88,18 @@ public final class CoralGenerator {
private static void buildFan(CoralCanvas canvas, IrisCoral coral, int height, long seed) {
int half = Math.max(1, coral.getFanWidth());
for (int y = 0; y < height; y++) {
int tippedWidth = -1;
for (int y = height - 1; y >= 0; y--) {
double t = y / (double) Math.max(1, height - 1);
double profile = Math.sin(Math.PI * t);
int w = (int) Math.round(half * profile);
for (int dx = -w; dx <= w; dx++) {
canvas.set(dx, y, 0, CoralCanvas.Role.STRUCTURE);
if (Math.abs(dx) > tippedWidth) {
placeTip(canvas, coral, dx, y, 0, seed + dx);
}
}
}
for (int dx = -half; dx <= half; dx++) {
placeTip(canvas, coral, dx, height - 1, 0, seed + dx);
tippedWidth = Math.max(tippedWidth, w);
}
}
@@ -23,6 +23,7 @@ import art.arcane.iris.engine.object.IrisMaterialPalette;
import art.arcane.iris.engine.object.IrisProceduralBlocks;
import art.arcane.iris.engine.object.IrisProceduralTree;
import art.arcane.iris.engine.object.IrisTreeDecorator;
import art.arcane.iris.engine.object.IrisTreeSecondaryLeaf;
import art.arcane.iris.spi.PlatformBlockState;
import art.arcane.iris.util.common.data.B;
import art.arcane.volmlib.util.math.RNG;
@@ -106,16 +107,16 @@ public final class TreeBlockResolver {
}
private static String pickWeighted(IrisProceduralTree tree, RNG rng) {
int total = 0;
for (art.arcane.iris.engine.object.IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
long total = 0;
for (IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
total += Math.max(0, s.getWeight());
}
if (total <= 0) {
return null;
}
double r = rng.nextDouble() * total;
double cumulative = 0;
for (art.arcane.iris.engine.object.IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
long cumulative = 0;
for (IrisTreeSecondaryLeaf s : tree.getWeightedSecondaryLeaves()) {
cumulative += Math.max(0, s.getWeight());
if (r < cumulative) {
return s.getBlock();