diff --git a/build.gradle b/build.gradle index d802ac566..6cf42af69 100755 --- a/build.gradle +++ b/build.gradle @@ -37,11 +37,11 @@ allprojects { } group = rootProject.maven_group - sourceCompatibility = targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = targetCompatibility = JavaVersion.toVersion(project.java_version) java { toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion.set(JavaLanguageVersion.of(sourceCompatibility.majorVersion.toInteger())) } } @@ -103,7 +103,7 @@ allprojects { tasks.withType(JavaCompile).configureEach { it.options.encoding = "UTF-8" - def targetVersion = 17 + def targetVersion = project.java_version.toInteger() if (JavaVersion.current().isJava9Compatible()) { it.options.release = targetVersion } diff --git a/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java b/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java index 2dad551f2..f27df9aaa 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/BaritoneGradleTask.java @@ -36,8 +36,8 @@ import java.nio.file.Paths; class BaritoneGradleTask extends DefaultTask { protected static final String - PROGUARD_ZIP = "proguard.zip", - PROGUARD_JAR = "proguard.jar", + PROGUARD_ZIP = "proguard-%s.zip", + PROGUARD_JAR = "proguard-%s.jar", PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro", PROGUARD_CONFIG_DEST = "template.pro", PROGUARD_API_CONFIG = "api.pro", diff --git a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java index a9c7f94ea..d5e05a19c 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java @@ -26,6 +26,9 @@ import org.gradle.api.tasks.TaskCollection; import org.gradle.api.tasks.compile.ForkOptions; import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.internal.jvm.Jvm; +import org.gradle.jvm.toolchain.JavaLanguageVersion; +import org.gradle.jvm.toolchain.JavaLauncher; +import org.gradle.jvm.toolchain.JavaToolchainService; import xyz.wagyourtail.unimined.api.UniminedExtension; import xyz.wagyourtail.unimined.api.minecraft.MinecraftConfig; @@ -47,17 +50,10 @@ import java.util.zip.ZipFile; public class ProguardTask extends BaritoneGradleTask { @Input - private String url; + private String proguardVersion; - public String getUrl() { - return url; - } - - @Input - private String extract; - - public String getExtract() { - return extract; + public String getProguardVersion() { + return proguardVersion; } private List requiredLibraries; @@ -99,98 +95,33 @@ public class ProguardTask extends BaritoneGradleTask { } private void downloadProguard() throws Exception { - Path proguardZip = getTemporaryFile(PROGUARD_ZIP); + Path proguardZip = getTemporaryFile(String.format(PROGUARD_ZIP, proguardVersion)); if (!Files.exists(proguardZip)) { - write(new URL(this.url).openStream(), proguardZip); + write(new URL(String.format("https://github.com/Guardsquare/proguard/releases/download/v%s/proguard-%s.zip", proguardVersion, proguardVersion)).openStream(), proguardZip); } } private void extractProguard() throws Exception { - Path proguardJar = getTemporaryFile(PROGUARD_JAR); + Path proguardJar = getTemporaryFile(String.format(PROGUARD_JAR, proguardVersion)); if (!Files.exists(proguardJar)) { - ZipFile zipFile = new ZipFile(getTemporaryFile(PROGUARD_ZIP).toFile()); - ZipEntry zipJarEntry = zipFile.getEntry(this.extract); + ZipFile zipFile = new ZipFile(getTemporaryFile(String.format(PROGUARD_ZIP, proguardVersion)).toFile()); + ZipEntry zipJarEntry = zipFile.getEntry(String.format("proguard-%s/lib/proguard.jar", proguardVersion)); write(zipFile.getInputStream(zipJarEntry), proguardJar); zipFile.close(); } } - private String getJavaBinPathForProguard() throws Exception { - String path; - try { - path = findJavaPathByGradleConfig(); - if (path != null) return path; - } catch (Exception ex) { - System.err.println("Unable to find java by javaCompile options"); - ex.printStackTrace(); + private JavaLauncher getJavaLauncherForProguard() { + var toolchains = getProject().getExtensions().getByType(JavaToolchainService.class); + var toolchain = toolchains.launcherFor((spec) -> { + spec.getLanguageVersion().set(JavaLanguageVersion.of(getProject().findProperty("java_version").toString())); + }).getOrNull(); + + if (toolchain == null) { + throw new IllegalStateException("Java toolchain not found"); } - path = findJavaByGradleCurrentRuntime(); - if (path != null) return path; - - try { - path = findJavaByJavaHome(); - if (path != null) return path; - } catch (Exception ex) { - System.err.println("Unable to find java by JAVA_HOME"); - ex.printStackTrace(); - } - - throw new Exception("Unable to find java to determine ProGuard libraryjars. Please specify forkOptions.executable in javaCompile," + - " JAVA_HOME environment variable, or make sure to run Gradle with the correct JDK (a v1.8 only)"); - } - - private String findJavaByGradleCurrentRuntime() { - String path = Jvm.current().getJavaExecutable().getAbsolutePath(); - System.out.println("Using Gradle's runtime Java for ProGuard"); - return path; - } - - private String findJavaByJavaHome() { - final String javaHomeEnv = System.getenv("JAVA_HOME"); - if (javaHomeEnv != null) { - String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath(); - System.out.println("Detected Java path by JAVA_HOME"); - return path; - } - return null; - } - - private String findJavaPathByGradleConfig() { - final TaskCollection javaCompiles = super.getProject().getTasks().withType(JavaCompile.class); - - final JavaCompile compileTask = javaCompiles.iterator().next(); - final ForkOptions forkOptions = compileTask.getOptions().getForkOptions(); - - if (forkOptions != null) { - String javacPath = forkOptions.getExecutable(); - if (javacPath != null) { - File javacFile = new File(javacPath); - if (javacFile.exists()) { - File[] maybeJava = javacFile.getParentFile().listFiles((dir, name) -> name.equals("java")); - if (maybeJava != null && maybeJava.length > 0) { - String path = maybeJava[0].getAbsolutePath(); - System.out.println("Detected Java path by forkOptions"); - return path; - } - } - } - } - return null; - } - - private boolean validateJavaVersion(String java) { - //TODO: fix for j16 -// final JavaVersion javaVersion = new DefaultJvmVersionDetector(new DefaultExecActionFactory(new IdentityFileResolver())).getJavaVersion(java); -// -// if (!javaVersion.getMajorVersion().equals("8")) { -// System.out.println("Failed to validate Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars"); -// // throw new RuntimeException("Java version incorrect: " + javaVersion.getMajorVersion() + " for " + java); -// return false; -// } -// -// System.out.println("Validated Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars"); - return true; + return toolchain; } private void generateConfigs() throws Exception { @@ -284,13 +215,8 @@ public class ProguardTask extends BaritoneGradleTask { } catch (IOException ignored) {} } - public void setUrl(String url) { - this.url = url; - } - - - public void setExtract(String extract) { - this.extract = extract; + public void setProguardVersion(String url) { + this.proguardVersion = url; } private void runProguard(Path config) throws Exception { @@ -299,39 +225,15 @@ public class ProguardTask extends BaritoneGradleTask { Files.delete(this.proguardOut); } - // Make paths relative to work directory; fixes spaces in path to config, @"" doesn't work Path workingDirectory = getTemporaryFile(""); - Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR)); - config = workingDirectory.relativize(config); - // Honestly, if you still have spaces in your path at this point, you're SOL. + getProject().javaexec(spec -> { + spec.workingDir(workingDirectory.toFile()); + spec.args("@" + workingDirectory.relativize(config)); + spec.classpath(getTemporaryFile(String.format(PROGUARD_JAR, proguardVersion))); - Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString()) - .directory(workingDirectory.toFile()) // Set the working directory to the temporary folder] - .start(); - - // We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this - this.printOutputLog(p.getInputStream(), System.out); - this.printOutputLog(p.getErrorStream(), System.err); - - // Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception - int exitCode = p.waitFor(); - if (exitCode != 0) { - Thread.sleep(1000); - throw new IllegalStateException("Proguard exited with code " + exitCode); - } + spec.executable(getJavaLauncherForProguard().getExecutablePath().getAsFile()); + }).assertNormalExitValue().rethrowFailure(); } - private void printOutputLog(InputStream stream, PrintStream outerr) { - new Thread(() -> { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { - String line; - while ((line = reader.readLine()) != null) { - outerr.println(line); - } - } catch (Exception e) { - e.printStackTrace(); - } - }).start(); - } } diff --git a/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java b/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java index 781aaec24..04bd74947 100644 --- a/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java +++ b/buildSrc/src/main/java/baritone/gradle/util/Determinizer.java @@ -71,10 +71,10 @@ public class Determinizer { ByteArrayOutputStream cancer = new ByteArrayOutputStream(); copy(jarFile.getInputStream(entry), cancer); String manifest = new String(cancer.toByteArray()); - if (!manifest.contains("baritone.launch.BaritoneTweaker")) { + if (!manifest.contains("baritone.launch.tweaker.BaritoneTweaker")) { throw new IllegalStateException("unable to replace"); } - manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker"); + manifest = manifest.replace("baritone.launch.tweaker.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker"); jos.write(manifest.getBytes()); } else { copy(jarFile.getInputStream(entry), jos); diff --git a/fabric/build.gradle b/fabric/build.gradle index bf3e6c38d..c607dbab2 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -78,8 +78,7 @@ components.java { } task proguard(type: ProguardTask) { - url 'https://github.com/Guardsquare/proguard/releases/download/v7.4.2/proguard-7.4.2.zip' - extract 'proguard-7.4.2/lib/proguard.jar' + proguardVersion "7.4.2" compType "fabric" } diff --git a/forge/build.gradle b/forge/build.gradle index 46c941a62..e7ba6a06c 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -95,8 +95,7 @@ components.java { } task proguard(type: ProguardTask) { - url 'https://github.com/Guardsquare/proguard/releases/download/v7.4.2/proguard-7.4.2.zip' - extract 'proguard-7.4.2/lib/proguard.jar' + proguardVersion "7.4.2" compType "forge" } diff --git a/gradle.properties b/gradle.properties index 9a7b5417c..dbfe4efb0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,8 @@ mod_version=1.11.0 maven_group=baritone archives_base_name=baritone +java_version=21 + minecraft_version=1.21 forge_version=51.0.16 diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 818999bf5..9f521ca11 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -105,8 +105,7 @@ components.java { } task proguard(type: ProguardTask) { - url 'https://github.com/Guardsquare/proguard/releases/download/v7.4.2/proguard-7.4.2.zip' - extract 'proguard-7.4.2/lib/proguard.jar' + proguardVersion "7.4.2" compType "neoforge" } diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 8609a0a88..1812fe486 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); @@ -973,6 +973,11 @@ public final class Settings { */ public final Setting replantNetherWart = new Setting<>(false); + /** + * Farming will scan for at most this many blocks. + */ + public final Setting farmMaxScanSize = new Setting<>(256); + /** * When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too. *

diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java index 444af26c3..d3eb8d831 100644 --- a/src/api/java/baritone/api/utils/SettingsUtil.java +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -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 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); } diff --git a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java index 34f39aee9..7a77d4849 100644 --- a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java +++ b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java @@ -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); } diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index bccb021c6..b38ba767f 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -42,6 +42,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.AirBlock; +import net.minecraft.world.level.block.BambooStalkBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.BonemealableBlock; @@ -95,6 +96,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro Items.NETHER_WART, Items.COCOA_BEANS, Blocks.SUGAR_CANE.asItem(), + Blocks.BAMBOO.asItem(), Blocks.CACTUS.asItem() ); @@ -137,6 +139,15 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro return true; } }, + BAMBOO(Blocks.BAMBOO, null) { + @Override + public boolean readyToHarvest(Level world, BlockPos pos, BlockState state) { + if (Baritone.settings().replantCrops.value) { + return world.getBlockState(pos.below()).getBlock() instanceof BambooStalkBlock; + } + return true; + } + }, CACTUS(Blocks.CACTUS, null) { @Override public boolean readyToHarvest(Level world, BlockPos pos, BlockState state) { @@ -191,20 +202,20 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { - ArrayList scan = new ArrayList<>(); - for (Harvest harvest : Harvest.values()) { - scan.add(harvest.block); - } - if (Baritone.settings().replantCrops.value) { - scan.add(Blocks.FARMLAND); - scan.add(Blocks.JUNGLE_LOG); - if (Baritone.settings().replantNetherWart.value) { - scan.add(Blocks.SOUL_SAND); - } - } - if (Baritone.settings().mineGoalUpdateInterval.value != 0 && tickCount++ % Baritone.settings().mineGoalUpdateInterval.value == 0) { - Baritone.getExecutor().execute(() -> locations = BaritoneAPI.getProvider().getWorldScanner().scanChunkRadius(ctx, scan, 256, 10, 10)); + ArrayList scan = new ArrayList<>(); + for (Harvest harvest : Harvest.values()) { + scan.add(harvest.block); + } + if (Baritone.settings().replantCrops.value) { + scan.add(Blocks.FARMLAND); + scan.add(Blocks.JUNGLE_LOG); + if (Baritone.settings().replantNetherWart.value) { + scan.add(Blocks.SOUL_SAND); + } + } + + Baritone.getExecutor().execute(() -> locations = BaritoneAPI.getProvider().getWorldScanner().scanChunkRadius(ctx, scan, Baritone.settings().farmMaxScanSize.value, 10, 10)); } if (locations == null) { return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); @@ -256,7 +267,12 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } baritone.getInputOverrideHandler().clearAllKeys(); + BetterBlockPos playerPos = ctx.playerFeet(); + double blockReachDistance = ctx.playerController().getBlockReachDistance(); for (BlockPos pos : toBreak) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { + continue; + } Optional rot = RotationUtils.reachable(ctx, pos); if (rot.isPresent() && isSafeToCancel) { baritone.getLookBehavior().updateTarget(rot.get(), true); @@ -270,10 +286,13 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro ArrayList both = new ArrayList<>(openFarmland); both.addAll(openSoulsand); for (BlockPos pos : both) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { + continue; + } boolean soulsand = openSoulsand.contains(pos); - Optional rot = RotationUtils.reachableOffset(ctx, pos, new Vec3(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance(), false); + Optional rot = RotationUtils.reachableOffset(ctx, pos, new Vec3(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), blockReachDistance, false); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) { - HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance()); + HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), blockReachDistance); if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == Direction.UP) { baritone.getLookBehavior().updateTarget(rot.get(), true); if (ctx.isLookingAt(pos)) { @@ -284,14 +303,17 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } } for (BlockPos pos : openLog) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { + continue; + } for (Direction dir : Direction.Plane.HORIZONTAL) { if (!(ctx.world().getBlockState(pos.relative(dir)).getBlock() instanceof AirBlock)) { continue; } Vec3 faceCenter = Vec3.atCenterOf(pos).add(Vec3.atLowerCornerOf(dir.getNormal()).scale(0.5)); - Optional rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, ctx.playerController().getBlockReachDistance(), false); + Optional rot = RotationUtils.reachableOffset(ctx, pos, faceCenter, blockReachDistance, false); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isCocoa)) { - HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance()); + HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), blockReachDistance); if (result instanceof BlockHitResult && ((BlockHitResult) result).getDirection() == dir) { baritone.getLookBehavior().updateTarget(rot.get(), true); if (ctx.isLookingAt(pos)) { @@ -303,6 +325,9 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } } for (BlockPos pos : bonemealable) { + if (playerPos.distSqr(pos) > blockReachDistance * blockReachDistance) { + continue; + } Optional rot = RotationUtils.reachable(ctx, pos); if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, this::isBoneMeal)) { baritone.getLookBehavior().updateTarget(rot.get(), true); @@ -359,6 +384,14 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro } } } + if (goalz.isEmpty()) { + logDirect("Farm failed"); + if (Baritone.settings().notificationOnFarmFail.value) { + logNotification("Farm failed", true); + } + onLostControl(); + return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); + } return new PathingCommand(new GoalComposite(goalz.toArray(new Goal[0])), PathingCommandType.SET_GOAL_AND_PATH); } diff --git a/src/main/java/baritone/utils/BlockBreakHelper.java b/src/main/java/baritone/utils/BlockBreakHelper.java index 3332aec76..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; @@ -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; } } } diff --git a/src/main/java/baritone/utils/GuiClick.java b/src/main/java/baritone/utils/GuiClick.java index 37259278b..488f13d25 100644 --- a/src/main/java/baritone/utils/GuiClick.java +++ b/src/main/java/baritone/utils/GuiClick.java @@ -75,13 +75,11 @@ public class GuiClick extends Screen implements Helper { Vec3 far = toWorld(mx, my, 1); // "Use 0.945 that's what stack overflow says" - leijurv if (near != null && far != null) { - /// Vec3 viewerPos = new Vec3(PathRenderer.posX(), PathRenderer.posY(), PathRenderer.posZ()); LocalPlayer player = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().player(); HitResult result = player.level().clip(new ClipContext(near.add(viewerPos), far.add(viewerPos), ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)); if (result != null && result.getType() == HitResult.Type.BLOCK) { currentMouseOver = ((BlockHitResult) result).getBlockPos(); - System.out.println("currentMouseOver = " + currentMouseOver); } } } diff --git a/src/main/java/baritone/utils/ToolSet.java b/src/main/java/baritone/utils/ToolSet.java index 4579a5b45..464fa40f4 100644 --- a/src/main/java/baritone/utils/ToolSet.java +++ b/src/main/java/baritone/utils/ToolSet.java @@ -188,7 +188,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; } diff --git a/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java b/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java index 72e6f7ee3..55fa43316 100644 --- a/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java +++ b/src/main/java/baritone/utils/accessor/IPlayerControllerMP.java @@ -23,7 +23,11 @@ public interface IPlayerControllerMP { void setIsHittingBlock(boolean isHittingBlock); + boolean isHittingBlock(); + BlockPos getCurrentBlock(); 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..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; @@ -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 diff --git a/tweaker/build.gradle b/tweaker/build.gradle index 71a025ca8..feb9dd039 100644 --- a/tweaker/build.gradle +++ b/tweaker/build.gradle @@ -26,7 +26,7 @@ plugins { unimined.minecraft { runs.client = { mainClass = "net.minecraft.launchwrapper.Launch" - args.addAll(["--tweakClass", "baritone.launch.BaritoneTweaker"]) + args.addAll(["--tweakClass", "baritone.launch.tweaker.BaritoneTweaker"]) } } @@ -94,8 +94,7 @@ jar { } task proguard(type: ProguardTask) { - url 'https://github.com/Guardsquare/proguard/releases/download/v7.4.2/proguard-7.4.2.zip' - extract 'proguard-7.4.2/lib/proguard.jar' + proguardVersion "7.4.2" } task createDist(type: CreateDistTask, dependsOn: proguard) diff --git a/tweaker/src/main/java/baritone/launch/BaritoneTweaker.java b/tweaker/src/main/java/baritone/launch/tweaker/BaritoneTweaker.java similarity index 98% rename from tweaker/src/main/java/baritone/launch/BaritoneTweaker.java rename to tweaker/src/main/java/baritone/launch/tweaker/BaritoneTweaker.java index b9db9b6a5..694aef533 100644 --- a/tweaker/src/main/java/baritone/launch/BaritoneTweaker.java +++ b/tweaker/src/main/java/baritone/launch/tweaker/BaritoneTweaker.java @@ -15,7 +15,7 @@ * along with Baritone. If not, see . */ -package baritone.launch; +package baritone.launch.tweaker; import io.github.impactdevelopment.simpletweaker.SimpleTweaker; import net.minecraft.launchwrapper.Launch;