diff --git a/README.md b/README.md index 90173889d..043aed085 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ![Lines of Code](https://tokei.rs/b1/github/cabaletta/baritone?category=code) [![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.10%20/%20v1.3.5%20/%20v1.4.2-brightgreen.svg)](https://impactclient.net/) +[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.10%20/%20v1.3.5%20/%20v1.4.3-brightgreen.svg)](https://impactclient.net/) [![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/) [![Aristois add-on integration](https://img.shields.io/badge/Aristois%20add--on%20integration-v1.3.4%20/%20v1.4.1-green.svg)](https://gitlab.com/emc-mods-indrit/baritone_api) [![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](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(); + } +}