Compare commits

...

61 Commits

Author SHA1 Message Date
Leijurv 22bb9f0ec8 v1.0.0-hotfix-3 2018-11-12 09:07:48 -08:00
Leijurv 654ac1075a wait a tick until objectMouseOver matches, fixes #254 2018-11-10 09:26:32 -08:00
Leijurv ffc050668b fix cherry pick merge errors 2018-11-07 10:01:58 -08:00
Leijurv 80f65452e1 make sure to pick up dropped items while mining, fixes #170 2018-11-07 09:56:47 -08:00
Leijurv c614d7ec6a fix stupid minebehavior bug 2018-11-03 20:25:09 -07:00
Leijurv c37a5ba956 revamp readme 2018-11-02 16:23:57 -07:00
Leijurv da5969c2fd shouldnt have taken this long to figure that out 2018-11-01 20:58:48 -07:00
Leijurv 990107a1fa simplify 2018-11-01 20:27:34 -07:00
Leijurv 42eb86b624 useless check? 2018-11-01 15:41:53 -07:00
Leijurv b65a199e54 move all checks from BlockStateInterface to MovementHelper 2018-11-01 15:36:32 -07:00
Leijurv 88e3bcdf63 what 2018-11-01 15:32:58 -07:00
Leijurv 0fbfa32e6b fix exception in pathfinder 2018-11-01 15:30:33 -07:00
Leijurv 20405716bc fix impact 4.4 compatibility and add help message 2018-11-01 14:07:08 -07:00
Leijurv 8da7406e8f green 2018-10-31 20:37:18 -07:00
Leijurv 97fd3df8f7 minecraft version badge 2018-10-30 19:06:42 -07:00
Leijurv b9b33b5351 move calculation context construction to main thread 2018-10-29 18:58:59 -07:00
Brady 19ecb1bbb3 Merge LocationTrackingBehavior into MemoryBehavior
Fixes #242
2018-10-29 16:43:03 -05:00
Leijurv f6043f4ac6 changed wording 2018-10-28 16:44:56 -07:00
Brady ed1941abdb Fix desynchronized allowFlying state 2018-10-28 18:38:23 -05:00
Leijurv 24d24728dc intellij be like 2018-10-28 16:05:08 -07:00
Leijurv 77db4cd19f codacy 2018-10-28 15:24:52 -07:00
Leijurv adbb03e5cb unused lol 2018-10-28 15:24:23 -07:00
Leijurv f0226f1ea7 brady doesn't know how to do imports 2018-10-28 15:23:34 -07:00
Leijurv be5df2677b finally add shulkers lol 2018-10-28 13:55:03 -07:00
Brady 3d4a856bb2 Remove unnecessary casts 2018-10-27 23:21:30 -05:00
Leijurv 1b1233d26a only one singleton 2018-10-27 18:45:17 -07:00
Leijurv c4b0e0a810 codady submission complete 2018-10-27 16:18:03 -07:00
Leijurv 1dee8ef355 completely submitting to codacy 2018-10-27 14:41:25 -07:00
Leijurv 8cee173f92 appease codacy some more 2018-10-27 14:16:34 -07:00
Brady 19e0e6d962 Feed codacy 2018-10-27 14:38:10 -05:00
Leijurv ef8fd70475 add some more badges for no reason lol 2018-10-27 09:25:53 -07:00
Leijurv 6df05f4b7f add link to my vid 2018-10-27 08:37:30 -07:00
Brady 4e1491a0cc Rename xrayFor to searchWorld 2018-10-26 13:30:16 -05:00
leijurv 55091154c4 start on legitMine 2018-10-25 21:22:00 -07:00
leijurv a0b1cb2993 preliminary refactoring 2018-10-25 20:09:06 -07:00
Leijurv 7617081637 no longer needed 2018-10-24 23:22:19 -07:00
Leijurv 96e7f37799 add link to adovin's video 2018-10-23 20:41:35 -07:00
Leijurv a0bf22de86 Merge pull request #233 from ave4224/toolkit
Toolkit fixes
2018-10-22 21:43:42 -07:00
ave4224 9a1aecc002 tool set, fixes #227 2018-10-23 00:41:59 -04:00
Brady ad941fcbb2 Clarify anti nudge 2018-10-22 18:02:18 -05:00
Leijurv e5ca30dc26 forgot that one 2018-10-22 14:04:19 -07:00
Leijurv a23eadf5cf Merge pull request #235 from 0-x-2-2/patch-1
Fixed serious issue.
2018-10-22 12:46:17 -07:00
Leijurv 82417f4f85 comment to explain weird thing 2018-10-22 12:42:08 -07:00
0x22 af788133c2 Fixed serious issue.
Determinizer description was incorrect.
2018-10-22 15:42:05 -04:00
Leijurv a6dc156a79 bump version to match build gradle 2018-10-21 14:24:23 -07:00
Leijurv 25bebdc172 leftClickCounter shadow appears to be unneeded 2018-10-20 20:33:49 -07:00
Leijurv b55d96169f update some documentation 2018-10-19 21:15:37 -07:00
Leijurv 1a809fa7a3 dispatch path events from main thread instead of calculation thread 2018-10-18 15:04:40 -07:00
Leijurv 313a5fddbe add release badge 2018-10-18 14:36:14 -07:00
Leijurv 732d806820 allow cutting onto next path one movement earlier 2018-10-17 12:16:03 -07:00
Leijurv 11ed8a2f21 rearrange fields and constructors 2018-10-16 20:05:18 -07:00
Leijurv 3aa8f51015 print shasums on build 2018-10-16 17:00:37 -07:00
Leijurv 85b038dada v1.0.0-hotfix-2 2018-10-16 16:03:51 -07:00
Leijurv dd25527a62 pillar fixes for ncp 2018-10-16 14:21:27 -07:00
Leijurv ac372bc6fc v1.0.0-hotfix-1 2018-10-16 11:32:44 -07:00
Leijurv 63ce4fe0bd don't crash on empty region 2018-10-16 11:32:27 -07:00
Leijurv 398169f68e special case for damn daniel 2018-10-16 11:13:35 -07:00
Leijurv 46a24af373 cancel chat event 2018-10-16 11:13:08 -07:00
Leijurv 0cd9bb658f keep ExampleBaritoneControl 2018-10-16 11:04:49 -07:00
Leijurv b0678fd259 better control 2018-10-16 10:47:44 -07:00
Leijurv 9cb4a1779e fix placement rotation during parkour 2018-10-15 20:37:10 -07:00
43 changed files with 827 additions and 642 deletions
+4 -4
View File
@@ -15,10 +15,10 @@ RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr
COPY . /code COPY . /code
# this .deb is specially patched to support lwjgl
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i /code/scripts/xvfb_1.16.4-1_amd64.deb
WORKDIR /code WORKDIR /code
# this .deb is specially patched to support lwjgl
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
RUN ./gradlew build RUN ./gradlew build
+4 -6
View File
@@ -3,6 +3,8 @@ Impact 4.4 has Baritone included.
These instructions apply to Impact 4.3 (and potentially other hacked clients). These instructions apply to Impact 4.3 (and potentially other hacked clients).
To run Baritone on Vanilla, just follow the instructions in the README (it's `./gradlew runClient`).
## An Introduction ## An Introduction
There are some basic steps to getting Baritone setup with Impact. There are some basic steps to getting Baritone setup with Impact.
@@ -12,7 +14,7 @@ There are some basic steps to getting Baritone setup with Impact.
- How to use Baritone - How to use Baritone
## Acquiring a build of Baritone ## Acquiring a build of Baritone
There are 3 methods of acquiring a build of Baritone (While it is still in development) There are two methods of acquiring a build of Baritone
### Official Release (Not always up to date) ### Official Release (Not always up to date)
https://github.com/cabaletta/baritone/releases https://github.com/cabaletta/baritone/releases
@@ -33,10 +35,6 @@ command line
- Mac/Linux: ``./gradlew build`` - Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar`` - The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
### Cutting Edge Release
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
from his Jenkins server, found <a href="https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/">here</a>.
## Placing Baritone in the libraries directory ## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a> ``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
that contains all of the dependencies that are required from the game and some mods. This is where we will be that contains all of the dependencies that are required from the game and some mods. This is where we will be
@@ -83,7 +81,7 @@ The final step is "registering" the Baritone library with Impact, so that it loa
"name": "cabaletta:baritone:X.Y.Z" "name": "cabaletta:baritone:X.Y.Z"
}, },
{ {
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.1", "name": "com.github.ImpactDevelopment:SimpleTweaker:1.2",
"url": "https://impactdevelopment.github.io/maven/" "url": "https://impactdevelopment.github.io/maven/"
}, },
``` ```
+18 -15
View File
@@ -1,14 +1,16 @@
# Baritone # Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone) [![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases)
[![License](https://img.shields.io/github/license/cabaletta/baritone.svg)](LICENSE) [![License](https://img.shields.io/github/license/cabaletta/baritone.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
<!-- Unofficial Jenkins: [![Build Status](https://plutiejenkins.leijurv.com/job/baritone/badge/icon)](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/) --> [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
Here are some links to help to get started: Here are some links to help to get started:
@@ -20,29 +22,30 @@ There's also some useful information down below
# Setup # Setup
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle task `setupDecompWorkspace`
- Run the Gradle task `genIntellijRuns`
- Refresh the Gradle project (or just restart IntelliJ)
- Select the "Minecraft Client" launch config and run
## Command Line ## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`. On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Running Baritone: Running Baritone:
``` ```
$ gradlew run $ gradlew runClient
``` ```
Setting up for IntelliJ: Building Baritone:
``` ```
$ gradlew setupDecompWorkspace $ gradlew build
$ gradlew --refresh-dependencies
$ gradlew genIntellijRuns
``` ```
For example, to replace out Impact 4.4's Baritone build with a customized one, build Baritone as above then copy `dist/baritone-api-$VERSION.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle task `setupDecompWorkspace`
- Run the Gradle task `genIntellijRuns`
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
- Select the "Minecraft Client" launch config
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
# Chat control # Chat control
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java) [Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
+1 -1
View File
@@ -16,7 +16,7 @@
*/ */
group 'baritone' group 'baritone'
version '1.0.0' version '1.0.0-hotfix-3'
buildscript { buildscript {
repositories { repositories {
@@ -34,9 +34,9 @@ import java.util.List;
*/ */
class BaritoneGradleTask extends DefaultTask { class BaritoneGradleTask extends DefaultTask {
static final JsonParser PARSER = new JsonParser(); protected static final JsonParser PARSER = new JsonParser();
static final String protected static final String
PROGUARD_ZIP = "proguard.zip", PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar", PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro", PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
@@ -54,10 +54,10 @@ class BaritoneGradleTask extends DefaultTask {
ARTIFACT_API = "%s-api-%s.jar", ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar"; ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
String artifactName, artifactVersion; protected String artifactName, artifactVersion;
Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut; protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
void verifyArtifacts() throws Exception { protected void verifyArtifacts() throws IllegalStateException {
this.artifactName = getProject().getName(); this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString(); this.artifactVersion = getProject().getVersion().toString();
@@ -69,34 +69,34 @@ class BaritoneGradleTask extends DefaultTask {
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH); this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
if (!Files.exists(this.artifactPath)) { if (!Files.exists(this.artifactPath)) {
throw new Exception("Artifact not found! Run build first!"); throw new IllegalStateException("Artifact not found! Run build first!");
} }
} }
void write(InputStream stream, Path file) throws Exception { protected void write(InputStream stream, Path file) throws Exception {
if (Files.exists(file)) { if (Files.exists(file)) {
Files.delete(file); Files.delete(file);
} }
Files.copy(stream, file); Files.copy(stream, file);
} }
String formatVersion(String string) { protected String formatVersion(String string) {
return String.format(string, this.artifactName, this.artifactVersion); return String.format(string, this.artifactName, this.artifactVersion);
} }
Path getRelativeFile(String file) { protected Path getRelativeFile(String file) {
return Paths.get(new File(file).getAbsolutePath()); return Paths.get(new File(file).getAbsolutePath());
} }
Path getTemporaryFile(String file) { protected Path getTemporaryFile(String file) {
return Paths.get(new File(getTemporaryDir(), file).getAbsolutePath()); return Paths.get(new File(getTemporaryDir(), file).getAbsolutePath());
} }
Path getBuildFile(String file) { protected Path getBuildFile(String file) {
return getRelativeFile("build/libs/" + file); return getRelativeFile("build/libs/" + file);
} }
JsonElement readJson(List<String> lines) { protected JsonElement readJson(List<String> lines) {
return PARSER.parse(String.join("\n", lines)); return PARSER.parse(String.join("\n", lines));
} }
} }
@@ -62,6 +62,8 @@ public class CreateDistTask extends BaritoneGradleTask {
.map(path -> sha1(path) + " " + path.getFileName().toString()) .map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList()); .collect(Collectors.toList());
shasum.forEach(System.out::println);
// Write the checksums to a file // Write the checksums to a file
Files.write(getRelativeFile("dist/checksums.txt"), shasum); Files.write(getRelativeFile("dist/checksums.txt"), shasum);
} }
@@ -74,7 +76,7 @@ public class CreateDistTask extends BaritoneGradleTask {
return DatatypeConverter.printHexBinary(SHA1_DIGEST.digest(Files.readAllBytes(path))).toLowerCase(); return DatatypeConverter.printHexBinary(SHA1_DIGEST.digest(Files.readAllBytes(path))).toLowerCase();
} catch (Exception e) { } catch (Exception e) {
// haha no thanks // haha no thanks
throw new RuntimeException(e); throw new IllegalStateException(e);
} }
} }
} }
@@ -241,7 +241,7 @@ public class ProguardTask extends BaritoneGradleTask {
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception // Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor(); int exitCode = p.waitFor();
if (exitCode != 0) { if (exitCode != 0) {
throw new Exception("Proguard exited with code " + exitCode); throw new IllegalStateException("Proguard exited with code " + exitCode);
} }
} }
@@ -32,7 +32,7 @@ import java.util.jar.JarOutputStream;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 0. * Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 42069.
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file. * This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
* *
* @author leijurv * @author leijurv
+5
View File
@@ -13,9 +13,14 @@
-repackageclasses 'baritone' -repackageclasses 'baritone'
-keep class baritone.api.** { *; } # this is the keep api -keep class baritone.api.** { *; } # this is the keep api
# service provider needs these class names
-keep class baritone.BaritoneProvider -keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider -keep class baritone.api.IBaritoneProvider
# hack
-keep class baritone.utils.ExampleBaritoneControl { *; }
# setting names are reflected from field names, so keep field names # setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings { -keepclassmembers class baritone.api.Settings {
public <fields>; public <fields>;
+17
View File
@@ -376,6 +376,11 @@ public class Settings {
*/ */
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5); public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
/**
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
*/
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
/** /**
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore. * Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
* <p> * <p>
@@ -396,6 +401,18 @@ public class Settings {
*/ */
public Setting<Integer> axisHeight = new Setting<>(120); public Setting<Integer> axisHeight = new Setting<>(120);
/**
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
* couldn't. If you don't want it to look like you're X-Raying, turn this off
*/
public Setting<Boolean> legitMine = new Setting<>(false);
/**
* What Y level to go to for legit strip mining
*/
public Setting<Integer> legitMineYLevel = new Setting<>(11);
/** /**
* When mining block of a certain type, try to mine two at once instead of one. * When mining block of a certain type, try to mine two at once instead of one.
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks * If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
@@ -30,14 +30,13 @@ import java.util.Optional;
* @since 8/25/2018 * @since 8/25/2018
*/ */
public final class RayTraceUtils { public final class RayTraceUtils {
private RayTraceUtils() {}
/** /**
* The {@link Minecraft} instance * The {@link Minecraft} instance
*/ */
private static final Minecraft mc = Minecraft.getMinecraft(); private static final Minecraft mc = Minecraft.getMinecraft();
private RayTraceUtils() {}
/** /**
* Simulates a "vanilla" raytrace. A RayTraceResult returned by this method * Simulates a "vanilla" raytrace. A RayTraceResult returned by this method
* will be that of the next render pass given that the local player's yaw and * will be that of the next render pass given that the local player's yaw and
@@ -46,7 +45,7 @@ public final class RayTraceUtils {
* thing to achieve the desired outcome (whether it is hitting and entity or placing * thing to achieve the desired outcome (whether it is hitting and entity or placing
* a block) can be done just by modifying user input. * a block) can be done just by modifying user input.
* *
* @param yaw The yaw to raytrace with * @param yaw The yaw to raytrace with
* @param pitch The pitch to raytrace with * @param pitch The pitch to raytrace with
* @return The calculated raytrace result * @return The calculated raytrace result
*/ */
@@ -31,8 +31,6 @@ import java.util.Optional;
*/ */
public final class RotationUtils { public final class RotationUtils {
private RotationUtils() {}
/** /**
* The {@link Minecraft} instance * The {@link Minecraft} instance
*/ */
@@ -60,6 +58,8 @@ public final class RotationUtils {
new Vec3d(1, 0.5, 0.5) // East new Vec3d(1, 0.5, 0.5) // East
}; };
private RotationUtils() {}
/** /**
* Clamps the specified pitch value between -90 and 90. * Clamps the specified pitch value between -90 and 90.
* *
@@ -177,6 +177,8 @@ public final class RotationUtils {
* is by setting the desired pitch to the current pitch * is by setting the desired pitch to the current pitch
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's * setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
* just what it currently is * just what it currently is
*
* or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level
*/ */
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F)); return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
} }
@@ -218,10 +220,8 @@ public final class RotationUtils {
if (result.getBlockPos().equals(pos)) { if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation); return Optional.of(rotation);
} }
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire) { if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) {
if (result.getBlockPos().equals(pos.down())) { return Optional.of(rotation);
return Optional.of(rotation);
}
} }
} }
return Optional.empty(); return Optional.empty();
+12 -18
View File
@@ -30,21 +30,19 @@ import net.minecraft.util.math.Vec3d;
* @since 10/13/2018 * @since 10/13/2018
*/ */
public final class VecUtils { public final class VecUtils {
private VecUtils() {}
/** /**
* The {@link Minecraft} instance * The {@link Minecraft} instance
*/ */
private static final Minecraft mc = Minecraft.getMinecraft(); private static final Minecraft mc = Minecraft.getMinecraft();
private VecUtils() {}
/** /**
* Calculates the center of the block at the specified position's bounding box * Calculates the center of the block at the specified position's bounding box
* *
* @see #getBlockPosCenter(BlockPos)
*
* @param pos The block position * @param pos The block position
* @return The center of the block's bounding box * @return The center of the block's bounding box
* @see #getBlockPosCenter(BlockPos)
*/ */
public static Vec3d calculateBlockCenter(BlockPos pos) { public static Vec3d calculateBlockCenter(BlockPos pos) {
IBlockState b = mc.world.getBlockState(pos); IBlockState b = mc.world.getBlockState(pos);
@@ -68,10 +66,9 @@ public final class VecUtils {
* <p> * <p>
* TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos) * TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos)
* *
* @see #calculateBlockCenter(BlockPos)
*
* @param pos The block position * @param pos The block position
* @return The assumed center of the position * @return The assumed center of the position
* @see #calculateBlockCenter(BlockPos)
*/ */
public static Vec3d getBlockPosCenter(BlockPos pos) { public static Vec3d getBlockPosCenter(BlockPos pos) {
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5); return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
@@ -80,13 +77,12 @@ public final class VecUtils {
/** /**
* Gets the distance from the specified position to the assumed center of the specified block position. * Gets the distance from the specified position to the assumed center of the specified block position.
* *
* @see #getBlockPosCenter(BlockPos)
*
* @param pos The block position * @param pos The block position
* @param x The x pos * @param x The x pos
* @param y The y pos * @param y The y pos
* @param z The z pos * @param z The z pos
* @return The distance from the assumed block center to the position * @return The distance from the assumed block center to the position
* @see #getBlockPosCenter(BlockPos)
*/ */
public static double distanceToCenter(BlockPos pos, double x, double y, double z) { public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
Vec3d center = getBlockPosCenter(pos); Vec3d center = getBlockPosCenter(pos);
@@ -100,11 +96,10 @@ public final class VecUtils {
* Gets the distance from the specified entity's position to the assumed * Gets the distance from the specified entity's position to the assumed
* center of the specified block position. * center of the specified block position.
* *
* @see #getBlockPosCenter(BlockPos)
*
* @param entity The entity * @param entity The entity
* @param pos The block position * @param pos The block position
* @return The distance from the entity to the block's assumed center * @return The distance from the entity to the block's assumed center
* @see #getBlockPosCenter(BlockPos)
*/ */
public static double entityDistanceToCenter(Entity entity, BlockPos pos) { public static double entityDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ); return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ);
@@ -114,11 +109,10 @@ public final class VecUtils {
* Gets the distance from the specified entity's position to the assumed * Gets the distance from the specified entity's position to the assumed
* center of the specified block position, ignoring the Y axis. * center of the specified block position, ignoring the Y axis.
* *
* @see #getBlockPosCenter(BlockPos)
*
* @param entity The entity * @param entity The entity
* @param pos The block position * @param pos The block position
* @return The horizontal distance from the entity to the block's assumed center * @return The horizontal distance from the entity to the block's assumed center
* @see #getBlockPosCenter(BlockPos)
*/ */
public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) { public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ); return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ);
@@ -40,6 +40,8 @@ public class MixinEntityLivingBase {
) )
private void preJump(CallbackInfo ci) { private void preJump(CallbackInfo ci) {
EntityLivingBase _this = (EntityLivingBase) (Object) this; EntityLivingBase _this = (EntityLivingBase) (Object) this;
// This uses Class.isInstance instead of instanceof since proguard optimizes out the instanceof (since MixinEntityLivingBase could never be instanceof EntityLivingBase in normal java)
// but proguard isn't smart enough to optimize out this Class.isInstance =)
if (EntityPlayerSP.class.isInstance(_this)) if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP)); Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
} }
@@ -50,6 +52,7 @@ public class MixinEntityLivingBase {
) )
private void postJump(CallbackInfo ci) { private void postJump(CallbackInfo ci) {
EntityLivingBase _this = (EntityLivingBase) (Object) this; EntityLivingBase _this = (EntityLivingBase) (Object) this;
// See above
if (EntityPlayerSP.class.isInstance(_this)) if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP)); Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
} }
@@ -21,10 +21,13 @@ import baritone.Baritone;
import baritone.api.event.events.ChatEvent; import baritone.api.event.events.ChatEvent;
import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.type.EventState; import baritone.api.event.events.type.EventState;
import baritone.behavior.PathingBehavior;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.PlayerCapabilities;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/** /**
@@ -72,4 +75,16 @@ public class MixinEntityPlayerSP {
private void onPostUpdate(CallbackInfo ci) { private void onPostUpdate(CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST)); Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
} }
@Redirect(
method = "onLivingUpdate",
at = @At(
value = "FIELD",
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
)
)
private boolean isAllowFlying(PlayerCapabilities capabilities) {
PathingBehavior pathingBehavior = Baritone.INSTANCE.getPathingBehavior();
return (!pathingBehavior.isEnabled() || !pathingBehavior.isPathing()) && capabilities.allowFlying;
}
} }
@@ -22,9 +22,7 @@ import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.TickEvent; import baritone.api.event.events.TickEvent;
import baritone.api.event.events.WorldEvent; import baritone.api.event.events.WorldEvent;
import baritone.api.event.events.type.EventState; import baritone.api.event.events.type.EventState;
import baritone.behavior.PathingBehavior;
import baritone.utils.BaritoneAutoTest; import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
@@ -49,8 +47,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(Minecraft.class) @Mixin(Minecraft.class)
public class MixinMinecraft { public class MixinMinecraft {
@Shadow
private int leftClickCounter;
@Shadow @Shadow
public EntityPlayerSP player; public EntityPlayerSP player;
@Shadow @Shadow
@@ -62,7 +58,6 @@ public class MixinMinecraft {
) )
private void postInit(CallbackInfo ci) { private void postInit(CallbackInfo ci) {
Baritone.INSTANCE.init(); Baritone.INSTANCE.init();
ExampleBaritoneControl.INSTANCE.initAndRegister();
} }
@Inject( @Inject(
@@ -147,7 +142,7 @@ public class MixinMinecraft {
) )
) )
private boolean isAllowUserInput(GuiScreen screen) { private boolean isAllowUserInput(GuiScreen screen) {
return (PathingBehavior.INSTANCE.getCurrent() != null && PathingBehavior.INSTANCE.isEnabled() && player != null) || screen.allowUserInput; return (Baritone.INSTANCE.getPathingBehavior().getCurrent() != null && Baritone.INSTANCE.getPathingBehavior().isEnabled() && player != null) || screen.allowUserInput;
} }
@Inject( @Inject(
+55 -8
View File
@@ -18,11 +18,15 @@
package baritone; package baritone;
import baritone.api.BaritoneAPI; import baritone.api.BaritoneAPI;
import baritone.api.IBaritoneProvider;
import baritone.api.Settings; import baritone.api.Settings;
import baritone.api.event.listener.IGameEventListener; import baritone.api.event.listener.IGameEventListener;
import baritone.behavior.*; import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import baritone.event.GameEventHandler; import baritone.event.GameEventHandler;
import baritone.utils.BaritoneAutoTest; import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import baritone.utils.InputOverrideHandler; import baritone.utils.InputOverrideHandler;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@@ -40,7 +44,7 @@ import java.util.concurrent.TimeUnit;
* @author Brady * @author Brady
* @since 7/31/2018 10:50 PM * @since 7/31/2018 10:50 PM
*/ */
public enum Baritone { public enum Baritone implements IBaritoneProvider {
/** /**
* Singleton instance of this class * Singleton instance of this class
@@ -55,10 +59,16 @@ public enum Baritone {
private GameEventHandler gameEventHandler; private GameEventHandler gameEventHandler;
private InputOverrideHandler inputOverrideHandler; private InputOverrideHandler inputOverrideHandler;
private Settings settings; private Settings settings;
private List<Behavior> behaviors;
private File dir; private File dir;
private ThreadPoolExecutor threadPool; private ThreadPoolExecutor threadPool;
private List<Behavior> behaviors;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private FollowBehavior followBehavior;
private MineBehavior mineBehavior;
/** /**
* Whether or not Baritone is active * Whether or not Baritone is active
*/ */
@@ -81,12 +91,13 @@ public enum Baritone {
this.behaviors = new ArrayList<>(); this.behaviors = new ArrayList<>();
{ {
registerBehavior(PathingBehavior.INSTANCE); // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
registerBehavior(LookBehavior.INSTANCE); pathingBehavior = new PathingBehavior(this);
registerBehavior(MemoryBehavior.INSTANCE); lookBehavior = new LookBehavior(this);
registerBehavior(LocationTrackingBehavior.INSTANCE); memoryBehavior = new MemoryBehavior(this);
registerBehavior(FollowBehavior.INSTANCE); followBehavior = new FollowBehavior(this);
registerBehavior(MineBehavior.INSTANCE); mineBehavior = new MineBehavior(this);
new ExampleBaritoneControl(this);
} }
if (BaritoneAutoTest.ENABLE_AUTO_TEST) { if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
registerEventListener(BaritoneAutoTest.INSTANCE); registerEventListener(BaritoneAutoTest.INSTANCE);
@@ -127,6 +138,42 @@ public enum Baritone {
this.registerEventListener(behavior); this.registerEventListener(behavior);
} }
@Override
public FollowBehavior getFollowBehavior() {
return followBehavior;
}
@Override
public LookBehavior getLookBehavior() {
return lookBehavior;
}
@Override
public MemoryBehavior getMemoryBehavior() {
return memoryBehavior;
}
@Override
public MineBehavior getMineBehavior() {
return mineBehavior;
}
@Override
public PathingBehavior getPathingBehavior() {
return pathingBehavior;
}
@Override
public WorldProvider getWorldProvider() {
return WorldProvider.INSTANCE;
}
@Override
public WorldScanner getWorldScanner() {
return WorldScanner.INSTANCE;
}
@Override
public void registerEventListener(IGameEventListener listener) { public void registerEventListener(IGameEventListener listener) {
this.gameEventHandler.registerEventListener(listener); this.gameEventHandler.registerEventListener(listener);
} }
+7 -6
View File
@@ -22,11 +22,12 @@ import baritone.api.behavior.*;
import baritone.api.cache.IWorldProvider; import baritone.api.cache.IWorldProvider;
import baritone.api.cache.IWorldScanner; import baritone.api.cache.IWorldScanner;
import baritone.api.event.listener.IGameEventListener; import baritone.api.event.listener.IGameEventListener;
import baritone.behavior.*;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner; import baritone.cache.WorldScanner;
/** /**
* todo fix this cancer
*
* @author Brady * @author Brady
* @since 9/29/2018 * @since 9/29/2018
*/ */
@@ -34,27 +35,27 @@ public final class BaritoneProvider implements IBaritoneProvider {
@Override @Override
public IFollowBehavior getFollowBehavior() { public IFollowBehavior getFollowBehavior() {
return FollowBehavior.INSTANCE; return Baritone.INSTANCE.getFollowBehavior();
} }
@Override @Override
public ILookBehavior getLookBehavior() { public ILookBehavior getLookBehavior() {
return LookBehavior.INSTANCE; return Baritone.INSTANCE.getLookBehavior();
} }
@Override @Override
public IMemoryBehavior getMemoryBehavior() { public IMemoryBehavior getMemoryBehavior() {
return MemoryBehavior.INSTANCE; return Baritone.INSTANCE.getMemoryBehavior();
} }
@Override @Override
public IMineBehavior getMineBehavior() { public IMineBehavior getMineBehavior() {
return MineBehavior.INSTANCE; return Baritone.INSTANCE.getMineBehavior();
} }
@Override @Override
public IPathingBehavior getPathingBehavior() { public IPathingBehavior getPathingBehavior() {
return PathingBehavior.INSTANCE; return Baritone.INSTANCE.getPathingBehavior();
} }
@Override @Override
@@ -17,6 +17,7 @@
package baritone.behavior; package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IBehavior; import baritone.api.behavior.IBehavior;
/** /**
@@ -27,11 +28,18 @@ import baritone.api.behavior.IBehavior;
*/ */
public class Behavior implements IBehavior { public class Behavior implements IBehavior {
public final Baritone baritone;
/** /**
* Whether or not this behavior is enabled * Whether or not this behavior is enabled
*/ */
private boolean enabled = true; private boolean enabled = true;
protected Behavior(Baritone baritone) {
this.baritone = baritone;
baritone.registerBehavior(this);
}
/** /**
* Toggles the enabled state of this {@link Behavior}. * Toggles the enabled state of this {@link Behavior}.
* *
@@ -33,11 +33,11 @@ import net.minecraft.util.math.BlockPos;
*/ */
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper { public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
public static final FollowBehavior INSTANCE = new FollowBehavior();
private Entity following; private Entity following;
private FollowBehavior() {} public FollowBehavior(Baritone baritone) {
super(baritone);
}
@Override @Override
public void onTick(TickEvent event) { public void onTick(TickEvent event) {
@@ -56,9 +56,9 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get()); GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
pos = new BlockPos(g.getX(), following.posY, g.getZ()); pos = new BlockPos(g.getX(), following.posY, g.getZ());
} }
PathingBehavior.INSTANCE.setGoal(new GoalNear(pos, Baritone.settings().followRadius.get())); baritone.getPathingBehavior().setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
PathingBehavior.INSTANCE.revalidateGoal(); ((PathingBehavior) baritone.getPathingBehavior()).revalidateGoal();
PathingBehavior.INSTANCE.path(); baritone.getPathingBehavior().path();
} }
@Override @Override
@@ -73,7 +73,7 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
@Override @Override
public void cancel() { public void cancel() {
PathingBehavior.INSTANCE.cancel(); baritone.getPathingBehavior().cancel();
follow(null); follow(null);
} }
} }
@@ -1,53 +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 <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.api.event.events.BlockInteractEvent;
import baritone.cache.Waypoint;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.BlockBed;
/**
* A collection of event methods that are used to interact with Baritone's
* waypoint system. This class probably needs a better name.
*
* @see Waypoint
*
* @author Brady
* @since 8/22/2018
*/
public final class LocationTrackingBehavior extends Behavior implements Helper {
public static final LocationTrackingBehavior INSTANCE = new LocationTrackingBehavior();
private LocationTrackingBehavior() {}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
}
}
@Override
public void onPlayerDeath() {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
}
}
@@ -26,9 +26,6 @@ import baritone.api.utils.Rotation;
import baritone.utils.Helper; import baritone.utils.Helper;
public final class LookBehavior extends Behavior implements ILookBehavior, Helper { public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
public static final LookBehavior INSTANCE = new LookBehavior();
/** /**
* Target's values are as follows: * Target's values are as follows:
* <p> * <p>
@@ -49,7 +46,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
*/ */
private float lastYaw; private float lastYaw;
private LookBehavior() {} public LookBehavior(Baritone baritone) {
super(baritone);
}
@Override @Override
public void updateTarget(Rotation target, boolean force) { public void updateTarget(Rotation target, boolean force) {
@@ -17,14 +17,19 @@
package baritone.behavior; package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IMemoryBehavior; import baritone.api.behavior.IMemoryBehavior;
import baritone.api.behavior.memory.IRememberedInventory; import baritone.api.behavior.memory.IRememberedInventory;
import baritone.api.cache.IWorldData; import baritone.api.cache.IWorldData;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PacketEvent; import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent; import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.type.EventState; import baritone.api.event.events.type.EventState;
import baritone.cache.Waypoint;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper; import baritone.utils.Helper;
import net.minecraft.block.BlockBed;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet; import net.minecraft.network.Packet;
import net.minecraft.network.play.client.CPacketCloseWindow; import net.minecraft.network.play.client.CPacketCloseWindow;
@@ -43,11 +48,11 @@ import java.util.*;
*/ */
public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper { public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper {
public static MemoryBehavior INSTANCE = new MemoryBehavior();
private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>(); private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>();
private MemoryBehavior() {} public MemoryBehavior(Baritone baritone) {
super(baritone);
}
@Override @Override
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) { public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
@@ -114,6 +119,18 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
} }
} }
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
}
}
@Override
public void onPlayerDeath() {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
}
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) { private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
return this.getCurrentContainer().rememberedInventories.values().stream().filter(i -> i.windowId == windowId).findFirst(); return this.getCurrentContainer().rememberedInventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
} }
+122 -42
View File
@@ -20,21 +20,23 @@ package baritone.behavior;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.behavior.IMineBehavior; import baritone.api.behavior.IMineBehavior;
import baritone.api.event.events.TickEvent; import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.*;
import baritone.api.pathing.goals.GoalBlock; import baritone.api.utils.RotationUtils;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.cache.CachedChunk; import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker; import baritone.cache.ChunkPacker;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner; import baritone.cache.WorldScanner;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.Helper; import baritone.utils.Helper;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.EmptyChunk; import net.minecraft.world.chunk.EmptyChunk;
import java.util.*; import java.util.*;
@@ -46,14 +48,15 @@ import java.util.stream.Collectors;
* @author leijurv * @author leijurv
*/ */
public final class MineBehavior extends Behavior implements IMineBehavior, Helper { public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
public static final int ORE_LOCATIONS_COUNT = 64;
public static final MineBehavior INSTANCE = new MineBehavior();
private List<Block> mining; private List<Block> mining;
private List<BlockPos> locationsCache; private List<BlockPos> knownOreLocations;
private int quantity; private BlockPos branchPoint;
private int desiredQuantity;
private MineBehavior() {} public MineBehavior(Baritone baritone) {
super(baritone);
}
@Override @Override
public void onTick(TickEvent event) { public void onTick(TickEvent event) {
@@ -64,53 +67,80 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
if (mining == null) { if (mining == null) {
return; return;
} }
if (quantity > 0) { if (desiredQuantity > 0) {
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0); Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum(); int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
System.out.println("Currently have " + curr + " " + item); System.out.println("Currently have " + curr + " " + item);
if (curr >= quantity) { if (curr >= desiredQuantity) {
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1))); logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
cancel(); cancel();
return; return;
} }
} }
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get(); int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0) { if (mineGoalUpdateInterval != 0 && event.getCount() % mineGoalUpdateInterval == 0) {
if (event.getCount() % mineGoalUpdateInterval == 0) { Baritone.INSTANCE.getExecutor().execute(this::rescan);
Baritone.INSTANCE.getExecutor().execute(this::rescan); }
} if (Baritone.settings().legitMine.get()) {
addNearby();
} }
updateGoal(); updateGoal();
PathingBehavior.INSTANCE.revalidateGoal(); baritone.getPathingBehavior().revalidateGoal();
} }
private void updateGoal() { private void updateGoal() {
if (mining == null) { if (mining == null) {
return; return;
} }
List<BlockPos> locs = locationsCache; List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) { if (!locs.isEmpty()) {
locs = prune(new ArrayList<>(locs), mining, 64); List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, world());
PathingBehavior.INSTANCE.setGoal(coalesce(locs)); // can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
PathingBehavior.INSTANCE.path(); baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
locationsCache = locs; knownOreLocations = locs2;
return;
} }
// we don't know any ore locations at the moment
if (!Baritone.settings().legitMine.get()) {
return;
}
// only in non-Xray mode (aka legit mode) do we do this
if (branchPoint == null) {
int y = Baritone.settings().legitMineYLevel.get();
if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
// cool, path is over and we are at desired y
branchPoint = playerFeet();
} else {
baritone.getPathingBehavior().setGoalAndPath(new GoalYLevel(y));
return;
}
}
if (playerFeet().equals(branchPoint)) {
// TODO mine 1x1 shafts to either side
branchPoint = branchPoint.north(10);
}
baritone.getPathingBehavior().setGoalAndPath(new GoalBlock(branchPoint));
} }
private void rescan() { private void rescan() {
if (mining == null) { if (mining == null) {
return; return;
} }
List<BlockPos> locs = scanFor(mining, 64); if (Baritone.settings().legitMine.get()) {
return;
}
List<BlockPos> locs = searchWorld(mining, ORE_LOCATIONS_COUNT, world());
locs.addAll(droppedItemsScan(mining, world()));
if (locs.isEmpty()) { if (locs.isEmpty()) {
logDebug("No locations for " + mining + " known, cancelling"); logDebug("No locations for " + mining + " known, cancelling");
mine(0, (String[]) null); mine(0, (String[]) null);
return; return;
} }
locationsCache = locs; knownOreLocations = locs;
} }
public Goal coalesce(BlockPos loc, List<BlockPos> locs) { private static Goal coalesce(BlockPos loc, List<BlockPos> locs) {
if (!Baritone.settings().forceInternalMining.get()) { if (!Baritone.settings().forceInternalMining.get()) {
return new GoalTwoBlocks(loc); return new GoalTwoBlocks(loc);
} }
@@ -132,11 +162,30 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
} }
} }
public GoalComposite coalesce(List<BlockPos> locs) { public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
return new GoalComposite(locs.stream().map(loc -> coalesce(loc, locs)).toArray(Goal[]::new)); if (!Baritone.settings().mineScanDroppedItems.get()) {
return new ArrayList<>();
}
Set<Item> searchingFor = new HashSet<>();
for (Block block : mining) {
Item drop = block.getItemDropped(block.getDefaultState(), new Random(), 0);
Item ore = Item.getItemFromBlock(block);
searchingFor.add(drop);
searchingFor.add(ore);
}
List<BlockPos> ret = new ArrayList<>();
for (Entity entity : world.loadedEntityList) {
if (entity instanceof EntityItem) {
EntityItem ei = (EntityItem) entity;
if (searchingFor.contains(ei.getItem().getItem())) {
ret.add(entity.getPosition());
}
}
}
return ret;
} }
public List<BlockPos> scanFor(List<Block> mining, int max) { public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) {
List<BlockPos> locs = new ArrayList<>(); List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>(); List<Block> uninteresting = new ArrayList<>();
//long b = System.currentTimeMillis(); //long b = System.currentTimeMillis();
@@ -156,29 +205,59 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26)); locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms"); //System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
} }
return prune(locs, mining, max); return prune(locs, mining, max, world);
} }
public List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) { public void addNearby() {
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet(); BlockPos playerFeet = playerFeet();
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq)); int searchDist = 4;//why four? idk
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) {
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
BlockPos pos = new BlockPos(x, y, z);
if (mining.contains(BlockStateInterface.getBlock(pos)) && RotationUtils.reachable(player(), pos).isPresent()) {//crucial to only add blocks we can see because otherwise this is an x-ray and it'll get caught
knownOreLocations.add(pos);
}
}
}
}
knownOreLocations = prune(knownOreLocations, mining, ORE_LOCATIONS_COUNT, world());
}
public static List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max, World world) {
List<BlockPos> dropped = droppedItemsScan(mining, world);
List<BlockPos> locs = locs2
.stream()
// remove any that are within loaded chunks that aren't actually what we want
.filter(pos -> world.getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()) || dropped.contains(pos))
// remove any that are implausible to mine (encased in bedrock, or touching lava)
.filter(MineBehavior::plausibleToBreak)
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
.collect(Collectors.toList());
// remove any that are within loaded chunks that aren't actually what we want
locs.removeAll(locs.stream()
.filter(pos -> !(MineBehavior.INSTANCE.world().getChunk(pos) instanceof EmptyChunk))
.filter(pos -> !mining.contains(BlockStateInterface.get(pos).getBlock()))
.collect(Collectors.toList()));
if (locs.size() > max) { if (locs.size() > max) {
return locs.subList(0, max); return locs.subList(0, max);
} }
return locs; return locs;
} }
public static boolean plausibleToBreak(BlockPos pos) {
if (MovementHelper.avoidBreaking(pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(pos))) {
return false;
}
// bedrock above and below makes it implausible, otherwise we're good
return !(BlockStateInterface.getBlock(pos.up()) == Blocks.BEDROCK && BlockStateInterface.getBlock(pos.down()) == Blocks.BEDROCK);
}
@Override @Override
public void mine(int quantity, String... blocks) { public void mine(int quantity, String... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList()); this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
this.quantity = quantity; this.desiredQuantity = quantity;
this.locationsCache = new ArrayList<>(); this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan(); rescan();
updateGoal(); updateGoal();
} }
@@ -186,8 +265,9 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
@Override @Override
public void mine(int quantity, Block... blocks) { public void mine(int quantity, Block... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks); this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
this.quantity = quantity; this.desiredQuantity = quantity;
this.locationsCache = new ArrayList<>(); this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan(); rescan();
updateGoal(); updateGoal();
} }
@@ -195,6 +275,6 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
@Override @Override
public void cancel() { public void cancel() {
mine(0, (String[]) null); mine(0, (String[]) null);
PathingBehavior.INSTANCE.cancel(); baritone.getPathingBehavior().cancel();
} }
} }
@@ -32,6 +32,7 @@ import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.pathing.calc.AStarPathFinder; import baritone.pathing.calc.AStarPathFinder;
import baritone.pathing.calc.AbstractNodeCostSearch; import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.calc.CutoffPath; import baritone.pathing.calc.CutoffPath;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.PathExecutor; import baritone.pathing.path.PathExecutor;
import baritone.utils.BlockBreakHelper; import baritone.utils.BlockBreakHelper;
@@ -41,12 +42,11 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk; import net.minecraft.world.chunk.EmptyChunk;
import java.util.*; import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper { public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper {
public static final PathingBehavior INSTANCE = new PathingBehavior();
private PathExecutor current; private PathExecutor current;
private PathExecutor next; private PathExecutor next;
@@ -59,29 +59,46 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private boolean lastAutoJump; private boolean lastAutoJump;
private PathingBehavior() {} private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
private void dispatchPathEvent(PathEvent event) { public PathingBehavior(Baritone baritone) {
Baritone.INSTANCE.getExecutor().execute(() -> Baritone.INSTANCE.getGameEventHandler().onPathEvent(event)); super(baritone);
}
private void queuePathEvent(PathEvent event) {
toDispatch.add(event);
}
private void dispatchEvents() {
ArrayList<PathEvent> curr = new ArrayList<>();
toDispatch.drainTo(curr);
for (PathEvent event : curr) {
Baritone.INSTANCE.getGameEventHandler().onPathEvent(event);
}
} }
@Override @Override
public void onTick(TickEvent event) { public void onTick(TickEvent event) {
dispatchEvents();
if (event.getType() == TickEvent.Type.OUT) { if (event.getType() == TickEvent.Type.OUT) {
this.cancel(); cancel();
return; return;
} }
mc.playerController.setPlayerCapabilities(mc.player); tickPath();
dispatchEvents();
}
private void tickPath() {
if (current == null) { if (current == null) {
return; return;
} }
boolean safe = current.onTick(event); boolean safe = current.onTick();
synchronized (pathPlanLock) { synchronized (pathPlanLock) {
if (current.failed() || current.finished()) { if (current.failed() || current.finished()) {
current = null; current = null;
if (goal == null || goal.isInGoal(playerFeet())) { if (goal == null || goal.isInGoal(playerFeet())) {
logDebug("All done. At " + goal); logDebug("All done. At " + goal);
dispatchPathEvent(PathEvent.AT_GOAL); queuePathEvent(PathEvent.AT_GOAL);
next = null; next = null;
return; return;
} }
@@ -93,43 +110,38 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
// but if we fail in the middle of current // but if we fail in the middle of current
// we're nowhere close to our planned ahead path // we're nowhere close to our planned ahead path
// so need to discard it sadly. // so need to discard it sadly.
dispatchPathEvent(PathEvent.DISCARD_NEXT); queuePathEvent(PathEvent.DISCARD_NEXT);
next = null; next = null;
} }
if (next != null) { if (next != null) {
logDebug("Continuing on to planned next path"); logDebug("Continuing on to planned next path");
dispatchPathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT); queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
current = next; current = next;
next = null; next = null;
current.onTick(event); current.onTick();
return; return;
} }
// at this point, current just ended, but we aren't in the goal and have no plan for the future // at this point, current just ended, but we aren't in the goal and have no plan for the future
synchronized (pathCalcLock) { synchronized (pathCalcLock) {
if (isPathCalcInProgress) { if (isPathCalcInProgress) {
dispatchPathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING); queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
// if we aren't calculating right now // if we aren't calculating right now
return; return;
} }
dispatchPathEvent(PathEvent.CALC_STARTED); queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true, Optional.empty()); findPathInNewThread(pathStart(), true, Optional.empty());
} }
return; return;
} }
// at this point, we know current is in progress // at this point, we know current is in progress
if (safe) { if (safe && next != null && next.snipsnapifpossible()) {
// a movement just ended // a movement just ended; jump directly onto the next path
if (next != null) { logDebug("Splicing into planned next path early...");
if (next.snipsnapifpossible()) { queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
// jump directly onto the next path current = next;
logDebug("Splicing into planned next path early..."); next = null;
dispatchPathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY); current.onTick();
current = next; return;
next = null;
current.onTick(event);
return;
}
}
} }
synchronized (pathCalcLock) { synchronized (pathCalcLock) {
if (isPathCalcInProgress) { if (isPathCalcInProgress) {
@@ -147,7 +159,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) { if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
// and this path has 5 seconds or less left // and this path has 5 seconds or less left
logDebug("Path almost over. Planning ahead..."); logDebug("Path almost over. Planning ahead...");
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED); queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath())); findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath()));
} }
} }
@@ -184,6 +196,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
this.goal = goal; this.goal = goal;
} }
public boolean setGoalAndPath(Goal goal) {
setGoal(goal);
return path();
}
@Override @Override
public Goal getGoal() { public Goal getGoal() {
return goal; return goal;
@@ -211,7 +228,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
@Override @Override
public void cancel() { public void cancel() {
dispatchPathEvent(PathEvent.CANCELED); queuePathEvent(PathEvent.CANCELED);
current = null; current = null;
next = null; next = null;
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys(); Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
@@ -244,7 +261,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (isPathCalcInProgress) { if (isPathCalcInProgress) {
return false; return false;
} }
dispatchPathEvent(PathEvent.CALC_STARTED); queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true, Optional.empty()); findPathInNewThread(pathStart(), true, Optional.empty());
return true; return true;
} }
@@ -309,12 +326,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} }
isPathCalcInProgress = true; isPathCalcInProgress = true;
} }
CalculationContext context = new CalculationContext(); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
Baritone.INSTANCE.getExecutor().execute(() -> { Baritone.INSTANCE.getExecutor().execute(() -> {
if (talkAboutIt) { if (talkAboutIt) {
logDebug("Starting to search for path from " + start + " to " + goal); logDebug("Starting to search for path from " + start + " to " + goal);
} }
Optional<IPath> path = findPath(start, previous); Optional<IPath> path = findPath(start, previous, context);
if (Baritone.settings().cutoffAtLoadBoundary.get()) { if (Baritone.settings().cutoffAtLoadBoundary.get()) {
path = path.map(p -> { path = path.map(p -> {
IPath result = p.cutoffAtLoadedChunks(); IPath result = p.cutoffAtLoadedChunks();
@@ -343,18 +361,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
synchronized (pathPlanLock) { synchronized (pathPlanLock) {
if (current == null) { if (current == null) {
if (executor.isPresent()) { if (executor.isPresent()) {
dispatchPathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING); queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
current = executor.get(); current = executor.get();
} else { } else {
dispatchPathEvent(PathEvent.CALC_FAILED); queuePathEvent(PathEvent.CALC_FAILED);
} }
} else { } else {
if (next == null) { if (next == null) {
if (executor.isPresent()) { if (executor.isPresent()) {
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED); queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
next = executor.get(); next = executor.get();
} else { } else {
dispatchPathEvent(PathEvent.NEXT_CALC_FAILED); queuePathEvent(PathEvent.NEXT_CALC_FAILED);
} }
} else { } else {
throw new IllegalStateException("I have no idea what to do with this path"); throw new IllegalStateException("I have no idea what to do with this path");
@@ -382,19 +400,15 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
* @param start * @param start
* @return * @return
*/ */
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous) { private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous, CalculationContext context) {
Goal goal = this.goal; Goal goal = this.goal;
if (goal == null) { if (goal == null) {
logDebug("no goal"); logDebug("no goal");
return Optional.empty(); return Optional.empty();
} }
if (Baritone.settings().simplifyUnloadedYCoord.get()) { if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
BlockPos pos = null; BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
if (goal instanceof IGoalRenderPos) { if (world().getChunk(pos) instanceof EmptyChunk) {
pos = ((IGoalRenderPos) goal).getGoalPos();
}
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance"); logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
goal = new GoalXZ(pos.getX(), pos.getZ()); goal = new GoalXZ(pos.getX(), pos.getZ());
} }
@@ -412,7 +426,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(BetterBlockPos::longHash)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(BetterBlockPos::longHash)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
} }
try { try {
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions); IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions, context);
return pf.calculate(timeout); return pf.calculate(timeout);
} catch (Exception e) { } catch (Exception e) {
logDebug("Pathing exception: " + e); logDebug("Pathing exception: " + e);
+55 -33
View File
@@ -33,40 +33,62 @@ import java.util.*;
*/ */
public final class CachedChunk implements IBlockTypeAccess, Helper { public final class CachedChunk implements IBlockTypeAccess, Helper {
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(new HashSet<Block>() {{ public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
add(Blocks.DIAMOND_ORE);
add(Blocks.DIAMOND_BLOCK);
//add(Blocks.COAL_ORE);
add(Blocks.COAL_BLOCK);
//add(Blocks.IRON_ORE);
add(Blocks.IRON_BLOCK);
//add(Blocks.GOLD_ORE);
add(Blocks.GOLD_BLOCK);
add(Blocks.EMERALD_ORE);
add(Blocks.EMERALD_BLOCK);
add(Blocks.ENDER_CHEST); static {
add(Blocks.FURNACE); HashSet<Block> temp = new HashSet<>();
add(Blocks.CHEST); temp.add(Blocks.DIAMOND_ORE);
add(Blocks.END_PORTAL); temp.add(Blocks.DIAMOND_BLOCK);
add(Blocks.END_PORTAL_FRAME); //temp.add(Blocks.COAL_ORE);
add(Blocks.MOB_SPAWNER); temp.add(Blocks.COAL_BLOCK);
// TODO add all shulker colors //temp.add(Blocks.IRON_ORE);
add(Blocks.PORTAL); temp.add(Blocks.IRON_BLOCK);
add(Blocks.HOPPER); //temp.add(Blocks.GOLD_ORE);
add(Blocks.BEACON); temp.add(Blocks.GOLD_BLOCK);
add(Blocks.BREWING_STAND); temp.add(Blocks.EMERALD_ORE);
add(Blocks.SKULL); temp.add(Blocks.EMERALD_BLOCK);
add(Blocks.ENCHANTING_TABLE);
add(Blocks.ANVIL); temp.add(Blocks.ENDER_CHEST);
add(Blocks.LIT_FURNACE); temp.add(Blocks.FURNACE);
add(Blocks.BED); temp.add(Blocks.CHEST);
add(Blocks.DRAGON_EGG); temp.add(Blocks.TRAPPED_CHEST);
add(Blocks.JUKEBOX); temp.add(Blocks.END_PORTAL);
add(Blocks.END_GATEWAY); temp.add(Blocks.END_PORTAL_FRAME);
add(Blocks.WEB); temp.add(Blocks.MOB_SPAWNER);
add(Blocks.NETHER_WART); temp.add(Blocks.BARRIER);
}}); temp.add(Blocks.OBSERVER);
temp.add(Blocks.WHITE_SHULKER_BOX);
temp.add(Blocks.ORANGE_SHULKER_BOX);
temp.add(Blocks.MAGENTA_SHULKER_BOX);
temp.add(Blocks.LIGHT_BLUE_SHULKER_BOX);
temp.add(Blocks.YELLOW_SHULKER_BOX);
temp.add(Blocks.LIME_SHULKER_BOX);
temp.add(Blocks.PINK_SHULKER_BOX);
temp.add(Blocks.GRAY_SHULKER_BOX);
temp.add(Blocks.SILVER_SHULKER_BOX);
temp.add(Blocks.CYAN_SHULKER_BOX);
temp.add(Blocks.PURPLE_SHULKER_BOX);
temp.add(Blocks.BLUE_SHULKER_BOX);
temp.add(Blocks.BROWN_SHULKER_BOX);
temp.add(Blocks.GREEN_SHULKER_BOX);
temp.add(Blocks.RED_SHULKER_BOX);
temp.add(Blocks.BLACK_SHULKER_BOX);
temp.add(Blocks.PORTAL);
temp.add(Blocks.HOPPER);
temp.add(Blocks.BEACON);
temp.add(Blocks.BREWING_STAND);
temp.add(Blocks.SKULL);
temp.add(Blocks.ENCHANTING_TABLE);
temp.add(Blocks.ANVIL);
temp.add(Blocks.LIT_FURNACE);
temp.add(Blocks.BED);
temp.add(Blocks.DRAGON_EGG);
temp.add(Blocks.JUKEBOX);
temp.add(Blocks.END_GATEWAY);
temp.add(Blocks.WEB);
temp.add(Blocks.NETHER_WART);
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
}
/** /**
* The size of the chunk data in bits. Equal to 16 KiB. * The size of the chunk data in bits. Equal to 16 KiB.
+6
View File
@@ -167,6 +167,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
private synchronized void prune() { private synchronized void prune() {
BlockPos pruneCenter = guessPosition(); BlockPos pruneCenter = guessPosition();
for (CachedRegion region : allRegions()) { for (CachedRegion region : allRegions()) {
if (region == null) {
continue;
}
int distX = (region.getX() * 512 + 256) - pruneCenter.getX(); int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ(); int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ); double dist = Math.sqrt(distX * distX + distZ * distZ);
@@ -187,6 +190,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
} }
CachedChunk mostRecentlyModified = null; CachedChunk mostRecentlyModified = null;
for (CachedRegion region : allRegions()) { for (CachedRegion region : allRegions()) {
if (region == null) {
continue;
}
CachedChunk ch = region.mostRecentlyModified(); CachedChunk ch = region.mostRecentlyModified();
if (ch == null) { if (ch == null) {
continue; continue;
@@ -41,10 +41,12 @@ import java.util.Optional;
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper { public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
private final Optional<HashSet<Long>> favoredPositions; private final Optional<HashSet<Long>> favoredPositions;
private final CalculationContext calcContext;
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<HashSet<Long>> favoredPositions) { public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<HashSet<Long>> favoredPositions, CalculationContext context) {
super(startX, startY, startZ, goal); super(startX, startY, startZ, goal);
this.favoredPositions = favoredPositions; this.favoredPositions = favoredPositions;
this.calcContext = context;
} }
@Override @Override
@@ -61,7 +63,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
bestHeuristicSoFar[i] = startNode.estimatedCostToGoal; bestHeuristicSoFar[i] = startNode.estimatedCostToGoal;
bestSoFar[i] = startNode; bestSoFar[i] = startNode;
} }
CalculationContext calcContext = new CalculationContext();
MutableMoveResult res = new MutableMoveResult(); MutableMoveResult res = new MutableMoveResult();
HashSet<Long> favored = favoredPositions.orElse(null); HashSet<Long> favored = favoredPositions.orElse(null);
BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder()); BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder());
@@ -99,14 +100,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
for (Moves moves : Moves.values()) { for (Moves moves : Moves.values()) {
int newX = currentNode.x + moves.xOffset; int newX = currentNode.x + moves.xOffset;
int newZ = currentNode.z + moves.zOffset; int newZ = currentNode.z + moves.zOffset;
if (newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) { if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !BlockStateInterface.isLoaded(newX, newZ)) {
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement // only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
if (!BlockStateInterface.isLoaded(newX, newZ)) { if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed numEmptyChunk++;
numEmptyChunk++;
}
continue;
} }
continue;
} }
if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) { if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) {
continue; continue;
@@ -132,7 +131,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ); throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
} }
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) { if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ); throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
} }
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z); long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (favoring && favored.contains(hashCode)) { if (favoring && favored.contains(hashCode)) {
@@ -48,11 +48,7 @@ public class CalculationContext implements Helper {
private final BetterWorldBorder worldBorder; private final BetterWorldBorder worldBorder;
public CalculationContext() { public CalculationContext() {
this(new ToolSet()); this.toolSet = new ToolSet();
}
public CalculationContext(ToolSet toolSet) {
this.toolSet = toolSet;
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false); this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether(); this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether();
this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6; this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6;
@@ -87,10 +83,7 @@ public class CalculationContext implements Helper {
if (!allowBreak()) { if (!allowBreak()) {
return false; return false;
} }
if (isPossiblyProtected(x, y, z)) { return !isPossiblyProtected(x, y, z);
return false;
}
return true;
} }
public boolean isPossiblyProtected(int x, int y, int z) { public boolean isPossiblyProtected(int x, int y, int z) {
@@ -20,11 +20,7 @@ package baritone.pathing.movement;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.pathing.movement.IMovement; import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus; import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.*;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.behavior.LookBehavior;
import baritone.utils.BlockBreakHelper; import baritone.utils.BlockBreakHelper;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import baritone.utils.Helper; import baritone.utils.Helper;
@@ -37,6 +33,7 @@ import net.minecraft.world.chunk.EmptyChunk;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import static baritone.utils.InputOverrideHandler.Input; import static baritone.utils.InputOverrideHandler.Input;
@@ -115,9 +112,9 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
*/ */
@Override @Override
public MovementStatus update() { public MovementStatus update() {
player().capabilities.allowFlying = false; player().capabilities.isFlying = false;
MovementState latestState = updateState(currentState); MovementState latestState = updateState(currentState);
if (BlockStateInterface.isLiquid(playerFeet())) { if (MovementHelper.isLiquid(playerFeet())) {
latestState.setInput(Input.JUMP, true); latestState.setInput(Input.JUMP, true);
} }
if (player().isEntityInsideOpaqueBlock()) { if (player().isEntityInsideOpaqueBlock()) {
@@ -126,7 +123,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations // If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
latestState.getTarget().getRotation().ifPresent(rotation -> latestState.getTarget().getRotation().ifPresent(rotation ->
LookBehavior.INSTANCE.updateTarget( Baritone.INSTANCE.getLookBehavior().updateTarget(
rotation, rotation,
latestState.getTarget().hasToForceRotations())); latestState.getTarget().hasToForceRotations()));
@@ -178,7 +175,10 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos); Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos);
if (reachable.isPresent()) { if (reachable.isPresent()) {
MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos)); MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos));
state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true); state.setTarget(new MovementState.MovementTarget(reachable.get(), true));
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), blockPos)) {
state.setInput(Input.CLICK_LEFT, true);
}
return false; return false;
} }
//get rekt minecraft //get rekt minecraft
@@ -187,7 +187,9 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
//you dont own me!!!! //you dont own me!!!!
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F), state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(blockPos)), true) VecUtils.getBlockPosCenter(blockPos)), true)
).setInput(InputOverrideHandler.Input.CLICK_LEFT, true); );
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
return false; return false;
} }
} }
@@ -105,7 +105,7 @@ public interface MovementHelper extends ActionCosts, Helper {
} }
throw new IllegalStateException(); throw new IllegalStateException();
} }
if (BlockStateInterface.isFlowing(state)) { if (isFlowing(state)) {
return false; // Don't walk through flowing liquids return false; // Don't walk through flowing liquids
} }
if (block instanceof BlockLiquid) { if (block instanceof BlockLiquid) {
@@ -226,7 +226,7 @@ public interface MovementHelper extends ActionCosts, Helper {
return true; return true;
} }
return facing == playerFacing == open; return (facing == playerFacing) == open;
} }
static boolean avoidWalkingInto(Block block) { static boolean avoidWalkingInto(Block block) {
@@ -254,9 +254,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return false; return false;
} }
if (state.isBlockNormalCube()) { if (state.isBlockNormalCube()) {
if (BlockStateInterface.isLava(block) || BlockStateInterface.isWater(block)) {
throw new IllegalStateException();
}
return true; return true;
} }
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this
@@ -268,20 +265,20 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) { if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
return true; return true;
} }
if (BlockStateInterface.isWater(block)) { if (isWater(block)) {
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()" // since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability // BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
Block up = BlockStateInterface.get(x, y + 1, z).getBlock(); Block up = BlockStateInterface.get(x, y + 1, z).getBlock();
if (up == Blocks.WATERLILY) { if (up == Blocks.WATERLILY) {
return true; return true;
} }
if (BlockStateInterface.isFlowing(state) || block == Blocks.FLOWING_WATER) { if (isFlowing(state) || block == Blocks.FLOWING_WATER) {
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off // the only scenario in which we can walk on flowing water is if it's under still water with jesus off
return BlockStateInterface.isWater(up) && !Baritone.settings().assumeWalkOnWater.get(); return isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
} }
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it // if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
// if assumeWalkOnWater is off, we can only walk on water if there is water above it // if assumeWalkOnWater is off, we can only walk on water if there is water above it
return BlockStateInterface.isWater(up) ^ Baritone.settings().assumeWalkOnWater.get(); return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
} }
if (block instanceof BlockGlass || block instanceof BlockStainedGlass) { if (block instanceof BlockGlass || block instanceof BlockStainedGlass) {
return true; return true;
@@ -295,10 +292,7 @@ public interface MovementHelper extends ActionCosts, Helper {
} }
return true; return true;
} }
if (block instanceof BlockStairs) { return block instanceof BlockStairs;
return true;
}
return false;
} }
static boolean canWalkOn(BetterBlockPos pos, IBlockState state) { static boolean canWalkOn(BetterBlockPos pos, IBlockState state) {
@@ -400,7 +394,7 @@ public interface MovementHelper extends ActionCosts, Helper {
* @param ts previously calculated ToolSet * @param ts previously calculated ToolSet
*/ */
static void switchToBestToolFor(IBlockState b, ToolSet ts) { static void switchToBestToolFor(IBlockState b, ToolSet ts) {
mc.player.inventory.currentItem = ts.getBestSlot(b); mc.player.inventory.currentItem = ts.getBestSlot(b.getBlock());
} }
static boolean throwaway(boolean select) { static boolean throwaway(boolean select) {
@@ -447,4 +441,47 @@ public interface MovementHelper extends ActionCosts, Helper {
false false
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true); )).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
} }
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
*
* @param b The block
* @return Whether or not the block is water
*/
static boolean isWater(Block b) {
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
}
/**
* Returns whether or not the block at the specified pos is
* water, regardless of whether or not it is flowing.
*
* @param bp The block pos
* @return Whether or not the block is water
*/
static boolean isWater(BlockPos bp) {
return isWater(BlockStateInterface.getBlock(bp));
}
static boolean isLava(Block b) {
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
}
/**
* Returns whether or not the specified pos has a liquid
*
* @param p The pos
* @return Whether or not the block is a liquid
*/
static boolean isLiquid(BlockPos p) {
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
}
static boolean isFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getPropertyKeys().contains(BlockLiquid.LEVEL)
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
} }
@@ -75,7 +75,7 @@ public class MovementAscend extends Movement {
if (!context.canPlaceThrowawayAt(destX, y, destZ)) { if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
return COST_INF; return COST_INF;
} }
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) { if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) {
return COST_INF; return COST_INF;
} }
// TODO: add ability to place against .down() as well as the cardinal directions // TODO: add ability to place against .down() as well as the cardinal directions
@@ -97,21 +97,19 @@ public class MovementAscend extends Movement {
} }
} }
IBlockState srcUp2 = null; IBlockState srcUp2 = null;
if (BlockStateInterface.get(x, y + 3, z).getBlock() instanceof BlockFalling) {//it would fall on us and possibly suffocate us if (BlockStateInterface.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(x, y + 1, z) || !((srcUp2 = BlockStateInterface.get(x, y + 2, z)).getBlock() instanceof BlockFalling))) {//it would fall on us and possibly suffocate us
// HOWEVER, we assume that we're standing in the start position // HOWEVER, we assume that we're standing in the start position
// that means that src and src.up(1) are both air // that means that src and src.up(1) are both air
// maybe they aren't now, but they will be by the time this starts // maybe they aren't now, but they will be by the time this starts
if (MovementHelper.canWalkThrough(x, y + 1, z) || !((srcUp2 = BlockStateInterface.get(x, y + 2, z)).getBlock() instanceof BlockFalling)) { // if the lower one is can't walk through and the upper one is falling, that means that by standing on src
// if the lower one is can't walk through and the upper one is falling, that means that by standing on src // (the presupposition of this Movement)
// (the presupposition of this Movement) // we have necessarily already cleared the entire BlockFalling stack
// we have necessarily already cleared the entire BlockFalling stack // on top of our head
// on top of our head
// as in, if we have a block, then two BlockFallings on top of it // as in, if we have a block, then two BlockFallings on top of it
// and that block is x, y+1, z, and we'd have to clear it to even start this movement // and that block is x, y+1, z, and we'd have to clear it to even start this movement
// we don't need to worry about those BlockFallings because we've already cleared them // we don't need to worry about those BlockFallings because we've already cleared them
return COST_INF; return COST_INF;
}
// you may think we only need to check srcUp2, not srcUp // you may think we only need to check srcUp2, not srcUp
// however, in the scenario where glitchy world gen where unsupported sand / gravel generates // however, in the scenario where glitchy world gen where unsupported sand / gravel generates
// it's possible srcUp is AIR from the start, and srcUp2 is falling // it's possible srcUp is AIR from the start, and srcUp2 is falling
@@ -206,10 +204,8 @@ public class MovementAscend extends Movement {
return state.setStatus(MovementStatus.UNREACHABLE); return state.setStatus(MovementStatus.UNREACHABLE);
} }
MovementHelper.moveTowards(state, dest); MovementHelper.moveTowards(state, dest);
if (MovementHelper.isBottomSlab(jumpingOnto)) { if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(src.down())) {
if (!MovementHelper.isBottomSlab(src.down())) { return state; // don't jump while walking from a non double slab into a bottom slab
return state; // don't jump while walking from a non double slab into a bottom slab
}
} }
if (Baritone.settings().assumeStep.get()) { if (Baritone.settings().assumeStep.get()) {
@@ -130,7 +130,7 @@ public class MovementDescend extends Movement {
} }
IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ); IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ);
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak; double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak;
if (ontoBlock.getBlock() == Blocks.WATER && !BlockStateInterface.isFlowing(ontoBlock) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here? if (ontoBlock.getBlock() == Blocks.WATER && !MovementHelper.isFlowing(ontoBlock) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here?
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad // lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
// however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works) // however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works)
if (Baritone.settings().assumeWalkOnWater.get()) { if (Baritone.settings().assumeWalkOnWater.get()) {
@@ -183,11 +183,10 @@ public class MovementDescend extends Movement {
} }
BlockPos playerFeet = playerFeet(); BlockPos playerFeet = playerFeet();
if (playerFeet.equals(dest)) { if (playerFeet.equals(dest) && (MovementHelper.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094)) { // lilypads
if (BlockStateInterface.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094) { // lilypads // Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately return state.setStatus(MovementStatus.SUCCESS);
return state.setStatus(MovementStatus.SUCCESS); /* else {
}/* else {
// System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY())); // System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY()));
}*/ }*/
} }
@@ -78,11 +78,11 @@ public class MovementDiagonal extends Movement {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2; multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
} }
Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock(); Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock();
if (cuttingOver1 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver1)) { if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
return COST_INF; return COST_INF;
} }
Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock(); Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock();
if (cuttingOver2 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver2)) { if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
return COST_INF; return COST_INF;
} }
IBlockState pb0 = BlockStateInterface.get(x, y, destZ); IBlockState pb0 = BlockStateInterface.get(x, y, destZ);
@@ -101,25 +101,21 @@ public class MovementDiagonal extends Movement {
return COST_INF; return COST_INF;
} }
IBlockState pb3 = BlockStateInterface.get(destX, y + 1, z); IBlockState pb3 = BlockStateInterface.get(destX, y + 1, z);
if (optionA == 0) { if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) {
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction // at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
if ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER)) { return COST_INF;
return COST_INF;
}
} }
optionB += MovementHelper.getMiningDurationTicks(context, destX, y + 1, z, pb3, true); optionB += MovementHelper.getMiningDurationTicks(context, destX, y + 1, z, pb3, true);
if (optionA != 0 && optionB != 0) { if (optionA != 0 && optionB != 0) {
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible // and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
return COST_INF; return COST_INF;
} }
if (optionB == 0) { if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER))) {
// and now that option B is fully calculated, see if we can edge around that way // and now that option B is fully calculated, see if we can edge around that way
if ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER)) { return COST_INF;
return COST_INF;
}
} }
boolean water = false; boolean water = false;
if (BlockStateInterface.isWater(BlockStateInterface.getBlock(x, y, z)) || BlockStateInterface.isWater(destInto.getBlock())) { if (MovementHelper.isWater(BlockStateInterface.getBlock(x, y, z)) || MovementHelper.isWater(destInto.getBlock())) {
// Ignore previous multiplier // Ignore previous multiplier
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water // Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below // Not even touching the blocks below
@@ -149,7 +145,7 @@ public class MovementDiagonal extends Movement {
state.setStatus(MovementStatus.SUCCESS); state.setStatus(MovementStatus.SUCCESS);
return state; return state;
} }
if (!BlockStateInterface.isLiquid(playerFeet())) { if (!MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true); state.setInput(InputOverrideHandler.Input.SPRINT, true);
} }
MovementHelper.moveTowards(state, dest); MovementHelper.moveTowards(state, dest);
@@ -25,7 +25,6 @@ import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState; import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementTarget; import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler; import baritone.utils.InputOverrideHandler;
import baritone.utils.pathing.MutableMoveResult; import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
@@ -63,7 +62,7 @@ public class MovementFall extends Movement {
BlockPos playerFeet = playerFeet(); BlockPos playerFeet = playerFeet();
Rotation targetRotation = null; Rotation targetRotation = null;
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) { if (!MovementHelper.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) { if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) {
return state.setStatus(MovementStatus.UNREACHABLE); return state.setStatus(MovementStatus.UNREACHABLE);
} }
@@ -84,8 +83,8 @@ public class MovementFall extends Movement {
} else { } else {
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false)); state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
} }
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || BlockStateInterface.isWater(dest))) { // 0.094 because lilypads if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(dest))) { // 0.094 because lilypads
if (BlockStateInterface.isWater(dest)) { if (MovementHelper.isWater(dest)) {
if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) { if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY); player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
if (player().motionY >= 0) { if (player().motionY >= 0) {
@@ -124,7 +124,7 @@ public class MovementParkour extends Movement {
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) { if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
return; return;
} }
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) { if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
return; return;
} }
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
@@ -202,7 +202,7 @@ public class MovementParkour extends Movement {
} else if (!playerFeet().equals(src)) { } else if (!playerFeet().equals(src)) {
if (playerFeet().equals(src.offset(direction)) || player().posY - playerFeet().getY() > 0.0001) { if (playerFeet().equals(src.offset(direction)) || player().posY - playerFeet().getY() > 0.0001) {
if (!MovementHelper.canWalkOn(dest.down())) { if (!MovementHelper.canWalkOn(dest.down()) && !player().onGround) {
BlockPos positionToPlace = dest.down(); BlockPos positionToPlace = dest.down();
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]); BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
@@ -54,16 +54,12 @@ public class MovementPillar extends Movement {
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) { if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
return COST_INF; return COST_INF;
} }
if (fromDownDown.getBlock() instanceof BlockSlab) { if (fromDownDown.getBlock() instanceof BlockSlab && !((BlockSlab) fromDownDown.getBlock()).isDouble() && fromDownDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
if (!((BlockSlab) fromDownDown.getBlock()).isDouble() && fromDownDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) { return COST_INF; // can't pillar up from a bottom slab onto a non ladder
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
}
} }
} }
if (fromDown instanceof BlockVine) { if (fromDown instanceof BlockVine && !hasAgainst(x, y, z)) {
if (!hasAgainst(x, y, z)) { return COST_INF;
return COST_INF;
}
} }
IBlockState toBreak = BlockStateInterface.get(x, y + 2, z); IBlockState toBreak = BlockStateInterface.get(x, y + 2, z);
Block toBreakBlock = toBreak.getBlock(); Block toBreakBlock = toBreak.getBlock();
@@ -71,9 +67,9 @@ public class MovementPillar extends Movement {
return COST_INF; return COST_INF;
} }
Block srcUp = null; Block srcUp = null;
if (BlockStateInterface.isWater(toBreakBlock) && BlockStateInterface.isWater(fromDown)) { if (MovementHelper.isWater(toBreakBlock) && MovementHelper.isWater(fromDown)) {
srcUp = BlockStateInterface.get(x, y + 1, z).getBlock(); srcUp = BlockStateInterface.get(x, y + 1, z).getBlock();
if (BlockStateInterface.isWater(srcUp)) { if (MovementHelper.isWater(srcUp)) {
return LADDER_UP_ONE_COST; return LADDER_UP_ONE_COST;
} }
} }
@@ -148,7 +144,7 @@ public class MovementPillar extends Movement {
} }
IBlockState fromDown = BlockStateInterface.get(src); IBlockState fromDown = BlockStateInterface.get(src);
if (BlockStateInterface.isWater(fromDown.getBlock()) && BlockStateInterface.isWater(dest)) { if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(dest)) {
// stay centered while swimming up a water column // stay centered while swimming up a water column
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false)); state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
Vec3d destCenter = VecUtils.getBlockPosCenter(dest); Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
@@ -162,10 +158,11 @@ public class MovementPillar extends Movement {
} }
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine; boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
boolean vine = fromDown.getBlock() instanceof BlockVine; boolean vine = fromDown.getBlock() instanceof BlockVine;
Rotation rotation = RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(positionToPlace),
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch));
if (!ladder) { if (!ladder) {
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), state.setTarget(new MovementState.MovementTarget(new Rotation(mc.player.rotationYaw, rotation.getPitch()), true));
VecUtils.getBlockPosCenter(positionToPlace),
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)), true));
} }
boolean blockIsThere = MovementHelper.canWalkOn(src) || ladder; boolean blockIsThere = MovementHelper.canWalkOn(src) || ladder;
@@ -198,7 +195,8 @@ public class MovementPillar extends Movement {
// If our Y coordinate is above our goal, stop jumping // If our Y coordinate is above our goal, stop jumping
state.setInput(InputOverrideHandler.Input.JUMP, player().posY < dest.getY()); state.setInput(InputOverrideHandler.Input.JUMP, player().posY < dest.getY());
state.setInput(InputOverrideHandler.Input.SNEAK, true); state.setInput(InputOverrideHandler.Input.SNEAK, player().posY > dest.getY()); // delay placement by 1 tick for ncp compatibility
// since (lower down) we only right click once player.isSneaking, and that happens the tick after we request to sneak
double diffX = player().posX - (dest.getX() + 0.5); double diffX = player().posX - (dest.getX() + 0.5);
double diffZ = player().posZ - (dest.getZ() + 0.5); double diffZ = player().posZ - (dest.getZ() + 0.5);
@@ -209,6 +207,9 @@ public class MovementPillar extends Movement {
// If it's been more than forty ticks of trying to jump and we aren't done yet, go forward, maybe we are stuck // If it's been more than forty ticks of trying to jump and we aren't done yet, go forward, maybe we are stuck
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true); state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
// revise our target to both yaw and pitch if we're going to be moving forward
state.setTarget(new MovementState.MovementTarget(rotation, true));
} }
@@ -217,7 +218,7 @@ public class MovementPillar extends Movement {
if (!(fr instanceof BlockAir || fr.isReplaceable(Minecraft.getMinecraft().world, src))) { if (!(fr instanceof BlockAir || fr.isReplaceable(Minecraft.getMinecraft().world, src))) {
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true); state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
blockIsThere = false; blockIsThere = false;
} else if (Minecraft.getMinecraft().player.isSneaking()) { } else if (Minecraft.getMinecraft().player.isSneaking()) { // 1 tick after we're able to place
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true); state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
} }
} }
@@ -239,7 +240,7 @@ public class MovementPillar extends Movement {
state.setInput(InputOverrideHandler.Input.SNEAK, true); state.setInput(InputOverrideHandler.Input.SNEAK, true);
} }
} }
if (BlockStateInterface.isWater(dest.up())) { if (MovementHelper.isWater(dest.up())) {
return true; return true;
} }
return super.prepared(state); return super.prepared(state);
@@ -66,7 +66,7 @@ public class MovementTraverse extends Movement {
if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
double WC = WALK_ONE_BLOCK_COST; double WC = WALK_ONE_BLOCK_COST;
boolean water = false; boolean water = false;
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) { if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
WC = context.waterWalkSpeed(); WC = context.waterWalkSpeed();
water = true; water = true;
} else { } else {
@@ -101,8 +101,8 @@ public class MovementTraverse extends Movement {
return COST_INF; return COST_INF;
} }
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) { if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) {
boolean throughWater = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock()); boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) { if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
return COST_INF; return COST_INF;
} }
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) { if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
@@ -189,11 +189,9 @@ public class MovementTraverse extends Movement {
} else if (pb1.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(dest, src)) { } else if (pb1.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(dest, src)) {
isDoorActuallyBlockingUs = true; isDoorActuallyBlockingUs = true;
} }
if (isDoorActuallyBlockingUs) { if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
if (!(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) { return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(positionsToBreak[0])), true))
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(positionsToBreak[0])), true)) .setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
} }
} }
@@ -225,7 +223,7 @@ public class MovementTraverse extends Movement {
if (playerFeet().equals(dest)) { if (playerFeet().equals(dest)) {
return state.setStatus(MovementStatus.SUCCESS); return state.setStatus(MovementStatus.SUCCESS);
} }
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) { if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true); state.setInput(InputOverrideHandler.Input.SPRINT, true);
} }
Block destDown = BlockStateInterface.get(dest.down()).getBlock(); Block destDown = BlockStateInterface.get(dest.down()).getBlock();
@@ -267,11 +265,8 @@ public class MovementTraverse extends Movement {
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true)); state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit; EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get())) { if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get()) && RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
if (RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) { return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
// wrong side?
} }
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock()); //System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
return state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true); return state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
@@ -18,7 +18,6 @@
package baritone.pathing.path; package baritone.pathing.path;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.calc.IPath; import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.movement.ActionCosts; import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.IMovement; import baritone.api.pathing.movement.IMovement;
@@ -81,14 +80,10 @@ public class PathExecutor implements IPathExecutor, Helper {
/** /**
* Tick this executor * Tick this executor
* *
* @param event
* @return True if a movement just finished (and the player is therefore in a "stable" state, like, * @return True if a movement just finished (and the player is therefore in a "stable" state, like,
* not sneaking out over lava), false otherwise * not sneaking out over lava), false otherwise
*/ */
public boolean onTick(TickEvent event) { public boolean onTick() {
if (event.getType() == TickEvent.Type.OUT) {
throw new IllegalStateException();
}
if (pathPosition == path.length() - 1) { if (pathPosition == path.length() - 1) {
pathPosition++; pathPosition++;
} }
@@ -261,7 +256,7 @@ public class PathExecutor implements IPathExecutor, Helper {
//System.out.println("Movement done, next path"); //System.out.println("Movement done, next path");
pathPosition++; pathPosition++;
onChangeInPathPosition(); onChangeInPathPosition();
onTick(event); onTick();
return true; return true;
} else { } else {
sprintIfRequested(); sprintIfRequested();
@@ -276,7 +271,7 @@ public class PathExecutor implements IPathExecutor, Helper {
return true; return true;
} }
} }
return false; // movement is in progress return canCancel; // movement is in progress, but if it reports cancellable, PathingBehavior is good to cut onto the next path
} }
private Tuple<Double, BlockPos> closestPathPos(IPath path) { private Tuple<Double, BlockPos> closestPathPos(IPath path) {
@@ -331,10 +326,7 @@ public class PathExecutor implements IPathExecutor, Helper {
// when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path // when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path
if (path.movements().get(pathPosition) instanceof MovementFall) { if (path.movements().get(pathPosition) instanceof MovementFall) {
BlockPos fallDest = path.positions().get(pathPosition + 1); // .get(pathPosition) is the block we fell off of BlockPos fallDest = path.positions().get(pathPosition + 1); // .get(pathPosition) is the block we fell off of
if (VecUtils.entityFlatDistanceToCenter(player(), fallDest) < leniency) { // ignore Y by using flat distance return VecUtils.entityFlatDistanceToCenter(player(), fallDest) >= leniency; // ignore Y by using flat distance
return false;
}
return true;
} else { } else {
return true; return true;
} }
@@ -432,20 +424,13 @@ public class PathExecutor implements IPathExecutor, Helper {
} }
private static boolean canSprintInto(IMovement current, IMovement next) { private static boolean canSprintInto(IMovement current, IMovement next) {
if (next instanceof MovementDescend) { if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
if (next.getDirection().equals(current.getDirection())) {
return true;
}
}
if (next instanceof MovementTraverse) {
if (next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
return true;
}
}
if (next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get()) {
return true; return true;
} }
return false; if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
return true;
}
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get();
} }
private void onChangeInPathPosition() { private void onChangeInPathPosition() {
@@ -17,11 +17,11 @@
package baritone.utils; package baritone.utils;
import baritone.Baritone;
import baritone.api.event.events.TickEvent; import baritone.api.event.events.TickEvent;
import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalBlock;
import baritone.behavior.PathingBehavior;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.settings.GameSettings; import net.minecraft.client.settings.GameSettings;
@@ -105,8 +105,8 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
} }
// Setup Baritone's pathing goal and (if needed) begin pathing // Setup Baritone's pathing goal and (if needed) begin pathing
PathingBehavior.INSTANCE.setGoal(GOAL); Baritone.INSTANCE.getPathingBehavior().setGoal(GOAL);
PathingBehavior.INSTANCE.path(); Baritone.INSTANCE.getPathingBehavior().path();
// If we have reached our goal, print a message and safely close the game // If we have reached our goal, print a message and safely close the game
if (GOAL.isInGoal(playerFeet())) { if (GOAL.isInGoal(playerFeet())) {
@@ -22,7 +22,6 @@ import baritone.cache.CachedRegion;
import baritone.cache.WorldData; import baritone.cache.WorldData;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -128,47 +127,4 @@ public class BlockStateInterface implements Helper {
public static Block getBlock(int x, int y, int z) { public static Block getBlock(int x, int y, int z) {
return get(x, y, z).getBlock(); return get(x, y, z).getBlock();
} }
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
*
* @param b The block
* @return Whether or not the block is water
*/
public static boolean isWater(Block b) {
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
}
/**
* Returns whether or not the block at the specified pos is
* water, regardless of whether or not it is flowing.
*
* @param bp The block pos
* @return Whether or not the block is water
*/
public static boolean isWater(BlockPos bp) {
return isWater(BlockStateInterface.getBlock(bp));
}
public static boolean isLava(Block b) {
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
}
/**
* Returns whether or not the specified pos has a liquid
*
* @param p The pos
* @return Whether or not the block is a liquid
*/
public static boolean isLiquid(BlockPos p) {
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
}
public static boolean isFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getPropertyKeys().contains(BlockLiquid.LEVEL)
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
} }
@@ -26,8 +26,6 @@ import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.RayTraceUtils; import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import baritone.behavior.Behavior; import baritone.behavior.Behavior;
import baritone.behavior.FollowBehavior;
import baritone.behavior.MineBehavior;
import baritone.behavior.PathingBehavior; import baritone.behavior.PathingBehavior;
import baritone.cache.ChunkPacker; import baritone.cache.ChunkPacker;
import baritone.cache.Waypoint; import baritone.cache.Waypoint;
@@ -48,47 +46,83 @@ import java.util.stream.Stream;
public class ExampleBaritoneControl extends Behavior implements Helper { public class ExampleBaritoneControl extends Behavior implements Helper {
public static ExampleBaritoneControl INSTANCE = new ExampleBaritoneControl(); public static ExampleBaritoneControl INSTANCE; // compatibility with impact 4.4
private ExampleBaritoneControl() { private static final String HELP_MSG =
"baritone - Output settings into chat\n" +
"settings - Same as baritone\n" +
"goal - Create a goal (one number is '<Y>', two is '<X> <Z>', three is '<X> <Y> <Z>, 'clear' to clear)\n" +
"path - Go towards goal\n" +
"repack - (debug) Repacks chunk cache\n" +
"rescan - (debug) Same as repack\n" +
"axis - Paths towards the closest axis or diagonal axis, at y=120\n" +
"cancel - Cancels current path\n" +
"forcecancel - sudo cancel (only use if very glitched, try toggling 'pause' first)\n" +
"gc - Calls System.gc();\n" +
"invert - Runs away from the goal instead of towards it\n" +
"follow - Follows a player 'follow username'\n" +
"reloadall - (debug) Reloads chunk cache\n" +
"saveall - (debug) Saves chunk cache\n" +
"find - (debug) outputs how many blocks of a certain type are within the cache\n" +
"mine - Paths to and mines specified blocks 'mine x_ore y_ore ...'\n" +
"thisway - Creates a goal X blocks where you're facing\n" +
"list - Lists waypoints under a category\n" +
"get - Same as list\n" +
"show - Same as list\n" +
"save - Saves a waypoint (works but don't try to make sense of it)\n" +
"goto - Paths towards specified block or waypoint\n" +
"spawn - Paths towards world spawn or your most recent bed right-click\n" +
"sethome - Sets \"home\"\n" +
"home - Paths towards \"home\" \n" +
"costs - (debug) all movement costs from current location\n" +
"pause - Toggle pause\n" +
"damn - Daniel ";
} public ExampleBaritoneControl(Baritone baritone) {
super(baritone);
public void initAndRegister() { INSTANCE = this;
Baritone.INSTANCE.registerBehavior(this);
} }
@Override @Override
public void onSendChatMessage(ChatEvent event) { public void onSendChatMessage(ChatEvent event) {
if (!Baritone.settings().chatControl.get()) { if (!Baritone.settings().chatControl.get() && !Baritone.settings().removePrefix.get()) {
if (!Baritone.settings().removePrefix.get()) { return;
return;
}
} }
String msg = event.getMessage().toLowerCase(Locale.US); String msg = event.getMessage();
if (Baritone.settings().prefix.get()) { if (Baritone.settings().prefix.get()) {
if (!msg.startsWith("#")) { if (!msg.startsWith("#")) {
return; return;
} }
msg = msg.substring(1); msg = msg.substring(1);
} }
if (runCommand(msg)) {
event.cancel();
}
}
public boolean runCommand(String msg0) {
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class); List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
for (Settings.Setting<Boolean> setting : toggleable) { for (Settings.Setting<Boolean> setting : toggleable) {
if (msg.equalsIgnoreCase(setting.getName())) { if (msg.equalsIgnoreCase(setting.getName())) {
setting.value ^= true; setting.value ^= true;
event.cancel();
logDirect("Toggled " + setting.getName() + " to " + setting.value); logDirect("Toggled " + setting.getName() + " to " + setting.value);
SettingsUtil.save(Baritone.settings()); SettingsUtil.save(Baritone.settings());
return; return true;
} }
} }
if (msg.equals("baritone") || msg.equals("settings")) { if (msg.equals("baritone") || msg.equals("settings")) {
for (Settings.Setting<?> setting : Baritone.settings().allSettings) { for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
logDirect(setting.toString()); logDirect(setting.toString());
} }
event.cancel(); return true;
return; }
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
for (String line : HELP_MSG.split("\n")) {
logDirect(line);
}
return false;
} }
if (msg.contains(" ")) { if (msg.contains(" ")) {
String[] data = msg.split(" "); String[] data = msg.split(" ");
@@ -110,25 +144,21 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
logDirect("Unable to parse " + data[1]); logDirect("Unable to parse " + data[1]);
event.cancel(); return true;
return;
} }
SettingsUtil.save(Baritone.settings()); SettingsUtil.save(Baritone.settings());
logDirect(setting.toString()); logDirect(setting.toString());
event.cancel(); return true;
return;
} }
} }
} }
if (Baritone.settings().byLowerName.containsKey(msg)) { if (Baritone.settings().byLowerName.containsKey(msg)) {
Settings.Setting<?> setting = Baritone.settings().byLowerName.get(msg); Settings.Setting<?> setting = Baritone.settings().byLowerName.get(msg);
logDirect(setting.toString()); logDirect(setting.toString());
event.cancel(); return true;
return;
} }
if (msg.startsWith("goal")) { if (msg.startsWith("goal")) {
event.cancel();
String[] params = msg.substring(4).trim().split(" "); String[] params = msg.substring(4).trim().split(" ");
if (params[0].equals("")) { if (params[0].equals("")) {
params = new String[]{}; params = new String[]{};
@@ -154,30 +184,29 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
break; break;
default: default:
logDirect("unable to understand lol"); logDirect("unable to understand lol");
return; return true;
} }
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
logDirect("unable to parse integer " + ex); logDirect("unable to parse integer " + ex);
return; return true;
} }
PathingBehavior.INSTANCE.setGoal(goal); pathingBehavior.setGoal(goal);
logDirect("Goal: " + goal); logDirect("Goal: " + goal);
return; return true;
} }
if (msg.equals("path")) { if (msg.equals("path")) {
if (!PathingBehavior.INSTANCE.path()) { if (!pathingBehavior.path()) {
if (PathingBehavior.INSTANCE.getGoal() == null) { if (pathingBehavior.getGoal() == null) {
logDirect("No goal."); logDirect("No goal.");
} else { } else {
if (PathingBehavior.INSTANCE.getGoal().isInGoal(playerFeet())) { if (pathingBehavior.getGoal().isInGoal(playerFeet())) {
logDirect("Already in goal"); logDirect("Already in goal");
} else { } else {
logDirect("Currently executing a path. Please cancel it first."); logDirect("Currently executing a path. Please cancel it first.");
} }
} }
} }
event.cancel(); return true;
return;
} }
if (msg.equals("repack") || msg.equals("rescan")) { if (msg.equals("repack") || msg.equals("rescan")) {
ChunkProviderClient cli = world().getChunkProvider(); ChunkProviderClient cli = world().getChunkProvider();
@@ -194,41 +223,36 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
} }
logDirect("Queued " + count + " chunks for repacking"); logDirect("Queued " + count + " chunks for repacking");
event.cancel(); return true;
return;
} }
if (msg.equals("axis")) { if (msg.equals("axis")) {
PathingBehavior.INSTANCE.setGoal(new GoalAxis()); pathingBehavior.setGoal(new GoalAxis());
PathingBehavior.INSTANCE.path(); pathingBehavior.path();
event.cancel(); return true;
return;
} }
if (msg.equals("cancel") || msg.equals("stop")) { if (msg.equals("cancel") || msg.equals("stop")) {
MineBehavior.INSTANCE.cancel(); baritone.getMineBehavior().cancel();
FollowBehavior.INSTANCE.cancel(); baritone.getFollowBehavior().cancel();
PathingBehavior.INSTANCE.cancel(); pathingBehavior.cancel();
event.cancel();
logDirect("ok canceled"); logDirect("ok canceled");
return; return true;
} }
if (msg.equals("forcecancel")) { if (msg.equals("forcecancel")) {
MineBehavior.INSTANCE.cancel(); baritone.getMineBehavior().cancel();
FollowBehavior.INSTANCE.cancel(); baritone.getFollowBehavior().cancel();
PathingBehavior.INSTANCE.cancel(); pathingBehavior.cancel();
AbstractNodeCostSearch.forceCancel(); AbstractNodeCostSearch.forceCancel();
PathingBehavior.INSTANCE.forceCancel(); pathingBehavior.forceCancel();
event.cancel();
logDirect("ok force canceled"); logDirect("ok force canceled");
return; return true;
} }
if (msg.equals("gc")) { if (msg.equals("gc")) {
System.gc(); System.gc();
event.cancel();
logDirect("Called System.gc();"); logDirect("Called System.gc();");
return; return true;
} }
if (msg.equals("invert")) { if (msg.equals("invert")) {
Goal goal = PathingBehavior.INSTANCE.getGoal(); Goal goal = pathingBehavior.getGoal();
BlockPos runAwayFrom; BlockPos runAwayFrom;
if (goal instanceof GoalXZ) { if (goal instanceof GoalXZ) {
runAwayFrom = new BlockPos(((GoalXZ) goal).getX(), 0, ((GoalXZ) goal).getZ()); runAwayFrom = new BlockPos(((GoalXZ) goal).getX(), 0, ((GoalXZ) goal).getZ());
@@ -239,17 +263,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Inverting goal of player feet"); logDirect("Inverting goal of player feet");
runAwayFrom = playerFeet(); runAwayFrom = playerFeet();
} }
PathingBehavior.INSTANCE.setGoal(new GoalRunAway(1, runAwayFrom) { pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) {
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
return false; return false;
} }
}); });
if (!PathingBehavior.INSTANCE.path()) { if (!pathingBehavior.path()) {
logDirect("Currently executing a path. Please cancel it first."); logDirect("Currently executing a path. Please cancel it first.");
} }
event.cancel(); return true;
return;
} }
if (msg.startsWith("follow")) { if (msg.startsWith("follow")) {
String name = msg.substring(6).trim(); String name = msg.substring(6).trim();
@@ -259,34 +282,28 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} else { } else {
for (EntityPlayer pl : world().playerEntities) { for (EntityPlayer pl : world().playerEntities) {
String theirName = pl.getName().trim().toLowerCase(); String theirName = pl.getName().trim().toLowerCase();
if (!theirName.equals(player().getName().trim().toLowerCase())) { // don't follow ourselves lol if (!theirName.equals(player().getName().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
if (theirName.contains(name) || name.contains(theirName)) { toFollow = Optional.of(pl);
toFollow = Optional.of(pl);
}
} }
} }
} }
if (!toFollow.isPresent()) { if (!toFollow.isPresent()) {
logDirect("Not found"); logDirect("Not found");
event.cancel(); return true;
return;
} }
FollowBehavior.INSTANCE.follow(toFollow.get()); baritone.getFollowBehavior().follow(toFollow.get());
logDirect("Following " + toFollow.get()); logDirect("Following " + toFollow.get());
event.cancel(); return true;
return;
} }
if (msg.equals("reloadall")) { if (msg.equals("reloadall")) {
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().reloadAllFromDisk(); WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().reloadAllFromDisk();
logDirect("ok"); logDirect("ok");
event.cancel(); return true;
return;
} }
if (msg.equals("saveall")) { if (msg.equals("saveall")) {
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().save(); WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().save();
logDirect("ok"); logDirect("ok");
event.cancel(); return true;
return;
} }
if (msg.startsWith("find")) { if (msg.startsWith("find")) {
String blockType = msg.substring(4).trim(); String blockType = msg.substring(4).trim();
@@ -298,8 +315,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
System.out.println("Was looking for " + blockType + " but actually found " + actually + " " + ChunkPacker.blockToString(actually)); System.out.println("Was looking for " + blockType + " but actually found " + actually + " " + ChunkPacker.blockToString(actually));
} }
} }
event.cancel(); return true;
return;
} }
if (msg.startsWith("mine")) { if (msg.startsWith("mine")) {
String[] blockTypes = msg.substring(4).trim().split(" "); String[] blockTypes = msg.substring(4).trim().split(" ");
@@ -307,34 +323,30 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
int quantity = Integer.parseInt(blockTypes[1]); int quantity = Integer.parseInt(blockTypes[1]);
Block block = ChunkPacker.stringToBlock(blockTypes[0]); Block block = ChunkPacker.stringToBlock(blockTypes[0]);
Objects.requireNonNull(block); Objects.requireNonNull(block);
MineBehavior.INSTANCE.mine(quantity, block); baritone.getMineBehavior().mine(quantity, block);
logDirect("Will mine " + quantity + " " + blockTypes[0]); logDirect("Will mine " + quantity + " " + blockTypes[0]);
event.cancel(); return true;
return;
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {} } catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
for (String s : blockTypes) { for (String s : blockTypes) {
if (ChunkPacker.stringToBlock(s) == null) { if (ChunkPacker.stringToBlock(s) == null) {
logDirect(s + " isn't a valid block name"); logDirect(s + " isn't a valid block name");
event.cancel(); return true;
return;
} }
} }
MineBehavior.INSTANCE.mine(0, blockTypes); baritone.getMineBehavior().mine(0, blockTypes);
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes)); logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
event.cancel(); return true;
return;
} }
if (msg.startsWith("thisway")) { if (msg.startsWith("thisway")) {
try { try {
Goal goal = GoalXZ.fromDirection(playerFeetAsVec(), player().rotationYaw, Double.parseDouble(msg.substring(7).trim())); Goal goal = GoalXZ.fromDirection(playerFeetAsVec(), player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
PathingBehavior.INSTANCE.setGoal(goal); pathingBehavior.setGoal(goal);
logDirect("Goal: " + goal); logDirect("Goal: " + goal);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double."); logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double.");
} }
event.cancel(); return true;
return;
} }
if (msg.startsWith("list") || msg.startsWith("get ") || msg.startsWith("show")) { if (msg.startsWith("list") || msg.startsWith("get ") || msg.startsWith("show")) {
String waypointType = msg.substring(4).trim(); String waypointType = msg.substring(4).trim();
@@ -345,8 +357,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType); Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
if (tag == null) { if (tag == null) {
logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase()); logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
event.cancel(); return true;
return;
} }
Set<IWaypoint> waypoints = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getByTag(tag); Set<IWaypoint> waypoints = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getByTag(tag);
// might as well show them from oldest to newest // might as well show them from oldest to newest
@@ -356,11 +367,9 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
for (IWaypoint waypoint : sorted) { for (IWaypoint waypoint : sorted) {
logDirect(waypoint.toString()); logDirect(waypoint.toString());
} }
event.cancel(); return true;
return;
} }
if (msg.startsWith("save")) { if (msg.startsWith("save")) {
event.cancel();
String name = msg.substring(4).trim(); String name = msg.substring(4).trim();
BlockPos pos = playerFeet(); BlockPos pos = playerFeet();
if (name.contains(" ")) { if (name.contains(" ")) {
@@ -368,19 +377,19 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
String[] parts = name.split(" "); String[] parts = name.split(" ");
if (parts.length != 4) { if (parts.length != 4) {
logDirect("Unable to parse, expected four things"); logDirect("Unable to parse, expected four things");
return; return true;
} }
try { try {
pos = new BlockPos(Integer.parseInt(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3])); pos = new BlockPos(Integer.parseInt(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3]));
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
logDirect("Unable to parse coordinate integers"); logDirect("Unable to parse coordinate integers");
return; return true;
} }
name = parts[0]; name = parts[0];
} }
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, Waypoint.Tag.USER, pos)); WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, Waypoint.Tag.USER, pos));
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto user' to set goal, say 'list user' to list."); logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
return; return true;
} }
if (msg.startsWith("goto")) { if (msg.startsWith("goto")) {
String waypointType = msg.substring(4).trim(); String waypointType = msg.substring(4).trim();
@@ -394,40 +403,35 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
String mining = waypointType; String mining = waypointType;
Block block = ChunkPacker.stringToBlock(mining); Block block = ChunkPacker.stringToBlock(mining);
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase()); //logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
event.cancel();
if (block == null) { if (block == null) {
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null); waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
if (waypoint == null) { if (waypoint == null) {
logDirect("No locations for " + mining + " known, cancelling"); logDirect("No locations for " + mining + " known, cancelling");
return; return true;
} }
} else { } else {
List<BlockPos> locs = MineBehavior.INSTANCE.scanFor(Collections.singletonList(block), 64); List<BlockPos> locs = baritone.getMineBehavior().searchWorld(Collections.singletonList(block), 64, world());
if (locs.isEmpty()) { if (locs.isEmpty()) {
logDirect("No locations for " + mining + " known, cancelling"); logDirect("No locations for " + mining + " known, cancelling");
return; return true;
} }
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new))); pathingBehavior.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
PathingBehavior.INSTANCE.path(); pathingBehavior.path();
return; return true;
} }
} else { } else {
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(tag); waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(tag);
if (waypoint == null) { if (waypoint == null) {
logDirect("None saved for tag " + tag); logDirect("None saved for tag " + tag);
event.cancel(); return true;
return;
} }
} }
Goal goal = new GoalBlock(waypoint.getLocation()); Goal goal = new GoalBlock(waypoint.getLocation());
PathingBehavior.INSTANCE.setGoal(goal); pathingBehavior.setGoal(goal);
if (!PathingBehavior.INSTANCE.path()) { if (!pathingBehavior.path() && !goal.isInGoal(playerFeet())) {
if (!goal.isInGoal(playerFeet())) { logDirect("Currently executing a path. Please cancel it first.");
logDirect("Currently executing a path. Please cancel it first.");
}
} }
event.cancel(); return true;
return;
} }
if (msg.equals("spawn") || msg.equals("bed")) { if (msg.equals("spawn") || msg.equals("bed")) {
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED); IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
@@ -436,20 +440,18 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
// for some reason the default spawnpoint is underground sometimes // for some reason the default spawnpoint is underground sometimes
Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ()); Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ());
logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal); logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal);
PathingBehavior.INSTANCE.setGoal(goal); pathingBehavior.setGoal(goal);
} else { } else {
Goal goal = new GoalBlock(waypoint.getLocation()); Goal goal = new GoalBlock(waypoint.getLocation());
PathingBehavior.INSTANCE.setGoal(goal); pathingBehavior.setGoal(goal);
logDirect("Set goal to most recent bed " + goal); logDirect("Set goal to most recent bed " + goal);
} }
event.cancel(); return true;
return;
} }
if (msg.equals("sethome")) { if (msg.equals("sethome")) {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, playerFeet())); WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, playerFeet()));
logDirect("Saved. Say home to set goal."); logDirect("Saved. Say home to set goal.");
event.cancel(); return true;
return;
} }
if (msg.equals("home")) { if (msg.equals("home")) {
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME); IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
@@ -457,12 +459,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("home not saved"); logDirect("home not saved");
} else { } else {
Goal goal = new GoalBlock(waypoint.getLocation()); Goal goal = new GoalBlock(waypoint.getLocation());
PathingBehavior.INSTANCE.setGoal(goal); pathingBehavior.setGoal(goal);
PathingBehavior.INSTANCE.path(); pathingBehavior.path();
logDirect("Going to saved home " + goal); logDirect("Going to saved home " + goal);
} }
event.cancel(); return true;
return;
} }
if (msg.equals("costs")) { if (msg.equals("costs")) {
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(playerFeet())).collect(Collectors.toCollection(ArrayList::new)); List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(playerFeet())).collect(Collectors.toCollection(ArrayList::new));
@@ -479,18 +480,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
} }
logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost); logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost);
} }
event.cancel(); return true;
return;
} }
if (msg.equals("pause")) { if (msg.equals("pause")) {
boolean enabled = PathingBehavior.INSTANCE.toggle(); boolean enabled = pathingBehavior.toggle();
logDirect("Pathing Behavior has " + (enabled ? "resumed" : "paused") + "."); logDirect("Pathing Behavior has " + (enabled ? "resumed" : "paused") + ".");
event.cancel(); return true;
return;
} }
if (msg.equals("damn")) { if (msg.equals("damn")) {
logDirect("daniel"); logDirect("daniel");
return;
} }
return false;
} }
} }
+114 -58
View File
@@ -23,41 +23,41 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.init.Enchantments; import net.minecraft.init.Enchantments;
import net.minecraft.init.MobEffects; import net.minecraft.init.MobEffects;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
/** /**
* A cached list of the best tools on the hotbar for any block * A cached list of the best tools on the hotbar for any block
* *
* @author avecowa, Brady, leijurv * @author Avery, Brady, leijurv
*/ */
public class ToolSet implements Helper { public class ToolSet implements Helper {
/** /**
* A cache mapping a {@link Block} to how long it will take to break * A cache mapping a {@link Block} to how long it will take to break
* with this toolset, given the optimum tool is used. * with this toolset, given the optimum tool is used.
*/ */
private Map<Block, Double> breakStrengthCache = new HashMap<>(); private final Map<Block, Double> breakStrengthCache;
/** /**
* Calculate which tool on the hotbar is best for mining * My buddy leijurv owned me so we have this to not create a new lambda instance.
*
* @param b the blockstate to be mined
* @return a byte indicating the index in the tools array that worked best
*/ */
public byte getBestSlot(IBlockState b) { private final Function<Block, Double> backendCalculation;
byte best = 0;
double value = -1; public ToolSet() {
for (byte i = 0; i < 9; i++) { breakStrengthCache = new HashMap<>();
double v = calculateStrVsBlock(i, b);
if (v > value || value == -1) { if (Baritone.settings().considerPotionEffects.get()) {
value = v; double amplifier = potionAmplifier();
best = i; Function<Double, Double> amplify = x -> amplifier * x;
} backendCalculation = amplify.compose(this::getBestDestructionTime);
} else {
backendCalculation = this::getBestDestructionTime;
} }
return best;
} }
/** /**
@@ -67,14 +67,64 @@ public class ToolSet implements Helper {
* @return how long it would take in ticks * @return how long it would take in ticks
*/ */
public double getStrVsBlock(IBlockState state) { public double getStrVsBlock(IBlockState state) {
Double strength = this.breakStrengthCache.get(state.getBlock()); return breakStrengthCache.computeIfAbsent(state.getBlock(), backendCalculation);
if (strength != null) { }
// the function will take this path >99% of the time
return strength; /**
* Evaluate the material cost of a possible tool. The priority matches the
* listed order in the Item.ToolMaterial enum.
*
* @param itemStack a possibly empty ItemStack
* @return values range from -1 to 4
*/
private int getMaterialCost(ItemStack itemStack) {
if (itemStack.getItem() instanceof ItemTool) {
ItemTool tool = (ItemTool) itemStack.getItem();
return ToolMaterial.valueOf(tool.getToolMaterialName()).ordinal();
} else {
return -1;
} }
double str = calculateStrVsBlock(getBestSlot(state), state); }
this.breakStrengthCache.put(state.getBlock(), str);
return str; /**
* Calculate which tool on the hotbar is best for mining
*
* @param b the blockstate to be mined
* @return A byte containing the index in the tools array that worked best
*/
public byte getBestSlot(Block b) {
byte best = 0;
double value = Double.NEGATIVE_INFINITY;
int materialCost = Integer.MIN_VALUE;
IBlockState blockState = b.getDefaultState();
for (byte i = 0; i < 9; i++) {
ItemStack itemStack = player().inventory.getStackInSlot(i);
double v = calculateStrVsBlock(itemStack, blockState);
if (v > value) {
value = v;
best = i;
materialCost = getMaterialCost(itemStack);
} else if (v == value) {
int c = getMaterialCost(itemStack);
if (c < materialCost) {
value = v;
best = i;
materialCost = c;
}
}
}
return best;
}
/**
* Calculate how effectively a block can be destroyed
*
* @param b the blockstate to be mined
* @return A double containing the destruction ticks with the best tool
*/
private double getBestDestructionTime(Block b) {
ItemStack stack = player().inventory.getStackInSlot(getBestSlot(b));
return calculateStrVsBlock(stack, b.getDefaultState());
} }
/** /**
@@ -84,49 +134,55 @@ public class ToolSet implements Helper {
* @param state the blockstate to be mined * @param state the blockstate to be mined
* @return how long it would take in ticks * @return how long it would take in ticks
*/ */
private double calculateStrVsBlock(byte slot, IBlockState state) { private double calculateStrVsBlock(ItemStack item, IBlockState state) {
// Calculate the slot with the best item float hardness = state.getBlockHardness(null, null);
ItemStack contents = player().inventory.getStackInSlot(slot); if (hardness < 0) {
float blockHard = state.getBlockHardness(null, null);
if (blockHard < 0) {
return -1; return -1;
} }
float speed = contents.getDestroySpeed(state); float speed = item.getDestroySpeed(state);
if (speed > 1) { if (speed > 1) {
int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, contents); int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, item);
if (effLevel > 0 && !contents.isEmpty()) { if (effLevel > 0 && !item.isEmpty()) {
speed += effLevel * effLevel + 1; speed += effLevel * effLevel + 1;
} }
} }
if (Baritone.settings().considerPotionEffects.get()) { speed /= hardness;
if (player().isPotionActive(MobEffects.HASTE)) { if (state.getMaterial().isToolNotRequired() || (!item.isEmpty() && item.canHarvestBlock(state))) {
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2; speed /= 30;
}
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
case 0:
speed *= 0.3;
break;
case 1:
speed *= 0.09;
break;
case 2:
speed *= 0.0027;
break;
default:
speed *= 0.00081;
break;
}
}
}
speed /= blockHard;
if (state.getMaterial().isToolNotRequired() || (!contents.isEmpty() && contents.canHarvestBlock(state))) {
return speed / 30;
} else { } else {
return speed / 100; speed /= 100;
} }
return speed;
}
/**
* Calculates any modifier to breaking time based on status effects.
*
* @return a double to scale block breaking speed.
*/
private double potionAmplifier() {
double speed = 1;
if (player().isPotionActive(MobEffects.HASTE)) {
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
}
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
case 0:
speed *= 0.3;
break;
case 1:
speed *= 0.09;
break;
case 2:
speed *= 0.0027;
break;
default:
speed *= 0.00081;
break;
}
}
return speed;
} }
} }