diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 527e3d364..24d644b61 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -847,6 +847,11 @@ public final class Settings { */ public final Setting skipFailedLayers = new Setting<>(false); + /** + * Only build the selected part of schematics + */ + public final Setting buildOnlySelection = new Setting<>(false); + /** * How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely */ diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index ca8ca534a..cf5c0193a 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -43,6 +43,7 @@ import baritone.utils.BlockStateInterface; import baritone.utils.NotificationHelper; import baritone.utils.PathingCommandContext; import baritone.utils.schematic.MapArtSchematic; +import baritone.utils.schematic.SelectionSchematic; import baritone.utils.schematic.SchematicSystem; import baritone.utils.schematic.schematica.SchematicaHelper; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -140,6 +141,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil parsed = new MapArtSchematic((IStaticSchematic) parsed); } + if (Baritone.settings().buildOnlySelection.value) { + parsed = new SelectionSchematic(parsed, origin, baritone.getSelectionManager().getSelections()); + } + + build(name, parsed, origin); return true; } @@ -150,10 +156,15 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil Optional> schematic = SchematicaHelper.getOpenSchematic(); if (schematic.isPresent()) { IStaticSchematic s = schematic.get().getFirst(); + BlockPos origin = schematic.get().getSecond(); + ISchematic schem = Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s; + if (Baritone.settings().buildOnlySelection.value) { + schem = new SelectionSchematic(schem, origin, baritone.getSelectionManager().getSelections()); + } this.build( schematic.get().getFirst().toString(), - Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s, - schematic.get().getSecond() + schem, + origin ); } else { logDirect("No schematic currently open"); diff --git a/src/main/java/baritone/utils/schematic/SelectionSchematic.java b/src/main/java/baritone/utils/schematic/SelectionSchematic.java new file mode 100644 index 000000000..243a3d4d0 --- /dev/null +++ b/src/main/java/baritone/utils/schematic/SelectionSchematic.java @@ -0,0 +1,53 @@ +/* + * 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.utils.schematic; + +import baritone.api.schematic.ISchematic; +import baritone.api.schematic.MaskSchematic; +import baritone.api.selection.ISelection; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.Vec3i; + +import java.util.stream.Stream; + +public class SelectionSchematic extends MaskSchematic { + + private final ISelection[] selections; + + public SelectionSchematic(ISchematic schematic, Vec3i origin, ISelection[] selections) { + super(schematic); + this.selections = Stream.of(selections).map( + sel -> sel + .shift(EnumFacing.WEST, origin.getX()) + .shift(EnumFacing.DOWN, origin.getY()) + .shift(EnumFacing.NORTH, origin.getZ())) + .toArray(ISelection[]::new); + } + + @Override + protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { + for (ISelection selection : selections) { + if (x >= selection.min().x && y >= selection.min().y && z >= selection.min().z + && x <= selection.max().x && y <= selection.max().y && z <= selection.max().z) { + return true; + } + } + return false; + } +}