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 @@



-
[](https://minecraft.gamepedia.com/1.12.2)
[](https://github.com/cabaletta/baritone/graphs/contributors/)
[](https://github.com/cabaletta/baritone/commit/)
-[](https://impactdevelopment.github.io/)
+[](https://impactdevelopment.github.io/)
[](https://wweclient.com/)
[](https://github.com/zeroeightysix/KAMI/)
[](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 -> {