Add optional axis parameter for #sel cyl

This commit is contained in:
Brady
2023-06-08 16:32:33 -05:00
parent a1b1ef88cf
commit 26574b4a9b
3 changed files with 84 additions and 16 deletions

View File

@@ -0,0 +1,43 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package baritone.api.command.datatypes;
import baritone.api.command.exception.CommandException;
import baritone.api.command.helpers.TabCompleteHelper;
import net.minecraft.util.EnumFacing;
import java.util.Locale;
import java.util.stream.Stream;
public enum ForAxis implements IDatatypeFor<EnumFacing.Axis> {
INSTANCE;
@Override
public EnumFacing.Axis get(IDatatypeContext ctx) throws CommandException {
return EnumFacing.Axis.valueOf(ctx.getConsumer().getString().toUpperCase(Locale.US));
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
return new TabCompleteHelper()
.append(Stream.of(EnumFacing.Axis.values())
.map(EnumFacing.Axis::getName).map(String::toLowerCase))
.filterPrefix(ctx.getConsumer().getString())
.stream();
}
}

View File

@@ -17,29 +17,39 @@
package baritone.api.schematic;
import net.minecraft.util.EnumFacing;
/**
* @author Brady
*/
public final class CylinderSchematic extends CachedMaskSchematic {
public CylinderSchematic(ISchematic schematic, boolean filled) {
public CylinderSchematic(ISchematic schematic, boolean filled, EnumFacing.Axis alignment) {
super(schematic, new StaticMaskFunction() {
private final double centerX = schematic.widthX() / 2.0;
private final double centerZ = schematic.lengthZ() / 2.0;
private final double radiusSqX = this.centerX * this.centerX;
private final double radiusSqZ = this.centerZ * this.centerZ;
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 dx = Math.abs((x + 0.5) - this.centerX);
double dz = Math.abs((z + 0.5) - this.centerZ);
return !this.outside(dx, dz)
&& (filled || outside(dx + 1, dz) || outside(dx, dz + 1));
double da = Math.abs((this.getA(x, y) + 0.5) - this.centerA);
double db = Math.abs((this.getB(y, z) + 0.5) - this.centerB);
return !this.outside(da, db)
&& (filled || outside(da + 1, db) || outside(da, db + 1));
}
private boolean outside(double dx, double dz) {
return dx * dx / this.radiusSqX + dz * dz / this.radiusSqZ > 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;
}
});
}

View File

@@ -21,6 +21,7 @@ import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.datatypes.ForAxis;
import baritone.api.command.datatypes.ForBlockOptionalMeta;
import baritone.api.command.datatypes.ForEnumFacing;
import baritone.api.command.datatypes.RelativeBlockPos;
@@ -122,7 +123,9 @@ public class SelCommand extends Command {
BlockOptionalMeta type = action == Action.CLEARAREA
? new BlockOptionalMeta(Blocks.AIR)
: args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE);
BlockOptionalMetaLookup replaces;
final BlockOptionalMetaLookup replaces; // Action.REPLACE
final EnumFacing.Axis alignment; // Action.(H)CYLINDER
if (action == Action.REPLACE) {
args.requireMin(1);
List<BlockOptionalMeta> replacesList = new ArrayList<>();
@@ -132,9 +135,15 @@ public class SelCommand extends Command {
}
type = args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE);
replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0]));
alignment = null;
} else if (action == Action.CYLINDER || action == Action.HCYLINDER) {
args.requireMax(1);
alignment = args.hasAny() ? args.getDatatypeFor(ForAxis.INSTANCE) : EnumFacing.Axis.Y;
replaces = null;
} else {
args.requireMax(0);
replaces = null;
alignment = null;
}
ISelection[] selections = manager.getSelections();
if (selections.length == 0) {
@@ -168,9 +177,9 @@ public class SelCommand extends Command {
case HSPHERE:
return new SphereSchematic(fill, false);
case CYLINDER:
return new CylinderSchematic(fill, true);
return new CylinderSchematic(fill, true, alignment);
case HCYLINDER:
return new CylinderSchematic(fill, false);
return new CylinderSchematic(fill, false, alignment);
default:
// Silent fail
return fill;
@@ -279,6 +288,12 @@ public class SelCommand extends Command {
args.get();
}
return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE);
} else if (action == Action.CYLINDER || action == Action.HCYLINDER) {
if (args.hasExactly(2)) {
if (args.getDatatypeForOrNull(ForBlockOptionalMeta.INSTANCE) != null) {
return args.tabCompleteDatatype(ForAxis.INSTANCE);
}
}
}
} else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) {
if (args.hasExactlyOne()) {
@@ -326,8 +341,8 @@ public class SelCommand extends Command {
"> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.",
"> sel sphere/sph [block] - Fills the selection with a sphere bounded by the sides.",
"> sel hsphere/hsph [block] - The same as sphere, but hollow.",
"> sel cylinder/cyl [block] - Fills the selection with a cylinder bounded by the sides.",
"> sel hcylinder/hcyl [block] - The same as cylinder, but hollow.",
"> sel cylinder/cyl [block] <axis> - Fills the selection with a cylinder bounded by the sides, oriented about the given axis. (default=y)",
"> sel hcylinder/hcyl [block] <axis> - The same as cylinder, but hollow.",
"> sel cleararea/ca - Basically 'set air'.",
"> sel replace/r <blocks...> <with> - Replaces blocks with another block.",
"> sel copy/cp <x> <y> <z> - Copy the selected area relative to the specified or your position.",