mirror of https://github.com/cabaletta/baritone
Compare commits
7 Commits
62b2f81ba1
...
0c09441154
Author | SHA1 | Date |
---|---|---|
leijurv | 0c09441154 | |
leijurv | 69d3bc0c2e | |
leijurv | b31e0a87cb | |
ZacSharp | 4572b75db7 | |
rfresh2 | 15fdbb2312 | |
ZacSharp | 848b7c6de0 | |
rfresh2 | 2b96a2e463 |
|
@ -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<Integer> blockBreakSpeed = new Setting<>(6);
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ public class SettingsUtil {
|
|||
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
|
||||
}
|
||||
|
||||
return io.toString(new ParserContext(setting), value);
|
||||
return io.toString(setting.getType(), value);
|
||||
}
|
||||
|
||||
public static String settingValueToString(Settings.Setting setting) throws IllegalArgumentException {
|
||||
|
@ -196,7 +196,7 @@ public class SettingsUtil {
|
|||
}
|
||||
Class intendedType = setting.getValueClass();
|
||||
ISettingParser ioMethod = Parser.getParser(setting.getType());
|
||||
Object parsed = ioMethod.parse(new ParserContext(setting), settingValue);
|
||||
Object parsed = ioMethod.parse(setting.getType(), settingValue);
|
||||
if (!intendedType.isInstance(parsed)) {
|
||||
throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass());
|
||||
}
|
||||
|
@ -205,26 +205,13 @@ public class SettingsUtil {
|
|||
|
||||
private interface ISettingParser<T> {
|
||||
|
||||
T parse(ParserContext context, String raw);
|
||||
T parse(Type type, String raw);
|
||||
|
||||
String toString(ParserContext context, T value);
|
||||
String toString(Type type, T value);
|
||||
|
||||
boolean accepts(Type type);
|
||||
}
|
||||
|
||||
private static class ParserContext {
|
||||
|
||||
private final Settings.Setting<?> setting;
|
||||
|
||||
private ParserContext(Settings.Setting<?> setting) {
|
||||
this.setting = setting;
|
||||
}
|
||||
|
||||
private Settings.Setting<?> getSetting() {
|
||||
return this.setting;
|
||||
}
|
||||
}
|
||||
|
||||
private enum Parser implements ISettingParser {
|
||||
|
||||
DOUBLE(Double.class, Double::parseDouble),
|
||||
|
@ -256,21 +243,21 @@ public class SettingsUtil {
|
|||
),
|
||||
LIST() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
public Object parse(Type type, String raw) {
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(elementType);
|
||||
return Stream.of(raw.split(","))
|
||||
.map(s -> parser.parse(context, s))
|
||||
.map(s -> parser.parse(elementType, s))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
public String toString(Type type, Object value) {
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(elementType);
|
||||
|
||||
return ((List<?>) value).stream()
|
||||
.map(o -> parser.toString(context, o))
|
||||
.map(o -> parser.toString(elementType, o))
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
|
@ -281,26 +268,26 @@ public class SettingsUtil {
|
|||
},
|
||||
MAPPING() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
|
||||
public Object parse(Type type, String raw) {
|
||||
Type keyType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) type).getActualTypeArguments()[1];
|
||||
Parser keyParser = Parser.getParser(keyType);
|
||||
Parser valueParser = Parser.getParser(valueType);
|
||||
|
||||
return Stream.of(raw.split(",(?=[^,]*->)"))
|
||||
.map(s -> s.split("->"))
|
||||
.collect(Collectors.toMap(s -> keyParser.parse(context, s[0]), s -> valueParser.parse(context, s[1])));
|
||||
.collect(Collectors.toMap(s -> keyParser.parse(keyType, s[0]), s -> valueParser.parse(valueType, s[1])));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
|
||||
public String toString(Type type, Object value) {
|
||||
Type keyType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) type).getActualTypeArguments()[1];
|
||||
Parser keyParser = Parser.getParser(keyType);
|
||||
Parser valueParser = Parser.getParser(valueType);
|
||||
|
||||
return ((Map<?, ?>) value).entrySet().stream()
|
||||
.map(o -> keyParser.toString(context, o.getKey()) + "->" + valueParser.toString(context, o.getValue()))
|
||||
.map(o -> keyParser.toString(keyType, o.getKey()) + "->" + valueParser.toString(valueType, o.getValue()))
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
|
@ -331,14 +318,14 @@ public class SettingsUtil {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
public Object parse(Type type, String raw) {
|
||||
Object parsed = this.parser.apply(raw);
|
||||
Objects.requireNonNull(parsed);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
public String toString(Type type, Object value) {
|
||||
return this.toString.apply(value);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ public abstract class MixinPlayerController implements IPlayerControllerMP {
|
|||
@Override
|
||||
public abstract void setIsHittingBlock(boolean isHittingBlock);
|
||||
|
||||
@Accessor("isDestroying")
|
||||
@Override
|
||||
public abstract boolean isHittingBlock();
|
||||
|
||||
@Accessor("destroyBlockPos")
|
||||
@Override
|
||||
public abstract BlockPos getCurrentBlock();
|
||||
|
@ -38,4 +42,8 @@ public abstract class MixinPlayerController implements IPlayerControllerMP {
|
|||
@Invoker("ensureHasSentCarriedItem")
|
||||
@Override
|
||||
public abstract void callSyncCurrentPlayItem();
|
||||
|
||||
@Accessor("destroyDelay")
|
||||
@Override
|
||||
public abstract void setDestroyDelay(int destroyDelay);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -29,10 +30,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 wasHitting;
|
||||
private int breakDelayTimer = 0;
|
||||
|
||||
BlockBreakHelper(IPlayerContext ctx) {
|
||||
|
@ -41,13 +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 && didBreakLastTick) {
|
||||
if (!ctx.playerController().hasBrokenBlock()) {
|
||||
// insane bypass to check breaking succeeded
|
||||
ctx.playerController().setHittingBlock(true);
|
||||
}
|
||||
if (ctx.player() != null && wasHitting) {
|
||||
ctx.playerController().setHittingBlock(false);
|
||||
ctx.playerController().resetBlockRemoving();
|
||||
didBreakLastTick = false;
|
||||
wasHitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,24 +58,30 @@ public final class BlockBreakHelper {
|
|||
boolean isBlockTrace = trace != null && trace.getType() == HitResult.Type.BLOCK;
|
||||
|
||||
if (isLeftClick && isBlockTrace) {
|
||||
if (!didBreakLastTick) {
|
||||
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);
|
||||
} else {
|
||||
if (ctx.playerController().onPlayerDamageBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection())) {
|
||||
ctx.player().swing(InteractionHand.MAIN_HAND);
|
||||
}
|
||||
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
|
||||
((IPlayerControllerMP) ctx.minecraft().gameMode).setDestroyDelay(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to break the block
|
||||
if (ctx.playerController().onPlayerDamageBlock(((BlockHitResult) trace).getBlockPos(), ((BlockHitResult) trace).getDirection())) {
|
||||
ctx.player().swing(InteractionHand.MAIN_HAND);
|
||||
}
|
||||
|
||||
// if true, we're breaking a block. if false, we broke the block this tick
|
||||
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().setHittingBlock(false);
|
||||
|
||||
didBreakLastTick = true;
|
||||
} else if (didBreakLastTick) {
|
||||
stopBreakingBlock();
|
||||
breakDelayTimer = BaritoneAPI.getSettings().blockBreakSpeed.value - BASE_BREAK_DELAY;
|
||||
didBreakLastTick = false;
|
||||
} else {
|
||||
wasHitting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,7 +177,13 @@ public class ToolSet {
|
|||
* @return how long it would take in ticks
|
||||
*/
|
||||
public static double calculateSpeedVsBlock(ItemStack item, BlockState state) {
|
||||
float hardness = state.getDestroySpeed(null, null);
|
||||
float hardness;
|
||||
try {
|
||||
hardness = state.getDestroySpeed(null, null);
|
||||
} catch (NullPointerException npe) {
|
||||
// can't easily determine the hardness so treat it as unbreakable
|
||||
return -1;
|
||||
}
|
||||
if (hardness < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,11 @@ public interface IPlayerControllerMP {
|
|||
|
||||
void setIsHittingBlock(boolean isHittingBlock);
|
||||
|
||||
boolean isHittingBlock();
|
||||
|
||||
BlockPos getCurrentBlock();
|
||||
|
||||
void callSyncCurrentPlayItem();
|
||||
|
||||
void setDestroyDelay(int destroyDelay);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -54,7 +53,7 @@ public final class BaritonePlayerController implements IPlayerController {
|
|||
|
||||
@Override
|
||||
public boolean hasBrokenBlock() {
|
||||
return ((IPlayerControllerMP) mc.gameMode).getCurrentBlock().getY() == -1;
|
||||
return !((IPlayerControllerMP) mc.gameMode).isHittingBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue