don't apply block break delay to insta-breaks

This commit is contained in:
rfresh2 2024-04-01 14:12:46 -07:00
parent 62b2f81ba1
commit 2b96a2e463
No known key found for this signature in database
GPG Key ID: FD6E7EA7A754A98A
5 changed files with 49 additions and 35 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}
}
}

View File

@ -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);
}

View File

@ -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);
}
}