From 991283182cde4b61bdef3743a1e2d53fc01c2bdb Mon Sep 17 00:00:00 2001 From: Logan Darklock Date: Tue, 3 Sep 2019 08:35:16 -0700 Subject: [PATCH] Fix some bugs with schematics --- .../api/schematic/AbstractSchematic.java | 48 ++++++++++++++++++- .../api/schematic/CompositeSchematic.java | 5 +- .../api/schematic/FillBomSchematic.java | 16 +++++-- .../baritone/api/schematic/MaskSchematic.java | 5 +- .../api/schematic/ReplaceSchematic.java | 21 ++++++++ .../api/schematic/ShellSchematic.java | 5 +- .../api/schematic/WallsSchematic.java | 5 +- .../baritone/api/utils/BlockOptionalMeta.java | 8 ---- .../utils/command/defaults/SelCommand.java | 42 ++++++++++++---- .../java/baritone/process/BuilderProcess.java | 2 +- 10 files changed, 128 insertions(+), 29 deletions(-) create mode 100644 src/api/java/baritone/api/schematic/ReplaceSchematic.java diff --git a/src/api/java/baritone/api/schematic/AbstractSchematic.java b/src/api/java/baritone/api/schematic/AbstractSchematic.java index 3b6bb41c..ec4d8731 100644 --- a/src/api/java/baritone/api/schematic/AbstractSchematic.java +++ b/src/api/java/baritone/api/schematic/AbstractSchematic.java @@ -1,13 +1,30 @@ package baritone.api.schematic; +import baritone.api.IBaritone; +import baritone.api.utils.IPlayerContext; import baritone.api.utils.ISchematic; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.NonNullList; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; public abstract class AbstractSchematic implements ISchematic { + protected final IBaritone baritone; + protected final IPlayerContext ctx; protected int x; protected int y; protected int z; - public AbstractSchematic(int x, int y, int z) { + public AbstractSchematic(@Nullable IBaritone baritone, int x, int y, int z) { + this.baritone = baritone; + this.ctx = baritone == null ? null : baritone.getPlayerContext(); this.x = x; this.y = y; this.z = z; @@ -27,4 +44,33 @@ public abstract class AbstractSchematic implements ISchematic { public int lengthZ() { return z; } + + protected IBlockState[] approxPlaceable() { + EntityPlayerSP player = ctx.player(); + NonNullList inventory = player.inventory.mainInventory; + List placeable = new ArrayList<>(); + placeable.add(Blocks.AIR.getDefaultState()); + + // 27 + 9 + for (int i = 0; i < 36; i++) { + ItemStack stack = inventory.get(i); + + if (!stack.isEmpty() && stack.getItem() instanceof ItemBlock) { + // + placeable.add(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement( + ctx.world(), + ctx.playerFeet(), + EnumFacing.UP, + (float) player.posX, + (float) player.posY, + (float) player.posZ, + stack.getItem().getMetadata(stack.getMetadata()), + player + )); + // + } + } + + return placeable.toArray(new IBlockState[0]); + } } diff --git a/src/api/java/baritone/api/schematic/CompositeSchematic.java b/src/api/java/baritone/api/schematic/CompositeSchematic.java index 56c49b80..deb9f5fe 100644 --- a/src/api/java/baritone/api/schematic/CompositeSchematic.java +++ b/src/api/java/baritone/api/schematic/CompositeSchematic.java @@ -1,5 +1,6 @@ package baritone.api.schematic; +import baritone.api.IBaritone; import baritone.api.utils.ISchematic; import net.minecraft.block.state.IBlockState; @@ -20,8 +21,8 @@ public class CompositeSchematic extends AbstractSchematic { } } - public CompositeSchematic(int x, int y, int z) { - super(x, y, z); + public CompositeSchematic(IBaritone baritone, int x, int y, int z) { + super(baritone, x, y, z); schematics = new ArrayList<>(); recalcArr(); } diff --git a/src/api/java/baritone/api/schematic/FillBomSchematic.java b/src/api/java/baritone/api/schematic/FillBomSchematic.java index b7536e81..7989cbfc 100644 --- a/src/api/java/baritone/api/schematic/FillBomSchematic.java +++ b/src/api/java/baritone/api/schematic/FillBomSchematic.java @@ -1,13 +1,15 @@ package baritone.api.schematic; +import baritone.api.IBaritone; import baritone.api.utils.BlockOptionalMeta; import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; public class FillBomSchematic extends AbstractSchematic { private final BlockOptionalMeta bom; - public FillBomSchematic(int x, int y, int z, BlockOptionalMeta bom) { - super(x, y, z); + public FillBomSchematic(IBaritone baritone, int x, int y, int z, BlockOptionalMeta bom) { + super(baritone, x, y, z); this.bom = bom; } @@ -19,8 +21,16 @@ public class FillBomSchematic extends AbstractSchematic { public IBlockState desiredState(int x, int y, int z, IBlockState current) { if (bom.matches(current)) { return current; + } else if (current.getBlock() != Blocks.AIR) { + return Blocks.AIR.getDefaultState(); } - return bom.getAnyBlockState(); + for (IBlockState placeable : approxPlaceable()) { + if (bom.matches(placeable)) { + return placeable; + } + } + + throw new IllegalStateException("Couldn't find desired state"); } } diff --git a/src/api/java/baritone/api/schematic/MaskSchematic.java b/src/api/java/baritone/api/schematic/MaskSchematic.java index 033e390c..133e4e62 100644 --- a/src/api/java/baritone/api/schematic/MaskSchematic.java +++ b/src/api/java/baritone/api/schematic/MaskSchematic.java @@ -1,13 +1,14 @@ package baritone.api.schematic; +import baritone.api.IBaritone; import baritone.api.utils.ISchematic; import net.minecraft.block.state.IBlockState; public abstract class MaskSchematic extends AbstractSchematic { private final ISchematic schematic; - public MaskSchematic(ISchematic schematic) { - super(schematic.widthX(), schematic.heightY(), schematic.lengthZ()); + public MaskSchematic(IBaritone baritone, ISchematic schematic) { + super(baritone, schematic.widthX(), schematic.heightY(), schematic.lengthZ()); this.schematic = schematic; } diff --git a/src/api/java/baritone/api/schematic/ReplaceSchematic.java b/src/api/java/baritone/api/schematic/ReplaceSchematic.java new file mode 100644 index 00000000..2d13f1eb --- /dev/null +++ b/src/api/java/baritone/api/schematic/ReplaceSchematic.java @@ -0,0 +1,21 @@ +package baritone.api.schematic; + +import baritone.api.IBaritone; +import baritone.api.utils.BlockOptionalMetaLookup; +import baritone.api.utils.ISchematic; +import net.minecraft.block.state.IBlockState; + +public class ReplaceSchematic extends MaskSchematic { + private final BlockOptionalMetaLookup filter; + private final boolean[][][] cache; + + public ReplaceSchematic(IBaritone baritone, ISchematic schematic, BlockOptionalMetaLookup filter) { + super(baritone, schematic); + this.filter = filter; + this.cache = new boolean[lengthZ()][heightY()][widthX()]; + } + + protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return cache[x][y][z] || (cache[x][y][z] = filter.has(currentState)); + } +} diff --git a/src/api/java/baritone/api/schematic/ShellSchematic.java b/src/api/java/baritone/api/schematic/ShellSchematic.java index 2c94fa9f..c6c1bcf2 100644 --- a/src/api/java/baritone/api/schematic/ShellSchematic.java +++ b/src/api/java/baritone/api/schematic/ShellSchematic.java @@ -1,11 +1,12 @@ package baritone.api.schematic; +import baritone.api.IBaritone; import baritone.api.utils.ISchematic; import net.minecraft.block.state.IBlockState; public class ShellSchematic extends MaskSchematic { - public ShellSchematic(ISchematic schematic) { - super(schematic); + public ShellSchematic(IBaritone baritone, ISchematic schematic) { + super(baritone, schematic); } protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { diff --git a/src/api/java/baritone/api/schematic/WallsSchematic.java b/src/api/java/baritone/api/schematic/WallsSchematic.java index 8091944e..ed66e2fc 100644 --- a/src/api/java/baritone/api/schematic/WallsSchematic.java +++ b/src/api/java/baritone/api/schematic/WallsSchematic.java @@ -1,11 +1,12 @@ package baritone.api.schematic; +import baritone.api.IBaritone; import baritone.api.utils.ISchematic; import net.minecraft.block.state.IBlockState; public class WallsSchematic extends MaskSchematic { - public WallsSchematic(ISchematic schematic) { - super(schematic); + public WallsSchematic(IBaritone baritone, ISchematic schematic) { + super(baritone, schematic); } protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index bd17307c..1fd4264f 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -322,12 +322,4 @@ public final class BlockOptionalMeta { //noinspection deprecation return Block.getBlockFromItem(stack.getItem()).getStateFromMeta(stack.getMetadata()); } - - public IBlockState getAnyBlockState() { - if (blockstates.size() > 0) { - return blockstates.iterator().next(); - } - - return null; - } } diff --git a/src/api/java/baritone/api/utils/command/defaults/SelCommand.java b/src/api/java/baritone/api/utils/command/defaults/SelCommand.java index 2579a3bd..fea637e8 100644 --- a/src/api/java/baritone/api/utils/command/defaults/SelCommand.java +++ b/src/api/java/baritone/api/utils/command/defaults/SelCommand.java @@ -21,12 +21,14 @@ import baritone.api.Settings; import baritone.api.event.events.RenderEvent; import baritone.api.schematic.CompositeSchematic; import baritone.api.schematic.FillBomSchematic; +import baritone.api.schematic.ReplaceSchematic; import baritone.api.schematic.ShellSchematic; import baritone.api.schematic.WallsSchematic; import baritone.api.selection.ISelection; import baritone.api.selection.ISelectionManager; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BlockOptionalMeta; +import baritone.api.utils.BlockOptionalMetaLookup; import baritone.api.utils.IRenderer; import baritone.api.utils.ISchematic; import baritone.api.utils.command.Command; @@ -43,6 +45,7 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.Vec3i; import java.awt.Color; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -104,11 +107,26 @@ public class SelCommand extends Command { logDirect("Undid pos2"); } } - } else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA) { + } else if (action == Action.SET || action == Action.WALLS || action == Action.SHELL || action == Action.CLEARAREA || action == Action.REPLACE) { BlockOptionalMeta type = action == Action.CLEARAREA ? new BlockOptionalMeta(Blocks.AIR) : args.getDatatypeFor(ForBlockOptionalMeta.class); - args.requireMax(0); + BlockOptionalMetaLookup replaces = null; + + if (action == Action.REPLACE) { + args.requireMin(1); + + List replacesList = new ArrayList<>(); + + while (args.has()) { + replacesList.add(args.getDatatypeFor(ForBlockOptionalMeta.class)); + } + + replaces = new BlockOptionalMetaLookup(replacesList.toArray(new BlockOptionalMeta[0])); + } else { + args.requireMax(0); + } + ISelection[] selections = manager.getSelections(); if (selections.length == 0) { @@ -116,7 +134,7 @@ public class SelCommand extends Command { } BetterBlockPos origin = selections[0].min(); - CompositeSchematic composite = new CompositeSchematic(0, 0, 0); + CompositeSchematic composite = new CompositeSchematic(baritone, 0, 0, 0); for (ISelection selection : selections) { BetterBlockPos min = selection.min(); @@ -131,12 +149,14 @@ public class SelCommand extends Command { Vec3i size = selection.size(); BetterBlockPos min = selection.min(); - ISchematic schematic = new FillBomSchematic(size.getX(), size.getY(), size.getZ(), type); + ISchematic schematic = new FillBomSchematic(baritone, size.getX(), size.getY(), size.getZ(), type); if (action == Action.WALLS) { - schematic = new WallsSchematic(schematic); + schematic = new WallsSchematic(baritone, schematic); } else if (action == Action.SHELL) { - schematic = new ShellSchematic(schematic); + schematic = new ShellSchematic(baritone, schematic); + } else if (action == Action.REPLACE) { + schematic = new ReplaceSchematic(baritone, schematic, replaces); } composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z); @@ -193,8 +213,12 @@ public class SelCommand extends Command { if (args.hasAtMost(3)) { return args.tabCompleteDatatype(RelativeBlockPos.class); } - } else if (action == Action.SET || action == Action.WALLS || action == Action.CLEARAREA) { - if (args.hasExactlyOne()) { + } else if (action == Action.SET || action == Action.WALLS || action == Action.CLEARAREA || action == Action.REPLACE) { + if (args.hasExactlyOne() || action == Action.REPLACE) { + while (args.has(2)) { + args.get(); + } + return args.tabCompleteDatatype(ForBlockOptionalMeta.class); } } else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) { @@ -239,6 +263,7 @@ public class SelCommand extends Command { "> sel walls/w [block] - Fill in the walls of the selection with a specified block.", "> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.", "> sel cleararea/ca - Basically 'set air'.", + "> sel replace/r - Replaces, with 'place', all blocks listed after it.", "", "> sel expand - Expand the targets.", "> sel contract - Contract the targets.", @@ -257,6 +282,7 @@ public class SelCommand extends Command { WALLS("walls", "w"), SHELL("shell", "shl"), CLEARAREA("cleararea", "ca"), + REPLACE("replace", "r"), EXPAND("expand", "ex"), CONTRACT("contract", "ct"), diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index b3f31059..6bea9a7c 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -522,7 +522,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil int blockX = x + origin.getX(); int blockY = y + origin.getY(); int blockZ = z + origin.getZ(); - IBlockState current = bcc.bsi.get0(x, y, z); + IBlockState current = bcc.bsi.get0(blockX, blockY, blockZ); if (!schematic.inSchematic(x, y, z, current)) { continue; }