diff --git a/README.md b/README.md
index 90173889d..043aed085 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@

[](https://github.com/cabaletta/baritone/graphs/contributors/)
[](https://github.com/cabaletta/baritone/commit/)
-[](https://impactclient.net/)
+[](https://impactclient.net/)
[](https://github.com/fr1kin/ForgeHax/)
[](https://gitlab.com/emc-mods-indrit/baritone_api)
[](https://wweclient.com/)
diff --git a/USAGE.md b/USAGE.md
index 118104993..0f911efaa 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -16,7 +16,7 @@ Try `#help` I promise it won't just send you back here =)
"wtf where is cleararea" -> look at `#help sel`
-"wtf where is goto death, goto waypoint" -> look at `#help wp`
+"wtf where is goto death, goto waypoint" -> look at `#help wp` (a "tag" is like "home" (created automatically on right clicking a bed) or "death" (created automatically on death) or "user" (has to be created manually)). So you might want `#wp save user coolbiome` then, to set the goal `#wp goal coolbiome` then `#path` to path to it. For death, `#wp goal death` (remember stuff is clickable!).
just look at `#help` lmao
diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java
index dac5f23f6..a30cf4c5e 100644
--- a/src/api/java/baritone/api/Settings.java
+++ b/src/api/java/baritone/api/Settings.java
@@ -183,6 +183,20 @@ public final class Settings {
Blocks.WALL_SIGN
)));
+ /**
+ * A list of blocks to be treated as if they're air.
+ *
+ * If a schematic asks for air at a certain position, and that position currently contains a block on this list, it will be treated as correct.
+ */
+ public final Setting> buildIgnoreBlocks = new Setting<>(new ArrayList<>(Arrays.asList(
+
+ )));
+
+ /**
+ * If this is true, the builder will treat all non-air blocks as correct. It will only place new blocks.
+ */
+ public final Setting buildIgnoreExisting = new Setting<>(false);
+
/**
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
*
@@ -233,7 +247,7 @@ public final class Settings {
/**
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
*
- * This helps with speed at >=20m/s
+ * This helps with speed exceeding 20m/s
*/
public final Setting overshootTraverse = new Setting<>(true);
@@ -252,6 +266,11 @@ public final class Settings {
*/
public final Setting randomLooking113 = new Setting<>(2d);
+ /**
+ * Block reach distance
+ */
+ public final Setting blockReachDistance = new Setting<>(4.5f);
+
/**
* How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable
*/
@@ -742,6 +761,11 @@ public final class Settings {
*/
public final Setting buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
+ /**
+ * How many times to buildrepeat. -1 for infinite.
+ */
+ public final Setting buildRepeatCount = new Setting<>(-1);
+
/**
* Allow standing above a block while mining it, in BuilderProcess
*
diff --git a/src/api/java/baritone/api/command/datatypes/RelativeGoal.java b/src/api/java/baritone/api/command/datatypes/RelativeGoal.java
index cda0ad665..19312907e 100644
--- a/src/api/java/baritone/api/command/datatypes/RelativeGoal.java
+++ b/src/api/java/baritone/api/command/datatypes/RelativeGoal.java
@@ -38,38 +38,26 @@ public enum RelativeGoal implements IDatatypePost {
if (origin == null) {
origin = BetterBlockPos.ORIGIN;
}
+
final IArgConsumer consumer = ctx.getConsumer();
- List> coords = new ArrayList<>();
- final IArgConsumer copy = consumer.copy(); // This is a hack and should be fixed in the future probably
- for (int i = 0; i < 3; i++) {
- if (copy.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) {
- coords.add(o -> consumer.getDatatypePost(RelativeCoordinate.INSTANCE, o));
- copy.get(); // Consume so we actually decrement the remaining arguments
- }
+ GoalBlock goalBlock = consumer.peekDatatypePostOrNull(RelativeGoalBlock.INSTANCE, origin);
+ if (goalBlock != null) {
+ return goalBlock;
}
- switch (coords.size()) {
- case 0:
- return new GoalBlock(origin);
- case 1:
- return new GoalYLevel(
- MathHelper.floor(coords.get(0).apply((double) origin.y))
- );
- case 2:
- return new GoalXZ(
- MathHelper.floor(coords.get(0).apply((double) origin.x)),
- MathHelper.floor(coords.get(1).apply((double) origin.z))
- );
- case 3:
- return new GoalBlock(
- MathHelper.floor(coords.get(0).apply((double) origin.x)),
- MathHelper.floor(coords.get(1).apply((double) origin.y)),
- MathHelper.floor(coords.get(2).apply((double) origin.z))
- );
- default:
- throw new IllegalStateException("Unexpected coords size: " + coords.size());
+ GoalXZ goalXZ = consumer.peekDatatypePostOrNull(RelativeGoalXZ.INSTANCE, origin);
+ if (goalXZ != null) {
+ return goalXZ;
}
+
+ GoalYLevel goalYLevel = consumer.peekDatatypePostOrNull(RelativeGoalYLevel.INSTANCE, origin);
+ if (goalYLevel != null) {
+ return goalYLevel;
+ }
+
+ // when the user doesn't input anything, default to the origin
+ return new GoalBlock(origin);
}
@Override
diff --git a/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java b/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java
index 4a21bede7..b31615163 100644
--- a/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java
+++ b/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java
@@ -22,4 +22,8 @@ public abstract class CommandErrorMessageException extends CommandException {
protected CommandErrorMessageException(String reason) {
super(reason);
}
+
+ protected CommandErrorMessageException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
}
diff --git a/src/api/java/baritone/api/command/exception/CommandException.java b/src/api/java/baritone/api/command/exception/CommandException.java
index b8962c159..53b8e6023 100644
--- a/src/api/java/baritone/api/command/exception/CommandException.java
+++ b/src/api/java/baritone/api/command/exception/CommandException.java
@@ -22,4 +22,8 @@ public abstract class CommandException extends Exception implements ICommandExce
protected CommandException(String reason) {
super(reason);
}
+
+ protected CommandException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
}
diff --git a/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java b/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java
index 1902d7355..6997d6d69 100644
--- a/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java
+++ b/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java
@@ -23,12 +23,21 @@ public abstract class CommandInvalidArgumentException extends CommandErrorMessag
public final ICommandArgument arg;
- protected CommandInvalidArgumentException(ICommandArgument arg, String reason) {
- super(String.format(
- "Error at argument #%s: %s",
- arg.getIndex() == -1 ? "" : Integer.toString(arg.getIndex() + 1),
- reason
- ));
+ protected CommandInvalidArgumentException(ICommandArgument arg, String message) {
+ super(formatMessage(arg, message));
this.arg = arg;
}
+
+ protected CommandInvalidArgumentException(ICommandArgument arg, String message, Throwable cause) {
+ super(formatMessage(arg, message), cause);
+ this.arg = arg;
+ }
+
+ private static String formatMessage(ICommandArgument arg, String message) {
+ return String.format(
+ "Error at argument #%s: %s",
+ arg.getIndex() == -1 ? "" : Integer.toString(arg.getIndex() + 1),
+ message
+ );
+ }
}
diff --git a/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java b/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java
index 516fd308f..06658c3a0 100644
--- a/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java
+++ b/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java
@@ -26,7 +26,7 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
}
public CommandInvalidTypeException(ICommandArgument arg, String expected, Throwable cause) {
- super(arg, String.format("Expected %s.\nMore details: %s", expected, cause.getMessage()));
+ super(arg, String.format("Expected %s", expected), cause);
}
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got) {
@@ -34,6 +34,6 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException
}
public CommandInvalidTypeException(ICommandArgument arg, String expected, String got, Throwable cause) {
- super(arg, String.format("Expected %s, but got %s instead.\nMore details: %s", expected, got, cause.getMessage()));
+ super(arg, String.format("Expected %s, but got %s instead", expected, got), cause);
}
}
diff --git a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java
index fe0b09fad..02987d4ee 100644
--- a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java
+++ b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java
@@ -37,7 +37,7 @@ public class CommandUnhandledException extends RuntimeException implements IComm
@Override
public void handle(ICommand command, List args) {
- HELPER.logDirect("An unhandled exception occurred." +
+ HELPER.logDirect("An unhandled exception occurred. " +
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
TextFormatting.RED);
diff --git a/src/api/java/baritone/api/event/events/TickEvent.java b/src/api/java/baritone/api/event/events/TickEvent.java
index da8f8878a..5c484ae49 100644
--- a/src/api/java/baritone/api/event/events/TickEvent.java
+++ b/src/api/java/baritone/api/event/events/TickEvent.java
@@ -19,22 +19,20 @@ package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
+import java.util.function.BiFunction;
+
public final class TickEvent {
+ private static int overallTickCount;
+
private final EventState state;
private final Type type;
private final int count;
- private static int overallTickCount;
-
- public TickEvent(EventState state, Type type) {
+ public TickEvent(EventState state, Type type, int count) {
this.state = state;
this.type = type;
- this.count = incrementCount();
- }
-
- private static synchronized int incrementCount() {
- return overallTickCount++;
+ this.count = count;
}
public int getCount() {
@@ -49,6 +47,10 @@ public final class TickEvent {
return state;
}
+ public static synchronized BiFunction createNextProvider() {
+ final int count = overallTickCount++;
+ return (state, type) -> new TickEvent(state, type, count);
+ }
public enum Type {
/**
diff --git a/src/api/java/baritone/api/utils/IPlayerController.java b/src/api/java/baritone/api/utils/IPlayerController.java
index 05199fcac..d6fa1837a 100644
--- a/src/api/java/baritone/api/utils/IPlayerController.java
+++ b/src/api/java/baritone/api/utils/IPlayerController.java
@@ -17,6 +17,7 @@
package baritone.api.utils;
+import baritone.api.BaritoneAPI;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ClickType;
@@ -56,6 +57,6 @@ public interface IPlayerController {
void setHittingBlock(boolean hittingBlock);
default double getBlockReachDistance() {
- return this.getGameType().isCreative() ? 5.0F : 4.5F;
+ return this.getGameType().isCreative() ? 5.0F : BaritoneAPI.getSettings().blockReachDistance.value;
}
}
diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java
index 453538502..f2b58596e 100644
--- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java
+++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java
@@ -41,6 +41,8 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
+import java.util.function.BiFunction;
+
/**
* @author Brady
* @since 7/31/2018
@@ -84,13 +86,15 @@ public class MixinMinecraft {
)
)
private void runTick(CallbackInfo ci) {
- for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
+ final BiFunction tickProvider = TickEvent.createNextProvider();
- TickEvent.Type type = ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().world() != null
+ for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
+
+ TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
? TickEvent.Type.IN
: TickEvent.Type.OUT;
- ibaritone.getGameEventHandler().onTick(new TickEvent(EventState.PRE, type));
+ baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type));
}
}
diff --git a/src/main/java/baritone/command/argument/ArgConsumer.java b/src/main/java/baritone/command/argument/ArgConsumer.java
index 651ca50bc..f4e7dd524 100644
--- a/src/main/java/baritone/command/argument/ArgConsumer.java
+++ b/src/main/java/baritone/command/argument/ArgConsumer.java
@@ -316,8 +316,7 @@ public class ArgConsumer implements IArgConsumer {
try {
return datatype.apply(this.context, original);
} catch (Exception e) {
- e.printStackTrace();
- throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName());
+ throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e);
}
}
@@ -346,7 +345,7 @@ public class ArgConsumer implements IArgConsumer {
try {
return datatype.get(this.context);
} catch (Exception e) {
- throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName());
+ throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e);
}
}
diff --git a/src/main/java/baritone/command/defaults/CancelCommand.java b/src/main/java/baritone/command/defaults/CancelCommand.java
deleted file mode 100644
index 3b4c63670..000000000
--- a/src/main/java/baritone/command/defaults/CancelCommand.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.command.defaults;
-
-import baritone.api.IBaritone;
-import baritone.api.command.Command;
-import baritone.api.command.exception.CommandException;
-import baritone.api.command.argument.IArgConsumer;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Stream;
-
-public class CancelCommand extends Command {
-
- public CancelCommand(IBaritone baritone) {
- super(baritone, "cancel", "stop");
- }
-
- @Override
- public void execute(String label, IArgConsumer args) throws CommandException {
- args.requireMax(0);
- baritone.getPathingBehavior().cancelEverything();
- logDirect("ok canceled");
- }
-
- @Override
- public Stream tabComplete(String label, IArgConsumer args) {
- return Stream.empty();
- }
-
- @Override
- public String getShortDesc() {
- return "Cancel what Baritone is currently doing";
- }
-
- @Override
- public List getLongDesc() {
- return Arrays.asList(
- "The cancel command tells Baritone to stop whatever it's currently doing.",
- "",
- "Usage:",
- "> cancel"
- );
- }
-}
diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java
index c48644e3b..67555ed51 100644
--- a/src/main/java/baritone/command/defaults/DefaultCommands.java
+++ b/src/main/java/baritone/command/defaults/DefaultCommands.java
@@ -24,52 +24,53 @@ import java.util.*;
public final class DefaultCommands {
- private DefaultCommands() {}
+ private DefaultCommands() {
+ }
public static List createAll(IBaritone baritone) {
Objects.requireNonNull(baritone);
List commands = new ArrayList<>(Arrays.asList(
- new HelpCommand(baritone),
- new SetCommand(baritone),
- new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"),
- new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"),
- new GoalCommand(baritone),
- new GotoCommand(baritone),
- new PathCommand(baritone),
- new ProcCommand(baritone),
- new VersionCommand(baritone),
- new RepackCommand(baritone),
- new BuildCommand(baritone),
- new SchematicaCommand(baritone),
- new ComeCommand(baritone),
- new AxisCommand(baritone),
- new CancelCommand(baritone),
- new ForceCancelCommand(baritone),
- new GcCommand(baritone),
- new InvertCommand(baritone),
- new TunnelCommand(baritone),
- new RenderCommand(baritone),
- new FarmCommand(baritone),
- new ChestsCommand(baritone),
- new FollowCommand(baritone),
- new ExploreFilterCommand(baritone),
- new ReloadAllCommand(baritone),
- new SaveAllCommand(baritone),
- new ExploreCommand(baritone),
- new BlacklistCommand(baritone),
- new FindCommand(baritone),
- new MineCommand(baritone),
- new ClickCommand(baritone),
- new ThisWayCommand(baritone),
- new WaypointsCommand(baritone),
- new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"),
- new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"),
- new SelCommand(baritone)
+ new HelpCommand(baritone),
+ new SetCommand(baritone),
+ new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"),
+ new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"),
+ new GoalCommand(baritone),
+ new GotoCommand(baritone),
+ new PathCommand(baritone),
+ new ProcCommand(baritone),
+ new VersionCommand(baritone),
+ new RepackCommand(baritone),
+ new BuildCommand(baritone),
+ new SchematicaCommand(baritone),
+ new ComeCommand(baritone),
+ new AxisCommand(baritone),
+ new ForceCancelCommand(baritone),
+ new GcCommand(baritone),
+ new InvertCommand(baritone),
+ new TunnelCommand(baritone),
+ new RenderCommand(baritone),
+ new FarmCommand(baritone),
+ new ChestsCommand(baritone),
+ new FollowCommand(baritone),
+ new ExploreFilterCommand(baritone),
+ new ReloadAllCommand(baritone),
+ new SaveAllCommand(baritone),
+ new ExploreCommand(baritone),
+ new BlacklistCommand(baritone),
+ new FindCommand(baritone),
+ new MineCommand(baritone),
+ new ClickCommand(baritone),
+ new ThisWayCommand(baritone),
+ new WaypointsCommand(baritone),
+ new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"),
+ new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"),
+ new SelCommand(baritone)
));
- PauseResumeCommands prc = new PauseResumeCommands(baritone);
+ ExecutionControlCommands prc = new ExecutionControlCommands(baritone);
commands.add(prc.pauseCommand);
commands.add(prc.resumeCommand);
commands.add(prc.pausedCommand);
+ commands.add(prc.cancelCommand);
return Collections.unmodifiableList(commands);
}
}
diff --git a/src/main/java/baritone/command/defaults/PauseResumeCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java
similarity index 82%
rename from src/main/java/baritone/command/defaults/PauseResumeCommands.java
rename to src/main/java/baritone/command/defaults/ExecutionControlCommands.java
index 54718e9b7..4a04b9e09 100644
--- a/src/main/java/baritone/command/defaults/PauseResumeCommands.java
+++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java
@@ -18,13 +18,13 @@
package baritone.command.defaults;
import baritone.api.IBaritone;
+import baritone.api.command.Command;
+import baritone.api.command.argument.IArgConsumer;
+import baritone.api.command.exception.CommandException;
+import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
-import baritone.api.command.Command;
-import baritone.api.command.exception.CommandException;
-import baritone.api.command.exception.CommandInvalidStateException;
-import baritone.api.command.argument.IArgConsumer;
import java.util.Arrays;
import java.util.List;
@@ -37,13 +37,14 @@ import java.util.stream.Stream;
* TO USE THIS to pause and resume Baritone. Make your own process that returns {@link PathingCommandType#REQUEST_PAUSE
* REQUEST_PAUSE} as needed.
*/
-public class PauseResumeCommands {
+public class ExecutionControlCommands {
Command pauseCommand;
Command resumeCommand;
Command pausedCommand;
+ Command cancelCommand;
- public PauseResumeCommands(IBaritone baritone) {
+ public ExecutionControlCommands(IBaritone baritone) {
// array for mutability, non-field so reflection can't touch it
final boolean[] paused = {false};
baritone.getPathingControlManager().registerProcess(
@@ -64,7 +65,8 @@ public class PauseResumeCommands {
}
@Override
- public void onLostControl() {}
+ public void onLostControl() {
+ }
@Override
public double priority() {
@@ -169,5 +171,36 @@ public class PauseResumeCommands {
);
}
};
+ cancelCommand = new Command(baritone, "cancel", "stop") {
+ @Override
+ public void execute(String label, IArgConsumer args) throws CommandException {
+ args.requireMax(0);
+ if (paused[0]) {
+ paused[0] = false;
+ }
+ baritone.getPathingBehavior().cancelEverything();
+ logDirect("ok canceled");
+ }
+
+ @Override
+ public Stream tabComplete(String label, IArgConsumer args) {
+ return Stream.empty();
+ }
+
+ @Override
+ public String getShortDesc() {
+ return "Cancel what Baritone is currently doing";
+ }
+
+ @Override
+ public List getLongDesc() {
+ return Arrays.asList(
+ "The cancel command tells Baritone to stop whatever it's currently doing.",
+ "",
+ "Usage:",
+ "> cancel"
+ );
+ }
+ };
}
}
diff --git a/src/main/java/baritone/command/defaults/GotoCommand.java b/src/main/java/baritone/command/defaults/GotoCommand.java
index 427e67b2a..28e768296 100644
--- a/src/main/java/baritone/command/defaults/GotoCommand.java
+++ b/src/main/java/baritone/command/defaults/GotoCommand.java
@@ -41,9 +41,13 @@ public class GotoCommand extends Command {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
- if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) { // if we have a numeric first argument...
+ // If we have a numeric first argument, then parse arguments as coordinates.
+ // Note: There is no reason to want to go where you're already at so there
+ // is no need to handle the case of empty arguments.
+ if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) {
+ args.requireMax(3);
BetterBlockPos origin = baritone.getPlayerContext().playerFeet();
- Goal goal = args.getDatatypePostOrNull(RelativeGoal.INSTANCE, origin);
+ Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin);
logDirect(String.format("Going to: %s", goal.toString()));
baritone.getCustomGoalProcess().setGoalAndPath(goal);
return;
diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java
index dc3128bcf..5462dd512 100644
--- a/src/main/java/baritone/pathing/movement/MovementHelper.java
+++ b/src/main/java/baritone/pathing/movement/MovementHelper.java
@@ -42,6 +42,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
+import net.minecraft.world.IBlockReader;
import java.util.Optional;
@@ -143,7 +144,7 @@ public interface MovementHelper extends ActionCosts, Helper {
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
// has already been accounted for above
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
- return state.allowsMovement(null, BlockPos.ORIGIN, PathType.LAND); // workaround for future compatibility =P
+ return state.allowsMovement(bsi.access, BlockPos.ORIGIN, PathType.LAND); // workaround for future compatibility =P
}
/**
@@ -157,10 +158,18 @@ public interface MovementHelper extends ActionCosts, Helper {
* @return Whether or not the block at the specified position
*/
static boolean fullyPassable(CalculationContext context, int x, int y, int z) {
- return fullyPassable(context.get(x, y, z));
+ return fullyPassable(
+ context.bsi.access,
+ context.bsi.isPassableBlockPos.setPos(x, y, z),
+ context.bsi.get0(x, y, z)
+ );
}
- static boolean fullyPassable(IBlockState state) {
+ static boolean fullyPassable(IPlayerContext ctx, BlockPos pos) {
+ return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos));
+ }
+
+ static boolean fullyPassable(IBlockReader access, BlockPos pos, IBlockState state) {
Block block = state.getBlock();
if (block instanceof BlockAir) { // early return for most common case
return true;
@@ -183,7 +192,7 @@ public interface MovementHelper extends ActionCosts, Helper {
return false;
}
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
- return state.allowsMovement(null, null, PathType.LAND);
+ return state.allowsMovement(access, pos, PathType.LAND);
}
static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
index adaacbf18..a52d48bb9 100644
--- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
+++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java
@@ -115,7 +115,7 @@ public class MovementParkour extends Movement {
return;
}
IBlockState destInto = context.bsi.get0(destX, y, destZ);
- if (!MovementHelper.fullyPassable(destInto)) {
+ if (!MovementHelper.fullyPassable(context.bsi.access, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) {
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
res.x = destX;
res.y = y + 1;
diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java
index 0edca7e2f..46fa6127f 100644
--- a/src/main/java/baritone/pathing/path/PathExecutor.java
+++ b/src/main/java/baritone/pathing/path/PathExecutor.java
@@ -465,7 +465,7 @@ public class PathExecutor implements IPathExecutor, Helper {
}
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z);
- if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
+ if (!MovementHelper.fullyPassable(ctx, chk)) {
break outer;
}
}
@@ -490,7 +490,7 @@ public class PathExecutor implements IPathExecutor, Helper {
}
// we are centered
BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2);
- if (MovementHelper.fullyPassable(ctx.world().getBlockState(headBonk))) {
+ if (MovementHelper.fullyPassable(ctx, headBonk)) {
return true;
}
// wait 0.3
@@ -523,7 +523,7 @@ public class PathExecutor implements IPathExecutor, Helper {
if (x == 1) {
chk = chk.add(current.getDirection());
}
- if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
+ if (!MovementHelper.fullyPassable(ctx, chk)) {
return false;
}
}
diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java
index e07b5e165..a79ce39e0 100644
--- a/src/main/java/baritone/process/BuilderProcess.java
+++ b/src/main/java/baritone/process/BuilderProcess.java
@@ -26,7 +26,10 @@ import baritone.api.process.IBuilderProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
import baritone.api.schematic.ISchematic;
-import baritone.api.utils.*;
+import baritone.api.utils.BetterBlockPos;
+import baritone.api.utils.RayTraceUtils;
+import baritone.api.utils.Rotation;
+import baritone.api.utils.RotationUtils;
import baritone.api.utils.input.Input;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
@@ -72,6 +75,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
private int ticks;
private boolean paused;
private int layer;
+ private int numRepeats;
private List approxPlaceable;
public BuilderProcess(Baritone baritone) {
@@ -98,6 +102,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
this.origin = new Vec3i(x, y, z);
this.paused = false;
this.layer = 0;
+ this.numRepeats = 0;
this.observedCompleted = new LongOpenHashSet();
}
@@ -408,7 +413,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return onTick(calcFailed, isSafeToCancel);
}
Vec3i repeat = Baritone.settings().buildRepeat.value;
- if (repeat.equals(new Vec3i(0, 0, 0))) {
+ int max = Baritone.settings().buildRepeatCount.value;
+ numRepeats++;
+ if (repeat.equals(new Vec3i(0, 0, 0)) || (max != -1 && numRepeats >= max)) {
logDirect("Done building");
onLostControl();
return null;
@@ -748,6 +755,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
schematic = null;
realSchematic = null;
layer = 0;
+ numRepeats = 0;
paused = false;
observedCompleted = null;
}
@@ -783,6 +791,12 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return true;
}
// TODO more complicated comparison logic I guess
+ if (desired.getBlock() instanceof BlockAir && Baritone.settings().buildIgnoreBlocks.value.contains(current.getBlock())) {
+ return true;
+ }
+ if (!(current.getBlock() instanceof BlockAir) && Baritone.settings().buildIgnoreExisting.value) {
+ return true;
+ }
return current.equals(desired);
}
diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java
index ebb16809d..612cb8363 100644
--- a/src/main/java/baritone/utils/BlockStateInterface.java
+++ b/src/main/java/baritone/utils/BlockStateInterface.java
@@ -30,6 +30,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
+import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@@ -42,6 +43,9 @@ public class BlockStateInterface {
private final Long2ObjectMap loadedChunks;
private final WorldData worldData;
+ protected final IBlockReader world;
+ public final BlockPos.MutableBlockPos isPassableBlockPos;
+ public final IBlockReader access;
private Chunk prev = null;
private CachedRegion prevCached = null;
@@ -59,6 +63,7 @@ public class BlockStateInterface {
}
public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) {
+ this.world = world;
this.worldData = worldData;
Long2ObjectMap worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks();
if (copyLoadedChunks) {
@@ -70,6 +75,8 @@ public class BlockStateInterface {
if (!Minecraft.getInstance().isCallingFromMinecraftThread()) {
throw new IllegalStateException();
}
+ this.isPassableBlockPos = new BlockPos.MutableBlockPos();
+ this.access = new BlockStateInterfaceAccessWrapper(this);
}
public boolean worldContainsLoadedChunk(int blockX, int blockZ) {
diff --git a/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java
new file mode 100644
index 000000000..915878c60
--- /dev/null
+++ b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java
@@ -0,0 +1,57 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.utils;
+
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.fluid.IFluidState;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+
+import javax.annotation.Nullable;
+
+/**
+ * @author Brady
+ * @since 11/5/2019
+ */
+@SuppressWarnings("NullableProblems")
+public final class BlockStateInterfaceAccessWrapper implements IBlockReader {
+
+ private final BlockStateInterface bsi;
+
+ BlockStateInterfaceAccessWrapper(BlockStateInterface bsi) {
+ this.bsi = bsi;
+ }
+
+ @Nullable
+ @Override
+ public TileEntity getTileEntity(BlockPos pos) {
+ throw new UnsupportedOperationException("getTileEntity not supported by BlockStateInterfaceAccessWrapper");
+ }
+
+ @Override
+ public IBlockState getBlockState(BlockPos pos) {
+ // BlockStateInterface#get0(BlockPos) btfo!
+ return this.bsi.get0(pos.getX(), pos.getY(), pos.getZ());
+ }
+
+ @Override
+ public IFluidState getFluidState(BlockPos blockPos) {
+ return getBlockState(blockPos).getFluidState();
+ }
+}