Compare commits

...

131 Commits

Author SHA1 Message Date
Leijurv e661330fb6 v1.0.0-hotfix-4 2018-12-04 14:19:20 -08:00
Leijurv 9b13380b29 fixed switched block states in traverse 2018-12-04 14:18:32 -08:00
Leijurv b48444da8c don't splice if not on ground 2018-12-01 10:48:43 -08:00
Leijurv 11a4225eaf fix inability to break fire 2018-11-29 20:10:04 -08:00
Leijurv 0611e3088e cherry pick flowing cache fix 2018-11-28 16:04:13 -08:00
Leijurv 73628f09c1 don't crash when Auto mine does weird things 2018-11-27 10:23:26 -08:00
Leijurv a907746f53 only walk through supported snow, fixes #276 2018-11-26 15:33:33 -08:00
Leijurv 8189e90569 unable to start a parkour jump from stairs 2018-11-26 15:19:03 -08:00
Leijurv 9f83677df9 favored lookup performance 2018-11-26 15:11:36 -08:00
Leijurv 5265c46f60 over 10k less objects per second 2018-11-26 15:08:37 -08:00
Leijurv 6d37e14b0e thousands here too, on long paths 2018-11-26 15:07:38 -08:00
Leijurv fbecff52af believe it or not, this saves thousands of object allocations per second 2018-11-26 15:07:29 -08:00
Leijurv 4af14cf0a6 unneeded, and was allocating thousands of sets a second 2018-11-26 15:07:12 -08:00
Leijurv 16a201255e fix behavior around cocoa pods and vines, fixes #277 2018-11-26 15:03:59 -08:00
Leijurv 22bb9f0ec8 v1.0.0-hotfix-3 2018-11-12 09:07:48 -08:00
Leijurv 654ac1075a wait a tick until objectMouseOver matches, fixes #254 2018-11-10 09:26:32 -08:00
Leijurv ffc050668b fix cherry pick merge errors 2018-11-07 10:01:58 -08:00
Leijurv 80f65452e1 make sure to pick up dropped items while mining, fixes #170 2018-11-07 09:56:47 -08:00
Leijurv c614d7ec6a fix stupid minebehavior bug 2018-11-03 20:25:09 -07:00
Leijurv c37a5ba956 revamp readme 2018-11-02 16:23:57 -07:00
Leijurv da5969c2fd shouldnt have taken this long to figure that out 2018-11-01 20:58:48 -07:00
Leijurv 990107a1fa simplify 2018-11-01 20:27:34 -07:00
Leijurv 42eb86b624 useless check? 2018-11-01 15:41:53 -07:00
Leijurv b65a199e54 move all checks from BlockStateInterface to MovementHelper 2018-11-01 15:36:32 -07:00
Leijurv 88e3bcdf63 what 2018-11-01 15:32:58 -07:00
Leijurv 0fbfa32e6b fix exception in pathfinder 2018-11-01 15:30:33 -07:00
Leijurv 20405716bc fix impact 4.4 compatibility and add help message 2018-11-01 14:07:08 -07:00
Leijurv 8da7406e8f green 2018-10-31 20:37:18 -07:00
Leijurv 97fd3df8f7 minecraft version badge 2018-10-30 19:06:42 -07:00
Leijurv b9b33b5351 move calculation context construction to main thread 2018-10-29 18:58:59 -07:00
Brady 19ecb1bbb3 Merge LocationTrackingBehavior into MemoryBehavior
Fixes #242
2018-10-29 16:43:03 -05:00
Leijurv f6043f4ac6 changed wording 2018-10-28 16:44:56 -07:00
Brady ed1941abdb Fix desynchronized allowFlying state 2018-10-28 18:38:23 -05:00
Leijurv 24d24728dc intellij be like 2018-10-28 16:05:08 -07:00
Leijurv 77db4cd19f codacy 2018-10-28 15:24:52 -07:00
Leijurv adbb03e5cb unused lol 2018-10-28 15:24:23 -07:00
Leijurv f0226f1ea7 brady doesn't know how to do imports 2018-10-28 15:23:34 -07:00
Leijurv be5df2677b finally add shulkers lol 2018-10-28 13:55:03 -07:00
Brady 3d4a856bb2 Remove unnecessary casts 2018-10-27 23:21:30 -05:00
Leijurv 1b1233d26a only one singleton 2018-10-27 18:45:17 -07:00
Leijurv c4b0e0a810 codady submission complete 2018-10-27 16:18:03 -07:00
Leijurv 1dee8ef355 completely submitting to codacy 2018-10-27 14:41:25 -07:00
Leijurv 8cee173f92 appease codacy some more 2018-10-27 14:16:34 -07:00
Brady 19e0e6d962 Feed codacy 2018-10-27 14:38:10 -05:00
Leijurv ef8fd70475 add some more badges for no reason lol 2018-10-27 09:25:53 -07:00
Leijurv 6df05f4b7f add link to my vid 2018-10-27 08:37:30 -07:00
Brady 4e1491a0cc Rename xrayFor to searchWorld 2018-10-26 13:30:16 -05:00
leijurv 55091154c4 start on legitMine 2018-10-25 21:22:00 -07:00
leijurv a0b1cb2993 preliminary refactoring 2018-10-25 20:09:06 -07:00
Leijurv 7617081637 no longer needed 2018-10-24 23:22:19 -07:00
Leijurv 96e7f37799 add link to adovin's video 2018-10-23 20:41:35 -07:00
Leijurv a0bf22de86 Merge pull request #233 from ave4224/toolkit
Toolkit fixes
2018-10-22 21:43:42 -07:00
ave4224 9a1aecc002 tool set, fixes #227 2018-10-23 00:41:59 -04:00
Brady ad941fcbb2 Clarify anti nudge 2018-10-22 18:02:18 -05:00
Leijurv e5ca30dc26 forgot that one 2018-10-22 14:04:19 -07:00
Leijurv a23eadf5cf Merge pull request #235 from 0-x-2-2/patch-1
Fixed serious issue.
2018-10-22 12:46:17 -07:00
Leijurv 82417f4f85 comment to explain weird thing 2018-10-22 12:42:08 -07:00
0x22 af788133c2 Fixed serious issue.
Determinizer description was incorrect.
2018-10-22 15:42:05 -04:00
Leijurv a6dc156a79 bump version to match build gradle 2018-10-21 14:24:23 -07:00
Leijurv 25bebdc172 leftClickCounter shadow appears to be unneeded 2018-10-20 20:33:49 -07:00
Leijurv b55d96169f update some documentation 2018-10-19 21:15:37 -07:00
Leijurv 1a809fa7a3 dispatch path events from main thread instead of calculation thread 2018-10-18 15:04:40 -07:00
Leijurv 313a5fddbe add release badge 2018-10-18 14:36:14 -07:00
Leijurv 732d806820 allow cutting onto next path one movement earlier 2018-10-17 12:16:03 -07:00
Leijurv 11ed8a2f21 rearrange fields and constructors 2018-10-16 20:05:18 -07:00
Leijurv 3aa8f51015 print shasums on build 2018-10-16 17:00:37 -07:00
Leijurv 85b038dada v1.0.0-hotfix-2 2018-10-16 16:03:51 -07:00
Leijurv dd25527a62 pillar fixes for ncp 2018-10-16 14:21:27 -07:00
Leijurv ac372bc6fc v1.0.0-hotfix-1 2018-10-16 11:32:44 -07:00
Leijurv 63ce4fe0bd don't crash on empty region 2018-10-16 11:32:27 -07:00
Leijurv 398169f68e special case for damn daniel 2018-10-16 11:13:35 -07:00
Leijurv 46a24af373 cancel chat event 2018-10-16 11:13:08 -07:00
Leijurv 0cd9bb658f keep ExampleBaritoneControl 2018-10-16 11:04:49 -07:00
Leijurv b0678fd259 better control 2018-10-16 10:47:44 -07:00
Leijurv 9cb4a1779e fix placement rotation during parkour 2018-10-15 20:37:10 -07:00
Leijurv 3cb4700b16 v1.0.0 2018-10-15 17:21:24 -07:00
Leijurv 94921fe03f update simpletweaker version in proguard too 2018-10-15 17:21:02 -07:00
Leijurv 0202865837 Merge branch 'master' of github.com:cabaletta/baritone 2018-10-15 17:01:35 -07:00
Leijurv b9b911eb3b add impact link 2018-10-15 17:01:29 -07:00
Brady 54fb2c5f81 Update to SimpleTweaker 1.2 2018-10-15 19:00:52 -05:00
Leijurv 2df97ff986 update install link 2018-10-15 16:55:13 -07:00
Leijurv 4374619ba2 update install and impact information 2018-10-15 16:22:03 -07:00
Leijurv 6b6ebd6968 optimize all imports 2018-10-15 16:16:04 -07:00
Leijurv b41fdc2bbd remove spammy log prints 2018-10-15 15:39:01 -07:00
Leijurv 3cac37d1a5 cached regions in ram should not expand without bound 2018-10-15 15:19:10 -07:00
Brady 2f7259714a Fix Pathing Thread crash on Forge 2018-10-14 23:46:41 -05:00
Leijurv c1076461e2 dont jump while using an item, fixes #222 2018-10-14 10:38:47 -07:00
Leijurv 6fdf845349 v0.0.9 2018-10-14 10:27:50 -07:00
Brady c80b855dab Move a lot of utils to api 2018-10-14 00:55:30 -05:00
Brady 83fc11e75b private static final > private final static 2018-10-14 00:24:59 -05:00
Brady 9654892e54 Make BlockStateInterface.AIR final 2018-10-14 00:23:49 -05:00
Brady b46fad1442 Fix bad reference 2018-10-13 23:27:11 -05:00
Brady ff652dbe40 scanLoadedChunks -> scanChunkRadius 2018-10-13 23:15:34 -05:00
leijurv 897483884a fix 2 block parkour failure on lilypads and after descends 2018-10-13 17:01:40 -07:00
Leijurv ba68990ef8 update codacy badge 2018-10-13 12:36:05 -07:00
Leijurv de29a6532f privatize 2018-10-13 12:29:14 -07:00
Leijurv 9045791e7f cleanup 2018-10-13 12:28:20 -07:00
Leijurv ab2fa0ba88 update instructions for new build system 2018-10-12 21:36:41 -07:00
Leijurv 56b67cbc47 no longer needed 2018-10-12 21:21:51 -07:00
leijurv b6a1608e73 some improvements 2018-10-12 21:19:24 -07:00
Brady 6277c20e4c funny number 2018-10-12 22:15:54 -05:00
Brady 2fc282477d No need to override Read 2018-10-12 22:13:21 -05:00
Brady 917f393f7a Merge pull request #221 from cabaletta/gradle-proguard
Proguard Gradle Build Magic
2018-10-12 21:39:47 -05:00
Brady 045504ecf7 No differences. 100% NONE 2018-10-12 21:38:05 -05:00
Leijurv 7efc0ae8ca fix snow bs 2018-10-12 19:33:03 -07:00
Brady 3958dce341 cancer 2018-10-12 21:31:33 -05:00
Brady d1a9012deb 2 spaces 2018-10-12 21:24:35 -05:00
Leijurv dbde993a76 Merge branch 'master' into gradle-proguard 2018-10-12 19:24:18 -07:00
Brady 96c66d2809 CreateDist task 2018-10-12 21:21:16 -05:00
Brady df1633b2a1 You shouldn't write a json to a jar and treat it like a jar 2018-10-12 20:42:24 -05:00
Brady 24f18f0ac2 Json sorting 2018-10-12 19:47:13 -05:00
Brady 416fea2aa5 Remove unnecessary removeIf usage 2018-10-12 18:10:54 -05:00
Brady 93286a646f Use Gradle Internal Pair 2018-10-12 18:08:15 -05:00
Brady 8fba36c05e Initial Proguard Task meme
Working Determinizer, but it doesn't sort the JSON object keys
time to rek travis
2018-10-12 17:56:09 -05:00
Leijurv b443be1795 more accurate check 2018-10-12 15:29:25 -07:00
Leijurv 4892192c6c remove unused functions 2018-10-12 15:14:39 -07:00
Leijurv 6b7a8e2bd3 better protection logic, fix placing outside worldborder 2018-10-12 14:34:33 -07:00
Leijurv c5f5445f4b fix exception when calculating descend from starting position above 256 2018-10-12 14:19:11 -07:00
Leijurv 8a65f43a0b check world border, fixes #218 2018-10-12 14:12:06 -07:00
Leijurv 76e4a1a649 brag about reproducible builds some more 2018-10-11 21:22:46 -07:00
Leijurv 5167c0c886 zip too 2018-10-11 21:12:00 -07:00
Leijurv 9d3d8f6c82 forgot install 2018-10-11 21:05:00 -07:00
Leijurv 7e4a1169af extract, sort, and reinsert refmap json into final jar 2018-10-11 21:04:07 -07:00
Leijurv 773ad89951 refactor problematic area 2018-10-11 20:36:18 -07:00
Leijurv c2adcdb051 fix 2018-10-11 20:11:35 -07:00
Leijurv b75bc6d03d comment out until its back online 2018-10-11 20:04:45 -07:00
Leijurv e3b80f11ad brag about how reproducible our builds are 2018-10-11 20:02:26 -07:00
Leijurv f33a2ef11b fully automated reproducible space deterministic builds 2018-10-11 18:52:58 -07:00
Brady 130b21f738 Fix issue with user input check that messed up Auto Eat 2018-10-11 18:50:55 -05:00
Leijurv ee954d6a4e break proguard less 2018-10-11 13:24:23 -07:00
Brady 54215bdb18 Just ONE tweaker
When we make the next release, we need to specify in the setup files that Baritone now requires the SimpleTweaker dependency, and we need to remove the old alternate tweaker references. (Optifine and Forge)
2018-10-11 14:53:20 -05:00
68 changed files with 2157 additions and 1288 deletions
+1
View File
@@ -3,6 +3,7 @@
run/
autotest/
dist/
# Gradle
build/
+1 -1
View File
@@ -9,7 +9,7 @@ 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 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; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runClient"
- docker cp baritone:/code/dist dist
- ls dist
- cat dist/checksums.txt
+4 -6
View File
@@ -13,14 +13,12 @@ RUN apt install --target-release jessie-backports \
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
COPY . /code
# this .deb is specially patched to support lwjgl
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i /code/scripts/xvfb_1.16.4-1_amd64.deb
WORKDIR /code
# this .deb is specially patched to support lwjgl
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
RUN ./gradlew build
+1 -91
View File
@@ -1,91 +1 @@
# Integration between Baritone and Impact
Impact 4.4 will have Baritone included on release, however, if you're impatient, you can install Baritone into Impact 4.3 right now!
## An Introduction
There are some basic steps to getting Baritone setup with Impact.
- Acquiring a build of Baritone
- Placing Baritone in the libraries directory
- Modifying the Impact Profile JSON to run baritone
- How to use Baritone
## Acquiring a build of Baritone
There are 3 methods of acquiring a build of Baritone (While it is still in development)
### Official Release (Not always up to date)
https://github.com/cabaletta/baritone/releases
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`.
The build for `baritone-unoptimized-X.Y.Z.jar` is deterministic, and you can verify Travis did it properly by running `scripts/build.sh` yourself and comparing the shasum. The proguarded files (api and standalone) aren't yet reproducible, because proguard annoyingly includes the current timestamp into the final jar.
### Building Baritone yourself
There are a few steps to this
- Clone this repository
- Setup the project as instructed in the README
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
command line
- Windows: ``gradlew build``
- Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
### Cutting Edge Release
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
from his Jenkins server, found <a href="https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/">here</a>.
## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
that contains all of the dependencies that are required from the game and some mods. This is where we will be
putting baritone.
- Locate the ``libraries`` folder, it should be in the Minecraft Installation Directory
- Create 3 new subdirectories starting from ``libraries``
- ``cabaletta``
- ``baritone``
- ``X.Y.Z``
- 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/X.Y.Z/baritone-X.Y.Z.jar``
## Modifying the Impact Profile JSON to run baritone
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
- Ensure your Minecraft launcher is closed
- Navigate back to the Minecraft Installation Directory
- Find the ``versions`` directory, and open in
- In here there should be a ``1.12.2-Impact_4.3`` folder.
- If you don't have any Impact folder or have a version older than 4.3, you can download Impact <a href="https://impactdevelopment.github.io">here</a>.
- Open the folder and inside there should be a file called ``1.12.2-Impact_4.3.json``
- Open the JSON file with a text editor that supports your system's line endings
- For example, Notepad on Windows likely will NOT work for this. You should instead use a Text Editor like
<a href="https://notepad-plus-plus.org/">Notepad++</a> if you're on Windows. (For other systems, I'm not sure
what would work the best so you may have to do some research.)
- Find the ``libraries`` array in the JSON. It should look something like this.
```
"libraries": [
{
"name": "net.minecraft:launchwrapper:1.12"
},
{
"name": "com.github.ImpactDevelopment:Impact:4.3-1.12.2",
"url": "https://impactdevelopment.github.io/maven/"
},
{
"name": "com.github.ImpactDeveloment:ClientAPI:3.0.2",
"url": "https://impactdevelopment.github.io/maven/"
},
...
```
- Create a new object in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
```
{
"name": "cabaletta:baritone:X.Y.Z"
},
```
- Now find the ``"minecraftArguments": "..."`` text near the top.
- At the very end of the quotes where it says ``--tweakClass clientapi.load.ClientTweaker"``, add on the following so it looks like:
- ``--tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine"``
- If you didn't close your launcher for this step, restart it now.
- You can now launch Impact 4.3 as normal, and Baritone should start up
## How to use Baritone
Instructions on how to use Baritone are limited, and you may have to read a little bit of code (Really nothing much
just plain English), you can view that <a href="https://github.com/cabaletta/baritone#chat-control">here</a>.
Impact 4.4 is out. See <a href="INSTALL.md">INSTALL.md</a>
+96
View File
@@ -0,0 +1,96 @@
# Integration between Baritone and Impact
Impact 4.4 has Baritone included.
These instructions apply to Impact 4.3 (and potentially other hacked clients).
To run Baritone on Vanilla, just follow the instructions in the README (it's `./gradlew runClient`).
## An Introduction
There are some basic steps to getting Baritone setup with Impact.
- Acquiring a build of Baritone
- Placing Baritone in the libraries directory
- Modifying the Impact Profile JSON to run baritone
- How to use Baritone
## Acquiring a build of Baritone
There are two methods of acquiring a build of Baritone
### Official Release (Not always up to date)
https://github.com/cabaletta/baritone/releases
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`.
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone . && docker run --rm cabaletta/baritone cat /code/dist/checksums.txt` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
### Building Baritone yourself
There are a few steps to this
- Clone this repository
- Setup the project as instructed in the README
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
command line
- Windows: ``gradlew build``
- Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
that contains all of the dependencies that are required from the game and some mods. This is where we will be
putting baritone.
- Locate the ``libraries`` folder, it should be in the Minecraft Installation Directory
- Create 3 new subdirectories starting from ``libraries``
- ``cabaletta``
- ``baritone``
- ``X.Y.Z``
- 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/X.Y.Z/baritone-X.Y.Z.jar``
## Modifying the Impact Profile JSON to run baritone
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
- Ensure your Minecraft launcher is closed
- Navigate back to the Minecraft Installation Directory
- Find the ``versions`` directory, and open in
- In here there should be a ``1.12.2-Impact_4.3`` folder.
- If you don't have any Impact folder or have a version older than 4.3, you can download Impact <a href="https://impactdevelopment.github.io">here</a>.
- Open the folder and inside there should be a file called ``1.12.2-Impact_4.3.json``
- Open the JSON file with a text editor that supports your system's line endings
- For example, Notepad on Windows likely will NOT work for this. You should instead use a Text Editor like
<a href="https://notepad-plus-plus.org/">Notepad++</a> if you're on Windows. (For other systems, I'm not sure
what would work the best so you may have to do some research.)
- Find the ``libraries`` array in the JSON. It should look something like this.
```
"libraries": [
{
"name": "net.minecraft:launchwrapper:1.12"
},
{
"name": "com.github.ImpactDevelopment:Impact:4.3-1.12.2",
"url": "https://impactdevelopment.github.io/maven/"
},
{
"name": "com.github.ImpactDeveloment:ClientAPI:3.0.2",
"url": "https://impactdevelopment.github.io/maven/"
},
...
```
- Create two new objects in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
```
{
"name": "cabaletta:baritone:X.Y.Z"
},
{
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.2",
"url": "https://impactdevelopment.github.io/maven/"
},
```
- Now find the ``"minecraftArguments": "..."`` text near the top.
- At the very end of the quotes where it says ``--tweakClass clientapi.load.ClientTweaker"``, add on the following so it looks like:
- ``--tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine"``
- If you didn't close your launcher for this step, restart it now.
- You can now launch Impact 4.3 as normal, and Baritone should start up
## How to use Baritone
Instructions on how to use Baritone are limited, and you may have to read a little bit of code (Really nothing much
just plain English), you can view that <a href="https://github.com/cabaletta/baritone#chat-control">here</a>.
+21 -16
View File
@@ -1,46 +1,51 @@
# Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases)
[![License](https://img.shields.io/github/license/cabaletta/baritone.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/7150d8ccf6094057b1782aa7a8f92d7d)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
Unofficial Jenkins: [![Build Status](https://plutiejenkins.leijurv.com/job/baritone/badge/icon)](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
Here are some links to help to get started:
- [Features](FEATURES.md)
- [Baritone + Impact](IMPACT.md)
- [Installation](INSTALL.md)
There's also some useful information down below
# Setup
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle task `setupDecompWorkspace`
- Run the Gradle task `genIntellijRuns`
- Refresh the Gradle project (or just restart IntelliJ)
- Select the "Minecraft Client" launch config and run
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Running Baritone:
```
$ gradlew run
$ gradlew runClient
```
Setting up for IntelliJ:
Building Baritone:
```
$ gradlew setupDecompWorkspace
$ gradlew --refresh-dependencies
$ gradlew genIntellijRuns
$ gradlew build
```
For example, to replace out Impact 4.4's Baritone build with a customized one, build Baritone as above then copy `dist/baritone-api-$VERSION.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle task `setupDecompWorkspace`
- Run the Gradle task `genIntellijRuns`
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
- Select the "Minecraft Client" launch config
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
# Chat control
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
+18 -32
View File
@@ -1,7 +1,3 @@
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
/*
* This file is part of Baritone.
*
@@ -20,7 +16,7 @@ import java.util.jar.JarOutputStream
*/
group 'baritone'
version '0.0.8'
version '1.0.0-hotfix-4'
buildscript {
repositories {
@@ -41,6 +37,10 @@ buildscript {
}
}
import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
apply plugin: 'java'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'org.spongepowered.mixin'
@@ -73,9 +73,15 @@ repositories {
name = 'spongepowered-repo'
url = 'http://repo.spongepowered.org/maven/'
}
maven {
name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/'
}
}
dependencies {
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: 'launchwrapper'
@@ -98,32 +104,12 @@ jar {
reproducibleFileOrder = true
}
build {
// while "jar" supports preserveFileTimestamps false
// reobfJar doesn't, it just sets all the last modified times to that instant where it runs the reobfuscator
// so we have to set all those last modified times back to zero
doLast {
File jarFile = new File("build/libs/baritone-" + version + ".jar")
JarFile jf = new JarFile(jarFile)
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File("temp.jar")))
jf.entries().unique { it.name }.sort { it.name }.each {
if (it.name != "META-INF/fml_cache_annotation.json" && it.name != "META-INF/fml_cache_class_versions.json") {
JarEntry clone = new JarEntry(it)
clone.time = 0
jos.putNextEntry(clone)
copy(jf.getInputStream(it), jos)
}
}
jos.finish()
jf.close()
file("temp.jar").renameTo(jarFile)
}
task proguard(type: ProguardTask) {
url 'https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip'
extract 'proguard6.0.3/lib/proguard.jar'
versionManifest 'https://launchermeta.mojang.com/mc/game/version_manifest.json'
}
void copy(InputStream is, OutputStream os) {
byte[] buffer = new byte[1024]
int len = 0
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len)
}
}
task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist)
+3
View File
@@ -0,0 +1,3 @@
build/
.gradle/
out/
@@ -15,20 +15,11 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Brady
* @since 7/31/2018 10:10 PM
*/
public class BaritoneTweakerOptifine extends BaritoneTweaker {
@Override
public final void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
this.args = new ArrayList<>();
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
}
@@ -0,0 +1,102 @@
/*
* 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.gradle.task;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.gradle.api.DefaultTask;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
/**
* @author Brady
* @since 10/12/2018
*/
class BaritoneGradleTask extends DefaultTask {
protected static final JsonParser PARSER = new JsonParser();
protected static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
PROGUARD_CONFIG_DEST = "template.pro",
PROGUARD_API_CONFIG = "api.pro",
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar",
VERSION_MANIFEST = "version_manifest.json",
TEMP_LIBRARY_DIR = "tempLibraries/",
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
protected String artifactName, artifactVersion;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
protected void verifyArtifacts() throws IllegalStateException {
this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString();
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
if (!Files.exists(this.artifactPath)) {
throw new IllegalStateException("Artifact not found! Run build first!");
}
}
protected void write(InputStream stream, Path file) throws Exception {
if (Files.exists(file)) {
Files.delete(file);
}
Files.copy(stream, file);
}
protected String formatVersion(String string) {
return String.format(string, this.artifactName, this.artifactVersion);
}
protected Path getRelativeFile(String file) {
return Paths.get(new File(file).getAbsolutePath());
}
protected Path getTemporaryFile(String file) {
return Paths.get(new File(getTemporaryDir(), file).getAbsolutePath());
}
protected Path getBuildFile(String file) {
return getRelativeFile("build/libs/" + file);
}
protected JsonElement readJson(List<String> lines) {
return PARSER.parse(String.join("\n", lines));
}
}
@@ -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.gradle.task;
import org.gradle.api.tasks.TaskAction;
import javax.xml.bind.DatatypeConverter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
* @author Brady
* @since 10/12/2018
*/
public class CreateDistTask extends BaritoneGradleTask {
private static MessageDigest SHA1_DIGEST;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
// Define the distribution file paths
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
// NIO will not automatically create directories
Path dir = getRelativeFile("dist/");
if (!Files.exists(dir)) {
Files.createDirectory(dir);
}
// Copy build jars to dist/
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
// Calculate all checksums and format them like "shasum"
List<String> shasum = Stream.of(api, standalone, unoptimized)
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());
shasum.forEach(System.out::println);
// Write the checksums to a file
Files.write(getRelativeFile("dist/checksums.txt"), shasum);
}
private static synchronized String sha1(Path path) {
try {
if (SHA1_DIGEST == null) {
SHA1_DIGEST = MessageDigest.getInstance("SHA-1");
}
return DatatypeConverter.printHexBinary(SHA1_DIGEST.digest(Files.readAllBytes(path))).toLowerCase();
} catch (Exception e) {
// haha no thanks
throw new IllegalStateException(e);
}
}
}
@@ -0,0 +1,260 @@
/*
* 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.gradle.task;
import baritone.gradle.util.Determinizer;
import com.google.gson.*;
import org.apache.commons.io.IOUtils;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.Pair;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
* @author Brady
* @since 10/11/2018
*/
public class ProguardTask extends BaritoneGradleTask {
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
@Input
private String url;
@Input
private String extract;
@Input
private String versionManifest;
private Map<String, String> versionDownloadMap;
private List<String> requiredLibraries;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
// "Haha brady why don't you make separate tasks"
processArtifact();
downloadProguard();
extractProguard();
generateConfigs();
downloadVersionManifest();
acquireDependencies();
proguardApi();
proguardStandalone();
cleanup();
}
private void processArtifact() throws Exception {
if (Files.exists(this.artifactUnoptimizedPath)) {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
}
private void downloadProguard() throws Exception {
Path proguardZip = getTemporaryFile(PROGUARD_ZIP);
if (!Files.exists(proguardZip)) {
write(new URL(this.url).openStream(), proguardZip);
}
}
private void extractProguard() throws Exception {
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
if (!Files.exists(proguardJar)) {
ZipFile zipFile = new ZipFile(getTemporaryFile(PROGUARD_ZIP).toFile());
ZipEntry zipJarEntry = zipFile.getEntry(this.extract);
write(zipFile.getInputStream(zipJarEntry), proguardJar);
zipFile.close();
}
}
private void generateConfigs() throws Exception {
Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), REPLACE_EXISTING);
// Setup the template that will be used to derive the API and Standalone configs
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
template.add(0, "-injars " + this.artifactPath.toString());
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
Process p = new ProcessBuilder("java", "-verbose").start();
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
template.add(2, "-libraryjars '" + out + "'");
// API config doesn't require any changes from the changes that we made to the template
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
// For the Standalone config, don't keep the API package
List<String> standalone = new ArrayList<>(template);
standalone.removeIf(s -> s.contains("# this is the keep api"));
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
// Discover all of the libraries that we will need to acquire from gradle
this.requiredLibraries = new ArrayList<>();
template.forEach(line -> {
if (!line.startsWith("#")) {
Matcher m = TEMP_LIBRARY_PATTERN.matcher(line);
if (m.find()) {
this.requiredLibraries.add(m.group(1));
}
}
});
}
private void downloadVersionManifest() throws Exception {
Path manifestJson = getTemporaryFile(VERSION_MANIFEST);
write(new URL(this.versionManifest).openStream(), manifestJson);
// Place all the versions in the map with their download URL
this.versionDownloadMap = new HashMap<>();
JsonObject json = readJson(Files.readAllLines(manifestJson)).getAsJsonObject();
JsonArray versions = json.getAsJsonArray("versions");
versions.forEach(element -> {
JsonObject object = element.getAsJsonObject();
this.versionDownloadMap.put(object.get("id").getAsString(), object.get("url").getAsString());
});
}
private void acquireDependencies() throws Exception {
// Create a map of all of the dependencies that we are able to access in this project
// Likely a better way to do this, I just pair the dependency with the first valid configuration
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
config.getAllDependencies().forEach(dependency ->
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
// Create the directory if it doesn't already exist
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
if (!Files.exists(tempLibraries)) {
Files.createDirectory(tempLibraries);
}
// Iterate the required libraries to copy them to tempLibraries
for (String lib : this.requiredLibraries) {
// Download the version jar from the URL acquired from the version manifest
if (lib.startsWith("minecraft")) {
String version = lib.split("-")[1];
Path versionJar = getTemporaryFile("tempLibraries/" + lib + ".jar");
if (!Files.exists(versionJar)) {
JsonObject versionJson = PARSER.parse(new InputStreamReader(new URL(this.versionDownloadMap.get(version)).openStream())).getAsJsonObject();
String url = versionJson.getAsJsonObject("downloads").getAsJsonObject("client").getAsJsonPrimitive("url").getAsString();
write(new URL(url).openStream(), versionJar);
}
continue;
}
// Find a configuration/dependency pair that matches the desired library
Pair<Configuration, Dependency> pair = null;
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
if (entry.getKey().startsWith(lib)) {
pair = entry.getValue();
}
}
// The pair must be non-null
Objects.requireNonNull(pair);
// Find the library jar file, and copy it to tempLibraries
for (File file : pair.getLeft().files(pair.getRight())) {
if (file.getName().startsWith(lib)) {
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
}
}
}
}
private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
}
private void cleanup() {
try {
Files.delete(this.proguardOut);
} catch (IOException ignored) {}
}
public void setUrl(String url) {
this.url = url;
}
public void setExtract(String extract) {
this.extract = extract;
}
public void setVersionManifest(String versionManifest) {
this.versionManifest = versionManifest;
}
private void runProguard(Path config) throws Exception {
// Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves
if (Files.exists(this.proguardOut)) {
Files.delete(this.proguardOut);
}
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
.directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder]
.start();
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
this.printOutputLog(p.getInputStream());
this.printOutputLog(p.getErrorStream());
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor();
if (exitCode != 0) {
throw new IllegalStateException("Proguard exited with code " + exitCode);
}
}
private void printOutputLog(InputStream stream) {
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (final Exception e) {
e.printStackTrace();
}
}).start();
}
}
@@ -0,0 +1,143 @@
/*
* 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.gradle.util;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;
/**
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 42069.
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
*
* @author leijurv
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath) throws IOException {
System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
try (
JarFile jarFile = new JarFile(new File(inputPath));
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File(outputPath)))
) {
List<JarEntry> entries = jarFile.stream()
.sorted(Comparator.comparing(JarEntry::getName))
.collect(Collectors.toList());
for (JarEntry entry : entries) {
if (entry.getName().equals("META-INF/fml_cache_annotation.json")) {
continue;
}
if (entry.getName().equals("META-INF/fml_cache_class_versions.json")) {
continue;
}
JarEntry clone = new JarEntry(entry.getName());
clone.setTime(42069);
jos.putNextEntry(clone);
if (entry.getName().endsWith(".refmap.json")) {
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
jos.write(writeSorted(object).getBytes());
} else {
copy(jarFile.getInputStream(entry), jos);
}
}
jos.finish();
}
}
private static void copy(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
}
private static String writeSorted(JsonObject in) throws IOException {
StringWriter writer = new StringWriter();
JsonWriter jw = new JsonWriter(writer);
ORDERED_JSON_WRITER.write(jw, in);
return writer.toString() + "\n";
}
/**
* All credits go to GSON and its contributors. GSON is licensed under the Apache 2.0 License.
* This implementation has been modified to write {@link JsonObject} keys in order.
*
* @see <a href="https://github.com/google/gson/blob/master/LICENSE">GSON License</a>
* @see <a href="https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java#L698">Original Source</a>
*/
private static final TypeAdapter<JsonElement> ORDERED_JSON_WRITER = new TypeAdapter<JsonElement>() {
@Override
public JsonElement read(JsonReader in) {
return null;
}
@Override
public void write(JsonWriter out, JsonElement value) throws IOException {
if (value == null || value.isJsonNull()) {
out.nullValue();
} else if (value.isJsonPrimitive()) {
JsonPrimitive primitive = value.getAsJsonPrimitive();
if (primitive.isNumber()) {
out.value(primitive.getAsNumber());
} else if (primitive.isBoolean()) {
out.value(primitive.getAsBoolean());
} else {
out.value(primitive.getAsString());
}
} else if (value.isJsonArray()) {
out.beginArray();
for (JsonElement e : value.getAsJsonArray()) {
write(out, e);
}
out.endArray();
} else if (value.isJsonObject()) {
out.beginObject();
List<Map.Entry<String, JsonElement>> entries = new ArrayList<>(value.getAsJsonObject().entrySet());
entries.sort(Comparator.comparing(Map.Entry::getKey));
for (Map.Entry<String, JsonElement> e : entries) {
out.name(e.getKey());
write(out, e.getValue());
}
out.endObject();
} else {
throw new IllegalArgumentException("Couldn't write " + value.getClass());
}
}
};
}
-27
View File
@@ -1,27 +0,0 @@
#!/bin/sh
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 "this is the keep api" > standalone.pro # standalone doesn't keep baritone api
#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 ..
+11 -13
View File
@@ -1,7 +1,3 @@
-injars baritone-0.0.8.jar
-outjars Obfuscated
-keepattributes Signature
-keepattributes *Annotation*
@@ -17,9 +13,14 @@
-repackageclasses 'baritone'
-keep class baritone.api.** { *; } # this is the keep api
# service provider needs these class names
-keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider
# hack
-keep class baritone.utils.ExampleBaritoneControl { *; }
# setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings {
public <fields>;
@@ -29,10 +30,11 @@
-keep class baritone.launch.** { *; }
# copy all necessary libraries into tempLibraries to build
-libraryjars '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/rt.jar' # this is the rt jar
-libraryjars 'tempLibraries/minecraft-1.12.2.jar'
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
-libraryjars 'tempLibraries/codecwav-20101023.jar'
@@ -47,7 +49,6 @@
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0.jar'
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
-libraryjars 'tempLibraries/jna-4.4.0.jar'
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
@@ -58,13 +59,10 @@
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
# linux / travis
-libraryjars 'tempLibraries/lwjgl-2.9.4-nightly-20150209.jar'
-libraryjars 'tempLibraries/lwjgl_util-2.9.4-nightly-20150209.jar'
# mac
#-libraryjars 'tempLibraries/lwjgl_util-2.9.2-nightly-20140822.jar'
#-libraryjars 'tempLibraries/lwjgl-2.9.2-nightly-20140822.jar'
# startsWith is used to check the library, and mac/linux differ in which version they use
# this is FINE
-libraryjars 'tempLibraries/lwjgl-.jar'
-libraryjars 'tempLibraries/lwjgl_util-.jar'
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
+2 -2
View File
@@ -36,8 +36,8 @@ import java.util.ServiceLoader;
*/
public final class BaritoneAPI {
private final static IBaritoneProvider baritone;
private final static Settings settings;
private static final IBaritoneProvider baritone;
private static final Settings settings;
static {
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
+17
View File
@@ -376,6 +376,11 @@ public class Settings {
*/
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
/**
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
*/
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
/**
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
* <p>
@@ -396,6 +401,18 @@ public class Settings {
*/
public Setting<Integer> axisHeight = new Setting<>(120);
/**
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
* couldn't. If you don't want it to look like you're X-Raying, turn this off
*/
public Setting<Boolean> legitMine = new Setting<>(false);
/**
* What Y level to go to for legit strip mining
*/
public Setting<Integer> legitMineYLevel = new Setting<>(11);
/**
* When mining block of a certain type, try to mine two at once instead of one.
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
@@ -17,9 +17,9 @@
package baritone.api.behavior;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.path.IPathExecutor;
import java.util.Optional;
+1 -1
View File
@@ -38,5 +38,5 @@ public interface IWorldScanner {
* @param maxSearchRadius The maximum chunk search radius
* @return The matching block positions
*/
List<BlockPos> scanLoadedChunks(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
List<BlockPos> scanChunkRadius(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
}
@@ -105,8 +105,9 @@ public interface IPath {
default double ticksRemainingFrom(int pathPosition) {
double sum = 0;
//this is fast because we aren't requesting recalculation, it's just cached
for (int i = pathPosition; i < movements().size(); i++) {
sum += movements().get(i).getCost();
List<IMovement> movements = movements();
for (int i = pathPosition; i < movements.size(); i++) {
sum += movements.get(i).getCost();
}
return sum;
}
@@ -15,19 +15,25 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
package baritone.api.utils;
import baritone.api.utils.Rotation;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import static baritone.behavior.LookBehaviorUtils.calcVec3dFromRotation;
import java.util.Optional;
/**
* @author Brady
* @since 8/25/2018
*/
public final class RayTraceUtils implements Helper {
public final class RayTraceUtils {
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
private RayTraceUtils() {}
@@ -39,7 +45,7 @@ public final class RayTraceUtils implements Helper {
* 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 yaw The yaw to raytrace with
* @param pitch The pitch to raytrace with
* @return The calculated raytrace result
*/
@@ -72,7 +78,7 @@ public final class RayTraceUtils implements Helper {
public static RayTraceResult rayTraceTowards(Rotation rotation) {
double blockReachDistance = mc.playerController.getBlockReachDistance();
Vec3d start = mc.player.getPositionEyes(1.0F);
Vec3d direction = calcVec3dFromRotation(rotation);
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
Vec3d end = start.add(
direction.x * blockReachDistance,
direction.y * blockReachDistance,
@@ -80,4 +86,28 @@ public final class RayTraceUtils implements Helper {
);
return mc.world.rayTraceBlocks(start, end, false, false, true);
}
/**
* Returns the block that the crosshair is currently placed over. Updated once per render tick.
*
* @return The position of the highlighted block
*/
public static Optional<BlockPos> getSelectedBlock() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(mc.objectMouseOver.getBlockPos());
}
return Optional.empty();
}
/**
* Returns the entity that the crosshair is currently placed over. Updated once per render tick.
*
* @return The entity
*/
public static Optional<Entity> getSelectedEntity() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(mc.objectMouseOver.entityHit);
}
return Optional.empty();
}
}
@@ -17,12 +17,47 @@
package baritone.api.utils;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.*;
import java.util.Optional;
/**
* @author Brady
* @since 9/25/2018
*/
public final class RotationUtils {
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
/**
* Constant that a degree value is multiplied by to get the equivalent radian value
*/
public static final double DEG_TO_RAD = Math.PI / 180.0;
/**
* Constant that a radian value is multiplied by to get the equivalent degree value
*/
public static final double RAD_TO_DEG = 180.0 / Math.PI;
/**
* Offsets from the root block position to the center of each side.
*/
private static final Vec3d[] BLOCK_SIDE_MULTIPLIERS = new Vec3d[]{
new Vec3d(0.5, 0, 0.5), // Down
new Vec3d(0.5, 1, 0.5), // Up
new Vec3d(0.5, 0.5, 0), // North
new Vec3d(0.5, 0.5, 1), // South
new Vec3d(0, 0.5, 0.5), // West
new Vec3d(1, 0.5, 0.5) // East
};
private RotationUtils() {}
/**
@@ -51,4 +86,156 @@ public final class RotationUtils {
}
return newYaw;
}
/**
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
*
* @param orig The origin position
* @param dest The destination position
* @return The rotation from the origin to the destination
*/
public static Rotation calcRotationFromCoords(BlockPos orig, BlockPos dest) {
return calcRotationFromVec3d(new Vec3d(orig), new Vec3d(dest));
}
/**
* Wraps the target angles to a relative value from the current angles. This is done by
* subtracting the current from the target, normalizing it, and then adding the current
* angles back to it.
*
* @param current The current angles
* @param target The target angles
* @return The wrapped angles
*/
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
return target.subtract(current).normalize().add(current);
}
/**
* Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub> and makes the
* return value relative to the specified current rotations.
*
* @param orig The origin position
* @param dest The destination position
* @param current The current rotations
* @return The rotation from the origin to the destination
* @see #wrapAnglesToRelative(Rotation, Rotation)
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest, Rotation current) {
return wrapAnglesToRelative(current, calcRotationFromVec3d(orig, dest));
}
/**
* Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub>
*
* @param orig The origin position
* @param dest The destination position
* @return The rotation from the origin to the destination
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
double yaw = MathHelper.atan2(delta[0], -delta[2]);
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
double pitch = MathHelper.atan2(delta[1], dist);
return new Rotation(
(float) (yaw * RAD_TO_DEG),
(float) (pitch * RAD_TO_DEG)
);
}
/**
* Calculates the look vector for the specified yaw/pitch rotations.
*
* @param rotation The input rotation
* @return Look vector for the rotation
*/
public static Vec3d calcVec3dFromRotation(Rotation rotation) {
float f = MathHelper.cos(-rotation.getYaw() * (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.getPitch() * (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));
}
/**
* Determines if the specified entity is able to reach the center of any of the sides
* of the specified block. It first checks if the block center is reachable, and if so,
* that rotation will be returned. If not, it will return the first center of a given
* side that is reachable. The return type will be {@link Optional#empty()} if the entity is
* unable to reach any of the sides of the block.
*
* @param entity The viewing entity
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachable(Entity entity, BlockPos pos) {
if (pos.equals(RayTraceUtils.getSelectedBlock().orElse(null))) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
* the way we indicate that the pitch can be whatever and we only care about the yaw
* is by setting the desired pitch to the current pitch
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
* just what it currently is
*
* or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level
*/
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
}
Optional<Rotation> possibleRotation = reachableCenter(entity, pos);
//System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
IBlockState state = mc.world.getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
if (possibleRotation.isPresent()) {
return possibleRotation;
}
}
return Optional.empty();
}
/**
* Determines if the specified entity is able to reach the specified block with
* the given offsetted position. The return type will be {@link Optional#empty()} if
* the entity is unable to reach the block with the offset applied.
*
* @param entity The viewing entity
* @param pos The target block position
* @param offsetPos The position of the block with the offset applied.
* @return The optional rotation
*/
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos) {
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
//System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation);
}
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) {
return Optional.of(rotation);
}
}
return Optional.empty();
}
/**
* Determines if the specified entity is able to reach the specified block where it is
* looking at the direct center of it's hitbox.
*
* @param entity The viewing entity
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos) {
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(pos));
}
}
@@ -31,6 +31,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SettingsUtil {
private static final File settingsFile = new File(new File(Minecraft.getMinecraft().gameDir, "baritone"), "settings.txt");
private static final Map<Class<?>, SettingsIO> map;
@@ -0,0 +1,119 @@
/*
* 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;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
/**
* @author Brady
* @since 10/13/2018
*/
public final class VecUtils {
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
private VecUtils() {}
/**
* Calculates the center of the block at the specified position's bounding box
*
* @param pos The block position
* @return The center of the block's bounding box
* @see #getBlockPosCenter(BlockPos)
*/
public static Vec3d calculateBlockCenter(BlockPos pos) {
IBlockState b = mc.world.getBlockState(pos);
AxisAlignedBB bbox = b.getBoundingBox(mc.world, pos);
double xDiff = (bbox.minX + bbox.maxX) / 2;
double yDiff = (bbox.minY + bbox.maxY) / 2;
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
yDiff = 0;
}
return new Vec3d(
pos.getX() + xDiff,
pos.getY() + yDiff,
pos.getZ() + zDiff
);
}
/**
* Gets the assumed center position of the given block position.
* This is done by adding 0.5 to the X, Y, and Z axes.
* <p>
* TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos)
*
* @param pos The block position
* @return The assumed center of the position
* @see #calculateBlockCenter(BlockPos)
*/
public static Vec3d getBlockPosCenter(BlockPos pos) {
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
}
/**
* Gets the distance from the specified position to the assumed center of the specified block position.
*
* @param pos The block position
* @param x The x pos
* @param y The y pos
* @param z The z pos
* @return The distance from the assumed block center to the position
* @see #getBlockPosCenter(BlockPos)
*/
public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
double xdiff = pos.getX() + 0.5 - x;
double ydiff = pos.getY() + 0.5 - y;
double zdiff = pos.getZ() + 0.5 - z;
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
}
/**
* Gets the distance from the specified entity's position to the assumed
* center of the specified block position.
*
* @param entity The entity
* @param pos The block position
* @return The distance from the entity to the block's assumed center
* @see #getBlockPosCenter(BlockPos)
*/
public static double entityDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ);
}
/**
* Gets the distance from the specified entity's position to the assumed
* center of the specified block position, ignoring the Y axis.
*
* @param entity The entity
* @param pos The block position
* @return The horizontal distance from the entity to the block's assumed center
* @see #getBlockPosCenter(BlockPos)
*/
public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ);
}
}
@@ -17,61 +17,39 @@
package baritone.launch;
import net.minecraft.launchwrapper.ITweaker;
import io.github.impactdevelopment.simpletweaker.SimpleTweaker;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.spongepowered.asm.launch.MixinBootstrap;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.Mixins;
import org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Brady
* @since 7/31/2018 9:59 PM
*/
public class BaritoneTweaker implements ITweaker {
List<String> args;
@Override
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
this.args = new ArrayList<>(args);
if (gameDir != null) {
addArg("gameDir", gameDir.getAbsolutePath());
}
if (assetsDir != null) {
addArg("assetsDir", assetsDir.getAbsolutePath());
}
if (profile != null) {
addArg("version", profile);
}
}
public class BaritoneTweaker extends SimpleTweaker {
@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
super.injectIntoClassLoader(classLoader);
MixinBootstrap.init();
// noinspection unchecked
List<String> tweakClasses = (List<String>) Launch.blackboard.get("TweakClasses");
String obfuscation = ObfuscationServiceMCP.NOTCH;
if (tweakClasses.stream().anyMatch(s -> s.contains("net.minecraftforge.fml.common.launcher"))) {
obfuscation = ObfuscationServiceMCP.SEARGE;
}
MixinEnvironment.getDefaultEnvironment().setSide(MixinEnvironment.Side.CLIENT);
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(ObfuscationServiceMCP.NOTCH);
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(obfuscation);
Mixins.addConfiguration("mixins.baritone.json");
}
@Override
public final String getLaunchTarget() {
return "net.minecraft.client.main.Main";
}
@Override
public final String[] getLaunchArguments() {
return this.args.toArray(new String[0]);
}
private void addArg(String label, String value) {
if (!args.contains("--" + label) && value != null) {
this.args.add("--" + label);
this.args.add(value);
}
}
}
@@ -1,44 +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.launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Brady
* @since 7/31/2018 10:09 PM
*/
public class BaritoneTweakerForge extends BaritoneTweaker {
@Override
public final void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
this.args = new ArrayList<>();
}
@Override
public final void injectIntoClassLoader(LaunchClassLoader classLoader) {
super.injectIntoClassLoader(classLoader);
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(ObfuscationServiceMCP.SEARGE);
}
}
@@ -40,6 +40,8 @@ public class MixinEntityLivingBase {
)
private void preJump(CallbackInfo ci) {
EntityLivingBase _this = (EntityLivingBase) (Object) this;
// This uses Class.isInstance instead of instanceof since proguard optimizes out the instanceof (since MixinEntityLivingBase could never be instanceof EntityLivingBase in normal java)
// but proguard isn't smart enough to optimize out this Class.isInstance =)
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
}
@@ -50,6 +52,7 @@ public class MixinEntityLivingBase {
)
private void postJump(CallbackInfo ci) {
EntityLivingBase _this = (EntityLivingBase) (Object) this;
// See above
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
}
@@ -21,10 +21,13 @@ import baritone.Baritone;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.type.EventState;
import baritone.behavior.PathingBehavior;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.PlayerCapabilities;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
@@ -72,4 +75,16 @@ public class MixinEntityPlayerSP {
private void onPostUpdate(CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
}
@Redirect(
method = "onLivingUpdate",
at = @At(
value = "FIELD",
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
)
)
private boolean isAllowFlying(PlayerCapabilities capabilities) {
PathingBehavior pathingBehavior = Baritone.INSTANCE.getPathingBehavior();
return (!pathingBehavior.isEnabled() || !pathingBehavior.isPathing()) && capabilities.allowFlying;
}
}
@@ -22,9 +22,7 @@ import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.WorldEvent;
import baritone.api.event.events.type.EventState;
import baritone.behavior.PathingBehavior;
import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen;
@@ -49,8 +47,6 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(Minecraft.class)
public class MixinMinecraft {
@Shadow
private int leftClickCounter;
@Shadow
public EntityPlayerSP player;
@Shadow
@@ -62,7 +58,6 @@ public class MixinMinecraft {
)
private void postInit(CallbackInfo ci) {
Baritone.INSTANCE.init();
ExampleBaritoneControl.INSTANCE.initAndRegister();
}
@Inject(
@@ -147,7 +142,7 @@ public class MixinMinecraft {
)
)
private boolean isAllowUserInput(GuiScreen screen) {
return (PathingBehavior.INSTANCE.getCurrent() != null && player != null) || screen.allowUserInput;
return (Baritone.INSTANCE.getPathingBehavior().getCurrent() != null && Baritone.INSTANCE.getPathingBehavior().isEnabled() && player != null) || screen.allowUserInput;
}
@Inject(
+55 -8
View File
@@ -18,11 +18,15 @@
package baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritoneProvider;
import baritone.api.Settings;
import baritone.api.event.listener.IGameEventListener;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import baritone.event.GameEventHandler;
import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import baritone.utils.InputOverrideHandler;
import net.minecraft.client.Minecraft;
@@ -40,7 +44,7 @@ import java.util.concurrent.TimeUnit;
* @author Brady
* @since 7/31/2018 10:50 PM
*/
public enum Baritone {
public enum Baritone implements IBaritoneProvider {
/**
* Singleton instance of this class
@@ -55,10 +59,16 @@ public enum Baritone {
private GameEventHandler gameEventHandler;
private InputOverrideHandler inputOverrideHandler;
private Settings settings;
private List<Behavior> behaviors;
private File dir;
private ThreadPoolExecutor threadPool;
private List<Behavior> behaviors;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private FollowBehavior followBehavior;
private MineBehavior mineBehavior;
/**
* Whether or not Baritone is active
*/
@@ -81,12 +91,13 @@ public enum Baritone {
this.behaviors = new ArrayList<>();
{
registerBehavior(PathingBehavior.INSTANCE);
registerBehavior(LookBehavior.INSTANCE);
registerBehavior(MemoryBehavior.INSTANCE);
registerBehavior(LocationTrackingBehavior.INSTANCE);
registerBehavior(FollowBehavior.INSTANCE);
registerBehavior(MineBehavior.INSTANCE);
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
memoryBehavior = new MemoryBehavior(this);
followBehavior = new FollowBehavior(this);
mineBehavior = new MineBehavior(this);
new ExampleBaritoneControl(this);
}
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
registerEventListener(BaritoneAutoTest.INSTANCE);
@@ -127,6 +138,42 @@ public enum Baritone {
this.registerEventListener(behavior);
}
@Override
public FollowBehavior getFollowBehavior() {
return followBehavior;
}
@Override
public LookBehavior getLookBehavior() {
return lookBehavior;
}
@Override
public MemoryBehavior getMemoryBehavior() {
return memoryBehavior;
}
@Override
public MineBehavior getMineBehavior() {
return mineBehavior;
}
@Override
public PathingBehavior getPathingBehavior() {
return pathingBehavior;
}
@Override
public WorldProvider getWorldProvider() {
return WorldProvider.INSTANCE;
}
@Override
public WorldScanner getWorldScanner() {
return WorldScanner.INSTANCE;
}
@Override
public void registerEventListener(IGameEventListener listener) {
this.gameEventHandler.registerEventListener(listener);
}
+7 -6
View File
@@ -22,11 +22,12 @@ import baritone.api.behavior.*;
import baritone.api.cache.IWorldProvider;
import baritone.api.cache.IWorldScanner;
import baritone.api.event.listener.IGameEventListener;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
/**
* todo fix this cancer
*
* @author Brady
* @since 9/29/2018
*/
@@ -34,27 +35,27 @@ public final class BaritoneProvider implements IBaritoneProvider {
@Override
public IFollowBehavior getFollowBehavior() {
return FollowBehavior.INSTANCE;
return Baritone.INSTANCE.getFollowBehavior();
}
@Override
public ILookBehavior getLookBehavior() {
return LookBehavior.INSTANCE;
return Baritone.INSTANCE.getLookBehavior();
}
@Override
public IMemoryBehavior getMemoryBehavior() {
return MemoryBehavior.INSTANCE;
return Baritone.INSTANCE.getMemoryBehavior();
}
@Override
public IMineBehavior getMineBehavior() {
return MineBehavior.INSTANCE;
return Baritone.INSTANCE.getMineBehavior();
}
@Override
public IPathingBehavior getPathingBehavior() {
return PathingBehavior.INSTANCE;
return Baritone.INSTANCE.getPathingBehavior();
}
@Override
@@ -17,6 +17,7 @@
package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IBehavior;
/**
@@ -27,11 +28,18 @@ import baritone.api.behavior.IBehavior;
*/
public class Behavior implements IBehavior {
public final Baritone baritone;
/**
* Whether or not this behavior is enabled
*/
private boolean enabled = true;
protected Behavior(Baritone baritone) {
this.baritone = baritone;
baritone.registerBehavior(this);
}
/**
* Toggles the enabled state of this {@link Behavior}.
*
@@ -33,11 +33,11 @@ import net.minecraft.util.math.BlockPos;
*/
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
public static final FollowBehavior INSTANCE = new FollowBehavior();
private Entity following;
private FollowBehavior() {}
public FollowBehavior(Baritone baritone) {
super(baritone);
}
@Override
public void onTick(TickEvent event) {
@@ -56,9 +56,9 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
pos = new BlockPos(g.getX(), following.posY, g.getZ());
}
PathingBehavior.INSTANCE.setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
PathingBehavior.INSTANCE.revalidateGoal();
PathingBehavior.INSTANCE.path();
baritone.getPathingBehavior().setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
((PathingBehavior) baritone.getPathingBehavior()).revalidateGoal();
baritone.getPathingBehavior().path();
}
@Override
@@ -73,7 +73,7 @@ public final class FollowBehavior extends Behavior implements IFollowBehavior, H
@Override
public void cancel() {
PathingBehavior.INSTANCE.cancel();
baritone.getPathingBehavior().cancel();
follow(null);
}
}
@@ -1,53 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.api.event.events.BlockInteractEvent;
import baritone.cache.Waypoint;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.BlockBed;
/**
* A collection of event methods that are used to interact with Baritone's
* waypoint system. This class probably needs a better name.
*
* @see Waypoint
*
* @author Brady
* @since 8/22/2018
*/
public final class LocationTrackingBehavior extends Behavior implements Helper {
public static final LocationTrackingBehavior INSTANCE = new LocationTrackingBehavior();
private LocationTrackingBehavior() {}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
}
}
@Override
public void onPlayerDeath() {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
}
}
@@ -26,9 +26,6 @@ import baritone.api.utils.Rotation;
import baritone.utils.Helper;
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
public static final LookBehavior INSTANCE = new LookBehavior();
/**
* Target's values are as follows:
* <p>
@@ -49,7 +46,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
*/
private float lastYaw;
private LookBehavior() {}
public LookBehavior(Baritone baritone) {
super(baritone);
}
@Override
public void updateTarget(Rotation target, boolean force) {
@@ -1,139 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.api.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.state.IBlockState;
import net.minecraft.util.math.*;
import java.util.Optional;
import static baritone.utils.Utils.DEG_TO_RAD;
public final class LookBehaviorUtils implements Helper {
/**
* Offsets from the root block position to the center of each side.
*/
private static final Vec3d[] BLOCK_SIDE_MULTIPLIERS = new Vec3d[]{
new Vec3d(0.5, 0, 0.5), // Down
new Vec3d(0.5, 1, 0.5), // Up
new Vec3d(0.5, 0.5, 0), // North
new Vec3d(0.5, 0.5, 1), // South
new Vec3d(0, 0.5, 0.5), // West
new Vec3d(1, 0.5, 0.5) // East
};
/**
* Calculates a vector given a rotation array
*
* @param rotation {@link LookBehavior#target}
* @return vector of the rotation
*/
public static Vec3d calcVec3dFromRotation(Rotation rotation) {
float f = MathHelper.cos(-rotation.getYaw() * (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.getPitch() * (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));
}
public static Optional<Rotation> reachable(BlockPos pos) {
if (pos.equals(getSelectedBlock().orElse(null))) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
* the way we indicate that the pitch can be whatever and we only care about the yaw
* is by setting the desired pitch to the current pitch
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
* just what it currently is
*/
return Optional.of(new Rotation(mc.player.rotationYaw, mc.player.rotationPitch + 0.0001f));
}
Optional<Rotation> possibleRotation = reachableCenter(pos);
//System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
IBlockState state = BlockStateInterface.get(pos);
AxisAlignedBB aabb = state.getBoundingBox(mc.world, pos);
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
possibleRotation = reachableOffset(pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
if (possibleRotation.isPresent()) {
return possibleRotation;
}
}
return Optional.empty();
}
/**
* Checks if coordinate is reachable with the given block-face rotation offset
*
* @param pos
* @param offsetPos
* @return
*/
protected static Optional<Rotation> reachableOffset(BlockPos pos, Vec3d offsetPos) {
Rotation rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), offsetPos);
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation);
}
if (BlockStateInterface.get(pos).getBlock() instanceof BlockFire) {
if (result.getBlockPos().equals(pos.down())) {
return Optional.of(rotation);
}
}
}
return Optional.empty();
}
/**
* Checks if center of block at coordinate is reachable
*
* @param pos
* @return
*/
protected static Optional<Rotation> reachableCenter(BlockPos pos) {
return reachableOffset(pos, Utils.calcCenterFromCoords(pos, mc.world));
}
/**
* The currently highlighted block.
* Updated once a tick by Minecraft.
*
* @return the position of the highlighted block
*/
public static Optional<BlockPos> getSelectedBlock() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(mc.objectMouseOver.getBlockPos());
}
return Optional.empty();
}
}
@@ -17,14 +17,19 @@
package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IMemoryBehavior;
import baritone.api.behavior.memory.IRememberedInventory;
import baritone.api.cache.IWorldData;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.type.EventState;
import baritone.cache.Waypoint;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.BlockBed;
import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet;
import net.minecraft.network.play.client.CPacketCloseWindow;
@@ -43,11 +48,11 @@ import java.util.*;
*/
public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper {
public static MemoryBehavior INSTANCE = new MemoryBehavior();
private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>();
private MemoryBehavior() {}
public MemoryBehavior(Baritone baritone) {
super(baritone);
}
@Override
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
@@ -114,6 +119,18 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
}
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
}
}
@Override
public void onPlayerDeath() {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
}
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
return this.getCurrentContainer().rememberedInventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
}
+144 -62
View File
@@ -20,21 +20,23 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IMineBehavior;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.api.pathing.goals.*;
import baritone.api.utils.RotationUtils;
import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.*;
@@ -46,14 +48,15 @@ import java.util.stream.Collectors;
* @author leijurv
*/
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
public static final MineBehavior INSTANCE = new MineBehavior();
public static final int ORE_LOCATIONS_COUNT = 64;
private List<Block> mining;
private List<BlockPos> locationsCache;
private int quantity;
private List<BlockPos> knownOreLocations;
private BlockPos branchPoint;
private int desiredQuantity;
private MineBehavior() {}
public MineBehavior(Baritone baritone) {
super(baritone);
}
@Override
public void onTick(TickEvent event) {
@@ -64,77 +67,125 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
if (mining == null) {
return;
}
if (quantity > 0) {
if (desiredQuantity > 0) {
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
System.out.println("Currently have " + curr + " " + item);
if (curr >= quantity) {
if (curr >= desiredQuantity) {
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
cancel();
return;
}
}
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0) {
if (event.getCount() % mineGoalUpdateInterval == 0) {
Baritone.INSTANCE.getExecutor().execute(this::rescan);
}
if (mineGoalUpdateInterval != 0 && event.getCount() % mineGoalUpdateInterval == 0) {
Baritone.INSTANCE.getExecutor().execute(this::rescan);
}
if (Baritone.settings().legitMine.get()) {
addNearby();
}
updateGoal();
PathingBehavior.INSTANCE.revalidateGoal();
baritone.getPathingBehavior().revalidateGoal();
}
private void updateGoal() {
if (mining == null) {
if (mining == null || world() == null || player() == null) {
return;
}
List<BlockPos> locs = locationsCache;
List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) {
locs = prune(new ArrayList<>(locs), mining, 64);
PathingBehavior.INSTANCE.setGoal(coalesce(locs));
PathingBehavior.INSTANCE.path();
locationsCache = locs;
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, world());
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
knownOreLocations = locs2;
return;
}
// we don't know any ore locations at the moment
if (!Baritone.settings().legitMine.get()) {
return;
}
// only in non-Xray mode (aka legit mode) do we do this
if (branchPoint == null) {
int y = Baritone.settings().legitMineYLevel.get();
if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
// cool, path is over and we are at desired y
branchPoint = playerFeet();
} else {
baritone.getPathingBehavior().setGoalAndPath(new GoalYLevel(y));
return;
}
}
if (playerFeet().equals(branchPoint)) {
// TODO mine 1x1 shafts to either side
branchPoint = branchPoint.north(10);
}
baritone.getPathingBehavior().setGoalAndPath(new GoalBlock(branchPoint));
}
private void rescan() {
if (mining == null) {
if (mining == null || world() == null || player() == null) {
return;
}
List<BlockPos> locs = scanFor(mining, 64);
if (Baritone.settings().legitMine.get()) {
return;
}
List<BlockPos> locs = searchWorld(mining, ORE_LOCATIONS_COUNT, world());
locs.addAll(droppedItemsScan(mining, world()));
if (locs.isEmpty()) {
logDebug("No locations for " + mining + " known, cancelling");
mine(0, (String[]) null);
return;
}
locationsCache = locs;
knownOreLocations = locs;
}
public GoalComposite coalesce(List<BlockPos> locs) {
return new GoalComposite(locs.stream().map(loc -> {
if (!Baritone.settings().forceInternalMining.get()) {
private static Goal coalesce(BlockPos loc, List<BlockPos> locs) {
if (!Baritone.settings().forceInternalMining.get()) {
return new GoalTwoBlocks(loc);
}
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
if (upwardGoal) {
if (downwardGoal) {
return new GoalTwoBlocks(loc);
} else {
return new GoalBlock(loc);
}
} else {
if (downwardGoal) {
return new GoalBlock(loc.down());
} else {
return new GoalTwoBlocks(loc);
}
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
if (upwardGoal) {
if (downwardGoal) {
return new GoalTwoBlocks(loc);
} else {
return new GoalBlock(loc);
}
} else {
if (downwardGoal) {
return new GoalBlock(loc.down());
} else {
return new GoalTwoBlocks(loc);
}
}
}).toArray(Goal[]::new));
}
}
public List<BlockPos> scanFor(List<Block> mining, int max) {
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
if (!Baritone.settings().mineScanDroppedItems.get()) {
return new ArrayList<>();
}
Set<Item> searchingFor = new HashSet<>();
for (Block block : mining) {
Item drop = block.getItemDropped(block.getDefaultState(), new Random(), 0);
Item ore = Item.getItemFromBlock(block);
searchingFor.add(drop);
searchingFor.add(ore);
}
List<BlockPos> ret = new ArrayList<>();
for (Entity entity : world.loadedEntityList) {
if (entity instanceof EntityItem) {
EntityItem ei = (EntityItem) entity;
if (searchingFor.contains(ei.getItem().getItem())) {
ret.add(entity.getPosition());
}
}
}
return ret;
}
public static List<BlockPos> searchWorld(List<Block> mining, int max, World world) {
List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>();
//long b = System.currentTimeMillis();
@@ -151,32 +202,62 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
}
if (!uninteresting.isEmpty()) {
//long before = System.currentTimeMillis();
locs.addAll(WorldScanner.INSTANCE.scanLoadedChunks(uninteresting, max, 10, 26));
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
}
return prune(locs, mining, max);
return prune(locs, mining, max, world);
}
public List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) {
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet();
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
public void addNearby() {
BlockPos playerFeet = playerFeet();
int searchDist = 4;//why four? idk
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) {
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
BlockPos pos = new BlockPos(x, y, z);
if (mining.contains(BlockStateInterface.getBlock(pos)) && RotationUtils.reachable(player(), pos).isPresent()) {//crucial to only add blocks we can see because otherwise this is an x-ray and it'll get caught
knownOreLocations.add(pos);
}
}
}
}
knownOreLocations = prune(knownOreLocations, mining, ORE_LOCATIONS_COUNT, world());
}
public static List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max, World world) {
List<BlockPos> dropped = droppedItemsScan(mining, world);
List<BlockPos> locs = locs2
.stream()
// remove any that are within loaded chunks that aren't actually what we want
.filter(pos -> world.getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()) || dropped.contains(pos))
// remove any that are implausible to mine (encased in bedrock, or touching lava)
.filter(MineBehavior::plausibleToBreak)
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
.collect(Collectors.toList());
// remove any that are within loaded chunks that aren't actually what we want
locs.removeAll(locs.stream()
.filter(pos -> !(MineBehavior.INSTANCE.world().getChunk(pos) instanceof EmptyChunk))
.filter(pos -> !mining.contains(BlockStateInterface.get(pos).getBlock()))
.collect(Collectors.toList()));
if (locs.size() > max) {
return locs.subList(0, max);
}
return locs;
}
public static boolean plausibleToBreak(BlockPos pos) {
if (MovementHelper.avoidBreaking(pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(pos))) {
return false;
}
// bedrock above and below makes it implausible, otherwise we're good
return !(BlockStateInterface.getBlock(pos.up()) == Blocks.BEDROCK && BlockStateInterface.getBlock(pos.down()) == Blocks.BEDROCK);
}
@Override
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.quantity = quantity;
this.locationsCache = new ArrayList<>();
this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan();
updateGoal();
}
@@ -184,8 +265,9 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
@Override
public void mine(int quantity, Block... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
this.quantity = quantity;
this.locationsCache = new ArrayList<>();
this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
rescan();
updateGoal();
}
@@ -193,6 +275,6 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
@Override
public void cancel() {
mine(0, (String[]) null);
PathingBehavior.INSTANCE.cancel();
baritone.getPathingBehavior().cancel();
}
}
@@ -32,21 +32,23 @@ import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.pathing.calc.AStarPathFinder;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.calc.CutoffPath;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.PathExecutor;
import baritone.utils.BlockBreakHelper;
import baritone.utils.Helper;
import baritone.utils.PathRenderer;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper {
public static final PathingBehavior INSTANCE = new PathingBehavior();
private PathExecutor current;
private PathExecutor next;
@@ -59,29 +61,46 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private boolean lastAutoJump;
private PathingBehavior() {}
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
private void dispatchPathEvent(PathEvent event) {
Baritone.INSTANCE.getExecutor().execute(() -> Baritone.INSTANCE.getGameEventHandler().onPathEvent(event));
public PathingBehavior(Baritone baritone) {
super(baritone);
}
private void queuePathEvent(PathEvent event) {
toDispatch.add(event);
}
private void dispatchEvents() {
ArrayList<PathEvent> curr = new ArrayList<>();
toDispatch.drainTo(curr);
for (PathEvent event : curr) {
Baritone.INSTANCE.getGameEventHandler().onPathEvent(event);
}
}
@Override
public void onTick(TickEvent event) {
dispatchEvents();
if (event.getType() == TickEvent.Type.OUT) {
this.cancel();
cancel();
return;
}
mc.playerController.setPlayerCapabilities(mc.player);
tickPath();
dispatchEvents();
}
private void tickPath() {
if (current == null) {
return;
}
boolean safe = current.onTick(event);
boolean safe = current.onTick();
synchronized (pathPlanLock) {
if (current.failed() || current.finished()) {
current = null;
if (goal == null || goal.isInGoal(playerFeet())) {
logDebug("All done. At " + goal);
dispatchPathEvent(PathEvent.AT_GOAL);
queuePathEvent(PathEvent.AT_GOAL);
next = null;
return;
}
@@ -93,43 +112,38 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
// but if we fail in the middle of current
// we're nowhere close to our planned ahead path
// so need to discard it sadly.
dispatchPathEvent(PathEvent.DISCARD_NEXT);
queuePathEvent(PathEvent.DISCARD_NEXT);
next = null;
}
if (next != null) {
logDebug("Continuing on to planned next path");
dispatchPathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
current = next;
next = null;
current.onTick(event);
current.onTick();
return;
}
// at this point, current just ended, but we aren't in the goal and have no plan for the future
synchronized (pathCalcLock) {
if (isPathCalcInProgress) {
dispatchPathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
// if we aren't calculating right now
return;
}
dispatchPathEvent(PathEvent.CALC_STARTED);
queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true, Optional.empty());
}
return;
}
// at this point, we know current is in progress
if (safe) {
// a movement just ended
if (next != null) {
if (next.snipsnapifpossible()) {
// jump directly onto the next path
logDebug("Splicing into planned next path early...");
dispatchPathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
current = next;
next = null;
current.onTick(event);
return;
}
}
if (safe && next != null && player().onGround && next.snipsnapifpossible()) {
// a movement just ended; jump directly onto the next path
logDebug("Splicing into planned next path early...");
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
current = next;
next = null;
current.onTick();
return;
}
synchronized (pathCalcLock) {
if (isPathCalcInProgress) {
@@ -147,7 +161,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
// and this path has 5 seconds or less left
logDebug("Path almost over. Planning ahead...");
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath()));
}
}
@@ -184,6 +198,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
this.goal = goal;
}
public boolean setGoalAndPath(Goal goal) {
setGoal(goal);
return path();
}
@Override
public Goal getGoal() {
return goal;
@@ -211,7 +230,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
@Override
public void cancel() {
dispatchPathEvent(PathEvent.CANCELED);
queuePathEvent(PathEvent.CANCELED);
current = null;
next = null;
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
@@ -244,7 +263,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (isPathCalcInProgress) {
return false;
}
dispatchPathEvent(PathEvent.CALC_STARTED);
queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true, Optional.empty());
return true;
}
@@ -309,12 +328,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
isPathCalcInProgress = true;
}
CalculationContext context = new CalculationContext(); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
Baritone.INSTANCE.getExecutor().execute(() -> {
if (talkAboutIt) {
logDebug("Starting to search for path from " + start + " to " + goal);
}
Optional<IPath> path = findPath(start, previous);
Optional<IPath> path = findPath(start, previous, context);
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
path = path.map(p -> {
IPath result = p.cutoffAtLoadedChunks();
@@ -343,18 +363,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
synchronized (pathPlanLock) {
if (current == null) {
if (executor.isPresent()) {
dispatchPathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
current = executor.get();
} else {
dispatchPathEvent(PathEvent.CALC_FAILED);
queuePathEvent(PathEvent.CALC_FAILED);
}
} else {
if (next == null) {
if (executor.isPresent()) {
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
next = executor.get();
} else {
dispatchPathEvent(PathEvent.NEXT_CALC_FAILED);
queuePathEvent(PathEvent.NEXT_CALC_FAILED);
}
} else {
throw new IllegalStateException("I have no idea what to do with this path");
@@ -382,19 +402,15 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
* @param start
* @return
*/
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous) {
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous, CalculationContext context) {
Goal goal = this.goal;
if (goal == null) {
logDebug("no goal");
return Optional.empty();
}
if (Baritone.settings().simplifyUnloadedYCoord.get()) {
BlockPos pos = null;
if (goal instanceof IGoalRenderPos) {
pos = ((IGoalRenderPos) goal).getGoalPos();
}
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
if (world().getChunk(pos) instanceof EmptyChunk) {
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
goal = new GoalXZ(pos.getX(), pos.getZ());
}
@@ -405,14 +421,14 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} else {
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
}
Optional<HashSet<Long>> favoredPositions;
if (Baritone.settings().backtrackCostFavoringCoefficient.get() == 1D) {
favoredPositions = Optional.empty();
} else {
favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(BetterBlockPos::longHash)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
Optional<LongOpenHashSet> favoredPositions = Optional.empty();
if (Baritone.settings().backtrackCostFavoringCoefficient.get() != 1D && previous.isPresent()) {
LongOpenHashSet tmp = new LongOpenHashSet();
previous.get().positions().forEach(pos -> tmp.add(BetterBlockPos.longHash(pos)));
favoredPositions = Optional.of(tmp);
}
try {
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions);
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions, context);
return pf.calculate(timeout);
} catch (Exception e) {
logDebug("Pathing exception: " + e);
+55 -33
View File
@@ -33,40 +33,62 @@ import java.util.*;
*/
public final class CachedChunk implements IBlockTypeAccess, Helper {
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(new HashSet<Block>() {{
add(Blocks.DIAMOND_ORE);
add(Blocks.DIAMOND_BLOCK);
//add(Blocks.COAL_ORE);
add(Blocks.COAL_BLOCK);
//add(Blocks.IRON_ORE);
add(Blocks.IRON_BLOCK);
//add(Blocks.GOLD_ORE);
add(Blocks.GOLD_BLOCK);
add(Blocks.EMERALD_ORE);
add(Blocks.EMERALD_BLOCK);
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
add(Blocks.ENDER_CHEST);
add(Blocks.FURNACE);
add(Blocks.CHEST);
add(Blocks.END_PORTAL);
add(Blocks.END_PORTAL_FRAME);
add(Blocks.MOB_SPAWNER);
// TODO add all shulker colors
add(Blocks.PORTAL);
add(Blocks.HOPPER);
add(Blocks.BEACON);
add(Blocks.BREWING_STAND);
add(Blocks.SKULL);
add(Blocks.ENCHANTING_TABLE);
add(Blocks.ANVIL);
add(Blocks.LIT_FURNACE);
add(Blocks.BED);
add(Blocks.DRAGON_EGG);
add(Blocks.JUKEBOX);
add(Blocks.END_GATEWAY);
add(Blocks.WEB);
add(Blocks.NETHER_WART);
}});
static {
HashSet<Block> temp = new HashSet<>();
temp.add(Blocks.DIAMOND_ORE);
temp.add(Blocks.DIAMOND_BLOCK);
//temp.add(Blocks.COAL_ORE);
temp.add(Blocks.COAL_BLOCK);
//temp.add(Blocks.IRON_ORE);
temp.add(Blocks.IRON_BLOCK);
//temp.add(Blocks.GOLD_ORE);
temp.add(Blocks.GOLD_BLOCK);
temp.add(Blocks.EMERALD_ORE);
temp.add(Blocks.EMERALD_BLOCK);
temp.add(Blocks.ENDER_CHEST);
temp.add(Blocks.FURNACE);
temp.add(Blocks.CHEST);
temp.add(Blocks.TRAPPED_CHEST);
temp.add(Blocks.END_PORTAL);
temp.add(Blocks.END_PORTAL_FRAME);
temp.add(Blocks.MOB_SPAWNER);
temp.add(Blocks.BARRIER);
temp.add(Blocks.OBSERVER);
temp.add(Blocks.WHITE_SHULKER_BOX);
temp.add(Blocks.ORANGE_SHULKER_BOX);
temp.add(Blocks.MAGENTA_SHULKER_BOX);
temp.add(Blocks.LIGHT_BLUE_SHULKER_BOX);
temp.add(Blocks.YELLOW_SHULKER_BOX);
temp.add(Blocks.LIME_SHULKER_BOX);
temp.add(Blocks.PINK_SHULKER_BOX);
temp.add(Blocks.GRAY_SHULKER_BOX);
temp.add(Blocks.SILVER_SHULKER_BOX);
temp.add(Blocks.CYAN_SHULKER_BOX);
temp.add(Blocks.PURPLE_SHULKER_BOX);
temp.add(Blocks.BLUE_SHULKER_BOX);
temp.add(Blocks.BROWN_SHULKER_BOX);
temp.add(Blocks.GREEN_SHULKER_BOX);
temp.add(Blocks.RED_SHULKER_BOX);
temp.add(Blocks.BLACK_SHULKER_BOX);
temp.add(Blocks.PORTAL);
temp.add(Blocks.HOPPER);
temp.add(Blocks.BEACON);
temp.add(Blocks.BREWING_STAND);
temp.add(Blocks.SKULL);
temp.add(Blocks.ENCHANTING_TABLE);
temp.add(Blocks.ANVIL);
temp.add(Blocks.LIT_FURNACE);
temp.add(Blocks.BED);
temp.add(Blocks.DRAGON_EGG);
temp.add(Blocks.JUKEBOX);
temp.add(Blocks.END_GATEWAY);
temp.add(Blocks.WEB);
temp.add(Blocks.NETHER_WART);
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
}
/**
* The size of the chunk data in bits. Equal to 16 KiB.
+15
View File
@@ -319,6 +319,21 @@ public final class CachedRegion implements ICachedRegion {
}
}
public synchronized final CachedChunk mostRecentlyModified() {
CachedChunk recent = null;
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
if (this.chunks[x][z] == null) {
continue;
}
if (recent == null || this.chunks[x][z].cacheTimestamp > recent.cacheTimestamp) {
recent = this.chunks[x][z];
}
}
}
return recent;
}
/**
* @return The region x coordinate
*/
+48
View File
@@ -147,6 +147,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
region.removeExpired();
}
}); // even if we aren't saving to disk, still delete expired old chunks from RAM
prune();
return;
}
long start = System.nanoTime() / 1000000L;
@@ -157,6 +158,53 @@ public final class CachedWorld implements ICachedWorld, Helper {
});
long now = System.nanoTime() / 1000000L;
System.out.println("World save took " + (now - start) + "ms");
prune();
}
/**
* Delete regions that are too far from the player
*/
private synchronized void prune() {
BlockPos pruneCenter = guessPosition();
for (CachedRegion region : allRegions()) {
if (region == null) {
continue;
}
int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ);
if (dist > 1024) {
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
cachedRegions.remove(getRegionID(region.getX(), region.getZ()));
}
}
}
/**
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
*/
private BlockPos guessPosition() {
WorldData data = WorldProvider.INSTANCE.getCurrentWorld();
if (data != null && data.getCachedWorld() == this) {
return playerFeet();
}
CachedChunk mostRecentlyModified = null;
for (CachedRegion region : allRegions()) {
if (region == null) {
continue;
}
CachedChunk ch = region.mostRecentlyModified();
if (ch == null) {
continue;
}
if (mostRecentlyModified == null || mostRecentlyModified.cacheTimestamp < ch.cacheTimestamp) {
mostRecentlyModified = ch;
}
}
if (mostRecentlyModified == null) {
return new BlockPos(0, 0, 0);
}
return new BlockPos(mostRecentlyModified.x * 16 + 8, 0, mostRecentlyModified.z * 16 + 8);
}
private synchronized List<CachedRegion> allRegions() {
+6 -3
View File
@@ -40,6 +40,8 @@ import java.util.*;
*/
public final class ChunkPacker implements Helper {
private static final Map<String, Block> resourceCache = new HashMap<>();
private ChunkPacker() {}
public static CachedChunk pack(Chunk chunk) {
@@ -93,7 +95,8 @@ public final class ChunkPacker implements Helper {
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 y = 255; y >= 0; y--) {
@@ -120,12 +123,12 @@ public final class ChunkPacker implements Helper {
}
public static Block stringToBlock(String name) {
return Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
}
private static PathingBlockType getPathingBlockType(IBlockState state) {
Block block = state.getBlock();
if (block.equals(Blocks.WATER)) {
if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) {
// only water source blocks are plausibly usable, flowing water should be avoid
return PathingBlockType.WATER;
}
+1 -1
View File
@@ -35,7 +35,7 @@ public enum WorldScanner implements IWorldScanner, Helper {
INSTANCE;
@Override
public List<BlockPos> scanLoadedChunks(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
public List<BlockPos> scanChunkRadius(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
if (blocks.contains(null)) {
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blocks.toString());
}
@@ -18,18 +18,19 @@
package baritone.pathing.calc;
import baritone.Baritone;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Moves;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.pathing.BetterWorldBorder;
import baritone.utils.pathing.MutableMoveResult;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import java.util.HashSet;
import java.util.Optional;
/**
@@ -39,11 +40,13 @@ import java.util.Optional;
*/
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
private final Optional<HashSet<Long>> favoredPositions;
private final Optional<LongOpenHashSet> favoredPositions;
private final CalculationContext calcContext;
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<HashSet<Long>> favoredPositions) {
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<LongOpenHashSet> favoredPositions, CalculationContext context) {
super(startX, startY, startZ, goal);
this.favoredPositions = favoredPositions;
this.calcContext = context;
}
@Override
@@ -60,10 +63,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
bestHeuristicSoFar[i] = startNode.estimatedCostToGoal;
bestSoFar[i] = startNode;
}
CalculationContext calcContext = new CalculationContext();
MutableMoveResult res = new MutableMoveResult();
HashSet<Long> favored = favoredPositions.orElse(null);
BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder());
BlockStateInterface.clearCachedChunk();
LongOpenHashSet favored = favoredPositions.orElse(null);
long startTime = System.nanoTime() / 1000000L;
boolean slowPath = Baritone.settings().slowPath.get();
if (slowPath) {
@@ -97,14 +100,18 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
for (Moves moves : Moves.values()) {
int newX = currentNode.x + moves.xOffset;
int newZ = currentNode.z + moves.zOffset;
if (newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) {
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !BlockStateInterface.isLoaded(newX, newZ)) {
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
if (!BlockStateInterface.isLoaded(newX, newZ)) {
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
numEmptyChunk++;
}
continue;
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
numEmptyChunk++;
}
continue;
}
if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) {
continue;
}
if (currentNode.y + moves.yOffset > 256 || currentNode.y + moves.yOffset < 0) {
continue;
}
res.reset();
moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res);
@@ -113,15 +120,18 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
if (actionCost >= ActionCosts.COST_INF) {
continue;
}
if (actionCost <= 0) {
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
}
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
continue;
}
// 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
if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) {
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
}
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
}
if (actionCost <= 0) {
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
}
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (favoring && favored.contains(hashCode)) {
@@ -18,9 +18,9 @@
package baritone.pathing.calc;
import baritone.Baritone;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.calc.IPath;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.Optional;
@@ -17,9 +17,9 @@
package baritone.pathing.calc;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import java.util.Collections;
@@ -18,9 +18,9 @@
package baritone.pathing.calc;
import baritone.api.BaritoneAPI;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
@@ -21,6 +21,7 @@ import baritone.Baritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.utils.Helper;
import baritone.utils.ToolSet;
import baritone.utils.pathing.BetterWorldBorder;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
@@ -44,13 +45,10 @@ public class CalculationContext implements Helper {
private final int maxFallHeightBucket;
private final double waterWalkSpeed;
private final double breakBlockAdditionalCost;
private final BetterWorldBorder worldBorder;
public CalculationContext() {
this(new ToolSet());
}
public CalculationContext(ToolSet toolSet) {
this.toolSet = toolSet;
this.toolSet = new ToolSet();
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether();
this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6;
@@ -68,6 +66,29 @@ public class CalculationContext implements Helper {
// why cache these things here, why not let the movements just get directly from settings?
// because if some movements are calculated one way and others are calculated another way,
// then you get a wildly inconsistent path that isn't optimal for either scenario.
this.worldBorder = new BetterWorldBorder(world().getWorldBorder());
}
public boolean canPlaceThrowawayAt(int x, int y, int z) {
if (!hasThrowaway()) { // only true if allowPlace is true, see constructor
return false;
}
if (isPossiblyProtected(x, y, z)) {
return false;
}
return worldBorder.canPlaceAt(x, z); // TODO perhaps MovementHelper.canPlaceAgainst could also use this?
}
public boolean canBreakAt(int x, int y, int z) {
if (!allowBreak()) {
return false;
}
return !isPossiblyProtected(x, y, z);
}
public boolean isPossiblyProtected(int x, int y, int z) {
// TODO more protection logic here; see #220
return false;
}
public ToolSet getToolSet() {
@@ -20,12 +20,13 @@ package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehavior;
import baritone.behavior.LookBehaviorUtils;
import baritone.utils.*;
import baritone.api.utils.*;
import baritone.utils.BlockBreakHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import net.minecraft.block.BlockLiquid;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
@@ -33,6 +34,7 @@ import net.minecraft.world.chunk.EmptyChunk;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import static baritone.utils.InputOverrideHandler.Input;
@@ -111,9 +113,9 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
*/
@Override
public MovementStatus update() {
player().capabilities.allowFlying = false;
player().capabilities.isFlying = false;
MovementState latestState = updateState(currentState);
if (BlockStateInterface.isLiquid(playerFeet())) {
if (MovementHelper.isLiquid(playerFeet())) {
latestState.setInput(Input.JUMP, true);
}
if (player().isEntityInsideOpaqueBlock()) {
@@ -122,7 +124,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
latestState.getTarget().getRotation().ifPresent(rotation ->
LookBehavior.INSTANCE.updateTarget(
Baritone.INSTANCE.getLookBehavior().updateTarget(
rotation,
latestState.getTarget().hasToForceRotations()));
@@ -171,19 +173,24 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
for (BetterBlockPos blockPos : positionsToBreak) {
if (!MovementHelper.canWalkThrough(blockPos) && !(BlockStateInterface.getBlock(blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
somethingInTheWay = true;
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos);
if (reachable.isPresent()) {
MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos));
state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true);
state.setTarget(new MovementState.MovementTarget(reachable.get(), true));
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), blockPos) || BlockStateInterface.getBlock(blockPos) == Blocks.FIRE) {
state.setInput(Input.CLICK_LEFT, true);
}
return false;
}
//get rekt minecraft
//i'm doing it anyway
//i dont care if theres snow in the way!!!!!!!
//you dont own me!!!!
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
Utils.getBlockPosCenter(blockPos)), true)
).setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(blockPos)), true)
);
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
return false;
}
}
@@ -19,28 +19,25 @@ package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.*;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.*;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import baritone.utils.ToolSet;
import net.minecraft.block.*;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.Optional;
/**
* Static helpers for cost calculation
*
@@ -48,10 +45,6 @@ import java.util.Optional;
*/
public interface MovementHelper extends ActionCosts, Helper {
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();
return b == Blocks.ICE // ice becomes water, and water can mess up the path
@@ -74,10 +67,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return canWalkThrough(pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
}
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));
}
@@ -87,7 +76,7 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.AIR) { // early return for most common case
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 || block == Blocks.COCOA) {
return false;
}
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
@@ -107,14 +96,20 @@ public interface MovementHelper extends ActionCosts, Helper {
return true;
}
if (snow) {
return state.getValue(BlockSnow.LAYERS) < 5; // see BlockSnow.isPassable
// the check in BlockSnow.isPassable is layers < 5
// while actually, we want < 3 because 3 or greater makes it impassable in a 2 high ceiling
if (state.getValue(BlockSnow.LAYERS) >= 3) {
return false;
}
// ok, it's low enough we could walk through it, but is it supported?
return canWalkOn(x, y - 1, z);
}
if (trapdoor) {
return !state.getValue(BlockTrapDoor.OPEN); // see BlockTrapDoor.isPassable
}
throw new IllegalStateException();
}
if (BlockStateInterface.isFlowing(state)) {
if (isFlowing(state)) {
return false; // Don't walk through flowing liquids
}
if (block instanceof BlockLiquid) {
@@ -139,10 +134,6 @@ public interface MovementHelper extends ActionCosts, Helper {
*
* @return
*/
static boolean fullyPassable(BlockPos pos) {
return fullyPassable(BlockStateInterface.get(pos));
}
static boolean fullyPassable(int x, int y, int z) {
return fullyPassable(BlockStateInterface.get(x, y, z));
}
@@ -158,6 +149,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|| block == Blocks.WEB
|| block == Blocks.VINE
|| block == Blocks.LADDER
|| block == Blocks.COCOA
|| block instanceof BlockDoor
|| block instanceof BlockFenceGate
|| block instanceof BlockSnow
@@ -170,10 +162,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return block.isPassable(null, null);
}
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
// block double plant defaults to true when the block doesn't match, so don't need to check that case
@@ -197,7 +185,7 @@ public interface MovementHelper extends ActionCosts, Helper {
BlockDoublePlant.EnumPlantType kek = state.getValue(BlockDoublePlant.VARIANT);
return kek == BlockDoublePlant.EnumPlantType.FERN || kek == BlockDoublePlant.EnumPlantType.GRASS;
}
return state.getBlock().isReplaceable(null, null);
return state.getMaterial().isReplaceable();
}
static boolean isDoorPassable(BlockPos doorPos, BlockPos playerPos) {
@@ -243,7 +231,7 @@ public interface MovementHelper extends ActionCosts, Helper {
return true;
}
return facing == playerFacing == open;
return (facing == playerFacing) == open;
}
static boolean avoidWalkingInto(Block block) {
@@ -271,9 +259,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return false;
}
if (state.isBlockNormalCube()) {
if (BlockStateInterface.isLava(block) || BlockStateInterface.isWater(block)) {
throw new IllegalStateException();
}
return true;
}
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this
@@ -285,22 +270,22 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
return true;
}
if (BlockStateInterface.isWater(block)) {
if (isWater(block)) {
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
Block up = BlockStateInterface.get(x, y + 1, z).getBlock();
if (up == Blocks.WATERLILY) {
return true;
}
if (BlockStateInterface.isFlowing(state) || block == Blocks.FLOWING_WATER) {
if (isFlowing(state) || block == Blocks.FLOWING_WATER) {
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
return BlockStateInterface.isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
return isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
}
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
return BlockStateInterface.isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
}
if (block instanceof BlockGlass || block instanceof BlockStainedGlass) {
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
return true;
}
if (block instanceof BlockSlab) {
@@ -312,10 +297,7 @@ public interface MovementHelper extends ActionCosts, Helper {
}
return true;
}
if (block instanceof BlockStairs) {
return true;
}
return false;
return block instanceof BlockStairs;
}
static boolean canWalkOn(BetterBlockPos pos, IBlockState state) {
@@ -343,15 +325,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return state.isBlockNormalCube();
}
static double getMiningDurationTicks(CalculationContext context, BetterBlockPos position, boolean includeFalling) {
IBlockState state = BlockStateInterface.get(position);
return getMiningDurationTicks(context, position.x, position.y, position.z, state, 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);
}
@@ -359,7 +332,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
Block block = state.getBlock();
if (!canWalkThrough(x, y, z, state)) {
if (!context.allowBreak()) {
if (!context.canBreakAt(x, y, z)) {
return COST_INF;
}
if (avoidBreaking(x, y, z, state)) {
@@ -397,23 +370,11 @@ public interface MovementHelper extends ActionCosts, Helper {
return isBottomSlab(BlockStateInterface.get(pos));
}
/**
* The entity the player is currently looking at
*
* @return the entity object
*/
static Optional<Entity> whatEntityAmILookingAt() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(mc.objectMouseOver.entityHit);
}
return Optional.empty();
}
/**
* AutoTool
*/
static void switchToBestTool() {
LookBehaviorUtils.getSelectedBlock().ifPresent(pos -> {
RayTraceUtils.getSelectedBlock().ifPresent(pos -> {
IBlockState state = BlockStateInterface.get(pos);
if (state.getBlock().equals(Blocks.AIR)) {
return;
@@ -438,7 +399,7 @@ public interface MovementHelper extends ActionCosts, Helper {
* @param ts previously calculated ToolSet
*/
static void switchToBestToolFor(IBlockState b, ToolSet ts) {
mc.player.inventory.currentItem = ts.getBestSlot(b);
mc.player.inventory.currentItem = ts.getBestSlot(b.getBlock());
}
static boolean throwaway(boolean select) {
@@ -479,10 +440,52 @@ public interface MovementHelper extends ActionCosts, Helper {
static void moveTowards(MovementState state, BlockPos pos) {
state.setTarget(new MovementTarget(
new Rotation(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
Utils.getBlockPosCenter(pos),
new Rotation(RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(pos),
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)).getYaw(), mc.player.rotationPitch),
false
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
*
* @param b The block
* @return Whether or not the block is water
*/
static boolean isWater(Block b) {
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
}
/**
* Returns whether or not the block at the specified pos is
* water, regardless of whether or not it is flowing.
*
* @param bp The block pos
* @return Whether or not the block is water
*/
static boolean isWater(BlockPos bp) {
return isWater(BlockStateInterface.getBlock(bp));
}
static boolean isLava(Block b) {
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
}
/**
* Returns whether or not the specified pos has a liquid
*
* @param p The pos
* @return Whether or not the block is a liquid
*/
static boolean isLiquid(BlockPos p) {
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
}
static boolean isFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
}
@@ -84,9 +84,6 @@ public class MovementState {
/**
* Yaw and pitch angles that must be matched
* <p>
* getFirst() -> YAW
* getSecond() -> PITCH
*/
public Rotation rotation;
@@ -148,7 +148,7 @@ public enum Moves {
}
},
DESCEND_EAST(+1, 0, 0, false, true) {
DESCEND_EAST(+1, -1, 0, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();
@@ -166,7 +166,7 @@ public enum Moves {
}
},
DESCEND_WEST(-1, 0, 0, false, true) {
DESCEND_WEST(-1, -1, 0, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();
@@ -184,7 +184,7 @@ public enum Moves {
}
},
DESCEND_NORTH(0, 0, -1, false, true) {
DESCEND_NORTH(0, -1, -1, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();
@@ -202,7 +202,7 @@ public enum Moves {
}
},
DESCEND_SOUTH(0, 0, +1, false, true) {
DESCEND_SOUTH(0, -1, +1, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();
@@ -20,14 +20,14 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.RotationUtils;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -72,10 +72,10 @@ public class MovementAscend extends Movement {
}
boolean hasToPlace = false;
if (!MovementHelper.canWalkOn(destX, y, destZ, toPlace)) {
if (!context.hasThrowaway()) {
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
return COST_INF;
}
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) {
if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) {
return COST_INF;
}
// TODO: add ability to place against .down() as well as the cardinal directions
@@ -97,21 +97,19 @@ public class MovementAscend extends Movement {
}
}
IBlockState srcUp2 = null;
if (BlockStateInterface.get(x, y + 3, z).getBlock() instanceof BlockFalling) {//it would fall on us and possibly suffocate us
if (BlockStateInterface.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(x, y + 1, z) || !((srcUp2 = BlockStateInterface.get(x, y + 2, z)).getBlock() instanceof BlockFalling))) {//it would fall on us and possibly suffocate us
// HOWEVER, we assume that we're standing in the start position
// 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
if (MovementHelper.canWalkThrough(x, y + 1, z) || !((srcUp2 = BlockStateInterface.get(x, y + 2, z)).getBlock() instanceof BlockFalling)) {
// if the lower one is can't walk through and the upper one is falling, that means that by standing on src
// (the presupposition of this Movement)
// we have necessarily already cleared the entire BlockFalling stack
// on top of our head
// if the lower one is can't walk through and the upper one is falling, that means that by standing on src
// (the presupposition of this Movement)
// we have necessarily already cleared the entire BlockFalling stack
// on top of our head
// as in, if we have a block, then two BlockFallings on top of it
// and that block is x, y+1, z, and we'd have to clear it to even start this movement
// we don't need to worry about those BlockFallings because we've already cleared them
return COST_INF;
}
// as in, if we have a block, then two BlockFallings on top of it
// and that block is x, y+1, z, and we'd have to clear it to even start this movement
// we don't need to worry about those BlockFallings because we've already cleared them
return COST_INF;
// you may think we only need to check srcUp2, not srcUp
// however, in the scenario where glitchy world gen where unsupported sand / gravel generates
// it's possible srcUp is AIR from the start, and srcUp2 is falling
@@ -181,10 +179,10 @@ public class MovementAscend extends Movement {
double faceX = (dest.getX() + anAgainst.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + anAgainst.getY()) * 0.5D;
double faceZ = (dest.getZ() + anAgainst.getZ() + 1.0D) * 0.5D;
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
LookBehaviorUtils.getSelectedBlock().ifPresent(selectedBlock -> {
RayTraceUtils.getSelectedBlock().ifPresent(selectedBlock -> {
if (Objects.equals(selectedBlock, anAgainst) && selectedBlock.offset(side).equals(positionToPlace)) {
ticksWithoutPlacement++;
state.setInput(InputOverrideHandler.Input.SNEAK, true);
@@ -198,7 +196,7 @@ public class MovementAscend extends Movement {
} else {
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true); // break whatever replaceable block is in the way
}
System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
//System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
});
return state;
}
@@ -206,10 +204,8 @@ public class MovementAscend extends Movement {
return state.setStatus(MovementStatus.UNREACHABLE);
}
MovementHelper.moveTowards(state, dest);
if (MovementHelper.isBottomSlab(jumpingOnto)) {
if (!MovementHelper.isBottomSlab(src.down())) {
return state; // don't jump while walking from a non double slab into a bottom slab
}
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(src.down())) {
return state; // don't jump while walking from a non double slab into a bottom slab
}
if (Baritone.settings().assumeStep.get()) {
@@ -130,7 +130,7 @@ public class MovementDescend extends Movement {
}
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) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here?
if (ontoBlock.getBlock() == Blocks.WATER && !MovementHelper.isFlowing(ontoBlock) && BlockStateInterface.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here?
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
// however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works)
if (Baritone.settings().assumeWalkOnWater.get()) {
@@ -183,13 +183,12 @@ public class MovementDescend extends Movement {
}
BlockPos playerFeet = playerFeet();
if (playerFeet.equals(dest)) {
if (BlockStateInterface.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094) { // lilypads
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
return state.setStatus(MovementStatus.SUCCESS);
} else {
System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY()));
}
if (playerFeet.equals(dest) && (MovementHelper.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094)) { // lilypads
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
return state.setStatus(MovementStatus.SUCCESS);
/* else {
// System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY()));
}*/
}
double diffX = player().posX - (dest.getX() + 0.5);
double diffZ = player().posZ - (dest.getZ() + 0.5);
@@ -78,11 +78,11 @@ public class MovementDiagonal extends Movement {
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
}
Block cuttingOver1 = BlockStateInterface.get(x, y - 1, destZ).getBlock();
if (cuttingOver1 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver1)) {
if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
return COST_INF;
}
Block cuttingOver2 = BlockStateInterface.get(destX, y - 1, z).getBlock();
if (cuttingOver2 == Blocks.MAGMA || BlockStateInterface.isLava(cuttingOver2)) {
if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
return COST_INF;
}
IBlockState pb0 = BlockStateInterface.get(x, y, destZ);
@@ -101,25 +101,22 @@ public class MovementDiagonal extends Movement {
return COST_INF;
}
IBlockState pb3 = BlockStateInterface.get(destX, y + 1, z);
if (optionA == 0) {
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) {
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
if ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER)) {
return COST_INF;
}
return COST_INF;
}
optionB += MovementHelper.getMiningDurationTicks(context, destX, y + 1, z, pb3, true);
if (optionA != 0 && optionB != 0) {
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
return COST_INF;
}
if (optionB == 0) {
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER))) {
// and now that option B is fully calculated, see if we can edge around that way
if ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER)) {
return COST_INF;
}
return COST_INF;
}
boolean water = false;
if (BlockStateInterface.isWater(BlockStateInterface.getBlock(x, y, z)) || BlockStateInterface.isWater(destInto.getBlock())) {
Block startIn = BlockStateInterface.getBlock(x, y, z);
if (MovementHelper.isWater(startIn) || MovementHelper.isWater(destInto.getBlock())) {
// Ignore previous multiplier
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
// Not even touching the blocks below
@@ -128,6 +125,10 @@ public class MovementDiagonal extends Movement {
}
if (optionA != 0 || optionB != 0) {
multiplier *= SQRT_2 - 0.001; // TODO tune
if (startIn == Blocks.LADDER || startIn == Blocks.VINE) {
// edging around doesn't work if doing so would climb a ladder or vine instead of moving sideways
return COST_INF;
}
}
if (context.canSprint() && !water) {
// If we aren't edging around anything, and we aren't in water
@@ -149,7 +150,7 @@ public class MovementDiagonal extends Movement {
state.setStatus(MovementStatus.SUCCESS);
return state;
}
if (!BlockStateInterface.isLiquid(playerFeet())) {
if (!MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true);
}
MovementHelper.moveTowards(state, dest);
@@ -19,17 +19,13 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.api.utils.*;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.RayTraceUtils;
import baritone.utils.Utils;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
@@ -66,7 +62,7 @@ public class MovementFall extends Movement {
BlockPos playerFeet = playerFeet();
Rotation targetRotation = null;
if (!BlockStateInterface.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
if (!MovementHelper.isWater(dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
if (!InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) || world().provider.isNether()) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
@@ -85,10 +81,10 @@ public class MovementFall extends Movement {
if (targetRotation != null) {
state.setTarget(new MovementTarget(targetRotation, true));
} else {
state.setTarget(new MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)), false));
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
}
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || BlockStateInterface.isWater(dest))) { // 0.094 because lilypads
if (BlockStateInterface.isWater(dest)) {
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(dest))) { // 0.094 because lilypads
if (MovementHelper.isWater(dest)) {
if (InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
player().inventory.currentItem = player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
if (player().motionY >= 0) {
@@ -105,7 +101,7 @@ public class MovementFall extends Movement {
return state.setStatus(MovementStatus.SUCCESS);
}
}
Vec3d destCenter = Utils.getBlockPosCenter(dest); // we are moving to the 0.5 center not the edge (like if we were falling on a ladder)
Vec3d destCenter = VecUtils.getBlockPosCenter(dest); // we are moving to the 0.5 center not the edge (like if we were falling on a ladder)
if (Math.abs(player().posX - destCenter.x) > 0.15 || Math.abs(player().posZ - destCenter.z) > 0.15) {
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
@@ -20,15 +20,19 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.RotationUtils;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.*;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.block.Block;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
@@ -65,7 +69,7 @@ public class MovementParkour extends Movement {
return;
}
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 || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn)) {
return;
}
int xDiff = dir.getXOffset();
@@ -118,10 +122,10 @@ public class MovementParkour extends Movement {
int destX = x + 4 * xDiff;
int destZ = z + 4 * zDiff;
IBlockState toPlace = BlockStateInterface.get(destX, y - 1, destZ);
if (!context.hasThrowaway()) {
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
return;
}
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
if (toPlace.getBlock() != Blocks.AIR && !MovementHelper.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
return;
}
for (int i = 0; i < 5; i++) {
@@ -178,6 +182,10 @@ public class MovementParkour extends Movement {
if (state.getStatus() != MovementStatus.RUNNING) {
return state;
}
if (player().isHandActive()) {
logDebug("Pausing parkour since hand is active");
return state;
}
if (dist >= 4) {
state.setInput(InputOverrideHandler.Input.SPRINT, true);
}
@@ -195,7 +203,7 @@ public class MovementParkour extends Movement {
} else if (!playerFeet().equals(src)) {
if (playerFeet().equals(src.offset(direction)) || player().posY - playerFeet().getY() > 0.0001) {
if (!MovementHelper.canWalkOn(dest.down())) {
if (!MovementHelper.canWalkOn(dest.down()) && !player().onGround) {
BlockPos positionToPlace = dest.down();
for (int i = 0; i < 5; i++) {
BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
@@ -209,12 +217,12 @@ public class MovementParkour extends Movement {
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + against1.getY()) * 0.5D;
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
Rotation place = Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
Rotation place = RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
RayTraceResult res = RayTraceUtils.rayTraceTowards(place);
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(dest.down())) {
state.setTarget(new MovementState.MovementTarget(place, true));
}
LookBehaviorUtils.getSelectedBlock().ifPresent(selectedBlock -> {
RayTraceUtils.getSelectedBlock().ifPresent(selectedBlock -> {
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
if (Objects.equals(selectedBlock, against1) && selectedBlock.offset(side).equals(dest.down())) {
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
@@ -223,9 +231,17 @@ public class MovementParkour extends Movement {
}
}
}
if (dist == 3) { // this is a 2 block gap, dest = src + direction * 3
double xDiff = (src.x + 0.5) - player().posX;
double zDiff = (src.z + 0.5) - player().posZ;
double distFromStart = Math.max(Math.abs(xDiff), Math.abs(zDiff));
if (distFromStart < 0.7) {
return state;
}
}
state.setInput(InputOverrideHandler.Input.JUMP, true);
} else if(!playerFeet().equals(dest.offset(direction, -1))) {
} else if (!playerFeet().equals(dest.offset(direction, -1))) {
state.setInput(InputOverrideHandler.Input.SPRINT, false);
if (playerFeet().equals(src.offset(direction, -1))) {
MovementHelper.moveTowards(state, src);
@@ -20,13 +20,14 @@ package baritone.pathing.movement.movements;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -53,16 +54,12 @@ public class MovementPillar extends Movement {
if (fromDownDown.getBlock() instanceof BlockLadder || fromDownDown.getBlock() instanceof BlockVine) {
return COST_INF;
}
if (fromDownDown.getBlock() instanceof BlockSlab) {
if (!((BlockSlab) fromDownDown.getBlock()).isDouble() && fromDownDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
}
if (fromDownDown.getBlock() instanceof BlockSlab && !((BlockSlab) fromDownDown.getBlock()).isDouble() && fromDownDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
}
}
if (fromDown instanceof BlockVine) {
if (!hasAgainst(x, y, z)) {
return COST_INF;
}
if (fromDown instanceof BlockVine && !hasAgainst(x, y, z)) {
return COST_INF;
}
IBlockState toBreak = BlockStateInterface.get(x, y + 2, z);
Block toBreakBlock = toBreak.getBlock();
@@ -70,13 +67,13 @@ public class MovementPillar extends Movement {
return COST_INF;
}
Block srcUp = null;
if (BlockStateInterface.isWater(toBreakBlock) && BlockStateInterface.isWater(fromDown)) {
if (MovementHelper.isWater(toBreakBlock) && MovementHelper.isWater(fromDown)) {
srcUp = BlockStateInterface.get(x, y + 1, z).getBlock();
if (BlockStateInterface.isWater(srcUp)) {
if (MovementHelper.isWater(srcUp)) {
return LADDER_UP_ONE_COST;
}
}
if (!context.hasThrowaway() && !ladder) {
if (!ladder && !context.canPlaceThrowawayAt(x, y, z)) {
return COST_INF;
}
double hardness = MovementHelper.getMiningDurationTicks(context, x, y + 2, z, toBreak, true);
@@ -147,10 +144,10 @@ public class MovementPillar extends Movement {
}
IBlockState fromDown = BlockStateInterface.get(src);
if (BlockStateInterface.isWater(fromDown.getBlock()) && BlockStateInterface.isWater(dest)) {
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(dest)) {
// stay centered while swimming up a water column
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)), false));
Vec3d destCenter = Utils.getBlockPosCenter(dest);
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
if (Math.abs(player().posX - destCenter.x) > 0.2 || Math.abs(player().posZ - destCenter.z) > 0.2) {
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
@@ -161,10 +158,11 @@ public class MovementPillar extends Movement {
}
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
boolean vine = fromDown.getBlock() instanceof BlockVine;
Rotation rotation = RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(positionToPlace),
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch));
if (!ladder) {
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
Utils.getBlockPosCenter(positionToPlace),
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)), true));
state.setTarget(new MovementState.MovementTarget(new Rotation(mc.player.rotationYaw, rotation.getPitch()), true));
}
boolean blockIsThere = MovementHelper.canWalkOn(src) || ladder;
@@ -197,7 +195,8 @@ public class MovementPillar extends Movement {
// If our Y coordinate is above our goal, stop jumping
state.setInput(InputOverrideHandler.Input.JUMP, player().posY < dest.getY());
state.setInput(InputOverrideHandler.Input.SNEAK, true);
state.setInput(InputOverrideHandler.Input.SNEAK, player().posY > dest.getY()); // delay placement by 1 tick for ncp compatibility
// since (lower down) we only right click once player.isSneaking, and that happens the tick after we request to sneak
double diffX = player().posX - (dest.getX() + 0.5);
double diffZ = player().posZ - (dest.getZ() + 0.5);
@@ -208,6 +207,9 @@ public class MovementPillar extends Movement {
// If it's been more than forty ticks of trying to jump and we aren't done yet, go forward, maybe we are stuck
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
// revise our target to both yaw and pitch if we're going to be moving forward
state.setTarget(new MovementState.MovementTarget(rotation, true));
}
@@ -216,7 +218,7 @@ public class MovementPillar extends Movement {
if (!(fr instanceof BlockAir || fr.isReplaceable(Minecraft.getMinecraft().world, src))) {
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
blockIsThere = false;
} else if (Minecraft.getMinecraft().player.isSneaking()) {
} else if (Minecraft.getMinecraft().player.isSneaking()) { // 1 tick after we're able to place
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
}
@@ -238,7 +240,7 @@ public class MovementPillar extends Movement {
state.setInput(InputOverrideHandler.Input.SNEAK, true);
}
}
if (BlockStateInterface.isWater(dest.up())) {
if (MovementHelper.isWater(dest.up())) {
return true;
}
return super.prepared(state);
@@ -19,16 +19,13 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.*;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -69,7 +66,7 @@ public class MovementTraverse extends Movement {
if (MovementHelper.canWalkOn(destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
double WC = WALK_ONE_BLOCK_COST;
boolean water = false;
if (BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock())) {
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
WC = context.waterWalkSpeed();
water = true;
} else {
@@ -104,18 +101,18 @@ public class MovementTraverse extends Movement {
return COST_INF;
}
if (destOn.getBlock().equals(Blocks.AIR) || MovementHelper.isReplacable(destX, y - 1, destZ, destOn)) {
boolean throughWater = BlockStateInterface.isWater(pb0.getBlock()) || BlockStateInterface.isWater(pb1.getBlock());
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
return COST_INF;
}
if (!context.hasThrowaway()) {
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
return COST_INF;
}
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb0, false);
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb1, false);
if (hardness1 >= COST_INF) {
return COST_INF;
}
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb1, true);
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true);
double WC = throughWater ? context.waterWalkSpeed() : WALK_ONE_BLOCK_COST;
for (int i = 0; i < 4; i++) {
@@ -169,7 +166,7 @@ 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
// 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())).getYaw();
float yawToDest = RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(dest)).getYaw();
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
@@ -192,11 +189,9 @@ public class MovementTraverse extends Movement {
} else if (pb1.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(dest, src)) {
isDoorActuallyBlockingUs = true;
}
if (isDoorActuallyBlockingUs) {
if (!(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
return state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(positionsToBreak[0], world())), true))
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(positionsToBreak[0])), true))
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
}
@@ -209,7 +204,7 @@ public class MovementTraverse extends Movement {
}
if (blocked != null) {
return state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(blocked, world())), true))
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(blocked)), true))
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
}
@@ -228,7 +223,7 @@ public class MovementTraverse extends Movement {
if (playerFeet().equals(dest)) {
return state.setStatus(MovementStatus.SUCCESS);
}
if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) {
if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(playerFeet())) {
state.setInput(InputOverrideHandler.Input.SPRINT, true);
}
Block destDown = BlockStateInterface.get(dest.down()).getBlock();
@@ -267,16 +262,13 @@ public class MovementTraverse extends Movement {
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + against1.getY()) * 0.5D;
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get())) {
if (LookBehaviorUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
// wrong side?
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get()) && RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
System.out.println("Trying to look at " + against1 + ", actually looking at" + LookBehaviorUtils.getSelectedBlock());
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
return state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
}
}
@@ -296,18 +288,18 @@ public class MovementTraverse extends Movement {
// faceX, faceY, faceZ is the middle of the face between from and to
BlockPos goalLook = src.down(); // this is the block we were just standing on, and the one we want to place against
Rotation backToFace = Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
Rotation backToFace = RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
float pitch = backToFace.getPitch();
double dist = Math.max(Math.abs(player().posX - faceX), Math.abs(player().posZ - faceZ));
if (dist < 0.29) {
float yaw = Utils.calcRotationFromVec3d(Utils.getBlockPosCenter(dest), playerHead(), playerRotations()).getYaw();
float yaw = RotationUtils.calcRotationFromVec3d(VecUtils.getBlockPosCenter(dest), playerHead(), playerRotations()).getYaw();
state.setTarget(new MovementState.MovementTarget(new Rotation(yaw, pitch), true));
state.setInput(InputOverrideHandler.Input.MOVE_BACK, true);
} else {
state.setTarget(new MovementState.MovementTarget(backToFace, true));
}
state.setInput(InputOverrideHandler.Input.SNEAK, true);
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), goalLook)) {
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), goalLook)) {
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true); // wait to right click until we are able to place
}
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
@@ -18,18 +18,21 @@
package baritone.pathing.path;
import baritone.Baritone;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.pathing.path.IPathExecutor;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.VecUtils;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.movements.*;
import baritone.utils.*;
import baritone.utils.BlockBreakHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import net.minecraft.init.Blocks;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
@@ -77,14 +80,10 @@ public class PathExecutor implements IPathExecutor, Helper {
/**
* Tick this executor
*
* @param event
* @return True if a movement just finished (and the player is therefore in a "stable" state, like,
* not sneaking out over lava), false otherwise
*/
public boolean onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
throw new IllegalStateException();
}
public boolean onTick() {
if (pathPosition == path.length() - 1) {
pathPosition++;
}
@@ -122,7 +121,7 @@ public class PathExecutor implements IPathExecutor, Helper {
if (i - pathPosition > 2) {
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
}
System.out.println("Double skip sundae");
//System.out.println("Double skip sundae");
pathPosition = i - 1;
onChangeInPathPosition();
return false;
@@ -257,7 +256,7 @@ public class PathExecutor implements IPathExecutor, Helper {
//System.out.println("Movement done, next path");
pathPosition++;
onChangeInPathPosition();
onTick(event);
onTick();
return true;
} else {
sprintIfRequested();
@@ -272,14 +271,14 @@ public class PathExecutor implements IPathExecutor, Helper {
return true;
}
}
return false; // movement is in progress
return canCancel; // movement is in progress, but if it reports cancellable, PathingBehavior is good to cut onto the next path
}
private Tuple<Double, BlockPos> closestPathPos(IPath path) {
double best = -1;
BlockPos bestPos = null;
for (BlockPos pos : path.positions()) {
double dist = Utils.playerDistanceToCenter(pos);
double dist = VecUtils.entityDistanceToCenter(player(), pos);
if (dist < best || best == -1) {
best = dist;
bestPos = pos;
@@ -327,10 +326,7 @@ public class PathExecutor implements IPathExecutor, Helper {
// when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path
if (path.movements().get(pathPosition) instanceof MovementFall) {
BlockPos fallDest = path.positions().get(pathPosition + 1); // .get(pathPosition) is the block we fell off of
if (Utils.playerFlatDistanceToCenter(fallDest) < leniency) { // ignore Y by using flat distance
return false;
}
return true;
return VecUtils.entityFlatDistanceToCenter(player(), fallDest) >= leniency; // ignore Y by using flat distance
} else {
return true;
}
@@ -428,20 +424,13 @@ public class PathExecutor implements IPathExecutor, Helper {
}
private static boolean canSprintInto(IMovement current, IMovement next) {
if (next instanceof MovementDescend) {
if (next.getDirection().equals(current.getDirection())) {
return true;
}
}
if (next instanceof MovementTraverse) {
if (next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
return true;
}
}
if (next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get()) {
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
return true;
}
return false;
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(next.getDest().down())) {
return true;
}
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get();
}
private void onChangeInPathPosition() {
@@ -17,11 +17,11 @@
package baritone.utils;
import baritone.Baritone;
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;
@@ -105,8 +105,8 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
}
// Setup Baritone's pathing goal and (if needed) begin pathing
PathingBehavior.INSTANCE.setGoal(GOAL);
PathingBehavior.INSTANCE.path();
Baritone.INSTANCE.getPathingBehavior().setGoal(GOAL);
Baritone.INSTANCE.getPathingBehavior().path();
// If we have reached our goal, print a message and safely close the game
if (GOAL.isInGoal(playerFeet())) {
@@ -22,7 +22,6 @@ import baritone.cache.CachedRegion;
import baritone.cache.WorldData;
import baritone.cache.WorldProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
@@ -38,7 +37,7 @@ public class BlockStateInterface implements Helper {
private static Chunk prev = null;
private static CachedRegion prevCached = null;
private static IBlockState AIR = Blocks.AIR.getDefaultState();
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
public static IBlockState get(BlockPos pos) {
return get(pos.getX(), pos.getY(), pos.getZ());
@@ -128,47 +127,4 @@ public class BlockStateInterface implements Helper {
public static Block getBlock(int x, int y, int z) {
return get(x, y, z).getBlock();
}
/**
* Returns whether or not the specified block is
* water, regardless of whether or not it is flowing.
*
* @param b The block
* @return Whether or not the block is water
*/
public static boolean isWater(Block b) {
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
}
/**
* Returns whether or not the block at the specified pos is
* water, regardless of whether or not it is flowing.
*
* @param bp The block pos
* @return Whether or not the block is water
*/
public static boolean isWater(BlockPos bp) {
return isWater(BlockStateInterface.getBlock(bp));
}
public static boolean isLava(Block b) {
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
}
/**
* Returns whether or not the specified pos has a liquid
*
* @param p The pos
* @return Whether or not the block is a liquid
*/
public static boolean isLiquid(BlockPos p) {
return BlockStateInterface.getBlock(p) instanceof BlockLiquid;
}
public static boolean isFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getPropertyKeys().contains(BlockLiquid.LEVEL)
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
}
@@ -23,17 +23,15 @@ import baritone.api.cache.IWaypoint;
import baritone.api.event.events.ChatEvent;
import baritone.api.pathing.goals.*;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.SettingsUtil;
import baritone.behavior.Behavior;
import baritone.behavior.FollowBehavior;
import baritone.behavior.MineBehavior;
import baritone.behavior.PathingBehavior;
import baritone.cache.ChunkPacker;
import baritone.cache.Waypoint;
import baritone.cache.WorldProvider;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.Moves;
import net.minecraft.block.Block;
import net.minecraft.client.multiplayer.ChunkProviderClient;
@@ -48,47 +46,83 @@ import java.util.stream.Stream;
public class ExampleBaritoneControl extends Behavior implements Helper {
public static ExampleBaritoneControl INSTANCE = new ExampleBaritoneControl();
public static ExampleBaritoneControl INSTANCE; // compatibility with impact 4.4
private ExampleBaritoneControl() {
private static final String HELP_MSG =
"baritone - Output settings into chat\n" +
"settings - Same as baritone\n" +
"goal - Create a goal (one number is '<Y>', two is '<X> <Z>', three is '<X> <Y> <Z>, 'clear' to clear)\n" +
"path - Go towards goal\n" +
"repack - (debug) Repacks chunk cache\n" +
"rescan - (debug) Same as repack\n" +
"axis - Paths towards the closest axis or diagonal axis, at y=120\n" +
"cancel - Cancels current path\n" +
"forcecancel - sudo cancel (only use if very glitched, try toggling 'pause' first)\n" +
"gc - Calls System.gc();\n" +
"invert - Runs away from the goal instead of towards it\n" +
"follow - Follows a player 'follow username'\n" +
"reloadall - (debug) Reloads chunk cache\n" +
"saveall - (debug) Saves chunk cache\n" +
"find - (debug) outputs how many blocks of a certain type are within the cache\n" +
"mine - Paths to and mines specified blocks 'mine x_ore y_ore ...'\n" +
"thisway - Creates a goal X blocks where you're facing\n" +
"list - Lists waypoints under a category\n" +
"get - Same as list\n" +
"show - Same as list\n" +
"save - Saves a waypoint (works but don't try to make sense of it)\n" +
"goto - Paths towards specified block or waypoint\n" +
"spawn - Paths towards world spawn or your most recent bed right-click\n" +
"sethome - Sets \"home\"\n" +
"home - Paths towards \"home\" \n" +
"costs - (debug) all movement costs from current location\n" +
"pause - Toggle pause\n" +
"damn - Daniel ";
}
public void initAndRegister() {
Baritone.INSTANCE.registerBehavior(this);
public ExampleBaritoneControl(Baritone baritone) {
super(baritone);
INSTANCE = this;
}
@Override
public void onSendChatMessage(ChatEvent event) {
if (!Baritone.settings().chatControl.get()) {
if (!Baritone.settings().removePrefix.get()) {
return;
}
if (!Baritone.settings().chatControl.get() && !Baritone.settings().removePrefix.get()) {
return;
}
String msg = event.getMessage().toLowerCase(Locale.US);
String msg = event.getMessage();
if (Baritone.settings().prefix.get()) {
if (!msg.startsWith("#")) {
return;
}
msg = msg.substring(1);
}
if (runCommand(msg)) {
event.cancel();
}
}
public boolean runCommand(String msg0) {
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
List<Settings.Setting<Boolean>> toggleable = Baritone.settings().getAllValuesByType(Boolean.class);
for (Settings.Setting<Boolean> setting : toggleable) {
if (msg.equalsIgnoreCase(setting.getName())) {
setting.value ^= true;
event.cancel();
logDirect("Toggled " + setting.getName() + " to " + setting.value);
SettingsUtil.save(Baritone.settings());
return;
return true;
}
}
if (msg.equals("baritone") || msg.equals("settings")) {
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
logDirect(setting.toString());
}
event.cancel();
return;
return true;
}
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
for (String line : HELP_MSG.split("\n")) {
logDirect(line);
}
return false;
}
if (msg.contains(" ")) {
String[] data = msg.split(" ");
@@ -110,25 +144,21 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
} catch (NumberFormatException e) {
logDirect("Unable to parse " + data[1]);
event.cancel();
return;
return true;
}
SettingsUtil.save(Baritone.settings());
logDirect(setting.toString());
event.cancel();
return;
return true;
}
}
}
if (Baritone.settings().byLowerName.containsKey(msg)) {
Settings.Setting<?> setting = Baritone.settings().byLowerName.get(msg);
logDirect(setting.toString());
event.cancel();
return;
return true;
}
if (msg.startsWith("goal")) {
event.cancel();
String[] params = msg.substring(4).trim().split(" ");
if (params[0].equals("")) {
params = new String[]{};
@@ -154,30 +184,29 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
break;
default:
logDirect("unable to understand lol");
return;
return true;
}
} catch (NumberFormatException ex) {
logDirect("unable to parse integer " + ex);
return;
return true;
}
PathingBehavior.INSTANCE.setGoal(goal);
pathingBehavior.setGoal(goal);
logDirect("Goal: " + goal);
return;
return true;
}
if (msg.equals("path")) {
if (!PathingBehavior.INSTANCE.path()) {
if (PathingBehavior.INSTANCE.getGoal() == null) {
if (!pathingBehavior.path()) {
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
} else {
if (PathingBehavior.INSTANCE.getGoal().isInGoal(playerFeet())) {
if (pathingBehavior.getGoal().isInGoal(playerFeet())) {
logDirect("Already in goal");
} else {
logDirect("Currently executing a path. Please cancel it first.");
}
}
}
event.cancel();
return;
return true;
}
if (msg.equals("repack") || msg.equals("rescan")) {
ChunkProviderClient cli = world().getChunkProvider();
@@ -194,41 +223,36 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
}
logDirect("Queued " + count + " chunks for repacking");
event.cancel();
return;
return true;
}
if (msg.equals("axis")) {
PathingBehavior.INSTANCE.setGoal(new GoalAxis());
PathingBehavior.INSTANCE.path();
event.cancel();
return;
pathingBehavior.setGoal(new GoalAxis());
pathingBehavior.path();
return true;
}
if (msg.equals("cancel") || msg.equals("stop")) {
MineBehavior.INSTANCE.cancel();
FollowBehavior.INSTANCE.cancel();
PathingBehavior.INSTANCE.cancel();
event.cancel();
baritone.getMineBehavior().cancel();
baritone.getFollowBehavior().cancel();
pathingBehavior.cancel();
logDirect("ok canceled");
return;
return true;
}
if (msg.equals("forcecancel")) {
MineBehavior.INSTANCE.cancel();
FollowBehavior.INSTANCE.cancel();
PathingBehavior.INSTANCE.cancel();
baritone.getMineBehavior().cancel();
baritone.getFollowBehavior().cancel();
pathingBehavior.cancel();
AbstractNodeCostSearch.forceCancel();
PathingBehavior.INSTANCE.forceCancel();
event.cancel();
pathingBehavior.forceCancel();
logDirect("ok force canceled");
return;
return true;
}
if (msg.equals("gc")) {
System.gc();
event.cancel();
logDirect("Called System.gc();");
return;
return true;
}
if (msg.equals("invert")) {
Goal goal = PathingBehavior.INSTANCE.getGoal();
Goal goal = pathingBehavior.getGoal();
BlockPos runAwayFrom;
if (goal instanceof GoalXZ) {
runAwayFrom = new BlockPos(((GoalXZ) goal).getX(), 0, ((GoalXZ) goal).getZ());
@@ -239,54 +263,47 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Inverting goal of player feet");
runAwayFrom = playerFeet();
}
PathingBehavior.INSTANCE.setGoal(new GoalRunAway(1, runAwayFrom) {
pathingBehavior.setGoal(new GoalRunAway(1, runAwayFrom) {
@Override
public boolean isInGoal(BlockPos pos) {
public boolean isInGoal(int x, int y, int z) {
return false;
}
});
if (!PathingBehavior.INSTANCE.path()) {
if (!pathingBehavior.path()) {
logDirect("Currently executing a path. Please cancel it first.");
}
event.cancel();
return;
return true;
}
if (msg.startsWith("follow")) {
String name = msg.substring(6).trim();
Optional<Entity> toFollow = Optional.empty();
if (name.length() == 0) {
toFollow = MovementHelper.whatEntityAmILookingAt();
toFollow = RayTraceUtils.getSelectedEntity();
} else {
for (EntityPlayer pl : world().playerEntities) {
String theirName = pl.getName().trim().toLowerCase();
if (!theirName.equals(player().getName().trim().toLowerCase())) { // don't follow ourselves lol
if (theirName.contains(name) || name.contains(theirName)) {
toFollow = Optional.of(pl);
}
if (!theirName.equals(player().getName().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
toFollow = Optional.of(pl);
}
}
}
if (!toFollow.isPresent()) {
logDirect("Not found");
event.cancel();
return;
return true;
}
FollowBehavior.INSTANCE.follow(toFollow.get());
baritone.getFollowBehavior().follow(toFollow.get());
logDirect("Following " + toFollow.get());
event.cancel();
return;
return true;
}
if (msg.equals("reloadall")) {
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().reloadAllFromDisk();
logDirect("ok");
event.cancel();
return;
return true;
}
if (msg.equals("saveall")) {
WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().save();
logDirect("ok");
event.cancel();
return;
return true;
}
if (msg.startsWith("find")) {
String blockType = msg.substring(4).trim();
@@ -298,8 +315,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
System.out.println("Was looking for " + blockType + " but actually found " + actually + " " + ChunkPacker.blockToString(actually));
}
}
event.cancel();
return;
return true;
}
if (msg.startsWith("mine")) {
String[] blockTypes = msg.substring(4).trim().split(" ");
@@ -307,34 +323,30 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
int quantity = Integer.parseInt(blockTypes[1]);
Block block = ChunkPacker.stringToBlock(blockTypes[0]);
Objects.requireNonNull(block);
MineBehavior.INSTANCE.mine(quantity, block);
baritone.getMineBehavior().mine(quantity, block);
logDirect("Will mine " + quantity + " " + blockTypes[0]);
event.cancel();
return;
return true;
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
for (String s : blockTypes) {
if (ChunkPacker.stringToBlock(s) == null) {
logDirect(s + " isn't a valid block name");
event.cancel();
return;
return true;
}
}
MineBehavior.INSTANCE.mine(0, blockTypes);
baritone.getMineBehavior().mine(0, blockTypes);
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
event.cancel();
return;
return true;
}
if (msg.startsWith("thisway")) {
try {
Goal goal = GoalXZ.fromDirection(playerFeetAsVec(), player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
PathingBehavior.INSTANCE.setGoal(goal);
pathingBehavior.setGoal(goal);
logDirect("Goal: " + goal);
} catch (NumberFormatException ex) {
logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double.");
}
event.cancel();
return;
return true;
}
if (msg.startsWith("list") || msg.startsWith("get ") || msg.startsWith("show")) {
String waypointType = msg.substring(4).trim();
@@ -345,8 +357,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
Waypoint.Tag tag = Waypoint.Tag.fromString(waypointType);
if (tag == null) {
logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
event.cancel();
return;
return true;
}
Set<IWaypoint> waypoints = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getByTag(tag);
// might as well show them from oldest to newest
@@ -356,11 +367,9 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
for (IWaypoint waypoint : sorted) {
logDirect(waypoint.toString());
}
event.cancel();
return;
return true;
}
if (msg.startsWith("save")) {
event.cancel();
String name = msg.substring(4).trim();
BlockPos pos = playerFeet();
if (name.contains(" ")) {
@@ -368,19 +377,19 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
String[] parts = name.split(" ");
if (parts.length != 4) {
logDirect("Unable to parse, expected four things");
return;
return true;
}
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;
return true;
}
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;
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
return true;
}
if (msg.startsWith("goto")) {
String waypointType = msg.substring(4).trim();
@@ -394,40 +403,35 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
String mining = waypointType;
Block block = ChunkPacker.stringToBlock(mining);
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
event.cancel();
if (block == null) {
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;
return true;
}
} else {
List<BlockPos> locs = MineBehavior.INSTANCE.scanFor(Collections.singletonList(block), 64);
List<BlockPos> locs = baritone.getMineBehavior().searchWorld(Collections.singletonList(block), 64, world());
if (locs.isEmpty()) {
logDirect("No locations for " + mining + " known, cancelling");
return;
return true;
}
PathingBehavior.INSTANCE.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
PathingBehavior.INSTANCE.path();
return;
pathingBehavior.setGoal(new GoalComposite(locs.stream().map(GoalGetToBlock::new).toArray(Goal[]::new)));
pathingBehavior.path();
return true;
}
} else {
waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(tag);
if (waypoint == null) {
logDirect("None saved for tag " + tag);
event.cancel();
return;
return true;
}
}
Goal goal = new GoalBlock(waypoint.getLocation());
PathingBehavior.INSTANCE.setGoal(goal);
if (!PathingBehavior.INSTANCE.path()) {
if (!goal.isInGoal(playerFeet())) {
logDirect("Currently executing a path. Please cancel it first.");
}
pathingBehavior.setGoal(goal);
if (!pathingBehavior.path() && !goal.isInGoal(playerFeet())) {
logDirect("Currently executing a path. Please cancel it first.");
}
event.cancel();
return;
return true;
}
if (msg.equals("spawn") || msg.equals("bed")) {
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.BED);
@@ -436,20 +440,18 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
// for some reason the default spawnpoint is underground sometimes
Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ());
logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal);
PathingBehavior.INSTANCE.setGoal(goal);
pathingBehavior.setGoal(goal);
} else {
Goal goal = new GoalBlock(waypoint.getLocation());
PathingBehavior.INSTANCE.setGoal(goal);
pathingBehavior.setGoal(goal);
logDirect("Set goal to most recent bed " + goal);
}
event.cancel();
return;
return true;
}
if (msg.equals("sethome")) {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", Waypoint.Tag.HOME, playerFeet()));
logDirect("Saved. Say home to set goal.");
event.cancel();
return;
return true;
}
if (msg.equals("home")) {
IWaypoint waypoint = WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().getMostRecentByTag(Waypoint.Tag.HOME);
@@ -457,12 +459,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("home not saved");
} else {
Goal goal = new GoalBlock(waypoint.getLocation());
PathingBehavior.INSTANCE.setGoal(goal);
PathingBehavior.INSTANCE.path();
pathingBehavior.setGoal(goal);
pathingBehavior.path();
logDirect("Going to saved home " + goal);
}
event.cancel();
return;
return true;
}
if (msg.equals("costs")) {
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(playerFeet())).collect(Collectors.toCollection(ArrayList::new));
@@ -479,18 +480,16 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost);
}
event.cancel();
return;
return true;
}
if (msg.equals("pause")) {
boolean enabled = PathingBehavior.INSTANCE.toggle();
boolean enabled = pathingBehavior.toggle();
logDirect("Pathing Behavior has " + (enabled ? "resumed" : "paused") + ".");
event.cancel();
return;
return true;
}
if (msg.equals("damn")) {
logDirect("daniel");
return;
}
return false;
}
}
+2 -2
View File
@@ -86,8 +86,8 @@ public interface Helper {
*/
default void logDebug(String message) {
if (!Baritone.settings().chatDebug.get()) {
System.out.println("Suppressed debug message:");
System.out.println(message);
//System.out.println("Suppressed debug message:");
//System.out.println(message);
return;
}
logDirect(message);
+114 -58
View File
@@ -23,41 +23,41 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.init.Enchantments;
import net.minecraft.init.MobEffects;
import net.minecraft.item.Item.ToolMaterial;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* A cached list of the best tools on the hotbar for any block
*
* @author avecowa, Brady, leijurv
* @author Avery, Brady, leijurv
*/
public class ToolSet implements Helper {
/**
* A cache mapping a {@link Block} to how long it will take to break
* with this toolset, given the optimum tool is used.
*/
private Map<Block, Double> breakStrengthCache = new HashMap<>();
private final Map<Block, Double> breakStrengthCache;
/**
* Calculate which tool on the hotbar is best for mining
*
* @param b the blockstate to be mined
* @return a byte indicating the index in the tools array that worked best
* My buddy leijurv owned me so we have this to not create a new lambda instance.
*/
public byte getBestSlot(IBlockState b) {
byte best = 0;
double value = -1;
for (byte i = 0; i < 9; i++) {
double v = calculateStrVsBlock(i, b);
if (v > value || value == -1) {
value = v;
best = i;
}
private final Function<Block, Double> backendCalculation;
public ToolSet() {
breakStrengthCache = new HashMap<>();
if (Baritone.settings().considerPotionEffects.get()) {
double amplifier = potionAmplifier();
Function<Double, Double> amplify = x -> amplifier * x;
backendCalculation = amplify.compose(this::getBestDestructionTime);
} else {
backendCalculation = this::getBestDestructionTime;
}
return best;
}
/**
@@ -67,14 +67,64 @@ public class ToolSet implements Helper {
* @return how long it would take in ticks
*/
public double getStrVsBlock(IBlockState state) {
Double strength = this.breakStrengthCache.get(state.getBlock());
if (strength != null) {
// the function will take this path >99% of the time
return strength;
return breakStrengthCache.computeIfAbsent(state.getBlock(), backendCalculation);
}
/**
* Evaluate the material cost of a possible tool. The priority matches the
* listed order in the Item.ToolMaterial enum.
*
* @param itemStack a possibly empty ItemStack
* @return values range from -1 to 4
*/
private int getMaterialCost(ItemStack itemStack) {
if (itemStack.getItem() instanceof ItemTool) {
ItemTool tool = (ItemTool) itemStack.getItem();
return ToolMaterial.valueOf(tool.getToolMaterialName()).ordinal();
} else {
return -1;
}
double str = calculateStrVsBlock(getBestSlot(state), state);
this.breakStrengthCache.put(state.getBlock(), str);
return str;
}
/**
* Calculate which tool on the hotbar is best for mining
*
* @param b the blockstate to be mined
* @return A byte containing the index in the tools array that worked best
*/
public byte getBestSlot(Block b) {
byte best = 0;
double value = Double.NEGATIVE_INFINITY;
int materialCost = Integer.MIN_VALUE;
IBlockState blockState = b.getDefaultState();
for (byte i = 0; i < 9; i++) {
ItemStack itemStack = player().inventory.getStackInSlot(i);
double v = calculateStrVsBlock(itemStack, blockState);
if (v > value) {
value = v;
best = i;
materialCost = getMaterialCost(itemStack);
} else if (v == value) {
int c = getMaterialCost(itemStack);
if (c < materialCost) {
value = v;
best = i;
materialCost = c;
}
}
}
return best;
}
/**
* Calculate how effectively a block can be destroyed
*
* @param b the blockstate to be mined
* @return A double containing the destruction ticks with the best tool
*/
private double getBestDestructionTime(Block b) {
ItemStack stack = player().inventory.getStackInSlot(getBestSlot(b));
return calculateStrVsBlock(stack, b.getDefaultState());
}
/**
@@ -84,49 +134,55 @@ public class ToolSet implements Helper {
* @param state the blockstate to be mined
* @return how long it would take in ticks
*/
private double calculateStrVsBlock(byte slot, IBlockState state) {
// Calculate the slot with the best item
ItemStack contents = player().inventory.getStackInSlot(slot);
float blockHard = state.getBlockHardness(null, null);
if (blockHard < 0) {
private double calculateStrVsBlock(ItemStack item, IBlockState state) {
float hardness = state.getBlockHardness(null, null);
if (hardness < 0) {
return -1;
}
float speed = contents.getDestroySpeed(state);
float speed = item.getDestroySpeed(state);
if (speed > 1) {
int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, contents);
if (effLevel > 0 && !contents.isEmpty()) {
int effLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, item);
if (effLevel > 0 && !item.isEmpty()) {
speed += effLevel * effLevel + 1;
}
}
if (Baritone.settings().considerPotionEffects.get()) {
if (player().isPotionActive(MobEffects.HASTE)) {
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
}
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
case 0:
speed *= 0.3;
break;
case 1:
speed *= 0.09;
break;
case 2:
speed *= 0.0027;
break;
default:
speed *= 0.00081;
break;
}
}
}
speed /= blockHard;
if (state.getMaterial().isToolNotRequired() || (!contents.isEmpty() && contents.canHarvestBlock(state))) {
return speed / 30;
speed /= hardness;
if (state.getMaterial().isToolNotRequired() || (!item.isEmpty() && item.canHarvestBlock(state))) {
speed /= 30;
} else {
return speed / 100;
speed /= 100;
}
return speed;
}
/**
* Calculates any modifier to breaking time based on status effects.
*
* @return a double to scale block breaking speed.
*/
private double potionAmplifier() {
double speed = 1;
if (player().isPotionActive(MobEffects.HASTE)) {
speed *= 1 + (player().getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2;
}
if (player().isPotionActive(MobEffects.MINING_FATIGUE)) {
switch (player().getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) {
case 0:
speed *= 0.3;
break;
case 1:
speed *= 0.09;
break;
case 2:
speed *= 0.0027;
break;
default:
speed *= 0.00081;
break;
}
}
return speed;
}
}
-133
View File
@@ -1,133 +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.utils;
import baritone.api.utils.Rotation;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import static baritone.utils.Helper.HELPER;
/**
* @author Brady
* @since 8/1/2018 12:56 AM
*/
public final class Utils {
/**
* Constant that a degree value is multiplied by to get the equivalent radian value
*/
public static final double DEG_TO_RAD = Math.PI / 180.0;
/**
* Constant that a radian value is multiplied by to get the equivalent degree value
*/
public static final double RAD_TO_DEG = 180.0 / Math.PI;
public static Rotation calcRotationFromCoords(BlockPos orig, BlockPos dest) {
return calcRotationFromVec3d(vec3dFromBlockPos(orig), vec3dFromBlockPos(dest));
}
/**
* Calculates rotation to given Vec<sub>dest</sub> from Vec<sub>orig</sub>
*
* @param orig
* @param dest
* @return Rotation {@link Rotation}
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
double yaw = MathHelper.atan2(delta[0], -delta[2]);
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
double pitch = MathHelper.atan2(delta[1], dist);
return new Rotation(
(float) radToDeg(yaw),
(float) radToDeg(pitch)
);
}
/**
* Calculates rotation to given Vec<sub>dest</sub> from Vec<sub>orig</sub>
*
* @param orig
* @param dest
* @return Rotation {@link Rotation}
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest, Rotation current) {
return wrapAnglesToRelative(current, calcRotationFromVec3d(orig, dest));
}
public static Vec3d calcCenterFromCoords(BlockPos orig, World world) {
IBlockState b = BlockStateInterface.get(orig);
AxisAlignedBB bbox = b.getBoundingBox(world, orig);
double xDiff = (bbox.minX + bbox.maxX) / 2;
double yDiff = (bbox.minY + bbox.maxY) / 2;
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
yDiff = 0;
}
return new Vec3d(
orig.getX() + xDiff,
orig.getY() + yDiff,
orig.getZ() + zDiff
);
}
public static Vec3d getBlockPosCenter(BlockPos pos) {
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
}
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
return target.subtract(current).normalize().add(current);
}
public static Vec3d vec3dFromBlockPos(BlockPos orig) {
return new Vec3d(orig.getX() + 0.0D, orig.getY() + 0.0D, orig.getZ() + 0.0D);
}
public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
double xdiff = x - (pos.getX() + 0.5D);
double ydiff = y - (pos.getY() + 0.5D);
double zdiff = z - (pos.getZ() + 0.5D);
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
}
public static double playerDistanceToCenter(BlockPos pos) {
EntityPlayerSP player = HELPER.player();
return distanceToCenter(pos, player.posX, player.posY, player.posZ);
}
public static double playerFlatDistanceToCenter(BlockPos pos) {
EntityPlayerSP player = HELPER.player();
return distanceToCenter(pos, player.posX, pos.getY() + 0.5, player.posZ);
}
public static double degToRad(double deg) {
return deg * DEG_TO_RAD;
}
public static double radToDeg(double rad) {
return rad * RAD_TO_DEG;
}
}
@@ -0,0 +1,46 @@
/*
* 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 baritone.utils.Helper;
import net.minecraft.world.border.WorldBorder;
public class BetterWorldBorder implements Helper {
private final double minX;
private final double maxX;
private final double minZ;
private final double maxZ;
public BetterWorldBorder(WorldBorder border) {
this.minX = border.minX();
this.maxX = border.maxX();
this.minZ = border.minZ();
this.maxZ = border.maxZ();
}
public boolean entirelyContains(int x, int z) {
return x + 1 > minX && x < maxX && z + 1 > minZ && z < maxZ;
}
public boolean canPlaceAt(int x, int z) {
// move it in 1 block on all sides
// because we can't place a block at the very edge against a block outside the border
// it won't let us right click it
return x > minX && x + 1 < maxX && z > minZ && z + 1 < maxZ;
}
}