diff --git a/core/src/main/java/art/arcane/iris/engine/object/tree/TreeDecoratorApplier.java b/core/src/main/java/art/arcane/iris/engine/object/tree/TreeDecoratorApplier.java index a4f34ffa4..6d36a0469 100644 --- a/core/src/main/java/art/arcane/iris/engine/object/tree/TreeDecoratorApplier.java +++ b/core/src/main/java/art/arcane/iris/engine/object/tree/TreeDecoratorApplier.java @@ -67,11 +67,24 @@ public final class TreeDecoratorApplier { if (rng.nextDouble() > dec.getChance()) { continue; } - if (canvas.has(e[0], e[1], e[2])) { + int dx = e[0] - e[3]; + int dz = e[2] - e[4]; + boolean alongX = Math.abs(dx) >= Math.abs(dz); + int stepX = alongX ? (dx >= 0 ? 1 : -1) : 0; + int stepZ = alongX ? 0 : (dz >= 0 ? 1 : -1); + int x = e[0] + stepX; + int z = e[2] + stepZ; + TreeBlockCanvas.Cell cell = canvas.get(x, e[1], z); + while (cell != null && cell.role() != TreeBlockCanvas.Role.DECORATOR) { + x += stepX; + z += stepZ; + cell = canvas.get(x, e[1], z); + } + if (cell != null) { continue; } String facing = dec.isAxisAware() ? facingAway(e[3], e[4], e[0], e[2]) : null; - canvas.setDecor(e[0], e[1], e[2], idx, facing); + canvas.setDecor(x, e[1], z, idx, facing); } } diff --git a/core/src/test/java/art/arcane/iris/engine/object/tree/TreeDecoratorApplierTest.java b/core/src/test/java/art/arcane/iris/engine/object/tree/TreeDecoratorApplierTest.java new file mode 100644 index 000000000..6fc05ebae --- /dev/null +++ b/core/src/test/java/art/arcane/iris/engine/object/tree/TreeDecoratorApplierTest.java @@ -0,0 +1,45 @@ +package art.arcane.iris.engine.object.tree; + +import art.arcane.iris.engine.object.IrisProceduralTree; +import art.arcane.iris.engine.object.IrisTreeDecorator; +import art.arcane.iris.engine.object.IrisTreeDecoratorTarget; +import art.arcane.volmlib.util.collection.KList; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class TreeDecoratorApplierTest { + @Test + public void branchTipsExtendOutwardThroughLeavesWithoutReplacingWood() { + TreeBlockCanvas canvas = new TreeBlockCanvas(); + for (int x = -3; x <= 3; x++) { + canvas.setTrunk(x, 4, 0, TreeBlockCanvas.Role.TRUNK, TreeBlockCanvas.Axis.X); + } + canvas.setLeaf(-4, 4, 0, TreeBlockCanvas.Role.LEAF); + canvas.setLeaf(4, 4, 0, TreeBlockCanvas.Role.LEAF); + IrisTreeDecorator decorator = new IrisTreeDecorator() + .setTarget(IrisTreeDecoratorTarget.BRANCH_TIP) + .setBlock("minecraft:shroomlight") + .setChance(1D) + .setAxisAware(true); + IrisProceduralTree tree = new IrisProceduralTree(); + tree.setDecorators(new KList<>(decorator)); + List endpoints = List.of(new int[]{-3, 4, 0, 0, 0}, new int[]{3, 4, 0, 0, 0}); + + TreeDecoratorApplier.apply(canvas, tree, 4321L, endpoints); + + assertEquals(TreeBlockCanvas.Role.DECORATOR, canvas.get(-5, 4, 0).role()); + assertEquals("west", canvas.get(-5, 4, 0).facing()); + assertEquals(TreeBlockCanvas.Role.DECORATOR, canvas.get(5, 4, 0).role()); + assertEquals("east", canvas.get(5, 4, 0).facing()); + assertEquals(7, canvas.getTrunk().size()); + assertEquals(2, canvas.getLeaf().size()); + assertEquals(11, canvas.getCells().size()); + + TreeDecoratorApplier.apply(canvas, tree, 4321L, endpoints); + + assertEquals(11, canvas.getCells().size()); + } +}