diff --git a/Dockerfile b/Dockerfile index bec43d69..020bea0c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,16 @@ -FROM debian:jessie +FROM debian:stretch -RUN echo 'deb http://deb.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list +RUN echo 'deb http://deb.debian.org/debian stretch-backports main' > /etc/apt/sources.list.d/stretch-backports.list ENV DEBIAN_FRONTEND noninteractive RUN apt update -y -RUN apt install --target-release jessie-backports \ +RUN apt install \ openjdk-8-jdk \ - ca-certificates-java \ --assume-yes -RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common +RUN apt install -qq --assume-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common COPY . /code @@ -21,4 +20,4 @@ WORKDIR /code # source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173 RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb -RUN ./gradlew build \ No newline at end of file +RUN ./gradlew build diff --git a/README.md b/README.md index f498951c..e016fa94 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,10 @@ ![Code size](https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg) ![GitHub repo size](https://img.shields.io/github/repo-size/cabaletta/baritone.svg) ![](https://tokei.rs/b1/github/cabaletta/baritone?category=code) -![](https://tokei.rs/b1/github/cabaletta/baritone?category=files) [![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2) [![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/) [![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/) -[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.3-brightgreen.svg)](https://impactdevelopment.github.io/) +[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.5%20/%20v1.3.0-brightgreen.svg)](https://impactdevelopment.github.io/) [![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/) [![KAMI integration](https://img.shields.io/badge/KAMI%20integration-v1.0.0-red.svg)](https://github.com/zeroeightysix/KAMI/) [![Future integration](https://img.shields.io/badge/Future%20integration-Soonβ„’%3F%3F%3F-red.svg)](https://futureclient.net/) @@ -32,7 +31,7 @@ Baritone is the pathfinding system used in [Impact](https://impactdevelopment.gi This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). -Have committed at least once a day for the last 7 months =D πŸ¦€ +Have committed at least once a day for the last 8 months =D πŸ¦€ 1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2 diff --git a/SETUP.md b/SETUP.md index 49ab838f..1767e2c5 100644 --- a/SETUP.md +++ b/SETUP.md @@ -1,7 +1,7 @@ # Installation ## Prebuilt official releases -These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `builder` branch for example, you'll have to build it yourself) +These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `backfill-2` branch for example, you'll have to build it yourself) Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 2a14e8df..fea28f95 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -21,6 +21,7 @@ import baritone.api.utils.SettingsUtil; import net.minecraft.client.Minecraft; import net.minecraft.init.Blocks; import net.minecraft.item.Item; +import net.minecraft.util.EnumFacing; import net.minecraft.util.text.ITextComponent; import java.awt.*; @@ -58,7 +59,9 @@ public final class Settings { /** * It doesn't actually take twenty ticks to place a block, this cost is so high - * because we want to generally conserve blocks which might be limited + * because we want to generally conserve blocks which might be limited. + *

