From ce59ef559fccfb2ceb925b539f88ea479038c950 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 9 Apr 2019 19:35:43 -0700 Subject: [PATCH 1/6] backport important world scanner fixes --- .../java/baritone/cache/WorldScanner.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/main/java/baritone/cache/WorldScanner.java b/src/main/java/baritone/cache/WorldScanner.java index 463dd22f7..91cc0f54e 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,22 @@ 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 + return true; + } + } } + result.add(new BlockPos(chunkX | x, yy, chunkZ | z)); } } } } } + return foundWithinY; } } From 76cdaaace614a9bd799aba42eeccd69dd5790844 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Wed, 10 Apr 2019 23:45:52 -0700 Subject: [PATCH 2/6] add todo --- src/main/java/baritone/cache/WorldScanner.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/cache/WorldScanner.java b/src/main/java/baritone/cache/WorldScanner.java index 91cc0f54e..d6cf69c3b 100644 --- a/src/main/java/baritone/cache/WorldScanner.java +++ b/src/main/java/baritone/cache/WorldScanner.java @@ -134,6 +134,7 @@ public enum WorldScanner implements IWorldScanner { } 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; } } From 2bf475d84005f23823e68df2c174fa3b304d2c2a Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 11 Apr 2019 15:17:26 -0700 Subject: [PATCH 3/6] build in layers test --- src/api/java/baritone/api/Settings.java | 5 +++ .../java/baritone/process/BuilderProcess.java | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 9793cf6bd..3a1c9fba6 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -566,6 +566,11 @@ 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); + /** * 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/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 56115b49a..6c38b7ff7 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -58,10 +58,12 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro 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); @@ -77,8 +79,10 @@ 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() { @@ -285,8 +289,39 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro 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); + } logDirect("Done building"); onLostControl(); return null; @@ -540,6 +575,8 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro incorrectPositions = null; name = null; schematic = null; + realSchematic = null; + layer = 0; paused = false; } From a09bb0d53865a17e5869b0eba14015e4ddc5e34a Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 11 Apr 2019 16:36:20 -0700 Subject: [PATCH 4/6] build repeat option --- src/api/java/baritone/api/Settings.java | 11 +++++++ .../java/baritone/api/utils/ISchematic.java | 14 +++++++++ .../java/baritone/process/BuilderProcess.java | 29 +++++++++++++------ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 3a1c9fba6..b61656a96 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.*; @@ -571,6 +572,16 @@ public final class Settings { */ 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/utils/ISchematic.java b/src/api/java/baritone/api/utils/ISchematic.java index 1f2cd8742..821dc68c3 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/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 6c38b7ff7..4e4fc3dfe 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -285,6 +285,11 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) { + ticks = 5; + } else { + ticks--; + } baritone.getInputOverrideHandler().clearAllKeys(); if (paused) { return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); @@ -322,18 +327,24 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro layer++; return onTick(calcFailed, isSafeToCancel); } - logDirect("Done building"); - onLostControl(); - return null; + 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); - if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) { - ticks = 5; - } else { - ticks--; - } + Optional> toBreak = toBreakNearPlayer(bcc); - baritone.getInputOverrideHandler().clearAllKeys(); 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 From 65cd6a92d316dad4ce8346c69d69dd1438b1ed41 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 11 Apr 2019 16:42:04 -0700 Subject: [PATCH 5/6] allow saving enumfacing value --- src/api/java/baritone/api/utils/SettingsUtil.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 051e87934..ae97ad7b8 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; From fcadf68c900ba867ac71b410f6675ec40b4d9dcf Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 12 Apr 2019 17:42:50 -0700 Subject: [PATCH 6/6] cool tunnel feature and various fixes --- .../baritone/api/pathing/goals/GoalNear.java | 2 +- .../pathing/goals/GoalStrictDirection.java | 76 +++++++++++++++++++ .../java/baritone/behavior/LookBehavior.java | 2 +- .../movement/movements/MovementTraverse.java | 17 +++-- .../utils/ExampleBaritoneControl.java | 5 ++ 5 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 src/api/java/baritone/api/pathing/goals/GoalStrictDirection.java diff --git a/src/api/java/baritone/api/pathing/goals/GoalNear.java b/src/api/java/baritone/api/pathing/goals/GoalNear.java index 6befda6bc..4f75aba72 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 000000000..749bed626 --- /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/main/java/baritone/behavior/LookBehavior.java b/src/main/java/baritone/behavior/LookBehavior.java index 4d2266179..de131d12b 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/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index 966dae951..012180e5e 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/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java index 9b8dd4880..7b422ef25 100644 --- a/src/main/java/baritone/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java @@ -366,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);