merge
This commit is contained in:
+27
@@ -1 +1,28 @@
|
|||||||
language: java
|
language: java
|
||||||
|
|
||||||
|
sudo: required
|
||||||
|
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
|
||||||
|
install:
|
||||||
|
- travis_retry docker build -t cabaletta/baritone .
|
||||||
|
|
||||||
|
script:
|
||||||
|
- docker run --name baritone cabaletta/baritone /bin/sh -c "set -e; /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 128x128x24 -ac +extension GLX +render; sh scripts/build.sh; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runClient"
|
||||||
|
- docker cp baritone:/code/dist dist
|
||||||
|
- ls dist
|
||||||
|
- cat dist/checksums.txt
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
api_key:
|
||||||
|
secure: YOuiXoJNpB4bW89TQoY2IGXg0tqOKls55YMXsSPU6Mx8WzRu8CjjO/A8KA9nGfNrKM+NucjiKr/h53O2Dp2uyy0i0SLvav/G0MaBMeB1NlPRwFopi6tVPNaoZsvr8NW4BIURhspckYLpOTYWnfmOkIv8q7AxrjUZWPKDlq0dte20UxEqUE6msHJ7U9XlKo/4fX40kvWMfwGI2hTyAtL0cRT1QPsd+uW3OQjAPcQj+jKaWld46V8pBK8g9Qde9mo8HC9NBv97zw1bBF1EFkynW569kElHvaS2Opl2QLGaf66guDbpnqDpGHMhQrDdxsZHJ4RksyITn+8A9UArmbkU35BxKqBeQqOWxod2+M0axdLh1pvX43Q1t9n7RiZBf7GvV8vkXL5Sjf8v6Y4LqkJGhvQkTUwpH+0knwrE761DMCtBC34AiWG70D4u7msmhurkflr9kmRHSj/3lyJ1Q2lkt8L+FOAlQBVs64vXTsfgc6Yge7N0O3UD5hCkrDNoz3BzhNBdCkbdxdKCGip71UZgUNkPy9o3ui8jATNj9ypx3+U8ovqP0XWlJqUZmyeXyNGW9NrLeCkRLTlLnZ/dv6OPONa1oAu4TwF1w5A+TGRFZcZjH/PnZKZDQ1OYQOR6drLKRYdr2unvuf5KUKUGqZ7aYtLGhP0rBvGWddRV7DSmX/s=
|
||||||
|
all_branches: true
|
||||||
|
file_glob: true
|
||||||
|
file:
|
||||||
|
- dist/*
|
||||||
|
skip_cleanup: true
|
||||||
|
on:
|
||||||
|
tags: true
|
||||||
|
repo: cabaletta/baritone
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
FROM debian:jessie
|
||||||
|
|
||||||
|
RUN echo 'deb http://deb.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
RUN apt update -y
|
||||||
|
|
||||||
|
RUN apt install --target-release jessie-backports \
|
||||||
|
openjdk-8-jdk \
|
||||||
|
ca-certificates-java \
|
||||||
|
--assume-yes
|
||||||
|
|
||||||
|
RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
|
||||||
|
|
||||||
|
RUN apt install -qq --force-yes unzip wget
|
||||||
|
|
||||||
|
ADD . /code
|
||||||
|
|
||||||
|
RUN echo "\nrunClient {\nargs \"--width\",\"128\",\"--height\",\"128\"\n}" >> /code/build.gradle
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
RUN ./gradlew build
|
||||||
@@ -11,9 +11,12 @@ There are some basic steps to getting Baritone setup with Impact.
|
|||||||
## 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 3 methods of acquiring a build of Baritone (While it is still in development)
|
||||||
|
|
||||||
### Official Build (Not always up to date)
|
### Official Release (Not always up to date)
|
||||||
Download the "official" jar (as of commit <a href="https://github.com/cabaletta/baritone/commit/2e63ac41d9b22e4ee0a62f2bd29974e43e2071a1">2e63ac4</a>,
|
https://github.com/cabaletta/baritone/releases
|
||||||
built on September 19) from <a href="https://www.dropbox.com/s/imc6xwwpwsh3i0y/baritone-1.0.0.jar?dl=0">here</a>.
|
|
||||||
|
For Impact 4.3, there is no Baritone integration yet, so you will want `baritone-standalone-X.Y.Z.jar`.
|
||||||
|
|
||||||
|
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
|
||||||
|
|
||||||
### Building Baritone yourself
|
### Building Baritone yourself
|
||||||
There are a few steps to this
|
There are a few steps to this
|
||||||
@@ -23,7 +26,7 @@ There are a few steps to this
|
|||||||
command line
|
command line
|
||||||
- Windows: ``gradlew build``
|
- Windows: ``gradlew build``
|
||||||
- Mac/Linux: ``./gradlew build``
|
- Mac/Linux: ``./gradlew build``
|
||||||
- The build should be exported into ``/build/libs/baritone-1.0.0.jar``
|
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
|
||||||
|
|
||||||
### Cutting Edge Release
|
### Cutting Edge Release
|
||||||
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
|
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
|
||||||
@@ -37,9 +40,9 @@ putting baritone.
|
|||||||
- Create 3 new subdirectories starting from ``libraries``
|
- Create 3 new subdirectories starting from ``libraries``
|
||||||
- ``cabaletta``
|
- ``cabaletta``
|
||||||
- ``baritone``
|
- ``baritone``
|
||||||
- ``1.0.0``
|
- ``X.Y.Z``
|
||||||
- Copy the build of Baritone that was acquired earlier, and place it into the ``1.0.0`` folder
|
- Copy the build of Baritone that was acquired earlier, and place it into the ``X.Y.Z`` folder
|
||||||
- The full path should look like ``<Minecraft>/libraries/cabaletta/baritone/1.0.0/baritone-1.0.0.jar``
|
- The full path should look like ``<Minecraft>/libraries/cabaletta/baritone/X.Y.Z/baritone-X.Y.Z.jar``
|
||||||
|
|
||||||
## Modifying the Impact Profile JSON to run baritone
|
## Modifying the Impact Profile JSON to run baritone
|
||||||
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
|
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
|
||||||
@@ -72,7 +75,7 @@ The final step is "registering" the Baritone library with Impact, so that it loa
|
|||||||
- Create a new object in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
|
- Create a new object in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"name": "cabaletta:baritone:1.0.0"
|
"name": "cabaletta:baritone:X.Y.Z"
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
- Now find the ``"minecraftArguments": "..."`` text near the top.
|
- Now find the ``"minecraftArguments": "..."`` text near the top.
|
||||||
|
|||||||
@@ -3,15 +3,19 @@
|
|||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<a href="https://github.com/cabaletta/baritone/blob/master/FEATURES.md">Features</a>
|
|
||||||
|
|
||||||
<a href="https://github.com/cabaletta/baritone/blob/master/IMPACT.md">Baritone + Impact</a>
|
|
||||||
|
|
||||||
Unofficial Jenkins: [](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/)
|
Unofficial Jenkins: [](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/)
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
Here are some links to help to get started:
|
||||||
|
|
||||||
|
- [Features](FEATURES.md)
|
||||||
|
|
||||||
|
- [Baritone + Impact](IMPACT.md)
|
||||||
|
|
||||||
|
There's also some useful information down below
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
|
||||||
## IntelliJ's Gradle UI
|
## IntelliJ's Gradle UI
|
||||||
@@ -38,18 +42,18 @@ $ gradlew genIntellijRuns
|
|||||||
```
|
```
|
||||||
|
|
||||||
# Chat control
|
# Chat control
|
||||||
<a href="https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java">Defined here</a>
|
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
|
||||||
|
|
||||||
Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actually start pathing. Also try `mine diamond_ore`. `cancel` to cancel.
|
Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actually start pathing. Also try `mine diamond_ore`. `cancel` to cancel.
|
||||||
|
|
||||||
# API example
|
# API example
|
||||||
|
|
||||||
```
|
```
|
||||||
Baritone.settings().allowSprint.value = true;
|
BaritoneAPI.getSettings().allowSprint.value = true;
|
||||||
Baritone.settings().pathTimeoutMS.value = 2000L;
|
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
|
||||||
|
|
||||||
PathingBehavior.INSTANCE.setGoal(new GoalXZ(10000, 20000));
|
BaritoneAPI.getPathingBehavior().setGoal(new GoalXZ(10000, 20000));
|
||||||
PathingBehavior.INSTANCE.path();
|
BaritoneAPI.getPathingBehavior().path();
|
||||||
```
|
```
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
@@ -60,7 +64,7 @@ Sure! (As long as usage is in compliance with the LGPL 3 License)
|
|||||||
|
|
||||||
## How is it so fast?
|
## How is it so fast?
|
||||||
|
|
||||||
Magic
|
Magic. (Hours of [Leijurv](https://github.com/leijurv) enduring excruciating pain)
|
||||||
|
|
||||||
## Why is it called Baritone?
|
## Why is it called Baritone?
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
group 'baritone'
|
group 'baritone'
|
||||||
version '1.0.0'
|
version '0.0.3'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
set -e # this makes the whole script fail immediately if any one of these commands fails
|
||||||
|
./gradlew build
|
||||||
|
export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2)
|
||||||
|
|
||||||
|
wget -nv https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip
|
||||||
|
unzip proguard6.0.3.zip 2>&1 > /dev/null
|
||||||
|
cd build/libs
|
||||||
|
echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version
|
||||||
|
cat ../../scripts/proguard.pro | grep -v "this is the rt jar" | grep -v "\-injars" >> api.pro # remove default rt jar and injar lines
|
||||||
|
echo "-libraryjars '$(java -verbose 2>/dev/null | sed -ne '1 s/\[Opened \(.*\)\]/\1/p')'" >> api.pro # insert correct rt.jar location
|
||||||
|
tail api.pro # debug, print out what the previous two commands generated
|
||||||
|
cat api.pro | grep -v "\-keep class baritone.api" > standalone.pro # standalone doesn't keep baritone api
|
||||||
|
|
||||||
|
#wget -nv https://www.dropbox.com/s/zmc2l3jnwdvzvak/tempLibraries.zip?dl=1 # i'm sorry
|
||||||
|
#mv tempLibraries.zip?dl=1 tempLibraries.zip
|
||||||
|
#unzip tempLibraries.zip
|
||||||
|
|
||||||
|
#instead of downloading these jars from my dropbox in a zip, just assume gradle's already got them for us
|
||||||
|
mkdir -p tempLibraries
|
||||||
|
cat ../../scripts/proguard.pro | grep tempLibraries | grep .jar | cut -d "/" -f 2- | cut -d "'" -f -1 | xargs -n1 -I{} bash -c "find ~/.gradle -name {}" | tee /dev/stderr | xargs -n1 -I{} cp {} tempLibraries
|
||||||
|
|
||||||
|
mkdir ../../dist
|
||||||
|
java -jar ../../proguard6.0.3/lib/proguard.jar @api.pro
|
||||||
|
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-api-$VERSION.jar
|
||||||
|
java -jar ../../proguard6.0.3/lib/proguard.jar @standalone.pro
|
||||||
|
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-standalone-$VERSION.jar
|
||||||
|
mv baritone-$VERSION.jar ../../dist/baritone-unoptimized-$VERSION.jar
|
||||||
|
cd ../../dist
|
||||||
|
shasum * | tee checksums.txt
|
||||||
|
cd ..
|
||||||
Vendored
+11
-15
@@ -1,28 +1,28 @@
|
|||||||
-injars baritone-1.0.0.jar
|
-injars baritone-0.0.3.jar
|
||||||
-outjars Obfuscated
|
-outjars Obfuscated
|
||||||
|
|
||||||
|
|
||||||
-keepattributes Signature
|
-keepattributes Signature
|
||||||
-keepattributes *Annotation*
|
-keepattributes *Annotation*
|
||||||
|
|
||||||
-optimizationpasses 20
|
-optimizationpasses 5
|
||||||
-verbose
|
-verbose
|
||||||
|
|
||||||
-allowaccessmodification # anything not kept can be changed from public to private and inlined etc
|
-allowaccessmodification # anything not kept can be changed from public to private and inlined etc
|
||||||
-overloadaggressively
|
-overloadaggressively
|
||||||
-dontusemixedcaseclassnames
|
-dontusemixedcaseclassnames
|
||||||
|
|
||||||
# instead of obfing to a, b, c, obf to baritone.a, baritone.b, baritone.c so as to not conflict with minecraft's obfd classes
|
# instead of renaming to a, b, c, rename to baritone.a, baritone.b, baritone.c so as to not conflict with minecraft's obfd classes
|
||||||
-flattenpackagehierarchy
|
-flattenpackagehierarchy
|
||||||
-repackageclasses 'baritone'
|
-repackageclasses 'baritone'
|
||||||
|
|
||||||
#-keep class baritone.behavior.** { *; }
|
#-keep class baritone.behavior.** { *; }
|
||||||
#-keep class baritone.api.** { *; }
|
-keep class baritone.api.** { *; }
|
||||||
#-keep class baritone.* { *; }
|
#-keep class baritone.* { *; }
|
||||||
#-keep class baritone.pathing.goals.** { *; }
|
#-keep class baritone.pathing.goals.** { *; }
|
||||||
|
|
||||||
# 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.Settings {
|
-keepclassmembers class baritone.api.Settings {
|
||||||
public <fields>;
|
public <fields>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
-keep class baritone.launch.** { *; }
|
-keep class baritone.launch.** { *; }
|
||||||
|
|
||||||
# copy all necessary libraries into tempLibraries to build
|
# copy all necessary libraries into tempLibraries to build
|
||||||
-libraryjars '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/rt.jar'
|
-libraryjars '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/rt.jar' # this is the rt jar
|
||||||
|
|
||||||
-libraryjars 'tempLibraries/1.12.2.jar'
|
-libraryjars 'tempLibraries/minecraft-1.12.2.jar'
|
||||||
|
|
||||||
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
|
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
|
||||||
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
|
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
|
||||||
@@ -48,22 +48,18 @@
|
|||||||
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
|
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
|
||||||
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
|
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
|
||||||
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
|
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
|
||||||
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0-natives-osx.jar'
|
|
||||||
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0.jar'
|
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0.jar'
|
||||||
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
|
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
|
||||||
-libraryjars 'tempLibraries/jinput-platform-2.0.5-natives-osx.jar'
|
|
||||||
-libraryjars 'tempLibraries/jna-4.4.0.jar'
|
-libraryjars 'tempLibraries/jna-4.4.0.jar'
|
||||||
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
|
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
|
||||||
-libraryjars 'tempLibraries/jsr305-3.0.1-sources.jar'
|
|
||||||
-libraryjars 'tempLibraries/jsr305-3.0.1.jar'
|
-libraryjars 'tempLibraries/jsr305-3.0.1.jar'
|
||||||
-libraryjars 'tempLibraries/jutils-1.0.0.jar'
|
-libraryjars 'tempLibraries/jutils-1.0.0.jar'
|
||||||
-libraryjars 'tempLibraries/libraryjavasound-20101123.jar'
|
-libraryjars 'tempLibraries/libraryjavasound-20101123.jar'
|
||||||
-libraryjars 'tempLibraries/librarylwjglopenal-20100824.jar'
|
-libraryjars 'tempLibraries/librarylwjglopenal-20100824.jar'
|
||||||
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
|
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
|
||||||
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
|
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
|
||||||
-libraryjars 'tempLibraries/lwjgl-2.9.2-nightly-20140822.jar'
|
-libraryjars 'tempLibraries/lwjgl-2.9.4-nightly-20150209.jar'
|
||||||
-libraryjars 'tempLibraries/lwjgl-platform-2.9.2-nightly-20140822-natives-osx.jar'
|
-libraryjars 'tempLibraries/lwjgl_util-2.9.4-nightly-20150209.jar'
|
||||||
-libraryjars 'tempLibraries/lwjgl_util-2.9.2-nightly-20140822.jar'
|
|
||||||
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
|
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
|
||||||
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
|
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
|
||||||
-libraryjars 'tempLibraries/patchy-1.1.jar'
|
-libraryjars 'tempLibraries/patchy-1.1.jar'
|
||||||
@@ -72,8 +68,8 @@
|
|||||||
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
|
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
|
||||||
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
|
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
|
||||||
|
|
||||||
-libraryjars 'tempLibraries/mixin-0.7.8-SNAPSHOT.jar'
|
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
|
||||||
-libraryjars 'tempLibraries/launchwrapper-1.12.jar'
|
-libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* 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.api;
|
||||||
|
|
||||||
|
import baritone.api.behavior.*;
|
||||||
|
import baritone.api.cache.IWorldProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API exposure for various things implemented in Baritone.
|
||||||
|
* <p>
|
||||||
|
* W.I.P
|
||||||
|
*
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public class BaritoneAPI {
|
||||||
|
|
||||||
|
// General
|
||||||
|
private static final Settings settings = new Settings();
|
||||||
|
private static IWorldProvider worldProvider;
|
||||||
|
|
||||||
|
// Behaviors
|
||||||
|
private static IFollowBehavior followBehavior;
|
||||||
|
private static ILookBehavior lookBehavior;
|
||||||
|
private static IMemoryBehavior memoryBehavior;
|
||||||
|
private static IMineBehavior mineBehavior;
|
||||||
|
private static IPathingBehavior pathingBehavior;
|
||||||
|
|
||||||
|
public static IFollowBehavior getFollowBehavior() {
|
||||||
|
return followBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ILookBehavior getLookBehavior() {
|
||||||
|
return lookBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IMemoryBehavior getMemoryBehavior() {
|
||||||
|
return memoryBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IMineBehavior getMineBehavior() {
|
||||||
|
return mineBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPathingBehavior getPathingBehavior() {
|
||||||
|
return pathingBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Settings getSettings() {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IWorldProvider getWorldProvider() {
|
||||||
|
return worldProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FOR INTERNAL USE ONLY
|
||||||
|
*/
|
||||||
|
public static void registerProviders(
|
||||||
|
IWorldProvider worldProvider
|
||||||
|
) {
|
||||||
|
BaritoneAPI.worldProvider = worldProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FOR INTERNAL USE ONLY
|
||||||
|
*/
|
||||||
|
// @formatter:off
|
||||||
|
public static void registerDefaultBehaviors(
|
||||||
|
IFollowBehavior followBehavior,
|
||||||
|
ILookBehavior lookBehavior,
|
||||||
|
IMemoryBehavior memoryBehavior,
|
||||||
|
IMineBehavior mineBehavior,
|
||||||
|
IPathingBehavior pathingBehavior
|
||||||
|
) {
|
||||||
|
BaritoneAPI.followBehavior = followBehavior;
|
||||||
|
BaritoneAPI.lookBehavior = lookBehavior;
|
||||||
|
BaritoneAPI.memoryBehavior = memoryBehavior;
|
||||||
|
BaritoneAPI.mineBehavior = mineBehavior;
|
||||||
|
BaritoneAPI.pathingBehavior = pathingBehavior;
|
||||||
|
}
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
@@ -15,15 +15,17 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone;
|
package baritone.api;
|
||||||
|
|
||||||
import baritone.utils.Helper;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,6 +34,7 @@ import java.util.function.Consumer;
|
|||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class Settings {
|
public class Settings {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to break blocks
|
* Allow Baritone to break blocks
|
||||||
*/
|
*/
|
||||||
@@ -320,8 +323,9 @@ public class Settings {
|
|||||||
public Setting<Boolean> prefix = new Setting<>(false);
|
public Setting<Boolean> prefix = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true: can mine blocks when in inventory, chat, or tabbed away in ESC menu
|
* {@code true}: can mine blocks when in inventory, chat, or tabbed away in ESC menu
|
||||||
* false: works on cosmic prisons
|
* <p>
|
||||||
|
* {@code false}: works on cosmic prisons
|
||||||
* <p>
|
* <p>
|
||||||
* LOL
|
* LOL
|
||||||
*/
|
*/
|
||||||
@@ -389,9 +393,51 @@ public class Settings {
|
|||||||
public Setting<Integer> followRadius = new Setting<>(3);
|
public Setting<Integer> followRadius = new Setting<>(3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instead of Baritone logging to chat, set a custom consumer.
|
* The function that is called when Baritone will log to chat. This function can be added to
|
||||||
|
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||||
|
* {@link Setting#value};
|
||||||
*/
|
*/
|
||||||
public Setting<Consumer<ITextComponent>> logger = new Setting<>(new Helper() {}::addToChat);
|
public Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the current path
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the next path
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the blocks to break
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the blocks to place
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the blocks to walk into
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the best path so far
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the path to the most recent considered node
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color of the goal box
|
||||||
|
*/
|
||||||
|
public Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
|
||||||
|
|
||||||
public final Map<String, Setting<?>> byLowerName;
|
public final Map<String, Setting<?>> byLowerName;
|
||||||
public final List<Setting<?>> allSettings;
|
public final List<Setting<?>> allSettings;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.behavior;
|
||||||
|
|
||||||
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
|
import baritone.api.utils.interfaces.Toggleable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public interface IBehavior extends AbstractGameEventListener, Toggleable {}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.behavior;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public interface IFollowBehavior extends IBehavior {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the follow target to the specified entity;
|
||||||
|
*
|
||||||
|
* @param entity The entity to follow
|
||||||
|
*/
|
||||||
|
void follow(Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The entity that is currently being followed
|
||||||
|
*/
|
||||||
|
Entity following();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the follow behavior, this will clear the current follow target.
|
||||||
|
*/
|
||||||
|
void cancel();
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.behavior;
|
||||||
|
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public interface ILookBehavior extends IBehavior {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current {@link ILookBehavior} target to target
|
||||||
|
* the specified rotations on the next tick. If force is {@code true},
|
||||||
|
* then freeLook will be overriden and angles will be set regardless.
|
||||||
|
* If any sort of block interaction is required, force should be {@code true},
|
||||||
|
* otherwise, it should be {@code false};
|
||||||
|
*
|
||||||
|
* @param rotation The target rotations
|
||||||
|
* @param force Whether or not to "force" the rotations
|
||||||
|
*/
|
||||||
|
void updateTarget(Rotation rotation, boolean force);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.behavior;
|
||||||
|
|
||||||
|
import baritone.api.behavior.memory.IRememberedInventory;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public interface IMemoryBehavior extends IBehavior {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a remembered inventory by its block position.
|
||||||
|
*
|
||||||
|
* @param pos The position of the container block
|
||||||
|
* @return The remembered inventory
|
||||||
|
*/
|
||||||
|
IRememberedInventory getInventoryByPos(BlockPos pos);
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.behavior;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public interface IMineBehavior extends IBehavior {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin to search for and mine the specified blocks until
|
||||||
|
* the number of specified items to get from the blocks that
|
||||||
|
* are mined. This is based on the first target block to mine.
|
||||||
|
*
|
||||||
|
* @param quantity The number of items to get from blocks mined
|
||||||
|
* @param blocks The blocks to mine
|
||||||
|
*/
|
||||||
|
void mine(int quantity, String... blocks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin to search for and mine the specified blocks until
|
||||||
|
* the number of specified items to get from the blocks that
|
||||||
|
* are mined. This is based on the first target block to mine.
|
||||||
|
*
|
||||||
|
* @param quantity The number of items to get from blocks mined
|
||||||
|
* @param blocks The blocks to mine
|
||||||
|
*/
|
||||||
|
void mine(int quantity, Block... blocks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin to search for and mine the specified blocks.
|
||||||
|
*
|
||||||
|
* @param blocks The blocks to mine
|
||||||
|
*/
|
||||||
|
default void mine(String... blocks) {
|
||||||
|
this.mine(0, blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin to search for and mine the specified blocks.
|
||||||
|
*
|
||||||
|
* @param blocks The blocks to mine
|
||||||
|
*/
|
||||||
|
default void mine(Block... blocks) {
|
||||||
|
this.mine(0, blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the current mining task
|
||||||
|
*/
|
||||||
|
void cancel();
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.behavior;
|
||||||
|
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public interface IPathingBehavior extends IBehavior {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the estimated remaining ticks in the current pathing
|
||||||
|
* segment. Given that the return type is an optional, {@link Optional#empty()}
|
||||||
|
* will be returned in the case that there is no current segment being pathed.
|
||||||
|
*
|
||||||
|
* @return The estimated remaining ticks in the current segment.
|
||||||
|
*/
|
||||||
|
Optional<Double> ticksRemainingInSegment();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pathing goal.
|
||||||
|
*
|
||||||
|
* @param goal The pathing goal
|
||||||
|
*/
|
||||||
|
void setGoal(Goal goal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current pathing goal
|
||||||
|
*/
|
||||||
|
Goal getGoal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins pathing. Calculation will start in a new thread, and once completed,
|
||||||
|
* movement will commence. Returns whether or not the operation was successful.
|
||||||
|
*
|
||||||
|
* @return Whether or not the operation was successful
|
||||||
|
*/
|
||||||
|
boolean path();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether or not a path is currently being executed.
|
||||||
|
*/
|
||||||
|
boolean isPathing();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the pathing behavior or the current path calculation.
|
||||||
|
*/
|
||||||
|
void cancel();
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.behavior.memory;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public interface IRememberedInventory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The contents of this inventory
|
||||||
|
*/
|
||||||
|
List<ItemStack> getContents();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of slots in this inventory
|
||||||
|
*/
|
||||||
|
int getSize();
|
||||||
|
}
|
||||||
+2
-3
@@ -15,9 +15,8 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.utils.pathing;
|
package baritone.api.cache;
|
||||||
|
|
||||||
import baritone.utils.Helper;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 2:01 AM
|
* @since 8/4/2018 2:01 AM
|
||||||
*/
|
*/
|
||||||
public interface IBlockTypeAccess extends Helper {
|
public interface IBlockTypeAccess {
|
||||||
|
|
||||||
IBlockState getBlock(int x, int y, int z);
|
IBlockState getBlock(int x, int y, int z);
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/24/2018
|
||||||
|
*/
|
||||||
|
public interface ICachedRegion extends IBlockTypeAccess {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the block at the specified X and Z coordinates
|
||||||
|
* is cached in this world. Similar to {@link ICachedWorld#isCached(int, int)},
|
||||||
|
* however, the block coordinates should in on a scale from 0 to 511 (inclusive)
|
||||||
|
* because region sizes are 512x512 blocks.
|
||||||
|
*
|
||||||
|
* @see ICachedWorld#isCached(int, int)
|
||||||
|
*
|
||||||
|
* @param blockX The block X coordinate
|
||||||
|
* @param blockZ The block Z coordinate
|
||||||
|
* @return Whether or not the specified XZ location is cached
|
||||||
|
*/
|
||||||
|
boolean isCached(int blockX, int blockZ);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The X coordinate of this region
|
||||||
|
*/
|
||||||
|
int getX();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Z coordinate of this region
|
||||||
|
*/
|
||||||
|
int getZ();
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.cache;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/24/2018
|
||||||
|
*/
|
||||||
|
public interface ICachedWorld {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the region at the specified region coordinates
|
||||||
|
*
|
||||||
|
* @param regionX The region X coordinate
|
||||||
|
* @param regionZ The region Z coordinate
|
||||||
|
* @return The region located at the specified coordinates
|
||||||
|
*/
|
||||||
|
ICachedRegion getRegion(int regionX, int regionZ);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues the specified chunk for packing. This entails reading the contents
|
||||||
|
* of the chunk, then packing the data into the 2-bit format, and storing that
|
||||||
|
* in this cached world.
|
||||||
|
*
|
||||||
|
* @param chunk The chunk to pack and store
|
||||||
|
*/
|
||||||
|
void queueForPacking(Chunk chunk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the block at the specified X and Z coordinates
|
||||||
|
* is cached in this world.
|
||||||
|
*
|
||||||
|
* @param blockX The block X coordinate
|
||||||
|
* @param blockZ The block Z coordinate
|
||||||
|
* @return Whether or not the specified XZ location is cached
|
||||||
|
*/
|
||||||
|
boolean isCached(int blockX, int blockZ);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans the cached chunks for location of the specified special block. The
|
||||||
|
* information that is returned by this method may not be up to date, because
|
||||||
|
* older cached chunks can contain data that is much more likely to have changed.
|
||||||
|
*
|
||||||
|
* @param block The special block to search for
|
||||||
|
* @param maximum The maximum number of position results to receive
|
||||||
|
* @param maxRegionDistanceSq The maximum region distance, squared
|
||||||
|
* @return The locations found that match the special block
|
||||||
|
*/
|
||||||
|
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads all of the cached regions in this world from disk. Anything that is not saved
|
||||||
|
* will be lost. This operation does not execute in a new thread by default.
|
||||||
|
*/
|
||||||
|
void reloadAllFromDisk();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves all of the cached regions in this world to disk. This operation does not execute
|
||||||
|
* in a new thread by default.
|
||||||
|
*/
|
||||||
|
void save();
|
||||||
|
}
|
||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.cache;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A marker for a position in the world.
|
||||||
|
*
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/24/2018
|
||||||
|
*/
|
||||||
|
public interface IWaypoint {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The label for this waypoint
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tag for this waypoint. The tag is a category
|
||||||
|
* for the waypoint in a sense, it describes the source of
|
||||||
|
* the waypoint.
|
||||||
|
*
|
||||||
|
* @return The waypoint tag
|
||||||
|
*/
|
||||||
|
Tag getTag();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unix epoch time in milliseconds that this waypoint
|
||||||
|
* was created. This value should only be set once, when the waypoint
|
||||||
|
* is initially created, and not when it is being loaded from file.
|
||||||
|
*
|
||||||
|
* @return The unix epoch milliseconds that this waypoint was created
|
||||||
|
*/
|
||||||
|
long getCreationTimestamp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the actual block position of this waypoint.
|
||||||
|
*
|
||||||
|
* @return The block position of this waypoint
|
||||||
|
*/
|
||||||
|
BlockPos getLocation();
|
||||||
|
|
||||||
|
enum Tag {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag indicating a position explictly marked as a home base
|
||||||
|
*/
|
||||||
|
HOME("home", "base"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag indicating a position that the local player has died at
|
||||||
|
*/
|
||||||
|
DEATH("death"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag indicating a bed position
|
||||||
|
*/
|
||||||
|
BED("bed", "spawn"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag indicating that the waypoint was user-created
|
||||||
|
*/
|
||||||
|
USER("user");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of all of the
|
||||||
|
*/
|
||||||
|
private static final List<Tag> TAG_LIST = Collections.unmodifiableList(Arrays.asList(Tag.values()));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The names for the tag, anything that the tag can be referred to as.
|
||||||
|
*/
|
||||||
|
private final String[] names;
|
||||||
|
|
||||||
|
Tag(String... names) {
|
||||||
|
this.names = names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a tag from one of the names that could be used to identify said tag.
|
||||||
|
*
|
||||||
|
* @param name The name of the tag
|
||||||
|
* @return The tag, if one is found, otherwise, {@code null}
|
||||||
|
*/
|
||||||
|
public static Tag fromString(String name) {
|
||||||
|
return TAG_LIST.stream().filter(tag -> ArrayUtils.contains(tag.names, name.toLowerCase())).findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.cache;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/24/2018
|
||||||
|
*/
|
||||||
|
public interface IWaypointCollection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a waypoint to this collection
|
||||||
|
*
|
||||||
|
* @param waypoint The waypoint
|
||||||
|
*/
|
||||||
|
void addWaypoint(IWaypoint waypoint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a waypoint from this collection
|
||||||
|
*
|
||||||
|
* @param waypoint The waypoint
|
||||||
|
*/
|
||||||
|
void removeWaypoint(IWaypoint waypoint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the most recently created waypoint by the specified {@link IWaypoint.Tag}
|
||||||
|
*
|
||||||
|
* @param tag The tag
|
||||||
|
* @return The most recently created waypoint with the specified tag
|
||||||
|
*/
|
||||||
|
IWaypoint getMostRecentByTag(IWaypoint.Tag tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all of the waypoints that have the specified tag
|
||||||
|
*
|
||||||
|
* @see IWaypointCollection#getAllWaypoints()
|
||||||
|
*
|
||||||
|
* @param tag The tag
|
||||||
|
* @return All of the waypoints with the specified tag
|
||||||
|
*/
|
||||||
|
Set<IWaypoint> getByTag(IWaypoint.Tag tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all of the waypoints in this collection, regardless of the tag.
|
||||||
|
*
|
||||||
|
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
|
||||||
|
*
|
||||||
|
* @return All of the waypoints in this collection
|
||||||
|
*/
|
||||||
|
Set<IWaypoint> getAllWaypoints();
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/24/2018
|
||||||
|
*/
|
||||||
|
public interface IWorldData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cached world for this world. A cached world is a simplified format
|
||||||
|
* of a regular world, intended for use on multiplayer servers where chunks are not
|
||||||
|
* traditionally stored to disk, allowing for long distance pathing with minimal disk usage.
|
||||||
|
*/
|
||||||
|
ICachedWorld getCachedWorld();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the waypoint collection for this world.
|
||||||
|
*
|
||||||
|
* @return The waypoint collection for this world
|
||||||
|
*/
|
||||||
|
IWaypointCollection getWaypoints();
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/24/2018
|
||||||
|
*/
|
||||||
|
public interface IWorldProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data of the currently loaded world
|
||||||
|
*
|
||||||
|
* @return The current world data
|
||||||
|
*/
|
||||||
|
IWorldData getCurrentWorld();
|
||||||
|
}
|
||||||
+12
-7
@@ -15,9 +15,8 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import baritone.pathing.movement.ActionCosts;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,22 +24,28 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public interface Goal extends ActionCosts {
|
public interface Goal {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the specified position
|
* Returns whether or not the specified position
|
||||||
* meets the requirement for this goal based.
|
* meets the requirement for this goal based.
|
||||||
*
|
*
|
||||||
* @param pos The position
|
|
||||||
* @return Whether or not it satisfies this goal
|
* @return Whether or not it satisfies this goal
|
||||||
*/
|
*/
|
||||||
boolean isInGoal(BlockPos pos);
|
boolean isInGoal(int x, int y, int z);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimate the number of ticks it will take to get to the goal
|
* Estimate the number of ticks it will take to get to the goal
|
||||||
*
|
*
|
||||||
* @param pos The
|
|
||||||
* @return The estimate number of ticks to satisfy the goal
|
* @return The estimate number of ticks to satisfy the goal
|
||||||
*/
|
*/
|
||||||
double heuristic(BlockPos pos);
|
double heuristic(int x, int y, int z);
|
||||||
|
|
||||||
|
default boolean isInGoal(BlockPos pos) {
|
||||||
|
return isInGoal(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
default double heuristic(BlockPos pos) {
|
||||||
|
return heuristic(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+8
-13
@@ -15,28 +15,23 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
public class GoalAxis implements Goal {
|
public class GoalAxis implements Goal {
|
||||||
|
|
||||||
private static final double SQRT_2_OVER_2 = Math.sqrt(2) / 2;
|
private static final double SQRT_2_OVER_2 = Math.sqrt(2) / 2;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
int x = pos.getX();
|
return y == BaritoneAPI.getSettings().axisHeight.get() && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
|
||||||
int y = pos.getY();
|
|
||||||
int z = pos.getZ();
|
|
||||||
return y == Baritone.settings().axisHeight.get() && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x0, int y, int z0) {
|
||||||
int x = Math.abs(pos.getX());
|
int x = Math.abs(x0);
|
||||||
int y = pos.getY();
|
int z = Math.abs(z0);
|
||||||
int z = Math.abs(pos.getZ());
|
|
||||||
|
|
||||||
int shrt = Math.min(x, z);
|
int shrt = Math.min(x, z);
|
||||||
int lng = Math.max(x, z);
|
int lng = Math.max(x, z);
|
||||||
@@ -44,7 +39,7 @@ public class GoalAxis implements Goal {
|
|||||||
|
|
||||||
double flatAxisDistance = Math.min(x, Math.min(z, diff * SQRT_2_OVER_2));
|
double flatAxisDistance = Math.min(x, Math.min(z, diff * SQRT_2_OVER_2));
|
||||||
|
|
||||||
return flatAxisDistance * Baritone.settings().costHeuristic.get() + GoalYLevel.calculate(Baritone.settings().axisHeight.get(), y);
|
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.get() + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.get(), y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
+8
-8
@@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import baritone.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,15 +53,15 @@ public class GoalBlock implements Goal, IGoalRenderPos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return pos.getX() == this.x && pos.getY() == this.y && pos.getZ() == this.z;
|
return x == this.x && y == this.y && z == this.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x, int y, int z) {
|
||||||
int xDiff = pos.getX() - this.x;
|
int xDiff = x - this.x;
|
||||||
int yDiff = pos.getY() - this.y;
|
int yDiff = y - this.y;
|
||||||
int zDiff = pos.getZ() - this.z;
|
int zDiff = z - this.z;
|
||||||
return calculate(xDiff, yDiff, zDiff);
|
return calculate(xDiff, yDiff, zDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
+11
-5
@@ -15,7 +15,7 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@@ -49,15 +49,21 @@ public class GoalComposite implements Goal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return Arrays.stream(this.goals).anyMatch(goal -> goal.isInGoal(pos));
|
for (Goal goal : goals) {
|
||||||
|
if (goal.isInGoal(x, y, z)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x, int y, int z) {
|
||||||
double min = Double.MAX_VALUE;
|
double min = Double.MAX_VALUE;
|
||||||
for (Goal g : goals) {
|
for (Goal g : goals) {
|
||||||
min = Math.min(min, g.heuristic(pos)); // whichever is closest
|
// TODO technically this isn't admissible...?
|
||||||
|
min = Math.min(min, g.heuristic(x, y, z)); // whichever is closest
|
||||||
}
|
}
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
+11
-12
@@ -15,10 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import baritone.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
|
||||||
@@ -41,14 +40,14 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPos getGoalPos() {
|
public BlockPos getGoalPos() {
|
||||||
return new BetterBlockPos(x, y, z);
|
return new BlockPos(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
int xDiff = pos.getX() - this.x;
|
int xDiff = x - this.x;
|
||||||
int yDiff = pos.getY() - this.y;
|
int yDiff = y - this.y;
|
||||||
int zDiff = pos.getZ() - this.z;
|
int zDiff = z - this.z;
|
||||||
if (yDiff < 0) {
|
if (yDiff < 0) {
|
||||||
yDiff++;
|
yDiff++;
|
||||||
}
|
}
|
||||||
@@ -56,10 +55,10 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x, int y, int z) {
|
||||||
int xDiff = pos.getX() - this.x;
|
int xDiff = x - this.x;
|
||||||
int yDiff = pos.getY() - this.y;
|
int yDiff = y - this.y;
|
||||||
int zDiff = pos.getZ() - this.z;
|
int zDiff = z - this.z;
|
||||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
+12
-12
@@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import baritone.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class GoalNear implements Goal, IGoalRenderPos {
|
public class GoalNear implements Goal, IGoalRenderPos {
|
||||||
@@ -34,19 +34,19 @@ public class GoalNear implements Goal, IGoalRenderPos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
int diffX = x - pos.getX();
|
int xDiff = x - this.x;
|
||||||
int diffY = y - pos.getY();
|
int yDiff = y - this.y;
|
||||||
int diffZ = z - pos.getZ();
|
int zDiff = z - this.z;
|
||||||
return diffX * diffX + diffY * diffY + diffZ * diffZ <= rangeSq;
|
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff <= rangeSq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x, int y, int z) {
|
||||||
int diffX = x - pos.getX();
|
int xDiff = x - this.x;
|
||||||
int diffY = y - pos.getY();
|
int yDiff = y - this.y;
|
||||||
int diffZ = z - pos.getZ();
|
int zDiff = z - this.z;
|
||||||
return GoalBlock.calculate(diffX, diffY, diffZ);
|
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
+6
-6
@@ -15,7 +15,7 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@@ -41,10 +41,10 @@ public class GoalRunAway implements Goal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
for (BlockPos p : from) {
|
for (BlockPos p : from) {
|
||||||
int diffX = pos.getX() - p.getX();
|
int diffX = x - p.getX();
|
||||||
int diffZ = pos.getZ() - p.getZ();
|
int diffZ = z - p.getZ();
|
||||||
double distSq = diffX * diffX + diffZ * diffZ;
|
double distSq = diffX * diffX + diffZ * diffZ;
|
||||||
if (distSq < distanceSq) {
|
if (distSq < distanceSq) {
|
||||||
return false;
|
return false;
|
||||||
@@ -54,10 +54,10 @@ public class GoalRunAway implements Goal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {//mostly copied from GoalBlock
|
public double heuristic(int x, int y, int z) {//mostly copied from GoalBlock
|
||||||
double min = Double.MAX_VALUE;
|
double min = Double.MAX_VALUE;
|
||||||
for (BlockPos p : from) {
|
for (BlockPos p : from) {
|
||||||
double h = GoalXZ.calculate(p.getX() - pos.getX(), p.getZ() - pos.getZ());
|
double h = GoalXZ.calculate(p.getX() - x, p.getZ() - z);
|
||||||
if (h < min) {
|
if (h < min) {
|
||||||
min = h;
|
min = h;
|
||||||
}
|
}
|
||||||
+8
-8
@@ -15,9 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import baritone.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,18 +54,18 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return pos.getX() == this.x && (pos.getY() == this.y || pos.getY() == this.y - 1) && pos.getZ() == this.z;
|
return x == this.x && (y == this.y || y == this.y - 1) && z == this.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x, int y, int z) {
|
||||||
double xDiff = pos.getX() - this.x;
|
int xDiff = x - this.x;
|
||||||
int yDiff = pos.getY() - this.y;
|
int yDiff = y - this.y;
|
||||||
|
int zDiff = z - this.z;
|
||||||
if (yDiff < 0) {
|
if (yDiff < 0) {
|
||||||
yDiff++;
|
yDiff++;
|
||||||
}
|
}
|
||||||
double zDiff = pos.getZ() - this.z;
|
|
||||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
+9
-11
@@ -15,11 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.utils.Utils;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
@@ -48,14 +46,14 @@ public class GoalXZ implements Goal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return pos.getX() == x && pos.getZ() == z;
|
return x == this.x && z == this.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {//mostly copied from GoalBlock
|
public double heuristic(int x, int y, int z) {//mostly copied from GoalBlock
|
||||||
double xDiff = pos.getX() - this.x;
|
int xDiff = x - this.x;
|
||||||
double zDiff = pos.getZ() - this.z;
|
int zDiff = z - this.z;
|
||||||
return calculate(xDiff, zDiff);
|
return calculate(xDiff, zDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,11 +80,11 @@ public class GoalXZ implements Goal {
|
|||||||
diagonal = z;
|
diagonal = z;
|
||||||
}
|
}
|
||||||
diagonal *= SQRT_2;
|
diagonal *= SQRT_2;
|
||||||
return (diagonal + straight) * Baritone.settings().costHeuristic.get(); // big TODO tune
|
return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.get(); // big TODO tune
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {
|
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {
|
||||||
float theta = (float) Utils.degToRad(yaw);
|
float theta = (float) Math.toRadians(yaw);
|
||||||
double x = origin.x - MathHelper.sin(theta) * distance;
|
double x = origin.x - MathHelper.sin(theta) * distance;
|
||||||
double z = origin.z + MathHelper.cos(theta) * distance;
|
double z = origin.z + MathHelper.cos(theta) * distance;
|
||||||
return new GoalXZ((int) x, (int) z);
|
return new GoalXZ((int) x, (int) z);
|
||||||
+7
-7
@@ -15,16 +15,16 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useful for mining (getting to diamond / iron level)
|
* Useful for mining (getting to diamond / iron level)
|
||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class GoalYLevel implements Goal {
|
public class GoalYLevel implements Goal, ActionCosts {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The target Y level
|
* The target Y level
|
||||||
@@ -36,13 +36,13 @@ public class GoalYLevel implements Goal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return pos.getY() == level;
|
return y == level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x, int y, int z) {
|
||||||
return calculate(level, pos.getY());
|
return calculate(level, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double calculate(int goalY, int currentY) {
|
public static double calculate(int goalY, int currentY) {
|
||||||
+29
-2
@@ -15,9 +15,36 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.movement;
|
package baritone.api.pathing.movement;
|
||||||
|
|
||||||
|
public interface ActionCosts {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These costs are measured roughly in ticks btw
|
||||||
|
*/
|
||||||
|
double WALK_ONE_BLOCK_COST = 20 / 4.317; // 4.633
|
||||||
|
double WALK_ONE_IN_WATER_COST = 20 / 2.2;
|
||||||
|
double WALK_ONE_OVER_SOUL_SAND_COST = WALK_ONE_BLOCK_COST * 2; // 0.4 in BlockSoulSand but effectively about half
|
||||||
|
double SPRINT_ONE_OVER_SOUL_SAND_COST = WALK_ONE_OVER_SOUL_SAND_COST * 0.75;
|
||||||
|
double LADDER_UP_ONE_COST = 20 / 2.35;
|
||||||
|
double LADDER_DOWN_ONE_COST = 20 / 3.0;
|
||||||
|
double SNEAK_ONE_BLOCK_COST = 20 / 1.3;
|
||||||
|
double SPRINT_ONE_BLOCK_COST = 20 / 5.612; // 3.564
|
||||||
|
/**
|
||||||
|
* To walk off an edge you need to walk 0.5 to the edge then 0.3 to start falling off
|
||||||
|
*/
|
||||||
|
double WALK_OFF_BLOCK_COST = WALK_ONE_BLOCK_COST * 0.8;
|
||||||
|
/**
|
||||||
|
* To walk the rest of the way to be centered on the new block
|
||||||
|
*/
|
||||||
|
double CENTER_AFTER_FALL_COST = WALK_ONE_BLOCK_COST - WALK_OFF_BLOCK_COST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* don't make this Double.MAX_VALUE because it's added to other things, maybe other COST_INFs,
|
||||||
|
* and that would make it overflow to negative
|
||||||
|
*/
|
||||||
|
double COST_INF = 1000000;
|
||||||
|
|
||||||
public interface ActionCostsButOnlyTheOnesThatMakeMickeyDieInside {
|
|
||||||
double[] FALL_N_BLOCKS_COST = generateFallNBlocksCost();
|
double[] FALL_N_BLOCKS_COST = generateFallNBlocksCost();
|
||||||
|
|
||||||
double FALL_1_25_BLOCKS_COST = distanceToTicks(1.25);
|
double FALL_1_25_BLOCKS_COST = distanceToTicks(1.25);
|
||||||
+6
-6
@@ -15,13 +15,13 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
import net.minecraft.util.Tuple;
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/23/2018
|
||||||
|
*/
|
||||||
|
public class Logger {
|
||||||
|
|
||||||
public class Rotation extends Tuple<Float, Float> {
|
|
||||||
|
|
||||||
public Rotation(Float yaw, Float pitch) {
|
|
||||||
super(yaw, pitch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/25/2018
|
||||||
|
*/
|
||||||
|
public class Rotation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The yaw angle of this Rotation
|
||||||
|
*/
|
||||||
|
private float yaw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pitch angle of this Rotation
|
||||||
|
*/
|
||||||
|
private float pitch;
|
||||||
|
|
||||||
|
public Rotation(float yaw, float pitch) {
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The yaw of this rotation
|
||||||
|
*/
|
||||||
|
public float getYaw() {
|
||||||
|
return this.yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The pitch of this rotation
|
||||||
|
*/
|
||||||
|
public float getPitch() {
|
||||||
|
return this.pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the yaw/pitch of the specified rotations to this
|
||||||
|
* rotation's yaw/pitch, and returns the result.
|
||||||
|
*
|
||||||
|
* @param other Another rotation
|
||||||
|
* @return The result from adding the other rotation to this rotation
|
||||||
|
*/
|
||||||
|
public Rotation add(Rotation other) {
|
||||||
|
return new Rotation(
|
||||||
|
this.yaw + other.yaw,
|
||||||
|
this.pitch + other.pitch
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subtracts the yaw/pitch of the specified rotations from this
|
||||||
|
* rotation's yaw/pitch, and returns the result.
|
||||||
|
*
|
||||||
|
* @param other Another rotation
|
||||||
|
* @return The result from subtracting the other rotation from this rotation
|
||||||
|
*/
|
||||||
|
public Rotation subtract(Rotation other) {
|
||||||
|
return new Rotation(
|
||||||
|
this.yaw - other.yaw,
|
||||||
|
this.pitch - other.pitch
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A copy of this rotation with the pitch clamped
|
||||||
|
*/
|
||||||
|
public Rotation clamp() {
|
||||||
|
return new Rotation(
|
||||||
|
this.yaw,
|
||||||
|
RotationUtils.clampPitch(this.pitch)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A copy of this rotation with the yaw normalized
|
||||||
|
*/
|
||||||
|
public Rotation normalize() {
|
||||||
|
return new Rotation(
|
||||||
|
RotationUtils.normalizeYaw(this.yaw),
|
||||||
|
this.pitch
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A copy of this rotation with the pitch clamped and the yaw normalized
|
||||||
|
*/
|
||||||
|
public Rotation normalizeAndClamp() {
|
||||||
|
return new Rotation(
|
||||||
|
RotationUtils.normalizeYaw(this.yaw),
|
||||||
|
RotationUtils.clampPitch(this.pitch)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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.api.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/25/2018
|
||||||
|
*/
|
||||||
|
public final class RotationUtils {
|
||||||
|
|
||||||
|
private RotationUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamps the specified pitch value between -90 and 90.
|
||||||
|
*
|
||||||
|
* @param pitch The input pitch
|
||||||
|
* @return The clamped pitch
|
||||||
|
*/
|
||||||
|
public static float clampPitch(float pitch) {
|
||||||
|
return Math.max(-90, Math.min(90, pitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the specified yaw value between -180 and 180.
|
||||||
|
*
|
||||||
|
* @param yaw The input yaw
|
||||||
|
* @return The normalized yaw
|
||||||
|
*/
|
||||||
|
public static float normalizeYaw(float yaw) {
|
||||||
|
float newYaw = yaw % 360F;
|
||||||
|
if (newYaw < -180F) {
|
||||||
|
newYaw += 360F;
|
||||||
|
}
|
||||||
|
if (newYaw >= 180F) {
|
||||||
|
newYaw -= 360F;
|
||||||
|
}
|
||||||
|
return newYaw;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.utils.interfaces;
|
package baritone.api.utils.interfaces;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@ 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.behavior.PathingBehavior;
|
||||||
|
import baritone.utils.BaritoneAutoTest;
|
||||||
import baritone.utils.ExampleBaritoneControl;
|
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;
|
||||||
@@ -39,6 +40,7 @@ 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.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,11 +61,22 @@ public class MixinMinecraft {
|
|||||||
method = "init",
|
method = "init",
|
||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void init(CallbackInfo ci) {
|
private void postInit(CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.init();
|
Baritone.INSTANCE.init();
|
||||||
ExampleBaritoneControl.INSTANCE.initAndRegister();
|
ExampleBaritoneControl.INSTANCE.initAndRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "init",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/client/Minecraft.startTimerHackThread()V"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void preInit(CallbackInfo ci) {
|
||||||
|
BaritoneAutoTest.INSTANCE.onPreInit();
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "runTick",
|
method = "runTick",
|
||||||
at = @At(
|
at = @At(
|
||||||
|
|||||||
@@ -17,10 +17,13 @@
|
|||||||
|
|
||||||
package baritone;
|
package baritone;
|
||||||
|
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.BaritoneAPI;
|
||||||
|
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.event.GameEventHandler;
|
import baritone.event.GameEventHandler;
|
||||||
|
import baritone.utils.BaritoneAutoTest;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
@@ -80,7 +83,13 @@ public enum Baritone {
|
|||||||
this.threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
this.threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||||
this.gameEventHandler = new GameEventHandler();
|
this.gameEventHandler = new GameEventHandler();
|
||||||
this.inputOverrideHandler = new InputOverrideHandler();
|
this.inputOverrideHandler = new InputOverrideHandler();
|
||||||
this.settings = new Settings();
|
|
||||||
|
// Acquire the "singleton" instance of the settings directly from the API
|
||||||
|
// We might want to change this...
|
||||||
|
this.settings = BaritoneAPI.getSettings();
|
||||||
|
|
||||||
|
BaritoneAPI.registerProviders(WorldProvider.INSTANCE);
|
||||||
|
|
||||||
this.behaviors = new ArrayList<>();
|
this.behaviors = new ArrayList<>();
|
||||||
{
|
{
|
||||||
registerBehavior(PathingBehavior.INSTANCE);
|
registerBehavior(PathingBehavior.INSTANCE);
|
||||||
@@ -89,6 +98,19 @@ public enum Baritone {
|
|||||||
registerBehavior(LocationTrackingBehavior.INSTANCE);
|
registerBehavior(LocationTrackingBehavior.INSTANCE);
|
||||||
registerBehavior(FollowBehavior.INSTANCE);
|
registerBehavior(FollowBehavior.INSTANCE);
|
||||||
registerBehavior(MineBehavior.INSTANCE);
|
registerBehavior(MineBehavior.INSTANCE);
|
||||||
|
|
||||||
|
// TODO: Clean this up
|
||||||
|
// Maybe combine this call in someway with the registerBehavior calls?
|
||||||
|
BaritoneAPI.registerDefaultBehaviors(
|
||||||
|
FollowBehavior.INSTANCE,
|
||||||
|
LookBehavior.INSTANCE,
|
||||||
|
MemoryBehavior.INSTANCE,
|
||||||
|
MineBehavior.INSTANCE,
|
||||||
|
PathingBehavior.INSTANCE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (BaritoneAutoTest.ENABLE_AUTO_TEST && "true".equals(System.getenv("BARITONE_AUTO_TEST"))) {
|
||||||
|
registerEventListener(BaritoneAutoTest.INSTANCE);
|
||||||
}
|
}
|
||||||
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||||
if (!Files.exists(dir.toPath())) {
|
if (!Files.exists(dir.toPath())) {
|
||||||
|
|||||||
+3
-4
@@ -15,10 +15,9 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.api.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.api.event.listener.AbstractGameEventListener;
|
import baritone.api.behavior.IBehavior;
|
||||||
import baritone.api.utils.interfaces.Toggleable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type of game event listener that can be toggled.
|
* A type of game event listener that can be toggled.
|
||||||
@@ -26,7 +25,7 @@ import baritone.api.utils.interfaces.Toggleable;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018 6:29 PM
|
* @since 8/1/2018 6:29 PM
|
||||||
*/
|
*/
|
||||||
public class Behavior implements AbstractGameEventListener, Toggleable {
|
public class Behavior implements IBehavior {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not this behavior is enabled
|
* Whether or not this behavior is enabled
|
||||||
@@ -18,10 +18,10 @@
|
|||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.behavior.IFollowBehavior;
|
||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.pathing.goals.GoalNear;
|
import baritone.api.pathing.goals.GoalNear;
|
||||||
import baritone.pathing.goals.GoalXZ;
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -31,7 +31,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public final class FollowBehavior extends Behavior implements Helper {
|
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
|
||||||
|
|
||||||
public static final FollowBehavior INSTANCE = new FollowBehavior();
|
public static final FollowBehavior INSTANCE = new FollowBehavior();
|
||||||
|
|
||||||
@@ -42,6 +42,7 @@ public final class FollowBehavior extends Behavior implements Helper {
|
|||||||
@Override
|
@Override
|
||||||
public void onTick(TickEvent event) {
|
public void onTick(TickEvent event) {
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
following = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (following == null) {
|
if (following == null) {
|
||||||
@@ -60,14 +61,17 @@ public final class FollowBehavior extends Behavior implements Helper {
|
|||||||
PathingBehavior.INSTANCE.path();
|
PathingBehavior.INSTANCE.path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void follow(Entity entity) {
|
public void follow(Entity entity) {
|
||||||
this.following = entity;
|
this.following = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Entity following() {
|
public Entity following() {
|
||||||
return this.following;
|
return this.following;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
PathingBehavior.INSTANCE.cancel();
|
PathingBehavior.INSTANCE.cancel();
|
||||||
follow(null);
|
follow(null);
|
||||||
|
|||||||
@@ -17,10 +17,9 @@
|
|||||||
|
|
||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.event.events.BlockInteractEvent;
|
||||||
import baritone.cache.Waypoint;
|
import baritone.cache.Waypoint;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.api.event.events.BlockInteractEvent;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.block.BlockBed;
|
import net.minecraft.block.BlockBed;
|
||||||
@@ -43,12 +42,12 @@ public final class LocationTrackingBehavior extends Behavior implements Helper {
|
|||||||
@Override
|
@Override
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
public void onBlockInteract(BlockInteractEvent event) {
|
||||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().waypoints.addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerDeath() {
|
public void onPlayerDeath() {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().waypoints.addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,14 +18,14 @@
|
|||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.Settings;
|
import baritone.api.Settings;
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.behavior.ILookBehavior;
|
||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
import baritone.api.event.events.RotationMoveEvent;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.Rotation;
|
|
||||||
|
|
||||||
public final class LookBehavior extends Behavior implements Helper {
|
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
|
||||||
|
|
||||||
public static final LookBehavior INSTANCE = new LookBehavior();
|
public static final LookBehavior INSTANCE = new LookBehavior();
|
||||||
|
|
||||||
@@ -51,6 +51,7 @@ public final class LookBehavior extends Behavior implements Helper {
|
|||||||
|
|
||||||
private LookBehavior() {}
|
private LookBehavior() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void updateTarget(Rotation target, boolean force) {
|
public void updateTarget(Rotation target, boolean force) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.force = force || !Baritone.settings().freeLook.get();
|
this.force = force || !Baritone.settings().freeLook.get();
|
||||||
@@ -68,9 +69,9 @@ public final class LookBehavior extends Behavior implements Helper {
|
|||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case PRE: {
|
case PRE: {
|
||||||
if (this.force) {
|
if (this.force) {
|
||||||
player().rotationYaw = this.target.getFirst();
|
player().rotationYaw = this.target.getYaw();
|
||||||
float oldPitch = player().rotationPitch;
|
float oldPitch = player().rotationPitch;
|
||||||
float desiredPitch = this.target.getSecond();
|
float desiredPitch = this.target.getPitch();
|
||||||
player().rotationPitch = desiredPitch;
|
player().rotationPitch = desiredPitch;
|
||||||
if (desiredPitch == oldPitch) {
|
if (desiredPitch == oldPitch) {
|
||||||
nudgeToLevel();
|
nudgeToLevel();
|
||||||
@@ -78,7 +79,7 @@ public final class LookBehavior extends Behavior implements Helper {
|
|||||||
this.target = null;
|
this.target = null;
|
||||||
} else if (silent) {
|
} else if (silent) {
|
||||||
this.lastYaw = player().rotationYaw;
|
this.lastYaw = player().rotationYaw;
|
||||||
player().rotationYaw = this.target.getFirst();
|
player().rotationYaw = this.target.getYaw();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -92,7 +93,6 @@ public final class LookBehavior extends Behavior implements Helper {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
new Thread().start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -101,7 +101,7 @@ public final class LookBehavior extends Behavior implements Helper {
|
|||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case PRE:
|
case PRE:
|
||||||
this.lastYaw = player().rotationYaw;
|
this.lastYaw = player().rotationYaw;
|
||||||
player().rotationYaw = this.target.getFirst();
|
player().rotationYaw = this.target.getYaw();
|
||||||
break;
|
break;
|
||||||
case POST:
|
case POST:
|
||||||
player().rotationYaw = this.lastYaw;
|
player().rotationYaw = this.lastYaw;
|
||||||
|
|||||||
@@ -17,7 +17,11 @@
|
|||||||
|
|
||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.utils.*;
|
import baritone.api.utils.Rotation;
|
||||||
|
import baritone.utils.BlockStateInterface;
|
||||||
|
import baritone.utils.Helper;
|
||||||
|
import baritone.utils.RayTraceUtils;
|
||||||
|
import baritone.utils.Utils;
|
||||||
import net.minecraft.block.BlockFire;
|
import net.minecraft.block.BlockFire;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
@@ -47,10 +51,10 @@ public final class LookBehaviorUtils implements Helper {
|
|||||||
* @return vector of the rotation
|
* @return vector of the rotation
|
||||||
*/
|
*/
|
||||||
public static Vec3d calcVec3dFromRotation(Rotation rotation) {
|
public static Vec3d calcVec3dFromRotation(Rotation rotation) {
|
||||||
float f = MathHelper.cos(-rotation.getFirst() * (float) DEG_TO_RAD - (float) Math.PI);
|
float f = MathHelper.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
|
||||||
float f1 = MathHelper.sin(-rotation.getFirst() * (float) DEG_TO_RAD - (float) Math.PI);
|
float f1 = MathHelper.sin(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
|
||||||
float f2 = -MathHelper.cos(-rotation.getSecond() * (float) DEG_TO_RAD);
|
float f2 = -MathHelper.cos(-rotation.getPitch() * (float) DEG_TO_RAD);
|
||||||
float f3 = MathHelper.sin(-rotation.getSecond() * (float) DEG_TO_RAD);
|
float f3 = MathHelper.sin(-rotation.getPitch() * (float) DEG_TO_RAD);
|
||||||
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
|
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.behavior.IMemoryBehavior;
|
||||||
|
import baritone.api.behavior.memory.IRememberedInventory;
|
||||||
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;
|
||||||
@@ -38,7 +39,7 @@ import java.util.*;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/6/2018 9:47 PM
|
* @since 8/6/2018 9:47 PM
|
||||||
*/
|
*/
|
||||||
public final class MemoryBehavior extends Behavior implements Helper {
|
public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper {
|
||||||
|
|
||||||
public static MemoryBehavior INSTANCE = new MemoryBehavior();
|
public static MemoryBehavior INSTANCE = new MemoryBehavior();
|
||||||
|
|
||||||
@@ -128,6 +129,7 @@ public final class MemoryBehavior extends Behavior implements Helper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final RememberedInventory getInventoryByPos(BlockPos pos) {
|
public final RememberedInventory getInventoryByPos(BlockPos pos) {
|
||||||
return this.rememberedInventories.get(pos);
|
return this.rememberedInventories.get(pos);
|
||||||
}
|
}
|
||||||
@@ -170,7 +172,7 @@ public final class MemoryBehavior extends Behavior implements Helper {
|
|||||||
* <p>
|
* <p>
|
||||||
* Associated with a {@link BlockPos} in {@link MemoryBehavior#rememberedInventories}.
|
* Associated with a {@link BlockPos} in {@link MemoryBehavior#rememberedInventories}.
|
||||||
*/
|
*/
|
||||||
public static class RememberedInventory {
|
public static class RememberedInventory implements IRememberedInventory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of items in the inventory
|
* The list of items in the inventory
|
||||||
@@ -191,11 +193,14 @@ public final class MemoryBehavior extends Behavior implements Helper {
|
|||||||
this.items = new ArrayList<>();
|
this.items = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @return The list of items in the inventory
|
public final List<ItemStack> getContents() {
|
||||||
*/
|
|
||||||
public final List<ItemStack> getItems() {
|
|
||||||
return this.items;
|
return this.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int getSize() {
|
||||||
|
return this.size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,17 +18,17 @@
|
|||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.behavior.IMineBehavior;
|
||||||
import baritone.api.event.events.PathEvent;
|
import baritone.api.event.events.PathEvent;
|
||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
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.goals.Goal;
|
import baritone.api.pathing.goals.GoalBlock;
|
||||||
import baritone.pathing.goals.GoalBlock;
|
import baritone.api.pathing.goals.GoalComposite;
|
||||||
import baritone.pathing.goals.GoalComposite;
|
import baritone.api.pathing.goals.GoalTwoBlocks;
|
||||||
import baritone.pathing.goals.GoalTwoBlocks;
|
|
||||||
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;
|
||||||
@@ -46,7 +46,7 @@ import java.util.stream.Collectors;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public final class MineBehavior extends Behavior implements Helper {
|
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
|
||||||
|
|
||||||
public static final MineBehavior INSTANCE = new MineBehavior();
|
public static final MineBehavior INSTANCE = new MineBehavior();
|
||||||
|
|
||||||
@@ -58,6 +58,10 @@ public final class MineBehavior extends Behavior implements Helper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTick(TickEvent event) {
|
public void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mining == null) {
|
if (mining == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -74,7 +78,7 @@ public final class MineBehavior extends Behavior implements Helper {
|
|||||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
||||||
if (mineGoalUpdateInterval != 0) {
|
if (mineGoalUpdateInterval != 0) {
|
||||||
if (event.getCount() % mineGoalUpdateInterval == 0) {
|
if (event.getCount() % mineGoalUpdateInterval == 0) {
|
||||||
updateGoal();
|
Baritone.INSTANCE.getExecutor().execute(this::updateGoal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PathingBehavior.INSTANCE.revalidateGoal();
|
PathingBehavior.INSTANCE.revalidateGoal();
|
||||||
@@ -105,7 +109,7 @@ public final class MineBehavior extends Behavior implements Helper {
|
|||||||
PathingBehavior.INSTANCE.path();
|
PathingBehavior.INSTANCE.path();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GoalComposite coalesce(List<BlockPos> locs) {
|
public GoalComposite coalesce(List<BlockPos> locs) {
|
||||||
return new GoalComposite(locs.stream().map(loc -> {
|
return new GoalComposite(locs.stream().map(loc -> {
|
||||||
if (!Baritone.settings().forceInternalMining.get()) {
|
if (!Baritone.settings().forceInternalMining.get()) {
|
||||||
return new GoalTwoBlocks(loc);
|
return new GoalTwoBlocks(loc);
|
||||||
@@ -129,13 +133,13 @@ public final class MineBehavior extends Behavior implements Helper {
|
|||||||
}).toArray(Goal[]::new));
|
}).toArray(Goal[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<BlockPos> scanFor(List<Block> mining, int max) {
|
public List<BlockPos> scanFor(List<Block> mining, int max) {
|
||||||
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();
|
||||||
for (Block m : mining) {
|
for (Block m : mining) {
|
||||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
||||||
locs.addAll(WorldProvider.INSTANCE.getCurrentWorld().cache.getLocationsOf(ChunkPacker.blockToString(m), 1, 1));
|
locs.addAll(WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, 1));
|
||||||
} else {
|
} else {
|
||||||
uninteresting.add(m);
|
uninteresting.add(m);
|
||||||
}
|
}
|
||||||
@@ -152,7 +156,7 @@ public final class MineBehavior extends Behavior implements Helper {
|
|||||||
return prune(locs, mining, max);
|
return prune(locs, mining, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) {
|
public List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) {
|
||||||
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet();
|
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet();
|
||||||
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
|
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
|
||||||
|
|
||||||
@@ -167,6 +171,7 @@ public final class MineBehavior extends Behavior implements Helper {
|
|||||||
return locs;
|
return locs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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.quantity = quantity;
|
||||||
@@ -174,12 +179,15 @@ public final class MineBehavior extends Behavior implements Helper {
|
|||||||
updateGoal();
|
updateGoal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mine(Block... blocks) {
|
@Override
|
||||||
|
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.locationsCache = new ArrayList<>();
|
this.locationsCache = new ArrayList<>();
|
||||||
updateGoal();
|
updateGoal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
mine(0, (String[]) null);
|
mine(0, (String[]) null);
|
||||||
PathingBehavior.INSTANCE.cancel();
|
PathingBehavior.INSTANCE.cancel();
|
||||||
|
|||||||
@@ -18,33 +18,36 @@
|
|||||||
package baritone.behavior;
|
package baritone.behavior;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
import baritone.api.event.events.PathEvent;
|
import baritone.api.event.events.PathEvent;
|
||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.api.event.events.RenderEvent;
|
import baritone.api.event.events.RenderEvent;
|
||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
|
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.IPathFinder;
|
import baritone.pathing.calc.IPathFinder;
|
||||||
import baritone.pathing.goals.Goal;
|
|
||||||
import baritone.pathing.goals.GoalXZ;
|
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
|
import baritone.utils.BlockBreakHelper;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.PathRenderer;
|
import baritone.utils.PathRenderer;
|
||||||
import baritone.utils.interfaces.IGoalRenderPos;
|
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public final class PathingBehavior extends Behavior implements Helper {
|
public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper {
|
||||||
|
|
||||||
public static final PathingBehavior INSTANCE = new PathingBehavior();
|
public static final PathingBehavior INSTANCE = new PathingBehavior();
|
||||||
|
|
||||||
@@ -170,6 +173,7 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Optional<Double> ticksRemainingInSegment() {
|
public Optional<Double> ticksRemainingInSegment() {
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
@@ -177,10 +181,12 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setGoal(Goal goal) {
|
public void setGoal(Goal goal) {
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Goal getGoal() {
|
public Goal getGoal() {
|
||||||
return goal;
|
return goal;
|
||||||
}
|
}
|
||||||
@@ -193,16 +199,30 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Expose this method in the API?
|
||||||
|
// In order to do so, we'd need to move over IPath which has a whole lot of references to other
|
||||||
|
// things that may not need to be exposed necessarily, so we'll need to figure that out.
|
||||||
public Optional<IPath> getPath() {
|
public Optional<IPath> getPath() {
|
||||||
return Optional.ofNullable(current).map(PathExecutor::getPath);
|
return Optional.ofNullable(current).map(PathExecutor::getPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPathing() {
|
||||||
|
return this.current != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
dispatchPathEvent(PathEvent.CANCELED);
|
dispatchPathEvent(PathEvent.CANCELED);
|
||||||
current = null;
|
current = null;
|
||||||
next = null;
|
next = null;
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
||||||
|
BlockBreakHelper.stopBreakingBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forceCancel() { // NOT exposed on public api
|
||||||
|
isPathCalcInProgress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,6 +230,7 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
*
|
*
|
||||||
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean path() {
|
public boolean path() {
|
||||||
if (goal == null) {
|
if (goal == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -232,7 +253,10 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockPos pathStart() {
|
/**
|
||||||
|
* @return The starting {@link BlockPos} for a new path
|
||||||
|
*/
|
||||||
|
private BlockPos pathStart() {
|
||||||
BetterBlockPos feet = playerFeet();
|
BetterBlockPos feet = playerFeet();
|
||||||
if (BlockStateInterface.get(feet.down()).getBlock().equals(Blocks.AIR) && MovementHelper.canWalkOn(feet.down().down())) {
|
if (BlockStateInterface.get(feet.down()).getBlock().equals(Blocks.AIR) && MovementHelper.canWalkOn(feet.down().down())) {
|
||||||
return feet.down();
|
return feet.down();
|
||||||
@@ -246,7 +270,8 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
* @param start
|
* @param start
|
||||||
* @param talkAboutIt
|
* @param talkAboutIt
|
||||||
*/
|
*/
|
||||||
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt, final Optional<IPath> previous) {
|
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt,
|
||||||
|
final Optional<IPath> previous) {
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (isPathCalcInProgress) {
|
if (isPathCalcInProgress) {
|
||||||
throw new IllegalStateException("Already doing it");
|
throw new IllegalStateException("Already doing it");
|
||||||
@@ -329,8 +354,9 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
} else {
|
} else {
|
||||||
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
|
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
|
||||||
}
|
}
|
||||||
|
Optional<HashSet<Long>> favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(y -> y.hashCode)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
|
||||||
try {
|
try {
|
||||||
IPathFinder pf = new AStarPathFinder(start, goal, previous.map(IPath::positions));
|
IPathFinder pf = new AStarPathFinder(start, goal, favoredPositions);
|
||||||
return pf.calculate(timeout);
|
return pf.calculate(timeout);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logDebug("Pathing exception: " + e);
|
logDebug("Pathing exception: " + e);
|
||||||
@@ -361,7 +387,7 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
// System.out.println(event.getPartialTicks());
|
// System.out.println(event.getPartialTicks());
|
||||||
float partialTicks = event.getPartialTicks();
|
float partialTicks = event.getPartialTicks();
|
||||||
if (goal != null && Baritone.settings().renderGoal.value) {
|
if (goal != null && Baritone.settings().renderGoal.value) {
|
||||||
PathRenderer.drawLitDankGoalBox(player(), goal, partialTicks, Color.GREEN);
|
PathRenderer.drawLitDankGoalBox(player(), goal, partialTicks, Baritone.settings().colorGoalBox.get());
|
||||||
}
|
}
|
||||||
if (!Baritone.settings().renderPath.get()) {
|
if (!Baritone.settings().renderPath.get()) {
|
||||||
return;
|
return;
|
||||||
@@ -378,27 +404,27 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
// Render the current path, if there is one
|
// Render the current path, if there is one
|
||||||
if (current != null && current.getPath() != null) {
|
if (current != null && current.getPath() != null) {
|
||||||
int renderBegin = Math.max(current.getPosition() - 3, 0);
|
int renderBegin = Math.max(current.getPosition() - 3, 0);
|
||||||
PathRenderer.drawPath(current.getPath(), renderBegin, player(), partialTicks, Color.RED, Baritone.settings().fadePath.get(), 10, 20);
|
PathRenderer.drawPath(current.getPath(), renderBegin, player(), partialTicks, Baritone.settings().colorCurrentPath.get(), Baritone.settings().fadePath.get(), 10, 20);
|
||||||
}
|
}
|
||||||
if (next != null && next.getPath() != null) {
|
if (next != null && next.getPath() != null) {
|
||||||
PathRenderer.drawPath(next.getPath(), 0, player(), partialTicks, Color.MAGENTA, Baritone.settings().fadePath.get(), 10, 20);
|
PathRenderer.drawPath(next.getPath(), 0, player(), partialTicks, Baritone.settings().colorNextPath.get(), Baritone.settings().fadePath.get(), 10, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
//long split = System.nanoTime();
|
//long split = System.nanoTime();
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
PathRenderer.drawManySelectionBoxes(player(), current.toBreak(), partialTicks, Color.RED);
|
PathRenderer.drawManySelectionBoxes(player(), current.toBreak(), partialTicks, Baritone.settings().colorBlocksToBreak.get());
|
||||||
PathRenderer.drawManySelectionBoxes(player(), current.toPlace(), partialTicks, Color.GREEN);
|
PathRenderer.drawManySelectionBoxes(player(), current.toPlace(), partialTicks, Baritone.settings().colorBlocksToPlace.get());
|
||||||
PathRenderer.drawManySelectionBoxes(player(), current.toWalkInto(), partialTicks, Color.MAGENTA);
|
PathRenderer.drawManySelectionBoxes(player(), current.toWalkInto(), partialTicks, Baritone.settings().colorBlocksToWalkInto.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a path calculation currently running, render the path calculation process
|
// If there is a path calculation currently running, render the path calculation process
|
||||||
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(currentlyRunning -> {
|
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(currentlyRunning -> {
|
||||||
currentlyRunning.bestPathSoFar().ifPresent(p -> {
|
currentlyRunning.bestPathSoFar().ifPresent(p -> {
|
||||||
PathRenderer.drawPath(p, 0, player(), partialTicks, Color.BLUE, Baritone.settings().fadePath.get(), 10, 20);
|
PathRenderer.drawPath(p, 0, player(), partialTicks, Baritone.settings().colorBestPathSoFar.get(), Baritone.settings().fadePath.get(), 10, 20);
|
||||||
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
|
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
|
||||||
|
|
||||||
PathRenderer.drawPath(mr, 0, player(), partialTicks, Color.CYAN, Baritone.settings().fadePath.get(), 10, 20);
|
PathRenderer.drawPath(mr, 0, player(), partialTicks, Baritone.settings().colorMostRecentConsidered.get(), Baritone.settings().fadePath.get(), 10, 20);
|
||||||
PathRenderer.drawManySelectionBoxes(player(), Collections.singletonList(mr.getDest()), partialTicks, Color.CYAN);
|
PathRenderer.drawManySelectionBoxes(player(), Collections.singletonList(mr.getDest()), partialTicks, Baritone.settings().colorMostRecentConsidered.get());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -408,4 +434,9 @@ public final class PathingBehavior extends Behavior implements Helper {
|
|||||||
// System.out.println("Frame took " + (split - start) + " " + (end - split));
|
// System.out.println("Frame took " + (split - start) + " " + (end - split));
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.utils.pathing.IBlockTypeAccess;
|
import baritone.api.cache.IBlockTypeAccess;
|
||||||
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.pathing.PathingBlockType;
|
import baritone.utils.pathing.PathingBlockType;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
@@ -30,7 +31,7 @@ import java.util.*;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/3/2018 1:04 AM
|
* @since 8/3/2018 1:04 AM
|
||||||
*/
|
*/
|
||||||
public final class CachedChunk implements IBlockTypeAccess {
|
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 = Collections.unmodifiableSet(new HashSet<Block>() {{
|
||||||
add(Blocks.DIAMOND_ORE);
|
add(Blocks.DIAMOND_ORE);
|
||||||
@@ -99,13 +100,13 @@ public final class CachedChunk implements IBlockTypeAccess {
|
|||||||
/**
|
/**
|
||||||
* The block names of each surface level block for generating an overview
|
* The block names of each surface level block for generating an overview
|
||||||
*/
|
*/
|
||||||
private final String[] overview;
|
private final IBlockState[] overview;
|
||||||
|
|
||||||
private final int[] heightMap;
|
private final int[] heightMap;
|
||||||
|
|
||||||
private final Map<String, List<BlockPos>> specialBlockLocations;
|
private final Map<String, List<BlockPos>> specialBlockLocations;
|
||||||
|
|
||||||
CachedChunk(int x, int z, BitSet data, String[] overview, Map<String, List<BlockPos>> specialBlockLocations) {
|
CachedChunk(int x, int z, BitSet data, IBlockState[] overview, Map<String, List<BlockPos>> specialBlockLocations) {
|
||||||
validateSize(data);
|
validateSize(data);
|
||||||
|
|
||||||
this.x = x;
|
this.x = x;
|
||||||
@@ -122,12 +123,11 @@ public final class CachedChunk implements IBlockTypeAccess {
|
|||||||
int internalPos = z << 4 | x;
|
int internalPos = z << 4 | x;
|
||||||
if (heightMap[internalPos] == y) {
|
if (heightMap[internalPos] == y) {
|
||||||
// we have this exact block, it's a surface block
|
// we have this exact block, it's a surface block
|
||||||
IBlockState state = ChunkPacker.stringToBlock(overview[internalPos]).getDefaultState();
|
|
||||||
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
||||||
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
||||||
throw new IllegalStateException("failed " + Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
throw new IllegalStateException("failed " + Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
||||||
}*/
|
}*/
|
||||||
return state;
|
return overview[internalPos];
|
||||||
}
|
}
|
||||||
PathingBlockType type = getType(x, y, z);
|
PathingBlockType type = getType(x, y, z);
|
||||||
if (type == PathingBlockType.SOLID && y == 127 && mc.player.dimension == -1) {
|
if (type == PathingBlockType.SOLID && y == 127 && mc.player.dimension == -1) {
|
||||||
@@ -157,7 +157,7 @@ public final class CachedChunk implements IBlockTypeAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String[] getOverview() {
|
public final IBlockState[] getOverview() {
|
||||||
return overview;
|
return overview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-5
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.utils.pathing.IBlockTypeAccess;
|
import baritone.api.cache.ICachedRegion;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@@ -33,7 +33,8 @@ import java.util.zip.GZIPOutputStream;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/3/2018 9:35 PM
|
* @since 8/3/2018 9:35 PM
|
||||||
*/
|
*/
|
||||||
public final class CachedRegion implements IBlockTypeAccess {
|
public final class CachedRegion implements ICachedRegion {
|
||||||
|
|
||||||
private static final byte CHUNK_NOT_PRESENT = 0;
|
private static final byte CHUNK_NOT_PRESENT = 0;
|
||||||
private static final byte CHUNK_PRESENT = 1;
|
private static final byte CHUNK_PRESENT = 1;
|
||||||
|
|
||||||
@@ -77,6 +78,7 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final boolean isCached(int x, int z) {
|
public final boolean isCached(int x, int z) {
|
||||||
return chunks[x >> 4][z >> 4] != null;
|
return chunks[x >> 4][z >> 4] != null;
|
||||||
}
|
}
|
||||||
@@ -145,7 +147,7 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
for (int x = 0; x < 32; x++) {
|
for (int x = 0; x < 32; x++) {
|
||||||
if (chunks[x][z] != null) {
|
if (chunks[x][z] != null) {
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
out.writeUTF(chunks[x][z].getOverview()[i]);
|
out.writeUTF(ChunkPacker.blockToString(chunks[x][z].getOverview()[i].getBlock()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,7 +217,7 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
int regionZ = this.z;
|
int regionZ = this.z;
|
||||||
int chunkX = x + 32 * regionX;
|
int chunkX = x + 32 * regionX;
|
||||||
int chunkZ = z + 32 * regionZ;
|
int chunkZ = z + 32 * regionZ;
|
||||||
tmpCached[x][z] = new CachedChunk(chunkX, chunkZ, BitSet.valueOf(bytes), new String[256], location[x][z]);
|
tmpCached[x][z] = new CachedChunk(chunkX, chunkZ, BitSet.valueOf(bytes), new IBlockState[256], location[x][z]);
|
||||||
break;
|
break;
|
||||||
case CHUNK_NOT_PRESENT:
|
case CHUNK_NOT_PRESENT:
|
||||||
tmpCached[x][z] = null;
|
tmpCached[x][z] = null;
|
||||||
@@ -229,7 +231,7 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
for (int x = 0; x < 32; x++) {
|
for (int x = 0; x < 32; x++) {
|
||||||
if (tmpCached[x][z] != null) {
|
if (tmpCached[x][z] != null) {
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
tmpCached[x][z].getOverview()[i] = in.readUTF();
|
tmpCached[x][z].getOverview()[i] = ChunkPacker.stringToBlock(in.readUTF()).getDefaultState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,6 +282,7 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
/**
|
/**
|
||||||
* @return The region x coordinate
|
* @return The region x coordinate
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public final int getX() {
|
public final int getX() {
|
||||||
return this.x;
|
return this.x;
|
||||||
}
|
}
|
||||||
@@ -287,6 +290,7 @@ public final class CachedRegion implements IBlockTypeAccess {
|
|||||||
/**
|
/**
|
||||||
* @return The region z coordinate
|
* @return The region z coordinate
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public final int getZ() {
|
public final int getZ() {
|
||||||
return this.z;
|
return this.z;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-18
@@ -18,6 +18,7 @@
|
|||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.cache.ICachedWorld;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
@@ -36,7 +37,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 12:02 AM
|
* @since 8/4/2018 12:02 AM
|
||||||
*/
|
*/
|
||||||
public final class CachedWorld implements Helper {
|
public final class CachedWorld implements ICachedWorld, Helper {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of regions in any direction from (0,0)
|
* The maximum number of regions in any direction from (0,0)
|
||||||
@@ -83,6 +84,7 @@ public final class CachedWorld implements Helper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final void queueForPacking(Chunk chunk) {
|
public final void queueForPacking(Chunk chunk) {
|
||||||
try {
|
try {
|
||||||
toPack.put(chunk);
|
toPack.put(chunk);
|
||||||
@@ -91,17 +93,17 @@ public final class CachedWorld implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isCached(BlockPos pos) {
|
@Override
|
||||||
int x = pos.getX();
|
public final boolean isCached(int blockX, int blockZ) {
|
||||||
int z = pos.getZ();
|
CachedRegion region = getRegion(blockX >> 9, blockZ >> 9);
|
||||||
CachedRegion region = getRegion(x >> 9, z >> 9);
|
|
||||||
if (region == null) {
|
if (region == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return region.isCached(x & 511, z & 511);
|
return region.isCached(blockX & 511, blockZ & 511);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LinkedList<BlockPos> getLocationsOf(String block, int minimum, int maxRegionDistanceSq) {
|
@Override
|
||||||
|
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq) {
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
LinkedList<BlockPos> res = new LinkedList<>();
|
||||||
int playerRegionX = playerFeet().getX() >> 9;
|
int playerRegionX = playerFeet().getX() >> 9;
|
||||||
int playerRegionZ = playerFeet().getZ() >> 9;
|
int playerRegionZ = playerFeet().getZ() >> 9;
|
||||||
@@ -118,13 +120,12 @@ public final class CachedWorld implements Helper {
|
|||||||
int regionZ = zoff + playerRegionZ;
|
int regionZ = zoff + playerRegionZ;
|
||||||
CachedRegion region = getOrCreateRegion(regionX, regionZ);
|
CachedRegion region = getOrCreateRegion(regionX, regionZ);
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
for (BlockPos pos : region.getLocationsOf(block)) {
|
// TODO: 100% verify if this or addAll is faster.
|
||||||
res.add(pos);
|
region.getLocationsOf(block).forEach(res::add);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res.size() >= minimum) {
|
if (res.size() >= maximum) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
searchRadius++;
|
searchRadius++;
|
||||||
@@ -137,6 +138,7 @@ public final class CachedWorld implements Helper {
|
|||||||
region.updateCachedChunk(chunk.x & 31, chunk.z & 31, chunk);
|
region.updateCachedChunk(chunk.x & 31, chunk.z & 31, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final void save() {
|
public final void save() {
|
||||||
if (!Baritone.settings().chunkCaching.get()) {
|
if (!Baritone.settings().chunkCaching.get()) {
|
||||||
System.out.println("Not saving to disk; chunk caching is disabled.");
|
System.out.println("Not saving to disk; chunk caching is disabled.");
|
||||||
@@ -156,6 +158,7 @@ public final class CachedWorld implements Helper {
|
|||||||
return new ArrayList<>(this.cachedRegions.values());
|
return new ArrayList<>(this.cachedRegions.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final void reloadAllFromDisk() {
|
public final void reloadAllFromDisk() {
|
||||||
long start = System.nanoTime() / 1000000L;
|
long start = System.nanoTime() / 1000000L;
|
||||||
allRegions().forEach(region -> {
|
allRegions().forEach(region -> {
|
||||||
@@ -167,13 +170,7 @@ public final class CachedWorld implements Helper {
|
|||||||
System.out.println("World load took " + (now - start) + "ms");
|
System.out.println("World load took " + (now - start) + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Returns the region at the specified region coordinates
|
|
||||||
*
|
|
||||||
* @param regionX The region X coordinate
|
|
||||||
* @param regionZ The region Z coordinate
|
|
||||||
* @return The region located at the specified coordinates
|
|
||||||
*/
|
|
||||||
public final synchronized CachedRegion getRegion(int regionX, int regionZ) {
|
public final synchronized CachedRegion getRegion(int regionX, int regionZ) {
|
||||||
return cachedRegions.get(getRegionID(regionX, regionZ));
|
return cachedRegions.get(getRegionID(regionX, regionZ));
|
||||||
}
|
}
|
||||||
@@ -224,6 +221,7 @@ public final class CachedWorld implements Helper {
|
|||||||
private class PackerThread implements Runnable {
|
private class PackerThread implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
// TODO: Add CachedWorld unloading to remove the redundancy of having this
|
||||||
LinkedBlockingQueue<Chunk> queue = toPack;
|
LinkedBlockingQueue<Chunk> queue = toPack;
|
||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
+7
-5
@@ -89,22 +89,24 @@ public final class ChunkPacker implements Helper {
|
|||||||
}
|
}
|
||||||
//long end = System.nanoTime() / 1000000L;
|
//long end = System.nanoTime() / 1000000L;
|
||||||
//System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z);
|
//System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z);
|
||||||
String[] blockNames = new String[256];
|
IBlockState[] blocks = new IBlockState[256];
|
||||||
|
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
|
// @formatter:off
|
||||||
https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
|
https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
|
||||||
|
// @formatter:on
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int y = 255; y >= 0; y--) {
|
for (int y = 255; y >= 0; y--) {
|
||||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
if (bitSet.get(index) || bitSet.get(index + 1)) {
|
if (bitSet.get(index) || bitSet.get(index + 1)) {
|
||||||
String name = blockToString(chunk.getBlockState(x, y, z).getBlock());
|
blocks[z << 4 | x] = chunk.getBlockState(x, y, z);
|
||||||
blockNames[z << 4 | x] = name;
|
|
||||||
continue https;
|
continue https;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blockNames[z << 4 | x] = "air";
|
blocks[z << 4 | x] = Blocks.AIR.getDefaultState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new CachedChunk(chunk.x, chunk.z, bitSet, blockNames, specialBlocks);
|
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String blockToString(Block block) {
|
public static String blockToString(Block block) {
|
||||||
|
|||||||
+43
-38
@@ -17,77 +17,82 @@
|
|||||||
|
|
||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import baritone.api.cache.IWaypoint;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single waypoint
|
* Basic implementation of {@link IWaypoint}
|
||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class Waypoint {
|
public class Waypoint implements IWaypoint {
|
||||||
|
|
||||||
public final String name;
|
private final String name;
|
||||||
public final Tag tag;
|
private final Tag tag;
|
||||||
private final long creationTimestamp;
|
private final long creationTimestamp;
|
||||||
public final BlockPos location;
|
private final BlockPos location;
|
||||||
|
|
||||||
public Waypoint(String name, Tag tag, BlockPos location) {
|
public Waypoint(String name, Tag tag, BlockPos location) {
|
||||||
this(name, tag, location, System.currentTimeMillis());
|
this(name, tag, location, System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) { // read from disk
|
/**
|
||||||
|
* Constructor called when a Waypoint is read from disk, adds the creationTimestamp
|
||||||
|
* as a parameter so that it is reserved after a waypoint is wrote to the disk.
|
||||||
|
*
|
||||||
|
* @param name The waypoint name
|
||||||
|
* @param tag The waypoint tag
|
||||||
|
* @param location The waypoint location
|
||||||
|
* @param creationTimestamp When the waypoint was created
|
||||||
|
*/
|
||||||
|
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.creationTimestamp = creationTimestamp;
|
this.creationTimestamp = creationTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(o instanceof Waypoint)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Waypoint w = (Waypoint) o;
|
|
||||||
return name.equals(w.name) && tag == w.tag && location.equals(w.location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return name.hashCode() + tag.hashCode() + location.hashCode(); //lol
|
return name.hashCode() + tag.hashCode() + location.hashCode(); //lol
|
||||||
}
|
}
|
||||||
|
|
||||||
public long creationTimestamp() {
|
@Override
|
||||||
return creationTimestamp;
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tag getTag() {
|
||||||
|
return this.tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCreationTimestamp() {
|
||||||
|
return this.creationTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getLocation() {
|
||||||
|
return this.location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name + " " + location.toString() + " " + new Date(creationTimestamp).toString();
|
return name + " " + location.toString() + " " + new Date(creationTimestamp).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Tag {
|
@Override
|
||||||
HOME("home", "base"),
|
public boolean equals(Object o) {
|
||||||
DEATH("death"),
|
if (o == null) {
|
||||||
BED("bed", "spawn"),
|
return false;
|
||||||
USER("user");
|
|
||||||
|
|
||||||
private static final List<Tag> TAG_LIST = ImmutableList.<Tag>builder().add(Tag.values()).build();
|
|
||||||
|
|
||||||
private final String[] names;
|
|
||||||
|
|
||||||
Tag(String... names) {
|
|
||||||
this.names = names;
|
|
||||||
}
|
}
|
||||||
|
if (!(o instanceof IWaypoint)) {
|
||||||
public static Tag fromString(String name) {
|
return false;
|
||||||
return TAG_LIST.stream().filter(tag -> ArrayUtils.contains(tag.names, name.toLowerCase())).findFirst().orElse(null);
|
|
||||||
}
|
}
|
||||||
|
IWaypoint w = (IWaypoint) o;
|
||||||
|
return name.equals(w.getName()) && tag == w.getTag() && location.equals(w.getLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-25
@@ -17,19 +17,22 @@
|
|||||||
|
|
||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
|
import baritone.api.cache.IWaypoint;
|
||||||
|
import baritone.api.cache.IWaypointCollection;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waypoints for a world
|
* Waypoints for a world
|
||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class Waypoints {
|
public class Waypoints implements IWaypointCollection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Magic value to detect invalid waypoint files
|
* Magic value to detect invalid waypoint files
|
||||||
@@ -37,7 +40,7 @@ public class Waypoints {
|
|||||||
private static final long WAYPOINT_MAGIC_VALUE = 121977993584L; // good value
|
private static final long WAYPOINT_MAGIC_VALUE = 121977993584L; // good value
|
||||||
|
|
||||||
private final Path directory;
|
private final Path directory;
|
||||||
private final Map<Waypoint.Tag, Set<Waypoint>> waypoints;
|
private final Map<IWaypoint.Tag, Set<IWaypoint>> waypoints;
|
||||||
|
|
||||||
Waypoints(Path directory) {
|
Waypoints(Path directory) {
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
@@ -58,9 +61,9 @@ public class Waypoints {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void load(Waypoint.Tag tag) {
|
private synchronized void load(Waypoint.Tag tag) {
|
||||||
waypoints.put(tag, new HashSet<>());
|
this.waypoints.put(tag, new HashSet<>());
|
||||||
|
|
||||||
Path fileName = directory.resolve(tag.name().toLowerCase() + ".mp4");
|
Path fileName = this.directory.resolve(tag.name().toLowerCase() + ".mp4");
|
||||||
if (!Files.exists(fileName)) {
|
if (!Files.exists(fileName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -82,44 +85,60 @@ public class Waypoints {
|
|||||||
int x = in.readInt();
|
int x = in.readInt();
|
||||||
int y = in.readInt();
|
int y = in.readInt();
|
||||||
int z = in.readInt();
|
int z = in.readInt();
|
||||||
waypoints.get(tag).add(new Waypoint(name, tag, new BlockPos(x, y, z), creationTimestamp));
|
this.waypoints.get(tag).add(new Waypoint(name, tag, new BlockPos(x, y, z), creationTimestamp));
|
||||||
}
|
}
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void save(Waypoint.Tag tag) {
|
private synchronized void save(Waypoint.Tag tag) {
|
||||||
Path fileName = directory.resolve(tag.name().toLowerCase() + ".mp4");
|
Path fileName = this.directory.resolve(tag.name().toLowerCase() + ".mp4");
|
||||||
try (
|
try (
|
||||||
FileOutputStream fileOut = new FileOutputStream(fileName.toFile());
|
FileOutputStream fileOut = new FileOutputStream(fileName.toFile());
|
||||||
BufferedOutputStream bufOut = new BufferedOutputStream(fileOut);
|
BufferedOutputStream bufOut = new BufferedOutputStream(fileOut);
|
||||||
DataOutputStream out = new DataOutputStream(bufOut)
|
DataOutputStream out = new DataOutputStream(bufOut)
|
||||||
) {
|
) {
|
||||||
out.writeLong(WAYPOINT_MAGIC_VALUE);
|
out.writeLong(WAYPOINT_MAGIC_VALUE);
|
||||||
out.writeLong(waypoints.get(tag).size());
|
out.writeLong(this.waypoints.get(tag).size());
|
||||||
for (Waypoint waypoint : waypoints.get(tag)) {
|
for (IWaypoint waypoint : this.waypoints.get(tag)) {
|
||||||
out.writeUTF(waypoint.name);
|
out.writeUTF(waypoint.getName());
|
||||||
out.writeLong(waypoint.creationTimestamp());
|
out.writeLong(waypoint.getCreationTimestamp());
|
||||||
out.writeInt(waypoint.location.getX());
|
out.writeInt(waypoint.getLocation().getX());
|
||||||
out.writeInt(waypoint.location.getY());
|
out.writeInt(waypoint.getLocation().getY());
|
||||||
out.writeInt(waypoint.location.getZ());
|
out.writeInt(waypoint.getLocation().getZ());
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Waypoint> getByTag(Waypoint.Tag tag) {
|
@Override
|
||||||
return Collections.unmodifiableSet(waypoints.get(tag));
|
public void addWaypoint(IWaypoint waypoint) {
|
||||||
}
|
|
||||||
|
|
||||||
public Waypoint getMostRecentByTag(Waypoint.Tag tag) {
|
|
||||||
// Find a waypoint of the given tag which has the greatest timestamp value, indicating the most recent
|
|
||||||
return this.waypoints.get(tag).stream().min(Comparator.comparingLong(w -> -w.creationTimestamp())).orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addWaypoint(Waypoint waypoint) {
|
|
||||||
// no need to check for duplicate, because it's a Set not a List
|
// no need to check for duplicate, because it's a Set not a List
|
||||||
waypoints.get(waypoint.tag).add(waypoint);
|
if (waypoints.get(waypoint.getTag()).add(waypoint)) {
|
||||||
save(waypoint.tag);
|
save(waypoint.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeWaypoint(IWaypoint waypoint) {
|
||||||
|
if (waypoints.get(waypoint.getTag()).remove(waypoint)) {
|
||||||
|
save(waypoint.getTag());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IWaypoint getMostRecentByTag(IWaypoint.Tag tag) {
|
||||||
|
// Find a waypoint of the given tag which has the greatest timestamp value, indicating the most recent
|
||||||
|
return this.waypoints.get(tag).stream().min(Comparator.comparingLong(w -> -w.getCreationTimestamp())).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<IWaypoint> getByTag(IWaypoint.Tag tag) {
|
||||||
|
return Collections.unmodifiableSet(this.waypoints.get(tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<IWaypoint> getAllWaypoints() {
|
||||||
|
return this.waypoints.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-2
@@ -18,6 +18,9 @@
|
|||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.cache.ICachedWorld;
|
||||||
|
import baritone.api.cache.IWaypointCollection;
|
||||||
|
import baritone.api.cache.IWorldData;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
@@ -26,9 +29,10 @@ import java.nio.file.Path;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class WorldData {
|
public class WorldData implements IWorldData {
|
||||||
|
|
||||||
public final CachedWorld cache;
|
public final CachedWorld cache;
|
||||||
public final Waypoints waypoints;
|
private final Waypoints waypoints;
|
||||||
//public final MapData map;
|
//public final MapData map;
|
||||||
public final Path directory;
|
public final Path directory;
|
||||||
|
|
||||||
@@ -44,4 +48,14 @@ public class WorldData {
|
|||||||
cache.save();
|
cache.save();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICachedWorld getCachedWorld() {
|
||||||
|
return this.cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IWaypointCollection getWaypoints() {
|
||||||
|
return this.waypoints;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -18,6 +18,7 @@
|
|||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.cache.IWorldProvider;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.accessor.IAnvilChunkLoader;
|
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||||
import baritone.utils.accessor.IChunkProviderServer;
|
import baritone.utils.accessor.IChunkProviderServer;
|
||||||
@@ -38,7 +39,7 @@ import java.util.function.Consumer;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 11:06 AM
|
* @since 8/4/2018 11:06 AM
|
||||||
*/
|
*/
|
||||||
public enum WorldProvider implements Helper {
|
public enum WorldProvider implements IWorldProvider, Helper {
|
||||||
|
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ public enum WorldProvider implements Helper {
|
|||||||
|
|
||||||
private WorldData currentWorld;
|
private WorldData currentWorld;
|
||||||
|
|
||||||
|
@Override
|
||||||
public final WorldData getCurrentWorld() {
|
public final WorldData getCurrentWorld() {
|
||||||
return this.currentWorld;
|
return this.currentWorld;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public final class GameEventHandler implements IGameEventListener, Helper {
|
|||||||
if (isPostPopulate || isPreUnload) {
|
if (isPostPopulate || isPreUnload) {
|
||||||
WorldProvider.INSTANCE.ifWorldLoaded(world -> {
|
WorldProvider.INSTANCE.ifWorldLoaded(world -> {
|
||||||
Chunk chunk = mc.world.getChunk(event.getX(), event.getZ());
|
Chunk chunk = mc.world.getChunk(event.getX(), event.getZ());
|
||||||
world.cache.queueForPacking(chunk);
|
world.getCachedWorld().queueForPacking(chunk);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,22 +18,16 @@
|
|||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.cache.CachedWorld;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
||||||
import baritone.pathing.goals.Goal;
|
|
||||||
import baritone.pathing.movement.ActionCosts;
|
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Moves;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
|
||||||
import baritone.pathing.movement.movements.*;
|
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.client.Minecraft;
|
import baritone.utils.pathing.MoveResult;
|
||||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -43,20 +37,18 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||||
|
|
||||||
private final Optional<HashSet<BetterBlockPos>> favoredPositions;
|
private final Optional<HashSet<Long>> favoredPositions;
|
||||||
|
|
||||||
private final Random random = new Random();
|
public AStarPathFinder(BlockPos start, Goal goal, Optional<HashSet<Long>> favoredPositions) {
|
||||||
|
|
||||||
public AStarPathFinder(BlockPos start, Goal goal, Optional<Collection<BetterBlockPos>> favoredPositions) {
|
|
||||||
super(start, goal);
|
super(start, goal);
|
||||||
this.favoredPositions = favoredPositions.map(HashSet::new); // <-- okay this is epic
|
this.favoredPositions = favoredPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Optional<IPath> calculate0(long timeout) {
|
protected Optional<IPath> calculate0(long timeout) {
|
||||||
startNode = getNodeAtPosition(start);
|
startNode = getNodeAtPosition(start.x, start.y, start.z);
|
||||||
startNode.cost = 0;
|
startNode.cost = 0;
|
||||||
startNode.combinedCost = startNode.estimatedCostToGoal;
|
startNode.combinedCost = startNode.estimatedCostToGoal;
|
||||||
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
|
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
|
||||||
@@ -69,9 +61,7 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
bestSoFar[i] = startNode;
|
bestSoFar[i] = startNode;
|
||||||
}
|
}
|
||||||
CalculationContext calcContext = new CalculationContext();
|
CalculationContext calcContext = new CalculationContext();
|
||||||
HashSet<BetterBlockPos> favored = favoredPositions.orElse(null);
|
HashSet<Long> favored = favoredPositions.orElse(null);
|
||||||
CachedWorld cachedWorld = Optional.ofNullable(WorldProvider.INSTANCE.getCurrentWorld()).map(w -> w.cache).orElse(null);
|
|
||||||
ChunkProviderClient chunkProvider = Minecraft.getMinecraft().world.getChunkProvider();
|
|
||||||
BlockStateInterface.clearCachedChunk();
|
BlockStateInterface.clearCachedChunk();
|
||||||
long startTime = System.nanoTime() / 1000000L;
|
long startTime = System.nanoTime() / 1000000L;
|
||||||
boolean slowPath = Baritone.settings().slowPath.get();
|
boolean slowPath = Baritone.settings().slowPath.get();
|
||||||
@@ -88,10 +78,10 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get();
|
double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get();
|
||||||
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
|
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
|
||||||
|
|
||||||
HashMap<Class<? extends Movement>, Long> timeConsumed = new HashMap<>();
|
long[] timeConsumed = new long[Moves.values().length];
|
||||||
HashMap<Class<? extends Movement>, Integer> count = new HashMap<>();
|
int[] count = new int[Moves.values().length];
|
||||||
HashMap<Class<? extends Movement>, Integer> stateLookup = new HashMap<>();
|
int[] stateLookup = new int[Moves.values().length];
|
||||||
HashMap<Class<? extends Movement>, Long> posCreation = new HashMap<>();
|
long[] posCreation = new long[Moves.values().length];
|
||||||
long heapRemove = 0;
|
long heapRemove = 0;
|
||||||
int heapRemoveCount = 0;
|
int heapRemoveCount = 0;
|
||||||
long heapAdd = 0;
|
long heapAdd = 0;
|
||||||
@@ -99,9 +89,6 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
long heapUpdate = 0;
|
long heapUpdate = 0;
|
||||||
int heapUpdateCount = 0;
|
int heapUpdateCount = 0;
|
||||||
|
|
||||||
long construction = 0;
|
|
||||||
int constructionCount = 0;
|
|
||||||
|
|
||||||
long chunk = 0;
|
long chunk = 0;
|
||||||
int chunkCount = 0;
|
int chunkCount = 0;
|
||||||
|
|
||||||
@@ -129,36 +116,24 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
heapRemoveCount++;
|
heapRemoveCount++;
|
||||||
currentNode.isOpen = false;
|
currentNode.isOpen = false;
|
||||||
mostRecentConsidered = currentNode;
|
mostRecentConsidered = currentNode;
|
||||||
BetterBlockPos currentNodePos = currentNode.pos;
|
|
||||||
numNodes++;
|
numNodes++;
|
||||||
if (goal.isInGoal(currentNodePos)) {
|
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
|
||||||
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||||
return Optional.of(new Path(startNode, currentNode, numNodes, goal));
|
return Optional.of(new Path(startNode, currentNode, numNodes, goal));
|
||||||
}
|
}
|
||||||
long constructStart = System.nanoTime();
|
goalCheck += System.nanoTime() - t;
|
||||||
goalCheck += constructStart - t;
|
|
||||||
goalCheckCount++;
|
goalCheckCount++;
|
||||||
Movement[] possibleMovements = getConnectedPositions(currentNodePos, calcContext);//movement that we could take that start at currentNodePos, in random order
|
for (Moves moves : Moves.values()) {
|
||||||
shuffle(possibleMovements);
|
|
||||||
long constructEnd = System.nanoTime();
|
|
||||||
construction += constructEnd - constructStart;
|
|
||||||
constructionCount++;
|
|
||||||
for (Movement movementToGetToNeighbor : possibleMovements) {
|
|
||||||
if (movementToGetToNeighbor == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
BetterBlockPos dest = movementToGetToNeighbor.getDest();
|
|
||||||
long s = System.nanoTime();
|
long s = System.nanoTime();
|
||||||
int chunkX = currentNodePos.x >> 4;
|
int newX = currentNode.x + moves.xOffset;
|
||||||
int chunkZ = currentNodePos.z >> 4;
|
int newZ = currentNode.z + moves.zOffset;
|
||||||
if (dest.x >> 4 != chunkX || dest.z >> 4 != chunkZ) {
|
if (newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) {
|
||||||
// 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 (chunkProvider.isChunkGeneratedAt(chunkX, chunkZ)) {
|
if (!BlockStateInterface.isLoaded(newX, newZ)) {
|
||||||
// see issue #106
|
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
|
||||||
if (cachedWorld == null || !cachedWorld.isCached(dest)) {
|
|
||||||
numEmptyChunk++;
|
numEmptyChunk++;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long costStart = System.nanoTime();
|
long costStart = System.nanoTime();
|
||||||
@@ -167,31 +142,39 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
// TODO cache cost
|
// TODO cache cost
|
||||||
int numLookupsBefore = BlockStateInterface.numBlockStateLookups;
|
int numLookupsBefore = BlockStateInterface.numBlockStateLookups;
|
||||||
long numCreatedBefore = BetterBlockPos.numCreated;
|
long numCreatedBefore = BetterBlockPos.numCreated;
|
||||||
double actionCost = movementToGetToNeighbor.getCost(calcContext);
|
|
||||||
|
MoveResult res = moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z);
|
||||||
|
|
||||||
long costEnd = System.nanoTime();
|
long costEnd = System.nanoTime();
|
||||||
stateLookup.put(movementToGetToNeighbor.getClass(), BlockStateInterface.numBlockStateLookups - numLookupsBefore + stateLookup.getOrDefault(movementToGetToNeighbor.getClass(), 0));
|
stateLookup[moves.ordinal()] += BlockStateInterface.numBlockStateLookups - numLookupsBefore;
|
||||||
posCreation.put(movementToGetToNeighbor.getClass(), BetterBlockPos.numCreated - numCreatedBefore + posCreation.getOrDefault(movementToGetToNeighbor.getClass(), 0L));
|
posCreation[moves.ordinal()] += BetterBlockPos.numCreated - numCreatedBefore;
|
||||||
timeConsumed.put(movementToGetToNeighbor.getClass(), costEnd - costStart + timeConsumed.getOrDefault(movementToGetToNeighbor.getClass(), 0L));
|
timeConsumed[moves.ordinal()] += costEnd - costStart;
|
||||||
count.put(movementToGetToNeighbor.getClass(), 1 + count.getOrDefault(movementToGetToNeighbor.getClass(), 0));
|
count[moves.ordinal()]++;
|
||||||
|
|
||||||
numMovementsConsidered++;
|
numMovementsConsidered++;
|
||||||
|
double actionCost = res.cost;
|
||||||
if (actionCost >= ActionCosts.COST_INF) {
|
if (actionCost >= ActionCosts.COST_INF) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (actionCost <= 0) {
|
// check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation
|
||||||
throw new IllegalStateException(movementToGetToNeighbor.getClass() + " " + movementToGetToNeighbor + " calculated implausible cost " + actionCost);
|
if (!moves.dynamicXZ && (res.destX != newX || res.destZ != newZ)) {
|
||||||
|
throw new IllegalStateException(moves + " " + res.destX + " " + newX + " " + res.destZ + " " + newZ);
|
||||||
}
|
}
|
||||||
if (favoring && favored.contains(dest)) {
|
if (actionCost <= 0) {
|
||||||
|
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
|
||||||
|
}
|
||||||
|
if (favoring && favored.contains(posHash(res.destX, res.destY, res.destZ))) {
|
||||||
// see issue #18
|
// see issue #18
|
||||||
actionCost *= favorCoeff;
|
actionCost *= favorCoeff;
|
||||||
}
|
}
|
||||||
long st = System.nanoTime();
|
long st = System.nanoTime();
|
||||||
PathNode neighbor = getNodeAtPosition(dest);
|
PathNode neighbor = getNodeAtPosition(res.destX, res.destY, res.destZ);
|
||||||
getNode += System.nanoTime() - st;
|
getNode += System.nanoTime() - st;
|
||||||
getNodeCount++;
|
getNodeCount++;
|
||||||
double tentativeCost = currentNode.cost + actionCost;
|
double tentativeCost = currentNode.cost + actionCost;
|
||||||
if (tentativeCost < neighbor.cost) {
|
if (tentativeCost < neighbor.cost) {
|
||||||
if (tentativeCost < 0) {
|
if (tentativeCost < 0) {
|
||||||
throw new IllegalStateException(movementToGetToNeighbor.getClass() + " " + movementToGetToNeighbor + " overflowed into negative " + actionCost + " " + neighbor.cost + " " + tentativeCost);
|
throw new IllegalStateException(moves + " overflowed into negative " + actionCost + " " + neighbor.cost + " " + tentativeCost);
|
||||||
}
|
}
|
||||||
double improvementBy = neighbor.cost - tentativeCost;
|
double improvementBy = neighbor.cost - tentativeCost;
|
||||||
// there are floating point errors caused by random combinations of traverse and diagonal over a flat area
|
// there are floating point errors caused by random combinations of traverse and diagonal over a flat area
|
||||||
@@ -202,7 +185,6 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
neighbor.previous = currentNode;
|
neighbor.previous = currentNode;
|
||||||
neighbor.previousMovement = movementToGetToNeighbor;
|
|
||||||
neighbor.cost = tentativeCost;
|
neighbor.cost = tentativeCost;
|
||||||
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
||||||
if (neighbor.isOpen) {
|
if (neighbor.isOpen) {
|
||||||
@@ -235,21 +217,20 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
long numSuccc = BetterBlockPos.numCreated - startVal3;
|
long numSuccc = BetterBlockPos.numCreated - startVal3;
|
||||||
System.out.println("Out of " + numBlockState + " block state lookups, " + numSucc + " were in the same chunk as the previous and could be cached");
|
System.out.println("Out of " + numBlockState + " block state lookups, " + numSucc + " were in the same chunk as the previous and could be cached");
|
||||||
System.out.println("Instantiated " + numSuccc + " BetterBlockPos objects");
|
System.out.println("Instantiated " + numSuccc + " BetterBlockPos objects");
|
||||||
System.out.println("Remove " + (heapRemove / heapRemoveCount) + " " + heapRemove / 1000000 + " " + heapRemoveCount);
|
System.out.println("Remove " + (heapRemove / heapRemoveCount) + " " + heapRemove / 1000000 + "ms " + heapRemoveCount);
|
||||||
System.out.println("Add " + (heapAdd / heapAddCount) + " " + heapAdd / 1000000 + " " + heapAddCount);
|
System.out.println("Add " + (heapAdd / heapAddCount) + " " + heapAdd / 1000000 + "ms " + heapAddCount);
|
||||||
System.out.println("Update " + (heapUpdate / heapUpdateCount) + " " + heapUpdate / 1000000 + " " + heapUpdateCount);
|
System.out.println("Update " + (heapUpdate / heapUpdateCount) + " " + heapUpdate / 1000000 + "ms " + heapUpdateCount);
|
||||||
System.out.println("Construction " + (construction / constructionCount) + " " + construction / 1000000 + " " + constructionCount);
|
System.out.println("Chunk " + (chunk / chunkCount) + " " + chunk / 1000000 + "ms " + chunkCount);
|
||||||
System.out.println("Chunk " + (chunk / chunkCount) + " " + chunk / 1000000 + " " + chunkCount);
|
System.out.println("GetNode " + (getNode / getNodeCount) + " " + getNode / 1000000 + "ms " + getNodeCount);
|
||||||
System.out.println("GetNode " + (getNode / getNodeCount) + " " + getNode / 1000000 + " " + getNodeCount);
|
System.out.println("GoalCheck " + (goalCheck / goalCheckCount) + " " + goalCheck / 1000000 + "ms " + goalCheckCount);
|
||||||
System.out.println("GoalCheck " + (goalCheck / goalCheckCount) + " " + goalCheck / 1000000 + " " + goalCheckCount);
|
ArrayList<Moves> moves = new ArrayList<>(Arrays.asList(Moves.values()));
|
||||||
ArrayList<Class<? extends Movement>> klasses = new ArrayList<>(count.keySet());
|
moves.sort(Comparator.comparingLong(k -> timeConsumed[k.ordinal()] / count[k.ordinal()]));
|
||||||
klasses.sort(Comparator.comparingLong(k -> timeConsumed.get(k) / count.get(k)));
|
for (Moves move : moves) {
|
||||||
for (Class<? extends Movement> klass : klasses) {
|
int num = count[move.ordinal()];
|
||||||
int num = count.get(klass);
|
long nanoTime = timeConsumed[move.ordinal()];
|
||||||
long nanoTime = timeConsumed.get(klass);
|
System.out.println(nanoTime / num + " " + move + " " + nanoTime / 1000000 + "ms " + num);
|
||||||
System.out.println(nanoTime / num + " " + klass + " " + nanoTime / 1000000 + "ms " + num);
|
System.out.println(stateLookup[move.ordinal()] / num + " " + stateLookup[move.ordinal()]);
|
||||||
System.out.println(stateLookup.get(klass) / num + " " + stateLookup.get(klass));
|
System.out.println(posCreation[move.ordinal()] / num + " " + posCreation[move.ordinal()]);
|
||||||
System.out.println(posCreation.get(klass) / num + " " + posCreation.get(klass));
|
|
||||||
}
|
}
|
||||||
if (cancelRequested) {
|
if (cancelRequested) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
@@ -282,56 +263,4 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
|||||||
logDebug("No path found =(");
|
logDebug("No path found =(");
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Movement[] getConnectedPositions(BetterBlockPos pos, CalculationContext calcContext) {
|
|
||||||
int x = pos.x;
|
|
||||||
int y = pos.y;
|
|
||||||
int z = pos.z;
|
|
||||||
BetterBlockPos east = new BetterBlockPos(x + 1, y, z);
|
|
||||||
BetterBlockPos west = new BetterBlockPos(x - 1, y, z);
|
|
||||||
BetterBlockPos south = new BetterBlockPos(x, y, z + 1);
|
|
||||||
BetterBlockPos north = new BetterBlockPos(x, y, z - 1);
|
|
||||||
return new Movement[]{
|
|
||||||
new MovementDownward(pos, new BetterBlockPos(x, y - 1, z)),
|
|
||||||
|
|
||||||
new MovementPillar(pos, new BetterBlockPos(x, y + 1, z)),
|
|
||||||
|
|
||||||
new MovementTraverse(pos, east),
|
|
||||||
new MovementTraverse(pos, west),
|
|
||||||
new MovementTraverse(pos, north),
|
|
||||||
new MovementTraverse(pos, south),
|
|
||||||
|
|
||||||
new MovementAscend(pos, new BetterBlockPos(x + 1, y + 1, z)),
|
|
||||||
new MovementAscend(pos, new BetterBlockPos(x - 1, y + 1, z)),
|
|
||||||
new MovementAscend(pos, new BetterBlockPos(x, y + 1, z + 1)),
|
|
||||||
new MovementAscend(pos, new BetterBlockPos(x, y + 1, z - 1)),
|
|
||||||
|
|
||||||
MovementHelper.generateMovementFallOrDescend(pos, east, calcContext),
|
|
||||||
MovementHelper.generateMovementFallOrDescend(pos, west, calcContext),
|
|
||||||
MovementHelper.generateMovementFallOrDescend(pos, north, calcContext),
|
|
||||||
MovementHelper.generateMovementFallOrDescend(pos, south, calcContext),
|
|
||||||
|
|
||||||
new MovementDiagonal(pos, EnumFacing.NORTH, EnumFacing.EAST),
|
|
||||||
new MovementDiagonal(pos, EnumFacing.NORTH, EnumFacing.WEST),
|
|
||||||
new MovementDiagonal(pos, EnumFacing.SOUTH, EnumFacing.EAST),
|
|
||||||
|
|
||||||
new MovementDiagonal(pos, EnumFacing.SOUTH, EnumFacing.WEST),
|
|
||||||
|
|
||||||
MovementParkour.generate(pos, EnumFacing.EAST, calcContext),
|
|
||||||
MovementParkour.generate(pos, EnumFacing.WEST, calcContext),
|
|
||||||
MovementParkour.generate(pos, EnumFacing.NORTH, calcContext),
|
|
||||||
MovementParkour.generate(pos, EnumFacing.SOUTH, calcContext),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> void shuffle(T[] list) {
|
|
||||||
int len = list.length;
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
int j = random.nextInt(len);
|
|
||||||
T t = list[j];
|
|
||||||
list[j] = list[i];
|
|
||||||
list[i] = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,7 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.behavior.PathingBehavior;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.goals.Goal;
|
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
@@ -115,9 +114,9 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
* @return The distance, squared
|
* @return The distance, squared
|
||||||
*/
|
*/
|
||||||
protected double getDistFromStartSq(PathNode n) {
|
protected double getDistFromStartSq(PathNode n) {
|
||||||
int xDiff = n.pos.x - start.x;
|
int xDiff = n.x - start.x;
|
||||||
int yDiff = n.pos.y - start.y;
|
int yDiff = n.y - start.y;
|
||||||
int zDiff = n.pos.z - start.z;
|
int zDiff = n.z - start.z;
|
||||||
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;
|
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,28 +125,62 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
* for the node mapped to the specified pos. If no node is found,
|
* for the node mapped to the specified pos. If no node is found,
|
||||||
* a new node is created.
|
* a new node is created.
|
||||||
*
|
*
|
||||||
* @param pos The pos to lookup
|
|
||||||
* @return The associated node
|
* @return The associated node
|
||||||
* @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a>
|
* @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a>
|
||||||
*/
|
*/
|
||||||
protected PathNode getNodeAtPosition(BetterBlockPos pos) {
|
protected PathNode getNodeAtPosition(int x, int y, int z) {
|
||||||
long hashCode = pos.hashCode;
|
long hashCode = posHash(x, y, z);
|
||||||
PathNode node = map.get(hashCode);
|
PathNode node = map.get(hashCode);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
node = new PathNode(pos, goal);
|
node = new PathNode(x, y, z, goal);
|
||||||
map.put(hashCode, node);
|
map.put(hashCode, node);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long posHash(int x, int y, int z) {
|
||||||
|
/*
|
||||||
|
* This is the hashcode implementation of Vec3i, the superclass of BlockPos
|
||||||
|
*
|
||||||
|
* public int hashCode() {
|
||||||
|
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* That is terrible and has tons of collisions and makes the HashMap terribly inefficient.
|
||||||
|
*
|
||||||
|
* That's why we grab out the X, Y, Z and calculate our own hashcode
|
||||||
|
*/
|
||||||
|
long hash = 3241;
|
||||||
|
hash = 3457689L * hash + x;
|
||||||
|
hash = 8734625L * hash + y;
|
||||||
|
hash = 2873465L * hash + z;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
public static void forceCancel() {
|
public static void forceCancel() {
|
||||||
PathingBehavior.INSTANCE.cancel();
|
|
||||||
currentlyRunning = null;
|
currentlyRunning = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PathNode mostRecentNodeConsidered() {
|
||||||
|
return mostRecentConsidered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathNode bestNodeSoFar() {
|
||||||
|
return bestSoFar[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathNode startNode() {
|
||||||
|
return startNode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<IPath> pathToMostRecentNodeConsidered() {
|
public Optional<IPath> pathToMostRecentNodeConsidered() {
|
||||||
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal));
|
try {
|
||||||
|
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal));
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
System.out.println("Unable to construct path to render");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int mapSize() {
|
protected int mapSize() {
|
||||||
@@ -164,7 +197,12 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal));
|
try {
|
||||||
|
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal));
|
||||||
|
} catch (IllegalStateException ex) {
|
||||||
|
System.out.println("Unable to construct path to render");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// instead of returning bestSoFar[0], be less misleading
|
// instead of returning bestSoFar[0], be less misleading
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
|
import baritone.pathing.movement.Moves;
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -60,8 +61,8 @@ class Path implements IPath {
|
|||||||
private volatile boolean verified;
|
private volatile boolean verified;
|
||||||
|
|
||||||
Path(PathNode start, PathNode end, int numNodes, Goal goal) {
|
Path(PathNode start, PathNode end, int numNodes, Goal goal) {
|
||||||
this.start = start.pos;
|
this.start = new BetterBlockPos(start.x, start.y, start.z);
|
||||||
this.end = end.pos;
|
this.end = new BetterBlockPos(end.x, end.y, end.z);
|
||||||
this.numNodes = numNodes;
|
this.numNodes = numNodes;
|
||||||
this.path = new ArrayList<>();
|
this.path = new ArrayList<>();
|
||||||
this.movements = new ArrayList<>();
|
this.movements = new ArrayList<>();
|
||||||
@@ -88,11 +89,11 @@ class Path implements IPath {
|
|||||||
LinkedList<BetterBlockPos> tempPath = new LinkedList<>(); // Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
LinkedList<BetterBlockPos> tempPath = new LinkedList<>(); // Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
||||||
LinkedList<Movement> tempMovements = new LinkedList<>(); // Instead, do it into a linked list, then convert at the end
|
LinkedList<Movement> tempMovements = new LinkedList<>(); // Instead, do it into a linked list, then convert at the end
|
||||||
while (!current.equals(start)) {
|
while (!current.equals(start)) {
|
||||||
tempPath.addFirst(current.pos);
|
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
|
||||||
tempMovements.addFirst(current.previousMovement);
|
tempMovements.addFirst(runBackwards(current.previous, current));
|
||||||
current = current.previous;
|
current = current.previous;
|
||||||
}
|
}
|
||||||
tempPath.addFirst(start.pos);
|
tempPath.addFirst(this.start);
|
||||||
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
|
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
|
||||||
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
||||||
// to performantly do that conversion since it knows the length.
|
// to performantly do that conversion since it knows the length.
|
||||||
@@ -100,6 +101,19 @@ class Path implements IPath {
|
|||||||
movements.addAll(tempMovements);
|
movements.addAll(tempMovements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Movement runBackwards(PathNode src0, PathNode dest0) { // TODO this is horrifying
|
||||||
|
BetterBlockPos src = new BetterBlockPos(src0.x, src0.y, src0.z);
|
||||||
|
BetterBlockPos dest = new BetterBlockPos(dest0.x, dest0.y, dest0.z);
|
||||||
|
for (Moves moves : Moves.values()) {
|
||||||
|
Movement move = moves.apply0(src);
|
||||||
|
if (move.getDest().equals(dest)) {
|
||||||
|
return move;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// leave this as IllegalStateException; it's caught in AbstractNodeCostSearch
|
||||||
|
throw new IllegalStateException("Movement became impossible during calculation " + src + " " + dest + " " + dest.subtract(src));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,10 +17,8 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.movement.ActionCosts;
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
import baritone.pathing.movement.Movement;
|
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node in the path, containing the cost and steps to get to it.
|
* A node in the path, containing the cost and steps to get to it.
|
||||||
@@ -32,12 +30,9 @@ public final class PathNode {
|
|||||||
/**
|
/**
|
||||||
* The position of this node
|
* The position of this node
|
||||||
*/
|
*/
|
||||||
final BetterBlockPos pos;
|
final int x;
|
||||||
|
final int y;
|
||||||
/**
|
final int z;
|
||||||
* The goal it's going towards
|
|
||||||
*/
|
|
||||||
final Goal goal;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached, should always be equal to goal.heuristic(pos)
|
* Cached, should always be equal to goal.heuristic(pos)
|
||||||
@@ -62,12 +57,6 @@ public final class PathNode {
|
|||||||
*/
|
*/
|
||||||
PathNode previous;
|
PathNode previous;
|
||||||
|
|
||||||
/**
|
|
||||||
* In the graph search, what previous movement (edge) was taken to get to here
|
|
||||||
* Mutable and changed by PathFinder
|
|
||||||
*/
|
|
||||||
Movement previousMovement;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this a member of the open set in A*? (only used during pathfinding)
|
* Is this a member of the open set in A*? (only used during pathfinding)
|
||||||
* Instead of doing a costly member check in the open set, cache membership in each node individually too.
|
* Instead of doing a costly member check in the open set, cache membership in each node individually too.
|
||||||
@@ -79,14 +68,14 @@ public final class PathNode {
|
|||||||
*/
|
*/
|
||||||
public int heapPosition;
|
public int heapPosition;
|
||||||
|
|
||||||
public PathNode(BetterBlockPos pos, Goal goal) {
|
public PathNode(int x, int y, int z, Goal goal) {
|
||||||
this.pos = pos;
|
|
||||||
this.previous = null;
|
this.previous = null;
|
||||||
this.cost = ActionCosts.COST_INF;
|
this.cost = ActionCosts.COST_INF;
|
||||||
this.goal = goal;
|
this.estimatedCostToGoal = goal.heuristic(x, y, z);
|
||||||
this.estimatedCostToGoal = goal.heuristic(pos);
|
|
||||||
this.previousMovement = null;
|
|
||||||
this.isOpen = false;
|
this.isOpen = false;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +85,7 @@ public final class PathNode {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return pos.hashCode() * 7 + 3;
|
return (int) AbstractNodeCostSearch.posHash(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,8 +97,9 @@ public final class PathNode {
|
|||||||
// return false;
|
// return false;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//final PathNode other = (PathNode) obj;
|
final PathNode other = (PathNode) obj;
|
||||||
//return Objects.equals(this.pos, other.pos) && Objects.equals(this.goal, other.goal);
|
//return Objects.equals(this.pos, other.pos) && Objects.equals(this.goal, other.goal);
|
||||||
return this.pos.equals(((PathNode) obj).pos);
|
|
||||||
|
return x == other.x && y == other.y && z == other.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +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.pathing.movement;
|
|
||||||
|
|
||||||
public interface ActionCosts extends ActionCostsButOnlyTheOnesThatMakeMickeyDieInside {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* These costs are measured roughly in ticks btw
|
|
||||||
*/
|
|
||||||
double WALK_ONE_BLOCK_COST = 20 / 4.317; // 4.633
|
|
||||||
double WALK_ONE_IN_WATER_COST = 20 / 2.2;
|
|
||||||
double WALK_ONE_OVER_SOUL_SAND_COST = WALK_ONE_BLOCK_COST * 2; // 0.4 in BlockSoulSand but effectively about half
|
|
||||||
double SPRINT_ONE_OVER_SOUL_SAND_COST = WALK_ONE_OVER_SOUL_SAND_COST * 0.75;
|
|
||||||
double LADDER_UP_ONE_COST = 20 / 2.35;
|
|
||||||
double LADDER_DOWN_ONE_COST = 20 / 3.0;
|
|
||||||
double SNEAK_ONE_BLOCK_COST = 20 / 1.3;
|
|
||||||
double SPRINT_ONE_BLOCK_COST = 20 / 5.612; // 3.564
|
|
||||||
/**
|
|
||||||
* To walk off an edge you need to walk 0.5 to the edge then 0.3 to start falling off
|
|
||||||
*/
|
|
||||||
double WALK_OFF_BLOCK_COST = WALK_ONE_BLOCK_COST * 0.8;
|
|
||||||
/**
|
|
||||||
* To walk the rest of the way to be centered on the new block
|
|
||||||
*/
|
|
||||||
double CENTER_AFTER_FALL_COST = WALK_ONE_BLOCK_COST - WALK_OFF_BLOCK_COST;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* don't make this Double.MAX_VALUE because it's added to other things, maybe other COST_INFs,
|
|
||||||
* and that would make it overflow to negative
|
|
||||||
*/
|
|
||||||
double COST_INF = 1000000;
|
|
||||||
}
|
|
||||||
@@ -18,18 +18,19 @@
|
|||||||
package baritone.pathing.movement;
|
package baritone.pathing.movement;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.behavior.LookBehavior;
|
import baritone.behavior.LookBehavior;
|
||||||
import baritone.behavior.LookBehaviorUtils;
|
import baritone.behavior.LookBehaviorUtils;
|
||||||
import baritone.pathing.movement.MovementState.MovementStatus;
|
import baritone.pathing.movement.MovementState.MovementStatus;
|
||||||
import baritone.utils.*;
|
import baritone.utils.*;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -158,8 +159,8 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
boolean somethingInTheWay = false;
|
boolean somethingInTheWay = false;
|
||||||
for (BlockPos blockPos : positionsToBreak) {
|
for (BetterBlockPos blockPos : positionsToBreak) {
|
||||||
if (!MovementHelper.canWalkThrough(blockPos)) {
|
if (!MovementHelper.canWalkThrough(blockPos) && !(BlockStateInterface.getBlock(blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
|
||||||
somethingInTheWay = true;
|
somethingInTheWay = true;
|
||||||
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
|
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
|
||||||
if (reachable.isPresent()) {
|
if (reachable.isPresent()) {
|
||||||
@@ -218,60 +219,6 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTotalHardnessOfBlocksToBreak(CalculationContext ctx) {
|
|
||||||
if (positionsToBreak.length == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (positionsToBreak.length == 1) {
|
|
||||||
return MovementHelper.getMiningDurationTicks(ctx, positionsToBreak[0], true);
|
|
||||||
}
|
|
||||||
int firstColumnX = positionsToBreak[0].getX();
|
|
||||||
int firstColumnZ = positionsToBreak[0].getZ();
|
|
||||||
int firstColumnMaxY = positionsToBreak[0].getY();
|
|
||||||
int firstColumnMaximalIndex = 0;
|
|
||||||
boolean hasSecondColumn = false;
|
|
||||||
int secondColumnX = -1;
|
|
||||||
int secondColumnZ = -1;
|
|
||||||
int secondColumnMaxY = -1;
|
|
||||||
int secondColumnMaximalIndex = -1;
|
|
||||||
for (int i = 0; i < positionsToBreak.length; i++) {
|
|
||||||
BlockPos pos = positionsToBreak[i];
|
|
||||||
if (pos.getX() == firstColumnX && pos.getZ() == firstColumnZ) {
|
|
||||||
if (pos.getY() > firstColumnMaxY) {
|
|
||||||
firstColumnMaxY = pos.getY();
|
|
||||||
firstColumnMaximalIndex = i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!hasSecondColumn || (pos.getX() == secondColumnX && pos.getZ() == secondColumnZ)) {
|
|
||||||
if (hasSecondColumn) {
|
|
||||||
if (pos.getY() > secondColumnMaxY) {
|
|
||||||
secondColumnMaxY = pos.getY();
|
|
||||||
secondColumnMaximalIndex = i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hasSecondColumn = true;
|
|
||||||
secondColumnX = pos.getX();
|
|
||||||
secondColumnZ = pos.getZ();
|
|
||||||
secondColumnMaxY = pos.getY();
|
|
||||||
secondColumnMaximalIndex = i;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("I literally have no idea " + Arrays.asList(positionsToBreak));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double sum = 0;
|
|
||||||
for (int i = 0; i < positionsToBreak.length; i++) {
|
|
||||||
sum += MovementHelper.getMiningDurationTicks(ctx, positionsToBreak[i], firstColumnMaximalIndex == i || secondColumnMaximalIndex == i);
|
|
||||||
if (sum >= COST_INF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate latest movement state.
|
* Calculate latest movement state.
|
||||||
* Gets called once a tick.
|
* Gets called once a tick.
|
||||||
@@ -309,7 +256,7 @@ public abstract class Movement implements Helper, MovementHelper {
|
|||||||
return toBreakCached;
|
return toBreakCached;
|
||||||
}
|
}
|
||||||
List<BlockPos> result = new ArrayList<>();
|
List<BlockPos> result = new ArrayList<>();
|
||||||
for (BlockPos positionToBreak : positionsToBreak) {
|
for (BetterBlockPos positionToBreak : positionsToBreak) {
|
||||||
if (!MovementHelper.canWalkThrough(positionToBreak)) {
|
if (!MovementHelper.canWalkThrough(positionToBreak)) {
|
||||||
result.add(positionToBreak);
|
result.add(positionToBreak);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,10 @@
|
|||||||
package baritone.pathing.movement;
|
package baritone.pathing.movement;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.behavior.LookBehaviorUtils;
|
import baritone.behavior.LookBehaviorUtils;
|
||||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||||
import baritone.pathing.movement.movements.MovementDescend;
|
|
||||||
import baritone.pathing.movement.movements.MovementFall;
|
|
||||||
import baritone.utils.*;
|
import baritone.utils.*;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
@@ -47,11 +47,12 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public interface MovementHelper extends ActionCosts, Helper {
|
public interface MovementHelper extends ActionCosts, Helper {
|
||||||
|
|
||||||
static boolean avoidBreaking(BlockPos pos, IBlockState state) {
|
static boolean avoidBreaking(BetterBlockPos pos, IBlockState state) {
|
||||||
|
return avoidBreaking(pos.x, pos.y, pos.z, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean avoidBreaking(int x, int y, int z, IBlockState state) {
|
||||||
Block b = state.getBlock();
|
Block b = state.getBlock();
|
||||||
int x = pos.getX();
|
|
||||||
int y = pos.getY();
|
|
||||||
int z = pos.getZ();
|
|
||||||
return b == Blocks.ICE // ice becomes water, and water can mess up the path
|
return b == Blocks.ICE // ice becomes water, and water can mess up the path
|
||||||
|| b instanceof BlockSilverfish // obvious reasons
|
|| b instanceof BlockSilverfish // obvious reasons
|
||||||
// call BlockStateInterface.get directly with x,y,z. no need to make 5 new BlockPos for no reason
|
// call BlockStateInterface.get directly with x,y,z. no need to make 5 new BlockPos for no reason
|
||||||
@@ -68,13 +69,21 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @param pos
|
* @param pos
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static boolean canWalkThrough(BlockPos pos) {
|
static boolean canWalkThrough(BetterBlockPos pos) {
|
||||||
return canWalkThrough(pos, BlockStateInterface.get(pos));
|
return canWalkThrough(pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canWalkThrough(BlockPos pos, IBlockState state) {
|
static boolean canWalkThrough(BetterBlockPos pos, IBlockState state) {
|
||||||
|
return canWalkThrough(pos.x, pos.y, pos.z, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean canWalkThrough(int x, int y, int z) {
|
||||||
|
return canWalkThrough(x, y, z, BlockStateInterface.get(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean canWalkThrough(int x, int y, int z, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block == Blocks.AIR) {
|
if (block == Blocks.AIR) { // early return for most common case
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL) {
|
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL) {
|
||||||
@@ -86,14 +95,23 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
// be opened by just interacting.
|
// be opened by just interacting.
|
||||||
return block != Blocks.IRON_DOOR;
|
return block != Blocks.IRON_DOOR;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockSnow || block instanceof BlockTrapDoor) {
|
boolean snow = block instanceof BlockSnow;
|
||||||
// we've already checked doors
|
boolean trapdoor = block instanceof BlockTrapDoor;
|
||||||
// so the only remaining dynamic isPassables are snow, fence gate, and trapdoor
|
if (snow || trapdoor) {
|
||||||
|
// we've already checked doors and fence gates
|
||||||
|
// so the only remaining dynamic isPassables are snow and trapdoor
|
||||||
// if they're cached as a top block, we don't know their metadata
|
// if they're cached as a top block, we don't know their metadata
|
||||||
// default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
|
// default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
|
||||||
if (mc.world.getChunk(pos) instanceof EmptyChunk) {
|
if (mc.world.getChunk(x >> 4, z >> 4) instanceof EmptyChunk) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (snow) {
|
||||||
|
return state.getValue(BlockSnow.LAYERS) < 5; // see BlockSnow.isPassable
|
||||||
|
}
|
||||||
|
if (trapdoor) {
|
||||||
|
return !state.getValue(BlockTrapDoor.OPEN); // see BlockTrapDoor.isPassable
|
||||||
|
}
|
||||||
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.isFlowing(state)) {
|
if (BlockStateInterface.isFlowing(state)) {
|
||||||
return false; // Don't walk through flowing liquids
|
return false; // Don't walk through flowing liquids
|
||||||
@@ -102,13 +120,16 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (Baritone.settings().assumeWalkOnWater.get()) {
|
if (Baritone.settings().assumeWalkOnWater.get()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
IBlockState up = BlockStateInterface.get(pos.up());
|
IBlockState up = BlockStateInterface.get(x, y + 1, z);
|
||||||
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return block == Blocks.WATER || block == Blocks.FLOWING_WATER;
|
return block == Blocks.WATER || block == Blocks.FLOWING_WATER;
|
||||||
}
|
}
|
||||||
return block.isPassable(mc.world, pos); // only blocks that can get here and actually that use world and pos for this call are snow and trapdoor
|
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
|
||||||
|
// has already been accounted for above
|
||||||
|
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
|
||||||
|
return block.isPassable(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,12 +139,16 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static boolean fullyPassable(BlockPos pos) {
|
static boolean fullyPassable(BlockPos pos) {
|
||||||
return fullyPassable(pos, BlockStateInterface.get(pos));
|
return fullyPassable(BlockStateInterface.get(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean fullyPassable(BlockPos pos, IBlockState state) {
|
static boolean fullyPassable(int x, int y, int z) {
|
||||||
|
return fullyPassable(BlockStateInterface.get(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean fullyPassable(IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block == Blocks.AIR) {
|
if (block == Blocks.AIR) { // early return for most common case
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// exceptions - blocks that are isPassable true, but we can't actually jump through
|
// exceptions - blocks that are isPassable true, but we can't actually jump through
|
||||||
@@ -140,10 +165,15 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
|| block instanceof BlockEndPortal) {
|
|| block instanceof BlockEndPortal) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return block.isPassable(mc.world, pos);
|
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
||||||
|
return block.isPassable(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isReplacable(BlockPos pos, IBlockState state) {
|
static boolean isReplacable(BlockPos pos, IBlockState state) {
|
||||||
|
return isReplacable(pos.getX(), pos.getY(), pos.getZ(), state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isReplacable(int x, int y, int z, IBlockState state) {
|
||||||
// for MovementTraverse and MovementAscend
|
// for MovementTraverse and MovementAscend
|
||||||
// block double plant defaults to true when the block doesn't match, so don't need to check that case
|
// block double plant defaults to true when the block doesn't match, so don't need to check that case
|
||||||
// all other overrides just return true or false
|
// all other overrides just return true or false
|
||||||
@@ -154,13 +184,19 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* return ((Integer)worldIn.getBlockState(pos).getValue(LAYERS)).intValue() == 1;
|
* return ((Integer)worldIn.getBlockState(pos).getValue(LAYERS)).intValue() == 1;
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
if (state.getBlock() instanceof BlockSnow) {
|
Block block = state.getBlock();
|
||||||
|
if (block instanceof BlockSnow) {
|
||||||
// as before, default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
|
// as before, default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
|
||||||
if (mc.world.getChunk(pos) instanceof EmptyChunk) {
|
if (mc.world.getChunk(x >> 4, z >> 4) instanceof EmptyChunk) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return state.getValue(BlockSnow.LAYERS) == 1;
|
||||||
}
|
}
|
||||||
return state.getBlock().isReplaceable(mc.world, pos);
|
if (block instanceof BlockDoublePlant) {
|
||||||
|
BlockDoublePlant.EnumPlantType kek = state.getValue(BlockDoublePlant.VARIANT);
|
||||||
|
return kek == BlockDoublePlant.EnumPlantType.FERN || kek == BlockDoublePlant.EnumPlantType.GRASS;
|
||||||
|
}
|
||||||
|
return state.getBlock().isReplaceable(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isDoorPassable(BlockPos doorPos, BlockPos playerPos) {
|
static boolean isDoorPassable(BlockPos doorPos, BlockPos playerPos) {
|
||||||
@@ -226,9 +262,11 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static boolean canWalkOn(BetterBlockPos pos, IBlockState state) {
|
static boolean canWalkOn(int x, int y, int z, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block == Blocks.AIR || block == Blocks.MAGMA) {
|
if (block == Blocks.AIR || block == Blocks.MAGMA) {
|
||||||
|
// early return for most common case (air)
|
||||||
|
// plus magma, which is a normal cube but it hurts you
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (state.isBlockNormalCube()) {
|
if (state.isBlockNormalCube()) {
|
||||||
@@ -249,7 +287,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (BlockStateInterface.isWater(block)) {
|
if (BlockStateInterface.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(pos.x, pos.y + 1, pos.z).getBlock();
|
Block up = BlockStateInterface.get(x, y + 1, z).getBlock();
|
||||||
if (up == Blocks.WATERLILY) {
|
if (up == Blocks.WATERLILY) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -279,42 +317,70 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean canWalkOn(BetterBlockPos pos, IBlockState state) {
|
||||||
|
return canWalkOn(pos.x, pos.y, pos.z, state);
|
||||||
|
}
|
||||||
|
|
||||||
static boolean canWalkOn(BetterBlockPos pos) {
|
static boolean canWalkOn(BetterBlockPos pos) {
|
||||||
return canWalkOn(pos, BlockStateInterface.get(pos));
|
return canWalkOn(pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean canWalkOn(int x, int y, int z) {
|
||||||
|
return canWalkOn(x, y, z, BlockStateInterface.get(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean canPlaceAgainst(int x, int y, int z) {
|
||||||
|
return canPlaceAgainst(BlockStateInterface.get(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canPlaceAgainst(BlockPos pos) {
|
static boolean canPlaceAgainst(BlockPos pos) {
|
||||||
IBlockState state = BlockStateInterface.get(pos);
|
return canPlaceAgainst(BlockStateInterface.get(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean canPlaceAgainst(IBlockState state) {
|
||||||
// TODO isBlockNormalCube isn't the best check for whether or not we can place a block against it. e.g. glass isn't normalCube but we can place against it
|
// TODO isBlockNormalCube isn't the best check for whether or not we can place a block against it. e.g. glass isn't normalCube but we can place against it
|
||||||
return state.isBlockNormalCube();
|
return state.isBlockNormalCube();
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, BlockPos position, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, BetterBlockPos position,
|
||||||
|
boolean includeFalling) {
|
||||||
IBlockState state = BlockStateInterface.get(position);
|
IBlockState state = BlockStateInterface.get(position);
|
||||||
return getMiningDurationTicks(context, position, state, includeFalling);
|
return getMiningDurationTicks(context, position.x, position.y, position.z, state, includeFalling);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, BlockPos position, IBlockState state, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, BetterBlockPos position, IBlockState state,
|
||||||
|
boolean includeFalling) {
|
||||||
|
return getMiningDurationTicks(context, position.x, position.y, position.z, state, includeFalling);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
||||||
|
return getMiningDurationTicks(context, x, y, z, BlockStateInterface.get(x, y, z), includeFalling);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state,
|
||||||
|
boolean includeFalling) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (!canWalkThrough(position, state)) {
|
if (!canWalkThrough(x, y, z, state)) {
|
||||||
if (!context.allowBreak()) {
|
if (!context.allowBreak()) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (avoidBreaking(position, state)) {
|
if (avoidBreaking(x, y, z, state)) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
if (block instanceof BlockLiquid) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
|
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
|
||||||
double strVsBlock = context.getToolSet().getStrVsBlock(state);
|
double strVsBlock = context.getToolSet().getStrVsBlock(state);
|
||||||
if (strVsBlock < 0) {
|
if (strVsBlock <= 0) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
|
|
||||||
double result = m / strVsBlock;
|
double result = m / strVsBlock;
|
||||||
if (includeFalling) {
|
if (includeFalling) {
|
||||||
BlockPos up = position.up();
|
IBlockState above = BlockStateInterface.get(x, y + 1, z);
|
||||||
IBlockState above = BlockStateInterface.get(up);
|
|
||||||
if (above.getBlock() instanceof BlockFalling) {
|
if (above.getBlock() instanceof BlockFalling) {
|
||||||
result += getMiningDurationTicks(context, up, above, true);
|
result += getMiningDurationTicks(context, x, y + 1, z, above, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -400,57 +466,8 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
state.setTarget(new MovementTarget(
|
state.setTarget(new MovementTarget(
|
||||||
new Rotation(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
new Rotation(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
|
||||||
Utils.getBlockPosCenter(pos),
|
Utils.getBlockPosCenter(pos),
|
||||||
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)).getFirst(), mc.player.rotationPitch),
|
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)).getYaw(), mc.player.rotationPitch),
|
||||||
false
|
false
|
||||||
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Movement generateMovementFallOrDescend(BetterBlockPos pos, BetterBlockPos dest, CalculationContext calcContext) {
|
|
||||||
// A
|
|
||||||
//SA
|
|
||||||
// A
|
|
||||||
// B
|
|
||||||
// C
|
|
||||||
// D
|
|
||||||
//if S is where you start, B needs to be air for a movementfall
|
|
||||||
//A is plausibly breakable by either descend or fall
|
|
||||||
//C, D, etc determine the length of the fall
|
|
||||||
|
|
||||||
if (!canWalkThrough(dest.down(2))) {
|
|
||||||
//if B in the diagram aren't air
|
|
||||||
//have to do a descend, because fall is impossible
|
|
||||||
|
|
||||||
//this doesn't guarantee descend is possible, it just guarantees fall is impossible
|
|
||||||
return new MovementDescend(pos, dest.down()); // standard move out by 1 and descend by 1
|
|
||||||
// we can't cost shortcut descend because !canWalkThrough doesn't mean canWalkOn
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're clear for a fall 2
|
|
||||||
// let's see how far we can fall
|
|
||||||
for (int fallHeight = 3; true; fallHeight++) {
|
|
||||||
BetterBlockPos onto = dest.down(fallHeight);
|
|
||||||
if (onto.getY() < 0) {
|
|
||||||
// when pathing in the end, where you could plausibly fall into the void
|
|
||||||
// this check prevents it from getting the block at y=-1 and crashing
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
IBlockState ontoBlock = BlockStateInterface.get(onto);
|
|
||||||
if (ontoBlock.getBlock() == Blocks.WATER) {
|
|
||||||
return new MovementFall(pos, onto);
|
|
||||||
}
|
|
||||||
if (canWalkThrough(onto, ontoBlock)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!canWalkOn(onto, ontoBlock)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((calcContext.hasWaterBucket() && fallHeight <= calcContext.maxFallHeightBucket() + 1) || fallHeight <= calcContext.maxFallHeightNoWater() + 1) {
|
|
||||||
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
|
||||||
return new MovementFall(pos, onto.up());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement;
|
package baritone.pathing.movement;
|
||||||
|
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.utils.InputOverrideHandler.Input;
|
import baritone.utils.InputOverrideHandler.Input;
|
||||||
import baritone.utils.Rotation;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|||||||
@@ -0,0 +1,333 @@
|
|||||||
|
/*
|
||||||
|
* 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.pathing.movement;
|
||||||
|
|
||||||
|
import baritone.pathing.movement.movements.*;
|
||||||
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
|
import baritone.utils.pathing.MoveResult;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum of all possible movements attached to all possible directions they could be taken in
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public enum Moves {
|
||||||
|
DOWNWARD(0, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementDownward(src, src.down());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x, y - 1, z, MovementDownward.cost(context, x, y, z));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
PILLAR(0, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementPillar(src, src.up());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x, y + 1, z, MovementPillar.cost(context, x, y, z));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
TRAVERSE_NORTH(0, -1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementTraverse(src, src.north());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x, y, z - 1, MovementTraverse.cost(context, x, y, z, x, z - 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
TRAVERSE_SOUTH(0, +1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementTraverse(src, src.south());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x, y, z + 1, MovementTraverse.cost(context, x, y, z, x, z + 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
TRAVERSE_EAST(+1, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementTraverse(src, src.east());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x + 1, y, z, MovementTraverse.cost(context, x, y, z, x + 1, z));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
TRAVERSE_WEST(-1, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementTraverse(src, src.west());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x - 1, y, z, MovementTraverse.cost(context, x, y, z, x - 1, z));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ASCEND_NORTH(0, -1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x, y + 1, z - 1, MovementAscend.cost(context, x, y, z, x, z - 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ASCEND_SOUTH(0, +1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x, y + 1, z + 1, MovementAscend.cost(context, x, y, z, x, z + 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ASCEND_EAST(+1, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementAscend(src, new BetterBlockPos(src.x + 1, src.y + 1, src.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x + 1, y + 1, z, MovementAscend.cost(context, x, y, z, x + 1, z));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ASCEND_WEST(-1, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementAscend(src, new BetterBlockPos(src.x - 1, src.y + 1, src.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x - 1, y + 1, z, MovementAscend.cost(context, x, y, z, x - 1, z));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DESCEND_EAST(+1, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
|
||||||
|
if (res.destY == src.y - 1) {
|
||||||
|
return new MovementDescend(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
} else {
|
||||||
|
return new MovementFall(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementDescend.cost(context, x, y, z, x + 1, z);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DESCEND_WEST(-1, 0) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
|
||||||
|
if (res.destY == src.y - 1) {
|
||||||
|
return new MovementDescend(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
} else {
|
||||||
|
return new MovementFall(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementDescend.cost(context, x, y, z, x - 1, z);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DESCEND_NORTH(0, -1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
|
||||||
|
if (res.destY == src.y - 1) {
|
||||||
|
return new MovementDescend(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
} else {
|
||||||
|
return new MovementFall(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementDescend.cost(context, x, y, z, x, z - 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DESCEND_SOUTH(0, +1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
|
||||||
|
if (res.destY == src.y - 1) {
|
||||||
|
return new MovementDescend(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
} else {
|
||||||
|
return new MovementFall(src, new BetterBlockPos(res.destX, res.destY, res.destZ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementDescend.cost(context, x, y, z, x, z + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DIAGONAL_NORTHEAST(+1, -1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.EAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x + 1, y, z - 1, MovementDiagonal.cost(context, x, y, z, x + 1, z - 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DIAGONAL_NORTHWEST(-1, -1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.WEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x - 1, y, z - 1, MovementDiagonal.cost(context, x, y, z, x - 1, z - 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DIAGONAL_SOUTHEAST(+1, +1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.EAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x + 1, y, z + 1, MovementDiagonal.cost(context, x, y, z, x + 1, z + 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DIAGONAL_SOUTHWEST(-1, +1) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.WEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return new MoveResult(x - 1, y, z + 1, MovementDiagonal.cost(context, x, y, z, x - 1, z + 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
PARKOUR_NORTH(0, -4, true) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.NORTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementParkour.cost(context, x, y, z, EnumFacing.NORTH);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
PARKOUR_SOUTH(0, +4, true) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.SOUTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementParkour.cost(context, x, y, z, EnumFacing.SOUTH);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
PARKOUR_EAST(+4, 0, true) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.EAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementParkour.cost(context, x, y, z, EnumFacing.EAST);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
PARKOUR_WEST(-4, 0, true) {
|
||||||
|
@Override
|
||||||
|
public Movement apply0(BetterBlockPos src) {
|
||||||
|
return MovementParkour.cost(new CalculationContext(), src, EnumFacing.WEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MoveResult apply(CalculationContext context, int x, int y, int z) {
|
||||||
|
return MovementParkour.cost(context, x, y, z, EnumFacing.WEST);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public final boolean dynamicXZ;
|
||||||
|
|
||||||
|
public final int xOffset;
|
||||||
|
public final int zOffset;
|
||||||
|
|
||||||
|
Moves(int x, int z, boolean dynamicXZ) {
|
||||||
|
this.xOffset = x;
|
||||||
|
this.zOffset = z;
|
||||||
|
this.dynamicXZ = dynamicXZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Moves(int x, int z) {
|
||||||
|
this(x, z, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Movement apply0(BetterBlockPos src);
|
||||||
|
|
||||||
|
public abstract MoveResult apply(CalculationContext context, int x, int y, int z);
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ import baritone.utils.BlockStateInterface;
|
|||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.Utils;
|
import baritone.utils.Utils;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockFalling;
|
import net.minecraft.block.BlockFalling;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -55,46 +54,54 @@ public class MovementAscend extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
IBlockState srcDown = BlockStateInterface.get(src.down());
|
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
|
IBlockState srcDown = BlockStateInterface.get(x, y - 1, z);
|
||||||
if (srcDown.getBlock() == Blocks.LADDER || srcDown.getBlock() == Blocks.VINE) {
|
if (srcDown.getBlock() == Blocks.LADDER || srcDown.getBlock() == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
// we can jump from soul sand, but not from a bottom slab
|
// we can jump from soul sand, but not from a bottom slab
|
||||||
boolean jumpingFromBottomSlab = MovementHelper.isBottomSlab(srcDown);
|
boolean jumpingFromBottomSlab = MovementHelper.isBottomSlab(srcDown);
|
||||||
IBlockState toPlace = BlockStateInterface.get(positionToPlace);
|
IBlockState toPlace = BlockStateInterface.get(destX, y, destZ);
|
||||||
boolean jumpingToBottomSlab = MovementHelper.isBottomSlab(toPlace);
|
boolean jumpingToBottomSlab = MovementHelper.isBottomSlab(toPlace);
|
||||||
|
|
||||||
if (jumpingFromBottomSlab && !jumpingToBottomSlab) {
|
if (jumpingFromBottomSlab && !jumpingToBottomSlab) {
|
||||||
return COST_INF;// the only thing we can ascend onto from a bottom slab is another bottom slab
|
return COST_INF;// the only thing we can ascend onto from a bottom slab is another bottom slab
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkOn(positionToPlace, toPlace)) {
|
boolean hasToPlace = false;
|
||||||
|
if (!MovementHelper.canWalkOn(destX, y, z, toPlace)) {
|
||||||
if (!context.hasThrowaway()) {
|
if (!context.hasThrowaway()) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionToPlace, toPlace)) {
|
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.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
|
||||||
// useful for when you are starting a staircase without anything to place against
|
// useful for when you are starting a staircase without anything to place against
|
||||||
// Counterpoint to the above TODO ^ you should move then pillar instead of ascend
|
// Counterpoint to the above TODO ^ you should move then pillar instead of ascend
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
BlockPos against1 = positionToPlace.offset(HORIZONTALS[i]);
|
int againstX = destX + HORIZONTALS[i].getXOffset();
|
||||||
if (against1.equals(src)) {
|
int againstZ = destZ + HORIZONTALS[i].getZOffset();
|
||||||
|
if (againstX == x && againstZ == z) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(against1)) {
|
if (MovementHelper.canPlaceAgainst(againstX, y, againstZ)) {
|
||||||
return JUMP_ONE_BLOCK_COST + WALK_ONE_BLOCK_COST + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
hasToPlace = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return COST_INF;
|
if (!hasToPlace) { // didn't find a valid place =(
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.get(src.up(3)).getBlock() instanceof BlockFalling) {//it would fall on us and possibly suffocate us
|
IBlockState srcUp2 = null;
|
||||||
|
if (BlockStateInterface.get(x, y + 3, 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
|
||||||
Block srcUp = BlockStateInterface.get(src.up(1)).getBlock();
|
if (!(BlockStateInterface.getBlock(x, y + 1, z) instanceof BlockFalling) || !((srcUp2 = BlockStateInterface.get(x, y + 2, z)).getBlock() instanceof BlockFalling)) {
|
||||||
Block srcUp2 = BlockStateInterface.get(src.up(2)).getBlock();
|
|
||||||
if (!(srcUp instanceof BlockFalling) || !(srcUp2 instanceof BlockFalling)) {
|
|
||||||
// if both of those are BlockFalling, that means that by standing on src
|
// if both of those are BlockFalling, 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
|
||||||
@@ -109,15 +116,41 @@ public class MovementAscend extends Movement {
|
|||||||
// 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
|
||||||
// and in that scenario, when we arrive and break srcUp2, that lets srcUp3 fall on us and suffocate us
|
// and in that scenario, when we arrive and break srcUp2, that lets srcUp3 fall on us and suffocate us
|
||||||
}
|
}
|
||||||
double walk = WALK_ONE_BLOCK_COST;
|
double walk;
|
||||||
if (jumpingToBottomSlab && !jumpingFromBottomSlab) {
|
if (jumpingToBottomSlab) {
|
||||||
return walk + getTotalHardnessOfBlocksToBreak(context); // we don't hit space we just walk into the slab
|
if (jumpingFromBottomSlab) {
|
||||||
|
walk = Math.max(JUMP_ONE_BLOCK_COST, WALK_ONE_BLOCK_COST); // we hit space immediately on entering this action
|
||||||
|
} else {
|
||||||
|
walk = WALK_ONE_BLOCK_COST; // we don't hit space we just walk into the slab
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (toPlace.getBlock() == Blocks.SOUL_SAND) {
|
||||||
|
walk = WALK_ONE_OVER_SOUL_SAND_COST;
|
||||||
|
} else {
|
||||||
|
walk = WALK_ONE_BLOCK_COST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!jumpingToBottomSlab && toPlace.getBlock().equals(Blocks.SOUL_SAND)) {
|
|
||||||
walk *= WALK_ONE_OVER_SOUL_SAND_COST / WALK_ONE_BLOCK_COST;
|
// cracks knuckles
|
||||||
|
|
||||||
|
double totalCost = 0;
|
||||||
|
totalCost += walk;
|
||||||
|
if (hasToPlace) {
|
||||||
|
totalCost += context.placeBlockCost();
|
||||||
}
|
}
|
||||||
// we hit space immediately on entering this action
|
if (srcUp2 == null) {
|
||||||
return Math.max(JUMP_ONE_BLOCK_COST, walk) + getTotalHardnessOfBlocksToBreak(context);
|
srcUp2 = BlockStateInterface.get(x, y + 2, z);
|
||||||
|
}
|
||||||
|
totalCost += MovementHelper.getMiningDurationTicks(context, x, y + 2, z, srcUp2, false); // TODO MAKE ABSOLUTELY SURE we don't need includeFalling here, from the falling check above
|
||||||
|
if (totalCost >= COST_INF) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, false);
|
||||||
|
if (totalCost >= COST_INF) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y + 2, destZ, true);
|
||||||
|
return totalCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -202,9 +235,9 @@ public class MovementAscend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean headBonkClear() {
|
private boolean headBonkClear() {
|
||||||
BlockPos startUp = src.up(2);
|
BetterBlockPos startUp = src.up(2);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
BlockPos check = startUp.offset(EnumFacing.byHorizontalIndex(i));
|
BetterBlockPos check = startUp.offset(EnumFacing.byHorizontalIndex(i));
|
||||||
if (!MovementHelper.canWalkThrough(check)) {
|
if (!MovementHelper.canWalkThrough(check)) {
|
||||||
// We might bonk our head
|
// We might bonk our head
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
@@ -25,10 +26,15 @@ import baritone.pathing.movement.MovementState.MovementStatus;
|
|||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
|
import baritone.utils.pathing.MoveResult;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockFalling;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import static baritone.utils.pathing.MoveResult.IMPOSSIBLE;
|
||||||
|
|
||||||
public class MovementDescend extends Movement {
|
public class MovementDescend extends Movement {
|
||||||
|
|
||||||
private int numTicks = 0;
|
private int numTicks = 0;
|
||||||
@@ -45,24 +51,111 @@ public class MovementDescend extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
Block fromDown = BlockStateInterface.get(src.down()).getBlock();
|
MoveResult result = cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||||
|
if (result.destY != dest.y) {
|
||||||
|
return COST_INF; // doesn't apply to us, this position is a fall not a descend
|
||||||
|
}
|
||||||
|
return result.cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MoveResult cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
|
Block fromDown = BlockStateInterface.get(x, y - 1, z).getBlock();
|
||||||
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
||||||
return COST_INF;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkOn(positionToPlace)) {
|
|
||||||
return COST_INF;
|
double totalCost = 0;
|
||||||
|
IBlockState destDown = BlockStateInterface.get(destX, y - 1, destZ);
|
||||||
|
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y - 1, destZ, destDown, false);
|
||||||
|
if (totalCost >= COST_INF) {
|
||||||
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
Block tmp1 = BlockStateInterface.get(dest).getBlock();
|
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y, destZ, false);
|
||||||
if (tmp1 == Blocks.LADDER || tmp1 == Blocks.VINE) {
|
if (totalCost >= COST_INF) {
|
||||||
return COST_INF;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
|
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, true); // only the top block in the 3 we need to mine needs to consider the falling blocks above
|
||||||
|
if (totalCost >= COST_INF) {
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A
|
||||||
|
//SA
|
||||||
|
// A
|
||||||
|
// B
|
||||||
|
// C
|
||||||
|
// D
|
||||||
|
//if S is where you start, B needs to be air for a movementfall
|
||||||
|
//A is plausibly breakable by either descend or fall
|
||||||
|
//C, D, etc determine the length of the fall
|
||||||
|
|
||||||
|
IBlockState below = BlockStateInterface.get(destX, y - 2, destZ);
|
||||||
|
if (!MovementHelper.canWalkOn(destX, y - 2, destZ, below)) {
|
||||||
|
return dynamicFallCost(context, x, y, z, destX, destZ, totalCost, below);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destDown.getBlock() == Blocks.LADDER || destDown.getBlock() == Blocks.VINE) {
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
// we walk half the block plus 0.3 to get to the edge, then we walk the other 0.2 while simultaneously falling (math.max because of how it's in parallel)
|
// we walk half the block plus 0.3 to get to the edge, then we walk the other 0.2 while simultaneously falling (math.max because of how it's in parallel)
|
||||||
double walk = WALK_OFF_BLOCK_COST;
|
double walk = WALK_OFF_BLOCK_COST;
|
||||||
if (fromDown == Blocks.SOUL_SAND) {
|
if (fromDown == Blocks.SOUL_SAND) {
|
||||||
// use this ratio to apply the soul sand speed penalty to our 0.8 block distance
|
// use this ratio to apply the soul sand speed penalty to our 0.8 block distance
|
||||||
walk = WALK_ONE_OVER_SOUL_SAND_COST;
|
walk = WALK_ONE_OVER_SOUL_SAND_COST;
|
||||||
}
|
}
|
||||||
return walk + Math.max(FALL_N_BLOCKS_COST[1], CENTER_AFTER_FALL_COST) + getTotalHardnessOfBlocksToBreak(context);
|
totalCost += walk + Math.max(FALL_N_BLOCKS_COST[1], CENTER_AFTER_FALL_COST);
|
||||||
|
return new MoveResult(destX, y - 1, destZ, totalCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MoveResult dynamicFallCost(CalculationContext context, int x, int y, int z, int destX, int destZ, double frontBreak, IBlockState below) {
|
||||||
|
if (frontBreak != 0 && BlockStateInterface.get(destX, y + 2, destZ).getBlock() instanceof BlockFalling) {
|
||||||
|
// if frontBreak is 0 we can actually get through this without updating the falling block and making it actually fall
|
||||||
|
// but if frontBreak is nonzero, we're breaking blocks in front, so don't let anything fall through this column,
|
||||||
|
// and potentially replace the water we're going to fall into
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
if (!MovementHelper.canWalkThrough(destX, y - 2, destZ, below) && below.getBlock() != Blocks.WATER) {
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
for (int fallHeight = 3; true; fallHeight++) {
|
||||||
|
int newY = y - fallHeight;
|
||||||
|
if (newY < 0) {
|
||||||
|
// when pathing in the end, where you could plausibly fall into the void
|
||||||
|
// this check prevents it from getting the block at y=-1 and crashing
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
IBlockState ontoBlock = BlockStateInterface.get(destX, newY, destZ);
|
||||||
|
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak;
|
||||||
|
if (ontoBlock.getBlock() == Blocks.WATER && !BlockStateInterface.isFlowing(ontoBlock)) { // TODO flowing check required here?
|
||||||
|
if (Baritone.settings().assumeWalkOnWater.get()) {
|
||||||
|
return IMPOSSIBLE; // TODO fix
|
||||||
|
}
|
||||||
|
// found a fall into water
|
||||||
|
return new MoveResult(destX, newY, destZ, tentativeCost); // TODO incorporate water swim up cost?
|
||||||
|
}
|
||||||
|
if (ontoBlock.getBlock() == Blocks.FLOWING_WATER) {
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
if (MovementHelper.canWalkThrough(destX, newY, destZ, ontoBlock)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!MovementHelper.canWalkOn(destX, newY, destZ, ontoBlock)) {
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
||||||
|
return IMPOSSIBLE; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
||||||
|
}
|
||||||
|
if (context.hasWaterBucket() && fallHeight <= context.maxFallHeightBucket() + 1) {
|
||||||
|
return new MoveResult(destX, newY + 1, destZ, tentativeCost + context.placeBlockCost()); // this is the block we're falling onto, so dest is +1
|
||||||
|
}
|
||||||
|
if (fallHeight <= context.maxFallHeightNoWater() + 1) {
|
||||||
|
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
||||||
|
return new MoveResult(destX, newY + 1, destZ, tentativeCost);
|
||||||
|
} else {
|
||||||
|
return IMPOSSIBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import baritone.utils.BlockStateInterface;
|
|||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockMagma;
|
|
||||||
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.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
@@ -53,40 +52,44 @@ public class MovementDiagonal extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
Block fromDown = BlockStateInterface.get(src.down()).getBlock();
|
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
|
Block fromDown = BlockStateInterface.get(x, y - 1, z).getBlock();
|
||||||
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkThrough(positionsToBreak[4]) || !MovementHelper.canWalkThrough(positionsToBreak[5])) {
|
IBlockState destInto = BlockStateInterface.get(destX, y, destZ);
|
||||||
|
if (!MovementHelper.canWalkThrough(destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(destX, y + 1, destZ)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
BetterBlockPos destDown = dest.down();
|
IBlockState destWalkOn = BlockStateInterface.get(destX, y - 1, destZ);
|
||||||
IBlockState destWalkOn = BlockStateInterface.get(destDown);
|
if (!MovementHelper.canWalkOn(destX, y - 1, destZ, destWalkOn)) {
|
||||||
if (!MovementHelper.canWalkOn(destDown, destWalkOn)) {
|
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double multiplier = WALK_ONE_BLOCK_COST;
|
double multiplier = WALK_ONE_BLOCK_COST;
|
||||||
// For either possible soul sand, that affects half of our walking
|
// For either possible soul sand, that affects half of our walking
|
||||||
if (destWalkOn.getBlock().equals(Blocks.SOUL_SAND)) {
|
if (destWalkOn.getBlock() == Blocks.SOUL_SAND) {
|
||||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
if (fromDown == Blocks.SOUL_SAND) {
|
if (fromDown == Blocks.SOUL_SAND) {
|
||||||
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(positionsToBreak[2].down()).getBlock();
|
Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock();
|
||||||
if (cuttingOver1 instanceof BlockMagma || BlockStateInterface.isLava(cuttingOver1)) {
|
if (cuttingOver1 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver1)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
Block cuttingOver2 = BlockStateInterface.get(positionsToBreak[4].down()).getBlock();
|
Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock();
|
||||||
if (cuttingOver2 instanceof BlockMagma || BlockStateInterface.isLava(cuttingOver2)) {
|
if (cuttingOver2 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver2)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState pb0 = BlockStateInterface.get(positionsToBreak[0]);
|
IBlockState pb0 = BlockStateInterface.get(x, y, destZ);
|
||||||
IBlockState pb1 = BlockStateInterface.get(positionsToBreak[1]);
|
IBlockState pb1 = BlockStateInterface.get(x, y + 1, destZ);
|
||||||
IBlockState pb2 = BlockStateInterface.get(positionsToBreak[2]);
|
IBlockState pb2 = BlockStateInterface.get(destX, y, z);
|
||||||
IBlockState pb3 = BlockStateInterface.get(positionsToBreak[3]);
|
IBlockState pb3 = BlockStateInterface.get(destX, y + 1, z);
|
||||||
double optionA = MovementHelper.getMiningDurationTicks(context, positionsToBreak[0], pb0, false) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[1], pb1, true);
|
double optionA = MovementHelper.getMiningDurationTicks(context, x, y, destZ, pb0, false) + MovementHelper.getMiningDurationTicks(context, x, y + 1, destZ, pb1, true);
|
||||||
double optionB = MovementHelper.getMiningDurationTicks(context, positionsToBreak[2], pb2, false) + MovementHelper.getMiningDurationTicks(context, positionsToBreak[3], pb3, true);
|
double optionB = MovementHelper.getMiningDurationTicks(context, destX, y, z, pb2, false) + MovementHelper.getMiningDurationTicks(context, destX, y + 1, z, pb3, true);
|
||||||
if (optionA != 0 && optionB != 0) {
|
if (optionA != 0 && optionB != 0) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
@@ -100,7 +103,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (BlockStateInterface.isWater(src) || BlockStateInterface.isWater(dest)) {
|
if (BlockStateInterface.isWater(BlockStateInterface.getBlock(x, y, z)) || BlockStateInterface.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
|
||||||
|
|||||||
@@ -43,17 +43,21 @@ public class MovementDownward extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
if (!MovementHelper.canWalkOn(dest.down())) {
|
return cost(context, src.x, src.y, src.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double cost(CalculationContext context, int x, int y, int z) {
|
||||||
|
if (!MovementHelper.canWalkOn(x, y - 2, z)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState d = BlockStateInterface.get(dest);
|
IBlockState d = BlockStateInterface.get(x, y - 1, z);
|
||||||
Block td = d.getBlock();
|
Block td = d.getBlock();
|
||||||
boolean ladder = td == Blocks.LADDER || td == Blocks.VINE;
|
boolean ladder = td == Blocks.LADDER || td == Blocks.VINE;
|
||||||
if (ladder) {
|
if (ladder) {
|
||||||
return LADDER_DOWN_ONE_COST;
|
return LADDER_DOWN_ONE_COST;
|
||||||
} else {
|
} else {
|
||||||
// we're standing on it, while it might be block falling, it'll be air by the time we get here in the movement
|
// we're standing on it, while it might be block falling, it'll be air by the time we get here in the movement
|
||||||
return FALL_N_BLOCKS_COST[1] + MovementHelper.getMiningDurationTicks(context, dest, d, false);
|
return FALL_N_BLOCKS_COST[1] + MovementHelper.getMiningDurationTicks(context, x, y - 1, z, d, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,19 +18,20 @@
|
|||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
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.MovementStatus;
|
import baritone.pathing.movement.MovementState.MovementStatus;
|
||||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||||
import baritone.utils.*;
|
import baritone.utils.BlockStateInterface;
|
||||||
|
import baritone.utils.InputOverrideHandler;
|
||||||
|
import baritone.utils.RayTraceUtils;
|
||||||
|
import baritone.utils.Utils;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.Block;
|
import baritone.utils.pathing.MoveResult;
|
||||||
import net.minecraft.block.BlockFalling;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.init.Blocks;
|
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -48,58 +49,11 @@ public class MovementFall extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
Block fromDown = BlockStateInterface.get(src.down()).getBlock();
|
MoveResult result = MovementDescend.cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||||
if (fromDown == Blocks.LADDER || fromDown == Blocks.VINE) {
|
if (result.destY != dest.y) {
|
||||||
return COST_INF;
|
return COST_INF; // doesn't apply to us, this position is a descend not a fall
|
||||||
}
|
}
|
||||||
IBlockState fallOnto = BlockStateInterface.get(dest.down());
|
return result.cost;
|
||||||
if (!MovementHelper.canWalkOn(dest.down(), fallOnto)) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
if (MovementHelper.isBottomSlab(fallOnto)) {
|
|
||||||
return COST_INF; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
|
||||||
}
|
|
||||||
double placeBucketCost = 0.0;
|
|
||||||
boolean destIsWater = BlockStateInterface.isWater(dest);
|
|
||||||
if (!destIsWater && src.getY() - dest.getY() > context.maxFallHeightNoWater()) {
|
|
||||||
if (!context.hasWaterBucket()) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
if (src.getY() - dest.getY() > context.maxFallHeightBucket()) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
placeBucketCost = context.placeBlockCost();
|
|
||||||
}
|
|
||||||
double frontThree = 0;
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
frontThree += MovementHelper.getMiningDurationTicks(context, positionsToBreak[i], false);
|
|
||||||
// don't include falling because we will check falling right after this, and if it's there it's COST_INF
|
|
||||||
if (frontThree >= COST_INF) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (BlockStateInterface.get(positionsToBreak[0].up()).getBlock() instanceof BlockFalling) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
for (int i = 3; i < positionsToBreak.length; i++) {
|
|
||||||
// TODO is this the right check here?
|
|
||||||
// MiningDurationTicks is all right, but shouldn't it be canWalkThrough instead?
|
|
||||||
// Lilypads (i think?) are 0 ticks to mine, but they definitely cause fall damage
|
|
||||||
// Same thing for falling through water... we can't actually do that
|
|
||||||
// And falling through signs is possible, but they do have a mining duration, right?
|
|
||||||
if (MovementHelper.getMiningDurationTicks(context, positionsToBreak[i], false) > 0) {
|
|
||||||
//can't break while falling
|
|
||||||
|
|
||||||
if (i != positionsToBreak.length - 1 || !destIsWater) {
|
|
||||||
// if we're checking the very last block to mine
|
|
||||||
// and it's water (so this is a water fall)
|
|
||||||
// don't consider the cost of "mining" it
|
|
||||||
// (if assumeWalkOnWater is true, water isn't canWalkThrough)
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[positionsToBreak.length - 1] + placeBucketCost + frontThree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import baritone.utils.BlockStateInterface;
|
|||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.Utils;
|
import baritone.utils.Utils;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.Block;
|
import baritone.utils.pathing.MoveResult;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
@@ -37,8 +37,10 @@ import net.minecraft.util.math.Vec3d;
|
|||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static baritone.utils.pathing.MoveResult.IMPOSSIBLE;
|
||||||
|
|
||||||
public class MovementParkour extends Movement {
|
public class MovementParkour extends Movement {
|
||||||
private static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN_SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
|
private static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
|
||||||
private static final BetterBlockPos[] EMPTY = new BetterBlockPos[]{};
|
private static final BetterBlockPos[] EMPTY = new BetterBlockPos[]{};
|
||||||
|
|
||||||
private final EnumFacing direction;
|
private final EnumFacing direction;
|
||||||
@@ -48,79 +50,81 @@ public class MovementParkour extends Movement {
|
|||||||
super(src, src.offset(dir, dist), EMPTY);
|
super(src, src.offset(dir, dist), EMPTY);
|
||||||
this.direction = dir;
|
this.direction = dir;
|
||||||
this.dist = dist;
|
this.dist = dist;
|
||||||
super.override(costFromJumpDistance(dist));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MovementParkour generate(BetterBlockPos src, EnumFacing dir, CalculationContext context) {
|
public static MovementParkour cost(CalculationContext context, BetterBlockPos src, EnumFacing direction) {
|
||||||
// MUST BE KEPT IN SYNC WITH calculateCost
|
MoveResult res = cost(context, src.x, src.y, src.z, direction);
|
||||||
|
int dist = Math.abs(res.destX - src.x) + Math.abs(res.destZ - src.z);
|
||||||
|
return new MovementParkour(src, dist, direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MoveResult cost(CalculationContext context, int x, int y, int z, EnumFacing dir) {
|
||||||
if (!Baritone.settings().allowParkour.get()) {
|
if (!Baritone.settings().allowParkour.get()) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
IBlockState standingOn = BlockStateInterface.get(src.down());
|
IBlockState standingOn = BlockStateInterface.get(x, y - 1, z);
|
||||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || MovementHelper.isBottomSlab(standingOn)) {
|
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || MovementHelper.isBottomSlab(standingOn)) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
BetterBlockPos adjBlock = src.down().offset(dir);
|
int xDiff = dir.getXOffset();
|
||||||
IBlockState adj = BlockStateInterface.get(adjBlock);
|
int zDiff = dir.getZOffset();
|
||||||
|
IBlockState adj = BlockStateInterface.get(x + xDiff, y - 1, z + zDiff);
|
||||||
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
|
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkOn(adjBlock, adj)) { // don't parkour if we could just traverse (for now)
|
if (MovementHelper.canWalkOn(x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MovementHelper.fullyPassable(src.offset(dir))) {
|
if (!MovementHelper.fullyPassable(x + xDiff, y, z + zDiff)) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(src.up().offset(dir))) {
|
if (!MovementHelper.fullyPassable(x + xDiff, y + 1, z + zDiff)) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(src.up(2).offset(dir))) {
|
if (!MovementHelper.fullyPassable(x + xDiff, y + 2, z + zDiff)) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(src.up(2))) {
|
if (!MovementHelper.fullyPassable(x, y + 2, z)) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
for (int i = 2; i <= (context.canSprint() ? 4 : 3); i++) {
|
for (int i = 2; i <= (context.canSprint() ? 4 : 3); i++) {
|
||||||
BetterBlockPos dest = src.offset(dir, i);
|
|
||||||
// TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly?
|
// TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly?
|
||||||
for (int y = 0; y < 4; y++) {
|
for (int y2 = 0; y2 < 4; y2++) {
|
||||||
if (!MovementHelper.fullyPassable(dest.up(y))) {
|
if (!MovementHelper.fullyPassable(x + xDiff * i, y + y2, z + zDiff * i)) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkOn(dest.down())) {
|
if (MovementHelper.canWalkOn(x + xDiff * i, y - 1, z + zDiff * i)) {
|
||||||
return new MovementParkour(src, i, dir);
|
return new MoveResult(x + xDiff * i, y, z + zDiff * i, costFromJumpDistance(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!context.canSprint()) {
|
if (!context.canSprint()) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
if (!Baritone.settings().allowParkourPlace.get()) {
|
if (!Baritone.settings().allowParkourPlace.get()) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
BlockPos dest = src.offset(dir, 4);
|
int destX = x + 4 * xDiff;
|
||||||
BlockPos positionToPlace = dest.down();
|
int destZ = z + 4 * zDiff;
|
||||||
IBlockState toPlace = BlockStateInterface.get(positionToPlace);
|
IBlockState toPlace = BlockStateInterface.get(destX, y - 1, destZ);
|
||||||
if (!context.hasThrowaway()) {
|
if (!context.hasThrowaway()) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionToPlace, toPlace)) {
|
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
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]);
|
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
||||||
if (against1.up().equals(src.offset(dir, 3))) { // we can't turn around that fast
|
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
|
||||||
|
if (againstX == x + xDiff * 3 && againstZ == z + zDiff * 3) { // we can't turn around that fast
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(against1)) {
|
if (MovementHelper.canPlaceAgainst(againstX, y - 1, againstZ)) {
|
||||||
// holy jesus we gonna do it
|
return new MoveResult(destX, y, destZ, costFromJumpDistance(i) + context.placeBlockCost());
|
||||||
MovementParkour ret = new MovementParkour(src, 4, dir);
|
|
||||||
ret.override(costFromJumpDistance(4) + context.placeBlockCost());
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return IMPOSSIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double costFromJumpDistance(int dist) {
|
private static double costFromJumpDistance(int dist) {
|
||||||
@@ -139,54 +143,11 @@ public class MovementParkour extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
// MUST BE KEPT IN SYNC WITH generate
|
MoveResult res = cost(context, src.x, src.y, src.z, direction);
|
||||||
if (!context.canSprint() && dist >= 4) {
|
if (res.destX != dest.x || res.destZ != dest.z) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
boolean placing = false;
|
return res.cost;
|
||||||
if (!MovementHelper.canWalkOn(dest.down())) {
|
|
||||||
if (dist != 4) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
if (!Baritone.settings().allowParkourPlace.get()) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
BlockPos positionToPlace = dest.down();
|
|
||||||
IBlockState toPlace = BlockStateInterface.get(positionToPlace);
|
|
||||||
if (!context.hasThrowaway()) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionToPlace, toPlace)) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN_SO_EVERY_DIRECTION_EXCEPT_UP[i]);
|
|
||||||
if (against1.up().equals(src.offset(direction, 3))) { // we can't turn around that fast
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (MovementHelper.canPlaceAgainst(against1)) {
|
|
||||||
// holy jesus we gonna do it
|
|
||||||
placing = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Block walkOff = BlockStateInterface.get(src.down().offset(direction)).getBlock();
|
|
||||||
if (MovementHelper.avoidWalkingInto(walkOff) && walkOff != Blocks.WATER && walkOff != Blocks.FLOWING_WATER) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
for (int i = 1; i <= 4; i++) {
|
|
||||||
BlockPos d = src.offset(direction, i);
|
|
||||||
for (int y = 0; y < (i == 1 ? 3 : 4); y++) {
|
|
||||||
if (!MovementHelper.fullyPassable(d.up(y))) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (d.equals(dest)) {
|
|
||||||
return costFromJumpDistance(i) + (placing ? context.placeBlockCost() : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("invalid jump distance?");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -209,7 +170,7 @@ public class MovementParkour extends Movement {
|
|||||||
if (!MovementHelper.canWalkOn(dest.down())) {
|
if (!MovementHelper.canWalkOn(dest.down())) {
|
||||||
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]);
|
||||||
if (against1.up().equals(src.offset(direction, 3))) { // we can't turn around that fast
|
if (against1.up().equals(src.offset(direction, 3))) { // we can't turn around that fast
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,13 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
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.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.Rotation;
|
|
||||||
import baritone.utils.Utils;
|
import baritone.utils.Utils;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
@@ -48,9 +48,13 @@ public class MovementPillar extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
Block fromDown = BlockStateInterface.get(src).getBlock();
|
return cost(context, src.x, src.y, src.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double cost(CalculationContext context, int x, int y, int z) {
|
||||||
|
Block fromDown = BlockStateInterface.get(x, y, z).getBlock();
|
||||||
boolean ladder = fromDown instanceof BlockLadder || fromDown instanceof BlockVine;
|
boolean ladder = fromDown instanceof BlockLadder || fromDown instanceof BlockVine;
|
||||||
IBlockState fromDownDown = BlockStateInterface.get(src.down());
|
IBlockState fromDownDown = BlockStateInterface.get(x, y - 1, z);
|
||||||
if (!ladder) {
|
if (!ladder) {
|
||||||
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
|
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
@@ -61,28 +65,27 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!context.hasThrowaway() && !ladder) {
|
|
||||||
return COST_INF;
|
|
||||||
}
|
|
||||||
if (fromDown instanceof BlockVine) {
|
if (fromDown instanceof BlockVine) {
|
||||||
if (getAgainst(src) == null) {
|
if (!hasAgainst(x, y, z)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BlockPos toBreakPos = src.up(2);
|
IBlockState toBreak = BlockStateInterface.get(x, y + 2, z);
|
||||||
IBlockState toBreak = BlockStateInterface.get(toBreakPos);
|
|
||||||
Block toBreakBlock = toBreak.getBlock();
|
Block toBreakBlock = toBreak.getBlock();
|
||||||
if (toBreakBlock instanceof BlockFenceGate) {
|
if (toBreakBlock instanceof BlockFenceGate) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
Block srcUp = null;
|
Block srcUp = null;
|
||||||
if (BlockStateInterface.isWater(toBreakBlock) && BlockStateInterface.isWater(fromDown)) {
|
if (BlockStateInterface.isWater(toBreakBlock) && BlockStateInterface.isWater(fromDown)) {
|
||||||
srcUp = BlockStateInterface.get(dest).getBlock();
|
srcUp = BlockStateInterface.get(x, y + 1, z).getBlock();
|
||||||
if (BlockStateInterface.isWater(srcUp)) {
|
if (BlockStateInterface.isWater(srcUp)) {
|
||||||
return LADDER_UP_ONE_COST;
|
return LADDER_UP_ONE_COST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double hardness = MovementHelper.getMiningDurationTicks(context, toBreakPos, toBreak, true);
|
if (!context.hasThrowaway() && !ladder) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
double hardness = MovementHelper.getMiningDurationTicks(context, x, y + 2, z, toBreak, true);
|
||||||
if (hardness >= COST_INF) {
|
if (hardness >= COST_INF) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
@@ -90,12 +93,11 @@ public class MovementPillar extends Movement {
|
|||||||
if (toBreakBlock instanceof BlockLadder || toBreakBlock instanceof BlockVine) {
|
if (toBreakBlock instanceof BlockLadder || toBreakBlock instanceof BlockVine) {
|
||||||
hardness = 0; // we won't actually need to break the ladder / vine because we're going to use it
|
hardness = 0; // we won't actually need to break the ladder / vine because we're going to use it
|
||||||
} else {
|
} else {
|
||||||
BlockPos chkPos = src.up(3);
|
IBlockState check = BlockStateInterface.get(x, y + 3, z);
|
||||||
IBlockState check = BlockStateInterface.get(chkPos);
|
|
||||||
if (check.getBlock() instanceof BlockFalling) {
|
if (check.getBlock() instanceof BlockFalling) {
|
||||||
// see MovementAscend's identical check for breaking a falling block above our head
|
// see MovementAscend's identical check for breaking a falling block above our head
|
||||||
if (srcUp == null) {
|
if (srcUp == null) {
|
||||||
srcUp = BlockStateInterface.get(dest).getBlock();
|
srcUp = BlockStateInterface.get(x, y + 1, z).getBlock();
|
||||||
}
|
}
|
||||||
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp instanceof BlockFalling)) {
|
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp instanceof BlockFalling)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
@@ -120,6 +122,13 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasAgainst(int x, int y, int z) {
|
||||||
|
return BlockStateInterface.get(x + 1, y, z).isBlockNormalCube() ||
|
||||||
|
BlockStateInterface.get(x - 1, y, z).isBlockNormalCube() ||
|
||||||
|
BlockStateInterface.get(x, y, z + 1).isBlockNormalCube() ||
|
||||||
|
BlockStateInterface.get(x, y, z - 1).isBlockNormalCube();
|
||||||
|
}
|
||||||
|
|
||||||
public static BlockPos getAgainst(BlockPos vine) {
|
public static BlockPos getAgainst(BlockPos vine) {
|
||||||
if (BlockStateInterface.get(vine.north()).isBlockNormalCube()) {
|
if (BlockStateInterface.get(vine.north()).isBlockNormalCube()) {
|
||||||
return vine.north();
|
return vine.north();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.behavior.LookBehaviorUtils;
|
import baritone.behavior.LookBehaviorUtils;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
@@ -25,7 +26,6 @@ import baritone.pathing.movement.MovementHelper;
|
|||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
import baritone.utils.Rotation;
|
|
||||||
import baritone.utils.Utils;
|
import baritone.utils.Utils;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
@@ -57,11 +57,15 @@ public class MovementTraverse extends Movement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double calculateCost(CalculationContext context) {
|
protected double calculateCost(CalculationContext context) {
|
||||||
IBlockState pb0 = BlockStateInterface.get(positionsToBreak[0]);
|
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||||
IBlockState pb1 = BlockStateInterface.get(positionsToBreak[1]);
|
}
|
||||||
IBlockState destOn = BlockStateInterface.get(positionToPlace);
|
|
||||||
Block srcDown = BlockStateInterface.getBlock(src.down());
|
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
if (MovementHelper.canWalkOn(positionToPlace, destOn)) {//this is a walk, not a bridge
|
IBlockState pb0 = BlockStateInterface.get(destX, y + 1, destZ);
|
||||||
|
IBlockState pb1 = BlockStateInterface.get(destX, y, destZ);
|
||||||
|
IBlockState destOn = BlockStateInterface.get(destX, y - 1, destZ);
|
||||||
|
Block srcDown = BlockStateInterface.getBlock(x, y - 1, z);
|
||||||
|
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;
|
||||||
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
|
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
|
||||||
WC = WALK_ONE_IN_WATER_COST;
|
WC = WALK_ONE_IN_WATER_COST;
|
||||||
@@ -73,11 +77,11 @@ public class MovementTraverse extends Movement {
|
|||||||
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
WC += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double hardness1 = MovementHelper.getMiningDurationTicks(context, positionsToBreak[0], pb0, true);
|
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true);
|
||||||
if (hardness1 >= COST_INF) {
|
if (hardness1 >= COST_INF) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double hardness2 = MovementHelper.getMiningDurationTicks(context, positionsToBreak[1], pb1, false);
|
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb1, false);
|
||||||
if (hardness1 == 0 && hardness2 == 0) {
|
if (hardness1 == 0 && hardness2 == 0) {
|
||||||
if (WC == WALK_ONE_BLOCK_COST && context.canSprint()) {
|
if (WC == WALK_ONE_BLOCK_COST && context.canSprint()) {
|
||||||
// If there's nothing in the way, and this isn't water or soul sand, and we aren't sneak placing
|
// If there's nothing in the way, and this isn't water or soul sand, and we aren't sneak placing
|
||||||
@@ -95,7 +99,7 @@ public class MovementTraverse extends Movement {
|
|||||||
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
|
if (srcDown == Blocks.LADDER || srcDown == Blocks.VINE) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(positionToPlace, 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 = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock());
|
||||||
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
|
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
@@ -103,15 +107,21 @@ public class MovementTraverse extends Movement {
|
|||||||
if (!context.hasThrowaway()) {
|
if (!context.hasThrowaway()) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
|
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb0, false);
|
||||||
|
if (hardness1 >= COST_INF) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb1, true);
|
||||||
|
|
||||||
double WC = throughWater ? WALK_ONE_IN_WATER_COST : WALK_ONE_BLOCK_COST;
|
double WC = throughWater ? WALK_ONE_IN_WATER_COST : WALK_ONE_BLOCK_COST;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
BlockPos against1 = dest.offset(HORIZONTALS[i]);
|
int againstX = destX + HORIZONTALS[i].getXOffset();
|
||||||
if (against1.equals(src)) {
|
int againstZ = destZ + HORIZONTALS[i].getZOffset();
|
||||||
|
if (againstX == x && againstZ == z) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
against1 = against1.down();
|
if (MovementHelper.canPlaceAgainst(againstX, y - 1, againstZ)) {
|
||||||
if (MovementHelper.canPlaceAgainst(against1)) {
|
return WC + context.placeBlockCost() + hardness1 + hardness2;
|
||||||
return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) {
|
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) {
|
||||||
@@ -121,7 +131,7 @@ public class MovementTraverse extends Movement {
|
|||||||
return COST_INF; // this is obviously impossible
|
return COST_INF; // this is obviously impossible
|
||||||
}
|
}
|
||||||
WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST;//since we are placing, we are sneaking
|
WC = WC * SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST;//since we are placing, we are sneaking
|
||||||
return WC + context.placeBlockCost() + getTotalHardnessOfBlocksToBreak(context);
|
return WC + context.placeBlockCost() + hardness1 + hardness2;
|
||||||
}
|
}
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
// Out.log("Can't walk on " + Baritone.get(positionsToPlace[0]).getBlock());
|
// Out.log("Can't walk on " + Baritone.get(positionsToPlace[0]).getBlock());
|
||||||
@@ -155,8 +165,8 @@ public class MovementTraverse extends Movement {
|
|||||||
|
|
||||||
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
|
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
|
||||||
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
|
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
|
||||||
float yawToDest = Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(dest, world())).getFirst();
|
float yawToDest = Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(dest, world())).getYaw();
|
||||||
float pitchToBreak = state.getTarget().getRotation().get().getSecond();
|
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
|
||||||
|
|
||||||
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
|
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
|
||||||
return state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
return state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
package baritone.pathing.path;
|
package baritone.pathing.path;
|
||||||
|
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
package baritone.pathing.path;
|
package baritone.pathing.path;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.Utils;
|
import baritone.utils.Utils;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package baritone.pathing.path;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
import baritone.pathing.movement.*;
|
import baritone.pathing.movement.*;
|
||||||
import baritone.pathing.movement.movements.*;
|
import baritone.pathing.movement.movements.*;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
@@ -94,6 +95,7 @@ public class PathExecutor implements Helper {
|
|||||||
|
|
||||||
if (pathPosition == 0 && whereAmI.equals(whereShouldIBe.up()) && Math.abs(player().motionY) < 0.1 && !(path.movements().get(0) instanceof MovementAscend) && !(path.movements().get(0) instanceof MovementPillar)) {
|
if (pathPosition == 0 && whereAmI.equals(whereShouldIBe.up()) && Math.abs(player().motionY) < 0.1 && !(path.movements().get(0) instanceof MovementAscend) && !(path.movements().get(0) instanceof MovementPillar)) {
|
||||||
// avoid the Wrong Y coordinate bug
|
// avoid the Wrong Y coordinate bug
|
||||||
|
// TODO add a timer here
|
||||||
new MovementDownward(whereAmI, whereShouldIBe).update();
|
new MovementDownward(whereAmI, whereShouldIBe).update();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils;
|
||||||
|
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.goals.GoalBlock;
|
||||||
|
import baritone.behavior.PathingBehavior;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiMainMenu;
|
||||||
|
import net.minecraft.client.settings.GameSettings;
|
||||||
|
import net.minecraft.client.tutorial.TutorialSteps;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.GameType;
|
||||||
|
import net.minecraft.world.WorldSettings;
|
||||||
|
import net.minecraft.world.WorldType;
|
||||||
|
|
||||||
|
public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
||||||
|
|
||||||
|
public static final BaritoneAutoTest INSTANCE = new BaritoneAutoTest();
|
||||||
|
|
||||||
|
private BaritoneAutoTest() {}
|
||||||
|
|
||||||
|
public static final boolean ENABLE_AUTO_TEST = true;
|
||||||
|
private static final long TEST_SEED = -928872506371745L;
|
||||||
|
private static final BlockPos STARTING_POSITION = new BlockPos(0, 65, 0);
|
||||||
|
private static final Goal GOAL = new GoalBlock(69, 121, 420);
|
||||||
|
private static final int MAX_TICKS = 3500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called right after the {@link GameSettings} object is created in the {@link Minecraft} instance.
|
||||||
|
*/
|
||||||
|
public void onPreInit() {
|
||||||
|
System.out.println("Optimizing Game Settings");
|
||||||
|
|
||||||
|
GameSettings s = mc.gameSettings;
|
||||||
|
s.limitFramerate = 20;
|
||||||
|
s.mipmapLevels = 0;
|
||||||
|
s.particleSetting = 2;
|
||||||
|
s.overrideWidth = 128;
|
||||||
|
s.overrideHeight = 128;
|
||||||
|
s.heldItemTooltips = false;
|
||||||
|
s.entityShadows = false;
|
||||||
|
s.chatScale = 0.0F;
|
||||||
|
s.ambientOcclusion = 0;
|
||||||
|
s.clouds = 0;
|
||||||
|
s.fancyGraphics = false;
|
||||||
|
s.tutorialStep = TutorialSteps.NONE;
|
||||||
|
s.hideGUI = true;
|
||||||
|
s.fovSetting = 30.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTick(TickEvent event) {
|
||||||
|
|
||||||
|
// If we're on the main menu then create the test world and launch the integrated server
|
||||||
|
if (mc.currentScreen instanceof GuiMainMenu) {
|
||||||
|
System.out.println("Beginning Baritone automatic test routine");
|
||||||
|
mc.displayGuiScreen(null);
|
||||||
|
WorldSettings worldsettings = new WorldSettings(TEST_SEED, GameType.getByName("survival"), true, false, WorldType.DEFAULT);
|
||||||
|
mc.launchIntegratedServer("BaritoneAutoTest", "BaritoneAutoTest", worldsettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the integrated server is launched and the world has initialized, set the spawn point
|
||||||
|
// to our defined starting position
|
||||||
|
if (mc.getIntegratedServer() != null && mc.getIntegratedServer().worlds[0] != null) {
|
||||||
|
mc.getIntegratedServer().worlds[0].setSpawnPoint(STARTING_POSITION);
|
||||||
|
mc.getIntegratedServer().worlds[0].getGameRules().setOrCreateGameRule("spawnRadius", "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getType() == TickEvent.Type.IN) { // If we're in-game
|
||||||
|
|
||||||
|
// Force the integrated server to share the world to LAN so that
|
||||||
|
// the ingame pause menu gui doesn't actually pause our game
|
||||||
|
if (mc.isSingleplayer() && !mc.getIntegratedServer().getPublic()) {
|
||||||
|
mc.getIntegratedServer().shareToLAN(GameType.getByName("survival"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the first 200 ticks, wait for the world to generate
|
||||||
|
if (event.getCount() < 200) {
|
||||||
|
System.out.println("Waiting for world to generate... " + event.getCount());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print out an update of our position every 5 seconds
|
||||||
|
if (event.getCount() % 100 == 0) {
|
||||||
|
System.out.println(playerFeet() + " " + event.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Baritone's pathing goal and (if needed) begin pathing
|
||||||
|
PathingBehavior.INSTANCE.setGoal(GOAL);
|
||||||
|
PathingBehavior.INSTANCE.path();
|
||||||
|
|
||||||
|
// If we have reached our goal, print a message and safely close the game
|
||||||
|
if (GOAL.isInGoal(playerFeet())) {
|
||||||
|
System.out.println("Successfully pathed to " + playerFeet() + " in " + event.getCount() + " ticks");
|
||||||
|
mc.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have exceeded the expected number of ticks to complete the pathing
|
||||||
|
// task, then throw an IllegalStateException to cause the build to fail
|
||||||
|
if (event.getCount() > MAX_TICKS) {
|
||||||
|
throw new IllegalStateException("took too long");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,7 +46,9 @@ public final class BlockBreakHelper implements Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void stopBreakingBlock() {
|
public static void stopBreakingBlock() {
|
||||||
mc.playerController.resetBlockRemoving();
|
if (mc.playerController != null) {
|
||||||
|
mc.playerController.resetBlockRemoving();
|
||||||
|
}
|
||||||
lastBlock = null;
|
lastBlock = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ public class BlockStateInterface implements Helper {
|
|||||||
// if it's the same chunk as last time
|
// if it's the same chunk as last time
|
||||||
// we can just skip the mc.world.getChunk lookup
|
// we can just skip the mc.world.getChunk lookup
|
||||||
// which is a Long2ObjectOpenHashMap.get
|
// which is a Long2ObjectOpenHashMap.get
|
||||||
|
// see issue #113
|
||||||
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
|
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
|
||||||
numTimesChunkSucceeded++;
|
numTimesChunkSucceeded++;
|
||||||
return cached.getBlockState(x, y, z);
|
return cached.getBlockState(x, y, z);
|
||||||
@@ -92,6 +93,32 @@ public class BlockStateInterface implements Helper {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isLoaded(int x, int z) {
|
||||||
|
Chunk prevChunk = prev;
|
||||||
|
if (prevChunk != null && prevChunk.x == x >> 4 && prevChunk.z == z >> 4) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
prevChunk = mc.world.getChunk(x >> 4, z >> 4);
|
||||||
|
if (prevChunk.isLoaded()) {
|
||||||
|
prev = prevChunk;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
CachedRegion prevRegion = prevCached;
|
||||||
|
if (prevRegion != null && prevRegion.getX() == x >> 9 && prevRegion.getZ() == z >> 9) {
|
||||||
|
return prevRegion.isCached(x & 511, z & 511);
|
||||||
|
}
|
||||||
|
WorldData world = WorldProvider.INSTANCE.getCurrentWorld();
|
||||||
|
if (world == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
prevRegion = world.cache.getRegion(x >> 9, z >> 9);
|
||||||
|
if (prevRegion == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
prevCached = prevRegion;
|
||||||
|
return prevRegion.isCached(x & 511, z & 511);
|
||||||
|
}
|
||||||
|
|
||||||
public static void clearCachedChunk() {
|
public static void clearCachedChunk() {
|
||||||
prev = null;
|
prev = null;
|
||||||
prevCached = null;
|
prevCached = null;
|
||||||
@@ -101,6 +128,9 @@ public class BlockStateInterface implements Helper {
|
|||||||
return get(pos).getBlock();
|
return get(pos).getBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Block getBlock(int x, int y, int z) {
|
||||||
|
return get(x, y, z).getBlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not the specified block is
|
* Returns whether or not the specified block is
|
||||||
|
|||||||
@@ -18,23 +18,20 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.Settings;
|
import baritone.api.Settings;
|
||||||
import baritone.api.behavior.Behavior;
|
import baritone.api.cache.IWaypoint;
|
||||||
import baritone.api.event.events.ChatEvent;
|
import baritone.api.event.events.ChatEvent;
|
||||||
|
import baritone.api.pathing.goals.*;
|
||||||
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
|
import baritone.behavior.Behavior;
|
||||||
import baritone.behavior.FollowBehavior;
|
import baritone.behavior.FollowBehavior;
|
||||||
import baritone.behavior.MineBehavior;
|
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;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.pathing.calc.AStarPathFinder;
|
|
||||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.goals.*;
|
import baritone.pathing.movement.*;
|
||||||
import baritone.pathing.movement.ActionCosts;
|
|
||||||
import baritone.pathing.movement.CalculationContext;
|
|
||||||
import baritone.pathing.movement.Movement;
|
|
||||||
import baritone.pathing.movement.MovementHelper;
|
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@@ -43,6 +40,8 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class ExampleBaritoneControl extends Behavior implements Helper {
|
public class ExampleBaritoneControl extends Behavior implements Helper {
|
||||||
|
|
||||||
@@ -185,7 +184,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
Chunk chunk = cli.getLoadedChunk(x, z);
|
Chunk chunk = cli.getLoadedChunk(x, z);
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
count++;
|
count++;
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().cache.queueForPacking(chunk);
|
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().queueForPacking(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,7 +207,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("forcecancel")) {
|
if (msg.equals("forcecancel")) {
|
||||||
|
MineBehavior.INSTANCE.cancel();
|
||||||
|
FollowBehavior.INSTANCE.cancel();
|
||||||
|
PathingBehavior.INSTANCE.cancel();
|
||||||
AbstractNodeCostSearch.forceCancel();
|
AbstractNodeCostSearch.forceCancel();
|
||||||
|
PathingBehavior.INSTANCE.forceCancel();
|
||||||
event.cancel();
|
event.cancel();
|
||||||
logDirect("ok force canceled");
|
logDirect("ok force canceled");
|
||||||
return;
|
return;
|
||||||
@@ -269,20 +272,20 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("reloadall")) {
|
if (msg.equals("reloadall")) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().cache.reloadAllFromDisk();
|
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().reloadAllFromDisk();
|
||||||
logDirect("ok");
|
logDirect("ok");
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("saveall")) {
|
if (msg.equals("saveall")) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().cache.save();
|
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().save();
|
||||||
logDirect("ok");
|
logDirect("ok");
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.startsWith("find")) {
|
if (msg.startsWith("find")) {
|
||||||
String blockType = msg.substring(4).trim();
|
String blockType = msg.substring(4).trim();
|
||||||
LinkedList<BlockPos> locs = WorldProvider.INSTANCE.getCurrentWorld().cache.getLocationsOf(blockType, 1, 4);
|
LinkedList<BlockPos> locs = WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, 4);
|
||||||
logDirect("Have " + locs.size() + " locations");
|
logDirect("Have " + locs.size() + " locations");
|
||||||
for (BlockPos pos : locs) {
|
for (BlockPos pos : locs) {
|
||||||
Block actually = BlockStateInterface.get(pos).getBlock();
|
Block actually = BlockStateInterface.get(pos).getBlock();
|
||||||
@@ -297,8 +300,9 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
String[] blockTypes = msg.substring(4).trim().split(" ");
|
String[] blockTypes = msg.substring(4).trim().split(" ");
|
||||||
try {
|
try {
|
||||||
int quantity = Integer.parseInt(blockTypes[1]);
|
int quantity = Integer.parseInt(blockTypes[1]);
|
||||||
ChunkPacker.stringToBlock(blockTypes[0]).hashCode();
|
Block block = ChunkPacker.stringToBlock(blockTypes[0]);
|
||||||
MineBehavior.INSTANCE.mine(quantity, blockTypes[0]);
|
Objects.requireNonNull(block);
|
||||||
|
MineBehavior.INSTANCE.mine(quantity, block);
|
||||||
logDirect("Will mine " + quantity + " " + blockTypes[0]);
|
logDirect("Will mine " + quantity + " " + blockTypes[0]);
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
@@ -339,22 +343,38 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Set<Waypoint> waypoints = WorldProvider.INSTANCE.getCurrentWorld().waypoints.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
|
||||||
List<Waypoint> sorted = new ArrayList<>(waypoints);
|
List<IWaypoint> sorted = new ArrayList<>(waypoints);
|
||||||
sorted.sort(Comparator.comparingLong(Waypoint::creationTimestamp));
|
sorted.sort(Comparator.comparingLong(IWaypoint::getCreationTimestamp));
|
||||||
logDirect("Waypoints under tag " + tag + ":");
|
logDirect("Waypoints under tag " + tag + ":");
|
||||||
for (Waypoint waypoint : sorted) {
|
for (IWaypoint waypoint : sorted) {
|
||||||
logDirect(waypoint.toString());
|
logDirect(waypoint.toString());
|
||||||
}
|
}
|
||||||
event.cancel();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.startsWith("save")) {
|
if (msg.startsWith("save")) {
|
||||||
String name = msg.substring(4).trim();
|
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().waypoints.addWaypoint(new Waypoint(name, Waypoint.Tag.USER, playerFeet()));
|
|
||||||
logDirect("Saved user defined tag under name '" + name + "'. Say 'goto user' to set goal, say 'list user' to list.");
|
|
||||||
event.cancel();
|
event.cancel();
|
||||||
|
String name = msg.substring(4).trim();
|
||||||
|
BlockPos pos = playerFeet();
|
||||||
|
if (name.contains(" ")) {
|
||||||
|
logDirect("Name contains a space, assuming it's in the format 'save waypointName X Y Z'");
|
||||||
|
String[] parts = name.split(" ");
|
||||||
|
if (parts.length != 4) {
|
||||||
|
logDirect("Unable to parse, expected four things");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
pos = new BlockPos(Integer.parseInt(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3]));
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
logDirect("Unable to parse coordinate integers");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
name = parts[0];
|
||||||
|
}
|
||||||
|
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.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.startsWith("goto")) {
|
if (msg.startsWith("goto")) {
|
||||||
@@ -364,31 +384,37 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
waypointType = waypointType.substring(0, waypointType.length() - 1);
|
||||||
}
|
}
|
||||||
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
|
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
|
||||||
|
IWaypoint waypoint;
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
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();
|
event.cancel();
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
logDirect("No locations for " + mining + " known, cancelling");
|
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
|
||||||
|
if (waypoint == null) {
|
||||||
|
logDirect("No locations for " + mining + " known, cancelling");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<BlockPos> locs = MineBehavior.INSTANCE.scanFor(Collections.singletonList(block), 64);
|
||||||
|
if (locs.isEmpty()) {
|
||||||
|
logDirect("No locations for " + mining + " known, cancelling");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
|
||||||
|
PathingBehavior.INSTANCE.path();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<BlockPos> locs = MineBehavior.scanFor(Collections.singletonList(block), 64);
|
} else {
|
||||||
if (locs.isEmpty()) {
|
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(tag);
|
||||||
logDirect("No locations for " + mining + " known, cancelling");
|
if (waypoint == null) {
|
||||||
|
logDirect("None saved for tag " + tag);
|
||||||
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
|
|
||||||
PathingBehavior.INSTANCE.path();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
Waypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().waypoints.getMostRecentByTag(tag);
|
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||||
if (waypoint == null) {
|
|
||||||
logDirect("None saved for tag " + tag);
|
|
||||||
event.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Goal goal = new GoalBlock(waypoint.location);
|
|
||||||
PathingBehavior.INSTANCE.setGoal(goal);
|
PathingBehavior.INSTANCE.setGoal(goal);
|
||||||
if (!PathingBehavior.INSTANCE.path()) {
|
if (!PathingBehavior.INSTANCE.path()) {
|
||||||
if (!goal.isInGoal(playerFeet())) {
|
if (!goal.isInGoal(playerFeet())) {
|
||||||
@@ -399,7 +425,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("spawn") || msg.equals("bed")) {
|
if (msg.equals("spawn") || msg.equals("bed")) {
|
||||||
Waypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().waypoints.getMostRecentByTag(Waypoint.Tag.BED);
|
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
|
||||||
if (waypoint == null) {
|
if (waypoint == null) {
|
||||||
BlockPos spawnPoint = player().getBedLocation();
|
BlockPos spawnPoint = player().getBedLocation();
|
||||||
// for some reason the default spawnpoint is underground sometimes
|
// for some reason the default spawnpoint is underground sometimes
|
||||||
@@ -407,7 +433,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
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.INSTANCE.setGoal(goal);
|
||||||
} else {
|
} else {
|
||||||
Goal goal = new GoalBlock(waypoint.location);
|
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||||
PathingBehavior.INSTANCE.setGoal(goal);
|
PathingBehavior.INSTANCE.setGoal(goal);
|
||||||
logDirect("Set goal to most recent bed " + goal);
|
logDirect("Set goal to most recent bed " + goal);
|
||||||
}
|
}
|
||||||
@@ -415,17 +441,17 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("sethome")) {
|
if (msg.equals("sethome")) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().waypoints.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();
|
event.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("home")) {
|
if (msg.equals("home")) {
|
||||||
Waypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().waypoints.getMostRecentByTag(Waypoint.Tag.HOME);
|
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
|
||||||
if (waypoint == null) {
|
if (waypoint == null) {
|
||||||
logDirect("home not saved");
|
logDirect("home not saved");
|
||||||
} else {
|
} else {
|
||||||
Goal goal = new GoalBlock(waypoint.location);
|
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||||
PathingBehavior.INSTANCE.setGoal(goal);
|
PathingBehavior.INSTANCE.setGoal(goal);
|
||||||
PathingBehavior.INSTANCE.path();
|
PathingBehavior.INSTANCE.path();
|
||||||
logDirect("Going to saved home " + goal);
|
logDirect("Going to saved home " + goal);
|
||||||
@@ -434,8 +460,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.equals("costs")) {
|
if (msg.equals("costs")) {
|
||||||
Movement[] movements = AStarPathFinder.getConnectedPositions(new BetterBlockPos(playerFeet()), new CalculationContext());
|
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(playerFeet())).collect(Collectors.toCollection(ArrayList::new));
|
||||||
List<Movement> moves = new ArrayList<>(Arrays.asList(movements));
|
|
||||||
while (moves.contains(null)) {
|
while (moves.contains(null)) {
|
||||||
moves.remove(null);
|
moves.remove(null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.BlockSlab;
|
import net.minecraft.block.BlockSlab;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -34,6 +35,11 @@ import net.minecraft.util.text.TextFormatting;
|
|||||||
*/
|
*/
|
||||||
public interface Helper {
|
public interface Helper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of {@link Helper}. Used for static-context reference.
|
||||||
|
*/
|
||||||
|
Helper HELPER = new Helper() {};
|
||||||
|
|
||||||
ITextComponent MESSAGE_PREFIX = new TextComponentString(String.format(
|
ITextComponent MESSAGE_PREFIX = new TextComponentString(String.format(
|
||||||
"%s[%sBaritone%s]%s",
|
"%s[%sBaritone%s]%s",
|
||||||
TextFormatting.DARK_PURPLE,
|
TextFormatting.DARK_PURPLE,
|
||||||
@@ -98,9 +104,4 @@ public interface Helper {
|
|||||||
component.appendSibling(new TextComponentString(" " + message));
|
component.appendSibling(new TextComponentString(" " + message));
|
||||||
Baritone.settings().logger.get().accept(component);
|
Baritone.settings().logger.get().accept(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void addToChat(ITextComponent msg) {
|
|
||||||
mc.ingameGUI.getChatGUI().printChatMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.goals.GoalComposite;
|
import baritone.api.pathing.goals.GoalComposite;
|
||||||
import baritone.pathing.goals.GoalTwoBlocks;
|
import baritone.api.pathing.goals.GoalTwoBlocks;
|
||||||
import baritone.pathing.goals.GoalXZ;
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
import baritone.pathing.path.IPath;
|
import baritone.pathing.path.IPath;
|
||||||
import baritone.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
import baritone.utils.pathing.BetterBlockPos;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
@@ -30,6 +31,18 @@ public final class RayTraceUtils implements Helper {
|
|||||||
|
|
||||||
private RayTraceUtils() {}
|
private RayTraceUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* pitch match the specified yaw and pitch values. This is particularly useful
|
||||||
|
* when you would like to simulate a "legit" raytrace with certainty that the only
|
||||||
|
* thing to achieve the desired outcome (whether it is hitting and entity or placing
|
||||||
|
* a block) can be done just by modifying user input.
|
||||||
|
*
|
||||||
|
* @param yaw The yaw to raytrace with
|
||||||
|
* @param pitch The pitch to raytrace with
|
||||||
|
* @return The calculated raytrace result
|
||||||
|
*/
|
||||||
public static RayTraceResult simulateRayTrace(float yaw, float pitch) {
|
public static RayTraceResult simulateRayTrace(float yaw, float pitch) {
|
||||||
RayTraceResult oldTrace = mc.objectMouseOver;
|
RayTraceResult oldTrace = mc.objectMouseOver;
|
||||||
float oldYaw = mc.player.rotationYaw;
|
float oldYaw = mc.player.rotationYaw;
|
||||||
@@ -48,6 +61,14 @@ public final class RayTraceUtils implements Helper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a block raytrace with the specified rotations. This should only be used when
|
||||||
|
* any entity collisions can be ignored, because this method will not recognize if an
|
||||||
|
* entity is in the way or not. The local player's block reach distance will be used.
|
||||||
|
*
|
||||||
|
* @param rotation The rotation to raytrace towards
|
||||||
|
* @return The calculated raytrace result
|
||||||
|
*/
|
||||||
public static RayTraceResult rayTraceTowards(Rotation rotation) {
|
public static RayTraceResult rayTraceTowards(Rotation rotation) {
|
||||||
double blockReachDistance = mc.playerController.getBlockReachDistance();
|
double blockReachDistance = mc.playerController.getBlockReachDistance();
|
||||||
Vec3d start = mc.player.getPositionEyes(1.0F);
|
Vec3d start = mc.player.getPositionEyes(1.0F);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.utils;
|
package baritone.utils;
|
||||||
|
|
||||||
|
import baritone.api.utils.Rotation;
|
||||||
import net.minecraft.block.BlockFire;
|
import net.minecraft.block.BlockFire;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
@@ -26,6 +27,8 @@ import net.minecraft.util.math.MathHelper;
|
|||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import static baritone.utils.Helper.HELPER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018 12:56 AM
|
* @since 8/1/2018 12:56 AM
|
||||||
@@ -96,10 +99,7 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
|
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
|
||||||
return new Rotation(
|
return target.subtract(current).normalize().add(current);
|
||||||
MathHelper.wrapDegrees(target.getFirst() - current.getFirst()) + current.getFirst(),
|
|
||||||
MathHelper.wrapDegrees(target.getSecond() - current.getSecond()) + current.getSecond()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vec3d vec3dFromBlockPos(BlockPos orig) {
|
public static Vec3d vec3dFromBlockPos(BlockPos orig) {
|
||||||
@@ -114,12 +114,12 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static double playerDistanceToCenter(BlockPos pos) {
|
public static double playerDistanceToCenter(BlockPos pos) {
|
||||||
EntityPlayerSP player = (new Helper() {}).player();
|
EntityPlayerSP player = HELPER.player();
|
||||||
return distanceToCenter(pos, player.posX, player.posY, player.posZ);
|
return distanceToCenter(pos, player.posX, player.posY, player.posZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double playerFlatDistanceToCenter(BlockPos pos) {
|
public static double playerFlatDistanceToCenter(BlockPos pos) {
|
||||||
EntityPlayerSP player = (new Helper() {}).player();
|
EntityPlayerSP player = HELPER.player();
|
||||||
return distanceToCenter(pos, player.posX, pos.getY() + 0.5, player.posZ);
|
return distanceToCenter(pos, player.posX, pos.getY() + 0.5, player.posZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.utils.pathing;
|
package baritone.utils.pathing;
|
||||||
|
|
||||||
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
@@ -51,22 +52,7 @@ public final class BetterBlockPos extends BlockPos {
|
|||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
/*
|
this.hashCode = AbstractNodeCostSearch.posHash(x, y, z);
|
||||||
* This is the hashcode implementation of Vec3i, the superclass of BlockPos
|
|
||||||
*
|
|
||||||
* public int hashCode() {
|
|
||||||
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* That is terrible and has tons of collisions and makes the HashMap terribly inefficient.
|
|
||||||
*
|
|
||||||
* That's why we grab out the X, Y, Z and calculate our own hashcode
|
|
||||||
*/
|
|
||||||
long hash = 3241;
|
|
||||||
hash = 3457689L * hash + x;
|
|
||||||
hash = 8734625L * hash + y;
|
|
||||||
hash = 2873465L * hash + z;
|
|
||||||
this.hashCode = hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BetterBlockPos(double x, double y, double z) {
|
public BetterBlockPos(double x, double y, double z) {
|
||||||
@@ -129,7 +115,7 @@ public final class BetterBlockPos extends BlockPos {
|
|||||||
@Override
|
@Override
|
||||||
public BetterBlockPos down(int amt) {
|
public BetterBlockPos down(int amt) {
|
||||||
// see comment in up()
|
// see comment in up()
|
||||||
return new BetterBlockPos(x, y - amt, z);
|
return amt == 0 ? this : new BetterBlockPos(x, y - amt, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -140,7 +126,50 @@ public final class BetterBlockPos extends BlockPos {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BetterBlockPos offset(EnumFacing dir, int dist) {
|
public BetterBlockPos offset(EnumFacing dir, int dist) {
|
||||||
|
if (dist == 0) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
Vec3i vec = dir.getDirectionVec();
|
Vec3i vec = dir.getDirectionVec();
|
||||||
return new BetterBlockPos(x + vec.getX() * dist, y + vec.getY() * dist, z + vec.getZ() * dist);
|
return new BetterBlockPos(x + vec.getX() * dist, y + vec.getY() * dist, z + vec.getZ() * dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos north() {
|
||||||
|
return new BetterBlockPos(x, y, z - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos north(int amt) {
|
||||||
|
return amt == 0 ? this : new BetterBlockPos(x, y, z - amt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos south() {
|
||||||
|
return new BetterBlockPos(x, y, z + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos south(int amt) {
|
||||||
|
return amt == 0 ? this : new BetterBlockPos(x, y, z + amt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos east() {
|
||||||
|
return new BetterBlockPos(x + 1, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos east(int amt) {
|
||||||
|
return amt == 0 ? this : new BetterBlockPos(x + amt, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos west() {
|
||||||
|
return new BetterBlockPos(x - 1, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterBlockPos west(int amt) {
|
||||||
|
return amt == 0 ? this : new BetterBlockPos(x - amt, y, z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils.pathing;
|
||||||
|
|
||||||
|
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result of a calculated movement, with destination x, y, z, and the cost of performing the movement
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public final class MoveResult {
|
||||||
|
public static final MoveResult IMPOSSIBLE = new MoveResult(0, 0, 0, COST_INF);
|
||||||
|
public final int destX;
|
||||||
|
public final int destY;
|
||||||
|
public final int destZ;
|
||||||
|
public final double cost;
|
||||||
|
|
||||||
|
public MoveResult(int x, int y, int z, double cost) {
|
||||||
|
this.destX = x;
|
||||||
|
this.destY = y;
|
||||||
|
this.destZ = z;
|
||||||
|
this.cost = cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,10 +17,8 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc.openset;
|
package baritone.pathing.calc.openset;
|
||||||
|
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.pathing.calc.PathNode;
|
import baritone.pathing.calc.PathNode;
|
||||||
import baritone.pathing.goals.Goal;
|
|
||||||
import baritone.utils.pathing.BetterBlockPos;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
@@ -91,14 +89,14 @@ public class OpenSetsTest {
|
|||||||
// can't use an existing goal
|
// can't use an existing goal
|
||||||
// because they use Baritone.settings()
|
// because they use Baritone.settings()
|
||||||
// and we can't do that because Minecraft itself isn't initted
|
// and we can't do that because Minecraft itself isn't initted
|
||||||
PathNode pn = new PathNode(new BetterBlockPos(0, 0, 0), new Goal() {
|
PathNode pn = new PathNode(0, 0, 0, new Goal() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(BlockPos pos) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double heuristic(BlockPos pos) {
|
public double heuristic(int x, int y, int z) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.pathing.goals;
|
package baritone.pathing.goals;
|
||||||
|
|
||||||
|
import baritone.api.pathing.goals.GoalGetToBlock;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -19,10 +19,10 @@ package baritone.pathing.movement;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static baritone.pathing.movement.ActionCostsButOnlyTheOnesThatMakeMickeyDieInside.*;
|
import static baritone.api.pathing.movement.ActionCosts.*;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class ActionCostsButOnlyTheOnesThatMakeMickeyDieInsideTest {
|
public class ActionCostsTest {
|
||||||
@Test
|
@Test
|
||||||
public void testFallNBlocksCost() {
|
public void testFallNBlocksCost() {
|
||||||
assertEquals(FALL_N_BLOCKS_COST.length, 257); // Fall 0 blocks through fall 256 blocks
|
assertEquals(FALL_N_BLOCKS_COST.length, 257); // Fall 0 blocks through fall 256 blocks
|
||||||
@@ -17,14 +17,17 @@
|
|||||||
|
|
||||||
package baritone.utils.pathing;
|
package baritone.utils.pathing;
|
||||||
|
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class BetterBlockPosTest {
|
public class BetterBlockPosTest {
|
||||||
|
|
||||||
@Test
|
// disabled since this is a benchmark, not really a test. also including it makes the tests take 50 seconds for no reason
|
||||||
|
/*@Test
|
||||||
public void benchMulti() {
|
public void benchMulti() {
|
||||||
System.out.println("Benching up()");
|
System.out.println("Benching up()");
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
@@ -37,7 +40,40 @@ public class BetterBlockPosTest {
|
|||||||
benchN();
|
benchN();
|
||||||
assertTrue(i<10);
|
assertTrue(i<10);
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure BetterBlockPos behaves just like BlockPos
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSimple() {
|
||||||
|
BlockPos pos = new BlockPos(1, 2, 3);
|
||||||
|
BetterBlockPos better = new BetterBlockPos(1, 2, 3);
|
||||||
|
assertEquals(pos, better);
|
||||||
|
assertEquals(pos.up(), better.up());
|
||||||
|
assertEquals(pos.down(), better.down());
|
||||||
|
assertEquals(pos.north(), better.north());
|
||||||
|
assertEquals(pos.south(), better.south());
|
||||||
|
assertEquals(pos.east(), better.east());
|
||||||
|
assertEquals(pos.west(), better.west());
|
||||||
|
for (EnumFacing dir : EnumFacing.values()) {
|
||||||
|
assertEquals(pos.offset(dir), better.offset(dir));
|
||||||
|
assertEquals(pos.offset(dir, 0), pos);
|
||||||
|
assertEquals(better.offset(dir, 0), better);
|
||||||
|
for (int i = -10; i < 10; i++) {
|
||||||
|
assertEquals(pos.offset(dir, i), better.offset(dir, i));
|
||||||
|
}
|
||||||
|
assertTrue(better.offset(dir, 0) == better);
|
||||||
|
}
|
||||||
|
for (int i = -10; i < 10; i++) {
|
||||||
|
assertEquals(pos.up(i), better.up(i));
|
||||||
|
assertEquals(pos.down(i), better.down(i));
|
||||||
|
assertEquals(pos.north(i), better.north(i));
|
||||||
|
assertEquals(pos.south(i), better.south(i));
|
||||||
|
assertEquals(pos.east(i), better.east(i));
|
||||||
|
assertEquals(pos.west(i), better.west(i));
|
||||||
|
}
|
||||||
|
assertTrue(better.offset(null, 0) == better);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void benchOne() {
|
public void benchOne() {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.utils.pathing;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class PathingBlockTypeTest {
|
||||||
|
@Test
|
||||||
|
public void testBits() {
|
||||||
|
for (PathingBlockType type : PathingBlockType.values()) {
|
||||||
|
boolean[] bits = type.getBits();
|
||||||
|
assertTrue(type == PathingBlockType.fromBits(bits[0], bits[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user