+ * Decrease to make Baritone more often consider paths that would require placing blocks */ public final Setting blockPlacementPenalty = new Setting<>(20D); @@ -91,6 +94,11 @@ public final class Settings { */ public final Setting assumeWalkOnWater = new Setting<>(false); + /** + * If you have Fire Resistance and Jesus then I guess you could turn this on lol + */ + public final Setting assumeWalkOnLava = new Setting<>(false); + /** * Assume step functionality; don't jump on an Ascend. */ @@ -108,7 +116,7 @@ public final class Settings { /** * If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256 *

- * Defaults to false because this fails on constantiam + * Defaults to false because this fails on constantiam. Please let me know if this is ever disabled. Please. */ public final Setting allowJumpAt256 = new Setting<>(false); @@ -121,6 +129,13 @@ public final class Settings { */ public final Setting allowDiagonalDescend = new Setting<>(false); + /** + * Allow mining the block directly beneath its feet + *

+ * Turn this off to force it to make more staircases and less shafts + */ + public final Setting allowDownward = new Setting<>(true); + /** * Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.) */ @@ -429,6 +444,11 @@ public final class Settings { */ public final Setting renderGoal = new Setting<>(true); + /** + * Render selection boxes + */ + public final Setting renderSelectionBoxes = new Setting<>(true); + /** * Ignore depth when rendering the goal */ @@ -552,6 +572,21 @@ public final class Settings { */ public final Setting exploreForBlocks = new Setting<>(true); + /** + * Don't consider the next layer in builder until the current one is done + */ + public final Setting buildInLayers = new Setting<>(false); + + /** + * How far to move before repeating the build. -1 for the size of the build in that axis. 0 to disable + */ + public final Setting buildRepeatDistance=new Setting<>(0); + + /** + * What direction te repeat the build in + */ + public final Setting buildRepeatDirection = new Setting<>(EnumFacing.NORTH); + /** * While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)? */ diff --git a/src/api/java/baritone/api/pathing/goals/GoalNear.java b/src/api/java/baritone/api/pathing/goals/GoalNear.java index 6befda6b..4f75aba7 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalNear.java +++ b/src/api/java/baritone/api/pathing/goals/GoalNear.java @@ -61,6 +61,6 @@ public class GoalNear implements Goal, IGoalRenderPos { ", y=" + y + ", z=" + z + ", rangeSq=" + rangeSq + - '}'; + "}"; } } diff --git a/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java new file mode 100644 index 00000000..749bed62 --- /dev/null +++ b/src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java @@ -0,0 +1,76 @@ +/* + * 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.pathing.goals; + +import baritone.api.BaritoneAPI; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; + +/** + * Dig a tunnel in a certain direction, but if you have to deviate from the path, go back to where you started + */ +public class GoalStrictDirection implements Goal { + public final int x; + public final int y; + public final int z; + public final int dx; + public final int dz; + + public GoalStrictDirection(BlockPos origin, EnumFacing direction) { + x = origin.getX(); + y = origin.getY(); + z = origin.getZ(); + dx = direction.getXOffset(); + dz = direction.getZOffset(); + if (dx == 0 && dz == 0) { + throw new IllegalArgumentException(direction + ""); + } + } + + @Override + public boolean isInGoal(int x, int y, int z) { + return false; + } + + @Override + public double heuristic(int x, int y, int z) { + int distanceFromStartInDesiredDirection = (x - this.x) * dx + (z - this.z) * dz; + + int distanceFromStartInIncorrectDirection = Math.abs((x - this.x) * dz) + Math.abs((z - this.z) * dx); + + int verticalDistanceFromStart = Math.abs(y - this.y); + + // we want heuristic to decrease as desiredDirection increases + double heuristic = -distanceFromStartInDesiredDirection * 100; + + heuristic += distanceFromStartInIncorrectDirection * 1000; + heuristic += verticalDistanceFromStart * 1000; + return heuristic; + } + + @Override + public String toString() { + return "GoalStrictDirection{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + ", dx=" + dx + + ", dz=" + dz + + "}"; + } +} diff --git a/src/api/java/baritone/api/utils/ISchematic.java b/src/api/java/baritone/api/utils/ISchematic.java index 1f2cd874..821dc68c 100644 --- a/src/api/java/baritone/api/utils/ISchematic.java +++ b/src/api/java/baritone/api/utils/ISchematic.java @@ -18,6 +18,7 @@ package baritone.api.utils; import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; /** * Basic representation of a schematic. Provides the dimensions and @@ -44,6 +45,19 @@ public interface ISchematic { return x >= 0 && x < widthX() && y >= 0 && y < heightY() && z >= 0 && z < lengthZ(); } + default int size(EnumFacing.Axis axis) { + switch (axis) { + case X: + return widthX(); + case Y: + return heightY(); + case Z: + return lengthZ(); + default: + throw new UnsupportedOperationException(axis + ""); + } + } + /** * Returns the desired block state at a given (X, Y, Z) position relative to the origin (0, 0, 0). * diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 051e8793..ae97ad7b 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -19,6 +19,7 @@ package baritone.api.utils; import baritone.api.Settings; import net.minecraft.item.Item; +import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import java.awt.*; @@ -147,7 +148,9 @@ public class SettingsUtil { LONG(Long.class, Long::parseLong), ITEM_LIST(ArrayList.class, str -> Stream.of(str.split(",")).map(Item::getByNameOrId).collect(Collectors.toCollection(ArrayList::new)), list -> ((ArrayList) list).stream().map(Item.REGISTRY::getNameForObject).map(ResourceLocation::toString).collect(Collectors.joining(","))), - COLOR(Color.class, str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue()); + COLOR(Color.class, str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue()), + ENUMFACING(EnumFacing.class, EnumFacing::byName); + Class klass; diff --git a/src/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 4d226617..de131d12 100644 --- a/src/main/java/baritone/behavior/LookBehavior.java +++ b/src/main/java/baritone/behavior/LookBehavior.java @@ -72,7 +72,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior { float oldPitch = ctx.player().rotationPitch; float desiredPitch = this.target.getPitch(); ctx.player().rotationPitch = desiredPitch; - if (desiredPitch == oldPitch && Baritone.settings().freeLook.value) { + if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) { nudgeToLevel(); } this.target = null; diff --git a/src/main/java/baritone/cache/WorldScanner.java b/src/main/java/baritone/cache/WorldScanner.java index 463dd22f..d6cf69c3 100644 --- a/src/main/java/baritone/cache/WorldScanner.java +++ b/src/main/java/baritone/cache/WorldScanner.java @@ -28,15 +28,15 @@ import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.stream.IntStream; public enum WorldScanner implements IWorldScanner { INSTANCE; + private static final int[] DEFAULT_COORDINATE_ITERATION_ORDER = IntStream.range(0, 16).toArray(); + @Override public List scanChunkRadius(IPlayerContext ctx, List blocks, int max, int yLevelThreshold, int maxSearchRadius) { if (blocks.contains(null)) { @@ -53,6 +53,9 @@ public enum WorldScanner implements IWorldScanner { int playerChunkZ = ctx.playerFeet().getZ() >> 4; int playerY = ctx.playerFeet().getY(); + int playerYBlockStateContainerIndex = playerY >> 4; + int[] coordinateIterationOrder = IntStream.range(0, 16).boxed().sorted(Comparator.comparingInt(y -> Math.abs(y - playerYBlockStateContainerIndex))).mapToInt(x -> x).toArray(); + int searchRadiusSq = 0; boolean foundWithinY = false; while (true) { @@ -72,7 +75,9 @@ public enum WorldScanner implements IWorldScanner { continue; } allUnloaded = false; - scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY); + if (scanChunkInto(chunkX << 4, chunkZ << 4, chunk, blocks, res, max, yLevelThreshold, playerY, coordinateIterationOrder)) { + foundWithinY = true; + } } } if ((allUnloaded && foundChunks) @@ -100,13 +105,15 @@ public enum WorldScanner implements IWorldScanner { } ArrayList res = new ArrayList<>(); - scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY); + scanChunkInto(pos.x << 4, pos.z << 4, chunk, blocks, res, max, yLevelThreshold, playerY, DEFAULT_COORDINATE_ITERATION_ORDER); return res; } - public void scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List search, Collection result, int max, int yLevelThreshold, int playerY) { + private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List search, Collection result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) { ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); - for (int y0 = 0; y0 < 16; y0++) { + boolean foundWithinY = false; + for (int yIndex = 0; yIndex < 16; yIndex++) { + int y0 = coordinateIterationOrder[yIndex]; ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0]; if (extendedblockstorage == null) { continue; @@ -121,14 +128,23 @@ public enum WorldScanner implements IWorldScanner { IBlockState state = bsc.get(x, y, z); if (search.contains(state.getBlock())) { int yy = yReal | y; - result.add(new BlockPos(chunkX | x, yy, chunkZ | z)); - if (result.size() >= max && Math.abs(yy - playerY) < yLevelThreshold) { - return; + if (result.size() >= max) { + if (Math.abs(yy - playerY) < yLevelThreshold) { + foundWithinY = true; + } else { + if (foundWithinY) { + // have found within Y in this chunk, so don't need to consider outside Y + // TODO continue iteration to one more sorted Y coordinate block + return true; + } + } } + result.add(new BlockPos(chunkX | x, yy, chunkZ | z)); } } } } } + return foundWithinY; } } diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 6edb8953..4dda3283 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -60,6 +60,7 @@ public class CalculationContext { public final boolean allowJumpAt256; public final boolean assumeWalkOnWater; public final boolean allowDiagonalDescend; + public final boolean allowDownward; public final int maxFallHeightNoWater; public final int maxFallHeightBucket; public final double waterWalkSpeed; @@ -91,6 +92,7 @@ public class CalculationContext { this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value; this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value; this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value; + this.allowDownward = Baritone.settings().allowDownward.value; this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value; this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value; int depth = EnchantmentHelper.getDepthStriderModifier(player); diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index a7247df3..0ad03758 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -290,6 +290,9 @@ public interface MovementHelper extends ActionCosts, Helper { // if assumeWalkOnWater is off, we can only walk on water if there is water above it return isWater(up) ^ Baritone.settings().assumeWalkOnWater.value; } + if (Baritone.settings().assumeWalkOnLava.value && isLava(block) && !isFlowing(x, y, z, state, bsi)) { + return true; + } if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) { return true; } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java index b7b7eb5f..2ba10f70 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java @@ -197,9 +197,7 @@ public class MovementAscend extends Movement { if (headBonkClear()) { return state.setInput(Input.JUMP, true); } - - - // System.out.println(flatDistToNext + " " + sideDist); + if (flatDistToNext > 1.2 || sideDist > 0.2) { return state; } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDownward.java b/src/main/java/baritone/pathing/movement/movements/MovementDownward.java index 2bec8fcf..47ed9580 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDownward.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDownward.java @@ -48,6 +48,9 @@ public class MovementDownward extends Movement { } public static double cost(CalculationContext context, int x, int y, int z) { + if (!context.allowDownward) { + return COST_INF; + } if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) { return COST_INF; } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index 966dae95..012180e5 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java @@ -30,10 +30,7 @@ import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; import baritone.utils.BlockStateInterface; -import net.minecraft.block.Block; -import net.minecraft.block.BlockDoor; -import net.minecraft.block.BlockFenceGate; -import net.minecraft.block.BlockSlab; +import net.minecraft.block.*; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; @@ -151,6 +148,8 @@ public class MovementTraverse extends Movement { @Override public MovementState updateState(MovementState state) { super.updateState(state); + IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]); + IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]); if (state.getStatus() != MovementStatus.RUNNING) { // if the setting is enabled if (!Baritone.settings().walkWhileBreaking.value) { @@ -161,10 +160,10 @@ public class MovementTraverse extends Movement { return state; } // and if it's fine to walk into the blocks in front - if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, positionsToBreak[0]).getBlock())) { + if (MovementHelper.avoidWalkingInto(pb0.getBlock())) { return state; } - if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, positionsToBreak[1]).getBlock())) { + if (MovementHelper.avoidWalkingInto(pb1.getBlock())) { return state; } // and we aren't already pressed up against the block @@ -177,6 +176,10 @@ public class MovementTraverse extends Movement { // it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest), ctx.playerRotations()).getYaw(); float pitchToBreak = state.getTarget().getRotation().get().getPitch(); + if ((pb0.isFullCube() || pb0.getBlock() instanceof BlockAir && (pb1.isFullCube() || pb1.getBlock() instanceof BlockAir))) { + // in the meantime, before we're right up against the block, we can break efficiently at this angle + pitchToBreak = 26; + } state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true)); return state.setInput(Input.MOVE_FORWARD, true).setInput(Input.SPRINT, true); @@ -187,8 +190,6 @@ public class MovementTraverse extends Movement { Block fd = BlockStateInterface.get(ctx, src.down()).getBlock(); boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE; - IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]); - IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]); boolean door = pb0.getBlock() instanceof BlockDoor || pb1.getBlock() instanceof BlockDoor; if (door) { diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 9dd6fc92..4e4fc3df 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -56,15 +56,18 @@ import static baritone.api.pathing.movement.ActionCosts.COST_INF; public class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess { - public BuilderProcess(Baritone baritone) { - super(baritone); - } - private HashSet incorrectPositions; private String name; + private ISchematic realSchematic; private ISchematic schematic; private Vec3i origin; private int ticks; + private boolean paused; + private int layer; + + public BuilderProcess(Baritone baritone) { + super(baritone); + } public boolean build(String schematicFile, BlockPos origin) { File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile); @@ -76,7 +79,14 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro public void build(String name, ISchematic schematic, Vec3i origin) { this.name = name; this.schematic = schematic; + this.realSchematic = null; this.origin = origin; + this.paused = false; + this.layer = 0; + } + + public void resume() { + paused = false; } @Override @@ -154,10 +164,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } public class Placement { - final int hotbarSelection; - final BlockPos placeAgainst; - final EnumFacing side; - final Rotation rot; + private final int hotbarSelection; + private final BlockPos placeAgainst; + private final EnumFacing side; + private final Rotation rot; public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) { this.hotbarSelection = hotbarSelection; @@ -269,34 +279,72 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro double z = side.getZOffset() == 0 ? 0.5 : (1 + side.getZOffset()) / 2D; return new Vec3d[]{new Vec3d(x, 0.25, z), new Vec3d(x, 0.75, z)}; default: // null - throw new NullPointerException(); + throw new IllegalStateException(); } } @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - // TODO somehow tell inventorybehavior what we'd like to have on the hotbar - // perhaps take the 16 closest positions in incorrectPositions to ctx.playerFeet that aren't desired to be air, and then snag the top 4 most common block states, then request those on the hotbar - - - // this will work as is, but it'll be trashy - // need to iterate over incorrectPositions and see which ones we can "correct" from our current standing position - - baritone.getInputOverrideHandler().clearAllKeys(); - BuilderCalculationContext bcc = new BuilderCalculationContext(); - if (!recalc(bcc)) { - logDirect("Done building"); - onLostControl(); - return null; - } - trim(bcc); if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) { ticks = 5; } else { ticks--; } - Optional> toBreak = toBreakNearPlayer(bcc); baritone.getInputOverrideHandler().clearAllKeys(); + if (paused) { + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } + if (Baritone.settings().buildInLayers.value) { + if (realSchematic == null) { + realSchematic = schematic; + } + schematic = new ISchematic() { + @Override + public IBlockState desiredState(int x, int y, int z) { + return realSchematic.desiredState(x, y, z); + } + + @Override + public int widthX() { + return realSchematic.widthX(); + } + + @Override + public int heightY() { + return layer; + } + + @Override + public int lengthZ() { + return realSchematic.lengthZ(); + } + }; + } + BuilderCalculationContext bcc = new BuilderCalculationContext(); + if (!recalc(bcc)) { + if (Baritone.settings().buildInLayers.value && layer < realSchematic.heightY()) { + logDirect("Starting layer " + layer); + layer++; + return onTick(calcFailed, isSafeToCancel); + } + int distance = Baritone.settings().buildRepeatDistance.value; + EnumFacing direction = Baritone.settings().buildRepeatDirection.value; + if (distance == 0) { + logDirect("Done building"); + onLostControl(); + return null; + } + // build repeat time + if (distance == -1) { + distance = schematic.size(direction.getAxis()); + } + layer = 0; + origin = new BlockPos(origin).offset(direction, distance); + logDirect("Repeating build " + distance + " blocks to the " + direction + ", new origin is " + origin); + } + trim(bcc); + + Optional> toBreak = toBreakNearPlayer(bcc); if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) { // we'd like to pause to break this block // only change look direction if it's safe (don't want to fuck up an in progress parkour for example @@ -359,9 +407,9 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro if (goal == null) { goal = assemble(bcc, approxPlacable); // we're far away, so assume that we have our whole inventory to recalculate placable properly if (goal == null) { - logDirect("Unable to do it =("); - onLostControl(); - return null; + logDirect("Unable to do it. Pausing. resume to resume, cancel to cancel"); + paused = true; + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } } return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc); @@ -417,10 +465,8 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro for (int y = 0; y < schematic.heightY(); y++) { for (int z = 0; z < schematic.lengthZ(); z++) { for (int x = 0; x < schematic.widthX(); x++) { - if (schematic.inSchematic(x, y, z)) { - if (!valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(x, y, z))) { - incorrectPositions.add(new BetterBlockPos(x + origin.getX(), y + origin.getY(), z + origin.getZ())); - } + if (schematic.inSchematic(x, y, z) && !valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(x, y, z))) { + incorrectPositions.add(new BetterBlockPos(x + origin.getX(), y + origin.getY(), z + origin.getZ())); } } } @@ -498,7 +544,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro } public static class GoalAdjacent extends GoalGetToBlock { - boolean allowSameLevel; + private boolean allowSameLevel; public GoalAdjacent(BlockPos pos, boolean allowSameLevel) { super(pos); @@ -540,11 +586,14 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro incorrectPositions = null; name = null; schematic = null; + realSchematic = null; + layer = 0; + paused = false; } @Override public String displayName0() { - return "Building " + name; + return paused ? "Builder Paused" : "Building " + name; } public List placable(int size) { diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index f2ebcd55..07e47b91 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -81,13 +81,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return null; } } + boolean shouldCancel = calcFailed; if (calcFailed && !knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) { logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance..."); - knownOreLocations.stream().sorted(Comparator.comparingDouble(ctx.player()::getDistanceSq)).findFirst().ifPresent(blacklist::add); + knownOreLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(blacklist::add); knownOreLocations.removeIf(blacklist::contains); - calcFailed = false; // 😎 + shouldCancel = false; // 😎 } - if (calcFailed) { + if (shouldCancel) { logDirect("Unable to find any path to " + mining + ", canceling Mine"); cancel(); return null; diff --git a/src/main/java/baritone/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java index 6dbdf388..7b422ef2 100644 --- a/src/main/java/baritone/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java @@ -353,6 +353,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper { baritone.getBuilderProcess().clearArea(corner1, corner2); return true; } + if (msg.equals("resume")) { + baritone.getBuilderProcess().resume(); + logDirect("resumed"); + return true; + } if (msg.equals("reset")) { for (Settings.Setting setting : Baritone.settings().allSettings) { setting.reset(); @@ -361,6 +366,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper { logDirect("Baritone settings reset"); return true; } + if (msg.equals("tunnel")) { + customGoalProcess.setGoalAndPath(new GoalStrictDirection(ctx.playerFeet(), ctx.player().getHorizontalFacing())); + logDirect("tunneling"); + return true; + } if (msg.equals("render")) { BetterBlockPos pf = ctx.playerFeet(); Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500); diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 0c9a45f3..e4fd58b1 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -83,17 +83,22 @@ public final class PathRenderer implements Helper { if (goal != null && Baritone.settings().renderGoal.value) { drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.value); } + if (!Baritone.settings().renderPath.value) { return; } + PathExecutor current = behavior.getCurrent(); // this should prevent most race conditions? + PathExecutor next = behavior.getNext(); // like, now it's not possible for current!=null to be true, then suddenly false because of another thread + if (current != null && Baritone.settings().renderSelectionBoxes.value) { + drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.value); + drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.value); + drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.value); + } //drawManySelectionBoxes(player, Collections.singletonList(behavior.pathStart()), partialTicks, Color.WHITE); //long start = System.nanoTime(); - PathExecutor current = behavior.getCurrent(); // this should prevent most race conditions? - PathExecutor next = behavior.getNext(); // like, now it's not possible for current!=null to be true, then suddenly false because of another thread - // Render the current path, if there is one if (current != null && current.getPath() != null) { int renderBegin = Math.max(current.getPosition() - 3, 0); @@ -104,11 +109,6 @@ public final class PathRenderer implements Helper { } //long split = System.nanoTime(); - if (current != null) { - drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.value); - drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.value); - drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.value); - } // If there is a path calculation currently running, render the path calculation process behavior.getInProgress().ifPresent(currentlyRunning -> {