From 2b96a2e4636f4d1714c5fb16712a53832a2cd8fb Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Mon, 1 Apr 2024 14:12:46 -0700 Subject: [PATCH 1/2] don't apply block break delay to insta-breaks --- .../baritone/api/utils/IPlayerController.java | 6 ++- .../launch/mixins/MixinPlayerController.java | 10 ++-- .../java/baritone/utils/BlockBreakHelper.java | 47 ++++++++++--------- .../utils/accessor/IPlayerControllerMP.java | 8 ++-- .../player/BaritonePlayerController.java | 13 +++-- 5 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/api/java/baritone/api/utils/IPlayerController.java b/src/api/java/baritone/api/utils/IPlayerController.java index 48142d13b..dbe152fc8 100644 --- a/src/api/java/baritone/api/utils/IPlayerController.java +++ b/src/api/java/baritone/api/utils/IPlayerController.java @@ -37,7 +37,7 @@ public interface IPlayerController { void syncHeldItem(); - boolean hasBrokenBlock(); + boolean isDestroyingBlock(); boolean onPlayerDamageBlock(BlockPos pos, Direction side); @@ -53,7 +53,9 @@ public interface IPlayerController { boolean clickBlock(BlockPos loc, Direction face); - void setHittingBlock(boolean hittingBlock); + void setDestroyingBlock(boolean hittingBlock); + + void setDestroyDelay(int destroyDelay); default double getBlockReachDistance() { return this.getGameType().isCreative() ? 5.0F : BaritoneAPI.getSettings().blockReachDistance.value; diff --git a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java index 34f39aee9..a486b8ec3 100644 --- a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java +++ b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java @@ -29,13 +29,17 @@ public abstract class MixinPlayerController implements IPlayerControllerMP { @Accessor("isDestroying") @Override - public abstract void setIsHittingBlock(boolean isHittingBlock); + public abstract void setIsDestroyingBlock(boolean isDestroyingBlock); - @Accessor("destroyBlockPos") + @Accessor("isDestroying") @Override - public abstract BlockPos getCurrentBlock(); + public abstract boolean isDestroyingBlock(); @Invoker("ensureHasSentCarriedItem") @Override public abstract void callSyncCurrentPlayItem(); + + @Accessor("destroyDelay") + @Override + public abstract void setDestroyDelay(int destroyDelay); } diff --git a/src/main/java/baritone/utils/BlockBreakHelper.java b/src/main/java/baritone/utils/BlockBreakHelper.java index 3332aec76..c70e5584a 100644 --- a/src/main/java/baritone/utils/BlockBreakHelper.java +++ b/src/main/java/baritone/utils/BlockBreakHelper.java @@ -29,10 +29,10 @@ import net.minecraft.world.phys.HitResult; */ public final class BlockBreakHelper { // base ticks between block breaks caused by tick logic - private static final int BASE_BREAK_DELAY = 2; + private static final int BASE_BREAK_DELAY = 1; private final IPlayerContext ctx; - private boolean didBreakLastTick; + private boolean wasDestroyingBlockLastTick; private int breakDelayTimer = 0; BlockBreakHelper(IPlayerContext ctx) { @@ -41,13 +41,10 @@ public final class BlockBreakHelper { public void stopBreakingBlock() { // The player controller will never be null, but the player can be - if (ctx.player() != null && didBreakLastTick) { - if (!ctx.playerController().hasBrokenBlock()) { - // insane bypass to check breaking succeeded - ctx.playerController().setHittingBlock(true); - } + if (ctx.player() != null && wasDestroyingBlockLastTick) { + ctx.playerController().setDestroyingBlock(false); ctx.playerController().resetBlockRemoving(); - didBreakLastTick = false; + wasDestroyingBlockLastTick = false; } } @@ -60,24 +57,30 @@ public final class BlockBreakHelper { boolean isBlockTrace = trace != null && trace.getType() == HitResult.Type.BLOCK; if (isLeftClick && isBlockTrace) { - if (!didBreakLastTick) { + ctx.playerController().setDestroyingBlock(wasDestroyingBlockLastTick); + if (!ctx.playerController().isDestroyingBlock()) { ctx.playerController().syncHeldItem(); ctx.playerController().clickBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection()); ctx.player().swing(InteractionHand.MAIN_HAND); + } else { + if (ctx.playerController().onPlayerDamageBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection())) { + ctx.player().swing(InteractionHand.MAIN_HAND); + } + if (!ctx.playerController().isDestroyingBlock()) { // block broken this tick + // break delay timer only applies for multi-tick block breaks like vanilla + breakDelayTimer = BaritoneAPI.getSettings().blockBreakSpeed.value - BASE_BREAK_DELAY; + // must reset controller's destroy delay to prevent the client from delaying itself unnecessarily + ctx.playerController().setDestroyDelay(0); + } } - - // Attempt to break the block - if (ctx.playerController().onPlayerDamageBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection())) { - ctx.player().swing(InteractionHand.MAIN_HAND); - } - - ctx.playerController().setHittingBlock(false); - - didBreakLastTick = true; - } else if (didBreakLastTick) { - stopBreakingBlock(); - breakDelayTimer = BaritoneAPI.getSettings().blockBreakSpeed.value - BASE_BREAK_DELAY; - didBreakLastTick = false; + // if true, we're breaking a block. if false, we broke the block this tick + wasDestroyingBlockLastTick = ctx.playerController().isDestroyingBlock(); + // this value will be reset by the MC client handling mouse keys + // since we're not spoofing the click keybind to the client, the client will stop the break if isDestroyingBlock is true + // we store and restore this value on the next tick to determine if we're breaking a block + ctx.playerController().setDestroyingBlock(false); + } else { + wasDestroyingBlockLastTick = false; } } } diff --git a/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java b/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java index 72e6f7ee3..9d1839b54 100644 --- a/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java +++ b/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java @@ -17,13 +17,13 @@ package baritone.utils.accessor; -import net.minecraft.core.BlockPos; - public interface IPlayerControllerMP { - void setIsHittingBlock(boolean isHittingBlock); + void setIsDestroyingBlock(boolean isDestroyingBlock); - BlockPos getCurrentBlock(); + boolean isDestroyingBlock(); void callSyncCurrentPlayItem(); + + void setDestroyDelay(int destroyDelay); } diff --git a/src/main/java/baritone/utils/player/BaritonePlayerController.java b/src/main/java/baritone/utils/player/BaritonePlayerController.java index 42ba49052..419b45f9c 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerController.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerController.java @@ -53,8 +53,13 @@ public final class BaritonePlayerController implements IPlayerController { } @Override - public boolean hasBrokenBlock() { - return ((IPlayerControllerMP) mc.gameMode).getCurrentBlock().getY() == -1; + public boolean isDestroyingBlock() { + return ((IPlayerControllerMP) mc.gameMode).isDestroyingBlock(); + } + + @Override + public void setDestroyDelay(int destroyDelay) { + ((IPlayerControllerMP) mc.gameMode).setDestroyDelay(destroyDelay); } @Override @@ -94,7 +99,7 @@ public final class BaritonePlayerController implements IPlayerController { } @Override - public void setHittingBlock(boolean hittingBlock) { - ((IPlayerControllerMP) mc.gameMode).setIsHittingBlock(hittingBlock); + public void setDestroyingBlock(boolean destroyingBlock) { + ((IPlayerControllerMP) mc.gameMode).setIsDestroyingBlock(destroyingBlock); } } From 15fdbb2312d663d7b401ac56d74ea83c676f11ee Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Sun, 7 Apr 2024 20:24:04 -0700 Subject: [PATCH 2/2] revert API renaming --- src/api/java/baritone/api/Settings.java | 2 +- .../baritone/api/utils/IPlayerController.java | 6 ++--- .../launch/mixins/MixinPlayerController.java | 8 +++++-- .../java/baritone/utils/BlockBreakHelper.java | 23 ++++++++++--------- .../utils/accessor/IPlayerControllerMP.java | 8 +++++-- .../player/BaritonePlayerController.java | 14 ++++------- 6 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 8609a0a88..071354620 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -387,7 +387,7 @@ public final class Settings { /** * How many ticks between breaking a block and starting to break the next block. Default in game is 6 ticks. - * Values under 2 will be clamped. + * Values under 1 will be clamped. The delay only applies to non-instant (1-tick) breaks. */ public final Setting blockBreakSpeed = new Setting<>(6); diff --git a/src/api/java/baritone/api/utils/IPlayerController.java b/src/api/java/baritone/api/utils/IPlayerController.java index dbe152fc8..48142d13b 100644 --- a/src/api/java/baritone/api/utils/IPlayerController.java +++ b/src/api/java/baritone/api/utils/IPlayerController.java @@ -37,7 +37,7 @@ public interface IPlayerController { void syncHeldItem(); - boolean isDestroyingBlock(); + boolean hasBrokenBlock(); boolean onPlayerDamageBlock(BlockPos pos, Direction side); @@ -53,9 +53,7 @@ public interface IPlayerController { boolean clickBlock(BlockPos loc, Direction face); - void setDestroyingBlock(boolean hittingBlock); - - void setDestroyDelay(int destroyDelay); + void setHittingBlock(boolean hittingBlock); default double getBlockReachDistance() { return this.getGameType().isCreative() ? 5.0F : BaritoneAPI.getSettings().blockReachDistance.value; diff --git a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java index a486b8ec3..7a77d4849 100644 --- a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java +++ b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java @@ -29,11 +29,15 @@ public abstract class MixinPlayerController implements IPlayerControllerMP { @Accessor("isDestroying") @Override - public abstract void setIsDestroyingBlock(boolean isDestroyingBlock); + public abstract void setIsHittingBlock(boolean isHittingBlock); @Accessor("isDestroying") @Override - public abstract boolean isDestroyingBlock(); + public abstract boolean isHittingBlock(); + + @Accessor("destroyBlockPos") + @Override + public abstract BlockPos getCurrentBlock(); @Invoker("ensureHasSentCarriedItem") @Override diff --git a/src/main/java/baritone/utils/BlockBreakHelper.java b/src/main/java/baritone/utils/BlockBreakHelper.java index c70e5584a..0c5cf6f00 100644 --- a/src/main/java/baritone/utils/BlockBreakHelper.java +++ b/src/main/java/baritone/utils/BlockBreakHelper.java @@ -19,6 +19,7 @@ package baritone.utils; import baritone.api.BaritoneAPI; import baritone.api.utils.IPlayerContext; +import baritone.utils.accessor.IPlayerControllerMP; import net.minecraft.world.InteractionHand; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; @@ -32,7 +33,7 @@ public final class BlockBreakHelper { private static final int BASE_BREAK_DELAY = 1; private final IPlayerContext ctx; - private boolean wasDestroyingBlockLastTick; + private boolean wasHitting; private int breakDelayTimer = 0; BlockBreakHelper(IPlayerContext ctx) { @@ -41,10 +42,10 @@ public final class BlockBreakHelper { public void stopBreakingBlock() { // The player controller will never be null, but the player can be - if (ctx.player() != null && wasDestroyingBlockLastTick) { - ctx.playerController().setDestroyingBlock(false); + if (ctx.player() != null && wasHitting) { + ctx.playerController().setHittingBlock(false); ctx.playerController().resetBlockRemoving(); - wasDestroyingBlockLastTick = false; + wasHitting = false; } } @@ -57,8 +58,8 @@ public final class BlockBreakHelper { boolean isBlockTrace = trace != null && trace.getType() == HitResult.Type.BLOCK; if (isLeftClick && isBlockTrace) { - ctx.playerController().setDestroyingBlock(wasDestroyingBlockLastTick); - if (!ctx.playerController().isDestroyingBlock()) { + ctx.playerController().setHittingBlock(wasHitting); + if (ctx.playerController().hasBrokenBlock()) { ctx.playerController().syncHeldItem(); ctx.playerController().clickBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection()); ctx.player().swing(InteractionHand.MAIN_HAND); @@ -66,21 +67,21 @@ public final class BlockBreakHelper { if (ctx.playerController().onPlayerDamageBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection())) { ctx.player().swing(InteractionHand.MAIN_HAND); } - if (!ctx.playerController().isDestroyingBlock()) { // block broken this tick + if (ctx.playerController().hasBrokenBlock()) { // block broken this tick // break delay timer only applies for multi-tick block breaks like vanilla breakDelayTimer = BaritoneAPI.getSettings().blockBreakSpeed.value - BASE_BREAK_DELAY; // must reset controller's destroy delay to prevent the client from delaying itself unnecessarily - ctx.playerController().setDestroyDelay(0); + ((IPlayerControllerMP) ctx.minecraft().gameMode).setDestroyDelay(0); } } // if true, we're breaking a block. if false, we broke the block this tick - wasDestroyingBlockLastTick = ctx.playerController().isDestroyingBlock(); + wasHitting = !ctx.playerController().hasBrokenBlock(); // this value will be reset by the MC client handling mouse keys // since we're not spoofing the click keybind to the client, the client will stop the break if isDestroyingBlock is true // we store and restore this value on the next tick to determine if we're breaking a block - ctx.playerController().setDestroyingBlock(false); + ctx.playerController().setHittingBlock(false); } else { - wasDestroyingBlockLastTick = false; + wasHitting = false; } } } diff --git a/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java b/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java index 9d1839b54..55fa43316 100644 --- a/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java +++ b/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java @@ -17,11 +17,15 @@ package baritone.utils.accessor; +import net.minecraft.core.BlockPos; + public interface IPlayerControllerMP { - void setIsDestroyingBlock(boolean isDestroyingBlock); + void setIsHittingBlock(boolean isHittingBlock); - boolean isDestroyingBlock(); + boolean isHittingBlock(); + + BlockPos getCurrentBlock(); void callSyncCurrentPlayItem(); diff --git a/src/main/java/baritone/utils/player/BaritonePlayerController.java b/src/main/java/baritone/utils/player/BaritonePlayerController.java index 419b45f9c..b7e729b70 100644 --- a/src/main/java/baritone/utils/player/BaritonePlayerController.java +++ b/src/main/java/baritone/utils/player/BaritonePlayerController.java @@ -20,7 +20,6 @@ package baritone.utils.player; import baritone.api.utils.IPlayerController; import baritone.utils.accessor.IPlayerControllerMP; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -53,13 +52,8 @@ public final class BaritonePlayerController implements IPlayerController { } @Override - public boolean isDestroyingBlock() { - return ((IPlayerControllerMP) mc.gameMode).isDestroyingBlock(); - } - - @Override - public void setDestroyDelay(int destroyDelay) { - ((IPlayerControllerMP) mc.gameMode).setDestroyDelay(destroyDelay); + public boolean hasBrokenBlock() { + return !((IPlayerControllerMP) mc.gameMode).isHittingBlock(); } @Override @@ -99,7 +93,7 @@ public final class BaritonePlayerController implements IPlayerController { } @Override - public void setDestroyingBlock(boolean destroyingBlock) { - ((IPlayerControllerMP) mc.gameMode).setIsDestroyingBlock(destroyingBlock); + public void setHittingBlock(boolean hittingBlock) { + ((IPlayerControllerMP) mc.gameMode).setIsHittingBlock(hittingBlock); } }