diff --git a/core/src/main/java/com/boydti/fawe/object/brush/BlobBrush.java b/core/src/main/java/com/boydti/fawe/object/brush/BlobBrush.java new file mode 100644 index 00000000..22bf95b2 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/brush/BlobBrush.java @@ -0,0 +1,51 @@ +package com.boydti.fawe.object.brush; + +import com.boydti.fawe.object.random.SimplexNoise; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.command.tool.brush.Brush; +import com.sk89q.worldedit.function.pattern.Pattern; +import java.util.concurrent.ThreadLocalRandom; + +public class BlobBrush implements Brush { + private final double amplitude; + private final double frequency; + + public BlobBrush(double frequency, double amplitude) { + this.frequency = frequency; + this.amplitude = amplitude; + } + + @Override + public void build(EditSession editSession, Vector position, Pattern pattern, double size) throws MaxChangedBlocksException { + double seedX = ThreadLocalRandom.current().nextDouble(); + double seedY = ThreadLocalRandom.current().nextDouble(); + double seedZ = ThreadLocalRandom.current().nextDouble(); + + int px = position.getBlockX(); + int py = position.getBlockY(); + int pz = position.getBlockZ(); + + double distort = this.frequency / size; + + int radiusSqr = (int) (size * size); + int sizeInt = (int) size * 2; + for (int x = -sizeInt; x <= sizeInt; x++) { + double nx = seedX + x * distort; + int d1 = x * x; + for (int y = -sizeInt; y <= sizeInt; y++) { + int d2 = d1 + y * y; + double ny = seedY + y * distort; + for (int z = -sizeInt; z <= sizeInt; z++) { + double nz = seedZ + z * distort; + double distance = d2 + z * z; + double noise = this.amplitude * SimplexNoise.noise(nx, ny, nz); + if (distance + distance * noise < radiusSqr) { + editSession.setBlock(px + x, py + y, pz + z, pattern); + } + } + } + } + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 5c017df8..29a60a78 100644 --- a/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -26,6 +26,7 @@ import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.brush.BlendBall; +import com.boydti.fawe.object.brush.BlobBrush; import com.boydti.fawe.object.brush.BrushSettings; import com.boydti.fawe.object.brush.CatenaryBrush; import com.boydti.fawe.object.brush.CircleBrush; @@ -286,6 +287,24 @@ public class BrushCommands extends MethodCommands { .setFill(fill); } + @Command( + aliases = {"blob", "rock"}, + usage = " [radius=10] [frequency=30] [amplitude=50]", + flags = "h", + desc = "Creates a distorted sphere", + min = 1, + max = 4 + ) + @CommandPermissions("worldedit.brush.blob") + public BrushSettings blobBrush(Player player, EditSession editSession, LocalSession session, Pattern fill, @Optional("10") double radius, @Optional("30") double frequency, @Optional("50") double amplitude, CommandContext context) throws WorldEditException { + worldEdit.checkMaxBrushRadius(radius); + Brush brush = new BlobBrush(frequency / 100, amplitude / 100); + return get(context) + .setBrush(brush) + .setSize(radius) + .setFill(fill); + } + @Command( aliases = {"sphere", "s"}, usage = " [radius=2]",