diff --git a/src/api/java/baritone/api/schematic/CachedMaskSchematic.java b/src/api/java/baritone/api/schematic/CachedMaskSchematic.java
deleted file mode 100644
index 19bcf4e3a..000000000
--- a/src/api/java/baritone/api/schematic/CachedMaskSchematic.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file is part of Baritone.
- *
- * Baritone is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Baritone is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Baritone. If not, see .
- */
-
-package baritone.api.schematic;
-
-import net.minecraft.block.state.IBlockState;
-
-/**
- * @author Brady
- */
-public abstract class CachedMaskSchematic extends MaskSchematic {
-
- /**
- * Mask array with {@code y,z,x} indexing
- */
- private final boolean[][][] mask;
-
- public CachedMaskSchematic(ISchematic schematic, StaticMaskFunction maskFunction) {
- super(schematic);
- this.mask = new boolean[schematic.heightY()][schematic.lengthZ()][schematic.widthX()];
- for (int y = 0; y < schematic.heightY(); y++) {
- for (int z = 0; z < schematic.lengthZ(); z++) {
- for (int x = 0; x < schematic.widthX(); x++) {
- this.mask[y][z][x] = maskFunction.partOfMask(x, y, z);
- }
- }
- }
- }
-
- @Override
- protected final boolean partOfMask(int x, int y, int z, IBlockState currentState) {
- return this.mask[y][z][x];
- }
-
- @FunctionalInterface
- public interface StaticMaskFunction {
- boolean partOfMask(int x, int y, int z);
- }
-}
diff --git a/src/api/java/baritone/api/schematic/CylinderSchematic.java b/src/api/java/baritone/api/schematic/CylinderSchematic.java
deleted file mode 100644
index 29b5aa5b3..000000000
--- a/src/api/java/baritone/api/schematic/CylinderSchematic.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is part of Baritone.
- *
- * Baritone is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Baritone is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Baritone. If not, see .
- */
-
-package baritone.api.schematic;
-
-import net.minecraft.util.EnumFacing;
-
-/**
- * @author Brady
- */
-public final class CylinderSchematic extends CachedMaskSchematic {
-
- public CylinderSchematic(ISchematic schematic, boolean filled, EnumFacing.Axis alignment) {
- super(schematic, new StaticMaskFunction() {
-
- private final double centerA = this.getA(schematic.widthX(), schematic.heightY()) / 2.0;
- private final double centerB = this.getB(schematic.heightY(), schematic.lengthZ()) / 2.0;
- private final double radiusSqA = this.centerA * this.centerA;
- private final double radiusSqB = this.centerB * this.centerB;
-
- @Override
- public boolean partOfMask(int x, int y, int z) {
- double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA);
- double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB);
- if (this.outside(da, db)) {
- return false;
- }
- return filled
- || this.outside(da + 1, db)
- || this.outside(da, db + 1);
- }
-
- private boolean outside(double da, double db) {
- return da * da / this.radiusSqA + db * db / this.radiusSqB > 1;
- }
-
- private int getA(int x, int y) {
- return alignment == EnumFacing.Axis.X ? y : x;
- }
-
- private int getB(int y, int z) {
- return alignment == EnumFacing.Axis.Z ? y : z;
- }
- });
- }
-}
diff --git a/src/api/java/baritone/api/schematic/MaskSchematic.java b/src/api/java/baritone/api/schematic/MaskSchematic.java
index 229f58d5b..2853c6e58 100644
--- a/src/api/java/baritone/api/schematic/MaskSchematic.java
+++ b/src/api/java/baritone/api/schematic/MaskSchematic.java
@@ -17,6 +17,7 @@
package baritone.api.schematic;
+import baritone.api.schematic.mask.Mask;
import net.minecraft.block.state.IBlockState;
import java.util.List;
@@ -41,4 +42,14 @@ public abstract class MaskSchematic extends AbstractSchematic {
public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) {
return schematic.desiredState(x, y, z, current, approxPlaceable);
}
+
+ public static MaskSchematic create(ISchematic schematic, Mask function) {
+ return new MaskSchematic(schematic) {
+
+ @Override
+ protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
+ return function.partOfMask(x, y, z, currentState);
+ }
+ };
+ }
}
diff --git a/src/api/java/baritone/api/schematic/SphereSchematic.java b/src/api/java/baritone/api/schematic/SphereSchematic.java
deleted file mode 100644
index 074e6ec51..000000000
--- a/src/api/java/baritone/api/schematic/SphereSchematic.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file is part of Baritone.
- *
- * Baritone is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Baritone is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Baritone. If not, see .
- */
-
-package baritone.api.schematic;
-
-/**
- * @author Brady
- */
-public final class SphereSchematic extends CachedMaskSchematic {
-
- public SphereSchematic(ISchematic schematic, boolean filled) {
- super(schematic, new StaticMaskFunction() {
-
- private final double centerX = schematic.widthX() / 2.0;
- private final double centerY = schematic.heightY() / 2.0;
- private final double centerZ = schematic.lengthZ() / 2.0;
- private final double radiusSqX = this.centerX * this.centerX;
- private final double radiusSqY = this.centerY * this.centerY;
- private final double radiusSqZ = this.centerZ * this.centerZ;
-
- @Override
- public boolean partOfMask(int x, int y, int z) {
- double dx = Math.abs((x + 0.5) - this.centerX);
- double dy = Math.abs((y + 0.5) - this.centerY);
- double dz = Math.abs((z + 0.5) - this.centerZ);
- if (this.outside(dx, dy, dz)) {
- return false;
- }
- return filled
- || this.outside(dx + 1, dy, dz)
- || this.outside(dx, dy + 1, dz)
- || this.outside(dx, dy, dz + 1);
- }
-
- private boolean outside(double dx, double dy, double dz) {
- return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1;
- }
- });
- }
-}
diff --git a/src/api/java/baritone/api/schematic/mask/AbstractMask.java b/src/api/java/baritone/api/schematic/mask/AbstractMask.java
new file mode 100644
index 000000000..ce92af0ec
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/mask/AbstractMask.java
@@ -0,0 +1,49 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic.mask;
+
+/**
+ * @author Brady
+ */
+public abstract class AbstractMask implements Mask {
+
+ private final int widthX;
+ private final int heightY;
+ private final int lengthZ;
+
+ public AbstractMask(int widthX, int heightY, int lengthZ) {
+ this.widthX = widthX;
+ this.heightY = heightY;
+ this.lengthZ = lengthZ;
+ }
+
+ @Override
+ public int widthX() {
+ return this.widthX;
+ }
+
+ @Override
+ public int heightY() {
+ return this.heightY;
+ }
+
+ @Override
+ public int lengthZ() {
+ return this.lengthZ;
+ }
+}
diff --git a/src/api/java/baritone/api/schematic/mask/Mask.java b/src/api/java/baritone/api/schematic/mask/Mask.java
new file mode 100644
index 000000000..540c2cee1
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/mask/Mask.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic.mask;
+
+import net.minecraft.block.state.IBlockState;
+
+/**
+ * @author Brady
+ */
+public interface Mask {
+
+ /**
+ * @param x The relative x position of the block
+ * @param y The relative y position of the block
+ * @param z The relative z position of the block
+ * @param currentState The current state of that block in the world, may be {@code null}
+ * @return Whether the given position is included in this mask
+ */
+ boolean partOfMask(int x, int y, int z, IBlockState currentState);
+
+ int widthX();
+
+ int heightY();
+
+ int lengthZ();
+}
diff --git a/src/api/java/baritone/api/schematic/mask/PreComputedMask.java b/src/api/java/baritone/api/schematic/mask/PreComputedMask.java
new file mode 100644
index 000000000..aed26cc94
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/mask/PreComputedMask.java
@@ -0,0 +1,44 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic.mask;
+
+/**
+ * @author Brady
+ */
+final class PreComputedMask extends AbstractMask implements StaticMask {
+
+ private final boolean[][][] mask;
+
+ public PreComputedMask(StaticMask mask) {
+ super(mask.widthX(), mask.heightY(), mask.lengthZ());
+
+ this.mask = new boolean[this.heightY()][this.lengthZ()][this.widthX()];
+ for (int y = 0; y < this.heightY(); y++) {
+ for (int z = 0; z < this.lengthZ(); z++) {
+ for (int x = 0; x < this.widthX(); x++) {
+ this.mask[y][z][x] = mask.partOfMask(x, y, z);
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean partOfMask(int x, int y, int z) {
+ return this.mask[y][z][x];
+ }
+}
diff --git a/src/api/java/baritone/api/schematic/mask/StaticMask.java b/src/api/java/baritone/api/schematic/mask/StaticMask.java
new file mode 100644
index 000000000..ef50a65cc
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/mask/StaticMask.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic.mask;
+
+import net.minecraft.block.state.IBlockState;
+
+/**
+ * A mask that is context-free. In other words, it doesn't require the current block state to determine if a relative
+ * position is a part of the mask.
+ *
+ * @author Brady
+ */
+public interface StaticMask extends Mask {
+
+ /**
+ * Determines if a given relative coordinate is included in this mask, without the need for the current block state.
+ *
+ * @param x The relative x position of the block
+ * @param y The relative y position of the block
+ * @param z The relative z position of the block
+ * @return Whether the given position is included in this mask
+ */
+ boolean partOfMask(int x, int y, int z);
+
+ /**
+ * Implements the parent {@link Mask#partOfMask partOfMask function} by calling the static function
+ * provided in this functional interface without needing the {@link IBlockState} argument. This {@code default}
+ * implementation should NOT be overriden.
+ *
+ * @param x The relative x position of the block
+ * @param y The relative y position of the block
+ * @param z The relative z position of the block
+ * @param currentState The current state of that block in the world, may be {@code null}
+ * @return Whether the given position is included in this mask
+ */
+ @Override
+ default boolean partOfMask(int x, int y, int z, IBlockState currentState) {
+ return this.partOfMask(x, y, z);
+ }
+
+ /**
+ * Returns a pre-computed mask using {@code this} function, with the specified size parameters.
+ */
+ default StaticMask compute() {
+ return new PreComputedMask(this);
+ }
+}
diff --git a/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java
new file mode 100644
index 000000000..71b0d43c9
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/mask/shape/CylinderMask.java
@@ -0,0 +1,69 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic.mask.shape;
+
+import baritone.api.schematic.mask.AbstractMask;
+import baritone.api.schematic.mask.StaticMask;
+import net.minecraft.util.EnumFacing;
+
+/**
+ * @author Brady
+ */
+public final class CylinderMask extends AbstractMask implements StaticMask {
+
+ private final double centerA;
+ private final double centerB;
+ private final double radiusSqA;
+ private final double radiusSqB;
+ private final boolean filled;
+ private final EnumFacing.Axis alignment;
+
+ public CylinderMask(int widthX, int heightY, int lengthZ, boolean filled, EnumFacing.Axis alignment) {
+ super(widthX, heightY, lengthZ);
+ this.centerA = this.getA(widthX, heightY) / 2.0;
+ this.centerB = this.getB(heightY, lengthZ) / 2.0;
+ this.radiusSqA = (this.centerA - 1) * (this.centerA - 1);
+ this.radiusSqB = (this.centerB - 1) * (this.centerB - 1);
+ this.filled = filled;
+ this.alignment = alignment;
+ }
+
+ @Override
+ public boolean partOfMask(int x, int y, int z) {
+ double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA);
+ double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB);
+ if (this.outside(da, db)) {
+ return false;
+ }
+ return this.filled
+ || this.outside(da + 1, db)
+ || this.outside(da, db + 1);
+ }
+
+ private boolean outside(double da, double db) {
+ return da * da / this.radiusSqA + db * db / this.radiusSqB > 1;
+ }
+
+ private int getA(int x, int y) {
+ return this.alignment == EnumFacing.Axis.X ? y : x;
+ }
+
+ private int getB(int y, int z) {
+ return this.alignment == EnumFacing.Axis.Z ? y : z;
+ }
+}
diff --git a/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java b/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java
new file mode 100644
index 000000000..d805c98a8
--- /dev/null
+++ b/src/api/java/baritone/api/schematic/mask/shape/SphereMask.java
@@ -0,0 +1,64 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.schematic.mask.shape;
+
+import baritone.api.schematic.mask.AbstractMask;
+import baritone.api.schematic.mask.StaticMask;
+
+/**
+ * @author Brady
+ */
+public final class SphereMask extends AbstractMask implements StaticMask {
+
+ private final double centerX;
+ private final double centerY;
+ private final double centerZ;
+ private final double radiusSqX;
+ private final double radiusSqY;
+ private final double radiusSqZ;
+ private final boolean filled;
+
+ public SphereMask(int widthX, int heightY, int lengthZ, boolean filled) {
+ super(widthX, heightY, lengthZ);
+ this.centerX = widthX / 2.0;
+ this.centerY = heightY / 2.0;
+ this.centerZ = lengthZ / 2.0;
+ this.radiusSqX = this.centerX * this.centerX;
+ this.radiusSqY = this.centerY * this.centerY;
+ this.radiusSqZ = this.centerZ * this.centerZ;
+ this.filled = filled;
+ }
+
+ @Override
+ public boolean partOfMask(int x, int y, int z) {
+ double dx = Math.abs((x + 0.5) - this.centerX);
+ double dy = Math.abs((y + 0.5) - this.centerY);
+ double dz = Math.abs((z + 0.5) - this.centerZ);
+ if (this.outside(dx, dy, dz)) {
+ return false;
+ }
+ return this.filled
+ || this.outside(dx + 1, dy, dz)
+ || this.outside(dx, dy + 1, dz)
+ || this.outside(dx, dy, dz + 1);
+ }
+
+ private boolean outside(double dx, double dy, double dz) {
+ return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1;
+ }
+}
diff --git a/src/main/java/baritone/command/defaults/SelCommand.java b/src/main/java/baritone/command/defaults/SelCommand.java
index 72c5cd1c0..e1d2082ff 100644
--- a/src/main/java/baritone/command/defaults/SelCommand.java
+++ b/src/main/java/baritone/command/defaults/SelCommand.java
@@ -32,6 +32,8 @@ import baritone.api.command.helpers.TabCompleteHelper;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.schematic.*;
+import baritone.api.schematic.mask.shape.CylinderMask;
+import baritone.api.schematic.mask.shape.SphereMask;
import baritone.api.selection.ISelection;
import baritone.api.selection.ISelectionManager;
import baritone.api.utils.BetterBlockPos;
@@ -173,13 +175,13 @@ public class SelCommand extends Command {
case REPLACE:
return new ReplaceSchematic(fill, replaces);
case SPHERE:
- return new SphereSchematic(fill, true);
+ return MaskSchematic.create(fill, new SphereMask(size.getX(), size.getY(), size.getZ(), true).compute());
case HSPHERE:
- return new SphereSchematic(fill, false);
+ return MaskSchematic.create(fill, new SphereMask(size.getX(), size.getY(), size.getZ(), false).compute());
case CYLINDER:
- return new CylinderSchematic(fill, true, alignment);
+ return MaskSchematic.create(fill, new CylinderMask(size.getX(), size.getY(), size.getZ(), true, alignment).compute());
case HCYLINDER:
- return new CylinderSchematic(fill, false, alignment);
+ return MaskSchematic.create(fill, new CylinderMask(size.getX(), size.getY(), size.getZ(), false, alignment).compute());
default:
// Silent fail
return fill;