diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 2d67dbe34..7b47a2a6f 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -170,6 +170,11 @@ public final class Settings { */ public final Setting sprintAscends = new Setting<>(true); + /** + * How many ticks between right clicks are allowed. Default in game is 4 + */ + public final Setting rightClickSpeed = new Setting<>(4); + /** * This is the big A* setting. * As long as your cost heuristic is an *underestimate*, it's guaranteed to find you the best path. @@ -386,11 +391,6 @@ public final class Settings { */ public final Setting pruneRegionsFromRAM = new Setting<>(false); - /** - * Cancel baritone on left click, as a form of "panic button" - */ - public final Setting clickCancel = new Setting<>(false); - /** * Remember the contents of containers (chests, echests, furnaces) *

@@ -509,11 +509,6 @@ public final class Settings { */ public final Setting cachedChunksOpacity = new Setting<>(0.5f); - /** - * If true, Baritone will not allow you to left or right click while pathing - */ - public final Setting suppressClicks = new Setting<>(false); - /** * Whether or not to use the "#" command prefix */ diff --git a/src/api/java/baritone/api/utils/IInputOverrideHandler.java b/src/api/java/baritone/api/utils/IInputOverrideHandler.java index 03f6e4ddf..3cfb74385 100644 --- a/src/api/java/baritone/api/utils/IInputOverrideHandler.java +++ b/src/api/java/baritone/api/utils/IInputOverrideHandler.java @@ -19,7 +19,6 @@ package baritone.api.utils; import baritone.api.behavior.IBehavior; import baritone.api.utils.input.Input; -import net.minecraft.client.settings.KeyBinding; /** * @author Brady @@ -27,8 +26,6 @@ import net.minecraft.client.settings.KeyBinding; */ public interface IInputOverrideHandler extends IBehavior { - Boolean isInputForcedDown(KeyBinding key); - boolean isInputForcedDown(Input input); void setInputForceState(Input input, boolean forced); diff --git a/src/api/java/baritone/api/utils/IPlayerController.java b/src/api/java/baritone/api/utils/IPlayerController.java index dd63a41b2..dced52865 100644 --- a/src/api/java/baritone/api/utils/IPlayerController.java +++ b/src/api/java/baritone/api/utils/IPlayerController.java @@ -17,12 +17,17 @@ package baritone.api.utils; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ClickType; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameType; +import net.minecraft.world.World; /** * @author Brady @@ -43,4 +48,6 @@ public interface IPlayerController { default double getBlockReachDistance() { return this.getGameType().isCreative() ? 5.0F : 4.5F; } + + EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand); } diff --git a/src/launch/java/baritone/launch/mixins/MixinKeyBinding.java b/src/launch/java/baritone/launch/mixins/MixinKeyBinding.java deleted file mode 100644 index d61537c9d..000000000 --- a/src/launch/java/baritone/launch/mixins/MixinKeyBinding.java +++ /dev/null @@ -1,79 +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.launch.mixins; - -import baritone.Baritone; -import baritone.api.BaritoneAPI; -import baritone.utils.Helper; -import net.minecraft.client.Minecraft; -import net.minecraft.client.settings.KeyBinding; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -/** - * @author Brady - * @since 7/31/2018 - */ -@Mixin(KeyBinding.class) -public class MixinKeyBinding { - - @Shadow - private int pressTime; - - @Inject( - method = "isKeyDown", - at = @At("HEAD"), - cancellable = true - ) - private void isKeyDown(CallbackInfoReturnable cir) { - // only the primary baritone forces keys - Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this); - if (force != null) { - if (!force && !Baritone.settings().suppressClicks.get()) { - return; - } - cir.setReturnValue(force); // :sunglasses: - } - } - - @Inject( - method = "isPressed", - at = @At("HEAD"), - cancellable = true - ) - private void isPressed(CallbackInfoReturnable cir) { - // only the primary baritone forces keys - Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this); - if (pressTime > 0 && (KeyBinding) (Object) this == Minecraft.getMinecraft().gameSettings.keyBindAttack && Baritone.settings().clickCancel.get() && BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().isPathing()) { - Helper.HELPER.logDirect("Cancelling path on left click since the clickCancel setting is enabled!"); - BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything(); - return; - } - if (force != null && !force && Baritone.settings().suppressClicks.get()) { // <-- cursed - if (pressTime > 0) { - Helper.HELPER.logDirect("You're trying to press this mouse button but I won't let you."); - Helper.HELPER.logDirect("Turn off the suppressClicks setting to allow clicking while pathing."); - pressTime--; - } - cir.setReturnValue(force); // :sunglasses: - } - } -} diff --git a/src/launch/resources/mixins.baritone.json b/src/launch/resources/mixins.baritone.json index fea9cca7d..3b5fa70cc 100644 --- a/src/launch/resources/mixins.baritone.json +++ b/src/launch/resources/mixins.baritone.json @@ -17,7 +17,6 @@ "MixinEntityLivingBase", "MixinEntityPlayerSP", "MixinEntityRenderer", - "MixinKeyBinding", "MixinMinecraft", "MixinNetHandlerPlayClient", "MixinNetworkManager", diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index d430f8c58..1bbfa6f91 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -226,7 +226,7 @@ public class MovementPillar extends Movement { if (!(fr instanceof BlockAir || fr.isReplaceable(ctx.world(), src))) { state.setInput(Input.CLICK_LEFT, true); blockIsThere = false; - } else if (ctx.player().isSneaking() && (Objects.equals(src.down(), ctx.objectMouseOver().getBlockPos()) || Objects.equals(src, ctx.objectMouseOver().getBlockPos()))) { + } else if (ctx.player().isSneaking() && (Objects.equals(src.down(), ctx.objectMouseOver().getBlockPos()) || Objects.equals(src, ctx.objectMouseOver().getBlockPos())) && ctx.player().posY > dest.getY() + 0.1) { state.setInput(Input.CLICK_RIGHT, true); } } diff --git a/src/main/java/baritone/utils/BlockBreakHelper.java b/src/main/java/baritone/utils/BlockBreakHelper.java index b410e6b37..db56b91f7 100644 --- a/src/main/java/baritone/utils/BlockBreakHelper.java +++ b/src/main/java/baritone/utils/BlockBreakHelper.java @@ -31,7 +31,7 @@ public final class BlockBreakHelper implements Helper { private boolean didBreakLastTick; - private IPlayerContext playerContext; + private final IPlayerContext playerContext; public BlockBreakHelper(IPlayerContext playerContext) { this.playerContext = playerContext; diff --git a/src/main/java/baritone/utils/BlockPlaceHelper.java b/src/main/java/baritone/utils/BlockPlaceHelper.java new file mode 100644 index 000000000..e0c782bb4 --- /dev/null +++ b/src/main/java/baritone/utils/BlockPlaceHelper.java @@ -0,0 +1,53 @@ +/* + * 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 baritone.Baritone; +import baritone.api.utils.IPlayerContext; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; + +public class BlockPlaceHelper implements Helper { + private final IPlayerContext ctx; + private int rightClickTimer; + + public BlockPlaceHelper(IPlayerContext playerContext) { + this.ctx = playerContext; + } + + public void tick(boolean rightClickRequested) { + if (rightClickTimer > 0) { + rightClickTimer--; + return; + } + RayTraceResult mouseOver = ctx.objectMouseOver(); + BlockPos pos = mouseOver.getBlockPos(); + if (!rightClickRequested || ctx.player().isRowingBoat() || pos == null || mouseOver.typeOfHit != RayTraceResult.Type.BLOCK) { + return; + } + rightClickTimer = Baritone.settings().rightClickSpeed.get(); + for (EnumHand hand : EnumHand.values()) { + if (ctx.playerController().processRightClickBlock(ctx.player(), ctx.world(), pos, mouseOver.sideHit, mouseOver.hitVec, hand) == EnumActionResult.SUCCESS) { + ctx.player().swingArm(hand); + return; + } + } + } +} diff --git a/src/main/java/baritone/utils/InputOverrideHandler.java b/src/main/java/baritone/utils/InputOverrideHandler.java index 6b0a96e70..47a068546 100755 --- a/src/main/java/baritone/utils/InputOverrideHandler.java +++ b/src/main/java/baritone/utils/InputOverrideHandler.java @@ -24,7 +24,6 @@ import baritone.api.utils.IInputOverrideHandler; import baritone.api.utils.input.Input; import baritone.behavior.Behavior; import net.minecraft.client.Minecraft; -import net.minecraft.client.settings.KeyBinding; import net.minecraft.util.MovementInputFromOptions; import java.util.HashMap; @@ -46,38 +45,12 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri private final Map inputForceStateMap = new HashMap<>(); private final BlockBreakHelper blockBreakHelper; + private final BlockPlaceHelper blockPlaceHelper; public InputOverrideHandler(Baritone baritone) { super(baritone); this.blockBreakHelper = new BlockBreakHelper(baritone.getPlayerContext()); - } - - /** - * Returns whether or not we are forcing down the specified {@link KeyBinding}. - * - * @param key The KeyBinding object - * @return Whether or not it is being forced down - */ - @Override - public final Boolean isInputForcedDown(KeyBinding key) { - Input input = Input.getInputForBind(key); - if (input == null) { - return null; - } - if (input == Input.CLICK_LEFT && inControl()) { - // only override left click off when pathing - return false; - } - if (input == Input.CLICK_RIGHT) { - if (isInputForcedDown(Input.CLICK_RIGHT)) { - // gettoblock and builder can right click even when not pathing; allow them to do so - return true; - } else if (inControl()) { - // but when we are pathing for real, force right click off - return false; - } - } - return null; // dont force any inputs other than left and right click + this.blockPlaceHelper = new BlockPlaceHelper(baritone.getPlayerContext()); } /** @@ -115,7 +88,11 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri if (event.getType() == TickEvent.Type.OUT) { return; } + if (isInputForcedDown(Input.CLICK_LEFT)) { + setInputForceState(Input.CLICK_RIGHT, false); + } blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT)); + blockPlaceHelper.tick(isInputForcedDown(Input.CLICK_RIGHT)); if (inControl()) { if (ctx.player().movementInput.getClass() != PlayerMovementInput.class) { @@ -131,6 +108,7 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri } private boolean inControl() { + // if we are not primary (a bot) we should set the movementinput even when idle (not pathing) return baritone.getPathingBehavior().isPathing() || baritone != BaritoneAPI.getProvider().getPrimaryBaritone(); } diff --git a/src/main/java/baritone/utils/player/PrimaryPlayerController.java b/src/main/java/baritone/utils/player/PrimaryPlayerController.java index c0dc8798b..76e389e77 100644 --- a/src/main/java/baritone/utils/player/PrimaryPlayerController.java +++ b/src/main/java/baritone/utils/player/PrimaryPlayerController.java @@ -19,12 +19,18 @@ package baritone.utils.player; import baritone.api.utils.IPlayerController; import baritone.utils.Helper; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ClickType; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameType; +import net.minecraft.world.World; /** * Implementation of {@link IPlayerController} that chains to the primary player controller's methods @@ -60,4 +66,10 @@ public enum PrimaryPlayerController implements IPlayerController, Helper { public GameType getGameType() { return mc.playerController.getCurrentGameType(); } + + @Override + public EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand) { + // primaryplayercontroller is always in a WorldClient so this is ok + return mc.playerController.processRightClickBlock(player, (WorldClient) world, pos, direction, vec, hand); + } }