Compare commits
302 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89fb5cecd5 | |||
| a75317cc2c | |||
| ee6df270ce | |||
| e09541151f | |||
| 74e0552be0 | |||
| 909ab553eb | |||
| 866408aece | |||
| 2215f170df | |||
| a5601fd89a | |||
| fa8f2632f5 | |||
| 52d8d271f1 | |||
| b240e8420a | |||
| 25024b58de | |||
| ba31d209c9 | |||
| 7974d9135b | |||
| a5a795a22c | |||
| 416b5b66d2 | |||
| 88e41f37b1 | |||
| 7cfa837604 | |||
| 6b7aca3081 | |||
| 580af2ab06 | |||
| d144d30890 | |||
| ecac546c6d | |||
| 76297e8176 | |||
| d90f391b5e | |||
| d80ae57964 | |||
| 74d7483b3c | |||
| b3c580e657 | |||
| 8050b69f2f | |||
| 459720c348 | |||
| a73f5c1359 | |||
| 71cb0f6d36 | |||
| 0d15225b1d | |||
| 826f3788d0 | |||
| 2133ab39b7 | |||
| 558c14a375 | |||
| 882ac41291 | |||
| 66c7a3f513 | |||
| 5904441a7e | |||
| c465228531 | |||
| 81b22019dd | |||
| 3e47d485f9 | |||
| 701bc772a8 | |||
| 3ae05b7348 | |||
| 2e186019f5 | |||
| 4c6f321cff | |||
| c72eb3e195 | |||
| a4237bf1f9 | |||
| e767e34b92 | |||
| 8ac82ebe2a | |||
| 0ed6ccab71 | |||
| bf25d7328e | |||
| a47b0c0581 | |||
| 596849c7e6 | |||
| 76914b7859 | |||
| 3dbbe053d7 | |||
| c474cdb1f8 | |||
| 3de02cbf21 | |||
| 26fefc70f0 | |||
| 4086c9f4b5 | |||
| c947c77853 | |||
| 9be44c0371 | |||
| 5412fa6cfd | |||
| 6e7320b954 | |||
| fbb2d37634 | |||
| 7afe16fc10 | |||
| b19f241d81 | |||
| 583ce80003 | |||
| 195c33407e | |||
| 600c5b77ad | |||
| f1084fab76 | |||
| bd65e32407 | |||
| e4416f424a | |||
| 73ec110b22 | |||
| 0bce801a3f | |||
| e8e00e8dfb | |||
| cc4335e48e | |||
| 5427911da3 | |||
| c808d5a42d | |||
| 3b46dbd6a1 | |||
| e63b2f1bf1 | |||
| d32e822057 | |||
| 2b672998e1 | |||
| e18dc7c7e7 | |||
| 16dcd2f44d | |||
| eb9f755b54 | |||
| 29a9e6e1d1 | |||
| 1f52f706ed | |||
| bf12763a10 | |||
| 963641a818 | |||
| 3e94d92fbd | |||
| a72040f83d | |||
| 84d8f826ff | |||
| 70d216b29f | |||
| 66356d5334 | |||
| d9625dfe78 | |||
| 6d847577d8 | |||
| 8fd687f9d7 | |||
| f7a9380b9d | |||
| 5617c595b2 | |||
| 8770524679 | |||
| a8ddb2fcf1 | |||
| 76c4ca9ba6 | |||
| ed2b0f0bb9 | |||
| 6702b44b3e | |||
| c486d8241e | |||
| d2bb8c374e | |||
| 530cecea5b | |||
| 266e2dada9 | |||
| ce73d34627 | |||
| 11af0a7aac | |||
| 46c2d8f7c7 | |||
| 38127011fb | |||
| 89b5ce4b63 | |||
| 4fe9c180d5 | |||
| f094e83e4d | |||
| 5b6c9fc348 | |||
| 3f1ee100bf | |||
| 41b1106c72 | |||
| b27d95a615 | |||
| 5b8a83853d | |||
| d0548b2715 | |||
| bffeb9c862 | |||
| dbd760fbcb | |||
| a84b3bfc7a | |||
| e8d3bf509c | |||
| b2583773d5 | |||
| 9ecd24c755 | |||
| f1bacd6210 | |||
| a21ec54d4f | |||
| 0b4efb24ae | |||
| c473914d05 | |||
| 90a1fa8337 | |||
| 99cb7f5142 | |||
| 4026b850f8 | |||
| aac7ebf6dd | |||
| 8d481ba394 | |||
| 24fa75c24e | |||
| cf38d593b8 | |||
| 36f608c63c | |||
| 1d88564a72 | |||
| 503f2fb197 | |||
| bb000c4e3f | |||
| 4868ed7560 | |||
| 7017e9e2ea | |||
| a18eb90702 | |||
| 9d1d4fe0d9 | |||
| 1a430dc2cf | |||
| e37a09a1c8 | |||
| d0d8b12fb8 | |||
| 9a29f9ce57 | |||
| 42513e4b56 | |||
| 67fa91abe8 | |||
| d8348ad292 | |||
| 6faa7344aa | |||
| 299540725e | |||
| 0ef08142fd | |||
| c0761c0eef | |||
| 8694d926c4 | |||
| 46f8829951 | |||
| 4c4bce3561 | |||
| 68e8717b5c | |||
| b484e6fa3f | |||
| aa8773a67e | |||
| a822d3ef05 | |||
| 311cf81e8a | |||
| bf9ee918f3 | |||
| 92ba76e7a1 | |||
| 3326339263 | |||
| 52cafbc7aa | |||
| efb316de14 | |||
| 3cf944398f | |||
| d2bfd47039 | |||
| 920cb6556b | |||
| cd3ae2a7f5 | |||
| b12fedb2d9 | |||
| 1cae7ad6b1 | |||
| 7dd881aa9a | |||
| c7ad235110 | |||
| a989547976 | |||
| fa75880626 | |||
| 529895f970 | |||
| 3d5de440fd | |||
| 568bb1b0e8 | |||
| b9ae8306dd | |||
| 4aededff46 | |||
| ed8f9863e3 | |||
| e85de55c8f | |||
| adbf927270 | |||
| dfe171a5c2 | |||
| b55e449398 | |||
| 62b11c0a8a | |||
| 90cb11f55e | |||
| 40a66b0306 | |||
| 8c899698e0 | |||
| 58fa1571f3 | |||
| 2cbe77aa04 | |||
| a0c2935580 | |||
| 798f25ff81 | |||
| 57b2e360ca | |||
| ee23d59e11 | |||
| 04e7da9b73 | |||
| 5382d265f2 | |||
| 0e1534613c | |||
| d799fac688 | |||
| 913247996e | |||
| dc3bab26de | |||
| 5c1cf050e2 | |||
| 747bee41b7 | |||
| 246c00c773 | |||
| 272dd79426 | |||
| b953da0341 | |||
| c2a6445c9e | |||
| b177ae7ee6 | |||
| 22bd5be5a9 | |||
| 90fa347fc2 | |||
| 68a9a1439a | |||
| 8947eff3b1 | |||
| 06b3c5ddb5 | |||
| 5fb8a1d3d1 | |||
| b4d307d4cc | |||
| 306bd18a40 | |||
| 1968f47fc9 | |||
| 9b42aa3634 | |||
| 9faa0ddc62 | |||
| 6a2cd9d3ba | |||
| 9028564c10 | |||
| 8f2b23f8f9 | |||
| b471d7419e | |||
| 5179cfc5ba | |||
| 784b2f541d | |||
| 735cf47c35 | |||
| 056742479e | |||
| 840b7e6987 | |||
| a87772c98c | |||
| c15f1e8276 | |||
| 49148dfb7a | |||
| 177f5de2bd | |||
| 96360ddb24 | |||
| f5f2e4970e | |||
| 742256c130 | |||
| b4a622d319 | |||
| b0c4752397 | |||
| bf78a4dfad | |||
| 8d7841b069 | |||
| 396eaa148c | |||
| 2a244f1e53 | |||
| 847181ada4 | |||
| f274f5a0ef | |||
| bb41883070 | |||
| fca5457ab9 | |||
| 4f355ed4a2 | |||
| b1452c714a | |||
| aba48cca53 | |||
| 772d5fb0cc | |||
| 6b6f8cadb2 | |||
| 82ab79e915 | |||
| 863471b5f1 | |||
| 314f280400 | |||
| b75f4bf9a9 | |||
| 253d67ce78 | |||
| 1753bc18c1 | |||
| eceba13164 | |||
| 3c6c640f50 | |||
| 30e3018966 | |||
| 5ab0bb3c0d | |||
| 0de1517bd8 | |||
| 39c6d81b9e | |||
| 1c1fbe83ec | |||
| ccd56e0368 | |||
| 38c7f226cb | |||
| f5446cc415 | |||
| aa2e680568 | |||
| bc651cb774 | |||
| 20b03d0004 | |||
| b005ce8e6b | |||
| 979b8b2663 | |||
| 69b1decbba | |||
| d32c92cbde | |||
| cef88cde20 | |||
| aa3833915b | |||
| 0c0bbeff27 | |||
| ceda14096c | |||
| d5b393d6bd | |||
| e2cdd6a7f9 | |||
| 261d02e67b | |||
| a6ce4694fc | |||
| 14bc65468a | |||
| 56d109bf0a | |||
| a965859095 | |||
| 863ae447b9 | |||
| 4dd922f1b5 | |||
| f95dc40f4c | |||
| 81786f7a7c | |||
| 1381d8d94c | |||
| 1dca02517e | |||
| b109fc7420 | |||
| c74c01271d | |||
| 702b916948 | |||
| 8ed2431f37 | |||
| c45cbebcce | |||
| 251110c4f8 |
@@ -9,6 +9,7 @@ install:
|
|||||||
- travis_retry docker build -t cabaletta/baritone .
|
- travis_retry docker build -t cabaletta/baritone .
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
- docker run --rm cabaletta/baritone ./gradlew javadoc
|
||||||
- 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 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
|
- docker cp baritone:/code/dist dist
|
||||||
- ls dist
|
- ls dist
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* No Anime
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* Anime
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* ~~Trolling, insulting/derogatory comments, and personal or political attacks~~
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at complaints@leijurv.com. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
||||||
+5
-5
@@ -4,13 +4,14 @@
|
|||||||
- **Block breaking** Baritone considers breaking blocks as part of its path. It also takes into account your current tool set and hot bar. For example, if you have a Eff V diamond pick, it may choose to mine through a stone barrier, while if you only had a wood pick it might be faster to climb over it.
|
- **Block breaking** Baritone considers breaking blocks as part of its path. It also takes into account your current tool set and hot bar. For example, if you have a Eff V diamond pick, it may choose to mine through a stone barrier, while if you only had a wood pick it might be faster to climb over it.
|
||||||
- **Block placing** Baritone considers placing blocks as part of its path. This includes sneak-back-placing, pillaring, etc. It has a configurable penalty of placing a block (set to 1 second by default), to conserve its resources. The list of acceptable throwaway blocks is also configurable, and is cobble, dirt, or netherrack by default. <a href="https://www.youtube.com/watch?v=F6FbI1L9UmU">Example</a>
|
- **Block placing** Baritone considers placing blocks as part of its path. This includes sneak-back-placing, pillaring, etc. It has a configurable penalty of placing a block (set to 1 second by default), to conserve its resources. The list of acceptable throwaway blocks is also configurable, and is cobble, dirt, or netherrack by default. <a href="https://www.youtube.com/watch?v=F6FbI1L9UmU">Example</a>
|
||||||
- **Falling** Baritone will fall up to 3 blocks onto solid ground (configurable, if you have Feather Falling and/or don't mind taking a little damage). If you have a water bucket on your hotbar, it will fall up to 23 blocks and place the bucket beneath it. It will fall an unlimited distance into existing still water.
|
- **Falling** Baritone will fall up to 3 blocks onto solid ground (configurable, if you have Feather Falling and/or don't mind taking a little damage). If you have a water bucket on your hotbar, it will fall up to 23 blocks and place the bucket beneath it. It will fall an unlimited distance into existing still water.
|
||||||
- **Vines and ladders** Baritone understands how to climb and descend vines and ladders. There is experimental support for more advanced maneuvers, like strafing to a different ladder / vine column in midair (off by default, setting named `allowVines`).
|
- **Vines and ladders** Baritone understands how to climb and descend vines and ladders. There is experimental support for more advanced maneuvers, like strafing to a different ladder / vine column in midair (off by default, setting named `allowVines`). Baritone can break its fall by grabbing ladders / vines midair, and understands when that is and isn't possible.
|
||||||
- **Opening fence gates and doors**
|
- **Opening fence gates and doors**
|
||||||
- **Slabs and stairs**
|
- **Slabs and stairs**
|
||||||
- **Falling blocks** Baritone understands the costs of breaking blocks with falling blocks on top, and includes all of their break costs. Additionally, since it avoids breaking any blocks touching a liquid, it won't break the bottom of a gravel stack below a lava lake (anymore).
|
- **Falling blocks** Baritone understands the costs of breaking blocks with falling blocks on top, and includes all of their break costs. Additionally, since it avoids breaking any blocks touching a liquid, it won't break the bottom of a gravel stack below a lava lake (anymore).
|
||||||
- **Avoiding dangerous blocks** Obviously, it knows not to walk through fire or on magma, not to corner over lava (that deals some damage), not to break any blocks touching a liquid (it might drown), etc.
|
- **Avoiding dangerous blocks** Obviously, it knows not to walk through fire or on magma, not to corner over lava (that deals some damage), not to break any blocks touching a liquid (it might drown), etc.
|
||||||
- **Parkour** Sprint jumping over 1, 2, or 3 block gaps
|
- **Parkour** Sprint jumping over 1, 2, or 3 block gaps
|
||||||
- **Parkour place** Sprint jumping over a 3 block gap and placing the block to land on while executing the jump. It's really cool.
|
- **Parkour place** Sprint jumping over a 3 block gap and placing the block to land on while executing the jump. It's really cool.
|
||||||
|
- **Pigs** It can sort of control pigs. I wouldn't rely on it though.
|
||||||
|
|
||||||
# Pathing method
|
# Pathing method
|
||||||
Baritone uses A*, with some modifications:
|
Baritone uses A*, with some modifications:
|
||||||
@@ -21,9 +22,9 @@ Baritone uses A*, with some modifications:
|
|||||||
- **Backtrack cost favoring** While calculating the next segment, Baritone favors backtracking its current segment. The cost is decreased heavily, but is still positive (this won't cause it to backtrack if it doesn't need to). This allows it to splice and jump onto the next segment as early as possible, if the next segment begins with a backtrack of the current one. <a href="https://www.youtube.com/watch?v=CGiMcb8-99Y">Example</a>
|
- **Backtrack cost favoring** While calculating the next segment, Baritone favors backtracking its current segment. The cost is decreased heavily, but is still positive (this won't cause it to backtrack if it doesn't need to). This allows it to splice and jump onto the next segment as early as possible, if the next segment begins with a backtrack of the current one. <a href="https://www.youtube.com/watch?v=CGiMcb8-99Y">Example</a>
|
||||||
- **Backtrack detection and pausing** While path calculation happens on a separate thread, the main game thread has access to the latest node considered, and the best path so far (those are rendered light blue and dark blue respectively). When the current best path (rendered dark blue) passes through the player's current position on the current path segment, path execution is paused (if it's safe to do so), because there's no point continuing forward if we're about to turn around and go back that same way. Note that the current best path as reported by the path calculation thread takes into account the incremental cost backoff system, so it's accurate to what the path calculation thread will actually pick once it finishes.
|
- **Backtrack detection and pausing** While path calculation happens on a separate thread, the main game thread has access to the latest node considered, and the best path so far (those are rendered light blue and dark blue respectively). When the current best path (rendered dark blue) passes through the player's current position on the current path segment, path execution is paused (if it's safe to do so), because there's no point continuing forward if we're about to turn around and go back that same way. Note that the current best path as reported by the path calculation thread takes into account the incremental cost backoff system, so it's accurate to what the path calculation thread will actually pick once it finishes.
|
||||||
|
|
||||||
# Configuring Baritone
|
# Chat control
|
||||||
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>.
|
|
||||||
To change a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `pathTimeoutMS 250`). It's case insensitive.
|
- [Baritone chat control usage](USAGE.md)
|
||||||
|
|
||||||
# Goals
|
# Goals
|
||||||
The pathing goal can be set to any of these options:
|
The pathing goal can be set to any of these options:
|
||||||
@@ -46,7 +47,6 @@ Things it doesn't have yet
|
|||||||
See <a href="https://github.com/cabaletta/baritone/issues">issues</a> for more.
|
See <a href="https://github.com/cabaletta/baritone/issues">issues</a> for more.
|
||||||
|
|
||||||
Things it may not ever have, from most likely to least likely =(
|
Things it may not ever have, from most likely to least likely =(
|
||||||
- Pigs
|
|
||||||
- Boats
|
- Boats
|
||||||
- Horses (2x3 path instead of 1x2)
|
- Horses (2x3 path instead of 1x2)
|
||||||
- Elytra
|
- Elytra
|
||||||
|
|||||||
-96
@@ -1,96 +0,0 @@
|
|||||||
# 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>.
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@@ -1,65 +1,64 @@
|
|||||||
# Baritone
|
# Baritone
|
||||||
[](https://travis-ci.com/cabaletta/baritone)
|
[](https://travis-ci.com/cabaletta/baritone)
|
||||||
[](https://github.com/cabaletta/baritone/releases)
|
[](https://github.com/cabaletta/baritone/releases)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
||||||
[](http://hits.dwyl.com/cabaletta/baritone)
|
[](http://hits.dwyl.com/cabaletta/baritone)
|
||||||
|
[](https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md)
|
||||||
[](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle)
|
[](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle)
|
||||||
[](https://github.com/cabaletta/baritone/issues)
|
[](https://github.com/cabaletta/baritone/issues)
|
||||||
|
[](https://github.com/cabaletta/baritone/issues/)
|
||||||
|
[](https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed)
|
||||||
|
[](https://github.com/cabaletta/baritone/pulls/)
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
[](https://minecraft.gamepedia.com/1.12.2)
|
[](https://minecraft.gamepedia.com/1.12.2)
|
||||||
[](https://impactdevelopment.github.io/)
|
[](https://github.com/cabaletta/baritone/graphs/contributors/)
|
||||||
[](https://github.com/zeroeightysix/KAMI/)
|
[](https://github.com/cabaletta/baritone/commit/)
|
||||||
[](https://github.com/EmotionalLove/Asuna/)
|
[](https://impactdevelopment.github.io/)
|
||||||
[](https://futureclient.net/)
|
[](https://wweclient.com/)
|
||||||
|
[](https://github.com/zeroeightysix/KAMI/)
|
||||||
|
[](https://futureclient.net/)
|
||||||
|
[](https://github.com/fr1kin/ForgeHax)
|
||||||
|
|
||||||
A Minecraft pathfinder bot.
|
A Minecraft pathfinder bot.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||||
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||||
|
|
||||||
|
Have committed at least once a day for the last 7 months =D 🦀
|
||||||
|
|
||||||
|
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
|
||||||
|
|
||||||
|
# Getting Started
|
||||||
|
|
||||||
Here are some links to help to get started:
|
Here are some links to help to get started:
|
||||||
|
|
||||||
- [Features](FEATURES.md)
|
- [Features](FEATURES.md)
|
||||||
|
|
||||||
- [Installation](INSTALL.md)
|
- [Installation & setup](SETUP.md)
|
||||||
|
|
||||||
# Setup
|
- [API Javadocs](https://baritone.leijurv.com/)
|
||||||
|
|
||||||
## Command Line
|
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
|
||||||
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
|
||||||
|
|
||||||
Running Baritone:
|
- [Baritone chat control usage](USAGE.md)
|
||||||
|
|
||||||
```
|
# API
|
||||||
$ gradlew runClient
|
|
||||||
```
|
|
||||||
|
|
||||||
Building Baritone:
|
The API is heavily documented, you can find the Javadocs for the latest release [here](https://baritone.leijurv.com/).
|
||||||
```
|
Please note that usage of anything located outside of the ``baritone.api`` package is not supported by the API release
|
||||||
$ gradlew build
|
jar.
|
||||||
```
|
|
||||||
|
|
||||||
To replace out Impact 4.4's Baritone build with a customized one, switch to the `impact4.4-compat` branch, 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"`).
|
Below is an example of basic usage for changing some settings, and then pathing to a X/Z goal.
|
||||||
|
|
||||||
## IntelliJ's Gradle UI
|
|
||||||
- Open the project in IntelliJ as a Gradle project
|
|
||||||
- Run the Gradle tasks `setupDecompWorkspace` then `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)
|
|
||||||
|
|
||||||
Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actually start pathing. Also try `mine diamond_ore`. `cancel` to cancel.
|
|
||||||
|
|
||||||
# API example
|
|
||||||
|
|
||||||
```
|
```
|
||||||
BaritoneAPI.getSettings().allowSprint.value = true;
|
BaritoneAPI.getSettings().allowSprint.value = true;
|
||||||
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
|
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;
|
||||||
|
|
||||||
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
|
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
|
||||||
```
|
```
|
||||||
@@ -68,11 +67,11 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd
|
|||||||
|
|
||||||
## Can I use Baritone as a library in my custom utility client?
|
## Can I use Baritone as a library in my custom utility client?
|
||||||
|
|
||||||
Sure! (As long as usage is in compliance with the LGPL 3 License)
|
That's what it's for, sure! (As long as usage is in compliance with the LGPL 3 License)
|
||||||
|
|
||||||
## How is it so fast?
|
## How is it so fast?
|
||||||
|
|
||||||
Magic. (Hours of [Leijurv](https://github.com/leijurv) enduring excruciating pain)
|
Magic. (Hours of [leijurv](https://github.com/leijurv) enduring excruciating pain)
|
||||||
|
|
||||||
## Why is it called Baritone?
|
## Why is it called Baritone?
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# Installation
|
||||||
|
|
||||||
|
## Prebuilt official releases
|
||||||
|
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `builder` branch for example, you'll have to build it yourself)
|
||||||
|
|
||||||
|
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
|
||||||
|
|
||||||
|
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 .` 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).
|
||||||
|
|
||||||
|
|
||||||
|
## Artifacts
|
||||||
|
|
||||||
|
Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
|
||||||
|
|
||||||
|
**The Forge release can simply be added as a Forge mod.**
|
||||||
|
|
||||||
|
If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar`
|
||||||
|
|
||||||
|
- **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features.
|
||||||
|
- **Forge API**: Same as API, but packaged for Forge. This should be used where another mod has a Baritone integration.
|
||||||
|
- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features.
|
||||||
|
- **Forge Standalone**: Same as Standalone, but packaged for Forge. This should be used when Baritone is your only Forge mod, or none of your other Forge mods integrate with Baritone.
|
||||||
|
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production.
|
||||||
|
|
||||||
|
## More Info
|
||||||
|
To replace out Impact 4.5's Baritone build with a customized one, build Baritone as above then copy & **rename** `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.2/baritone-api-1.2.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.5/1.12.2-Impact_4.5.json`, find the line `"name": "cabaletta:baritone-api:1.2"`, remove the comma from the end, and **entirely remove the NEXT line** (starts with `"url"`). **Restart your launcher** then load as normal.
|
||||||
|
|
||||||
|
You can verify whether or not it worked by running `.b version` in chat (only valid in Impact). It should print out the version that you downloaded. Note: The version that comes with 4.5 is `v1.2.3`.
|
||||||
|
|
||||||
|
## Build it yourself
|
||||||
|
- Clone or download Baritone
|
||||||
|
|
||||||
|

|
||||||
|
- If you choose to download, make sure you extract the ZIP archive.
|
||||||
|
- Follow one of the instruction sets below, based on your preference
|
||||||
|
|
||||||
|
## Command Line
|
||||||
|
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
||||||
|
|
||||||
|
Setting up the Environment:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gradlew setupDecompWorkspace
|
||||||
|
$ gradlew --refresh-dependencies
|
||||||
|
```
|
||||||
|
|
||||||
|
Running Baritone:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gradlew runClient
|
||||||
|
```
|
||||||
|
|
||||||
|
For information on how to build baritone, see [Building Baritone](#building-baritone)
|
||||||
|
|
||||||
|
## IntelliJ
|
||||||
|
- Open the project in IntelliJ as a Gradle project
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Select the "Minecraft Client" launch config
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Click on ``Edit Configurations...`` from the same dropdown and select the "Minecraft Client" config
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- In `Edit Configurations...` you need to select `baritone_launch` for `Use classpath of module:`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
Make sure that you have properly [setup](#setup) the environment before trying to build it.
|
||||||
|
|
||||||
|
## Command Line
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gradlew build
|
||||||
|
```
|
||||||
|
|
||||||
|
## IntelliJ
|
||||||
|
|
||||||
|
- Navigate to the gradle tasks on the right tab as follows
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Double click on **build** to run it
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
(assuming you already have Baritone [set up](SETUP.md))
|
||||||
|
|
||||||
|
# Prefix
|
||||||
|
|
||||||
|
Baritone commands can by default be typed in the chatbox. However if you make a typo, like typing "gola 10000 10000" instead of goal it goes into public chat, which is bad.
|
||||||
|
|
||||||
|
Therefore you can use a prefix before your messages.
|
||||||
|
|
||||||
|
On Baritone v1.1.0 and newer: The prefix is `#` by default. Anything beginning with `#` isn't sent, and is only interpreted by Baritone.
|
||||||
|
For older than v1.1.0, `#` must be enabled by toggling on the `prefix` setting.
|
||||||
|
|
||||||
|
**Only** in Impact is `.b` also a valid prefix. In 4.4, `#` does **not** work, neither does saying the commands directly in chat. `#` works by default in 4.5 (not 4.4).
|
||||||
|
|
||||||
|
Other clients like Kami and Asuna have their own custom things (like `-path`), and can disable direct chat control entirely.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Commands
|
||||||
|
|
||||||
|
**All** of these commands may need a prefix before them, as above ^.
|
||||||
|
|
||||||
|
`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java#L53).
|
||||||
|
|
||||||
|
To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Some common examples:
|
||||||
|
- `thisway 1000` then `path` to go in the direction you're facing for a thousand blocks
|
||||||
|
- `goal x y z` or `goal x z` or `goal y`, then `path` to go to a certain coordinate
|
||||||
|
- `goal` to set the goal to your player's feet
|
||||||
|
- `goal clear` to clear the goal
|
||||||
|
- `cancel` or `stop` to stop everything
|
||||||
|
- `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part)
|
||||||
|
- `mine diamond_ore` to mine diamond ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.)
|
||||||
|
- `click` to click your destination on the screen. left click to path into it, right click to path on top of it.
|
||||||
|
- `follow playerName` to follow a player. `follow` to follow the entity you're looking at (only works if it hitting range). `followplayers` to follow any players in range (combine with Kill Aura for a fun time).
|
||||||
|
- `save waypointName` to save a waypoint. `goto waypointName` to go to it.
|
||||||
|
- `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120).
|
||||||
|
- `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start.
|
||||||
|
- `render` to rerender the world in case `renderCachedChunks` is being glitchy
|
||||||
|
- `version` to get the version of Baritone you're running
|
||||||
|
- `damn` daniel
|
||||||
|
|
||||||
|
For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java).
|
||||||
|
|
||||||
|
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>. If you find HTML easier to read than Javadoc, you can look <a href="https://baritone.leijurv.com/baritone/api/Settings.html#field.detail">here</a>.
|
||||||
|
|
||||||
|
There are about a hundred settings, but here are some fun / interesting / important ones that you might want to look at changing in normal usage of Baritone. The documentation for each can be found at the above links.
|
||||||
|
- `allowBreak`
|
||||||
|
- `allowSprint`
|
||||||
|
- `allowPlace`
|
||||||
|
- `allowParkour`
|
||||||
|
- `allowParkourPlace`
|
||||||
|
- `renderCachedChunks` (and `cachedChunksOpacity`) <-- very fun but you need a beefy computer
|
||||||
|
- `avoidance`
|
||||||
|
- `legitMine`
|
||||||
|
- `followRadius`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Troubleshooting / common issues
|
||||||
|
|
||||||
|
## Baritone highlights a block in green but gets completely stuck? Also I'm using Baritone with Future?
|
||||||
|
Baritone is trying to right click to place a block there, but it can't since there's a conflicting mixin. Baritone can't force click right click when Future is also installed. Left click **does work** on recent Baritone even with Future, however. For now, turn off `allowPlace` and Baritone will only search for paths that don't require placing blocks to complete. `allowBreak` can remain on.
|
||||||
|
|
||||||
|
## Why doesn't Baritone respond to any of my chat commands?
|
||||||
|
This could be one of many things.
|
||||||
|
|
||||||
|
First, make sure it's actually installed. An easy way to check is seeing if it created the folder `baritone` in your Minecraft folder.
|
||||||
|
|
||||||
|
Second, make sure that you're using the prefix properly, and that chat control is enabled in the way you expect.
|
||||||
|
|
||||||
|
For example, Impact disables direct chat control. (i.e. anything typed in chat without a prefix will be ignored and sent publicly). **This is a saved setting**, so if you run Impact once, `chatControl` will be off from then on, **even in other clients**.
|
||||||
|
So you'll need to use the `#` prefix or edit `baritone/settings.txt` in your Minecraft folder to undo that (specifically, remove the line `chatControl false` then restart your client).
|
||||||
|
|
||||||
|
|
||||||
|
## Why can I do `.goto x z` in Impact but nowhere else? Why can I do `-path to x z` in KAMI but nowhere else?
|
||||||
|
These are custom commands that they added; those aren't from Baritone.
|
||||||
|
The equivalent you're looking for is `goal x z` then `path`.
|
||||||
+16
-3
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
group 'baritone'
|
group 'baritone'
|
||||||
version '1.0.0-hotfix-2'
|
version '1.2.4'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
@@ -48,6 +48,7 @@ apply plugin: 'org.spongepowered.mixin'
|
|||||||
sourceCompatibility = targetCompatibility = '1.8'
|
sourceCompatibility = targetCompatibility = '1.8'
|
||||||
compileJava {
|
compileJava {
|
||||||
sourceCompatibility = targetCompatibility = '1.8'
|
sourceCompatibility = targetCompatibility = '1.8'
|
||||||
|
options.encoding = "UTF-8" // allow emoji in comments :^)
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -94,19 +95,31 @@ dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mixin {
|
mixin {
|
||||||
defaultObfuscationEnv notch
|
defaultObfuscationEnv searge
|
||||||
add sourceSets.launch, 'mixins.baritone.refmap.json'
|
add sourceSets.launch, 'mixins.baritone.refmap.json'
|
||||||
}
|
}
|
||||||
|
|
||||||
javadoc {
|
javadoc {
|
||||||
|
options.addStringOption('Xwerror', '-quiet') // makes the build fail on travis when there is a javadoc error
|
||||||
|
options.linkSource true
|
||||||
|
options.encoding "UTF-8" // allow emoji in comments :^)
|
||||||
source = sourceSets.api.allJava
|
source = sourceSets.api.allJava
|
||||||
classpath = sourceSets.api.compileClasspath
|
classpath += sourceSets.api.compileClasspath
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
from sourceSets.launch.output, sourceSets.api.output
|
from sourceSets.launch.output, sourceSets.api.output
|
||||||
preserveFileTimestamps = false
|
preserveFileTimestamps = false
|
||||||
reproducibleFileOrder = true
|
reproducibleFileOrder = true
|
||||||
|
|
||||||
|
manifest {
|
||||||
|
attributes(
|
||||||
|
'MixinConfigs': 'mixins.baritone.json',
|
||||||
|
|
||||||
|
'Implementation-Title': 'Baritone',
|
||||||
|
'Implementation-Version': version
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task proguard(type: ProguardTask) {
|
task proguard(type: ProguardTask) {
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
package baritone.gradle.task;
|
package baritone.gradle.task;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import org.gradle.api.DefaultTask;
|
import org.gradle.api.DefaultTask;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -26,7 +24,6 @@ import java.io.InputStream;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@@ -34,8 +31,6 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
class BaritoneGradleTask extends DefaultTask {
|
class BaritoneGradleTask extends DefaultTask {
|
||||||
|
|
||||||
protected static final JsonParser PARSER = new JsonParser();
|
|
||||||
|
|
||||||
protected static final String
|
protected static final String
|
||||||
PROGUARD_ZIP = "proguard.zip",
|
PROGUARD_ZIP = "proguard.zip",
|
||||||
PROGUARD_JAR = "proguard.jar",
|
PROGUARD_JAR = "proguard.jar",
|
||||||
@@ -45,26 +40,28 @@ class BaritoneGradleTask extends DefaultTask {
|
|||||||
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
||||||
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
||||||
|
|
||||||
VERSION_MANIFEST = "version_manifest.json",
|
|
||||||
|
|
||||||
TEMP_LIBRARY_DIR = "tempLibraries/",
|
TEMP_LIBRARY_DIR = "tempLibraries/",
|
||||||
|
|
||||||
ARTIFACT_STANDARD = "%s-%s.jar",
|
ARTIFACT_STANDARD = "%s-%s.jar",
|
||||||
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
||||||
ARTIFACT_API = "%s-api-%s.jar",
|
ARTIFACT_API = "%s-api-%s.jar",
|
||||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
|
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
|
||||||
|
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
|
||||||
|
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
|
||||||
|
|
||||||
protected String artifactName, artifactVersion;
|
protected String artifactName, artifactVersion;
|
||||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
|
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, proguardOut;
|
||||||
|
|
||||||
protected void verifyArtifacts() throws IllegalStateException {
|
protected void verifyArtifacts() throws IllegalStateException {
|
||||||
this.artifactName = getProject().getName();
|
this.artifactName = getProject().getName();
|
||||||
this.artifactVersion = getProject().getVersion().toString();
|
this.artifactVersion = getProject().getVersion().toString();
|
||||||
|
|
||||||
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
|
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
|
||||||
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
|
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||||
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
|
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
|
||||||
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
|
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
|
||||||
|
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
|
||||||
|
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
|
||||||
|
|
||||||
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
|
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
|
||||||
|
|
||||||
@@ -95,8 +92,4 @@ class BaritoneGradleTask extends DefaultTask {
|
|||||||
protected Path getBuildFile(String file) {
|
protected Path getBuildFile(String file) {
|
||||||
return getRelativeFile("build/libs/" + file);
|
return getRelativeFile("build/libs/" + file);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JsonElement readJson(List<String> lines) {
|
|
||||||
return PARSER.parse(String.join("\n", lines));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,9 +42,11 @@ public class CreateDistTask extends BaritoneGradleTask {
|
|||||||
super.verifyArtifacts();
|
super.verifyArtifacts();
|
||||||
|
|
||||||
// Define the distribution file paths
|
// Define the distribution file paths
|
||||||
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
|
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
|
||||||
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
|
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
|
||||||
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
|
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||||
|
Path forgeApi = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_API));
|
||||||
|
Path forgeStandalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_STANDALONE));
|
||||||
|
|
||||||
// NIO will not automatically create directories
|
// NIO will not automatically create directories
|
||||||
Path dir = getRelativeFile("dist/");
|
Path dir = getRelativeFile("dist/");
|
||||||
@@ -53,12 +55,14 @@ public class CreateDistTask extends BaritoneGradleTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy build jars to dist/
|
// Copy build jars to dist/
|
||||||
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
|
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
|
||||||
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
|
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
|
||||||
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
|
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
|
||||||
|
Files.copy(this.artifactForgeApiPath, forgeApi, REPLACE_EXISTING);
|
||||||
|
Files.copy(this.artifactForgeStandalonePath, forgeStandalone, REPLACE_EXISTING);
|
||||||
|
|
||||||
// Calculate all checksums and format them like "shasum"
|
// Calculate all checksums and format them like "shasum"
|
||||||
List<String> shasum = Stream.of(api, standalone, unoptimized)
|
List<String> shasum = Stream.of(api, forgeApi, standalone, forgeStandalone, unoptimized)
|
||||||
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
|
|
||||||
private List<String> requiredLibraries;
|
private List<String> requiredLibraries;
|
||||||
|
|
||||||
|
private File mixin;
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
protected void exec() throws Exception {
|
protected void exec() throws Exception {
|
||||||
super.verifyArtifacts();
|
super.verifyArtifacts();
|
||||||
@@ -79,7 +81,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
Files.delete(this.artifactUnoptimizedPath);
|
Files.delete(this.artifactUnoptimizedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
|
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadProguard() throws Exception {
|
private void downloadProguard() throws Exception {
|
||||||
@@ -173,10 +175,16 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
// Find the library jar file, and copy it to tempLibraries
|
// Find the library jar file, and copy it to tempLibraries
|
||||||
for (File file : pair.getLeft().files(pair.getRight())) {
|
for (File file : pair.getLeft().files(pair.getRight())) {
|
||||||
if (file.getName().startsWith(lib)) {
|
if (file.getName().startsWith(lib)) {
|
||||||
|
if (lib.contains("mixin")) {
|
||||||
|
mixin = file;
|
||||||
|
}
|
||||||
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
|
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mixin == null) {
|
||||||
|
throw new IllegalStateException("Unable to find mixin jar");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// a bunch of epic stuff to get the path to the cached jar
|
// a bunch of epic stuff to get the path to the cached jar
|
||||||
@@ -264,12 +272,14 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
|
|
||||||
private void proguardApi() throws Exception {
|
private void proguardApi() throws Exception {
|
||||||
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
||||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
|
||||||
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void proguardStandalone() throws Exception {
|
private void proguardStandalone() throws Exception {
|
||||||
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
||||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
|
||||||
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanup() {
|
private void cleanup() {
|
||||||
@@ -298,8 +308,8 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
.start();
|
.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
|
// 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.getInputStream(), System.out);
|
||||||
this.printOutputLog(p.getErrorStream());
|
this.printOutputLog(p.getErrorStream(), System.err);
|
||||||
|
|
||||||
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
|
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
|
||||||
int exitCode = p.waitFor();
|
int exitCode = p.waitFor();
|
||||||
@@ -308,12 +318,12 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printOutputLog(InputStream stream) {
|
private void printOutputLog(InputStream stream, PrintStream outerr) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
System.out.println(line);
|
outerr.println(line);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import com.google.gson.stream.JsonReader;
|
|||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
@@ -39,7 +36,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class Determinizer {
|
public class Determinizer {
|
||||||
|
|
||||||
public static void determinize(String inputPath, String outputPath) throws IOException {
|
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
|
||||||
System.out.println("Running Determinizer");
|
System.out.println("Running Determinizer");
|
||||||
System.out.println(" Input path: " + inputPath);
|
System.out.println(" Input path: " + inputPath);
|
||||||
System.out.println(" Output path: " + outputPath);
|
System.out.println(" Output path: " + outputPath);
|
||||||
@@ -66,10 +63,30 @@ public class Determinizer {
|
|||||||
if (entry.getName().endsWith(".refmap.json")) {
|
if (entry.getName().endsWith(".refmap.json")) {
|
||||||
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
|
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
|
||||||
jos.write(writeSorted(object).getBytes());
|
jos.write(writeSorted(object).getBytes());
|
||||||
|
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
|
||||||
|
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
|
||||||
|
copy(jarFile.getInputStream(entry), cancer);
|
||||||
|
String manifest = new String(cancer.toByteArray());
|
||||||
|
if (!manifest.contains("baritone.launch.BaritoneTweaker")) {
|
||||||
|
throw new IllegalStateException("unable to replace");
|
||||||
|
}
|
||||||
|
manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
|
||||||
|
jos.write(manifest.getBytes());
|
||||||
} else {
|
} else {
|
||||||
copy(jarFile.getInputStream(entry), jos);
|
copy(jarFile.getInputStream(entry), jos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (toInclude.isPresent()) {
|
||||||
|
try (JarFile mixin = new JarFile(toInclude.get())) {
|
||||||
|
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
|
||||||
|
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
jos.putNextEntry(entry);
|
||||||
|
copy(mixin.getInputStream(entry), jos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
jos.finish();
|
jos.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -12,15 +12,15 @@
|
|||||||
-flattenpackagehierarchy
|
-flattenpackagehierarchy
|
||||||
-repackageclasses 'baritone'
|
-repackageclasses 'baritone'
|
||||||
|
|
||||||
|
# lwjgl is weird
|
||||||
|
-dontwarn org.lwjgl.**
|
||||||
|
|
||||||
-keep class baritone.api.** { *; } # this is the keep api
|
-keep class baritone.api.** { *; } # this is the keep api
|
||||||
|
|
||||||
# service provider needs these class names
|
# service provider needs these class names
|
||||||
-keep class baritone.BaritoneProvider
|
-keep class baritone.BaritoneProvider
|
||||||
-keep class baritone.api.IBaritoneProvider
|
-keep class baritone.api.IBaritoneProvider
|
||||||
|
|
||||||
# hack
|
|
||||||
-keep class baritone.utils.ExampleBaritoneControl { *; } # have to include this string to remove this keep in the standalone build: # this is the keep api
|
|
||||||
|
|
||||||
# setting names are reflected from field names, so keep field names
|
# setting names are reflected from field names, so keep field names
|
||||||
-keepclassmembers class baritone.api.Settings {
|
-keepclassmembers class baritone.api.Settings {
|
||||||
public <fields>;
|
public <fields>;
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ import java.util.Iterator;
|
|||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API exposure for various things implemented in Baritone.
|
* Exposes the {@link IBaritoneProvider} instance and the {@link Settings} instance for API usage.
|
||||||
* <p>
|
|
||||||
* W.I.P
|
|
||||||
*
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import baritone.api.behavior.IPathingBehavior;
|
|||||||
import baritone.api.cache.IWorldProvider;
|
import baritone.api.cache.IWorldProvider;
|
||||||
import baritone.api.event.listener.IEventBus;
|
import baritone.api.event.listener.IEventBus;
|
||||||
import baritone.api.pathing.calc.IPathingControlManager;
|
import baritone.api.pathing.calc.IPathingControlManager;
|
||||||
import baritone.api.process.ICustomGoalProcess;
|
import baritone.api.process.*;
|
||||||
import baritone.api.process.IFollowProcess;
|
|
||||||
import baritone.api.process.IGetToBlockProcess;
|
|
||||||
import baritone.api.process.IMineProcess;
|
|
||||||
import baritone.api.utils.IInputOverrideHandler;
|
import baritone.api.utils.IInputOverrideHandler;
|
||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
|
||||||
@@ -36,22 +33,13 @@ import baritone.api.utils.IPlayerContext;
|
|||||||
public interface IBaritone {
|
public interface IBaritone {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The {@link IFollowProcess} instance
|
* Call as soon as Minecraft is ready, initializes all of the processes, behaviors, etc. This will
|
||||||
* @see IFollowProcess
|
* only effectively be ran once, any additional calls are redundant because the initialization state
|
||||||
|
* is saved.
|
||||||
|
* <p>
|
||||||
|
* Or whenever your overeager utility client wants.
|
||||||
*/
|
*/
|
||||||
IFollowProcess getFollowProcess();
|
void init();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The {@link ILookBehavior} instance
|
|
||||||
* @see ILookBehavior
|
|
||||||
*/
|
|
||||||
ILookBehavior getLookBehavior();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The {@link IMineProcess} instance
|
|
||||||
* @see IMineProcess
|
|
||||||
*/
|
|
||||||
IMineProcess getMineProcess();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The {@link IPathingBehavior} instance
|
* @return The {@link IPathingBehavior} instance
|
||||||
@@ -59,21 +47,72 @@ public interface IBaritone {
|
|||||||
*/
|
*/
|
||||||
IPathingBehavior getPathingBehavior();
|
IPathingBehavior getPathingBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link ILookBehavior} instance
|
||||||
|
* @see ILookBehavior
|
||||||
|
*/
|
||||||
|
ILookBehavior getLookBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IFollowProcess} instance
|
||||||
|
* @see IFollowProcess
|
||||||
|
*/
|
||||||
|
IFollowProcess getFollowProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IMineProcess} instance
|
||||||
|
* @see IMineProcess
|
||||||
|
*/
|
||||||
|
IMineProcess getMineProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IBuilderProcess} instance
|
||||||
|
* @see IBuilderProcess
|
||||||
|
*/
|
||||||
|
IBuilderProcess getBuilderProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link ICustomGoalProcess} instance
|
||||||
|
* @see ICustomGoalProcess
|
||||||
|
*/
|
||||||
|
ICustomGoalProcess getCustomGoalProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IGetToBlockProcess} instance
|
||||||
|
* @see IGetToBlockProcess
|
||||||
|
*/
|
||||||
|
IGetToBlockProcess getGetToBlockProcess();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The {@link IWorldProvider} instance
|
* @return The {@link IWorldProvider} instance
|
||||||
* @see IWorldProvider
|
* @see IWorldProvider
|
||||||
*/
|
*/
|
||||||
IWorldProvider getWorldProvider();
|
IWorldProvider getWorldProvider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link IPathingControlManager} for this {@link IBaritone} instance, which is responsible
|
||||||
|
* for managing the {@link IBaritoneProcess}es which control the {@link IPathingBehavior} state.
|
||||||
|
*
|
||||||
|
* @return The {@link IPathingControlManager} instance
|
||||||
|
* @see IPathingControlManager
|
||||||
|
*/
|
||||||
IPathingControlManager getPathingControlManager();
|
IPathingControlManager getPathingControlManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IInputOverrideHandler} instance
|
||||||
|
* @see IInputOverrideHandler
|
||||||
|
*/
|
||||||
IInputOverrideHandler getInputOverrideHandler();
|
IInputOverrideHandler getInputOverrideHandler();
|
||||||
|
|
||||||
ICustomGoalProcess getCustomGoalProcess();
|
/**
|
||||||
|
* @return The {@link IPlayerContext} instance
|
||||||
IGetToBlockProcess getGetToBlockProcess();
|
* @see IPlayerContext
|
||||||
|
*/
|
||||||
IPlayerContext getPlayerContext();
|
IPlayerContext getPlayerContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IEventBus} instance
|
||||||
|
* @see IEventBus
|
||||||
|
*/
|
||||||
IEventBus getGameEventHandler();
|
IEventBus getGameEventHandler();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import net.minecraft.client.entity.EntityPlayerSP;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Leijurv
|
* Provides the present {@link IBaritone} instances
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public interface IBaritoneProvider {
|
public interface IBaritoneProvider {
|
||||||
|
|
||||||
@@ -47,7 +49,8 @@ public interface IBaritoneProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
|
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
|
||||||
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
|
* replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when
|
||||||
|
* {@code bot-system} is merged into {@code master}.
|
||||||
*
|
*
|
||||||
* @param player The player
|
* @param player The player
|
||||||
* @return The {@link IBaritone} instance.
|
* @return The {@link IBaritone} instance.
|
||||||
@@ -58,7 +61,7 @@ public interface IBaritoneProvider {
|
|||||||
return baritone;
|
return baritone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("No baritone for player " + player);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.api;
|
package baritone.api;
|
||||||
|
|
||||||
|
import baritone.api.utils.SettingsUtil;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
@@ -29,71 +30,71 @@ import java.util.List;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Baritone's settings
|
* Baritone's settings. Settings apply to all Baritone instances.
|
||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public class Settings {
|
public final class Settings {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to break blocks
|
* Allow Baritone to break blocks
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowBreak = new Setting<>(true);
|
public final Setting<Boolean> allowBreak = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to sprint
|
* Allow Baritone to sprint
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowSprint = new Setting<>(true);
|
public final Setting<Boolean> allowSprint = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to place blocks
|
* Allow Baritone to place blocks
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowPlace = new Setting<>(true);
|
public final Setting<Boolean> allowPlace = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to move items in your inventory to your hotbar
|
* Allow Baritone to move items in your inventory to your hotbar
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowInventory = new Setting<>(false);
|
public final Setting<Boolean> allowInventory = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It doesn't actually take twenty ticks to place a block, this cost is so high
|
* It doesn't actually take twenty ticks to place a block, this cost is so high
|
||||||
* because we want to generally conserve blocks which might be limited
|
* because we want to generally conserve blocks which might be limited
|
||||||
*/
|
*/
|
||||||
public Setting<Double> blockPlacementPenalty = new Setting<>(20D);
|
public final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is just a tiebreaker to make it less likely to break blocks if it can avoid it.
|
* This is just a tiebreaker to make it less likely to break blocks if it can avoid it.
|
||||||
* For example, fire has a break cost of 0, this makes it nonzero, so all else being equal
|
* For example, fire has a break cost of 0, this makes it nonzero, so all else being equal
|
||||||
* it will take an otherwise equivalent route that doesn't require it to put out fire.
|
* it will take an otherwise equivalent route that doesn't require it to put out fire.
|
||||||
*/
|
*/
|
||||||
public Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
|
public final Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) beacuse it uses hunger
|
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) because it uses hunger
|
||||||
*/
|
*/
|
||||||
public Setting<Double> jumpPenalty = new Setting<>(2D);
|
public final Setting<Double> jumpPenalty = new Setting<>(2D);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walking on water uses up hunger really quick, so penalize it
|
* Walking on water uses up hunger really quick, so penalize it
|
||||||
*/
|
*/
|
||||||
public Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
|
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
|
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
|
||||||
* Reliability: questionable.
|
* Reliability: questionable.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
|
public final Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow Baritone to assume it can walk on still water just like any other block.
|
* Allow Baritone to assume it can walk on still water just like any other block.
|
||||||
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
|
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
|
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assume step functionality; don't jump on an Ascend.
|
* Assume step functionality; don't jump on an Ascend.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> assumeStep = new Setting<>(false);
|
public final Setting<Boolean> assumeStep = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assume safe walk functionality; don't sneak on a backplace traverse.
|
* Assume safe walk functionality; don't sneak on a backplace traverse.
|
||||||
@@ -102,14 +103,14 @@ public class Settings {
|
|||||||
* it won't sneak right click, it'll just right click, which means it'll open the chest instead of placing
|
* it won't sneak right click, it'll just right click, which means it'll open the chest instead of placing
|
||||||
* against it. That's why this defaults to off.
|
* against it. That's why this defaults to off.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> assumeSafeWalk = new Setting<>(false);
|
public final Setting<Boolean> assumeSafeWalk = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
|
* If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
|
||||||
* <p>
|
* <p>
|
||||||
* Defaults to false because this fails on NCP
|
* Defaults to false because this fails on constantiam
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow descending diagonally
|
* Allow descending diagonally
|
||||||
@@ -118,12 +119,12 @@ public class Settings {
|
|||||||
* <p>
|
* <p>
|
||||||
* For a generic "take some risks" mode I'd turn on this one, parkour, and parkour place.
|
* For a generic "take some risks" mode I'd turn on this one, parkour, and parkour place.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
|
public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||||
*/
|
*/
|
||||||
public Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||||
Item.getItemFromBlock(Blocks.DIRT),
|
Item.getItemFromBlock(Blocks.DIRT),
|
||||||
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
||||||
Item.getItemFromBlock(Blocks.NETHERRACK)
|
Item.getItemFromBlock(Blocks.NETHERRACK)
|
||||||
@@ -132,31 +133,47 @@ public class Settings {
|
|||||||
/**
|
/**
|
||||||
* Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
|
* Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
|
||||||
* pathing scenarios. And they can cause Baritone to get trapped indefinitely in a strange scenario.
|
* pathing scenarios. And they can cause Baritone to get trapped indefinitely in a strange scenario.
|
||||||
|
* <p>
|
||||||
|
* Never turn this on lol
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowVines = new Setting<>(false);
|
public final Setting<Boolean> allowVines = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Slab behavior is complicated, disable this for higher path reliability. Leave enabled if you have bottom slabs
|
* Slab behavior is complicated, disable this for higher path reliability. Leave enabled if you have bottom slabs
|
||||||
* everywhere in your base.
|
* everywhere in your base.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
|
public final Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You know what it is
|
* You know what it is
|
||||||
* <p>
|
* <p>
|
||||||
* But it's very unreliable and falls off when cornering like all the time so.
|
* But it's very unreliable and falls off when cornering like all the time so.
|
||||||
|
* <p>
|
||||||
|
* It also overshoots the landing pretty much always (making contact with the next block over), so be careful
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowParkour = new Setting<>(false);
|
public final Setting<Boolean> allowParkour = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like parkour, but even more unreliable!
|
* Actually pretty reliable.
|
||||||
|
* <p>
|
||||||
|
* Doesn't make it any more dangerous compared to just normal allowParkour th
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowParkourPlace = new Setting<>(false);
|
public final Setting<Boolean> allowParkourPlace = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
|
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> considerPotionEffects = new Setting<>(true);
|
public final Setting<Boolean> considerPotionEffects = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sprint and jump a block early on ascends wherever possible
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> sprintAscends = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many ticks between right clicks are allowed. Default in game is 4
|
||||||
|
*/
|
||||||
|
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the big A* setting.
|
* This is the big A* setting.
|
||||||
@@ -173,131 +190,139 @@ public class Settings {
|
|||||||
* <p>
|
* <p>
|
||||||
* Finding the optimal path is worth it, so it's the default.
|
* Finding the optimal path is worth it, so it's the default.
|
||||||
*/
|
*/
|
||||||
public Setting<Double> costHeuristic = new Setting<>(3.563);
|
public final Setting<Double> costHeuristic = new Setting<>(3.563);
|
||||||
|
|
||||||
// a bunch of obscure internal A* settings that you probably don't want to change
|
// a bunch of obscure internal A* settings that you probably don't want to change
|
||||||
/**
|
/**
|
||||||
* The maximum number of times it will fetch outside loaded or cached chunks before assuming that
|
* The maximum number of times it will fetch outside loaded or cached chunks before assuming that
|
||||||
* pathing has reached the end of the known area, and should therefore stop.
|
* pathing has reached the end of the known area, and should therefore stop.
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
|
public final Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to 1.0 to effectively disable this feature
|
* Set to 1.0 to effectively disable this feature
|
||||||
*
|
*
|
||||||
* @see <a href="https://github.com/cabaletta/baritone/issues/18">Issue #18</a>
|
* @see <a href="https://github.com/cabaletta/baritone/issues/18">Issue #18</a>
|
||||||
*/
|
*/
|
||||||
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
|
public final Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle the following 4 settings
|
* Toggle the following 4 settings
|
||||||
* <p>
|
* <p>
|
||||||
* They have a noticable performance impact, so they default off
|
* They have a noticeable performance impact, so they default off
|
||||||
|
* <p>
|
||||||
|
* Specifically, building up the avoidance map on the main thread before pathing starts actually takes a noticeable
|
||||||
|
* amount of time, especially when there are a lot of mobs around, and your game jitters for like 200ms while doing so
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> avoidance = new Setting<>(false);
|
public final Setting<Boolean> avoidance = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to 1.0 to effectively disable this feature
|
* Set to 1.0 to effectively disable this feature
|
||||||
* <p>
|
* <p>
|
||||||
* Set below 1.0 to go out of your way to walk near mob spawners
|
* Set below 1.0 to go out of your way to walk near mob spawners
|
||||||
*/
|
*/
|
||||||
public Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
|
public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
|
||||||
|
|
||||||
public Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
|
public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to 1.0 to effectively disable this feature
|
* Set to 1.0 to effectively disable this feature
|
||||||
* <p>
|
* <p>
|
||||||
* Set below 1.0 to go out of your way to walk near mobs
|
* Set below 1.0 to go out of your way to walk near mobs
|
||||||
*/
|
*/
|
||||||
public Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
|
public final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
|
||||||
|
|
||||||
public Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
|
public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When running a goto towards a container block (chest, ender chest, furnace, etc),
|
* When running a goto towards a container block (chest, ender chest, furnace, etc),
|
||||||
* right click and open it once you arrive.
|
* right click and open it once you arrive.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> rightClickContainerOnArrival = new Setting<>(true);
|
public final Setting<Boolean> rightClickContainerOnArrival = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When running a goto towards a nether portal block, walk all the way into the portal
|
* When running a goto towards a nether portal block, walk all the way into the portal
|
||||||
* instead of stopping one block before.
|
* instead of stopping one block before.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> enterPortal = new Setting<>(true);
|
public final Setting<Boolean> enterPortal = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
|
* Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
|
||||||
* and there's no point.
|
* and there's no point.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
|
public final Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
|
* After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
|
||||||
* entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
|
* entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
|
||||||
|
* <p>
|
||||||
|
* This is much safer to leave off now, and makes pathing more efficient. More explanation in the issue.
|
||||||
*
|
*
|
||||||
* @see <a href="https://github.com/cabaletta/baritone/issues/144">Issue #144</a>
|
* @see <a href="https://github.com/cabaletta/baritone/issues/114">Issue #114</a>
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
|
public final Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a movement's cost increases by more than this amount between calculation and execution (due to changes
|
* If a movement's cost increases by more than this amount between calculation and execution (due to changes
|
||||||
* in the environment / world), cancel and recalculate
|
* in the environment / world), cancel and recalculate
|
||||||
*/
|
*/
|
||||||
public Setting<Double> maxCostIncrease = new Setting<>(10D);
|
public final Setting<Double> maxCostIncrease = new Setting<>(10D);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop 5 movements before anything that made the path COST_INF.
|
* Stop 5 movements before anything that made the path COST_INF.
|
||||||
* For example, if lava has spread across the path, don't walk right up to it then recalculate, it might
|
* For example, if lava has spread across the path, don't walk right up to it then recalculate, it might
|
||||||
* still be spreading lol
|
* still be spreading lol
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> costVerificationLookahead = new Setting<>(5);
|
public final Setting<Integer> costVerificationLookahead = new Setting<>(5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
|
* Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
|
||||||
*/
|
*/
|
||||||
public Setting<Double> pathCutoffFactor = new Setting<>(0.9);
|
public final Setting<Double> pathCutoffFactor = new Setting<>(0.9);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only apply static cutoff for paths of at least this length (in terms of number of movements)
|
* Only apply static cutoff for paths of at least this length (in terms of number of movements)
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
|
public final Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start planning the next path once the remaining movements tick estimates sum up to less than this value
|
* Start planning the next path once the remaining movements tick estimates sum up to less than this value
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> planningTickLookAhead = new Setting<>(150);
|
public final Setting<Integer> planningTickLookahead = new Setting<>(150);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default size of the Long2ObjectOpenHashMap used in pathing
|
* Default size of the Long2ObjectOpenHashMap used in pathing
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
|
public final Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load factor coefficient for the Long2ObjectOpenHashMap used in pathing
|
* Load factor coefficient for the Long2ObjectOpenHashMap used in pathing
|
||||||
* <p>
|
* <p>
|
||||||
* Decrease for faster map operations, but higher memory usage
|
* Decrease for faster map operations, but higher memory usage
|
||||||
*/
|
*/
|
||||||
public Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
|
public final Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How far are you allowed to fall onto solid ground (without a water bucket)?
|
* How far are you allowed to fall onto solid ground (without a water bucket)?
|
||||||
* 3 won't deal any damage. But if you just want to get down the mountain quickly and you have
|
* 3 won't deal any damage. But if you just want to get down the mountain quickly and you have
|
||||||
* Feather Falling IV, you might set it a bit higher, like 4 or 5.
|
* Feather Falling IV, you might set it a bit higher, like 4 or 5.
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
|
public final Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How far are you allowed to fall onto solid ground (with a water bucket)?
|
* How far are you allowed to fall onto solid ground (with a water bucket)?
|
||||||
* It's not that reliable, so I've set it below what would kill an unarmored player (23)
|
* It's not that reliable, so I've set it below what would kill an unarmored player (23)
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> maxFallHeightBucket = new Setting<>(20);
|
public final Setting<Integer> maxFallHeightBucket = new Setting<>(20);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is it okay to sprint through a descend followed by a diagonal?
|
* Is it okay to sprint through a descend followed by a diagonal?
|
||||||
* The player overshoots the landing, but not enough to fall off. And the diagonal ensures that there isn't
|
* The player overshoots the landing, but not enough to fall off. And the diagonal ensures that there isn't
|
||||||
* lava or anything that's !canWalkInto in that space, so it's technically safe, just a little sketchy.
|
* lava or anything that's !canWalkInto in that space, so it's technically safe, just a little sketchy.
|
||||||
|
* <p>
|
||||||
|
* Note: this is *not* related to the allowDiagonalDescend setting, that is a completely different thing.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
|
public final Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
|
* If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
|
||||||
@@ -306,131 +331,140 @@ public class Settings {
|
|||||||
* of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away,
|
* of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away,
|
||||||
* your Y coordinate's accuracy doesn't matter at all until you get much much closer.
|
* your Y coordinate's accuracy doesn't matter at all until you get much much closer.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
|
public final Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a movement takes this many ticks more than its initial cost estimate, cancel it
|
* If a movement takes this many ticks more than its initial cost estimate, cancel it
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
|
public final Setting<Integer> movementTimeoutTicks = new Setting<>(100);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pathing ends after this amount of time, but only if a path has been found
|
* Pathing ends after this amount of time, but only if a path has been found
|
||||||
* <p>
|
* <p>
|
||||||
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
|
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
|
||||||
*/
|
*/
|
||||||
public Setting<Long> primaryTimeoutMS = new Setting<>(500L);
|
public final Setting<Long> primaryTimeoutMS = new Setting<>(500L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pathing can never take longer than this, even if that means failing to find any path at all
|
* Pathing can never take longer than this, even if that means failing to find any path at all
|
||||||
*/
|
*/
|
||||||
public Setting<Long> failureTimeoutMS = new Setting<>(2000L);
|
public final Setting<Long> failureTimeoutMS = new Setting<>(2000L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Planning ahead while executing a segment ends after this amount of time, but only if a path has been found
|
* Planning ahead while executing a segment ends after this amount of time, but only if a path has been found
|
||||||
* <p>
|
* <p>
|
||||||
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
|
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
|
||||||
*/
|
*/
|
||||||
public Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
|
public final Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all
|
* Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all
|
||||||
*/
|
*/
|
||||||
public Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
|
public final Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For debugging, consider nodes much much slower
|
* For debugging, consider nodes much much slower
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> slowPath = new Setting<>(false);
|
public final Setting<Boolean> slowPath = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Milliseconds between each node
|
* Milliseconds between each node
|
||||||
*/
|
*/
|
||||||
public Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
|
public final Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The alternative timeout number when slowPath is on
|
* The alternative timeout number when slowPath is on
|
||||||
*/
|
*/
|
||||||
public Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
|
public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
|
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> chunkCaching = new Setting<>(true);
|
public final Setting<Boolean> chunkCaching = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
|
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
|
||||||
* <p>
|
* <p>
|
||||||
* Temporarily disabled, see issue #248
|
* Temporarily disabled
|
||||||
|
*
|
||||||
|
* @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
|
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remember the contents of containers (chests, echests, furnaces)
|
||||||
|
* <p>
|
||||||
|
* Really buggy since the packet stuff is multithreaded badly thanks to brady
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> containerMemory = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print all the debug messages to chat
|
* Print all the debug messages to chat
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> chatDebug = new Setting<>(true);
|
public final Setting<Boolean> chatDebug = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow chat based control of Baritone. Most likely should be disabled when Baritone is imported for use in
|
* Allow chat based control of Baritone. Most likely should be disabled when Baritone is imported for use in
|
||||||
* something else
|
* something else
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> chatControl = new Setting<>(true);
|
public final Setting<Boolean> chatControl = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A second override over chatControl to force it on
|
* A second override over chatControl to force it on
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> removePrefix = new Setting<>(false);
|
public final Setting<Boolean> removePrefix = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the path
|
* Render the path
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderPath = new Setting<>(true);
|
public final Setting<Boolean> renderPath = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the goal
|
* Render the goal
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderGoal = new Setting<>(true);
|
public final Setting<Boolean> renderGoal = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the goal
|
* Ignore depth when rendering the goal
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
|
public final Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders X/Z type Goals with the vanilla beacon beam effect. Combining this with
|
* Renders X/Z type Goals with the vanilla beacon beam effect. Combining this with
|
||||||
* {@link #renderGoalIgnoreDepth} will cause strange render clipping.
|
* {@link #renderGoalIgnoreDepth} will cause strange render clipping.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
|
public final Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
|
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
|
public final Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the path
|
* Ignore depth when rendering the path
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
|
public final Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Line width of the path when rendered, in pixels
|
* Line width of the path when rendered, in pixels
|
||||||
*/
|
*/
|
||||||
public Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
|
public final Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Line width of the goal when rendered, in pixels
|
* Line width of the goal when rendered, in pixels
|
||||||
*/
|
*/
|
||||||
public Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
|
public final Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start fading out the path at 20 movements ahead, and stop rendering it entirely 30 movements ahead.
|
* Start fading out the path at 20 movements ahead, and stop rendering it entirely 30 movements ahead.
|
||||||
* Improves FPS.
|
* Improves FPS.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> fadePath = new Setting<>(false);
|
public final Setting<Boolean> fadePath = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move without having to force the client-sided rotations
|
* Move without having to force the client-sided rotations
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> freeLook = new Setting<>(true);
|
public final Setting<Boolean> freeLook = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
|
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
|
||||||
@@ -438,48 +472,85 @@ public class Settings {
|
|||||||
* At the moment this will silently set the player's rotations when using freeLook so you're not sprinting in
|
* At the moment this will silently set the player's rotations when using freeLook so you're not sprinting in
|
||||||
* directions other than forward, which is picken up by more "advanced" anticheats like AAC, but not NCP.
|
* directions other than forward, which is picken up by more "advanced" anticheats like AAC, but not NCP.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
|
public final Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exclusively use cached chunks for pathing
|
* Exclusively use cached chunks for pathing
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
|
public final Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Continue sprinting while in water
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> sprintInWater = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When GetToBlockProcess or MineProcess fails to calculate a path, instead of just giving up, mark the closest instance
|
||||||
|
* of that block as "unreachable" and go towards the next closest. GetToBlock expands this seaarch to the whole "vein"; MineProcess does not.
|
||||||
|
* This is because MineProcess finds individual impossible blocks (like one block in a vein that has gravel on top then lava, so it can't break)
|
||||||
|
* Whereas GetToBlock should blacklist the whole "vein" if it can't get to any of them.
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> blacklistClosestOnFailure = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 😎 Render cached chunks as semitransparent. Doesn't work with OptiFine 😭 Rarely randomly crashes, see <a href="https://github.com/cabaletta/baritone/issues/327">this issue</a>.
|
||||||
|
* <p>
|
||||||
|
* Can be very useful on servers with low render distance. After enabling, you may need to reload the world in order for it to have an effect
|
||||||
|
* (e.g. disconnect and reconnect, enter then exit the nether, die and respawn, etc). This may literally kill your FPS and CPU because
|
||||||
|
* every chunk gets recompiled twice as much as normal, since the cached version comes into range, then the normal one comes from the server for real.
|
||||||
|
* <p>
|
||||||
|
* Note that flowing water is cached as AVOID, which is rendered as lava. As you get closer, you may therefore see lava falls being replaced with water falls.
|
||||||
|
* <p>
|
||||||
|
* SOLID is rendered as stone in the overworld, netherrack in the nether, and end stone in the end
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> renderCachedChunks = new Setting<>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0.0f = not visible, fully transparent
|
||||||
|
* 1.0f = fully opaque
|
||||||
|
*/
|
||||||
|
public final Setting<Float> cachedChunksOpacity = new Setting<>(0.5f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not to use the "#" command prefix
|
* Whether or not to use the "#" command prefix
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> prefix = new Setting<>(false);
|
public final Setting<Boolean> prefixControl = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
|
||||||
* {@code true}: can mine blocks when in inventory, chat, or tabbed away in ESC menu
|
|
||||||
*/
|
|
||||||
public Setting<Boolean> leftClickWorkaround = new Setting<>(true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't stop walking forward when you need to break blocks in your way
|
* Don't stop walking forward when you need to break blocks in your way
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
public final Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
|
* If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
|
public final Setting<Integer> maxPathHistoryLength = new Setting<>(300);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the current path is too long, cut off this many movements from the beginning.
|
* If the current path is too long, cut off this many movements from the beginning.
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
|
public final Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rescan for the goal once every 5 ticks.
|
* Rescan for the goal once every 5 ticks.
|
||||||
* Set to 0 to disable.
|
* Set to 0 to disable.
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
public final Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After finding this many instances of the target block in the cache, it will stop expanding outward the chunk search.
|
||||||
|
*/
|
||||||
|
public final Setting<Integer> maxCachedWorldScanCount = new Setting<>(10);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When GetToBlock doesn't know any locations for the desired block, explore randomly instead of giving up.
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
* 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);
|
public final Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
||||||
@@ -494,54 +565,79 @@ public class Settings {
|
|||||||
* <p>
|
* <p>
|
||||||
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
|
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
|
public final Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> axisHeight = new Setting<>(120);
|
public final 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"
|
* Disconnect from the server upon arriving at your goal
|
||||||
* 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);
|
public final Setting<Boolean> disconnectOnArrival = new Setting<>(false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disallow MineBehavior from using X-Ray to see where the ores are. Turn this option on 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 on
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> legitMine = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What Y level to go to for legit strip mining
|
* What Y level to go to for legit strip mining
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> legitMineYLevel = new Setting<>(11);
|
public final Setting<Integer> legitMineYLevel = new Setting<>(11);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magically see ores that are separated diagonally from existing ores. Basically like mining around the ores that it finds
|
||||||
|
* in case there's one there touching it diagonally, except it checks it un-legit-ly without having the mine blocks to see it.
|
||||||
|
* You can decide whether this looks plausible or not.
|
||||||
|
* <p>
|
||||||
|
* This is disabled because it results in some weird behavior. For example, it can """see""" the top block of a vein of iron_ore
|
||||||
|
* through a lava lake. This isn't an issue normally since it won't consider anything touching lava, so it just ignores it.
|
||||||
|
* However, this setting expands that and allows it to see the entire vein so it'll mine under the lava lake to get the iron that
|
||||||
|
* it can reach without mining blocks adjacent to lava. This really defeats the purpose of legitMine since a player could never
|
||||||
|
* do that lol, so thats one reason why its disabled
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> legitMineIncludeDiagonals = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When mining block of a certain type, try to mine two at once instead of one.
|
* When mining block of a certain type, try to mine two at once instead of one.
|
||||||
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
|
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
|
||||||
* If the block below is also a goal block, set GoalBlock to the position one down instead of GoalTwoBlocks
|
* If the block below is also a goal block, set GoalBlock to the position one down instead of GoalTwoBlocks
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> forceInternalMining = new Setting<>(true);
|
public final Setting<Boolean> forceInternalMining = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modification to the previous setting, only has effect if forceInternalMining is true
|
* Modification to the previous setting, only has effect if forceInternalMining is true
|
||||||
* If true, only apply the previous setting if the block adjacent to the goal isn't air.
|
* If true, only apply the previous setting if the block adjacent to the goal isn't air.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> internalMiningAirException = new Setting<>(true);
|
public final Setting<Boolean> internalMiningAirException = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual GoalNear is set this distance away from the entity you're following
|
* The actual GoalNear is set this distance away from the entity you're following
|
||||||
* <p>
|
* <p>
|
||||||
* For example, set followOffsetDistance to 5 and followRadius to 0 to always stay precisely 5 blocks north of your follow target.
|
* For example, set followOffsetDistance to 5 and followRadius to 0 to always stay precisely 5 blocks north of your follow target.
|
||||||
*/
|
*/
|
||||||
public Setting<Double> followOffsetDistance = new Setting<>(0D);
|
public final Setting<Double> followOffsetDistance = new Setting<>(0D);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual GoalNear is set in this direction from the entity you're following
|
* The actual GoalNear is set in this direction from the entity you're following. This value is in degrees.
|
||||||
*/
|
*/
|
||||||
public Setting<Float> followOffsetDirection = new Setting<>(0F);
|
public final Setting<Float> followOffsetDirection = new Setting<>(0F);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The radius (for the GoalNear) of how close to your target position you actually have to be
|
* The radius (for the GoalNear) of how close to your target position you actually have to be
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> followRadius = new Setting<>(3);
|
public final Setting<Integer> followRadius = new Setting<>(3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true = exploration uses pythagorean distance to choose closest uncached chunk
|
||||||
|
* <p>
|
||||||
|
* false = exploration uses manhattan / taxicab distance to choose
|
||||||
|
*/
|
||||||
|
public final Setting<Boolean> exploreUsePythagorean = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached chunks (regardless of if they're in RAM or saved to disk) expire and are deleted after this number of seconds
|
* Cached chunks (regardless of if they're in RAM or saved to disk) expire and are deleted after this number of seconds
|
||||||
@@ -563,54 +659,55 @@ public class Settings {
|
|||||||
* has to build up that cache from scratch. But after it's gone through an area just once, the next time will have zero
|
* has to build up that cache from scratch. But after it's gone through an area just once, the next time will have zero
|
||||||
* backtracking, since the entire area is now known and cached.
|
* backtracking, since the entire area is now known and cached.
|
||||||
*/
|
*/
|
||||||
public Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
|
public final Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The function that is called when Baritone will log to chat. This function can be added to
|
* The function that is called when Baritone will log to chat. This function can be added to
|
||||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||||
* {@link Setting#value};
|
* {@link Setting#value};
|
||||||
*/
|
*/
|
||||||
public Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
|
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the current path
|
* The color of the current path
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
|
public final Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the next path
|
* The color of the next path
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
|
public final Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the blocks to break
|
* The color of the blocks to break
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
|
public final Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the blocks to place
|
* The color of the blocks to place
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
|
public final Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the blocks to walk into
|
* The color of the blocks to walk into
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
|
public final Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the best path so far
|
* The color of the best path so far
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
|
public final Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the path to the most recent considered node
|
* The color of the path to the most recent considered node
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
|
public final Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the goal box
|
* The color of the goal box
|
||||||
*/
|
*/
|
||||||
public Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
|
public final Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of lowercase setting field names to their respective setting
|
* A map of lowercase setting field names to their respective setting
|
||||||
@@ -622,13 +719,7 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public final List<Setting<?>> allSettings;
|
public final List<Setting<?>> allSettings;
|
||||||
|
|
||||||
public void reset() {
|
public final class Setting<T> {
|
||||||
for (Setting setting : allSettings) {
|
|
||||||
setting.value = setting.defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Setting<T> {
|
|
||||||
public T value;
|
public T value;
|
||||||
public final T defaultValue;
|
public final T defaultValue;
|
||||||
private String name;
|
private String name;
|
||||||
@@ -644,9 +735,14 @@ public class Settings {
|
|||||||
this.klass = (Class<T>) value.getClass();
|
this.klass = (Class<T>) value.getClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
/**
|
||||||
public final <K extends T> K get() {
|
* Deprecated! Please use .value directly instead
|
||||||
return (K) value;
|
*
|
||||||
|
* @return the current setting value
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public final T get() {
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String getName() {
|
public final String getName() {
|
||||||
@@ -657,8 +753,16 @@ public class Settings {
|
|||||||
return klass;
|
return klass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name + ": " + value;
|
return SettingsUtil.settingToString(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this setting to its default value
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
value = defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,13 @@
|
|||||||
package baritone.api.behavior;
|
package baritone.api.behavior;
|
||||||
|
|
||||||
import baritone.api.event.listener.AbstractGameEventListener;
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A behavior is simply a type that is able to listen to events.
|
||||||
|
*
|
||||||
|
* @see IGameEventListener
|
||||||
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,7 +37,26 @@ public interface IPathingBehavior extends IBehavior {
|
|||||||
*
|
*
|
||||||
* @return The estimated remaining ticks in the current segment.
|
* @return The estimated remaining ticks in the current segment.
|
||||||
*/
|
*/
|
||||||
Optional<Double> ticksRemainingInSegment();
|
default Optional<Double> ticksRemainingInSegment() {
|
||||||
|
return ticksRemainingInSegment(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the estimated remaining ticks in the current pathing
|
||||||
|
* segment. Given that the return type is an optional, {@link Optional#empty()}
|
||||||
|
* will be returned in the case that there is no current segment being pathed.
|
||||||
|
*
|
||||||
|
* @param includeCurrentMovement whether or not to include the entirety of the cost of the currently executing movement in the total
|
||||||
|
* @return The estimated remaining ticks in the current segment.
|
||||||
|
*/
|
||||||
|
default Optional<Double> ticksRemainingInSegment(boolean includeCurrentMovement) {
|
||||||
|
IPathExecutor current = getCurrent();
|
||||||
|
if (current == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
int start = includeCurrentMovement ? current.getPosition() : current.getPosition() + 1;
|
||||||
|
return Optional.of(current.getPath().ticksRemainingFrom(start));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The current pathing goal
|
* @return The current pathing goal
|
||||||
@@ -47,7 +66,9 @@ public interface IPathingBehavior extends IBehavior {
|
|||||||
/**
|
/**
|
||||||
* @return Whether or not a path is currently being executed.
|
* @return Whether or not a path is currently being executed.
|
||||||
*/
|
*/
|
||||||
boolean isPathing();
|
default boolean isPathing() {
|
||||||
|
return getCurrent() != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
|
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,7 @@ package baritone.api.cache;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@@ -68,7 +68,7 @@ public interface ICachedWorld {
|
|||||||
* @param maxRegionDistanceSq The maximum region distance, squared
|
* @param maxRegionDistanceSq The maximum region distance, squared
|
||||||
* @return The locations found that match the special block
|
* @return The locations found that match the special block
|
||||||
*/
|
*/
|
||||||
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq);
|
ArrayList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads all of the cached regions in this world from disk. Anything that is not saved
|
* Reloads all of the cached regions in this world from disk. Anything that is not saved
|
||||||
|
|||||||
@@ -17,22 +17,20 @@
|
|||||||
|
|
||||||
package baritone.api.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.api.event.events.type.ManagedPlayerEvent;
|
import baritone.api.event.events.type.Cancellable;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018
|
* @since 8/1/2018
|
||||||
*/
|
*/
|
||||||
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
|
public final class ChatEvent extends Cancellable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The message being sent
|
* The message being sent
|
||||||
*/
|
*/
|
||||||
private final String message;
|
private final String message;
|
||||||
|
|
||||||
public ChatEvent(EntityPlayerSP player, String message) {
|
public ChatEvent(String message) {
|
||||||
super(player);
|
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,22 +18,19 @@
|
|||||||
package baritone.api.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.api.event.events.type.ManagedPlayerEvent;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/21/2018
|
* @since 8/21/2018
|
||||||
*/
|
*/
|
||||||
public final class PlayerUpdateEvent extends ManagedPlayerEvent {
|
public final class PlayerUpdateEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The state of the event
|
* The state of the event
|
||||||
*/
|
*/
|
||||||
private final EventState state;
|
private final EventState state;
|
||||||
|
|
||||||
public PlayerUpdateEvent(EntityPlayerSP player, EventState state) {
|
public PlayerUpdateEvent(EventState state) {
|
||||||
super(player);
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
package baritone.api.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.api.event.events.type.ManagedPlayerEvent;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
|
||||||
@@ -26,7 +24,7 @@ import net.minecraft.entity.EntityLivingBase;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/21/2018
|
* @since 8/21/2018
|
||||||
*/
|
*/
|
||||||
public final class RotationMoveEvent extends ManagedPlayerEvent {
|
public final class RotationMoveEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of event
|
* The type of event
|
||||||
@@ -38,8 +36,7 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
|
|||||||
*/
|
*/
|
||||||
private float yaw;
|
private float yaw;
|
||||||
|
|
||||||
public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
|
public RotationMoveEvent(Type type, float yaw) {
|
||||||
super(player);
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.yaw = yaw;
|
this.yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.event.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 1/18/2019
|
||||||
|
*/
|
||||||
|
public final class SprintStateEvent {
|
||||||
|
|
||||||
|
private Boolean state;
|
||||||
|
|
||||||
|
public final void setState(boolean state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Boolean getState() {
|
||||||
|
return this.state;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,61 +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.api.event.events.type;
|
|
||||||
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An event that has a reference to a locally managed player.
|
|
||||||
*
|
|
||||||
* @author Brady
|
|
||||||
* @since 10/11/2018
|
|
||||||
*/
|
|
||||||
public class ManagedPlayerEvent {
|
|
||||||
|
|
||||||
protected final EntityPlayerSP player;
|
|
||||||
|
|
||||||
public ManagedPlayerEvent(EntityPlayerSP player) {
|
|
||||||
this.player = player;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final EntityPlayerSP getPlayer() {
|
|
||||||
return this.player;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Cancellable extends ManagedPlayerEvent implements ICancellable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not this event has been cancelled
|
|
||||||
*/
|
|
||||||
private boolean cancelled;
|
|
||||||
|
|
||||||
public Cancellable(EntityPlayerSP player) {
|
|
||||||
super(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void cancel() {
|
|
||||||
this.cancelled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean isCancelled() {
|
|
||||||
return this.cancelled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -57,6 +57,9 @@ public interface AbstractGameEventListener extends IGameEventListener {
|
|||||||
@Override
|
@Override
|
||||||
default void onPlayerRotationMove(RotationMoveEvent event) {}
|
default void onPlayerRotationMove(RotationMoveEvent event) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void onPlayerSprintState(SprintStateEvent event) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void onBlockInteract(BlockInteractEvent event) {}
|
default void onBlockInteract(BlockInteractEvent event) {}
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,14 @@ public interface IGameEventListener {
|
|||||||
*/
|
*/
|
||||||
void onPlayerRotationMove(RotationMoveEvent event);
|
void onPlayerRotationMove(RotationMoveEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate}
|
||||||
|
*
|
||||||
|
* @param event The event
|
||||||
|
* @see EntityPlayerSP#onLivingUpdate()
|
||||||
|
*/
|
||||||
|
void onPlayerSprintState(SprintStateEvent event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the local player interacts with a block, whether it is breaking or opening/placing.
|
* Called when the local player interacts with a block, whether it is breaking or opening/placing.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,10 +22,26 @@ import baritone.api.process.PathingCommand;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
public interface IPathingControlManager {
|
public interface IPathingControlManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a process with this pathing control manager. See {@link IBaritoneProcess} for more details.
|
||||||
|
*
|
||||||
|
* @param process The process
|
||||||
|
* @see IBaritoneProcess
|
||||||
|
*/
|
||||||
void registerProcess(IBaritoneProcess process);
|
void registerProcess(IBaritoneProcess process);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The most recent {@link IBaritoneProcess} that had control
|
||||||
|
*/
|
||||||
Optional<IBaritoneProcess> mostRecentInControl();
|
Optional<IBaritoneProcess> mostRecentInControl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The most recent pathing command executed
|
||||||
|
*/
|
||||||
Optional<PathingCommand> mostRecentCommand();
|
Optional<PathingCommand> mostRecentCommand();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class GoalAxis implements Goal {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(int x, int y, int z) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
return y == BaritoneAPI.getSettings().axisHeight.get() && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
|
return y == BaritoneAPI.getSettings().axisHeight.value && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -39,7 +39,7 @@ public class GoalAxis implements Goal {
|
|||||||
|
|
||||||
double flatAxisDistance = Math.min(x, Math.min(z, diff * SQRT_2_OVER_2));
|
double flatAxisDistance = Math.min(x, Math.min(z, diff * SQRT_2_OVER_2));
|
||||||
|
|
||||||
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.get() + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.get(), y);
|
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,17 +30,17 @@ public class GoalBlock implements Goal, IGoalRenderPos {
|
|||||||
/**
|
/**
|
||||||
* The X block position of this goal
|
* The X block position of this goal
|
||||||
*/
|
*/
|
||||||
private final int x;
|
public final int x;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Y block position of this goal
|
* The Y block position of this goal
|
||||||
*/
|
*/
|
||||||
private final int y;
|
public final int y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Z block position of this goal
|
* The Z block position of this goal
|
||||||
*/
|
*/
|
||||||
private final int z;
|
public final int z;
|
||||||
|
|
||||||
public GoalBlock(BlockPos pos) {
|
public GoalBlock(BlockPos pos) {
|
||||||
this(pos.getX(), pos.getY(), pos.getZ());
|
this(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
*/
|
*/
|
||||||
public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
||||||
|
|
||||||
private final int x;
|
public final int x;
|
||||||
private final int y;
|
public final int y;
|
||||||
private final int z;
|
public final int z;
|
||||||
|
|
||||||
public GoalGetToBlock(BlockPos pos) {
|
public GoalGetToBlock(BlockPos pos) {
|
||||||
this.x = pos.getX();
|
this.x = pos.getX();
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ public class GoalXZ implements Goal {
|
|||||||
diagonal = z;
|
diagonal = z;
|
||||||
}
|
}
|
||||||
diagonal *= SQRT_2;
|
diagonal *= SQRT_2;
|
||||||
return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.get(); // big TODO tune
|
return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.value; // big TODO tune
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {
|
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {
|
||||||
|
|||||||
@@ -45,10 +45,6 @@ public interface IMovement {
|
|||||||
*/
|
*/
|
||||||
boolean safeToCancel();
|
boolean safeToCancel();
|
||||||
|
|
||||||
double recalculateCost();
|
|
||||||
|
|
||||||
double calculateCostWithoutCaching();
|
|
||||||
|
|
||||||
boolean calculatedWhileLoaded();
|
boolean calculatedWhileLoaded();
|
||||||
|
|
||||||
BetterBlockPos getSrc();
|
BetterBlockPos getSrc();
|
||||||
|
|||||||
@@ -26,4 +26,6 @@ import baritone.api.pathing.calc.IPath;
|
|||||||
public interface IPathExecutor {
|
public interface IPathExecutor {
|
||||||
|
|
||||||
IPath getPath();
|
IPath getPath();
|
||||||
|
|
||||||
|
int getPosition();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package baritone.api.process;
|
package baritone.api.process;
|
||||||
|
|
||||||
import baritone.api.IBaritone;
|
|
||||||
import baritone.api.behavior.IPathingBehavior;
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
import baritone.api.event.events.PathEvent;
|
import baritone.api.event.events.PathEvent;
|
||||||
|
|
||||||
@@ -25,8 +24,10 @@ import baritone.api.event.events.PathEvent;
|
|||||||
* A process that can control the PathingBehavior.
|
* A process that can control the PathingBehavior.
|
||||||
* <p>
|
* <p>
|
||||||
* Differences between a baritone process and a behavior:
|
* Differences between a baritone process and a behavior:
|
||||||
* Only one baritone process can be active at a time
|
* <ul>
|
||||||
* PathingBehavior can only be controlled by a process
|
* <li>Only one baritone process can be active at a time</li>
|
||||||
|
* <li>PathingBehavior can only be controlled by a process</li>
|
||||||
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
* That's it actually
|
* That's it actually
|
||||||
*
|
*
|
||||||
@@ -34,6 +35,16 @@ import baritone.api.event.events.PathEvent;
|
|||||||
*/
|
*/
|
||||||
public interface IBaritoneProcess {
|
public interface IBaritoneProcess {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default priority. Most normal processes should have this value.
|
||||||
|
* <p>
|
||||||
|
* Some examples of processes that should have different values might include some kind of automated mob avoidance
|
||||||
|
* that would be temporary and would forcefully take control. Same for something that pauses pathing for auto eat, etc.
|
||||||
|
* <p>
|
||||||
|
* The value is -1 beacuse that's what Impact 4.5's beta auto walk returns and I want to tie with it.
|
||||||
|
*/
|
||||||
|
double DEFAULT_PRIORITY = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Would this process like to be in control?
|
* Would this process like to be in control?
|
||||||
*
|
*
|
||||||
@@ -81,19 +92,23 @@ public interface IBaritoneProcess {
|
|||||||
*
|
*
|
||||||
* @return A double representing the priority
|
* @return A double representing the priority
|
||||||
*/
|
*/
|
||||||
double priority();
|
default double priority() {
|
||||||
|
return DEFAULT_PRIORITY;
|
||||||
/**
|
}
|
||||||
* Returns which bot this process is associated with. (5000000iq forward thinking)
|
|
||||||
*
|
|
||||||
* @return The Bot associated with this process
|
|
||||||
*/
|
|
||||||
IBaritone associatedWith();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a user-friendly name for this process. Suitable for a HUD.
|
* Returns a user-friendly name for this process. Suitable for a HUD.
|
||||||
*
|
*
|
||||||
* @return A display name that's suitable for a HUD
|
* @return A display name that's suitable for a HUD
|
||||||
*/
|
*/
|
||||||
String displayName();
|
default String displayName() {
|
||||||
|
if (!isActive()) {
|
||||||
|
// i love it when impcat's scuffed HUD calls displayName for inactive processes for 1 tick too long
|
||||||
|
// causing NPEs when the displayname relies on fields that become null when inactive
|
||||||
|
return "INACTIVE";
|
||||||
|
}
|
||||||
|
return displayName0();
|
||||||
|
}
|
||||||
|
|
||||||
|
String displayName0();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import baritone.api.utils.ISchematic;
|
||||||
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 1/15/2019
|
||||||
|
*/
|
||||||
|
public interface IBuilderProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a build for the specified schematic, labeled as specified, with the specified origin.
|
||||||
|
*
|
||||||
|
* @param name A user-friendly name for the schematic
|
||||||
|
* @param schematic The object representation of the schematic
|
||||||
|
* @param origin The origin position of the schematic being built
|
||||||
|
*/
|
||||||
|
void build(String name, ISchematic schematic, Vec3i origin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a build for the specified schematic, labeled as specified, with the specified origin.
|
||||||
|
*
|
||||||
|
* @param name A user-friendly name for the schematic
|
||||||
|
* @param schematic The file path of the schematic
|
||||||
|
* @param origin The origin position of the schematic being built
|
||||||
|
* @return Whether or not the schematic was able to load from file
|
||||||
|
*/
|
||||||
|
boolean build(String name, File schematic, Vec3i origin);
|
||||||
|
}
|
||||||
@@ -53,4 +53,9 @@ public class PathingCommand {
|
|||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
this.commandType = commandType;
|
this.commandType = commandType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return commandType + " " + goal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package baritone.api.utils;
|
|||||||
|
|
||||||
import baritone.api.behavior.IBehavior;
|
import baritone.api.behavior.IBehavior;
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@@ -27,8 +26,6 @@ import net.minecraft.client.settings.KeyBinding;
|
|||||||
*/
|
*/
|
||||||
public interface IInputOverrideHandler extends IBehavior {
|
public interface IInputOverrideHandler extends IBehavior {
|
||||||
|
|
||||||
Boolean isInputForcedDown(KeyBinding key);
|
|
||||||
|
|
||||||
boolean isInputForcedDown(Input input);
|
boolean isInputForcedDown(Input input);
|
||||||
|
|
||||||
void setInputForceState(Input input, boolean forced);
|
void setInputForceState(Input input, boolean forced);
|
||||||
|
|||||||
@@ -17,12 +17,17 @@
|
|||||||
|
|
||||||
package baritone.api.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.inventory.ClickType;
|
import net.minecraft.inventory.ClickType;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.EnumActionResult;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.GameType;
|
import net.minecraft.world.GameType;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
@@ -43,4 +48,6 @@ public interface IPlayerController {
|
|||||||
default double getBlockReachDistance() {
|
default double getBlockReachDistance() {
|
||||||
return this.getGameType().isCreative() ? 5.0F : 4.5F;
|
return this.getGameType().isCreative() ? 5.0F : 4.5F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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.state.IBlockState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic representation of a schematic. Provides the dimensions and
|
||||||
|
* the desired statefor a given position relative to the origin.
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public interface ISchematic {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the block at this coordinate matter to the schematic?
|
||||||
|
* <p>
|
||||||
|
* Normally just a check for if the coordinate is in the cube.
|
||||||
|
* <p>
|
||||||
|
* However, in the case of something like a map art, anything that's below the level of the map art doesn't matter,
|
||||||
|
* so this function should return false in that case. (i.e. it doesn't really have to be air below the art blocks)
|
||||||
|
*
|
||||||
|
* @param x The x position of the block, relative to the origin
|
||||||
|
* @param y The y position of the block, relative to the origin
|
||||||
|
* @param z The z position of the block, relative to the origin
|
||||||
|
* @return Whether or not the specified position is within the bounds of this schematic
|
||||||
|
*/
|
||||||
|
default boolean inSchematic(int x, int y, int z) {
|
||||||
|
return x >= 0 && x < widthX() && y >= 0 && y < heightY() && z >= 0 && z < lengthZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the desired block state at a given (X, Y, Z) position relative to the origin (0, 0, 0).
|
||||||
|
*
|
||||||
|
* @param x The x position of the block, relative to the origin
|
||||||
|
* @param y The y position of the block, relative to the origin
|
||||||
|
* @param z The z position of the block, relative to the origin
|
||||||
|
* @return The desired block state at the specified position
|
||||||
|
*/
|
||||||
|
IBlockState desiredState(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The width (X axis length) of this schematic
|
||||||
|
*/
|
||||||
|
int widthX();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The height (Y axis length) of this schematic
|
||||||
|
*/
|
||||||
|
int heightY();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The length (Z axis length) of this schematic
|
||||||
|
*/
|
||||||
|
int lengthZ();
|
||||||
|
}
|
||||||
@@ -117,8 +117,12 @@ public class Rotation {
|
|||||||
* @return are they really close
|
* @return are they really close
|
||||||
*/
|
*/
|
||||||
public boolean isReallyCloseTo(Rotation other) {
|
public boolean isReallyCloseTo(Rotation other) {
|
||||||
float yawDiff = Math.abs(this.yaw - other.yaw); // you cant fool me
|
return yawIsReallyClose(other) && Math.abs(this.pitch - other.pitch) < 0.01;
|
||||||
return (yawDiff < 0.01 || yawDiff > 359.9) && Math.abs(this.pitch - other.pitch) < 0.01;
|
}
|
||||||
|
|
||||||
|
public boolean yawIsReallyClose(Rotation other) {
|
||||||
|
float yawDiff = Math.abs(normalizeYaw(yaw) - normalizeYaw(other.yaw)); // you cant fool me
|
||||||
|
return (yawDiff < 0.01 || yawDiff > 359.99);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,4 +151,9 @@ public class Rotation {
|
|||||||
}
|
}
|
||||||
return newYaw;
|
return newYaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Yaw: " + yaw + ", Pitch: " + pitch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,9 @@ public final class RotationUtils {
|
|||||||
* @return The wrapped angles
|
* @return The wrapped angles
|
||||||
*/
|
*/
|
||||||
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
|
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
|
||||||
|
if (current.yawIsReallyClose(target)) {
|
||||||
|
return new Rotation(current.getYaw(), target.getPitch());
|
||||||
|
}
|
||||||
return target.subtract(current).normalize().add(current);
|
return target.subtract(current).normalize().add(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +105,7 @@ public final class RotationUtils {
|
|||||||
* @param dest The destination position
|
* @param dest The destination position
|
||||||
* @return The rotation from the origin to the destination
|
* @return The rotation from the origin to the destination
|
||||||
*/
|
*/
|
||||||
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
|
private static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
|
||||||
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
|
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
|
||||||
double yaw = MathHelper.atan2(delta[0], -delta[2]);
|
double yaw = MathHelper.atan2(delta[0], -delta[2]);
|
||||||
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
|
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
|
||||||
@@ -196,7 +199,7 @@ public final class RotationUtils {
|
|||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
||||||
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
|
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
|
||||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
||||||
//System.out.println(result);
|
//System.out.println(result);
|
||||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
|
|||||||
@@ -27,10 +27,8 @@ import java.io.BufferedWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
import java.util.List;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@@ -89,22 +87,8 @@ public class SettingsUtil {
|
|||||||
|
|
||||||
public static synchronized void save(Settings settings) {
|
public static synchronized void save(Settings settings) {
|
||||||
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
|
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
|
||||||
for (Settings.Setting setting : settings.allSettings) {
|
for (Settings.Setting setting : modifiedSettings(settings)) {
|
||||||
if (setting.get() == null) {
|
out.write(settingToString(setting) + "\n");
|
||||||
System.out.println("NULL SETTING?" + setting.getName());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (setting.getName().equals("logger")) {
|
|
||||||
continue; // NO
|
|
||||||
}
|
|
||||||
if (setting.value == setting.defaultValue) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SettingsIO io = map.get(setting.getValueClass());
|
|
||||||
if (io == null) {
|
|
||||||
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting + " " + setting.getName());
|
|
||||||
}
|
|
||||||
out.write(setting.getName() + " " + io.toString.apply(setting.get()) + "\n");
|
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
System.out.println("Exception thrown while saving Baritone settings!");
|
System.out.println("Exception thrown while saving Baritone settings!");
|
||||||
@@ -112,7 +96,36 @@ public class SettingsUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
|
public static List<Settings.Setting> modifiedSettings(Settings settings) {
|
||||||
|
List<Settings.Setting> modified = new ArrayList<>();
|
||||||
|
for (Settings.Setting setting : settings.allSettings) {
|
||||||
|
if (setting.value == null) {
|
||||||
|
System.out.println("NULL SETTING?" + setting.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (setting.getName().equals("logger")) {
|
||||||
|
continue; // NO
|
||||||
|
}
|
||||||
|
if (setting.value == setting.defaultValue) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
modified.add(setting);
|
||||||
|
}
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
|
||||||
|
if (setting.getName().equals("logger")) {
|
||||||
|
return "logger";
|
||||||
|
}
|
||||||
|
SettingsIO io = map.get(setting.getValueClass());
|
||||||
|
if (io == null) {
|
||||||
|
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
|
||||||
|
}
|
||||||
|
return setting.getName() + " " + io.toString.apply(setting.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
|
||||||
Settings.Setting setting = settings.byLowerName.get(settingName);
|
Settings.Setting setting = settings.byLowerName.get(settingName);
|
||||||
if (setting == null) {
|
if (setting == null) {
|
||||||
throw new IllegalStateException("No setting by that name");
|
throw new IllegalStateException("No setting by that name");
|
||||||
|
|||||||
@@ -17,15 +17,6 @@
|
|||||||
|
|
||||||
package baritone.api.utils.input;
|
package baritone.api.utils.input;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.settings.GameSettings;
|
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link Enum} representing the inputs that control the player's
|
* An {@link Enum} representing the inputs that control the player's
|
||||||
* behavior. This includes moving, interacting with blocks, jumping,
|
* behavior. This includes moving, interacting with blocks, jumping,
|
||||||
@@ -36,84 +27,45 @@ public enum Input {
|
|||||||
/**
|
/**
|
||||||
* The move forward input
|
* The move forward input
|
||||||
*/
|
*/
|
||||||
MOVE_FORWARD(s -> s.keyBindForward),
|
MOVE_FORWARD,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The move back input
|
* The move back input
|
||||||
*/
|
*/
|
||||||
MOVE_BACK(s -> s.keyBindBack),
|
MOVE_BACK,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The move left input
|
* The move left input
|
||||||
*/
|
*/
|
||||||
MOVE_LEFT(s -> s.keyBindLeft),
|
MOVE_LEFT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The move right input
|
* The move right input
|
||||||
*/
|
*/
|
||||||
MOVE_RIGHT(s -> s.keyBindRight),
|
MOVE_RIGHT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attack input
|
* The attack input
|
||||||
*/
|
*/
|
||||||
CLICK_LEFT(s -> s.keyBindAttack),
|
CLICK_LEFT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The use item input
|
* The use item input
|
||||||
*/
|
*/
|
||||||
CLICK_RIGHT(s -> s.keyBindUseItem),
|
CLICK_RIGHT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The jump input
|
* The jump input
|
||||||
*/
|
*/
|
||||||
JUMP(s -> s.keyBindJump),
|
JUMP,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sneak input
|
* The sneak input
|
||||||
*/
|
*/
|
||||||
SNEAK(s -> s.keyBindSneak),
|
SNEAK,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sprint input
|
* The sprint input
|
||||||
*/
|
*/
|
||||||
SPRINT(s -> s.keyBindSprint);
|
SPRINT
|
||||||
|
|
||||||
/**
|
|
||||||
* Map of {@link KeyBinding} to {@link Input}. Values should be queried through {@link #getInputForBind(KeyBinding)}
|
|
||||||
*/
|
|
||||||
private static final Map<KeyBinding, Input> bindToInputMap = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The actual game {@link KeyBinding} being forced.
|
|
||||||
*/
|
|
||||||
private final KeyBinding keyBinding;
|
|
||||||
|
|
||||||
Input(Function<GameSettings, KeyBinding> keyBindingMapper) {
|
|
||||||
/*
|
|
||||||
|
|
||||||
Here, a Function is used because referring to a static field in this enum for the game instance,
|
|
||||||
as it was before, wouldn't be possible in an Enum constructor unless the static field was in an
|
|
||||||
interface that this class implemented. (Helper acted as this interface) I didn't feel like making
|
|
||||||
an interface with a game instance field just to not have to do this.
|
|
||||||
|
|
||||||
*/
|
|
||||||
this.keyBinding = keyBindingMapper.apply(Minecraft.getMinecraft().gameSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The actual game {@link KeyBinding} being forced.
|
|
||||||
*/
|
|
||||||
public final KeyBinding getKeyBinding() {
|
|
||||||
return this.keyBinding;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the {@link Input} constant that is associated with the specified {@link KeyBinding}.
|
|
||||||
*
|
|
||||||
* @param binding The {@link KeyBinding} to find the associated {@link Input} for
|
|
||||||
* @return The {@link Input} associated with the specified {@link KeyBinding}
|
|
||||||
*/
|
|
||||||
public static Input getInputForBind(KeyBinding binding) {
|
|
||||||
return bindToInputMap.computeIfAbsent(binding, b -> Arrays.stream(values()).filter(input -> input.keyBinding == b).findFirst().orElse(null));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.mixins;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.ChunkRenderContainer;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.chunk.RenderChunk;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import org.lwjgl.opengl.GL14;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
|
|
||||||
|
@Mixin(ChunkRenderContainer.class)
|
||||||
|
public class MixinChunkRenderContainer {
|
||||||
|
|
||||||
|
@Redirect( // avoid creating CallbackInfo at all costs; this is called 40k times per second
|
||||||
|
method = "preRenderChunk",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/client/renderer/chunk/RenderChunk.getPosition()Lnet/minecraft/util/math/BlockPos;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private BlockPos getPosition(RenderChunk renderChunkIn) {
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null && Minecraft.getMinecraft().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
|
||||||
|
GlStateManager.enableAlpha();
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GL14.glBlendColor(0, 0, 0, Baritone.settings().cachedChunksOpacity.value);
|
||||||
|
GlStateManager.tryBlendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
|
||||||
|
}
|
||||||
|
return renderChunkIn.getPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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.mixins;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkRenderWorker;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(ChunkRenderWorker.class)
|
||||||
|
public abstract class MixinChunkRenderWorker {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected abstract boolean isChunkExisting(BlockPos pos, World worldIn);
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "processTask",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/client/renderer/chunk/ChunkRenderWorker.isChunkExisting(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/World;)Z"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private boolean isChunkExisting(ChunkRenderWorker worker, BlockPos pos, World world) {
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
|
||||||
|
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
|
IPlayerContext ctx = baritone.getPlayerContext();
|
||||||
|
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||||
|
return baritone.bsi.isLoaded(pos.getX(), pos.getZ()) || this.isChunkExisting(pos, world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.isChunkExisting(pos, world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,74 +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.mixins;
|
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Brady
|
|
||||||
* @since 8/21/2018
|
|
||||||
*/
|
|
||||||
@Mixin(Entity.class)
|
|
||||||
public class MixinEntity {
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public float rotationYaw;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event called to override the movement direction when walking
|
|
||||||
*/
|
|
||||||
private RotationMoveEvent motionUpdateRotationEvent;
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "moveRelative",
|
|
||||||
at = @At("HEAD")
|
|
||||||
)
|
|
||||||
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
|
||||||
// noinspection ConstantConditions
|
|
||||||
if (EntityPlayerSP.class.isInstance(this)) {
|
|
||||||
this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
|
|
||||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(
|
|
||||||
method = "moveRelative",
|
|
||||||
at = @At(
|
|
||||||
value = "FIELD",
|
|
||||||
opcode = GETFIELD,
|
|
||||||
target = "net/minecraft/entity/Entity.rotationYaw:F"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
private float overrideYaw(Entity self) {
|
|
||||||
if (self instanceof EntityPlayerSP) {
|
|
||||||
return this.motionUpdateRotationEvent.getYaw();
|
|
||||||
}
|
|
||||||
return self.rotationYaw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
import baritone.api.event.events.RotationMoveEvent;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@@ -55,8 +56,11 @@ public abstract class MixinEntityLivingBase extends Entity {
|
|||||||
private void preMoveRelative(CallbackInfo ci) {
|
private void preMoveRelative(CallbackInfo ci) {
|
||||||
// noinspection ConstantConditions
|
// noinspection ConstantConditions
|
||||||
if (EntityPlayerSP.class.isInstance(this)) {
|
if (EntityPlayerSP.class.isInstance(this)) {
|
||||||
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
if (baritone != null) {
|
||||||
|
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw);
|
||||||
|
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,9 +73,30 @@ public abstract class MixinEntityLivingBase extends Entity {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private float overrideYaw(EntityLivingBase self) {
|
private float overrideYaw(EntityLivingBase self) {
|
||||||
if (self instanceof EntityPlayerSP) {
|
if (self instanceof EntityPlayerSP && BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) != null) {
|
||||||
return this.jumpRotationEvent.getYaw();
|
return this.jumpRotationEvent.getYaw();
|
||||||
}
|
}
|
||||||
return self.rotationYaw;
|
return self.rotationYaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "travel",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void travel(EntityLivingBase self, float strafe, float up, float forward, float friction) {
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
if (!EntityPlayerSP.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) == null) {
|
||||||
|
moveRelative(strafe, up, forward, friction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
|
||||||
|
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent);
|
||||||
|
float originalYaw = this.rotationYaw;
|
||||||
|
this.rotationYaw = motionUpdateRotationEvent.getYaw();
|
||||||
|
this.moveRelative(strafe, up, forward, friction);
|
||||||
|
this.rotationYaw = originalYaw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,14 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.behavior.IPathingBehavior;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.ChatEvent;
|
import baritone.api.event.events.ChatEvent;
|
||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
|
import baritone.api.event.events.SprintStateEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
|
import baritone.behavior.LookBehavior;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
import net.minecraft.entity.player.PlayerCapabilities;
|
import net.minecraft.entity.player.PlayerCapabilities;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -43,8 +46,12 @@ public class MixinEntityPlayerSP {
|
|||||||
cancellable = true
|
cancellable = true
|
||||||
)
|
)
|
||||||
private void sendChatMessage(String msg, CallbackInfo ci) {
|
private void sendChatMessage(String msg, CallbackInfo ci) {
|
||||||
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
|
ChatEvent event = new ChatEvent(msg);
|
||||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onSendChatMessage(event);
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||||
|
if (baritone == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
baritone.getGameEventHandler().onSendChatMessage(event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
@@ -60,7 +67,10 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void onPreUpdate(CallbackInfo ci) {
|
private void onPreUpdate(CallbackInfo ci) {
|
||||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||||
|
if (baritone != null) {
|
||||||
|
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -73,7 +83,10 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void onPostUpdate(CallbackInfo ci) {
|
private void onPostUpdate(CallbackInfo ci) {
|
||||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||||
|
if (baritone != null) {
|
||||||
|
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(
|
@Redirect(
|
||||||
@@ -84,7 +97,47 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
||||||
IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior();
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||||
return !pathingBehavior.isPathing() && capabilities.allowFlying;
|
if (baritone == null) {
|
||||||
|
return capabilities.allowFlying;
|
||||||
|
}
|
||||||
|
return !baritone.getPathingBehavior().isPathing() && capabilities.allowFlying;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "onLivingUpdate",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private boolean isKeyDown(KeyBinding keyBinding) {
|
||||||
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||||
|
if (baritone == null) {
|
||||||
|
return keyBinding.isKeyDown();
|
||||||
|
}
|
||||||
|
SprintStateEvent event = new SprintStateEvent();
|
||||||
|
baritone.getGameEventHandler().onPlayerSprintState(event);
|
||||||
|
if (event.getState() != null) {
|
||||||
|
return event.getState();
|
||||||
|
}
|
||||||
|
if (baritone != BaritoneAPI.getProvider().getPrimaryBaritone()) {
|
||||||
|
// hitting control shouldn't make all bots sprint
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return keyBinding.isKeyDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "updateRidden",
|
||||||
|
at = @At(
|
||||||
|
value = "HEAD"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void updateRidden(CallbackInfo cb) {
|
||||||
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||||
|
if (baritone != null) {
|
||||||
|
((LookBehavior) baritone.getLookBehavior()).pig();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +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.mixins;
|
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
|
||||||
import baritone.utils.Helper;
|
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Brady
|
|
||||||
* @since 7/31/2018
|
|
||||||
*/
|
|
||||||
@Mixin(KeyBinding.class)
|
|
||||||
public class MixinKeyBinding {
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
public int pressTime;
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "isKeyDown",
|
|
||||||
at = @At("HEAD"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
// only the primary baritone forces keys
|
|
||||||
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
|
|
||||||
if (force != null) {
|
|
||||||
cir.setReturnValue(force); // :sunglasses:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "isPressed",
|
|
||||||
at = @At("HEAD"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
private void isPressed(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
// only the primary baritone forces keys
|
|
||||||
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
|
|
||||||
if (force != null && force == false) { // <-- cursed
|
|
||||||
if (pressTime > 0) {
|
|
||||||
Helper.HELPER.logDirect("You're trying to press this mouse button but I won't let you");
|
|
||||||
pressTime--;
|
|
||||||
}
|
|
||||||
cir.setReturnValue(force); // :sunglasses:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* 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.mixins;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.chunk.RenderChunk;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ChunkCache;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 1/29/2019
|
||||||
|
*/
|
||||||
|
@Mixin(RenderChunk.class)
|
||||||
|
public class MixinRenderChunk {
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "rebuildChunk",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/world/ChunkCache.isEmpty()Z"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private boolean isEmpty(ChunkCache chunkCache) {
|
||||||
|
if (!chunkCache.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
|
||||||
|
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
|
IPlayerContext ctx = baritone.getPlayerContext();
|
||||||
|
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||||
|
BlockPos position = ((RenderChunk) (Object) this).getPosition();
|
||||||
|
// RenderChunk extends from -1,-1,-1 to +16,+16,+16
|
||||||
|
// then the constructor of ChunkCache extends it one more (presumably to get things like the connected status of fences? idk)
|
||||||
|
// so if ANY of the adjacent chunks are loaded, we are unempty
|
||||||
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
|
if (baritone.bsi.isLoaded(16 * dx + position.getX(), 16 * dz + position.getZ())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "rebuildChunk",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/world/ChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private IBlockState getBlockState(ChunkCache chunkCache, BlockPos pos) {
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
|
||||||
|
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
|
IPlayerContext ctx = baritone.getPlayerContext();
|
||||||
|
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||||
|
return baritone.bsi.get0(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunkCache.getBlockState(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.mixins;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.RenderList;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
|
|
||||||
|
@Mixin(RenderList.class)
|
||||||
|
public class MixinRenderList {
|
||||||
|
|
||||||
|
@Redirect( // avoid creating CallbackInfo at all costs; this is called 40k times per second
|
||||||
|
method = "renderChunkLayer",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/client/renderer/GlStateManager.popMatrix()V"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void popMatrix() {
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
|
||||||
|
// reset the blend func to normal (not dependent on constant alpha)
|
||||||
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||||
|
}
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.mixins;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.VboRenderList;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
|
|
||||||
|
@Mixin(VboRenderList.class)
|
||||||
|
public class MixinVboRenderList {
|
||||||
|
|
||||||
|
@Redirect( // avoid creating CallbackInfo at all costs; this is called 40k times per second
|
||||||
|
method = "renderChunkLayer",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/client/renderer/GlStateManager.popMatrix()V"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private void popMatrix() {
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && Minecraft.getMinecraft().getIntegratedServer() == null) {
|
||||||
|
// reset the blend func to normal (not dependent on constant alpha)
|
||||||
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||||
|
}
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,14 +12,17 @@
|
|||||||
"MixinBlockPos",
|
"MixinBlockPos",
|
||||||
"MixinChunkProviderClient",
|
"MixinChunkProviderClient",
|
||||||
"MixinChunkProviderServer",
|
"MixinChunkProviderServer",
|
||||||
"MixinEntity",
|
"MixinChunkRenderContainer",
|
||||||
|
"MixinChunkRenderWorker",
|
||||||
"MixinEntityLivingBase",
|
"MixinEntityLivingBase",
|
||||||
"MixinEntityPlayerSP",
|
"MixinEntityPlayerSP",
|
||||||
"MixinEntityRenderer",
|
"MixinEntityRenderer",
|
||||||
"MixinKeyBinding",
|
|
||||||
"MixinMinecraft",
|
"MixinMinecraft",
|
||||||
"MixinNetHandlerPlayClient",
|
"MixinNetHandlerPlayClient",
|
||||||
"MixinNetworkManager",
|
"MixinNetworkManager",
|
||||||
|
"MixinRenderChunk",
|
||||||
|
"MixinRenderList",
|
||||||
|
"MixinVboRenderList",
|
||||||
"MixinWorldClient"
|
"MixinWorldClient"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -25,14 +25,8 @@ import baritone.api.utils.IPlayerContext;
|
|||||||
import baritone.behavior.*;
|
import baritone.behavior.*;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.event.GameEventHandler;
|
import baritone.event.GameEventHandler;
|
||||||
import baritone.process.CustomGoalProcess;
|
import baritone.process.*;
|
||||||
import baritone.process.FollowProcess;
|
import baritone.utils.*;
|
||||||
import baritone.process.GetToBlockProcess;
|
|
||||||
import baritone.process.MineProcess;
|
|
||||||
import baritone.utils.BaritoneAutoTest;
|
|
||||||
import baritone.utils.ExampleBaritoneControl;
|
|
||||||
import baritone.utils.InputOverrideHandler;
|
|
||||||
import baritone.utils.PathingControlManager;
|
|
||||||
import baritone.utils.player.PrimaryPlayerContext;
|
import baritone.utils.player.PrimaryPlayerContext;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
@@ -77,22 +71,28 @@ public class Baritone implements IBaritone {
|
|||||||
private PathingBehavior pathingBehavior;
|
private PathingBehavior pathingBehavior;
|
||||||
private LookBehavior lookBehavior;
|
private LookBehavior lookBehavior;
|
||||||
private MemoryBehavior memoryBehavior;
|
private MemoryBehavior memoryBehavior;
|
||||||
|
private InventoryBehavior inventoryBehavior;
|
||||||
private InputOverrideHandler inputOverrideHandler;
|
private InputOverrideHandler inputOverrideHandler;
|
||||||
|
|
||||||
private FollowProcess followProcess;
|
private FollowProcess followProcess;
|
||||||
private MineProcess mineProcess;
|
private MineProcess mineProcess;
|
||||||
private GetToBlockProcess getToBlockProcess;
|
private GetToBlockProcess getToBlockProcess;
|
||||||
private CustomGoalProcess customGoalProcess;
|
private CustomGoalProcess customGoalProcess;
|
||||||
|
private BuilderProcess builderProcess;
|
||||||
|
private ExploreProcess exploreProcess;
|
||||||
|
|
||||||
private PathingControlManager pathingControlManager;
|
private PathingControlManager pathingControlManager;
|
||||||
|
|
||||||
private IPlayerContext playerContext;
|
private IPlayerContext playerContext;
|
||||||
private WorldProvider worldProvider;
|
private WorldProvider worldProvider;
|
||||||
|
|
||||||
|
public BlockStateInterface bsi;
|
||||||
|
|
||||||
Baritone() {
|
Baritone() {
|
||||||
this.gameEventHandler = new GameEventHandler(this);
|
this.gameEventHandler = new GameEventHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void init() {
|
public synchronized void init() {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return;
|
return;
|
||||||
@@ -107,7 +107,7 @@ public class Baritone implements IBaritone {
|
|||||||
pathingBehavior = new PathingBehavior(this);
|
pathingBehavior = new PathingBehavior(this);
|
||||||
lookBehavior = new LookBehavior(this);
|
lookBehavior = new LookBehavior(this);
|
||||||
memoryBehavior = new MemoryBehavior(this);
|
memoryBehavior = new MemoryBehavior(this);
|
||||||
new InventoryBehavior(this);
|
inventoryBehavior = new InventoryBehavior(this);
|
||||||
inputOverrideHandler = new InputOverrideHandler(this);
|
inputOverrideHandler = new InputOverrideHandler(this);
|
||||||
new ExampleBaritoneControl(this);
|
new ExampleBaritoneControl(this);
|
||||||
}
|
}
|
||||||
@@ -118,6 +118,8 @@ public class Baritone implements IBaritone {
|
|||||||
mineProcess = new MineProcess(this);
|
mineProcess = new MineProcess(this);
|
||||||
customGoalProcess = new CustomGoalProcess(this); // very high iq
|
customGoalProcess = new CustomGoalProcess(this); // very high iq
|
||||||
getToBlockProcess = new GetToBlockProcess(this);
|
getToBlockProcess = new GetToBlockProcess(this);
|
||||||
|
builderProcess = new BuilderProcess(this);
|
||||||
|
exploreProcess = new ExploreProcess(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.worldProvider = new WorldProvider();
|
this.worldProvider = new WorldProvider();
|
||||||
@@ -172,11 +174,24 @@ public class Baritone implements IBaritone {
|
|||||||
return this.followProcess;
|
return this.followProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BuilderProcess getBuilderProcess() {
|
||||||
|
return this.builderProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InventoryBehavior getInventoryBehavior() {
|
||||||
|
return this.inventoryBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LookBehavior getLookBehavior() {
|
public LookBehavior getLookBehavior() {
|
||||||
return this.lookBehavior;
|
return this.lookBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExploreProcess getExploreProcess() {
|
||||||
|
return this.exploreProcess;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MineProcess getMineProcess() {
|
public MineProcess getMineProcess() {
|
||||||
return this.mineProcess;
|
return this.mineProcess;
|
||||||
|
|||||||
@@ -21,13 +21,18 @@ import baritone.Baritone;
|
|||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.utils.ToolSet;
|
import baritone.utils.ToolSet;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.inventory.ClickType;
|
import net.minecraft.inventory.ClickType;
|
||||||
import net.minecraft.item.ItemPickaxe;
|
import net.minecraft.item.*;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.ItemTool;
|
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.NonNullList;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class InventoryBehavior extends Behavior {
|
public class InventoryBehavior extends Behavior {
|
||||||
public InventoryBehavior(Baritone baritone) {
|
public InventoryBehavior(Baritone baritone) {
|
||||||
super(baritone);
|
super(baritone);
|
||||||
@@ -35,7 +40,7 @@ public class InventoryBehavior extends Behavior {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTick(TickEvent event) {
|
public void onTick(TickEvent event) {
|
||||||
if (!Baritone.settings().allowInventory.get()) {
|
if (!Baritone.settings().allowInventory.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
@@ -54,6 +59,34 @@ public class InventoryBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void attemptToPutOnHotbar(int inMainInvy, Predicate<Integer> disallowedHotbar) {
|
||||||
|
OptionalInt destination = getTempHotbarSlot(disallowedHotbar);
|
||||||
|
if (destination.isPresent()) {
|
||||||
|
swapWithHotBar(inMainInvy, destination.getAsInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public OptionalInt getTempHotbarSlot(Predicate<Integer> disallowedHotbar) {
|
||||||
|
// we're using 0 and 8 for pickaxe and throwaway
|
||||||
|
ArrayList<Integer> candidates = new ArrayList<>();
|
||||||
|
for (int i = 1; i < 8; i++) {
|
||||||
|
if (ctx.player().inventory.mainInventory.get(i).isEmpty() && !disallowedHotbar.test(i)) {
|
||||||
|
candidates.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidates.isEmpty()) {
|
||||||
|
for (int i = 1; i < 8; i++) {
|
||||||
|
if (!disallowedHotbar.test(i)) {
|
||||||
|
candidates.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidates.isEmpty()) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
return OptionalInt.of(candidates.get(new Random().nextInt(candidates.size())));
|
||||||
|
}
|
||||||
|
|
||||||
private void swapWithHotBar(int inInventory, int inHotbar) {
|
private void swapWithHotBar(int inInventory, int inHotbar) {
|
||||||
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player());
|
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player());
|
||||||
}
|
}
|
||||||
@@ -61,7 +94,7 @@ public class InventoryBehavior extends Behavior {
|
|||||||
private int firstValidThrowaway() { // TODO offhand idk
|
private int firstValidThrowaway() { // TODO offhand idk
|
||||||
NonNullList<ItemStack> invy = ctx.player().inventory.mainInventory;
|
NonNullList<ItemStack> invy = ctx.player().inventory.mainInventory;
|
||||||
for (int i = 0; i < invy.size(); i++) {
|
for (int i = 0; i < invy.size(); i++) {
|
||||||
if (Baritone.settings().acceptableThrowawayItems.get().contains(invy.get(i).getItem())) {
|
if (Baritone.settings().acceptableThrowawayItems.value.contains(invy.get(i).getItem())) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,4 +120,62 @@ public class InventoryBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
return bestInd;
|
return bestInd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasGenericThrowaway() {
|
||||||
|
for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
|
||||||
|
if (throwaway(false, item::equals)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean selectThrowawayForLocation(int x, int y, int z) {
|
||||||
|
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z);
|
||||||
|
if (maybe != null && throwaway(true, item -> item instanceof ItemBlock && ((ItemBlock) item).getBlock().equals(maybe.getBlock()))) {
|
||||||
|
return true; // gotem
|
||||||
|
}
|
||||||
|
for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
|
||||||
|
if (throwaway(true, item::equals)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean throwaway(boolean select, Predicate<? super Item> desired) {
|
||||||
|
EntityPlayerSP p = ctx.player();
|
||||||
|
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||||
|
for (byte i = 0; i < 9; i++) {
|
||||||
|
ItemStack item = inv.get(i);
|
||||||
|
// this usage of settings() is okay because it's only called once during pathing
|
||||||
|
// (while creating the CalculationContext at the very beginning)
|
||||||
|
// and then it's called during execution
|
||||||
|
// since this function is never called during cost calculation, we don't need to migrate
|
||||||
|
// acceptableThrowawayItems to the CalculationContext
|
||||||
|
if (desired.test(item.getItem())) {
|
||||||
|
if (select) {
|
||||||
|
p.inventory.currentItem = i;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (desired.test(p.inventory.offHandInventory.get(0).getItem())) {
|
||||||
|
// main hand takes precedence over off hand
|
||||||
|
// that means that if we have block A selected in main hand and block B in off hand, right clicking places block B
|
||||||
|
// we've already checked above ^ and the main hand can't possible have an acceptablethrowawayitem
|
||||||
|
// so we need to select in the main hand something that doesn't right click
|
||||||
|
// so not a shovel, not a hoe, not a block, etc
|
||||||
|
for (byte i = 0; i < 9; i++) {
|
||||||
|
ItemStack item = inv.get(i);
|
||||||
|
if (item.isEmpty() || item.getItem() instanceof ItemPickaxe) {
|
||||||
|
if (select) {
|
||||||
|
p.inventory.currentItem = i;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
|||||||
@Override
|
@Override
|
||||||
public void updateTarget(Rotation target, boolean force) {
|
public void updateTarget(Rotation target, boolean force) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.force = force || !Baritone.settings().freeLook.get();
|
this.force = force || !Baritone.settings().freeLook.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -63,7 +63,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Whether or not we're going to silently set our angles
|
// Whether or not we're going to silently set our angles
|
||||||
boolean silent = Baritone.settings().antiCheatCompatibility.get() && !this.force;
|
boolean silent = Baritone.settings().antiCheatCompatibility.value && !this.force;
|
||||||
|
|
||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case PRE: {
|
case PRE: {
|
||||||
@@ -73,7 +73,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
|||||||
float desiredPitch = this.target.getPitch();
|
float desiredPitch = this.target.getPitch();
|
||||||
ctx.player().rotationPitch = desiredPitch;
|
ctx.player().rotationPitch = desiredPitch;
|
||||||
if (desiredPitch == oldPitch) {
|
if (desiredPitch == oldPitch) {
|
||||||
nudgeToLevel();
|
//nudgeToLevel();
|
||||||
}
|
}
|
||||||
this.target = null;
|
this.target = null;
|
||||||
}
|
}
|
||||||
@@ -95,15 +95,21 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void pig() {
|
||||||
|
if (this.target != null) {
|
||||||
|
ctx.player().rotationYaw = this.target.getYaw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerRotationMove(RotationMoveEvent event) {
|
public void onPlayerRotationMove(RotationMoveEvent event) {
|
||||||
if (this.target != null && !this.force) {
|
if (this.target != null) {
|
||||||
|
|
||||||
event.setYaw(this.target.getYaw());
|
event.setYaw(this.target.getYaw());
|
||||||
|
|
||||||
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
||||||
// Also the type has to be MOTION_UPDATE because that is called after JUMP
|
// Also the type has to be MOTION_UPDATE because that is called after JUMP
|
||||||
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
|
if (!Baritone.settings().antiCheatCompatibility.value && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE && !this.force) {
|
||||||
this.target = null;
|
this.target = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import baritone.api.event.events.TickEvent;
|
|||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.cache.ContainerMemory;
|
import baritone.cache.ContainerMemory;
|
||||||
import baritone.cache.Waypoint;
|
import baritone.cache.Waypoint;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockBed;
|
import net.minecraft.block.BlockBed;
|
||||||
@@ -48,6 +47,8 @@ import java.nio.file.Path;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* doesn't work for horse inventories :^)
|
||||||
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/6/2018
|
* @since 8/6/2018
|
||||||
*/
|
*/
|
||||||
@@ -63,6 +64,9 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onTick(TickEvent event) {
|
public synchronized void onTick(TickEvent event) {
|
||||||
|
if (!Baritone.settings().containerMemory.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
enderChestWindowId = null;
|
enderChestWindowId = null;
|
||||||
futureInventories.clear();
|
futureInventories.clear();
|
||||||
@@ -78,6 +82,9 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onSendPacket(PacketEvent event) {
|
public synchronized void onSendPacket(PacketEvent event) {
|
||||||
|
if (!Baritone.settings().containerMemory.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Packet p = event.getPacket();
|
Packet p = event.getPacket();
|
||||||
|
|
||||||
if (event.getState() == EventState.PRE) {
|
if (event.getState() == EventState.PRE) {
|
||||||
@@ -107,7 +114,6 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p instanceof CPacketCloseWindow) {
|
if (p instanceof CPacketCloseWindow) {
|
||||||
updateInventory();
|
|
||||||
getCurrent().save();
|
getCurrent().save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,6 +121,9 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onReceivePacket(PacketEvent event) {
|
public synchronized void onReceivePacket(PacketEvent event) {
|
||||||
|
if (!Baritone.settings().containerMemory.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Packet p = event.getPacket();
|
Packet p = event.getPacket();
|
||||||
|
|
||||||
if (event.getState() == EventState.PRE) {
|
if (event.getState() == EventState.PRE) {
|
||||||
@@ -142,7 +151,6 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p instanceof SPacketCloseWindow) {
|
if (p instanceof SPacketCloseWindow) {
|
||||||
updateInventory();
|
|
||||||
getCurrent().save();
|
getCurrent().save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,6 +170,9 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
|
|
||||||
|
|
||||||
private void updateInventory() {
|
private void updateInventory() {
|
||||||
|
if (!Baritone.settings().containerMemory.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int windowId = ctx.player().openContainer.windowId;
|
int windowId = ctx.player().openContainer.windowId;
|
||||||
if (enderChestWindowId != null) {
|
if (enderChestWindowId != null) {
|
||||||
if (windowId == enderChestWindowId) {
|
if (windowId == enderChestWindowId) {
|
||||||
@@ -184,7 +195,7 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
||||||
BlockStateInterface bsi = new CalculationContext(baritone).bsi;
|
BlockStateInterface bsi = baritone.bsi;
|
||||||
Block block = bsi.get0(in).getBlock();
|
Block block = bsi.get0(in).getBlock();
|
||||||
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
||||||
return null; // other things that have contents, but can be placed adjacent without combining
|
return null; // other things that have contents, but can be placed adjacent without combining
|
||||||
|
|||||||
@@ -19,13 +19,11 @@ package baritone.behavior;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.behavior.IPathingBehavior;
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
import baritone.api.event.events.PathEvent;
|
import baritone.api.event.events.*;
|
||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
|
||||||
import baritone.api.event.events.RenderEvent;
|
|
||||||
import baritone.api.event.events.TickEvent;
|
|
||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.goals.GoalXZ;
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
import baritone.api.utils.PathCalculationResult;
|
import baritone.api.utils.PathCalculationResult;
|
||||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
@@ -33,13 +31,12 @@ import baritone.pathing.calc.AStarPathFinder;
|
|||||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.path.CutoffPath;
|
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.PathRenderer;
|
import baritone.utils.PathRenderer;
|
||||||
|
import baritone.utils.PathingCommandContext;
|
||||||
import baritone.utils.pathing.Favoring;
|
import baritone.utils.pathing.Favoring;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -53,9 +50,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
private PathExecutor next;
|
private PathExecutor next;
|
||||||
|
|
||||||
private Goal goal;
|
private Goal goal;
|
||||||
|
private CalculationContext context;
|
||||||
|
|
||||||
private boolean safeToCancel;
|
private boolean safeToCancel;
|
||||||
private boolean pauseRequestedLastTick;
|
private boolean pauseRequestedLastTick;
|
||||||
|
private boolean unpausedLastTick;
|
||||||
private boolean cancelRequested;
|
private boolean cancelRequested;
|
||||||
private boolean calcFailedLastTick;
|
private boolean calcFailedLastTick;
|
||||||
|
|
||||||
@@ -66,6 +65,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
|
|
||||||
private boolean lastAutoJump;
|
private boolean lastAutoJump;
|
||||||
|
|
||||||
|
private BlockPos expectedSegmentStart;
|
||||||
|
|
||||||
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
|
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
public PathingBehavior(Baritone baritone) {
|
public PathingBehavior(Baritone baritone) {
|
||||||
@@ -93,36 +94,67 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
baritone.getPathingControlManager().cancelEverything();
|
baritone.getPathingControlManager().cancelEverything();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
expectedSegmentStart = pathStart();
|
||||||
baritone.getPathingControlManager().preTick();
|
baritone.getPathingControlManager().preTick();
|
||||||
tickPath();
|
tickPath();
|
||||||
dispatchEvents();
|
dispatchEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerSprintState(SprintStateEvent event) {
|
||||||
|
if (current != null) {
|
||||||
|
event.setState(current.isSprinting());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void tickPath() {
|
private void tickPath() {
|
||||||
if (pauseRequestedLastTick && safeToCancel) {
|
if (pauseRequestedLastTick && safeToCancel) {
|
||||||
pauseRequestedLastTick = false;
|
pauseRequestedLastTick = false;
|
||||||
baritone.getInputOverrideHandler().clearAllKeys();
|
if (unpausedLastTick) {
|
||||||
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
||||||
|
}
|
||||||
|
unpausedLastTick = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
unpausedLastTick = true;
|
||||||
if (cancelRequested) {
|
if (cancelRequested) {
|
||||||
cancelRequested = false;
|
cancelRequested = false;
|
||||||
baritone.getInputOverrideHandler().clearAllKeys();
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
}
|
}
|
||||||
if (current == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
safeToCancel = current.onTick();
|
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
|
synchronized (pathCalcLock) {
|
||||||
|
if (inProgress != null) {
|
||||||
|
// we are calculating
|
||||||
|
// are we calculating the right thing though? 🤔
|
||||||
|
BetterBlockPos calcFrom = inProgress.getStart();
|
||||||
|
Optional<IPath> currentBest = inProgress.bestPathSoFar();
|
||||||
|
if ((current == null || !current.getPath().getDest().equals(calcFrom)) // if current ends in inProgress's start, then we're ok
|
||||||
|
&& !calcFrom.equals(ctx.playerFeet()) && !calcFrom.equals(expectedSegmentStart) // if current starts in our playerFeet or pathStart, then we're ok
|
||||||
|
&& (!currentBest.isPresent() || (!currentBest.get().positions().contains(ctx.playerFeet()) && !currentBest.get().positions().contains(expectedSegmentStart))) // if
|
||||||
|
) {
|
||||||
|
// when it was *just* started, currentBest will be empty so we need to also check calcFrom since that's always present
|
||||||
|
inProgress.cancel(); // cancellation doesn't dispatch any events
|
||||||
|
inProgress = null; // this is safe since we hold both locks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
safeToCancel = current.onTick();
|
||||||
if (current.failed() || current.finished()) {
|
if (current.failed() || current.finished()) {
|
||||||
current = null;
|
current = null;
|
||||||
if (goal == null || goal.isInGoal(ctx.playerFeet())) {
|
if (goal == null || goal.isInGoal(ctx.playerFeet())) {
|
||||||
logDebug("All done. At " + goal);
|
logDebug("All done. At " + goal);
|
||||||
queuePathEvent(PathEvent.AT_GOAL);
|
queuePathEvent(PathEvent.AT_GOAL);
|
||||||
next = null;
|
next = null;
|
||||||
|
if (Baritone.settings().disconnectOnArrival.value) {
|
||||||
|
ctx.world().sendQuittingDisconnectingPacket();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (next != null && !next.getPath().positions().contains(ctx.playerFeet())) {
|
if (next != null && !next.getPath().positions().contains(ctx.playerFeet()) && !next.getPath().positions().contains(expectedSegmentStart)) { // can contain either one
|
||||||
// if the current path failed, we may not actually be on the next one, so make sure
|
// if the current path failed, we may not actually be on the next one, so make sure
|
||||||
logDebug("Discarding next path as it does not contain current position");
|
logDebug("Discarding next path as it does not contain current position");
|
||||||
// for example if we had a nicely planned ahead path that starts where current ends
|
// for example if we had a nicely planned ahead path that starts where current ends
|
||||||
@@ -138,18 +170,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
|
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
|
||||||
current = next;
|
current = next;
|
||||||
next = null;
|
next = null;
|
||||||
current.onTick();
|
current.onTick(); // don't waste a tick doing nothing, get started right away
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// at this point, current just ended, but we aren't in the goal and have no plan for the future
|
// at this point, current just ended, but we aren't in the goal and have no plan for the future
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (inProgress != null) {
|
if (inProgress != null) {
|
||||||
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
||||||
// if we aren't calculating right now
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// we aren't calculating
|
||||||
queuePathEvent(PathEvent.CALC_STARTED);
|
queuePathEvent(PathEvent.CALC_STARTED);
|
||||||
findPathInNewThread(pathStart(), true);
|
findPathInNewThread(expectedSegmentStart, true, context);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -177,14 +209,16 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
||||||
// and this path dosen't get us all the way there
|
// and this path doesn't get us all the way there
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
|
if (ticksRemainingInSegment(false).get() < Baritone.settings().planningTickLookahead.value) {
|
||||||
// and this path has 5 seconds or less left
|
// and this path has 7.5 seconds or less left
|
||||||
|
// don't include the current movement so a very long last movement (e.g. descend) doesn't trip it up
|
||||||
|
// if we actually included current, it wouldn't start planning ahead until the last movement was done, if the last movement took more than 7.5 seconds on its own
|
||||||
logDebug("Path almost over. Planning ahead...");
|
logDebug("Path almost over. Planning ahead...");
|
||||||
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
||||||
findPathInNewThread(current.getPath().getDest(), false);
|
findPathInNewThread(current.getPath().getDest(), false, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,21 +241,36 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<Double> ticksRemainingInSegment() {
|
|
||||||
if (current == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void secretInternalSetGoal(Goal goal) {
|
public void secretInternalSetGoal(Goal goal) {
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean secretInternalSetGoalAndPath(Goal goal) {
|
public boolean secretInternalSetGoalAndPath(PathingCommand command) {
|
||||||
secretInternalSetGoal(goal);
|
secretInternalSetGoal(command.goal);
|
||||||
return secretInternalPath();
|
if (command instanceof PathingCommandContext) {
|
||||||
|
context = ((PathingCommandContext) command).desiredCalcContext;
|
||||||
|
} else {
|
||||||
|
context = new CalculationContext(baritone, true);
|
||||||
|
}
|
||||||
|
if (goal == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (goal.isInGoal(ctx.playerFeet()) || goal.isInGoal(expectedSegmentStart)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
synchronized (pathPlanLock) {
|
||||||
|
if (current != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
synchronized (pathCalcLock) {
|
||||||
|
if (inProgress != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
queuePathEvent(PathEvent.CALC_STARTED);
|
||||||
|
findPathInNewThread(expectedSegmentStart, true, context);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -244,11 +293,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return Optional.ofNullable(inProgress);
|
return Optional.ofNullable(inProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPathing() {
|
|
||||||
return this.current != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSafeToCancel() {
|
public boolean isSafeToCancel() {
|
||||||
return current == null || safeToCancel;
|
return current == null || safeToCancel;
|
||||||
}
|
}
|
||||||
@@ -271,7 +315,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
if (doIt) {
|
if (doIt) {
|
||||||
secretInternalSegmentCancel();
|
secretInternalSegmentCancel();
|
||||||
}
|
}
|
||||||
baritone.getPathingControlManager().cancelEverything();
|
baritone.getPathingControlManager().cancelEverything(); // regardless of if we can stop the current segment, we can still stop the processes
|
||||||
return doIt;
|
return doIt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,44 +340,21 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
public void secretInternalSegmentCancel() {
|
public void secretInternalSegmentCancel() {
|
||||||
queuePathEvent(PathEvent.CANCELED);
|
queuePathEvent(PathEvent.CANCELED);
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
current = null;
|
if (current != null) {
|
||||||
next = null;
|
current = null;
|
||||||
|
next = null;
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
|
||||||
|
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
baritone.getInputOverrideHandler().clearAllKeys();
|
|
||||||
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
|
|
||||||
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forceCancel() { // NOT exposed on public api
|
public void forceCancel() { // NOT exposed on public api
|
||||||
cancelEverything();
|
cancelEverything();
|
||||||
secretInternalSegmentCancel();
|
secretInternalSegmentCancel();
|
||||||
inProgress = null;
|
synchronized (pathCalcLock) {
|
||||||
}
|
inProgress = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Start calculating a path if we aren't already
|
|
||||||
*
|
|
||||||
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
|
||||||
*/
|
|
||||||
public boolean secretInternalPath() {
|
|
||||||
if (goal == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (goal.isInGoal(ctx.playerFeet())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
synchronized (pathPlanLock) {
|
|
||||||
if (current != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
synchronized (pathCalcLock) {
|
|
||||||
if (inProgress != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
queuePathEvent(PathEvent.CALC_STARTED);
|
|
||||||
findPathInNewThread(pathStart(), true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,6 +364,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CalculationContext secretInternalGetCalculationContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See issue #209
|
* See issue #209
|
||||||
*
|
*
|
||||||
@@ -371,7 +396,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
}
|
}
|
||||||
if (MovementHelper.canWalkOn(ctx, possibleSupport.down()) && MovementHelper.canWalkThrough(ctx, possibleSupport) && MovementHelper.canWalkThrough(ctx, possibleSupport.up())) {
|
if (MovementHelper.canWalkOn(ctx, possibleSupport.down()) && MovementHelper.canWalkThrough(ctx, possibleSupport) && MovementHelper.canWalkThrough(ctx, possibleSupport.up())) {
|
||||||
// this is plausible
|
// this is plausible
|
||||||
logDebug("Faking path start assuming player is standing off the edge of a block");
|
//logDebug("Faking path start assuming player is standing off the edge of a block");
|
||||||
return possibleSupport;
|
return possibleSupport;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,7 +405,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
// !onGround
|
// !onGround
|
||||||
// we're in the middle of a jump
|
// we're in the middle of a jump
|
||||||
if (MovementHelper.canWalkOn(ctx, feet.down().down())) {
|
if (MovementHelper.canWalkOn(ctx, feet.down().down())) {
|
||||||
logDebug("Faking path start assuming player is midair and falling");
|
//logDebug("Faking path start assuming player is midair and falling");
|
||||||
return feet.down();
|
return feet.down();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +419,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
* @param start
|
* @param start
|
||||||
* @param talkAboutIt
|
* @param talkAboutIt
|
||||||
*/
|
*/
|
||||||
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt) {
|
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt, CalculationContext context) {
|
||||||
// this must be called with synchronization on pathCalcLock!
|
// this must be called with synchronization on pathCalcLock!
|
||||||
// actually, we can check this, muahaha
|
// actually, we can check this, muahaha
|
||||||
if (!Thread.holdsLock(pathCalcLock)) {
|
if (!Thread.holdsLock(pathCalcLock)) {
|
||||||
@@ -404,6 +429,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
if (inProgress != null) {
|
if (inProgress != null) {
|
||||||
throw new IllegalStateException("Already doing it"); // should have been checked by caller
|
throw new IllegalStateException("Already doing it"); // should have been checked by caller
|
||||||
}
|
}
|
||||||
|
if (!context.safeForThreadedUse) {
|
||||||
|
throw new IllegalStateException("Improper context thread safety level");
|
||||||
|
}
|
||||||
Goal goal = this.goal;
|
Goal goal = this.goal;
|
||||||
if (goal == null) {
|
if (goal == null) {
|
||||||
logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller
|
logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller
|
||||||
@@ -412,13 +440,12 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
long primaryTimeout;
|
long primaryTimeout;
|
||||||
long failureTimeout;
|
long failureTimeout;
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
primaryTimeout = Baritone.settings().primaryTimeoutMS.get();
|
primaryTimeout = Baritone.settings().primaryTimeoutMS.value;
|
||||||
failureTimeout = Baritone.settings().failureTimeoutMS.get();
|
failureTimeout = Baritone.settings().failureTimeoutMS.value;
|
||||||
} else {
|
} else {
|
||||||
primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.get();
|
primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.value;
|
||||||
failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.get();
|
failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.value;
|
||||||
}
|
}
|
||||||
CalculationContext context = new CalculationContext(baritone, true); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
|
|
||||||
AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context);
|
AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context);
|
||||||
if (!Objects.equals(pathfinder.getGoal(), goal)) { // will return the exact same object if simplification didn't happen
|
if (!Objects.equals(pathfinder.getGoal(), goal)) { // will return the exact same object if simplification didn't happen
|
||||||
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
||||||
@@ -430,37 +457,16 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout);
|
PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout);
|
||||||
Optional<IPath> path = calcResult.getPath();
|
|
||||||
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
|
||||||
path = path.map(p -> {
|
|
||||||
IPath result = p.cutoffAtLoadedChunks(context.bsi);
|
|
||||||
|
|
||||||
if (result instanceof CutoffPath) {
|
|
||||||
logDebug("Cutting off path at edge of loaded chunks");
|
|
||||||
logDebug("Length decreased by " + (p.length() - result.length()));
|
|
||||||
} else {
|
|
||||||
logDebug("Path ends within loaded chunks");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<PathExecutor> executor = path.map(p -> {
|
|
||||||
IPath result = p.staticCutoff(goal);
|
|
||||||
|
|
||||||
if (result instanceof CutoffPath) {
|
|
||||||
logDebug("Static cutoff " + p.length() + " to " + result.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}).map(p -> new PathExecutor(this, p));
|
|
||||||
|
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
|
Optional<PathExecutor> executor = calcResult.getPath().map(p -> new PathExecutor(PathingBehavior.this, p));
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
if (executor.isPresent()) {
|
if (executor.isPresent()) {
|
||||||
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
if (executor.get().getPath().positions().contains(expectedSegmentStart)) {
|
||||||
current = executor.get();
|
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||||
|
current = executor.get();
|
||||||
|
} else {
|
||||||
|
logDebug("Warning: discarding orphan path segment with incorrect start");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (calcResult.getType() != PathCalculationResult.Type.CANCELLATION && calcResult.getType() != PathCalculationResult.Type.EXCEPTION) {
|
if (calcResult.getType() != PathCalculationResult.Type.CANCELLATION && calcResult.getType() != PathCalculationResult.Type.EXCEPTION) {
|
||||||
// don't dispatch CALC_FAILED on cancellation
|
// don't dispatch CALC_FAILED on cancellation
|
||||||
@@ -470,8 +476,12 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
} else {
|
} else {
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
if (executor.isPresent()) {
|
if (executor.isPresent()) {
|
||||||
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
|
if (executor.get().getPath().getSrc().equals(current.getPath().getDest())) {
|
||||||
next = executor.get();
|
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
|
||||||
|
next = executor.get();
|
||||||
|
} else {
|
||||||
|
logDebug("Warning: discarding orphan next segment with incorrect start");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
queuePathEvent(PathEvent.NEXT_CALC_FAILED);
|
queuePathEvent(PathEvent.NEXT_CALC_FAILED);
|
||||||
}
|
}
|
||||||
@@ -497,13 +507,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
|
|
||||||
public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
|
public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
|
||||||
Goal transformed = goal;
|
Goal transformed = goal;
|
||||||
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
if (Baritone.settings().simplifyUnloadedYCoord.value && goal instanceof IGoalRenderPos) {
|
||||||
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||||
if (!context.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ())) {
|
if (!context.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ())) {
|
||||||
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Favoring favoring = new Favoring(context.getBaritone().getPlayerContext(), previous);
|
Favoring favoring = new Favoring(context.getBaritone().getPlayerContext(), previous, context);
|
||||||
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoring, context);
|
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoring, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+34
-6
@@ -18,6 +18,7 @@
|
|||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.utils.pathing.PathingBlockType;
|
import baritone.utils.pathing.PathingBlockType;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
@@ -85,6 +86,8 @@ public final class CachedChunk {
|
|||||||
temp.add(Blocks.END_GATEWAY);
|
temp.add(Blocks.END_GATEWAY);
|
||||||
temp.add(Blocks.WEB);
|
temp.add(Blocks.WEB);
|
||||||
temp.add(Blocks.NETHER_WART);
|
temp.add(Blocks.NETHER_WART);
|
||||||
|
temp.add(Blocks.LADDER);
|
||||||
|
temp.add(Blocks.VINE);
|
||||||
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
|
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +120,8 @@ public final class CachedChunk {
|
|||||||
*/
|
*/
|
||||||
private final BitSet data;
|
private final BitSet data;
|
||||||
|
|
||||||
|
private final Int2ObjectOpenHashMap<String> special;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The block names of each surface level block for generating an overview
|
* The block names of each surface level block for generating an overview
|
||||||
*/
|
*/
|
||||||
@@ -138,12 +143,30 @@ public final class CachedChunk {
|
|||||||
this.heightMap = new int[256];
|
this.heightMap = new int[256];
|
||||||
this.specialBlockLocations = specialBlockLocations;
|
this.specialBlockLocations = specialBlockLocations;
|
||||||
this.cacheTimestamp = cacheTimestamp;
|
this.cacheTimestamp = cacheTimestamp;
|
||||||
|
if (specialBlockLocations.isEmpty()) {
|
||||||
|
this.special = null;
|
||||||
|
} else {
|
||||||
|
this.special = new Int2ObjectOpenHashMap<>();
|
||||||
|
setSpecial();
|
||||||
|
}
|
||||||
calculateHeightMap();
|
calculateHeightMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final void setSpecial() {
|
||||||
|
for (Map.Entry<String, List<BlockPos>> entry : specialBlockLocations.entrySet()) {
|
||||||
|
for (BlockPos pos : entry.getValue()) {
|
||||||
|
special.put(getPositionIndex(pos.getX(), pos.getY(), pos.getZ()), entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final IBlockState getBlock(int x, int y, int z, int dimension) {
|
public final IBlockState getBlock(int x, int y, int z, int dimension) {
|
||||||
|
int index = getPositionIndex(x, y, z);
|
||||||
|
PathingBlockType type = getType(index);
|
||||||
int internalPos = z << 4 | x;
|
int internalPos = z << 4 | x;
|
||||||
if (heightMap[internalPos] == y) {
|
if (heightMap[internalPos] == y && type != PathingBlockType.AVOID) {
|
||||||
|
// if the top block in a column is water, we cache it as AVOID but we don't want to just return default state water (which is not flowing) beacuse then it would try to path through it
|
||||||
|
|
||||||
// we have this exact block, it's a surface block
|
// we have this exact block, it's a surface block
|
||||||
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
||||||
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
||||||
@@ -151,15 +174,20 @@ public final class CachedChunk {
|
|||||||
}*/
|
}*/
|
||||||
return overview[internalPos];
|
return overview[internalPos];
|
||||||
}
|
}
|
||||||
PathingBlockType type = getType(x, y, z);
|
if (special != null) {
|
||||||
|
String str = special.get(index);
|
||||||
|
if (str != null) {
|
||||||
|
return ChunkPacker.stringToBlock(str).getDefaultState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (type == PathingBlockType.SOLID && y == 127 && dimension == -1) {
|
if (type == PathingBlockType.SOLID && y == 127 && dimension == -1) {
|
||||||
return Blocks.BEDROCK.getDefaultState();
|
return Blocks.BEDROCK.getDefaultState();
|
||||||
}
|
}
|
||||||
return ChunkPacker.pathingTypeToBlock(type, dimension);
|
return ChunkPacker.pathingTypeToBlock(type, dimension);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PathingBlockType getType(int x, int y, int z) {
|
private PathingBlockType getType(int index) {
|
||||||
int index = getPositionIndex(x, y, z);
|
|
||||||
return PathingBlockType.fromBits(data.get(index), data.get(index + 1));
|
return PathingBlockType.fromBits(data.get(index), data.get(index + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,11 +215,11 @@ public final class CachedChunk {
|
|||||||
return specialBlockLocations;
|
return specialBlockLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LinkedList<BlockPos> getAbsoluteBlocks(String blockType) {
|
public final ArrayList<BlockPos> getAbsoluteBlocks(String blockType) {
|
||||||
if (specialBlockLocations.get(blockType) == null) {
|
if (specialBlockLocations.get(blockType) == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
ArrayList<BlockPos> res = new ArrayList<>();
|
||||||
for (BlockPos pos : specialBlockLocations.get(blockType)) {
|
for (BlockPos pos : specialBlockLocations.get(blockType)) {
|
||||||
res.add(new BlockPos(pos.getX() + x * 16, pos.getY(), pos.getZ() + z * 16));
|
res.add(new BlockPos(pos.getX() + x * 16, pos.getY(), pos.getZ() + z * 16));
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-9
@@ -87,19 +87,16 @@ public final class CachedRegion implements ICachedRegion {
|
|||||||
return chunks[x >> 4][z >> 4] != null;
|
return chunks[x >> 4][z >> 4] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LinkedList<BlockPos> getLocationsOf(String block) {
|
public final ArrayList<BlockPos> getLocationsOf(String block) {
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
ArrayList<BlockPos> res = new ArrayList<>();
|
||||||
for (int chunkX = 0; chunkX < 32; chunkX++) {
|
for (int chunkX = 0; chunkX < 32; chunkX++) {
|
||||||
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
|
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
|
||||||
if (chunks[chunkX][chunkZ] == null) {
|
if (chunks[chunkX][chunkZ] == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<BlockPos> locs = chunks[chunkX][chunkZ].getAbsoluteBlocks(block);
|
ArrayList<BlockPos> locs = chunks[chunkX][chunkZ].getAbsoluteBlocks(block);
|
||||||
if (locs == null) {
|
if (locs != null) {
|
||||||
continue;
|
res.addAll(locs);
|
||||||
}
|
|
||||||
for (BlockPos pos : locs) {
|
|
||||||
res.add(pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +303,7 @@ public final class CachedRegion implements ICachedRegion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized final void removeExpired() {
|
public synchronized final void removeExpired() {
|
||||||
long expiry = Baritone.settings().cachedChunksExpirySeconds.get();
|
long expiry = Baritone.settings().cachedChunksExpirySeconds.value;
|
||||||
if (expiry < 0) {
|
if (expiry < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-7
@@ -32,7 +32,6 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
@@ -45,7 +44,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
/**
|
/**
|
||||||
* The maximum number of regions in any direction from (0,0)
|
* The maximum number of regions in any direction from (0,0)
|
||||||
*/
|
*/
|
||||||
private static final int REGION_MAX = 58594;
|
private static final int REGION_MAX = 30_000_000 / 512 + 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of all of the cached regions.
|
* A map of all of the cached regions.
|
||||||
@@ -108,9 +107,13 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
return region.isCached(blockX & 511, blockZ & 511);
|
return region.isCached(blockX & 511, blockZ & 511);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean regionLoaded(int blockX, int blockZ) {
|
||||||
|
return getRegion(blockX >> 9, blockZ >> 9) != null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq) {
|
public final ArrayList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq) {
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
ArrayList<BlockPos> res = new ArrayList<>();
|
||||||
int centerRegionX = centerX >> 9;
|
int centerRegionX = centerX >> 9;
|
||||||
int centerRegionZ = centerZ >> 9;
|
int centerRegionZ = centerZ >> 9;
|
||||||
|
|
||||||
@@ -127,7 +130,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
CachedRegion region = getOrCreateRegion(regionX, regionZ);
|
CachedRegion region = getOrCreateRegion(regionX, regionZ);
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
// TODO: 100% verify if this or addAll is faster.
|
// TODO: 100% verify if this or addAll is faster.
|
||||||
region.getLocationsOf(block).forEach(res::add);
|
res.addAll(region.getLocationsOf(block));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +149,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void save() {
|
public final void save() {
|
||||||
if (!Baritone.settings().chunkCaching.get()) {
|
if (!Baritone.settings().chunkCaching.value) {
|
||||||
System.out.println("Not saving to disk; chunk caching is disabled.");
|
System.out.println("Not saving to disk; chunk caching is disabled.");
|
||||||
allRegions().forEach(region -> {
|
allRegions().forEach(region -> {
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
@@ -171,7 +174,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
* Delete regions that are too far from the player
|
* Delete regions that are too far from the player
|
||||||
*/
|
*/
|
||||||
private synchronized void prune() {
|
private synchronized void prune() {
|
||||||
if (!Baritone.settings().pruneRegionsFromRAM.get()) {
|
if (!Baritone.settings().pruneRegionsFromRAM.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BlockPos pruneCenter = guessPosition();
|
BlockPos pruneCenter = guessPosition();
|
||||||
|
|||||||
+20
-9
@@ -19,10 +19,7 @@ package baritone.cache;
|
|||||||
|
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.utils.pathing.PathingBlockType;
|
import baritone.utils.pathing.PathingBlockType;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.BlockDoublePlant;
|
|
||||||
import net.minecraft.block.BlockFlower;
|
|
||||||
import net.minecraft.block.BlockTallGrass;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
@@ -73,7 +70,7 @@ public final class ChunkPacker {
|
|||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
IBlockState state = bsc.get(x, y1, z);
|
IBlockState state = bsc.get(x, y1, z);
|
||||||
boolean[] bits = getPathingBlockType(state).getBits();
|
boolean[] bits = getPathingBlockType(state, chunk, x, y, z).getBits();
|
||||||
bitSet.set(index, bits[0]);
|
bitSet.set(index, bits[0]);
|
||||||
bitSet.set(index + 1, bits[1]);
|
bitSet.set(index + 1, bits[1]);
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
@@ -93,7 +90,8 @@ public final class ChunkPacker {
|
|||||||
IBlockState[] blocks = new IBlockState[256];
|
IBlockState[] blocks = new IBlockState[256];
|
||||||
|
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
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
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int y = 255; y >= 0; y--) {
|
for (int y = 255; y >= 0; y--) {
|
||||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
@@ -122,14 +120,27 @@ public final class ChunkPacker {
|
|||||||
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
|
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PathingBlockType getPathingBlockType(IBlockState state) {
|
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) {
|
if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) {
|
||||||
// only water source blocks are plausibly usable, flowing water should be avoid
|
// only water source blocks are plausibly usable, flowing water should be avoid
|
||||||
|
// FLOWING_WATER is a waterfall, it doesn't really matter and caching it as AVOID just makes it look wrong
|
||||||
|
if (MovementHelper.possiblyFlowing(state)) {
|
||||||
|
return PathingBlockType.AVOID;
|
||||||
|
}
|
||||||
|
if (x == 0 || x == 15 || z == 0 || z == 15) {
|
||||||
|
if (BlockLiquid.getSlopeAngle(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4), state.getMaterial(), state) == -1000.0F) {
|
||||||
|
return PathingBlockType.WATER;
|
||||||
|
}
|
||||||
|
return PathingBlockType.AVOID;
|
||||||
|
}
|
||||||
|
if (MovementHelper.possiblyFlowing(chunk.getBlockState(x + 1, y, z)) || MovementHelper.possiblyFlowing(chunk.getBlockState(x - 1, y, z)) || MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z + 1)) || MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z - 1))) {
|
||||||
|
return PathingBlockType.AVOID;
|
||||||
|
}
|
||||||
return PathingBlockType.WATER;
|
return PathingBlockType.WATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MovementHelper.avoidWalkingInto(block) || block == Blocks.FLOWING_WATER || MovementHelper.isBottomSlab(state)) {
|
if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) {
|
||||||
return PathingBlockType.AVOID;
|
return PathingBlockType.AVOID;
|
||||||
}
|
}
|
||||||
// We used to do an AABB check here
|
// We used to do an AABB check here
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
import baritone.api.cache.IContainerMemory;
|
import baritone.api.cache.IContainerMemory;
|
||||||
import baritone.api.cache.IRememberedInventory;
|
import baritone.api.cache.IRememberedInventory;
|
||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
@@ -69,6 +70,9 @@ public class ContainerMemory implements IContainerMemory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void save() throws IOException {
|
public synchronized void save() throws IOException {
|
||||||
|
if (!Baritone.settings().containerMemory.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
|
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
|
||||||
PacketBuffer out = new PacketBuffer(buf);
|
PacketBuffer out = new PacketBuffer(buf);
|
||||||
out.writeInt(inventories.size());
|
out.writeInt(inventories.size());
|
||||||
|
|||||||
+6
-1
@@ -24,6 +24,7 @@ import baritone.utils.accessor.IAnvilChunkLoader;
|
|||||||
import baritone.utils.accessor.IChunkProviderServer;
|
import baritone.utils.accessor.IChunkProviderServer;
|
||||||
import net.minecraft.server.integrated.IntegratedServer;
|
import net.minecraft.server.integrated.IntegratedServer;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@@ -76,7 +77,11 @@ public class WorldProvider implements IWorldProvider, Helper {
|
|||||||
directory = new File(directory, "baritone");
|
directory = new File(directory, "baritone");
|
||||||
readme = directory;
|
readme = directory;
|
||||||
} else { // Otherwise, the server must be remote...
|
} else { // Otherwise, the server must be remote...
|
||||||
directory = new File(Baritone.getDir(), mc.getCurrentServerData().serverIP);
|
String folderName = mc.getCurrentServerData().serverIP;
|
||||||
|
if (SystemUtils.IS_OS_WINDOWS) {
|
||||||
|
folderName = folderName.replace(":", "_");
|
||||||
|
}
|
||||||
|
directory = new File(Baritone.getDir(), folderName);
|
||||||
readme = Baritone.getDir();
|
readme = Baritone.getDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import baritone.api.event.events.type.EventState;
|
|||||||
import baritone.api.event.listener.IEventBus;
|
import baritone.api.event.listener.IEventBus;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
@@ -46,6 +47,15 @@ public final class GameEventHandler implements IEventBus, Helper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onTick(TickEvent event) {
|
public final void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.IN) {
|
||||||
|
try {
|
||||||
|
baritone.bsi = new BlockStateInterface(baritone.getPlayerContext(), true);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
baritone.bsi = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baritone.bsi = null;
|
||||||
|
}
|
||||||
listeners.forEach(l -> l.onTick(event));
|
listeners.forEach(l -> l.onTick(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +131,11 @@ public final class GameEventHandler implements IEventBus, Helper {
|
|||||||
listeners.forEach(l -> l.onPlayerRotationMove(event));
|
listeners.forEach(l -> l.onPlayerRotationMove(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerSprintState(SprintStateEvent event) {
|
||||||
|
listeners.forEach(l -> l.onPlayerSprintState(event));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
public void onBlockInteract(BlockInteractEvent event) {
|
||||||
listeners.forEach(l -> l.onBlockInteract(event));
|
listeners.forEach(l -> l.onBlockInteract(event));
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import baritone.api.utils.BetterBlockPos;
|
|||||||
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
import baritone.utils.Helper;
|
|
||||||
import baritone.utils.pathing.BetterWorldBorder;
|
import baritone.utils.pathing.BetterWorldBorder;
|
||||||
import baritone.utils.pathing.Favoring;
|
import baritone.utils.pathing.Favoring;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
@@ -37,7 +36,7 @@ import java.util.Optional;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
public final class AStarPathFinder extends AbstractNodeCostSearch {
|
||||||
|
|
||||||
private final Favoring favoring;
|
private final Favoring favoring;
|
||||||
private final CalculationContext calcContext;
|
private final CalculationContext calcContext;
|
||||||
@@ -55,30 +54,28 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
startNode.combinedCost = startNode.estimatedCostToGoal;
|
startNode.combinedCost = startNode.estimatedCostToGoal;
|
||||||
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
|
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
|
||||||
openSet.insert(startNode);
|
openSet.insert(startNode);
|
||||||
bestSoFar = new PathNode[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
|
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
|
||||||
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];
|
|
||||||
for (int i = 0; i < bestHeuristicSoFar.length; i++) {
|
for (int i = 0; i < bestHeuristicSoFar.length; i++) {
|
||||||
bestHeuristicSoFar[i] = startNode.estimatedCostToGoal;
|
bestHeuristicSoFar[i] = startNode.estimatedCostToGoal;
|
||||||
bestSoFar[i] = startNode;
|
bestSoFar[i] = startNode;
|
||||||
}
|
}
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
Favoring favored = favoring;
|
|
||||||
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world.getWorldBorder());
|
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world.getWorldBorder());
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
boolean slowPath = Baritone.settings().slowPath.get();
|
boolean slowPath = Baritone.settings().slowPath.value;
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.<Long>get() + "ms instead of " + primaryTimeout + "ms");
|
logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.value + "ms instead of " + primaryTimeout + "ms");
|
||||||
}
|
}
|
||||||
long primaryTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.<Long>get() : primaryTimeout);
|
long primaryTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.value : primaryTimeout);
|
||||||
long failureTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.<Long>get() : failureTimeout);
|
long failureTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.value : failureTimeout);
|
||||||
boolean failing = true;
|
boolean failing = true;
|
||||||
int numNodes = 0;
|
int numNodes = 0;
|
||||||
int numMovementsConsidered = 0;
|
int numMovementsConsidered = 0;
|
||||||
int numEmptyChunk = 0;
|
int numEmptyChunk = 0;
|
||||||
boolean favoring = !favored.isEmpty();
|
boolean isFavoring = !favoring.isEmpty();
|
||||||
int timeCheckInterval = 1 << 6;
|
int timeCheckInterval = 1 << 6;
|
||||||
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.value; // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
||||||
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
|
double minimumImprovement = Baritone.settings().minimumImprovementRepropagation.value ? MIN_IMPROVEMENT : 0;
|
||||||
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) {
|
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) {
|
||||||
if ((numNodes & (timeCheckInterval - 1)) == 0) { // only call this once every 64 nodes (about half a millisecond)
|
if ((numNodes & (timeCheckInterval - 1)) == 0) { // only call this once every 64 nodes (about half a millisecond)
|
||||||
long now = System.currentTimeMillis(); // since nanoTime is slow on windows (takes many microseconds)
|
long now = System.currentTimeMillis(); // since nanoTime is slow on windows (takes many microseconds)
|
||||||
@@ -88,7 +85,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
}
|
}
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.<Long>get());
|
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.value);
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,21 +133,13 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
|
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
|
||||||
}
|
}
|
||||||
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
||||||
if (favoring) {
|
if (isFavoring) {
|
||||||
// see issue #18
|
// see issue #18
|
||||||
actionCost *= favored.calculate(hashCode);
|
actionCost *= favoring.calculate(hashCode);
|
||||||
}
|
}
|
||||||
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
||||||
double tentativeCost = currentNode.cost + actionCost;
|
double tentativeCost = currentNode.cost + actionCost;
|
||||||
if (tentativeCost < neighbor.cost) {
|
if (neighbor.cost - tentativeCost > minimumImprovement) {
|
||||||
double improvementBy = neighbor.cost - tentativeCost;
|
|
||||||
// there are floating point errors caused by random combinations of traverse and diagonal over a flat area
|
|
||||||
// that means that sometimes there's a cost improvement of like 10 ^ -16
|
|
||||||
// it's not worth the time to update the costs, decrease-key the heap, potentially repropagate, etc
|
|
||||||
if (improvementBy < 0.01 && minimumImprovementRepropagation) {
|
|
||||||
// who cares about a hundredth of a tick? that's half a millisecond for crying out loud!
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbor.previous = currentNode;
|
neighbor.previous = currentNode;
|
||||||
neighbor.cost = tentativeCost;
|
neighbor.cost = tentativeCost;
|
||||||
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
||||||
@@ -159,15 +148,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
} else {
|
} else {
|
||||||
openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there
|
openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there
|
||||||
}
|
}
|
||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
for (int i = 0; i < COEFFICIENTS.length; i++) {
|
||||||
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
||||||
if (heuristic < bestHeuristicSoFar[i]) {
|
if (bestHeuristicSoFar[i] - heuristic > minimumImprovement) {
|
||||||
if (bestHeuristicSoFar[i] - heuristic < 0.01 && minimumImprovementRepropagation) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bestHeuristicSoFar[i] = heuristic;
|
bestHeuristicSoFar[i] = heuristic;
|
||||||
bestSoFar[i] = neighbor;
|
bestSoFar[i] = neighbor;
|
||||||
if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
|
if (failing && getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
|
||||||
failing = false;
|
failing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,28 +168,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
System.out.println("Open set size: " + openSet.size());
|
System.out.println("Open set size: " + openSet.size());
|
||||||
System.out.println("PathNode map size: " + mapSize());
|
System.out.println("PathNode map size: " + mapSize());
|
||||||
System.out.println((int) (numNodes * 1.0 / ((System.currentTimeMillis() - startTime) / 1000F)) + " nodes per second");
|
System.out.println((int) (numNodes * 1.0 / ((System.currentTimeMillis() - startTime) / 1000F)) + " nodes per second");
|
||||||
double bestDist = 0;
|
Optional<IPath> result = bestSoFar(true, numNodes);
|
||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
if (result.isPresent()) {
|
||||||
if (bestSoFar[i] == null) {
|
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double dist = getDistFromStartSq(bestSoFar[i]);
|
|
||||||
if (dist > bestDist) {
|
|
||||||
bestDist = dist;
|
|
||||||
}
|
|
||||||
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
|
||||||
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, A* cost coefficient " + COEFFICIENTS[i] + ", " + numMovementsConsidered + " movements considered");
|
|
||||||
if (COEFFICIENTS[i] >= 3) {
|
|
||||||
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
|
|
||||||
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
|
|
||||||
System.out.println("But I'm going to do it anyway, because yolo");
|
|
||||||
}
|
|
||||||
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
|
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, calcContext));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
|
return result;
|
||||||
logDebug("No path found =(");
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import java.util.Optional;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNodeCostSearch implements IPathFinder {
|
public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
|
||||||
|
|
||||||
protected final int startX;
|
protected final int startX;
|
||||||
protected final int startY;
|
protected final int startY;
|
||||||
@@ -53,7 +53,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
|
|
||||||
protected PathNode mostRecentConsidered;
|
protected PathNode mostRecentConsidered;
|
||||||
|
|
||||||
protected PathNode[] bestSoFar;
|
protected final PathNode[] bestSoFar = new PathNode[COEFFICIENTS.length];
|
||||||
|
|
||||||
private volatile boolean isFinished;
|
private volatile boolean isFinished;
|
||||||
|
|
||||||
@@ -63,13 +63,23 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
* This is really complicated and hard to explain. I wrote a comment in the old version of MineBot but it was so
|
* This is really complicated and hard to explain. I wrote a comment in the old version of MineBot but it was so
|
||||||
* long it was easier as a Google Doc (because I could insert charts).
|
* long it was easier as a Google Doc (because I could insert charts).
|
||||||
*
|
*
|
||||||
* @see <a href="https://docs.google.com/document/d/1WVHHXKXFdCR1Oz__KtK8sFqyvSwJN_H4lftkHFgmzlc/edit"></a>
|
* @see <a href="https://docs.google.com/document/d/1WVHHXKXFdCR1Oz__KtK8sFqyvSwJN_H4lftkHFgmzlc/edit">here</a>
|
||||||
*/
|
*/
|
||||||
protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10}; // big TODO tune
|
protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a path goes less than 5 blocks and doesn't make it to its goal, it's not worth considering.
|
* If a path goes less than 5 blocks and doesn't make it to its goal, it's not worth considering.
|
||||||
*/
|
*/
|
||||||
protected final static double MIN_DIST_PATH = 5;
|
protected static final double MIN_DIST_PATH = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* there are floating point errors caused by random combinations of traverse and diagonal over a flat area
|
||||||
|
* that means that sometimes there's a cost improvement of like 10 ^ -16
|
||||||
|
* it's not worth the time to update the costs, decrease-key the heap, potentially repropagate, etc
|
||||||
|
* <p>
|
||||||
|
* who cares about a hundredth of a tick? that's half a millisecond for crying out loud!
|
||||||
|
*/
|
||||||
|
protected static final double MIN_IMPROVEMENT = 0.01;
|
||||||
|
|
||||||
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) {
|
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) {
|
||||||
this.startX = startX;
|
this.startX = startX;
|
||||||
@@ -77,7 +87,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
this.startZ = startZ;
|
this.startZ = startZ;
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.map = new Long2ObjectOpenHashMap<>(Baritone.settings().pathingMapDefaultSize.value, Baritone.settings().pathingMapLoadFactor.get());
|
this.map = new Long2ObjectOpenHashMap<>(Baritone.settings().pathingMapDefaultSize.value, Baritone.settings().pathingMapLoadFactor.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
@@ -92,13 +102,25 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
cancelRequested = false;
|
cancelRequested = false;
|
||||||
try {
|
try {
|
||||||
IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null);
|
IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null);
|
||||||
isFinished = true;
|
|
||||||
if (cancelRequested) {
|
if (cancelRequested) {
|
||||||
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path);
|
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION);
|
||||||
}
|
}
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
return new PathCalculationResult(PathCalculationResult.Type.FAILURE);
|
return new PathCalculationResult(PathCalculationResult.Type.FAILURE);
|
||||||
}
|
}
|
||||||
|
int previousLength = path.length();
|
||||||
|
path = path.cutoffAtLoadedChunks(context.bsi);
|
||||||
|
if (path.length() < previousLength) {
|
||||||
|
Helper.HELPER.logDebug("Cutting off path at edge of loaded chunks");
|
||||||
|
Helper.HELPER.logDebug("Length decreased by " + (previousLength - path.length()));
|
||||||
|
} else {
|
||||||
|
Helper.HELPER.logDebug("Path ends within loaded chunks");
|
||||||
|
}
|
||||||
|
previousLength = path.length();
|
||||||
|
path = path.staticCutoff(goal);
|
||||||
|
if (path.length() < previousLength) {
|
||||||
|
Helper.HELPER.logDebug("Static cutoff " + previousLength + " to " + path.length());
|
||||||
|
}
|
||||||
if (goal.isInGoal(path.getDest())) {
|
if (goal.isInGoal(path.getDest())) {
|
||||||
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_TO_GOAL, path);
|
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_TO_GOAL, path);
|
||||||
} else {
|
} else {
|
||||||
@@ -158,25 +180,43 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context));
|
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int mapSize() {
|
|
||||||
return map.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<IPath> bestPathSoFar() {
|
public Optional<IPath> bestPathSoFar() {
|
||||||
|
return bestSoFar(false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Optional<IPath> bestSoFar(boolean logInfo, int numNodes) {
|
||||||
if (startNode == null || bestSoFar == null) {
|
if (startNode == null || bestSoFar == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
double bestDist = 0;
|
||||||
|
for (int i = 0; i < COEFFICIENTS.length; i++) {
|
||||||
if (bestSoFar[i] == null) {
|
if (bestSoFar[i] == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
double dist = getDistFromStartSq(bestSoFar[i]);
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context));
|
if (dist > bestDist) {
|
||||||
|
bestDist = dist;
|
||||||
|
}
|
||||||
|
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
||||||
|
if (logInfo) {
|
||||||
|
if (COEFFICIENTS[i] >= 3) {
|
||||||
|
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
|
||||||
|
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
|
||||||
|
System.out.println("But I'm going to do it anyway, because yolo");
|
||||||
|
}
|
||||||
|
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
|
||||||
|
logDebug("A* cost coefficient " + COEFFICIENTS[i]);
|
||||||
|
}
|
||||||
|
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// instead of returning bestSoFar[0], be less misleading
|
// instead of returning bestSoFar[0], be less misleading
|
||||||
// if it actually won't find any path, don't make them think it will by rendering a dark blue that will never actually happen
|
// if it actually won't find any path, don't make them think it will by rendering a dark blue that will never actually happen
|
||||||
|
if (logInfo) {
|
||||||
|
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
|
||||||
|
logDebug("No path found =(");
|
||||||
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,4 +229,12 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
public final Goal getGoal() {
|
public final Goal getGoal() {
|
||||||
return goal;
|
return goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BetterBlockPos getStart() {
|
||||||
|
return new BetterBlockPos(startX, startY, startZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int mapSize() {
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import net.minecraft.item.ItemStack;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/7/2018
|
* @since 8/7/2018
|
||||||
@@ -42,6 +44,7 @@ public class CalculationContext {
|
|||||||
|
|
||||||
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
||||||
|
|
||||||
|
public final boolean safeForThreadedUse;
|
||||||
public final IBaritone baritone;
|
public final IBaritone baritone;
|
||||||
public final World world;
|
public final World world;
|
||||||
public final WorldData worldData;
|
public final WorldData worldData;
|
||||||
@@ -50,7 +53,7 @@ public class CalculationContext {
|
|||||||
public final boolean hasWaterBucket;
|
public final boolean hasWaterBucket;
|
||||||
public final boolean hasThrowaway;
|
public final boolean hasThrowaway;
|
||||||
public final boolean canSprint;
|
public final boolean canSprint;
|
||||||
public final double placeBlockCost;
|
protected final double placeBlockCost; // protected because you should call the function instead
|
||||||
public final boolean allowBreak;
|
public final boolean allowBreak;
|
||||||
public final boolean allowParkour;
|
public final boolean allowParkour;
|
||||||
public final boolean allowParkourPlace;
|
public final boolean allowParkourPlace;
|
||||||
@@ -61,7 +64,8 @@ public class CalculationContext {
|
|||||||
public final int maxFallHeightBucket;
|
public final int maxFallHeightBucket;
|
||||||
public final double waterWalkSpeed;
|
public final double waterWalkSpeed;
|
||||||
public final double breakBlockAdditionalCost;
|
public final double breakBlockAdditionalCost;
|
||||||
public final double jumpPenalty;
|
public double backtrackCostFavoringCoefficient;
|
||||||
|
public double jumpPenalty;
|
||||||
public final double walkOnWaterOnePenalty;
|
public final double walkOnWaterOnePenalty;
|
||||||
public final BetterWorldBorder worldBorder;
|
public final BetterWorldBorder worldBorder;
|
||||||
|
|
||||||
@@ -70,33 +74,35 @@ public class CalculationContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
|
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
|
||||||
|
this.safeForThreadedUse = forUseOnAnotherThread;
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
EntityPlayerSP player = baritone.getPlayerContext().player();
|
EntityPlayerSP player = baritone.getPlayerContext().player();
|
||||||
this.world = baritone.getPlayerContext().world();
|
this.world = baritone.getPlayerContext().world();
|
||||||
this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld();
|
this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld();
|
||||||
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread); // TODO TODO TODO
|
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread);
|
||||||
this.toolSet = new ToolSet(player);
|
this.toolSet = new ToolSet(player);
|
||||||
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(baritone.getPlayerContext(), false);
|
this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway();
|
||||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
||||||
this.canSprint = Baritone.settings().allowSprint.get() && player.getFoodStats().getFoodLevel() > 6;
|
this.canSprint = Baritone.settings().allowSprint.value && player.getFoodStats().getFoodLevel() > 6;
|
||||||
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.get();
|
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.value;
|
||||||
this.allowBreak = Baritone.settings().allowBreak.get();
|
this.allowBreak = Baritone.settings().allowBreak.value;
|
||||||
this.allowParkour = Baritone.settings().allowParkour.get();
|
this.allowParkour = Baritone.settings().allowParkour.value;
|
||||||
this.allowParkourPlace = Baritone.settings().allowParkourPlace.get();
|
this.allowParkourPlace = Baritone.settings().allowParkourPlace.value;
|
||||||
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.get();
|
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
|
||||||
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.get();
|
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
|
||||||
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.get();
|
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
|
||||||
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.get();
|
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value;
|
||||||
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.get();
|
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value;
|
||||||
int depth = EnchantmentHelper.getDepthStriderModifier(player);
|
int depth = EnchantmentHelper.getDepthStriderModifier(player);
|
||||||
if (depth > 3) {
|
if (depth > 3) {
|
||||||
depth = 3;
|
depth = 3;
|
||||||
}
|
}
|
||||||
float mult = depth / 3.0F;
|
float mult = depth / 3.0F;
|
||||||
this.waterWalkSpeed = ActionCosts.WALK_ONE_IN_WATER_COST * (1 - mult) + ActionCosts.WALK_ONE_BLOCK_COST * mult;
|
this.waterWalkSpeed = ActionCosts.WALK_ONE_IN_WATER_COST * (1 - mult) + ActionCosts.WALK_ONE_BLOCK_COST * mult;
|
||||||
this.breakBlockAdditionalCost = Baritone.settings().blockBreakAdditionalPenalty.get();
|
this.breakBlockAdditionalCost = Baritone.settings().blockBreakAdditionalPenalty.value;
|
||||||
this.jumpPenalty = Baritone.settings().jumpPenalty.get();
|
this.backtrackCostFavoringCoefficient = Baritone.settings().backtrackCostFavoringCoefficient.value;
|
||||||
this.walkOnWaterOnePenalty = Baritone.settings().walkOnWaterOnePenalty.get();
|
this.jumpPenalty = Baritone.settings().jumpPenalty.value;
|
||||||
|
this.walkOnWaterOnePenalty = Baritone.settings().walkOnWaterOnePenalty.value;
|
||||||
// why cache these things here, why not let the movements just get directly from settings?
|
// 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,
|
// 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.
|
// then you get a wildly inconsistent path that isn't optimal for either scenario.
|
||||||
@@ -123,21 +129,32 @@ public class CalculationContext {
|
|||||||
return get(x, y, z).getBlock();
|
return get(x, y, z).getBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canPlaceThrowawayAt(int x, int y, int z) {
|
public double costOfPlacingAt(int x, int y, int z) {
|
||||||
if (!hasThrowaway) { // only true if allowPlace is true, see constructor
|
if (!hasThrowaway) { // only true if allowPlace is true, see constructor
|
||||||
return false;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (isPossiblyProtected(x, y, z)) {
|
if (isPossiblyProtected(x, y, z)) {
|
||||||
return false;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
return worldBorder.canPlaceAt(x, z); // TODO perhaps MovementHelper.canPlaceAgainst could also use this?
|
if (!worldBorder.canPlaceAt(x, z)) {
|
||||||
|
// TODO perhaps MovementHelper.canPlaceAgainst could also use this?
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
return placeBlockCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBreakAt(int x, int y, int z) {
|
public double breakCostMultiplierAt(int x, int y, int z) {
|
||||||
if (!allowBreak) {
|
if (!allowBreak) {
|
||||||
return false;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
return !isPossiblyProtected(x, y, z);
|
if (isPossiblyProtected(x, y, z)) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double placeBucketCost() {
|
||||||
|
return placeBlockCost; // shrug
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPossiblyProtected(int x, int y, int z) {
|
public boolean isPossiblyProtected(int x, int y, int z) {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import java.util.Optional;
|
|||||||
|
|
||||||
public abstract class Movement implements IMovement, MovementHelper {
|
public abstract class Movement implements IMovement, MovementHelper {
|
||||||
|
|
||||||
protected static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
|
public static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
|
||||||
|
|
||||||
protected final IBaritone baritone;
|
protected final IBaritone baritone;
|
||||||
protected final IPlayerContext ctx;
|
protected final IPlayerContext ctx;
|
||||||
@@ -76,31 +76,28 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
this(baritone, src, dest, toBreak, null);
|
this(baritone, src, dest, toBreak, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public double getCost() throws NullPointerException {
|
||||||
public double getCost() {
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCost(CalculationContext context) {
|
||||||
if (cost == null) {
|
if (cost == null) {
|
||||||
cost = calculateCost(new CalculationContext(baritone));
|
cost = calculateCost(context);
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract double calculateCost(CalculationContext context);
|
public abstract double calculateCost(CalculationContext context);
|
||||||
|
|
||||||
@Override
|
public double recalculateCost(CalculationContext context) {
|
||||||
public double recalculateCost() {
|
|
||||||
cost = null;
|
cost = null;
|
||||||
return getCost();
|
return getCost(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void override(double cost) {
|
public void override(double cost) {
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public double calculateCostWithoutCaching() {
|
|
||||||
return calculateCost(new CalculationContext(baritone));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the execution of the latest Movement
|
* Handles the execution of the latest Movement
|
||||||
* State, and offers a Status to the calling class.
|
* State, and offers a Status to the calling class.
|
||||||
@@ -123,7 +120,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
baritone.getLookBehavior().updateTarget(
|
baritone.getLookBehavior().updateTarget(
|
||||||
rotation,
|
rotation,
|
||||||
currentState.getTarget().hasToForceRotations()));
|
currentState.getTarget().hasToForceRotations()));
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
currentState.getInputStates().forEach((input, forced) -> {
|
currentState.getInputStates().forEach((input, forced) -> {
|
||||||
baritone.getInputOverrideHandler().setInputForceState(input, forced);
|
baritone.getInputOverrideHandler().setInputForceState(input, forced);
|
||||||
});
|
});
|
||||||
@@ -160,7 +157,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
//i dont care if theres snow in the way!!!!!!!
|
//i dont care if theres snow in the way!!!!!!!
|
||||||
//you dont own me!!!!
|
//you dont own me!!!!
|
||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(blockPos)), true)
|
VecUtils.getBlockPosCenter(blockPos), ctx.playerRotations()), 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
|
// 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(Input.CLICK_LEFT, true);
|
state.setInput(Input.CLICK_LEFT, true);
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
package baritone.pathing.movement;
|
package baritone.pathing.movement;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.pathing.movement.ActionCosts;
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.*;
|
import baritone.api.utils.*;
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||||
@@ -28,13 +30,15 @@ import baritone.utils.ToolSet;
|
|||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.properties.PropertyBool;
|
import net.minecraft.block.properties.PropertyBool;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.ItemPickaxe;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static helpers for cost calculation
|
* Static helpers for cost calculation
|
||||||
@@ -68,7 +72,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (block == Blocks.AIR) { // early return for most common case
|
if (block == Blocks.AIR) { // early return for most common case
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA) {
|
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
|
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
|
||||||
@@ -77,6 +81,9 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
// be opened by just interacting.
|
// be opened by just interacting.
|
||||||
return block != Blocks.IRON_DOOR;
|
return block != Blocks.IRON_DOOR;
|
||||||
}
|
}
|
||||||
|
if (block == Blocks.CARPET) {
|
||||||
|
return canWalkOn(bsi, x, y - 1, z);
|
||||||
|
}
|
||||||
boolean snow = block instanceof BlockSnow;
|
boolean snow = block instanceof BlockSnow;
|
||||||
boolean trapdoor = block instanceof BlockTrapDoor;
|
boolean trapdoor = block instanceof BlockTrapDoor;
|
||||||
if (snow || trapdoor) {
|
if (snow || trapdoor) {
|
||||||
@@ -101,11 +108,11 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
}
|
}
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
if (isFlowing(state)) {
|
if (isFlowing(x, y, z, state, bsi)) {
|
||||||
return false; // Don't walk through flowing liquids
|
return false; // Don't walk through flowing liquids
|
||||||
}
|
}
|
||||||
if (block instanceof BlockLiquid) {
|
if (block instanceof BlockLiquid) {
|
||||||
if (Baritone.settings().assumeWalkOnWater.get()) {
|
if (Baritone.settings().assumeWalkOnWater.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
IBlockState up = bsi.get0(x, y + 1, z);
|
IBlockState up = bsi.get0(x, y + 1, z);
|
||||||
@@ -151,7 +158,8 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
|| block instanceof BlockSnow
|
|| block instanceof BlockSnow
|
||||||
|| block instanceof BlockLiquid
|
|| block instanceof BlockLiquid
|
||||||
|| block instanceof BlockTrapDoor
|
|| block instanceof BlockTrapDoor
|
||||||
|| block instanceof BlockEndPortal) {
|
|| block instanceof BlockEndPortal
|
||||||
|
|| block instanceof BlockSkull) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
||||||
@@ -266,7 +274,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (state.isBlockNormalCube()) {
|
if (state.isBlockNormalCube()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.get())) { // TODO reconsider this
|
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.value)) { // TODO reconsider this
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block == Blocks.FARMLAND || block == Blocks.GRASS_PATH) {
|
if (block == Blocks.FARMLAND || block == Blocks.GRASS_PATH) {
|
||||||
@@ -279,22 +287,22 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
|
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
|
||||||
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
|
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
|
||||||
Block up = bsi.get0(x, y + 1, z).getBlock();
|
Block up = bsi.get0(x, y + 1, z).getBlock();
|
||||||
if (up == Blocks.WATERLILY) {
|
if (up == Blocks.WATERLILY || up == Blocks.CARPET) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isFlowing(state) || block == Blocks.FLOWING_WATER) {
|
if (isFlowing(x, y, z, state, bsi) || block == Blocks.FLOWING_WATER) {
|
||||||
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
|
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
|
||||||
return isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
|
return isWater(up) && !Baritone.settings().assumeWalkOnWater.value;
|
||||||
}
|
}
|
||||||
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
|
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
|
||||||
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
|
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
|
||||||
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.get();
|
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.value;
|
||||||
}
|
}
|
||||||
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
|
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockSlab) {
|
if (block instanceof BlockSlab) {
|
||||||
if (!Baritone.settings().allowWalkOnBottomSlab.get()) {
|
if (!Baritone.settings().allowWalkOnBottomSlab.value) {
|
||||||
if (((BlockSlab) block).isDouble()) {
|
if (((BlockSlab) block).isDouble()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -318,20 +326,22 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z) {
|
static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z) {
|
||||||
return canPlaceAgainst(bsi.get0(x, y, z));
|
return canPlaceAgainst(bsi, x, y, z, bsi.get0(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canPlaceAgainst(BlockStateInterface bsi, BlockPos pos) {
|
static boolean canPlaceAgainst(BlockStateInterface bsi, BlockPos pos) {
|
||||||
return canPlaceAgainst(bsi.get0(pos.getX(), pos.getY(), pos.getZ()));
|
return canPlaceAgainst(bsi, pos.getX(), pos.getY(), pos.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canPlaceAgainst(IPlayerContext ctx, BlockPos pos) {
|
static boolean canPlaceAgainst(IPlayerContext ctx, BlockPos pos) {
|
||||||
return canPlaceAgainst(new BlockStateInterface(ctx), pos);
|
return canPlaceAgainst(new BlockStateInterface(ctx), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canPlaceAgainst(IBlockState state) {
|
static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||||
// TODO isBlockNormalCube isn't the best check for whether or not we can place a block against it. e.g. glass isn't normalCube but we can place against it
|
// can we look at the center of a side face of this block and likely be able to place?
|
||||||
return state.isBlockNormalCube();
|
// (thats how this check is used)
|
||||||
|
// therefore dont include weird things that we technically could place against (like carpet) but practically can't
|
||||||
|
return state.isBlockNormalCube() || state.isFullBlock() || state.getBlock() == Blocks.GLASS || state.getBlock() == Blocks.STAINED_GLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
||||||
@@ -341,7 +351,8 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (!canWalkThrough(context.bsi, x, y, z, state)) {
|
if (!canWalkThrough(context.bsi, x, y, z, state)) {
|
||||||
if (!context.canBreakAt(x, y, z)) {
|
double mult = context.breakCostMultiplierAt(x, y, z);
|
||||||
|
if (mult >= COST_INF) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (avoidBreaking(context.bsi, x, y, z, state)) {
|
if (avoidBreaking(context.bsi, x, y, z, state)) {
|
||||||
@@ -358,6 +369,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
|
|
||||||
double result = m / strVsBlock;
|
double result = m / strVsBlock;
|
||||||
result += context.breakBlockAdditionalCost;
|
result += context.breakBlockAdditionalCost;
|
||||||
|
result *= mult;
|
||||||
if (includeFalling) {
|
if (includeFalling) {
|
||||||
IBlockState above = context.get(x, y + 1, z);
|
IBlockState above = context.get(x, y + 1, z);
|
||||||
if (above.getBlock() instanceof BlockFalling) {
|
if (above.getBlock() instanceof BlockFalling) {
|
||||||
@@ -396,48 +408,11 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock());
|
ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean throwaway(IPlayerContext ctx, boolean select) {
|
|
||||||
EntityPlayerSP p = ctx.player();
|
|
||||||
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
|
||||||
for (byte i = 0; i < 9; i++) {
|
|
||||||
ItemStack item = inv.get(i);
|
|
||||||
// this usage of settings() is okay because it's only called once during pathing
|
|
||||||
// (while creating the CalculationContext at the very beginning)
|
|
||||||
// and then it's called during execution
|
|
||||||
// since this function is never called during cost calculation, we don't need to migrate
|
|
||||||
// acceptableThrowawayItems to the CalculationContext
|
|
||||||
if (Baritone.settings().acceptableThrowawayItems.get().contains(item.getItem())) {
|
|
||||||
if (select) {
|
|
||||||
p.inventory.currentItem = i;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Baritone.settings().acceptableThrowawayItems.get().contains(p.inventory.offHandInventory.get(0).getItem())) {
|
|
||||||
// main hand takes precedence over off hand
|
|
||||||
// that means that if we have block A selected in main hand and block B in off hand, right clicking places block B
|
|
||||||
// we've already checked above ^ and the main hand can't possible have an acceptablethrowawayitem
|
|
||||||
// so we need to select in the main hand something that doesn't right click
|
|
||||||
// so not a shovel, not a hoe, not a block, etc
|
|
||||||
for (byte i = 0; i < 9; i++) {
|
|
||||||
ItemStack item = inv.get(i);
|
|
||||||
if (item.isEmpty() || item.getItem() instanceof ItemPickaxe) {
|
|
||||||
if (select) {
|
|
||||||
p.inventory.currentItem = i;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) {
|
static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) {
|
||||||
EntityPlayerSP player = ctx.player();
|
|
||||||
state.setTarget(new MovementTarget(
|
state.setTarget(new MovementTarget(
|
||||||
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
|
new Rotation(RotationUtils.calcRotationFromVec3d(ctx.playerHead(),
|
||||||
VecUtils.getBlockPosCenter(pos),
|
VecUtils.getBlockPosCenter(pos),
|
||||||
new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch),
|
ctx.playerRotations()).getYaw(), ctx.player().rotationPitch),
|
||||||
false
|
false
|
||||||
)).setInput(Input.MOVE_FORWARD, true);
|
)).setInput(Input.MOVE_FORWARD, true);
|
||||||
}
|
}
|
||||||
@@ -480,9 +455,71 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return BlockStateInterface.getBlock(ctx, p) instanceof BlockLiquid;
|
return BlockStateInterface.getBlock(ctx, p) instanceof BlockLiquid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isFlowing(IBlockState state) {
|
static boolean possiblyFlowing(IBlockState state) {
|
||||||
// Will be IFluidState in 1.13
|
// Will be IFluidState in 1.13
|
||||||
return state.getBlock() instanceof BlockLiquid
|
return state.getBlock() instanceof BlockLiquid
|
||||||
&& state.getValue(BlockLiquid.LEVEL) != 0;
|
&& state.getValue(BlockLiquid.LEVEL) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isFlowing(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
||||||
|
if (!(state.getBlock() instanceof BlockLiquid)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (state.getValue(BlockLiquid.LEVEL) != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return possiblyFlowing(bsi.get0(x + 1, y, z))
|
||||||
|
|| possiblyFlowing(bsi.get0(x - 1, y, z))
|
||||||
|
|| possiblyFlowing(bsi.get0(x, y, z + 1))
|
||||||
|
|| possiblyFlowing(bsi.get0(x, y, z - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PlaceResult attemptToPlaceABlock(MovementState state, IBaritone baritone, BlockPos placeAt, boolean preferDown) {
|
||||||
|
IPlayerContext ctx = baritone.getPlayerContext();
|
||||||
|
Optional<Rotation> direct = RotationUtils.reachable(ctx, placeAt); // we assume that if there is a block there, it must be replacable
|
||||||
|
boolean found = false;
|
||||||
|
if (direct.isPresent()) {
|
||||||
|
state.setTarget(new MovementState.MovementTarget(direct.get(), true));
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
|
||||||
|
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
|
||||||
|
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
|
||||||
|
Helper.HELPER.logDebug("bb pls get me some blocks. dirt or cobble");
|
||||||
|
state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
|
return PlaceResult.NO_OPTION;
|
||||||
|
}
|
||||||
|
double faceX = (placeAt.getX() + against1.getX() + 1.0D) * 0.5D;
|
||||||
|
double faceY = (placeAt.getY() + against1.getY() + 1.0D) * 0.5D;
|
||||||
|
double faceZ = (placeAt.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
||||||
|
Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
|
||||||
|
RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance());
|
||||||
|
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) {
|
||||||
|
state.setTarget(new MovementState.MovementTarget(place, true));
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if (!preferDown) {
|
||||||
|
// if preferDown is true, we want the last option
|
||||||
|
// if preferDown is false, we want the first
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctx.getSelectedBlock().isPresent()) {
|
||||||
|
BlockPos selectedBlock = ctx.getSelectedBlock().get();
|
||||||
|
EnumFacing side = ctx.objectMouseOver().sideHit;
|
||||||
|
// only way for selectedBlock.equals(placeAt) to be true is if it's replacable
|
||||||
|
if (selectedBlock.equals(placeAt) || (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(placeAt))) {
|
||||||
|
return PlaceResult.READY_TO_PLACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found ? PlaceResult.ATTEMPTING : PlaceResult.NO_OPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PlaceResult {
|
||||||
|
READY_TO_PLACE, ATTEMPTING, NO_OPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import baritone.Baritone;
|
|||||||
import baritone.api.IBaritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
import baritone.api.utils.RotationUtils;
|
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
@@ -32,10 +31,6 @@ import net.minecraft.block.BlockFalling;
|
|||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class MovementAscend extends Movement {
|
public class MovementAscend extends Movement {
|
||||||
|
|
||||||
@@ -58,14 +53,16 @@ public class MovementAscend extends Movement {
|
|||||||
|
|
||||||
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||||
IBlockState toPlace = context.get(destX, y, destZ);
|
IBlockState toPlace = context.get(destX, y, destZ);
|
||||||
boolean hasToPlace = false;
|
double additionalPlacementCost = 0;
|
||||||
if (!MovementHelper.canWalkOn(context.bsi, destX, y, destZ, toPlace)) {
|
if (!MovementHelper.canWalkOn(context.bsi, destX, y, destZ, toPlace)) {
|
||||||
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
|
additionalPlacementCost = context.costOfPlacingAt(destX, y, destZ);
|
||||||
|
if (additionalPlacementCost >= COST_INF) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.isReplacable(destX, y, destZ, toPlace, context.bsi)) {
|
if (!MovementHelper.isReplacable(destX, y, destZ, toPlace, context.bsi)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
|
boolean foundPlaceOption = false;
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
||||||
int againstY = y + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
int againstY = y + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
||||||
@@ -74,11 +71,11 @@ public class MovementAscend extends Movement {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
|
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) {
|
||||||
hasToPlace = true;
|
foundPlaceOption = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasToPlace) { // didn't find a valid place =(
|
if (!foundPlaceOption) { // didn't find a valid place =(
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,10 +126,7 @@ public class MovementAscend extends Movement {
|
|||||||
walk += context.jumpPenalty;
|
walk += context.jumpPenalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
double totalCost = walk;
|
double totalCost = walk + additionalPlacementCost;
|
||||||
if (hasToPlace) {
|
|
||||||
totalCost += context.placeBlockCost;
|
|
||||||
}
|
|
||||||
// start with srcUp2 since we already have its state
|
// start with srcUp2 since we already have its state
|
||||||
// includeFalling isn't needed because of the falling check above -- if srcUp3 is falling we will have already exited with COST_INF if we'd actually have to break it
|
// includeFalling isn't needed because of the falling check above -- if srcUp3 is falling we will have already exited with COST_INF if we'd actually have to break it
|
||||||
totalCost += MovementHelper.getMiningDurationTicks(context, x, y + 2, z, srcUp2, false);
|
totalCost += MovementHelper.getMiningDurationTicks(context, x, y + 2, z, srcUp2, false);
|
||||||
@@ -160,65 +154,51 @@ public class MovementAscend extends Movement {
|
|||||||
return state.setStatus(MovementStatus.SUCCESS);
|
return state.setStatus(MovementStatus.SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx.playerFeet().y < src.y) {
|
||||||
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
|
}
|
||||||
|
|
||||||
IBlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace);
|
IBlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace);
|
||||||
if (!MovementHelper.canWalkOn(ctx, positionToPlace, jumpingOnto)) {
|
if (!MovementHelper.canWalkOn(ctx, positionToPlace, jumpingOnto)) {
|
||||||
for (int i = 0; i < 5; i++) {
|
ticksWithoutPlacement++;
|
||||||
BlockPos anAgainst = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
|
if (MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), false) == PlaceResult.READY_TO_PLACE) {
|
||||||
if (anAgainst.equals(src)) {
|
state.setInput(Input.SNEAK, true);
|
||||||
continue;
|
if (ctx.player().isSneaking()) {
|
||||||
}
|
state.setInput(Input.CLICK_RIGHT, true);
|
||||||
if (MovementHelper.canPlaceAgainst(ctx, anAgainst)) {
|
|
||||||
if (!MovementHelper.throwaway(ctx, true)) {//get ready to place a throwaway block
|
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
|
||||||
}
|
|
||||||
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(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()), true));
|
|
||||||
EnumFacing side = ctx.objectMouseOver().sideHit;
|
|
||||||
|
|
||||||
ctx.getSelectedBlock().ifPresent(selectedBlock -> {
|
|
||||||
if (Objects.equals(selectedBlock, anAgainst) && selectedBlock.offset(side).equals(positionToPlace)) {
|
|
||||||
ticksWithoutPlacement++;
|
|
||||||
state.setInput(Input.SNEAK, true);
|
|
||||||
if (ctx.player().isSneaking()) {
|
|
||||||
state.setInput(Input.CLICK_RIGHT, true);
|
|
||||||
}
|
|
||||||
if (ticksWithoutPlacement > 10) {
|
|
||||||
// After 10 ticks without placement, we might be standing in the way, move back
|
|
||||||
state.setInput(Input.MOVE_BACK, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state.setInput(Input.CLICK_LEFT, true); // break whatever replaceable block is in the way
|
|
||||||
}
|
|
||||||
//System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
|
|
||||||
});
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
if (ticksWithoutPlacement > 10) {
|
||||||
|
// After 10 ticks without placement, we might be standing in the way, move back
|
||||||
|
state.setInput(Input.MOVE_BACK, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
MovementHelper.moveTowards(ctx, state, dest);
|
MovementHelper.moveTowards(ctx, state, dest);
|
||||||
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(BlockStateInterface.get(ctx, src.down()))) {
|
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(BlockStateInterface.get(ctx, src.down()))) {
|
||||||
return state; // don't jump while walking from a non double slab into a bottom slab
|
return state; // don't jump while walking from a non double slab into a bottom slab
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Baritone.settings().assumeStep.get()) {
|
if (Baritone.settings().assumeStep.value || ctx.playerFeet().equals(src.up())) {
|
||||||
|
// no need to hit space if we're already jumping
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.playerFeet().equals(src.up())) {
|
|
||||||
return state; // no need to hit space if we're already jumping
|
|
||||||
}
|
|
||||||
|
|
||||||
if (headBonkClear()) {
|
|
||||||
return state.setInput(Input.JUMP, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xAxis = Math.abs(src.getX() - dest.getX()); // either 0 or 1
|
int xAxis = Math.abs(src.getX() - dest.getX()); // either 0 or 1
|
||||||
int zAxis = Math.abs(src.getZ() - dest.getZ()); // either 0 or 1
|
int zAxis = Math.abs(src.getZ() - dest.getZ()); // either 0 or 1
|
||||||
double flatDistToNext = xAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + zAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
|
double flatDistToNext = xAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + zAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
|
||||||
double sideDist = zAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + xAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
|
double sideDist = zAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + xAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
|
||||||
|
|
||||||
|
double lateralMotion = xAxis * ctx.player().motionZ + zAxis * ctx.player().motionX;
|
||||||
|
if (Math.abs(lateralMotion) > 0.1) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headBonkClear()) {
|
||||||
|
return state.setInput(Input.JUMP, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// System.out.println(flatDistToNext + " " + sideDist);
|
// System.out.println(flatDistToNext + " " + sideDist);
|
||||||
if (flatDistToNext > 1.2 || sideDist > 0.2) {
|
if (flatDistToNext > 1.2 || sideDist > 0.2) {
|
||||||
return state;
|
return state;
|
||||||
@@ -230,7 +210,7 @@ public class MovementAscend extends Movement {
|
|||||||
return state.setInput(Input.JUMP, true);
|
return state.setInput(Input.JUMP, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean headBonkClear() {
|
public boolean headBonkClear() {
|
||||||
BetterBlockPos startUp = src.up(2);
|
BetterBlockPos startUp = src.up(2);
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
BetterBlockPos check = startUp.offset(EnumFacing.byHorizontalIndex(i));
|
BetterBlockPos check = startUp.offset(EnumFacing.byHorizontalIndex(i));
|
||||||
@@ -241,4 +221,10 @@ public class MovementAscend extends Movement {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean safeToCancel(MovementState state) {
|
||||||
|
// if we had to place, don't allow pause
|
||||||
|
return state.getStatus() != MovementStatus.RUNNING || ticksWithoutPlacement == 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ public class MovementDescend extends Movement {
|
|||||||
// and potentially replace the water we're going to fall into
|
// and potentially replace the water we're going to fall into
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkThrough(context.bsi, destX, y - 2, destZ, below) && below.getBlock() != Blocks.WATER) {
|
if (!MovementHelper.canWalkThrough(context.bsi, destX, y - 2, destZ, below)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
double costSoFar = 0;
|
double costSoFar = 0;
|
||||||
@@ -137,13 +137,14 @@ public class MovementDescend extends Movement {
|
|||||||
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
||||||
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
|
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
|
||||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
|
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
|
||||||
if (ontoBlock.getBlock() == Blocks.WATER && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) {
|
if (MovementHelper.isWater(ontoBlock.getBlock())) {
|
||||||
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
|
if (!MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
|
||||||
// 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)
|
return false;
|
||||||
|
}
|
||||||
if (context.assumeWalkOnWater) {
|
if (context.assumeWalkOnWater) {
|
||||||
return false; // TODO fix
|
return false; // TODO fix
|
||||||
}
|
}
|
||||||
if (MovementHelper.isFlowing(ontoBlock)) {
|
if (MovementHelper.isFlowing(destX, newY, destZ, ontoBlock, context.bsi)) {
|
||||||
return false; // TODO flowing check required here?
|
return false; // TODO flowing check required here?
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkOn(context.bsi, destX, newY - 1, destZ)) {
|
if (!MovementHelper.canWalkOn(context.bsi, destX, newY - 1, destZ)) {
|
||||||
@@ -157,9 +158,6 @@ public class MovementDescend extends Movement {
|
|||||||
res.cost = tentativeCost;// TODO incorporate water swim up cost?
|
res.cost = tentativeCost;// TODO incorporate water swim up cost?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ontoBlock.getBlock() == Blocks.FLOWING_WATER) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) {
|
if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) {
|
||||||
// if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know
|
// if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know
|
||||||
// this effectively "resets" our falling speed
|
// this effectively "resets" our falling speed
|
||||||
@@ -177,13 +175,6 @@ public class MovementDescend extends Movement {
|
|||||||
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
||||||
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
||||||
}
|
}
|
||||||
if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
|
|
||||||
res.x = destX;
|
|
||||||
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
|
|
||||||
res.z = destZ;
|
|
||||||
res.cost = tentativeCost + context.placeBlockCost;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (unprotectedFallHeight <= context.maxFallHeightNoWater + 1) {
|
if (unprotectedFallHeight <= context.maxFallHeightNoWater + 1) {
|
||||||
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
||||||
res.x = destX;
|
res.x = destX;
|
||||||
@@ -191,6 +182,13 @@ public class MovementDescend extends Movement {
|
|||||||
res.z = destZ;
|
res.z = destZ;
|
||||||
res.cost = tentativeCost;
|
res.cost = tentativeCost;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
|
||||||
|
res.x = destX;
|
||||||
|
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
|
||||||
|
res.z = destZ;
|
||||||
|
res.cost = tentativeCost + context.placeBucketCost();
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -205,7 +203,8 @@ public class MovementDescend extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlockPos playerFeet = ctx.playerFeet();
|
BlockPos playerFeet = ctx.playerFeet();
|
||||||
if (playerFeet.equals(dest) && (MovementHelper.isLiquid(ctx, dest) || ctx.player().posY - playerFeet.getY() < 0.094)) { // lilypads
|
BlockPos fakeDest = new BlockPos(dest.getX() * 2 - src.getX(), dest.getY(), dest.getZ() * 2 - src.getZ());
|
||||||
|
if ((playerFeet.equals(dest) || playerFeet.equals(fakeDest)) && (MovementHelper.isLiquid(ctx, dest) || ctx.player().posY - dest.getY() < 0.5)) { // lilypads
|
||||||
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
|
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
|
||||||
return state.setStatus(MovementStatus.SUCCESS);
|
return state.setStatus(MovementStatus.SUCCESS);
|
||||||
/* else {
|
/* else {
|
||||||
@@ -213,8 +212,8 @@ public class MovementDescend extends Movement {
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
if (safeMode()) {
|
if (safeMode()) {
|
||||||
double destX = (src.getX() + 0.5) * 0.19 + (dest.getX() + 0.5) * 0.81;
|
double destX = (src.getX() + 0.5) * 0.17 + (dest.getX() + 0.5) * 0.83;
|
||||||
double destZ = (src.getZ() + 0.5) * 0.19 + (dest.getZ() + 0.5) * 0.81;
|
double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83;
|
||||||
EntityPlayerSP player = ctx.player();
|
EntityPlayerSP player = ctx.player();
|
||||||
state.setTarget(new MovementState.MovementTarget(
|
state.setTarget(new MovementState.MovementTarget(
|
||||||
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
|
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
|
||||||
@@ -231,13 +230,8 @@ public class MovementDescend extends Movement {
|
|||||||
double z = ctx.player().posZ - (src.getZ() + 0.5);
|
double z = ctx.player().posZ - (src.getZ() + 0.5);
|
||||||
double fromStart = Math.sqrt(x * x + z * z);
|
double fromStart = Math.sqrt(x * x + z * z);
|
||||||
if (!playerFeet.equals(dest) || ab > 0.25) {
|
if (!playerFeet.equals(dest) || ab > 0.25) {
|
||||||
BlockPos fakeDest = new BlockPos(dest.getX() * 2 - src.getX(), dest.getY(), dest.getZ() * 2 - src.getZ());
|
if (numTicks++ < 20 && fromStart < 1.25) {
|
||||||
if (numTicks++ < 20) {
|
|
||||||
MovementHelper.moveTowards(ctx, state, fakeDest);
|
MovementHelper.moveTowards(ctx, state, fakeDest);
|
||||||
if (fromStart > 1.25) {
|
|
||||||
state.setInput(Input.MOVE_FORWARD, false);
|
|
||||||
state.setInput(Input.MOVE_BACK, true);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
MovementHelper.moveTowards(ctx, state, dest);
|
MovementHelper.moveTowards(ctx, state, dest);
|
||||||
}
|
}
|
||||||
@@ -249,6 +243,10 @@ public class MovementDescend extends Movement {
|
|||||||
// (dest - src) + dest is offset 1 more in the same direction
|
// (dest - src) + dest is offset 1 more in the same direction
|
||||||
// so it's the block we'd need to worry about running into if we decide to sprint straight through this descend
|
// so it's the block we'd need to worry about running into if we decide to sprint straight through this descend
|
||||||
BlockPos into = dest.subtract(src.down()).add(dest);
|
BlockPos into = dest.subtract(src.down()).add(dest);
|
||||||
|
if (skipToAscend()) {
|
||||||
|
// if dest extends into can't walk through, but the two above are can walk through, then we can overshoot and glitch in that weird way
|
||||||
|
return true;
|
||||||
|
}
|
||||||
for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks
|
for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks
|
||||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(ctx, into.up(y)))) {
|
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(ctx, into.up(y)))) {
|
||||||
return true;
|
return true;
|
||||||
@@ -256,4 +254,9 @@ public class MovementDescend extends Movement {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean skipToAscend() {
|
||||||
|
BlockPos into = dest.subtract(src.down()).add(dest);
|
||||||
|
return !MovementHelper.canWalkThrough(ctx, new BetterBlockPos(into)) && MovementHelper.canWalkThrough(ctx, new BetterBlockPos(into).up()) && MovementHelper.canWalkThrough(ctx, new BetterBlockPos(into).up(2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
import baritone.api.IBaritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
@@ -114,7 +115,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState pb3 = context.get(destX, y + 1, z);
|
IBlockState pb3 = context.get(destX, y + 1, z);
|
||||||
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) {
|
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3.getBlock()))) {
|
||||||
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
|
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -123,7 +124,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
|
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER))) {
|
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1.getBlock()))) {
|
||||||
// and now that option B is fully calculated, see if we can edge around that way
|
// and now that option B is fully calculated, see if we can edge around that way
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -173,13 +174,25 @@ public class MovementDiagonal extends Movement {
|
|||||||
state.setStatus(MovementStatus.SUCCESS);
|
state.setStatus(MovementStatus.SUCCESS);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.isLiquid(ctx, ctx.playerFeet())) {
|
if (sprint()) {
|
||||||
state.setInput(Input.SPRINT, true);
|
state.setInput(Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
MovementHelper.moveTowards(ctx, state, dest);
|
MovementHelper.moveTowards(ctx, state, dest);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean sprint() {
|
||||||
|
if (MovementHelper.isLiquid(ctx, ctx.playerFeet()) && !Baritone.settings().sprintInWater.value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (!MovementHelper.canWalkThrough(ctx, positionsToBreak[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean prepared(MovementState state) {
|
protected boolean prepared(MovementState state) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import baritone.pathing.movement.MovementHelper;
|
|||||||
import baritone.pathing.movement.MovementState;
|
import baritone.pathing.movement.MovementState;
|
||||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockLadder;
|
import net.minecraft.block.BlockLadder;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
@@ -77,9 +78,11 @@ public class MovementFall extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BlockPos playerFeet = ctx.playerFeet();
|
BlockPos playerFeet = ctx.playerFeet();
|
||||||
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest));
|
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations());
|
||||||
Rotation targetRotation = null;
|
Rotation targetRotation = null;
|
||||||
if (!MovementHelper.isWater(ctx, dest) && willPlaceBucket() && !playerFeet.equals(dest)) {
|
Block destBlock = ctx.world().getBlockState(dest).getBlock();
|
||||||
|
boolean isWater = destBlock == Blocks.WATER || destBlock == Blocks.FLOWING_WATER;
|
||||||
|
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
|
||||||
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) {
|
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) {
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
@@ -100,8 +103,8 @@ public class MovementFall extends Movement {
|
|||||||
} else {
|
} else {
|
||||||
state.setTarget(new MovementTarget(toDest, false));
|
state.setTarget(new MovementTarget(toDest, false));
|
||||||
}
|
}
|
||||||
if (playerFeet.equals(dest) && (ctx.player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(ctx, dest))) { // 0.094 because lilypads
|
if (playerFeet.equals(dest) && (ctx.player().posY - playerFeet.getY() < 0.094 || isWater)) { // 0.094 because lilypads
|
||||||
if (MovementHelper.isWater(ctx, dest)) {
|
if (isWater) { // only match water, not flowing water (which we cannot pick up with a bucket)
|
||||||
if (InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
|
if (InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) {
|
||||||
ctx.player().inventory.currentItem = ctx.player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
|
ctx.player().inventory.currentItem = ctx.player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
|
||||||
if (ctx.player().motionY >= 0) {
|
if (ctx.player().motionY >= 0) {
|
||||||
@@ -132,13 +135,13 @@ public class MovementFall extends Movement {
|
|||||||
double dist = Math.abs(avoid.getX() * (destCenter.x - avoid.getX() / 2.0 - ctx.player().posX)) + Math.abs(avoid.getZ() * (destCenter.z - avoid.getZ() / 2.0 - ctx.player().posZ));
|
double dist = Math.abs(avoid.getX() * (destCenter.x - avoid.getX() / 2.0 - ctx.player().posX)) + Math.abs(avoid.getZ() * (destCenter.z - avoid.getZ() / 2.0 - ctx.player().posZ));
|
||||||
if (dist < 0.6) {
|
if (dist < 0.6) {
|
||||||
state.setInput(Input.MOVE_FORWARD, true);
|
state.setInput(Input.MOVE_FORWARD, true);
|
||||||
} else {
|
} else if (!ctx.player().onGround) {
|
||||||
state.setInput(Input.SNEAK, false);
|
state.setInput(Input.SNEAK, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targetRotation == null) {
|
if (targetRotation == null) {
|
||||||
Vec3d destCenterOffset = new Vec3d(destCenter.x + 0.125 * avoid.getX(), destCenter.y, destCenter.z + 0.125 * avoid.getZ());
|
Vec3d destCenterOffset = new Vec3d(destCenter.x + 0.125 * avoid.getX(), destCenter.y, destCenter.z + 0.125 * avoid.getZ());
|
||||||
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), destCenterOffset), false));
|
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), destCenterOffset, ctx.playerRotations()), false));
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ package baritone.pathing.movement.movements;
|
|||||||
import baritone.api.IBaritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
import baritone.api.utils.RayTraceUtils;
|
|
||||||
import baritone.api.utils.Rotation;
|
|
||||||
import baritone.api.utils.RotationUtils;
|
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
@@ -31,13 +28,11 @@ import baritone.pathing.movement.MovementState;
|
|||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.block.BlockStairs;
|
import net.minecraft.block.BlockStairs;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
|
|
||||||
public class MovementParkour extends Movement {
|
public class MovementParkour extends Movement {
|
||||||
|
|
||||||
@@ -91,7 +86,7 @@ public class MovementParkour extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState standingOn = context.get(x, y - 1, z);
|
IBlockState standingOn = context.get(x, y - 1, z);
|
||||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn)) {
|
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn) || standingOn.getBlock() instanceof BlockLiquid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int maxJump;
|
int maxJump;
|
||||||
@@ -125,9 +120,11 @@ public class MovementParkour extends Movement {
|
|||||||
if (!context.allowParkourPlace) {
|
if (!context.allowParkourPlace) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// time 2 pop off with that dank skynet parkour place
|
||||||
int destX = x + 4 * xDiff;
|
int destX = x + 4 * xDiff;
|
||||||
int destZ = z + 4 * zDiff;
|
int destZ = z + 4 * zDiff;
|
||||||
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
double placeCost = context.costOfPlacingAt(destX, y - 1, destZ);
|
||||||
|
if (placeCost >= COST_INF) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState toReplace = context.get(destX, y - 1, destZ);
|
IBlockState toReplace = context.get(destX, y - 1, destZ);
|
||||||
@@ -145,7 +142,7 @@ public class MovementParkour extends Movement {
|
|||||||
res.x = destX;
|
res.x = destX;
|
||||||
res.y = y;
|
res.y = y;
|
||||||
res.z = destZ;
|
res.z = destZ;
|
||||||
res.cost = costFromJumpDistance(4) + context.placeBlockCost + context.jumpPenalty;
|
res.cost = costFromJumpDistance(4) + placeCost + context.jumpPenalty;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,6 +190,11 @@ public class MovementParkour extends Movement {
|
|||||||
logDebug("Pausing parkour since hand is active");
|
logDebug("Pausing parkour since hand is active");
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
if (ctx.playerFeet().y < src.y) {
|
||||||
|
// we have fallen
|
||||||
|
logDebug("sorry");
|
||||||
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
|
}
|
||||||
if (dist >= 4) {
|
if (dist >= 4) {
|
||||||
state.setInput(Input.SPRINT, true);
|
state.setInput(Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
@@ -209,35 +211,9 @@ public class MovementParkour extends Movement {
|
|||||||
}
|
}
|
||||||
} else if (!ctx.playerFeet().equals(src)) {
|
} else if (!ctx.playerFeet().equals(src)) {
|
||||||
if (ctx.playerFeet().equals(src.offset(direction)) || ctx.player().posY - ctx.playerFeet().getY() > 0.0001) {
|
if (ctx.playerFeet().equals(src.offset(direction)) || ctx.player().posY - ctx.playerFeet().getY() > 0.0001) {
|
||||||
|
if (!MovementHelper.canWalkOn(ctx, dest.down()) && !ctx.player().onGround && MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), true) == PlaceResult.READY_TO_PLACE) {
|
||||||
if (!MovementHelper.canWalkOn(ctx, dest.down()) && !ctx.player().onGround) {
|
// go in the opposite order to check DOWN before all horizontals -- down is preferable because you don't have to look to the side while in midair, which could mess up the trajectory
|
||||||
BlockPos positionToPlace = dest.down();
|
state.setInput(Input.CLICK_RIGHT, true);
|
||||||
for (int i = 4; i >= 0; i--) { // go in the opposite order to check DOWN before all horizontals -- down is preferable because you don't have to look to the side while in midair, which could mess up the trajectory
|
|
||||||
BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
|
|
||||||
if (against1.up().equals(src.offset(direction, 3))) { // we can't turn around that fast
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
|
|
||||||
if (!MovementHelper.throwaway(ctx, true)) {//get ready to place a throwaway block
|
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
|
||||||
}
|
|
||||||
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 = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
|
|
||||||
RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance());
|
|
||||||
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));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.getSelectedBlock().ifPresent(selectedBlock -> {
|
|
||||||
EnumFacing side = ctx.objectMouseOver().sideHit;
|
|
||||||
if (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(dest.down())) {
|
|
||||||
state.setInput(Input.CLICK_RIGHT, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (dist == 3) { // this is a 2 block gap, dest = src + direction * 3
|
if (dist == 3) { // this is a 2 block gap, dest = src + direction * 3
|
||||||
double xDiff = (src.x + 0.5) - ctx.player().posX;
|
double xDiff = (src.x + 0.5) - ctx.player().posX;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement.movements;
|
package baritone.pathing.movement.movements;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
import baritone.api.IBaritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
@@ -35,6 +36,9 @@ import net.minecraft.init.Blocks;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class MovementPillar extends Movement {
|
public class MovementPillar extends Movement {
|
||||||
|
|
||||||
public MovementPillar(IBaritone baritone, BetterBlockPos start, BetterBlockPos end) {
|
public MovementPillar(IBaritone baritone, BetterBlockPos start, BetterBlockPos end) {
|
||||||
@@ -73,8 +77,16 @@ public class MovementPillar extends Movement {
|
|||||||
return LADDER_UP_ONE_COST; // allow ascending pillars of water, but only if we're already in one
|
return LADDER_UP_ONE_COST; // allow ascending pillars of water, but only if we're already in one
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ladder && !context.canPlaceThrowawayAt(x, y, z)) { // we need to place a block where we started to jump on it
|
double placeCost = 0;
|
||||||
return COST_INF;
|
if (!ladder) {
|
||||||
|
// we need to place a block where we started to jump on it
|
||||||
|
placeCost = context.costOfPlacingAt(x, y, z);
|
||||||
|
if (placeCost >= COST_INF) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
if (fromDown.getBlock() == Blocks.AIR) {
|
||||||
|
placeCost += 0.1; // slightly (1/200th of a second) penalize pillaring on what's currently air
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (from instanceof BlockLiquid || (fromDown.getBlock() instanceof BlockLiquid && context.assumeWalkOnWater)) {
|
if (from instanceof BlockLiquid || (fromDown.getBlock() instanceof BlockLiquid && context.assumeWalkOnWater)) {
|
||||||
// otherwise, if we're standing in water, we cannot pillar
|
// otherwise, if we're standing in water, we cannot pillar
|
||||||
@@ -112,7 +124,7 @@ public class MovementPillar extends Movement {
|
|||||||
if (ladder) {
|
if (ladder) {
|
||||||
return LADDER_UP_ONE_COST + hardness * 5;
|
return LADDER_UP_ONE_COST + hardness * 5;
|
||||||
} else {
|
} else {
|
||||||
return JUMP_ONE_BLOCK_COST + context.placeBlockCost + context.jumpPenalty + hardness;
|
return JUMP_ONE_BLOCK_COST + placeCost + context.jumpPenalty + hardness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,10 +158,14 @@ public class MovementPillar extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx.playerFeet().y < src.y) {
|
||||||
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
|
}
|
||||||
|
|
||||||
IBlockState fromDown = BlockStateInterface.get(ctx, src);
|
IBlockState fromDown = BlockStateInterface.get(ctx, src);
|
||||||
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(ctx, dest)) {
|
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(ctx, dest)) {
|
||||||
// stay centered while swimming up a water column
|
// stay centered while swimming up a water column
|
||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest)), false));
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()), false));
|
||||||
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
||||||
if (Math.abs(ctx.player().posX - destCenter.x) > 0.2 || Math.abs(ctx.player().posZ - destCenter.z) > 0.2) {
|
if (Math.abs(ctx.player().posX - destCenter.x) > 0.2 || Math.abs(ctx.player().posZ - destCenter.z) > 0.2) {
|
||||||
state.setInput(Input.MOVE_FORWARD, true);
|
state.setInput(Input.MOVE_FORWARD, true);
|
||||||
@@ -192,7 +208,7 @@ public class MovementPillar extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
} else {
|
} else {
|
||||||
// Get ready to place a throwaway block
|
// Get ready to place a throwaway block
|
||||||
if (!MovementHelper.throwaway(ctx, true)) {
|
if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(src.x, src.y, src.z)) {
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,11 +236,18 @@ public class MovementPillar extends Movement {
|
|||||||
|
|
||||||
|
|
||||||
if (!blockIsThere) {
|
if (!blockIsThere) {
|
||||||
Block fr = BlockStateInterface.get(ctx, src).getBlock();
|
IBlockState frState = BlockStateInterface.get(ctx, src);
|
||||||
if (!(fr instanceof BlockAir || fr.isReplaceable(ctx.world(), src))) {
|
Block fr = frState.getBlock();
|
||||||
|
// TODO: Evaluate usage of getMaterial().isReplaceable()
|
||||||
|
if (!(fr instanceof BlockAir || frState.getMaterial().isReplaceable())) {
|
||||||
|
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), src, ctx.playerController().getBlockReachDistance());
|
||||||
|
if (reachable.isPresent()) {
|
||||||
|
state.setTarget(new MovementState.MovementTarget(reachable.get(), true));
|
||||||
|
}
|
||||||
|
state.setInput(Input.JUMP, false); // breaking is like 5x slower when you're jumping
|
||||||
state.setInput(Input.CLICK_LEFT, true);
|
state.setInput(Input.CLICK_LEFT, true);
|
||||||
blockIsThere = false;
|
blockIsThere = false;
|
||||||
} else if (ctx.player().isSneaking()) { // 1 tick after we're able to place
|
} else if (ctx.player().isSneaking() && (Objects.equals(src.down(), ctx.objectMouseOver().getBlockPos()) || Objects.equals(src, ctx.objectMouseOver().getBlockPos())) && ctx.player().posY > dest.getY() + 0.1) {
|
||||||
state.setInput(Input.CLICK_RIGHT, true);
|
state.setInput(Input.CLICK_RIGHT, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import net.minecraft.block.BlockFenceGate;
|
|||||||
import net.minecraft.block.BlockSlab;
|
import net.minecraft.block.BlockSlab;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
@@ -114,7 +113,8 @@ public class MovementTraverse extends Movement {
|
|||||||
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
|
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
|
double placeCost = context.costOfPlacingAt(destX, y - 1, destZ);
|
||||||
|
if (placeCost >= COST_INF) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb1, false);
|
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb1, false);
|
||||||
@@ -131,18 +131,18 @@ public class MovementTraverse extends Movement {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) { // found a side place option
|
if (MovementHelper.canPlaceAgainst(context.bsi, againstX, againstY, againstZ)) { // found a side place option
|
||||||
return WC + context.placeBlockCost + hardness1 + hardness2;
|
return WC + placeCost + hardness1 + hardness2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now that we've checked all possible directions to side place, we actually need to backplace
|
// now that we've checked all possible directions to side place, we actually need to backplace
|
||||||
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) {
|
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) {
|
||||||
return COST_INF; // can't sneak and backplace against soul sand or half slabs =/
|
return COST_INF; // can't sneak and backplace against soul sand or half slabs (regardless of whether it's top half or bottom half) =/
|
||||||
}
|
}
|
||||||
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
|
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
|
||||||
return COST_INF; // this is obviously impossible
|
return COST_INF; // this is obviously impossible
|
||||||
}
|
}
|
||||||
WC = WC * (SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST);//since we are sneak backplacing, we are sneaking lol
|
WC = WC * (SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST);//since we are sneak backplacing, we are sneaking lol
|
||||||
return WC + context.placeBlockCost + hardness1 + hardness2;
|
return WC + placeCost + hardness1 + hardness2;
|
||||||
}
|
}
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ public class MovementTraverse extends Movement {
|
|||||||
super.updateState(state);
|
super.updateState(state);
|
||||||
if (state.getStatus() != MovementStatus.RUNNING) {
|
if (state.getStatus() != MovementStatus.RUNNING) {
|
||||||
// if the setting is enabled
|
// if the setting is enabled
|
||||||
if (!Baritone.settings().walkWhileBreaking.get()) {
|
if (!Baritone.settings().walkWhileBreaking.value) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
// and if we're prepping (aka mining the block in front)
|
// and if we're prepping (aka mining the block in front)
|
||||||
@@ -175,11 +175,11 @@ public class MovementTraverse extends Movement {
|
|||||||
|
|
||||||
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
|
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
|
||||||
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
|
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
|
||||||
float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest)).getYaw();
|
float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest), ctx.playerRotations()).getYaw();
|
||||||
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
|
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
|
||||||
|
|
||||||
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
|
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
|
||||||
return state.setInput(Input.MOVE_FORWARD, true);
|
return state.setInput(Input.MOVE_FORWARD, true).setInput(Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//sneak may have been set to true in the PREPPING state while mining an adjacent block
|
//sneak may have been set to true in the PREPPING state while mining an adjacent block
|
||||||
@@ -199,7 +199,7 @@ public class MovementTraverse extends Movement {
|
|||||||
isDoorActuallyBlockingUs = true;
|
isDoorActuallyBlockingUs = true;
|
||||||
}
|
}
|
||||||
if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
|
if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
|
||||||
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), positionsToBreak[0])), true))
|
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), positionsToBreak[0]), ctx.playerRotations()), true))
|
||||||
.setInput(Input.CLICK_RIGHT, true);
|
.setInput(Input.CLICK_RIGHT, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (blocked != null) {
|
if (blocked != null) {
|
||||||
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), blocked)), true))
|
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), blocked), ctx.playerRotations()), true))
|
||||||
.setInput(Input.CLICK_RIGHT, true);
|
.setInput(Input.CLICK_RIGHT, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,10 +232,17 @@ public class MovementTraverse extends Movement {
|
|||||||
if (ctx.playerFeet().equals(dest)) {
|
if (ctx.playerFeet().equals(dest)) {
|
||||||
return state.setStatus(MovementStatus.SUCCESS);
|
return state.setStatus(MovementStatus.SUCCESS);
|
||||||
}
|
}
|
||||||
|
Block low = BlockStateInterface.get(ctx, src).getBlock();
|
||||||
|
Block high = BlockStateInterface.get(ctx, src.up()).getBlock();
|
||||||
|
if (!ctx.player().onGround && (low == Blocks.VINE || low == Blocks.LADDER || high == Blocks.VINE || high == Blocks.LADDER)) {
|
||||||
|
// hitting W could cause us to climb the ladder instead of going forward
|
||||||
|
// wait until we're on the ground
|
||||||
|
return state;
|
||||||
|
}
|
||||||
BlockPos into = dest.subtract(src).add(dest);
|
BlockPos into = dest.subtract(src).add(dest);
|
||||||
Block intoBelow = BlockStateInterface.get(ctx, into).getBlock();
|
Block intoBelow = BlockStateInterface.get(ctx, into).getBlock();
|
||||||
Block intoAbove = BlockStateInterface.get(ctx, into.up()).getBlock();
|
Block intoAbove = BlockStateInterface.get(ctx, into.up()).getBlock();
|
||||||
if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(ctx, ctx.playerFeet()) && !MovementHelper.avoidWalkingInto(intoBelow) && !MovementHelper.avoidWalkingInto(intoAbove)) {
|
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, ctx.playerFeet()) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
|
||||||
state.setInput(Input.SPRINT, true);
|
state.setInput(Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock();
|
Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock();
|
||||||
@@ -247,53 +254,47 @@ public class MovementTraverse extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
} else {
|
} else {
|
||||||
wasTheBridgeBlockAlwaysThere = false;
|
wasTheBridgeBlockAlwaysThere = false;
|
||||||
for (int i = 0; i < 5; i++) {
|
Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock();
|
||||||
BlockPos against1 = dest.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
|
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
|
||||||
if (against1.equals(src)) {
|
double dist = Math.max(Math.abs(dest.getX() + 0.5 - ctx.player().posX), Math.abs(dest.getZ() + 0.5 - ctx.player().posZ));
|
||||||
continue;
|
if (dist < 0.85) { // 0.5 + 0.3 + epsilon
|
||||||
}
|
MovementHelper.moveTowards(ctx, state, dest);
|
||||||
against1 = against1.down();
|
return state.setInput(Input.MOVE_FORWARD, false)
|
||||||
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
|
.setInput(Input.MOVE_BACK, true);
|
||||||
if (!MovementHelper.throwaway(ctx, true)) { // get ready to place a throwaway block
|
|
||||||
logDebug("bb pls get me some blocks. dirt or cobble");
|
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
|
||||||
}
|
|
||||||
if (!Baritone.settings().assumeSafeWalk.get()) {
|
|
||||||
state.setInput(Input.SNEAK, true);
|
|
||||||
}
|
|
||||||
Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock();
|
|
||||||
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
|
|
||||||
double dist = Math.max(Math.abs(dest.getX() + 0.5 - ctx.player().posX), Math.abs(dest.getZ() + 0.5 - ctx.player().posZ));
|
|
||||||
if (dist < 0.85) { // 0.5 + 0.3 + epsilon
|
|
||||||
MovementHelper.moveTowards(ctx, state, dest);
|
|
||||||
return state.setInput(Input.MOVE_FORWARD, false)
|
|
||||||
.setInput(Input.MOVE_BACK, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.setInput(Input.MOVE_BACK, false);
|
|
||||||
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(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()), true));
|
|
||||||
|
|
||||||
EnumFacing side = ctx.objectMouseOver().sideHit;
|
|
||||||
if (Objects.equals(ctx.getSelectedBlock().orElse(null), against1) && (ctx.player().isSneaking() || Baritone.settings().assumeSafeWalk.get()) && ctx.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
|
|
||||||
return state.setInput(Input.CLICK_RIGHT, true);
|
|
||||||
}
|
|
||||||
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
|
|
||||||
return state.setInput(Input.CLICK_LEFT, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Baritone.settings().assumeSafeWalk.get()) {
|
double dist1 = Math.max(Math.abs(ctx.player().posX - (dest.getX() + 0.5D)), Math.abs(ctx.player().posZ - (dest.getZ() + 0.5D)));
|
||||||
|
PlaceResult p = MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), false);
|
||||||
|
if ((p == PlaceResult.READY_TO_PLACE || dist1 < 0.6) && !Baritone.settings().assumeSafeWalk.value) {
|
||||||
state.setInput(Input.SNEAK, true);
|
state.setInput(Input.SNEAK, true);
|
||||||
}
|
}
|
||||||
|
switch (p) {
|
||||||
|
case READY_TO_PLACE: {
|
||||||
|
if (ctx.player().isSneaking() || Baritone.settings().assumeSafeWalk.value) {
|
||||||
|
state.setInput(Input.CLICK_RIGHT, true);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
case ATTEMPTING: {
|
||||||
|
if (dist1 > 0.83) {
|
||||||
|
// might need to go forward a bit
|
||||||
|
float yaw = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()).getYaw();
|
||||||
|
if (Math.abs(state.getTarget().rotation.getYaw() - yaw) < 0.1) {
|
||||||
|
// but only if our attempted place is straight ahead
|
||||||
|
return state.setInput(Input.MOVE_FORWARD, true);
|
||||||
|
}
|
||||||
|
} else if (ctx.playerRotations().isReallyCloseTo(state.getTarget().rotation)) {
|
||||||
|
// well i guess theres something in the way
|
||||||
|
return state.setInput(Input.CLICK_LEFT, true);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (whereAmI.equals(dest)) {
|
if (whereAmI.equals(dest)) {
|
||||||
// If we are in the block that we are trying to get to, we are sneaking over air and we need to place a block beneath us against the one we just walked off of
|
// If we are in the block that we are trying to get to, we are sneaking over air and we need to place a block beneath us against the one we just walked off of
|
||||||
// Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
|
// Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
|
||||||
if (!MovementHelper.throwaway(ctx, true)) {// get ready to place a throwaway block
|
|
||||||
logDebug("bb pls get me some blocks. dirt or cobble");
|
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
|
||||||
}
|
|
||||||
double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D;
|
double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D;
|
||||||
double faceY = (dest.getY() + src.getY() - 1.0D) * 0.5D;
|
double faceY = (dest.getY() + src.getY() - 1.0D) * 0.5D;
|
||||||
double faceZ = (dest.getZ() + src.getZ() + 1.0D) * 0.5D;
|
double faceZ = (dest.getZ() + src.getZ() + 1.0D) * 0.5D;
|
||||||
@@ -302,25 +303,26 @@ public class MovementTraverse extends Movement {
|
|||||||
|
|
||||||
Rotation backToFace = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
|
Rotation backToFace = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
|
||||||
float pitch = backToFace.getPitch();
|
float pitch = backToFace.getPitch();
|
||||||
double dist = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ));
|
double dist2 = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ));
|
||||||
if (dist < 0.29) {
|
if (dist2 < 0.29) { // see issue #208
|
||||||
float yaw = RotationUtils.calcRotationFromVec3d(VecUtils.getBlockPosCenter(dest), ctx.playerHead(), ctx.playerRotations()).getYaw();
|
float yaw = RotationUtils.calcRotationFromVec3d(VecUtils.getBlockPosCenter(dest), ctx.playerHead(), ctx.playerRotations()).getYaw();
|
||||||
state.setTarget(new MovementState.MovementTarget(new Rotation(yaw, pitch), true));
|
state.setTarget(new MovementState.MovementTarget(new Rotation(yaw, pitch), true));
|
||||||
state.setInput(Input.MOVE_BACK, true);
|
state.setInput(Input.MOVE_BACK, true);
|
||||||
} else {
|
} else {
|
||||||
state.setTarget(new MovementState.MovementTarget(backToFace, true));
|
state.setTarget(new MovementState.MovementTarget(backToFace, true));
|
||||||
}
|
}
|
||||||
state.setInput(Input.SNEAK, true);
|
|
||||||
if (Objects.equals(ctx.getSelectedBlock().orElse(null), goalLook)) {
|
if (Objects.equals(ctx.getSelectedBlock().orElse(null), goalLook)) {
|
||||||
return state.setInput(Input.CLICK_RIGHT, true); // wait to right click until we are able to place
|
return state.setInput(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());
|
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
|
||||||
return state.setInput(Input.CLICK_LEFT, true);
|
if (ctx.playerRotations().isReallyCloseTo(state.getTarget().rotation)) {
|
||||||
} else {
|
state.setInput(Input.CLICK_LEFT, true);
|
||||||
MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
|
}
|
||||||
return state;
|
return state;
|
||||||
// TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
|
|
||||||
}
|
}
|
||||||
|
MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
|
||||||
|
return state;
|
||||||
|
// TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import baritone.api.pathing.movement.MovementStatus;
|
|||||||
import baritone.api.pathing.path.IPathExecutor;
|
import baritone.api.pathing.path.IPathExecutor;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
import baritone.api.utils.RotationUtils;
|
||||||
import baritone.api.utils.VecUtils;
|
import baritone.api.utils.VecUtils;
|
||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.behavior.PathingBehavior;
|
import baritone.behavior.PathingBehavior;
|
||||||
@@ -39,6 +40,8 @@ import net.minecraft.block.BlockLiquid;
|
|||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -79,6 +82,8 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
private PathingBehavior behavior;
|
private PathingBehavior behavior;
|
||||||
private IPlayerContext ctx;
|
private IPlayerContext ctx;
|
||||||
|
|
||||||
|
private boolean sprintNextTick;
|
||||||
|
|
||||||
public PathExecutor(PathingBehavior behavior, IPath path) {
|
public PathExecutor(PathingBehavior behavior, IPath path) {
|
||||||
this.behavior = behavior;
|
this.behavior = behavior;
|
||||||
this.ctx = behavior.ctx;
|
this.ctx = behavior.ctx;
|
||||||
@@ -101,39 +106,31 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
}
|
}
|
||||||
BetterBlockPos whereShouldIBe = path.positions().get(pathPosition);
|
BetterBlockPos whereShouldIBe = path.positions().get(pathPosition);
|
||||||
BetterBlockPos whereAmI = ctx.playerFeet();
|
BetterBlockPos whereAmI = ctx.playerFeet();
|
||||||
if (!whereShouldIBe.equals(whereAmI)) {
|
if (!whereShouldIBe.equals(whereAmI) && !Blocks.AIR.equals(BlockStateInterface.getBlock(ctx, whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
|
||||||
|
for (int i = 0; i < pathPosition - 1 && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
|
||||||
if (pathPosition == 0 && whereAmI.equals(whereShouldIBe.up()) && Math.abs(ctx.player().motionY) < 0.1 && !(path.movements().get(0) instanceof MovementAscend) && !(path.movements().get(0) instanceof MovementPillar)) {
|
if (whereAmI.equals(path.positions().get(i))) {
|
||||||
// avoid the Wrong Y coordinate bug
|
logDebug("Skipping back " + (pathPosition - i) + " steps, to " + i);
|
||||||
// TODO add a timer here
|
int previousPos = pathPosition;
|
||||||
new MovementDownward(behavior.baritone, whereAmI, whereShouldIBe).update();
|
pathPosition = Math.max(i - 1, 0); // previous step might not actually be done
|
||||||
return false;
|
for (int j = pathPosition; j <= previousPos; j++) {
|
||||||
}
|
path.movements().get(j).reset();
|
||||||
|
|
||||||
if (!Blocks.AIR.equals(BlockStateInterface.getBlock(ctx, whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
|
|
||||||
for (int i = 0; i < pathPosition - 1 && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
|
|
||||||
if (whereAmI.equals(path.positions().get(i))) {
|
|
||||||
logDebug("Skipping back " + (pathPosition - i) + " steps, to " + i);
|
|
||||||
int previousPos = pathPosition;
|
|
||||||
pathPosition = Math.max(i - 1, 0); // previous step might not actually be done
|
|
||||||
for (int j = pathPosition; j <= previousPos; j++) {
|
|
||||||
path.movements().get(j).reset();
|
|
||||||
}
|
|
||||||
onChangeInPathPosition();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
onChangeInPathPosition();
|
||||||
|
onTick();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = pathPosition + 3; i < path.length(); i++) { //dont check pathPosition+1. the movement tells us when it's done (e.g. sneak placing)
|
}
|
||||||
// also don't check pathPosition+2 because reasons
|
for (int i = pathPosition + 3; i < path.length(); i++) { //dont check pathPosition+1. the movement tells us when it's done (e.g. sneak placing)
|
||||||
if (whereAmI.equals(path.positions().get(i))) {
|
// also don't check pathPosition+2 because reasons
|
||||||
if (i - pathPosition > 2) {
|
if (whereAmI.equals(path.positions().get(i))) {
|
||||||
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
|
if (i - pathPosition > 2) {
|
||||||
}
|
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
|
||||||
//System.out.println("Double skip sundae");
|
|
||||||
pathPosition = i - 1;
|
|
||||||
onChangeInPathPosition();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
//System.out.println("Double skip sundae");
|
||||||
|
pathPosition = i - 1;
|
||||||
|
onChangeInPathPosition();
|
||||||
|
onTick();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,17 +190,17 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Movement m = (Movement) path.movements().get(i);
|
Movement m = (Movement) path.movements().get(i);
|
||||||
HashSet<BlockPos> prevBreak = new HashSet<>(m.toBreak(bsi));
|
List<BlockPos> prevBreak = m.toBreak(bsi);
|
||||||
HashSet<BlockPos> prevPlace = new HashSet<>(m.toPlace(bsi));
|
List<BlockPos> prevPlace = m.toPlace(bsi);
|
||||||
HashSet<BlockPos> prevWalkInto = new HashSet<>(m.toWalkInto(bsi));
|
List<BlockPos> prevWalkInto = m.toWalkInto(bsi);
|
||||||
m.resetBlockCache();
|
m.resetBlockCache();
|
||||||
if (!prevBreak.equals(new HashSet<>(m.toBreak(bsi)))) {
|
if (!prevBreak.equals(m.toBreak(bsi))) {
|
||||||
recalcBP = true;
|
recalcBP = true;
|
||||||
}
|
}
|
||||||
if (!prevPlace.equals(new HashSet<>(m.toPlace(bsi)))) {
|
if (!prevPlace.equals(m.toPlace(bsi))) {
|
||||||
recalcBP = true;
|
recalcBP = true;
|
||||||
}
|
}
|
||||||
if (!prevWalkInto.equals(new HashSet<>(m.toWalkInto(bsi)))) {
|
if (!prevWalkInto.equals(m.toWalkInto(bsi))) {
|
||||||
recalcBP = true;
|
recalcBP = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,21 +229,23 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
costEstimateIndex = pathPosition;
|
costEstimateIndex = pathPosition;
|
||||||
// do this only once, when the movement starts, and deliberately get the cost as cached when this path was calculated, not the cost as it is right now
|
// do this only once, when the movement starts, and deliberately get the cost as cached when this path was calculated, not the cost as it is right now
|
||||||
currentMovementOriginalCostEstimate = movement.getCost();
|
currentMovementOriginalCostEstimate = movement.getCost();
|
||||||
for (int i = 1; i < Baritone.settings().costVerificationLookahead.get() && pathPosition + i < path.length() - 1; i++) {
|
for (int i = 1; i < Baritone.settings().costVerificationLookahead.value && pathPosition + i < path.length() - 1; i++) {
|
||||||
if (path.movements().get(pathPosition + i).calculateCostWithoutCaching() >= ActionCosts.COST_INF && canCancel) {
|
if (((Movement) path.movements().get(pathPosition + i)).calculateCost(behavior.secretInternalGetCalculationContext()) >= ActionCosts.COST_INF && canCancel) {
|
||||||
logDebug("Something has changed in the world and a future movement has become impossible. Cancelling.");
|
logDebug("Something has changed in the world and a future movement has become impossible. Cancelling.");
|
||||||
cancel();
|
cancel();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double currentCost = movement.recalculateCost();
|
double currentCost = ((Movement) movement).recalculateCost(behavior.secretInternalGetCalculationContext());
|
||||||
if (currentCost >= ActionCosts.COST_INF && canCancel) {
|
if (currentCost >= ActionCosts.COST_INF && canCancel) {
|
||||||
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
|
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
|
||||||
cancel();
|
cancel();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!movement.calculatedWhileLoaded() && currentCost - currentMovementOriginalCostEstimate > Baritone.settings().maxCostIncrease.get() && canCancel) {
|
if (!movement.calculatedWhileLoaded() && currentCost - currentMovementOriginalCostEstimate > Baritone.settings().maxCostIncrease.value && canCancel) {
|
||||||
|
// don't do this if the movement was calculated while loaded
|
||||||
|
// that means that this isn't a cache error, it's just part of the path interfering with a later part
|
||||||
logDebug("Original cost " + currentMovementOriginalCostEstimate + " current cost " + currentCost + ". Cancelling.");
|
logDebug("Original cost " + currentMovementOriginalCostEstimate + " current cost " + currentCost + ". Cancelling.");
|
||||||
cancel();
|
cancel();
|
||||||
return true;
|
return true;
|
||||||
@@ -269,9 +268,12 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
onTick();
|
onTick();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
sprintIfRequested();
|
sprintNextTick = shouldSprintNextTick();
|
||||||
|
if (!sprintNextTick) {
|
||||||
|
ctx.player().setSprinting(false); // letting go of control doesn't make you stop sprinting actually
|
||||||
|
}
|
||||||
ticksOnCurrent++;
|
ticksOnCurrent++;
|
||||||
if (ticksOnCurrent > currentMovementOriginalCostEstimate + Baritone.settings().movementTimeoutTicks.get()) {
|
if (ticksOnCurrent > currentMovementOriginalCostEstimate + Baritone.settings().movementTimeoutTicks.value) {
|
||||||
// only cancel if the total time has exceeded the initial estimate
|
// only cancel if the total time has exceeded the initial estimate
|
||||||
// as you break the blocks required, the remaining cost goes down, to the point where
|
// as you break the blocks required, the remaining cost goes down, to the point where
|
||||||
// ticksOnCurrent is greater than recalculateCost + 100
|
// ticksOnCurrent is greater than recalculateCost + 100
|
||||||
@@ -371,58 +373,69 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sprintIfRequested() {
|
private boolean shouldSprintNextTick() {
|
||||||
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
|
boolean requested = behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT);
|
||||||
if (!new CalculationContext(behavior.baritone).canSprint) {
|
|
||||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
|
|
||||||
ctx.player().setSprinting(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the movement requested sprinting, then we're done
|
|
||||||
if (behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT)) {
|
|
||||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
|
|
||||||
if (!ctx.player().isSprinting()) {
|
|
||||||
ctx.player().setSprinting(true);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we'll take it from here, no need for minecraft to see we're holding down control and sprint for us
|
// we'll take it from here, no need for minecraft to see we're holding down control and sprint for us
|
||||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
|
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
|
||||||
|
|
||||||
// however, descend doesn't request sprinting, beceause it doesn't know the context of what movement comes after it
|
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
|
||||||
|
if (!new CalculationContext(behavior.baritone).canSprint) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
IMovement current = path.movements().get(pathPosition);
|
IMovement current = path.movements().get(pathPosition);
|
||||||
if (current instanceof MovementDescend && pathPosition < path.length() - 2) {
|
|
||||||
|
|
||||||
if (((MovementDescend) current).safeMode()) {
|
|
||||||
logDebug("Sprinting would be unsafe");
|
|
||||||
ctx.player().setSprinting(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// traverse requests sprinting, so we need to do this check first
|
||||||
|
if (current instanceof MovementTraverse && pathPosition < path.length() - 3) {
|
||||||
IMovement next = path.movements().get(pathPosition + 1);
|
IMovement next = path.movements().get(pathPosition + 1);
|
||||||
if (next instanceof MovementAscend && current.getDirection().up().equals(next.getDirection().down())) {
|
if (next instanceof MovementAscend && sprintableAscend(ctx, (MovementTraverse) current, (MovementAscend) next, path.movements().get(pathPosition + 2))) {
|
||||||
// a descend then an ascend in the same direction
|
if (skipNow(ctx, current)) {
|
||||||
if (!ctx.player().isSprinting()) {
|
logDebug("Skipping traverse to straight ascend");
|
||||||
ctx.player().setSprinting(true);
|
|
||||||
}
|
|
||||||
pathPosition++;
|
|
||||||
// okay to skip clearKeys and / or onChangeInPathPosition here since this isn't possible to repeat, since it's asymmetric
|
|
||||||
logDebug("Skipping descend to straight ascend");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (canSprintInto(ctx, current, next)) {
|
|
||||||
if (ctx.playerFeet().equals(current.getDest())) {
|
|
||||||
pathPosition++;
|
pathPosition++;
|
||||||
onChangeInPathPosition();
|
onChangeInPathPosition();
|
||||||
|
onTick();
|
||||||
|
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
logDebug("Too far to the side to safely sprint ascend");
|
||||||
}
|
}
|
||||||
if (!ctx.player().isSprinting()) {
|
|
||||||
ctx.player().setSprinting(true);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
//logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));
|
}
|
||||||
|
|
||||||
|
// if the movement requested sprinting, then we're done
|
||||||
|
if (requested) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// however, descend and ascend don't request sprinting, because they don't know the context of what movement comes after it
|
||||||
|
if (current instanceof MovementDescend) {
|
||||||
|
|
||||||
|
if (((MovementDescend) current).safeMode() && !((MovementDescend) current).skipToAscend()) {
|
||||||
|
logDebug("Sprinting would be unsafe");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathPosition < path.length() - 2) {
|
||||||
|
IMovement next = path.movements().get(pathPosition + 1);
|
||||||
|
if (next instanceof MovementAscend && current.getDirection().up().equals(next.getDirection().down())) {
|
||||||
|
// a descend then an ascend in the same direction
|
||||||
|
pathPosition++;
|
||||||
|
onChangeInPathPosition();
|
||||||
|
onTick();
|
||||||
|
// okay to skip clearKeys and / or onChangeInPathPosition here since this isn't possible to repeat, since it's asymmetric
|
||||||
|
logDebug("Skipping descend to straight ascend");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (canSprintFromDescendInto(ctx, current, next)) {
|
||||||
|
if (ctx.playerFeet().equals(current.getDest())) {
|
||||||
|
pathPosition++;
|
||||||
|
onChangeInPathPosition();
|
||||||
|
onTick();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (current instanceof MovementAscend && pathPosition != 0) {
|
if (current instanceof MovementAscend && pathPosition != 0) {
|
||||||
IMovement prev = path.movements().get(pathPosition - 1);
|
IMovement prev = path.movements().get(pathPosition - 1);
|
||||||
@@ -430,24 +443,133 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
BlockPos center = current.getSrc().up();
|
BlockPos center = current.getSrc().up();
|
||||||
if (ctx.player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand
|
if (ctx.player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand
|
||||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, false);
|
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, false);
|
||||||
if (!ctx.player().isSprinting()) {
|
return true;
|
||||||
ctx.player().setSprinting(true);
|
}
|
||||||
}
|
}
|
||||||
return;
|
if (pathPosition < path.length() - 2 && prev instanceof MovementTraverse && sprintableAscend(ctx, (MovementTraverse) prev, (MovementAscend) current, path.movements().get(pathPosition + 1))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current instanceof MovementFall) {
|
||||||
|
Tuple<Vec3d, BlockPos> data = overrideFall((MovementFall) current);
|
||||||
|
if (data != null) {
|
||||||
|
BlockPos fallDest = data.getSecond();
|
||||||
|
if (!path.positions().contains(fallDest)) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
if (ctx.playerFeet().equals(fallDest)) {
|
||||||
|
pathPosition = path.positions().indexOf(fallDest);
|
||||||
|
onChangeInPathPosition();
|
||||||
|
onTick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
clearKeys();
|
||||||
|
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getFirst(), ctx.playerRotations()), false);
|
||||||
|
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tuple<Vec3d, BlockPos> overrideFall(MovementFall movement) {
|
||||||
|
Vec3i dir = movement.getDirection();
|
||||||
|
if (dir.getY() < -3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!movement.toBreakCached.isEmpty()) {
|
||||||
|
return null; // it's breaking
|
||||||
|
}
|
||||||
|
Vec3i flatDir = new Vec3i(dir.getX(), 0, dir.getZ());
|
||||||
|
int i;
|
||||||
|
outer:
|
||||||
|
for (i = pathPosition + 1; i < path.length() - 1 && i < pathPosition + 3; i++) {
|
||||||
|
IMovement next = path.movements().get(i);
|
||||||
|
if (!(next instanceof MovementTraverse)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!flatDir.equals(next.getDirection())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
|
||||||
|
BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z);
|
||||||
|
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
|
||||||
|
break outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!MovementHelper.canWalkOn(ctx, next.getDest().down())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
if (i == pathPosition) {
|
||||||
|
return null; // no valid extension exists
|
||||||
|
}
|
||||||
|
double len = i - pathPosition - 0.4;
|
||||||
|
return new Tuple<>(
|
||||||
|
new Vec3d(flatDir.getX() * len + movement.getDest().x + 0.5, movement.getDest().y, flatDir.getZ() * len + movement.getDest().z + 0.5),
|
||||||
|
movement.getDest().add(flatDir.getX() * (i - pathPosition), 0, flatDir.getZ() * (i - pathPosition)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean skipNow(IPlayerContext ctx, IMovement current) {
|
||||||
|
double offTarget = Math.abs(current.getDirection().getX() * (current.getSrc().z + 0.5D - ctx.player().posZ)) + Math.abs(current.getDirection().getZ() * (current.getSrc().x + 0.5D - ctx.player().posX));
|
||||||
|
if (offTarget > 0.1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// we are centered
|
||||||
|
BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2);
|
||||||
|
if (MovementHelper.fullyPassable(ctx.world().getBlockState(headBonk))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// wait 0.3
|
||||||
|
double flatDist = Math.abs(current.getDirection().getX() * (headBonk.getX() + 0.5D - ctx.player().posX)) + Math.abs(current.getDirection().getZ() * (headBonk.getZ() + 0.5 - ctx.player().posZ));
|
||||||
|
return flatDist > 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean sprintableAscend(IPlayerContext ctx, MovementTraverse current, MovementAscend next, IMovement nextnext) {
|
||||||
|
if (!Baritone.settings().sprintAscends.value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!current.getDirection().equals(next.getDirection().down())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (nextnext.getDirection().getX() != next.getDirection().getX() || nextnext.getDirection().getZ() != next.getDirection().getZ()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!MovementHelper.canWalkOn(ctx, current.getDest().down())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!MovementHelper.canWalkOn(ctx, next.getDest().down())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!next.toBreakCached.isEmpty()) {
|
||||||
|
return false; // it's breaking
|
||||||
|
}
|
||||||
|
for (int x = 0; x < 2; x++) {
|
||||||
|
for (int y = 0; y < 3; y++) {
|
||||||
|
BlockPos chk = current.getSrc().up(y);
|
||||||
|
if (x == 1) {
|
||||||
|
chk = chk.add(current.getDirection());
|
||||||
|
}
|
||||||
|
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.player().setSprinting(false);
|
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)).getBlock())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2)).getBlock()); // codacy smh my head
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean canSprintInto(IPlayerContext ctx, IMovement current, IMovement next) {
|
private static boolean canSprintFromDescendInto(IPlayerContext ctx, IMovement current, IMovement next) {
|
||||||
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
|
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(ctx, next.getDest().down())) {
|
if (next instanceof MovementTraverse && next.getDirection().down().equals(current.getDirection()) && MovementHelper.canWalkOn(ctx, next.getDest().down())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.get();
|
return next instanceof MovementDiagonal && Baritone.settings().allowOvershootDiagonalDescend.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onChangeInPathPosition() {
|
private void onChangeInPathPosition() {
|
||||||
@@ -467,6 +589,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getPosition() {
|
public int getPosition() {
|
||||||
return pathPosition;
|
return pathPosition;
|
||||||
}
|
}
|
||||||
@@ -489,8 +612,8 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private PathExecutor cutIfTooLong() {
|
private PathExecutor cutIfTooLong() {
|
||||||
if (pathPosition > Baritone.settings().maxPathHistoryLength.get()) {
|
if (pathPosition > Baritone.settings().maxPathHistoryLength.value) {
|
||||||
int cutoffAmt = Baritone.settings().pathHistoryCutoffAmount.get();
|
int cutoffAmt = Baritone.settings().pathHistoryCutoffAmount.value;
|
||||||
CutoffPath newPath = new CutoffPath(path, cutoffAmt, path.length() - 1);
|
CutoffPath newPath = new CutoffPath(path, cutoffAmt, path.length() - 1);
|
||||||
if (!newPath.getDest().equals(path.getDest())) {
|
if (!newPath.getDest().equals(path.getDest())) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
@@ -532,4 +655,8 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
public Set<BlockPos> toWalkInto() {
|
public Set<BlockPos> toWalkInto() {
|
||||||
return Collections.unmodifiableSet(toWalkInto);
|
return Collections.unmodifiableSet(toWalkInto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSprinting() {
|
||||||
|
return sprintNextTick;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,661 @@
|
|||||||
|
/*
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.goals.GoalBlock;
|
||||||
|
import baritone.api.pathing.goals.GoalComposite;
|
||||||
|
import baritone.api.pathing.goals.GoalGetToBlock;
|
||||||
|
import baritone.api.process.IBuilderProcess;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
|
import baritone.api.utils.*;
|
||||||
|
import baritone.api.utils.input.Input;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
|
import baritone.pathing.movement.Movement;
|
||||||
|
import baritone.pathing.movement.MovementHelper;
|
||||||
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
|
import baritone.utils.BlockStateInterface;
|
||||||
|
import baritone.utils.PathingCommandContext;
|
||||||
|
import baritone.utils.schematic.AirSchematic;
|
||||||
|
import baritone.utils.schematic.Schematic;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.item.ItemBlock;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompressedStreamTools;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.Tuple;
|
||||||
|
import net.minecraft.util.math.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
|
||||||
|
|
||||||
|
public class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
|
||||||
|
|
||||||
|
public BuilderProcess(Baritone baritone) {
|
||||||
|
super(baritone);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashSet<BetterBlockPos> incorrectPositions;
|
||||||
|
private String name;
|
||||||
|
private ISchematic schematic;
|
||||||
|
private Vec3i origin;
|
||||||
|
private int ticks;
|
||||||
|
|
||||||
|
public boolean build(String schematicFile, BlockPos origin) {
|
||||||
|
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
|
||||||
|
System.out.println(file + " " + file.exists());
|
||||||
|
return build(schematicFile, file, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(String name, ISchematic schematic, Vec3i origin) {
|
||||||
|
this.name = name;
|
||||||
|
this.schematic = schematic;
|
||||||
|
this.origin = origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean build(String name, File schematic, Vec3i origin) {
|
||||||
|
NBTTagCompound tag;
|
||||||
|
try (FileInputStream fileIn = new FileInputStream(schematic)) {
|
||||||
|
tag = CompressedStreamTools.readCompressed(fileIn);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (tag == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
build(name, parse(tag), origin);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearArea(BlockPos corner1, BlockPos corner2) {
|
||||||
|
BlockPos origin = new BlockPos(Math.min(corner1.getX(), corner2.getX()), Math.min(corner1.getY(), corner2.getY()), Math.min(corner1.getZ(), corner2.getZ()));
|
||||||
|
int widthX = Math.abs(corner1.getX() - corner2.getX()) + 1;
|
||||||
|
int heightY = Math.abs(corner1.getY() - corner2.getY()) + 1;
|
||||||
|
int lengthZ = Math.abs(corner1.getZ() - corner2.getZ()) + 1;
|
||||||
|
build("clear area", new AirSchematic(widthX, heightY, lengthZ), origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ISchematic parse(NBTTagCompound schematic) {
|
||||||
|
return new Schematic(schematic);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
return schematic != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockState placeAt(int x, int y, int z) {
|
||||||
|
if (!isActive()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!schematic.inSchematic(x - origin.getX(), y - origin.getY(), z - origin.getZ())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
IBlockState state = schematic.desiredState(x - origin.getX(), y - origin.getY(), z - origin.getZ());
|
||||||
|
if (state.getBlock() == Blocks.AIR) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Optional<Tuple<BetterBlockPos, Rotation>> toBreakNearPlayer(BuilderCalculationContext bcc) {
|
||||||
|
BetterBlockPos center = ctx.playerFeet();
|
||||||
|
for (int dx = -5; dx <= 5; dx++) {
|
||||||
|
for (int dy = 0; dy <= 5; dy++) {
|
||||||
|
for (int dz = -5; dz <= 5; dz++) {
|
||||||
|
int x = center.x + dx;
|
||||||
|
int y = center.y + dy;
|
||||||
|
int z = center.z + dz;
|
||||||
|
IBlockState desired = bcc.getSchematic(x, y, z);
|
||||||
|
if (desired == null) {
|
||||||
|
continue; // irrelevant
|
||||||
|
}
|
||||||
|
IBlockState curr = bcc.bsi.get0(x, y, z);
|
||||||
|
if (curr.getBlock() != Blocks.AIR && !valid(curr, desired)) {
|
||||||
|
BetterBlockPos pos = new BetterBlockPos(x, y, z);
|
||||||
|
Optional<Rotation> rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
|
||||||
|
if (rot.isPresent()) {
|
||||||
|
return Optional.of(new Tuple<>(pos, rot.get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Placement {
|
||||||
|
final int hotbarSelection;
|
||||||
|
final BlockPos placeAgainst;
|
||||||
|
final EnumFacing side;
|
||||||
|
final Rotation rot;
|
||||||
|
|
||||||
|
public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) {
|
||||||
|
this.hotbarSelection = hotbarSelection;
|
||||||
|
this.placeAgainst = placeAgainst;
|
||||||
|
this.side = side;
|
||||||
|
this.rot = rot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Placement> searchForPlacables(BuilderCalculationContext bcc, List<IBlockState> desirableOnHotbar) {
|
||||||
|
BetterBlockPos center = ctx.playerFeet();
|
||||||
|
for (int dx = -5; dx <= 5; dx++) {
|
||||||
|
for (int dy = -5; dy <= 1; dy++) {
|
||||||
|
for (int dz = -5; dz <= 5; dz++) {
|
||||||
|
int x = center.x + dx;
|
||||||
|
int y = center.y + dy;
|
||||||
|
int z = center.z + dz;
|
||||||
|
IBlockState desired = bcc.getSchematic(x, y, z);
|
||||||
|
if (desired == null) {
|
||||||
|
continue; // irrelevant
|
||||||
|
}
|
||||||
|
IBlockState curr = bcc.bsi.get0(x, y, z);
|
||||||
|
if (MovementHelper.isReplacable(x, y, z, curr, bcc.bsi) && !valid(curr, desired)) {
|
||||||
|
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() == Blocks.AIR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
desirableOnHotbar.add(desired);
|
||||||
|
Optional<Placement> opt = possibleToPlace(desired, x, y, z, bcc.bsi);
|
||||||
|
if (opt.isPresent()) {
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Placement> possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) {
|
||||||
|
for (EnumFacing against : EnumFacing.values()) {
|
||||||
|
BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against);
|
||||||
|
IBlockState placeAgainstState = bsi.get0(placeAgainstPos);
|
||||||
|
if (MovementHelper.isReplacable(placeAgainstPos.x, placeAgainstPos.y, placeAgainstPos.z, placeAgainstState, bsi)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!ctx.world().mayPlace(toPlace.getBlock(), new BetterBlockPos(x, y, z), false, against, null)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AxisAlignedBB aabb = placeAgainstState.getBoundingBox(ctx.world(), placeAgainstPos);
|
||||||
|
for (Vec3d placementMultiplier : aabbSideMultipliers(against)) {
|
||||||
|
double placeX = placeAgainstPos.x + aabb.minX * placementMultiplier.x + aabb.maxX * (1 - placementMultiplier.x);
|
||||||
|
double placeY = placeAgainstPos.y + aabb.minY * placementMultiplier.y + aabb.maxY * (1 - placementMultiplier.y);
|
||||||
|
double placeZ = placeAgainstPos.z + aabb.minZ * placementMultiplier.z + aabb.maxZ * (1 - placementMultiplier.z);
|
||||||
|
Rotation rot = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(placeX, placeY, placeZ), ctx.playerRotations());
|
||||||
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot, ctx.playerController().getBlockReachDistance());
|
||||||
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) {
|
||||||
|
OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot);
|
||||||
|
if (hotbar.isPresent()) {
|
||||||
|
return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) {
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
ItemStack stack = ctx.player().inventory.mainInventory.get(i);
|
||||||
|
if (stack.isEmpty() || !(stack.getItem() instanceof ItemBlock)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
float originalYaw = ctx.player().rotationYaw;
|
||||||
|
float originalPitch = ctx.player().rotationPitch;
|
||||||
|
// the state depends on the facing of the player sometimes
|
||||||
|
ctx.player().rotationYaw = rot.getYaw();
|
||||||
|
ctx.player().rotationPitch = rot.getPitch();
|
||||||
|
IBlockState wouldBePlaced = ((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(
|
||||||
|
ctx.world(),
|
||||||
|
result.getBlockPos().offset(result.sideHit),
|
||||||
|
result.sideHit,
|
||||||
|
(float) result.hitVec.x - result.getBlockPos().getX(), // as in PlayerControllerMP
|
||||||
|
(float) result.hitVec.y - result.getBlockPos().getY(),
|
||||||
|
(float) result.hitVec.z - result.getBlockPos().getZ(),
|
||||||
|
stack.getItem().getMetadata(stack.getMetadata()),
|
||||||
|
ctx.player()
|
||||||
|
);
|
||||||
|
ctx.player().rotationYaw = originalYaw;
|
||||||
|
ctx.player().rotationPitch = originalPitch;
|
||||||
|
if (valid(wouldBePlaced, desired)) {
|
||||||
|
return OptionalInt.of(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vec3d[] aabbSideMultipliers(EnumFacing side) {
|
||||||
|
switch (side) {
|
||||||
|
case UP:
|
||||||
|
return new Vec3d[]{new Vec3d(0.5, 1, 0.5), new Vec3d(0.1, 1, 0.5), new Vec3d(0.9, 1, 0.5), new Vec3d(0.5, 1, 0.1), new Vec3d(0.5, 1, 0.9)};
|
||||||
|
case DOWN:
|
||||||
|
return new Vec3d[]{new Vec3d(0.5, 0, 0.5), new Vec3d(0.1, 0, 0.5), new Vec3d(0.9, 0, 0.5), new Vec3d(0.5, 0, 0.1), new Vec3d(0.5, 0, 0.9)};
|
||||||
|
case NORTH:
|
||||||
|
case SOUTH:
|
||||||
|
case EAST:
|
||||||
|
case WEST:
|
||||||
|
double x = side.getXOffset() == 0 ? 0.5 : (1 + side.getXOffset()) / 2D;
|
||||||
|
double z = side.getZOffset() == 0 ? 0.5 : (1 + side.getZOffset()) / 2D;
|
||||||
|
return new Vec3d[]{new Vec3d(x, 0.25, z), new Vec3d(x, 0.75, z)};
|
||||||
|
default: // null
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
|
// TODO somehow tell inventorybehavior what we'd like to have on the hotbar
|
||||||
|
// perhaps take the 16 closest positions in incorrectPositions to ctx.playerFeet that aren't desired to be air, and then snag the top 4 most common block states, then request those on the hotbar
|
||||||
|
|
||||||
|
|
||||||
|
// this will work as is, but it'll be trashy
|
||||||
|
// need to iterate over incorrectPositions and see which ones we can "correct" from our current standing position
|
||||||
|
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
BuilderCalculationContext bcc = new BuilderCalculationContext();
|
||||||
|
if (!recalc(bcc)) {
|
||||||
|
logDirect("Done building");
|
||||||
|
onLostControl();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
trim(bcc);
|
||||||
|
if (baritone.getInputOverrideHandler().isInputForcedDown(Input.CLICK_LEFT)) {
|
||||||
|
ticks = 5;
|
||||||
|
} else {
|
||||||
|
ticks--;
|
||||||
|
}
|
||||||
|
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) {
|
||||||
|
// we'd like to pause to break this block
|
||||||
|
// only change look direction if it's safe (don't want to fuck up an in progress parkour for example
|
||||||
|
Rotation rot = toBreak.get().getSecond();
|
||||||
|
BetterBlockPos pos = toBreak.get().getFirst();
|
||||||
|
baritone.getLookBehavior().updateTarget(rot, true);
|
||||||
|
MovementHelper.switchToBestToolFor(ctx, bcc.get(pos));
|
||||||
|
if (ctx.player().isSneaking()) {
|
||||||
|
// really horrible bug where a block is visible for breaking while sneaking but not otherwise
|
||||||
|
// so you can't see it, it goes to place something else, sneaks, then the next tick it tries to break
|
||||||
|
// and is unable since it's unsneaked in the intermediary tick
|
||||||
|
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true);
|
||||||
|
}
|
||||||
|
if (Objects.equals(ctx.objectMouseOver().getBlockPos(), pos) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||||
|
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true);
|
||||||
|
}
|
||||||
|
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||||
|
}
|
||||||
|
List<IBlockState> desirableOnHotbar = new ArrayList<>();
|
||||||
|
Optional<Placement> toPlace = searchForPlacables(bcc, desirableOnHotbar);
|
||||||
|
if (toPlace.isPresent() && isSafeToCancel && ctx.player().onGround && ticks <= 0) {
|
||||||
|
Rotation rot = toPlace.get().rot;
|
||||||
|
baritone.getLookBehavior().updateTarget(rot, true);
|
||||||
|
ctx.player().inventory.currentItem = toPlace.get().hotbarSelection;
|
||||||
|
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true);
|
||||||
|
if ((Objects.equals(ctx.objectMouseOver().getBlockPos(), toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||||
|
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||||
|
}
|
||||||
|
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IBlockState> approxPlacable = placable(36);
|
||||||
|
if (Baritone.settings().allowInventory.value) {
|
||||||
|
ArrayList<Integer> usefulSlots = new ArrayList<>();
|
||||||
|
List<IBlockState> noValidHotbarOption = new ArrayList<>();
|
||||||
|
outer:
|
||||||
|
for (IBlockState desired : desirableOnHotbar) {
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
if (valid(approxPlacable.get(i), desired)) {
|
||||||
|
usefulSlots.add(i);
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
noValidHotbarOption.add(desired);
|
||||||
|
}
|
||||||
|
|
||||||
|
outer:
|
||||||
|
for (int i = 9; i < 36; i++) {
|
||||||
|
for (IBlockState desired : noValidHotbarOption) {
|
||||||
|
if (valid(approxPlacable.get(i), desired)) {
|
||||||
|
baritone.getInventoryBehavior().attemptToPutOnHotbar(i, usefulSlots::contains);
|
||||||
|
break outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Goal goal = assemble(bcc, approxPlacable.subList(0, 9));
|
||||||
|
if (goal == null) {
|
||||||
|
goal = assemble(bcc, approxPlacable); // we're far away, so assume that we have our whole inventory to recalculate placable properly
|
||||||
|
if (goal == null) {
|
||||||
|
logDirect("Unable to do it =(");
|
||||||
|
onLostControl();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean recalc(BuilderCalculationContext bcc) {
|
||||||
|
if (incorrectPositions == null) {
|
||||||
|
incorrectPositions = new HashSet<>();
|
||||||
|
fullRecalc(bcc);
|
||||||
|
if (incorrectPositions.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recalcNearby(bcc);
|
||||||
|
if (incorrectPositions.isEmpty()) {
|
||||||
|
fullRecalc(bcc);
|
||||||
|
}
|
||||||
|
return !incorrectPositions.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void trim(BuilderCalculationContext bcc) {
|
||||||
|
HashSet<BetterBlockPos> copy = new HashSet<>(incorrectPositions);
|
||||||
|
copy.removeIf(pos -> pos.distanceSq(ctx.player().posX, ctx.player().posY, ctx.player().posZ) > 200);
|
||||||
|
if (!copy.isEmpty()) {
|
||||||
|
incorrectPositions = copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recalcNearby(BuilderCalculationContext bcc) {
|
||||||
|
BetterBlockPos center = ctx.playerFeet();
|
||||||
|
for (int dx = -5; dx <= 5; dx++) {
|
||||||
|
for (int dy = -5; dy <= 5; dy++) {
|
||||||
|
for (int dz = -5; dz <= 5; dz++) {
|
||||||
|
int x = center.x + dx;
|
||||||
|
int y = center.y + dy;
|
||||||
|
int z = center.z + dz;
|
||||||
|
IBlockState desired = bcc.getSchematic(x, y, z);
|
||||||
|
if (desired != null) {
|
||||||
|
// we care about this position
|
||||||
|
if (valid(bcc.bsi.get0(x, y, z), desired)) {
|
||||||
|
incorrectPositions.remove(new BetterBlockPos(x, y, z));
|
||||||
|
} else {
|
||||||
|
incorrectPositions.add(new BetterBlockPos(x, y, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fullRecalc(BuilderCalculationContext bcc) {
|
||||||
|
incorrectPositions = new HashSet<>();
|
||||||
|
for (int y = 0; y < schematic.heightY(); y++) {
|
||||||
|
for (int z = 0; z < schematic.lengthZ(); z++) {
|
||||||
|
for (int x = 0; x < schematic.widthX(); x++) {
|
||||||
|
if (schematic.inSchematic(x, y, z)) {
|
||||||
|
if (!valid(bcc.bsi.get0(x + origin.getX(), y + origin.getY(), z + origin.getZ()), schematic.desiredState(x, y, z))) {
|
||||||
|
incorrectPositions.add(new BetterBlockPos(x + origin.getX(), y + origin.getY(), z + origin.getZ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Goal assemble(BuilderCalculationContext bcc, List<IBlockState> approxPlacable) {
|
||||||
|
List<BetterBlockPos> placable = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() == Blocks.AIR && approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))).collect(Collectors.toList());
|
||||||
|
Goal[] toBreak = incorrectPositions.stream().filter(pos -> bcc.bsi.get0(pos).getBlock() != Blocks.AIR).map(GoalBreak::new).toArray(Goal[]::new);
|
||||||
|
Goal[] toPlace = placable.stream().filter(pos -> !placable.contains(pos.down()) && !placable.contains(pos.down(2))).map(pos -> placementgoal(pos, bcc)).toArray(Goal[]::new);
|
||||||
|
|
||||||
|
if (toPlace.length != 0) {
|
||||||
|
return new JankyGoalComposite(new GoalComposite(toPlace), new GoalComposite(toBreak));
|
||||||
|
}
|
||||||
|
if (toBreak.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new GoalComposite(toBreak);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class JankyGoalComposite implements Goal {
|
||||||
|
private final Goal primary;
|
||||||
|
private final Goal fallback;
|
||||||
|
|
||||||
|
public JankyGoalComposite(Goal primary, Goal fallback) {
|
||||||
|
this.primary = primary;
|
||||||
|
this.fallback = fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
|
return primary.isInGoal(x, y, z) || fallback.isInGoal(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double heuristic(int x, int y, int z) {
|
||||||
|
return primary.heuristic(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "JankyComposite Primary: " + primary + " Fallback: " + fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GoalBreak extends GoalGetToBlock {
|
||||||
|
|
||||||
|
public GoalBreak(BlockPos pos) {
|
||||||
|
super(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
|
// can't stand right on top of a block, that might not work (what if it's unsupported, can't break then)
|
||||||
|
if (y > this.y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// but any other adjacent works for breaking, including inside or below
|
||||||
|
return super.isInGoal(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Goal placementgoal(BlockPos pos, BuilderCalculationContext bcc) {
|
||||||
|
if (ctx.world().getBlockState(pos).getBlock() != Blocks.AIR) {
|
||||||
|
return new GoalPlace(pos);
|
||||||
|
}
|
||||||
|
boolean allowSameLevel = ctx.world().getBlockState(pos.up()).getBlock() != Blocks.AIR;
|
||||||
|
for (EnumFacing facing : Movement.HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP) {
|
||||||
|
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && ctx.world().mayPlace(bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ()).getBlock(), pos, false, facing, null)) {
|
||||||
|
return new GoalAdjacent(pos, allowSameLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new GoalPlace(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GoalAdjacent extends GoalGetToBlock {
|
||||||
|
boolean allowSameLevel;
|
||||||
|
|
||||||
|
public GoalAdjacent(BlockPos pos, boolean allowSameLevel) {
|
||||||
|
super(pos);
|
||||||
|
this.allowSameLevel = allowSameLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
|
if (x == this.x && y == this.y && z == this.z) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!allowSameLevel && y == this.y - 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (y < this.y - 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return super.isInGoal(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double heuristic(int x, int y, int z) {
|
||||||
|
// prioritize lower y coordinates
|
||||||
|
return this.y * 100 + super.heuristic(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GoalPlace extends GoalBlock {
|
||||||
|
public GoalPlace(BlockPos placeAt) {
|
||||||
|
super(placeAt.up());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double heuristic(int x, int y, int z) {
|
||||||
|
// prioritize lower y coordinates
|
||||||
|
return this.y * 100 + super.heuristic(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLostControl() {
|
||||||
|
incorrectPositions = null;
|
||||||
|
name = null;
|
||||||
|
schematic = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String displayName0() {
|
||||||
|
return "Building " + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IBlockState> placable(int size) {
|
||||||
|
List<IBlockState> result = new ArrayList<>();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
ItemStack stack = ctx.player().inventory.mainInventory.get(i);
|
||||||
|
if (stack.isEmpty() || !(stack.getItem() instanceof ItemBlock)) {
|
||||||
|
result.add(Blocks.AIR.getDefaultState());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// <toxic cloud>
|
||||||
|
result.add(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(ctx.world(), ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ, stack.getItem().getMetadata(stack.getMetadata()), ctx.player()));
|
||||||
|
// </toxic cloud>
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean valid(IBlockState current, IBlockState desired) {
|
||||||
|
// TODO more complicated comparison logic I guess
|
||||||
|
return desired == null || current.equals(desired);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BuilderCalculationContext extends CalculationContext {
|
||||||
|
private final List<IBlockState> placable;
|
||||||
|
private final ISchematic schematic;
|
||||||
|
private final int originX;
|
||||||
|
private final int originY;
|
||||||
|
private final int originZ;
|
||||||
|
|
||||||
|
public BuilderCalculationContext() {
|
||||||
|
super(BuilderProcess.this.baritone, true); // wew lad
|
||||||
|
this.placable = placable(9);
|
||||||
|
this.schematic = BuilderProcess.this.schematic;
|
||||||
|
this.originX = origin.getX();
|
||||||
|
this.originY = origin.getY();
|
||||||
|
this.originZ = origin.getZ();
|
||||||
|
|
||||||
|
this.jumpPenalty += 10;
|
||||||
|
this.backtrackCostFavoringCoefficient = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IBlockState getSchematic(int x, int y, int z) {
|
||||||
|
if (schematic.inSchematic(x - originX, y - originY, z - originZ)) {
|
||||||
|
return schematic.desiredState(x - originX, y - originY, z - originZ);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double costOfPlacingAt(int x, int y, int z) {
|
||||||
|
if (isPossiblyProtected(x, y, z) || !worldBorder.canPlaceAt(x, z)) { // make calculation fail properly if we can't build
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
IBlockState sch = getSchematic(x, y, z);
|
||||||
|
if (sch != null) {
|
||||||
|
// TODO this can return true even when allowPlace is off.... is that an issue?
|
||||||
|
if (sch.getBlock() == Blocks.AIR) {
|
||||||
|
// we want this to be air, but they're asking if they can place here
|
||||||
|
// this won't be a schematic block, this will be a throwaway
|
||||||
|
return placeBlockCost * 2; // we're going to have to break it eventually
|
||||||
|
}
|
||||||
|
if (placable.contains(sch)) {
|
||||||
|
return 0; // thats right we gonna make it FREE to place a block where it should go in a structure
|
||||||
|
// no place block penalty at all 😎
|
||||||
|
// i'm such an idiot that i just tried to copy and paste the epic gamer moment emoji too
|
||||||
|
// get added to unicode when?
|
||||||
|
}
|
||||||
|
if (!hasThrowaway) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
// we want it to be something that we don't have
|
||||||
|
// even more of a pain to place something wrong
|
||||||
|
return placeBlockCost * 3;
|
||||||
|
} else {
|
||||||
|
if (hasThrowaway) {
|
||||||
|
return placeBlockCost;
|
||||||
|
} else {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double breakCostMultiplierAt(int x, int y, int z) {
|
||||||
|
if (!allowBreak || isPossiblyProtected(x, y, z)) {
|
||||||
|
return COST_INF;
|
||||||
|
}
|
||||||
|
IBlockState sch = getSchematic(x, y, z);
|
||||||
|
if (sch != null) {
|
||||||
|
if (sch.getBlock() == Blocks.AIR) {
|
||||||
|
// it should be air
|
||||||
|
// regardless of current contents, we can break it
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// it should be a real block
|
||||||
|
// is it already that block?
|
||||||
|
if (valid(bsi.get0(x, y, z), sch)) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
// can break if it's wrong
|
||||||
|
// would be great to return less than 1 here, but that would actually make the cost calculation messed up
|
||||||
|
// since we're breaking a block, if we underestimate the cost, then it'll fail when it really takes the correct amount of time
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
// TODO do blocks in render distace only?
|
||||||
|
// TODO allow breaking blocks that we have a tool to harvest and immediately place back?
|
||||||
|
} else {
|
||||||
|
return 1; // why not lol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,8 +24,6 @@ import baritone.api.process.PathingCommand;
|
|||||||
import baritone.api.process.PathingCommandType;
|
import baritone.api.process.PathingCommandType;
|
||||||
import baritone.utils.BaritoneProcessHelper;
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As set by ExampleBaritoneControl or something idk
|
* As set by ExampleBaritoneControl or something idk
|
||||||
*
|
*
|
||||||
@@ -46,7 +44,7 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
|
|||||||
private State state;
|
private State state;
|
||||||
|
|
||||||
public CustomGoalProcess(Baritone baritone) {
|
public CustomGoalProcess(Baritone baritone) {
|
||||||
super(baritone, 3);
|
super(baritone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,6 +53,9 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
|
|||||||
if (this.state == State.NONE) {
|
if (this.state == State.NONE) {
|
||||||
this.state = State.GOAL_SET;
|
this.state = State.GOAL_SET;
|
||||||
}
|
}
|
||||||
|
if (this.state == State.EXECUTING) {
|
||||||
|
this.state = State.PATH_REQUESTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -76,20 +77,20 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
|
|||||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
switch (this.state) {
|
switch (this.state) {
|
||||||
case GOAL_SET:
|
case GOAL_SET:
|
||||||
if (!baritone.getPathingBehavior().isPathing() && Objects.equals(baritone.getPathingBehavior().getGoal() + "", this.goal + "")) {
|
|
||||||
this.state = State.NONE;
|
|
||||||
}
|
|
||||||
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
|
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
case PATH_REQUESTED:
|
case PATH_REQUESTED:
|
||||||
PathingCommand ret = new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
|
// return FORCE_REVALIDATE_GOAL_AND_PATH just once
|
||||||
|
PathingCommand ret = new PathingCommand(this.goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
||||||
this.state = State.EXECUTING;
|
this.state = State.EXECUTING;
|
||||||
return ret;
|
return ret;
|
||||||
case EXECUTING:
|
case EXECUTING:
|
||||||
if (calcFailed) {
|
if (calcFailed) {
|
||||||
onLostControl();
|
onLostControl();
|
||||||
|
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
}
|
}
|
||||||
if (this.goal == null || this.goal.isInGoal(ctx.playerFeet())) {
|
if (this.goal == null || (this.goal.isInGoal(ctx.playerFeet()) && this.goal.isInGoal(baritone.getPathingBehavior().pathStart()))) {
|
||||||
onLostControl(); // we're there xd
|
onLostControl(); // we're there xd
|
||||||
|
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
}
|
}
|
||||||
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
|
return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
|
||||||
default:
|
default:
|
||||||
@@ -104,7 +105,7 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName() {
|
public String displayName0() {
|
||||||
return "Custom Goal " + this.goal;
|
return "Custom Goal " + this.goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.cache.ICachedWorld;
|
||||||
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
|
import baritone.cache.CachedWorld;
|
||||||
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public class ExploreProcess extends BaritoneProcessHelper {
|
||||||
|
|
||||||
|
private BlockPos explorationOrigin;
|
||||||
|
|
||||||
|
public ExploreProcess(Baritone baritone) {
|
||||||
|
super(baritone);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
return explorationOrigin != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void explore(int centerX, int centerZ) {
|
||||||
|
explorationOrigin = new BlockPos(centerX, 0, centerZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
|
if (calcFailed) {
|
||||||
|
logDirect("Failed");
|
||||||
|
onLostControl();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BlockPos closestUncached = closestUncachedChunk(explorationOrigin);
|
||||||
|
if (closestUncached == null) {
|
||||||
|
logDebug("awaiting region load from disk");
|
||||||
|
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||||
|
}
|
||||||
|
System.out.println("Closest uncached: " + closestUncached);
|
||||||
|
return new PathingCommand(new GoalXZ(closestUncached.getX(), closestUncached.getZ()), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockPos closestUncachedChunk(BlockPos pos) {
|
||||||
|
int chunkX = pos.getX() >> 4;
|
||||||
|
int chunkZ = pos.getZ() >> 4;
|
||||||
|
ICachedWorld cache = baritone.getWorldProvider().getCurrentWorld().getCachedWorld();
|
||||||
|
for (int dist = 0; ; dist++) {
|
||||||
|
for (int dx = -dist; dx <= dist; dx++) {
|
||||||
|
for (int dz = -dist; dz <= dist; dz++) {
|
||||||
|
int trueDist = Baritone.settings().exploreUsePythagorean.value ? dx * dx + dz + dz : Math.abs(dx) + Math.abs(dz);
|
||||||
|
if (trueDist != dist) {
|
||||||
|
continue; // not considering this one just yet in our expanding search
|
||||||
|
}
|
||||||
|
int centerX = (chunkX + dx) * 16 + 8;
|
||||||
|
int centerZ = (chunkZ + dz) * 18 + 8;
|
||||||
|
|
||||||
|
if (cache.isCached(centerX, centerZ)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!((CachedWorld) cache).regionLoaded(centerX, centerZ)) {
|
||||||
|
Baritone.getExecutor().execute(() -> {
|
||||||
|
((CachedWorld) cache).tryLoadFromDisk(centerX >> 9, centerZ >> 9);
|
||||||
|
});
|
||||||
|
return null; // we still need to load regions from disk in order to decide properly
|
||||||
|
}
|
||||||
|
return new BlockPos(centerX, 0, centerZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLostControl() {
|
||||||
|
explorationOrigin = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String displayName0() {
|
||||||
|
return "Exploring around " + explorationOrigin + ", currently going to " + closestUncachedChunk(explorationOrigin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
|||||||
private List<Entity> cache;
|
private List<Entity> cache;
|
||||||
|
|
||||||
public FollowProcess(Baritone baritone) {
|
public FollowProcess(Baritone baritone) {
|
||||||
super(baritone, 1);
|
super(baritone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -58,13 +58,13 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
|||||||
|
|
||||||
private Goal towards(Entity following) {
|
private Goal towards(Entity following) {
|
||||||
BlockPos pos;
|
BlockPos pos;
|
||||||
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
if (Baritone.settings().followOffsetDistance.value == 0) {
|
||||||
pos = new BlockPos(following);
|
pos = new BlockPos(following);
|
||||||
} else {
|
} else {
|
||||||
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.value, Baritone.settings().followOffsetDistance.value);
|
||||||
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
||||||
}
|
}
|
||||||
return new GoalNear(pos, Baritone.settings().followRadius.get());
|
return new GoalNear(pos, Baritone.settings().followRadius.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName() {
|
public String displayName0() {
|
||||||
return "Follow " + cache;
|
return "Follow " + cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,7 @@
|
|||||||
package baritone.process;
|
package baritone.process;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.*;
|
||||||
import baritone.api.pathing.goals.GoalComposite;
|
|
||||||
import baritone.api.pathing.goals.GoalGetToBlock;
|
|
||||||
import baritone.api.pathing.goals.GoalTwoBlocks;
|
|
||||||
import baritone.api.process.IGetToBlockProcess;
|
import baritone.api.process.IGetToBlockProcess;
|
||||||
import baritone.api.process.PathingCommand;
|
import baritone.api.process.PathingCommand;
|
||||||
import baritone.api.process.PathingCommandType;
|
import baritone.api.process.PathingCommandType;
|
||||||
@@ -35,26 +32,27 @@ import net.minecraft.init.Blocks;
|
|||||||
import net.minecraft.inventory.ContainerPlayer;
|
import net.minecraft.inventory.ContainerPlayer;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
|
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
|
||||||
|
|
||||||
private Block gettingTo;
|
private Block gettingTo;
|
||||||
private List<BlockPos> knownLocations;
|
private List<BlockPos> knownLocations;
|
||||||
|
private List<BlockPos> blacklist; // locations we failed to calc to
|
||||||
|
private BlockPos start;
|
||||||
|
|
||||||
private int tickCount = 0;
|
private int tickCount = 0;
|
||||||
|
|
||||||
public GetToBlockProcess(Baritone baritone) {
|
public GetToBlockProcess(Baritone baritone) {
|
||||||
super(baritone, 2);
|
super(baritone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getToBlock(Block block) {
|
public void getToBlock(Block block) {
|
||||||
onLostControl();
|
onLostControl();
|
||||||
gettingTo = block;
|
gettingTo = block;
|
||||||
|
start = ctx.playerFeet();
|
||||||
|
blacklist = new ArrayList<>();
|
||||||
rescan(new ArrayList<>(), new CalculationContext(baritone));
|
rescan(new ArrayList<>(), new CalculationContext(baritone));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,62 +62,125 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||||
if (knownLocations == null) {
|
if (knownLocations == null) {
|
||||||
rescan(new ArrayList<>(), new CalculationContext(baritone));
|
rescan(new ArrayList<>(), new CalculationContext(baritone));
|
||||||
}
|
}
|
||||||
if (knownLocations.isEmpty()) {
|
if (knownLocations.isEmpty()) {
|
||||||
|
if (Baritone.settings().exploreForBlocks.value && !calcFailed) {
|
||||||
|
return new PathingCommand(new GoalRunAway(1, start) {
|
||||||
|
@Override
|
||||||
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
||||||
|
}
|
||||||
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
|
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
|
||||||
if (isSafeToCancel) {
|
if (isSafeToCancel) {
|
||||||
onLostControl();
|
onLostControl();
|
||||||
}
|
}
|
||||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
}
|
}
|
||||||
|
Goal goal = new GoalComposite(knownLocations.stream().map(this::createGoal).toArray(Goal[]::new));
|
||||||
if (calcFailed) {
|
if (calcFailed) {
|
||||||
logDirect("Unable to find any path to " + gettingTo + ", canceling GetToBlock");
|
if (Baritone.settings().blacklistClosestOnFailure.value) {
|
||||||
if (isSafeToCancel) {
|
logDirect("Unable to find any path to " + gettingTo + ", blacklisting presumably unreachable closest instances...");
|
||||||
onLostControl();
|
blacklistClosest();
|
||||||
|
return onTick(false, isSafeToCancel); // gamer moment
|
||||||
|
} else {
|
||||||
|
logDirect("Unable to find any path to " + gettingTo + ", canceling GetToBlock");
|
||||||
|
if (isSafeToCancel) {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
|
return new PathingCommand(goal, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
}
|
}
|
||||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
|
||||||
}
|
}
|
||||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
|
||||||
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
||||||
List<BlockPos> current = new ArrayList<>(knownLocations);
|
List<BlockPos> current = new ArrayList<>(knownLocations);
|
||||||
CalculationContext context = new CalculationContext(baritone, true);
|
CalculationContext context = new CalculationContext(baritone, true);
|
||||||
Baritone.getExecutor().execute(() -> rescan(current, context));
|
Baritone.getExecutor().execute(() -> rescan(current, context));
|
||||||
}
|
}
|
||||||
Goal goal = new GoalComposite(knownLocations.stream().map(this::createGoal).toArray(Goal[]::new));
|
if (goal.isInGoal(ctx.playerFeet()) && goal.isInGoal(baritone.getPathingBehavior().pathStart()) && isSafeToCancel) {
|
||||||
if (goal.isInGoal(ctx.playerFeet()) && isSafeToCancel) {
|
|
||||||
// we're there
|
// we're there
|
||||||
if (rightClickOnArrival(gettingTo)) {
|
if (rightClickOnArrival(gettingTo)) {
|
||||||
if (rightClick()) {
|
if (rightClick()) {
|
||||||
onLostControl();
|
onLostControl();
|
||||||
|
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onLostControl();
|
onLostControl();
|
||||||
|
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// blacklist the closest block and its adjacent blocks
|
||||||
|
public synchronized void blacklistClosest() {
|
||||||
|
List<BlockPos> newBlacklist = new ArrayList<>();
|
||||||
|
knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add);
|
||||||
|
outer:
|
||||||
|
while (true) {
|
||||||
|
for (BlockPos known : knownLocations) {
|
||||||
|
for (BlockPos blacklist : newBlacklist) {
|
||||||
|
if (areAdjacent(known, blacklist)) { // directly adjacent
|
||||||
|
newBlacklist.add(known);
|
||||||
|
knownLocations.remove(known);
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// i can't do break; (codacy gets mad), and i can't do if(true){break}; (codacy gets mad)
|
||||||
|
// so i will do this
|
||||||
|
switch (newBlacklist.size()) {
|
||||||
|
default:
|
||||||
|
break outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logDebug("Blacklisting unreachable locations " + newBlacklist);
|
||||||
|
blacklist.addAll(newBlacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// safer than direct double comparison from distanceSq
|
||||||
|
private boolean areAdjacent(BlockPos posA, BlockPos posB) {
|
||||||
|
int diffX = Math.abs(posA.getX() - posB.getX());
|
||||||
|
int diffY = Math.abs(posA.getY() - posB.getY());
|
||||||
|
int diffZ = Math.abs(posA.getZ() - posB.getZ());
|
||||||
|
return (diffX + diffY + diffZ) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLostControl() {
|
public synchronized void onLostControl() {
|
||||||
gettingTo = null;
|
gettingTo = null;
|
||||||
knownLocations = null;
|
knownLocations = null;
|
||||||
|
start = null;
|
||||||
|
blacklist = null;
|
||||||
baritone.getInputOverrideHandler().clearAllKeys();
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName() {
|
public String displayName0() {
|
||||||
return "Get To Block " + gettingTo;
|
if (knownLocations.isEmpty()) {
|
||||||
|
return "Exploring randomly to find " + gettingTo + ", no known locations";
|
||||||
|
}
|
||||||
|
return "Get To " + gettingTo + ", " + knownLocations.size() + " known locations";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rescan(List<BlockPos> known, CalculationContext context) {
|
private synchronized void rescan(List<BlockPos> known, CalculationContext context) {
|
||||||
knownLocations = MineProcess.searchWorld(context, Collections.singletonList(gettingTo), 64, known);
|
List<BlockPos> positions = MineProcess.searchWorld(context, Collections.singletonList(gettingTo), 64, known, blacklist);
|
||||||
|
positions.removeIf(blacklist::contains);
|
||||||
|
knownLocations = positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Goal createGoal(BlockPos pos) {
|
private Goal createGoal(BlockPos pos) {
|
||||||
return walkIntoInsteadOfAdjacent(gettingTo) ? new GoalTwoBlocks(pos) : new GoalGetToBlock(pos);
|
if (walkIntoInsteadOfAdjacent(gettingTo)) {
|
||||||
|
return new GoalTwoBlocks(pos);
|
||||||
|
}
|
||||||
|
if (blockOnTopMustBeRemoved(gettingTo) && baritone.bsi.get0(pos.up()).isBlockNormalCube()) {
|
||||||
|
return new GoalBlock(pos.up());
|
||||||
|
}
|
||||||
|
return new GoalGetToBlock(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean rightClick() {
|
private boolean rightClick() {
|
||||||
@@ -142,16 +203,24 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean walkIntoInsteadOfAdjacent(Block block) {
|
private boolean walkIntoInsteadOfAdjacent(Block block) {
|
||||||
if (!Baritone.settings().enterPortal.get()) {
|
if (!Baritone.settings().enterPortal.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return block == Blocks.PORTAL;
|
return block == Blocks.PORTAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean rightClickOnArrival(Block block) {
|
private boolean rightClickOnArrival(Block block) {
|
||||||
if (!Baritone.settings().rightClickContainerOnArrival.get()) {
|
if (!Baritone.settings().rightClickContainerOnArrival.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
|
return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean blockOnTopMustBeRemoved(Block block) {
|
||||||
|
if (!rightClickOnArrival(block)) { // only if we plan to actually open it on arrival
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// only these chests; you can open a crafting table or furnace even with a block on top
|
||||||
|
return block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,13 +54,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
|
|
||||||
private List<Block> mining;
|
private List<Block> mining;
|
||||||
private List<BlockPos> knownOreLocations;
|
private List<BlockPos> knownOreLocations;
|
||||||
|
private List<BlockPos> blacklist; // inaccessible
|
||||||
private BlockPos branchPoint;
|
private BlockPos branchPoint;
|
||||||
private GoalRunAway branchPointRunaway;
|
private GoalRunAway branchPointRunaway;
|
||||||
private int desiredQuantity;
|
private int desiredQuantity;
|
||||||
private int tickCount;
|
private int tickCount;
|
||||||
|
|
||||||
public MineProcess(Baritone baritone) {
|
public MineProcess(Baritone baritone) {
|
||||||
super(baritone, 0);
|
super(baritone);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,28 +81,34 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (calcFailed && !knownOreLocations.isEmpty() && Baritone.settings().blacklistClosestOnFailure.value) {
|
||||||
|
logDirect("Unable to find any path to " + mining + ", blacklisting presumably unreachable closest instance...");
|
||||||
|
knownOreLocations.stream().sorted(Comparator.comparingDouble(ctx.player()::getDistanceSq)).findFirst().ifPresent(blacklist::add);
|
||||||
|
knownOreLocations.removeIf(blacklist::contains);
|
||||||
|
calcFailed = false; // 😎
|
||||||
|
}
|
||||||
if (calcFailed) {
|
if (calcFailed) {
|
||||||
logDirect("Unable to find any path to " + mining + ", canceling Mine");
|
logDirect("Unable to find any path to " + mining + ", canceling Mine");
|
||||||
cancel();
|
cancel();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.value;
|
||||||
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
|
||||||
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
|
List<BlockPos> curr = new ArrayList<>(knownOreLocations);
|
||||||
CalculationContext context = new CalculationContext(baritone, true);
|
CalculationContext context = new CalculationContext(baritone, true);
|
||||||
Baritone.getExecutor().execute(() -> rescan(curr, context));
|
Baritone.getExecutor().execute(() -> rescan(curr, context));
|
||||||
}
|
}
|
||||||
if (Baritone.settings().legitMine.get()) {
|
if (Baritone.settings().legitMine.value) {
|
||||||
addNearby();
|
addNearby();
|
||||||
}
|
}
|
||||||
Goal goal = updateGoal();
|
PathingCommand command = updateGoal();
|
||||||
if (goal == null) {
|
if (command == null) {
|
||||||
// none in range
|
// none in range
|
||||||
// maybe say something in chat? (ahem impact)
|
// maybe say something in chat? (ahem impact)
|
||||||
cancel();
|
cancel();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new PathingCommand(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,25 +117,26 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String displayName() {
|
public String displayName0() {
|
||||||
return "Mine " + mining;
|
return "Mine " + mining;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Goal updateGoal() {
|
private PathingCommand updateGoal() {
|
||||||
|
boolean legit = Baritone.settings().legitMine.value;
|
||||||
List<BlockPos> locs = knownOreLocations;
|
List<BlockPos> locs = knownOreLocations;
|
||||||
if (!locs.isEmpty()) {
|
if (!locs.isEmpty()) {
|
||||||
List<BlockPos> locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT);
|
List<BlockPos> locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT, blacklist);
|
||||||
// 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
|
// 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
|
||||||
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new));
|
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new));
|
||||||
knownOreLocations = locs2;
|
knownOreLocations = locs2;
|
||||||
return goal;
|
return new PathingCommand(goal, legit ? PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
||||||
}
|
}
|
||||||
// we don't know any ore locations at the moment
|
// we don't know any ore locations at the moment
|
||||||
if (!Baritone.settings().legitMine.get()) {
|
if (!legit) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// only in non-Xray mode (aka legit mode) do we do this
|
// only in non-Xray mode (aka legit mode) do we do this
|
||||||
int y = Baritone.settings().legitMineYLevel.get();
|
int y = Baritone.settings().legitMineYLevel.value;
|
||||||
if (branchPoint == null) {
|
if (branchPoint == null) {
|
||||||
/*if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
|
/*if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
|
||||||
// cool, path is over and we are at desired y
|
// cool, path is over and we are at desired y
|
||||||
@@ -149,20 +157,20 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return branchPointRunaway;
|
return new PathingCommand(branchPointRunaway, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rescan(List<BlockPos> already, CalculationContext context) {
|
private void rescan(List<BlockPos> already, CalculationContext context) {
|
||||||
if (mining == null) {
|
if (mining == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Baritone.settings().legitMine.get()) {
|
if (Baritone.settings().legitMine.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<BlockPos> locs = searchWorld(context, mining, ORE_LOCATIONS_COUNT, already);
|
List<BlockPos> locs = searchWorld(context, mining, ORE_LOCATIONS_COUNT, already, blacklist);
|
||||||
locs.addAll(droppedItemsScan(mining, ctx.world()));
|
locs.addAll(droppedItemsScan(mining, ctx.world()));
|
||||||
if (locs.isEmpty()) {
|
if (locs.isEmpty()) {
|
||||||
logDebug("No locations for " + mining + " known, cancelling");
|
logDirect("No locations for " + mining + " known, cancelling");
|
||||||
cancel();
|
cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -170,18 +178,18 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Goal coalesce(IPlayerContext ctx, BlockPos loc, List<BlockPos> locs) {
|
private static Goal coalesce(IPlayerContext ctx, BlockPos loc, List<BlockPos> locs) {
|
||||||
if (!Baritone.settings().forceInternalMining.get()) {
|
if (!Baritone.settings().forceInternalMining.value) {
|
||||||
return new GoalTwoBlocks(loc);
|
return new GoalTwoBlocks(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of)
|
// Here, BlockStateInterface is used because the position may be in a cached chunk (the targeted block is one that is kept track of)
|
||||||
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(ctx, loc.up()) == Blocks.AIR);
|
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.up()) == Blocks.AIR);
|
||||||
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(ctx, loc.down()) == Blocks.AIR);
|
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.value && BlockStateInterface.getBlock(ctx, loc.down()) == Blocks.AIR);
|
||||||
return upwardGoal == downwardGoal ? new GoalTwoBlocks(loc) : upwardGoal ? new GoalBlock(loc) : new GoalBlock(loc.down());
|
return upwardGoal == downwardGoal ? new GoalTwoBlocks(loc) : upwardGoal ? new GoalBlock(loc) : new GoalBlock(loc.down());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
|
public static List<BlockPos> droppedItemsScan(List<Block> mining, World world) {
|
||||||
if (!Baritone.settings().mineScanDroppedItems.get()) {
|
if (!Baritone.settings().mineScanDroppedItems.value) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
Set<Item> searchingFor = new HashSet<>();
|
Set<Item> searchingFor = new HashSet<>();
|
||||||
@@ -203,31 +211,33 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<BlockPos> searchWorld(CalculationContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown) {
|
public static List<BlockPos> searchWorld(CalculationContext ctx, List<Block> mining, int max, List<BlockPos> alreadyKnown, List<BlockPos> blacklist) {
|
||||||
List<BlockPos> locs = new ArrayList<>();
|
List<BlockPos> locs = new ArrayList<>();
|
||||||
List<Block> uninteresting = new ArrayList<>();
|
List<Block> uninteresting = new ArrayList<>();
|
||||||
//long b = System.currentTimeMillis();
|
//long b = System.currentTimeMillis();
|
||||||
for (Block m : mining) {
|
for (Block m : mining) {
|
||||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
||||||
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
|
// maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that
|
||||||
|
locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), Baritone.settings().maxCachedWorldScanCount.value, ctx.getBaritone().getPlayerContext().playerFeet().getX(), ctx.getBaritone().getPlayerContext().playerFeet().getZ(), 2));
|
||||||
} else {
|
} else {
|
||||||
uninteresting.add(m);
|
uninteresting.add(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
locs = prune(ctx, locs, mining, max, blacklist);
|
||||||
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
|
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
|
||||||
if (locs.isEmpty()) {
|
if (locs.isEmpty()) {
|
||||||
uninteresting = mining;
|
uninteresting = mining;
|
||||||
}
|
}
|
||||||
if (!uninteresting.isEmpty()) {
|
if (!uninteresting.isEmpty()) {
|
||||||
//long before = System.currentTimeMillis();
|
//long before = System.currentTimeMillis();
|
||||||
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 26));
|
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(ctx.getBaritone().getPlayerContext(), uninteresting, max, 10, 32)); // maxSearchRadius is NOT sq
|
||||||
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
||||||
}
|
}
|
||||||
locs.addAll(alreadyKnown);
|
locs.addAll(alreadyKnown);
|
||||||
return prune(ctx, locs, mining, max);
|
return prune(ctx, locs, mining, max, blacklist);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNearby() {
|
private void addNearby() {
|
||||||
knownOreLocations.addAll(droppedItemsScan(mining, ctx.world()));
|
knownOreLocations.addAll(droppedItemsScan(mining, ctx.world()));
|
||||||
BlockPos playerFeet = ctx.playerFeet();
|
BlockPos playerFeet = ctx.playerFeet();
|
||||||
BlockStateInterface bsi = new BlockStateInterface(ctx);
|
BlockStateInterface bsi = new BlockStateInterface(ctx);
|
||||||
@@ -238,28 +248,40 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
|
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
|
||||||
// crucial to only add blocks we can see because otherwise this
|
// crucial to only add blocks we can see because otherwise this
|
||||||
// is an x-ray and it'll get caught
|
// is an x-ray and it'll get caught
|
||||||
if (mining.contains(bsi.get0(x, y, z).getBlock()) && RotationUtils.reachable(ctx.player(), new BlockPos(x, y, z), fakedBlockReachDistance).isPresent()) {
|
if (mining.contains(bsi.get0(x, y, z).getBlock())) {
|
||||||
knownOreLocations.add(new BlockPos(x, y, z));
|
BlockPos pos = new BlockPos(x, y, z);
|
||||||
|
if ((Baritone.settings().legitMineIncludeDiagonals.value && knownOreLocations.stream().anyMatch(ore -> ore.distanceSq(pos) <= 2 /* sq means this is pytha dist <= sqrt(2) */)) || RotationUtils.reachable(ctx.player(), pos, fakedBlockReachDistance).isPresent()) {
|
||||||
|
knownOreLocations.add(pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, mining, ORE_LOCATIONS_COUNT);
|
knownOreLocations = prune(new CalculationContext(baritone), knownOreLocations, mining, ORE_LOCATIONS_COUNT, blacklist);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, List<Block> mining, int max) {
|
private static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, List<Block> mining, int max, List<BlockPos> blacklist) {
|
||||||
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world);
|
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world);
|
||||||
|
dropped.removeIf(drop -> {
|
||||||
|
for (BlockPos pos : locs2) {
|
||||||
|
if (pos.distanceSq(drop) <= 9 && mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) && MineProcess.plausibleToBreak(ctx.bsi, pos)) { // TODO maybe drop also has to be supported? no lava below?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
List<BlockPos> locs = locs2
|
List<BlockPos> locs = locs2
|
||||||
.stream()
|
.stream()
|
||||||
.distinct()
|
.distinct()
|
||||||
|
|
||||||
// remove any that are within loaded chunks that aren't actually what we want
|
// remove any that are within loaded chunks that aren't actually what we want
|
||||||
|
|
||||||
.filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
|
.filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
|
||||||
|
|
||||||
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
||||||
.filter(pos -> MineProcess.plausibleToBreak(ctx.bsi, pos))
|
.filter(pos -> MineProcess.plausibleToBreak(ctx.bsi, pos))
|
||||||
|
|
||||||
|
.filter(pos -> !blacklist.contains(pos))
|
||||||
|
|
||||||
.sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq))
|
.sorted(Comparator.comparingDouble(ctx.getBaritone().getPlayerContext().playerFeet()::distanceSq))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
@@ -288,6 +310,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
|
|||||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
|
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
|
||||||
this.desiredQuantity = quantity;
|
this.desiredQuantity = quantity;
|
||||||
this.knownOreLocations = new ArrayList<>();
|
this.knownOreLocations = new ArrayList<>();
|
||||||
|
this.blacklist = new ArrayList<>();
|
||||||
this.branchPoint = null;
|
this.branchPoint = null;
|
||||||
this.branchPointRunaway = null;
|
this.branchPointRunaway = null;
|
||||||
if (mining != null) {
|
if (mining != null) {
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup Baritone's pathing goal and (if needed) begin pathing
|
// Setup Baritone's pathing goal and (if needed) begin pathing
|
||||||
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(GOAL);
|
if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(GOAL);
|
||||||
|
}
|
||||||
|
|
||||||
// If we have reached our goal, print a message and safely close the game
|
// If we have reached our goal, print a message and safely close the game
|
||||||
if (GOAL.isInGoal(ctx.playerFeet())) {
|
if (GOAL.isInGoal(ctx.playerFeet())) {
|
||||||
|
|||||||
@@ -25,27 +25,15 @@ public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper
|
|||||||
|
|
||||||
protected final Baritone baritone;
|
protected final Baritone baritone;
|
||||||
protected final IPlayerContext ctx;
|
protected final IPlayerContext ctx;
|
||||||
private final double priority;
|
|
||||||
|
|
||||||
public BaritoneProcessHelper(Baritone baritone, double priority) {
|
public BaritoneProcessHelper(Baritone baritone) {
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
this.ctx = baritone.getPlayerContext();
|
this.ctx = baritone.getPlayerContext();
|
||||||
this.priority = priority;
|
|
||||||
baritone.getPathingControlManager().registerProcess(this);
|
baritone.getPathingControlManager().registerProcess(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Baritone associatedWith() {
|
|
||||||
return baritone;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTemporary() {
|
public boolean isTemporary() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public double priority() {
|
|
||||||
return priority;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public final class BlockBreakHelper implements Helper {
|
|||||||
|
|
||||||
private boolean didBreakLastTick;
|
private boolean didBreakLastTick;
|
||||||
|
|
||||||
private IPlayerContext playerContext;
|
private final IPlayerContext playerContext;
|
||||||
|
|
||||||
public BlockBreakHelper(IPlayerContext playerContext) {
|
public BlockBreakHelper(IPlayerContext playerContext) {
|
||||||
this.playerContext = playerContext;
|
this.playerContext = playerContext;
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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.Baritone;
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
import net.minecraft.util.EnumActionResult;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
|
||||||
|
public class BlockPlaceHelper implements Helper {
|
||||||
|
private final IPlayerContext ctx;
|
||||||
|
private int rightClickTimer;
|
||||||
|
|
||||||
|
public BlockPlaceHelper(IPlayerContext playerContext) {
|
||||||
|
this.ctx = playerContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick(boolean rightClickRequested) {
|
||||||
|
if (rightClickTimer > 0) {
|
||||||
|
rightClickTimer--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RayTraceResult mouseOver = ctx.objectMouseOver();
|
||||||
|
if (!rightClickRequested || ctx.player().isRowingBoat() || mouseOver == null || mouseOver.getBlockPos() == null || mouseOver.typeOfHit != RayTraceResult.Type.BLOCK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rightClickTimer = Baritone.settings().rightClickSpeed.value;
|
||||||
|
for (EnumHand hand : EnumHand.values()) {
|
||||||
|
if (ctx.playerController().processRightClickBlock(ctx.player(), ctx.world(), mouseOver.getBlockPos(), mouseOver.sideHit, mouseOver.hitVec, hand) == EnumActionResult.SUCCESS) {
|
||||||
|
ctx.player().swingArm(hand);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,7 +66,7 @@ public class BlockStateInterface {
|
|||||||
} else {
|
} else {
|
||||||
this.loadedChunks = worldLoaded; // this will only be used on the main thread
|
this.loadedChunks = worldLoaded; // this will only be used on the main thread
|
||||||
}
|
}
|
||||||
this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.get();
|
this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.value;
|
||||||
if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
|
if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import baritone.api.cache.IWaypoint;
|
|||||||
import baritone.api.event.events.ChatEvent;
|
import baritone.api.event.events.ChatEvent;
|
||||||
import baritone.api.pathing.goals.*;
|
import baritone.api.pathing.goals.*;
|
||||||
import baritone.api.pathing.movement.ActionCosts;
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
|
import baritone.api.process.IBaritoneProcess;
|
||||||
|
import baritone.api.utils.BetterBlockPos;
|
||||||
import baritone.api.utils.SettingsUtil;
|
import baritone.api.utils.SettingsUtil;
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
import baritone.behavior.PathingBehavior;
|
import baritone.behavior.PathingBehavior;
|
||||||
@@ -35,6 +37,7 @@ import baritone.pathing.movement.Moves;
|
|||||||
import baritone.process.CustomGoalProcess;
|
import baritone.process.CustomGoalProcess;
|
||||||
import baritone.utils.pathing.SegmentedCalculator;
|
import baritone.utils.pathing.SegmentedCalculator;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@@ -75,7 +78,10 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
"sethome - Sets \"home\"\n" +
|
"sethome - Sets \"home\"\n" +
|
||||||
"home - Paths towards \"home\" \n" +
|
"home - Paths towards \"home\" \n" +
|
||||||
"costs - (debug) all movement costs from current location\n" +
|
"costs - (debug) all movement costs from current location\n" +
|
||||||
"damn - Daniel ";
|
"damn - Daniel\n" +
|
||||||
|
"Go to https://github.com/cabaletta/baritone/blob/master/USAGE.md for more information";
|
||||||
|
|
||||||
|
private static final String COMMAND_PREFIX = "#";
|
||||||
|
|
||||||
public ExampleBaritoneControl(Baritone baritone) {
|
public ExampleBaritoneControl(Baritone baritone) {
|
||||||
super(baritone);
|
super(baritone);
|
||||||
@@ -83,22 +89,23 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendChatMessage(ChatEvent event) {
|
public void onSendChatMessage(ChatEvent event) {
|
||||||
if (!Baritone.settings().chatControl.get() && !Baritone.settings().removePrefix.get()) {
|
String msg = event.getMessage();
|
||||||
|
if (Baritone.settings().prefixControl.value && msg.startsWith(COMMAND_PREFIX)) {
|
||||||
|
if (!runCommand(msg.substring(COMMAND_PREFIX.length()))) {
|
||||||
|
logDirect("Invalid command");
|
||||||
|
}
|
||||||
|
event.cancel(); // always cancel if using prefixControl
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String msg = event.getMessage();
|
if (!Baritone.settings().chatControl.value && !Baritone.settings().removePrefix.value) {
|
||||||
if (Baritone.settings().prefix.get()) {
|
return;
|
||||||
if (!msg.startsWith("#")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
msg = msg.substring(1);
|
|
||||||
}
|
}
|
||||||
if (runCommand(msg)) {
|
if (runCommand(msg)) {
|
||||||
event.cancel();
|
event.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runCommand(String msg0) {
|
public boolean runCommand(String msg0) { // you may think this can be private, but impcat calls it from .b =)
|
||||||
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
|
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
|
||||||
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
||||||
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
|
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
|
||||||
@@ -111,44 +118,58 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg.equals("baritone") || msg.equals("settings")) {
|
if (msg.equals("baritone") || msg.equals("modifiedsettings") || msg.startsWith("settings m") || msg.equals("modified")) {
|
||||||
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
|
logDirect("All settings that have been modified from their default values:");
|
||||||
|
for (Settings.Setting<?> setting : SettingsUtil.modifiedSettings(Baritone.settings())) {
|
||||||
logDirect(setting.toString());
|
logDirect(setting.toString());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.startsWith("settings")) {
|
||||||
|
String rest = msg.substring("settings".length());
|
||||||
|
try {
|
||||||
|
int page = Integer.parseInt(rest.trim());
|
||||||
|
int min = page * 10;
|
||||||
|
int max = Math.min(Baritone.settings().allSettings.size(), (page + 1) * 10);
|
||||||
|
logDirect("Settings " + min + " to " + (max - 1) + ":");
|
||||||
|
for (int i = min; i < max; i++) {
|
||||||
|
logDirect(Baritone.settings().allSettings.get(i).toString());
|
||||||
|
}
|
||||||
|
} catch (Exception ex) { // NumberFormatException | ArrayIndexOutOfBoundsException and probably some others I'm forgetting lol
|
||||||
|
ex.printStackTrace();
|
||||||
|
logDirect("All settings:");
|
||||||
|
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
|
||||||
|
logDirect(setting.toString());
|
||||||
|
}
|
||||||
|
logDirect("To get one page of ten settings at a time, do settings <num>");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
|
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
|
||||||
for (String line : HELP_MSG.split("\n")) {
|
for (String line : HELP_MSG.split("\n")) {
|
||||||
logDirect(line);
|
logDirect(line);
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.contains(" ")) {
|
if (msg.contains(" ")) {
|
||||||
String[] data = msg.split(" ");
|
String settingName = msg.substring(0, msg.indexOf(' '));
|
||||||
if (data.length == 2) {
|
String settingValue = msg.substring(msg.indexOf(' ') + 1);
|
||||||
Settings.Setting setting = Baritone.settings().byLowerName.get(data[0]);
|
Settings.Setting setting = Baritone.settings().byLowerName.get(settingName);
|
||||||
if (setting != null) {
|
if (setting != null) {
|
||||||
|
if (settingValue.equals("reset")) {
|
||||||
|
logDirect("Resetting setting " + settingName + " to default value.");
|
||||||
|
setting.reset();
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
if (setting.value.getClass() == Long.class) {
|
SettingsUtil.parseAndApply(Baritone.settings(), settingName, settingValue);
|
||||||
setting.value = Long.parseLong(data[1]);
|
} catch (Exception ex) {
|
||||||
}
|
logDirect("Unable to parse setting");
|
||||||
if (setting.value.getClass() == Integer.class) {
|
|
||||||
setting.value = Integer.parseInt(data[1]);
|
|
||||||
}
|
|
||||||
if (setting.value.getClass() == Double.class) {
|
|
||||||
setting.value = Double.parseDouble(data[1]);
|
|
||||||
}
|
|
||||||
if (setting.value.getClass() == Float.class) {
|
|
||||||
setting.value = Float.parseFloat(data[1]);
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
logDirect("Unable to parse " + data[1]);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
SettingsUtil.save(Baritone.settings());
|
|
||||||
logDirect(setting.toString());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
SettingsUtil.save(Baritone.settings());
|
||||||
|
logDirect(setting.toString());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Baritone.settings().byLowerName.containsKey(msg)) {
|
if (Baritone.settings().byLowerName.containsKey(msg)) {
|
||||||
@@ -158,36 +179,19 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg.startsWith("goal")) {
|
if (msg.startsWith("goal")) {
|
||||||
String[] params = msg.substring(4).trim().split(" ");
|
String rest = msg.substring(4).trim();
|
||||||
if (params[0].equals("")) {
|
|
||||||
params = new String[]{};
|
|
||||||
}
|
|
||||||
Goal goal;
|
Goal goal;
|
||||||
try {
|
if (rest.equals("clear") || rest.equals("none")) {
|
||||||
switch (params.length) {
|
goal = null;
|
||||||
case 0:
|
} else {
|
||||||
goal = new GoalBlock(ctx.playerFeet());
|
String[] params = rest.split(" ");
|
||||||
break;
|
if (params[0].equals("")) {
|
||||||
case 1:
|
params = new String[]{};
|
||||||
if (params[0].equals("clear") || params[0].equals("none")) {
|
}
|
||||||
goal = null;
|
goal = parseGoal(params);
|
||||||
} else {
|
if (goal == null) {
|
||||||
goal = new GoalYLevel(Integer.parseInt(params[0]));
|
return true;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
goal = new GoalXZ(Integer.parseInt(params[0]), Integer.parseInt(params[1]));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
goal = new GoalBlock(new BlockPos(Integer.parseInt(params[0]), Integer.parseInt(params[1]), Integer.parseInt(params[2])));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
logDirect("unable to understand lol");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
logDirect("unable to parse integer " + ex);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
customGoalProcess.setGoal(goal);
|
customGoalProcess.setGoal(goal);
|
||||||
logDirect("Goal: " + goal);
|
logDirect("Goal: " + goal);
|
||||||
@@ -222,6 +226,29 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.equals("proc")) {
|
||||||
|
Optional<IBaritoneProcess> proc = baritone.getPathingControlManager().mostRecentInControl();
|
||||||
|
if (!proc.isPresent()) {
|
||||||
|
logDirect("No process is in control");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
IBaritoneProcess p = proc.get();
|
||||||
|
logDirect("Class: " + p.getClass());
|
||||||
|
logDirect("Priority: " + p.priority());
|
||||||
|
logDirect("Temporary: " + p.isTemporary());
|
||||||
|
logDirect("Display name: " + p.displayName());
|
||||||
|
logDirect("Command: " + baritone.getPathingControlManager().mostRecentCommand());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (msg.equals("version")) {
|
||||||
|
String version = ExampleBaritoneControl.class.getPackage().getImplementationVersion();
|
||||||
|
if (version == null) {
|
||||||
|
logDirect("No version detected. Either dev environment or broken install.");
|
||||||
|
} else {
|
||||||
|
logDirect("You are using Baritone v" + version);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (msg.equals("repack") || msg.equals("rescan")) {
|
if (msg.equals("repack") || msg.equals("rescan")) {
|
||||||
ChunkProviderClient cli = (ChunkProviderClient) ctx.world().getChunkProvider();
|
ChunkProviderClient cli = (ChunkProviderClient) ctx.world().getChunkProvider();
|
||||||
int playerChunkX = ctx.playerFeet().getX() >> 4;
|
int playerChunkX = ctx.playerFeet().getX() >> 4;
|
||||||
@@ -239,7 +266,28 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("Queued " + count + " chunks for repacking");
|
logDirect("Queued " + count + " chunks for repacking");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.equals("axis")) {
|
if (msg.startsWith("build")) {
|
||||||
|
String file;
|
||||||
|
BlockPos origin;
|
||||||
|
try {
|
||||||
|
String[] coords = msg.substring("build".length()).trim().split(" ");
|
||||||
|
file = coords[0] + ".schematic";
|
||||||
|
origin = new BlockPos(parseOrDefault(coords[1], ctx.playerFeet().x), parseOrDefault(coords[2], ctx.playerFeet().y), parseOrDefault(coords[3], ctx.playerFeet().z));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
file = msg.substring(5).trim() + ".schematic";
|
||||||
|
origin = ctx.playerFeet();
|
||||||
|
}
|
||||||
|
logDirect("Loading '" + file + "' to build from origin " + origin);
|
||||||
|
boolean success = baritone.getBuilderProcess().build(file, origin);
|
||||||
|
logDirect(success ? "Loaded" : "Unable to load");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (msg.equals("come")) {
|
||||||
|
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(mc.getRenderViewEntity())));
|
||||||
|
logDirect("Coming");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (msg.equals("axis") || msg.equals("highway")) {
|
||||||
customGoalProcess.setGoalAndPath(new GoalAxis());
|
customGoalProcess.setGoalAndPath(new GoalAxis());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -279,11 +327,46 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.startsWith("cleararea")) {
|
||||||
|
String suffix = msg.substring("cleararea".length());
|
||||||
|
BlockPos corner1;
|
||||||
|
BlockPos corner2;
|
||||||
|
if (suffix.isEmpty()) {
|
||||||
|
// clear the area from the current goal to here
|
||||||
|
Goal goal = baritone.getPathingBehavior().getGoal();
|
||||||
|
if (goal == null || !(goal instanceof GoalBlock)) {
|
||||||
|
logDirect("Need to specify goal of opposite corner");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
corner1 = ((GoalBlock) goal).getGoalPos();
|
||||||
|
corner2 = ctx.playerFeet();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
String[] spl = suffix.split(" ");
|
||||||
|
corner1 = ctx.playerFeet();
|
||||||
|
corner2 = new BlockPos(Integer.parseInt(spl[0]), Integer.parseInt(spl[1]), Integer.parseInt(spl[2]));
|
||||||
|
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {
|
||||||
|
logDirect("unable to parse");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
baritone.getBuilderProcess().clearArea(corner1, corner2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (msg.equals("reset")) {
|
if (msg.equals("reset")) {
|
||||||
Baritone.settings().reset();
|
for (Settings.Setting setting : Baritone.settings().allSettings) {
|
||||||
|
setting.reset();
|
||||||
|
}
|
||||||
|
SettingsUtil.save(Baritone.settings());
|
||||||
logDirect("Baritone settings reset");
|
logDirect("Baritone settings reset");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.equals("render")) {
|
||||||
|
BetterBlockPos pf = ctx.playerFeet();
|
||||||
|
Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500);
|
||||||
|
logDirect("okay");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (msg.equals("echest")) {
|
if (msg.equals("echest")) {
|
||||||
Optional<List<ItemStack>> contents = baritone.getMemoryBehavior().echest();
|
Optional<List<ItemStack>> contents = baritone.getMemoryBehavior().echest();
|
||||||
if (contents.isPresent()) {
|
if (contents.isPresent()) {
|
||||||
@@ -348,9 +431,24 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("ok");
|
logDirect("ok");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (msg.startsWith("explore")) {
|
||||||
|
String rest = msg.substring("explore".length()).trim();
|
||||||
|
int centerX;
|
||||||
|
int centerZ;
|
||||||
|
try {
|
||||||
|
centerX = Integer.parseInt(rest.split(" ")[0]);
|
||||||
|
centerZ = Integer.parseInt(rest.split(" ")[1]);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
centerX = ctx.playerFeet().x;
|
||||||
|
centerZ = ctx.playerFeet().z;
|
||||||
|
}
|
||||||
|
baritone.getExploreProcess().explore(centerX, centerZ);
|
||||||
|
logDirect("Exploring from " + centerX + "," + centerZ);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (msg.startsWith("find")) {
|
if (msg.startsWith("find")) {
|
||||||
String blockType = msg.substring(4).trim();
|
String blockType = msg.substring(4).trim();
|
||||||
LinkedList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 4);
|
ArrayList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 4);
|
||||||
logDirect("Have " + locs.size() + " locations");
|
logDirect("Have " + locs.size() + " locations");
|
||||||
for (BlockPos pos : locs) {
|
for (BlockPos pos : locs) {
|
||||||
Block actually = BlockStateInterface.get(ctx, pos).getBlock();
|
Block actually = BlockStateInterface.get(ctx, pos).getBlock();
|
||||||
@@ -381,7 +479,17 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
|
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (msg.startsWith("thisway")) {
|
if (msg.equals("click")) {
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick()));
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}).start();
|
||||||
|
logDirect("aight dude");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (msg.startsWith("thisway") || msg.startsWith("forward")) {
|
||||||
try {
|
try {
|
||||||
Goal goal = GoalXZ.fromDirection(ctx.playerFeetAsVec(), ctx.player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
|
Goal goal = GoalXZ.fromDirection(ctx.playerFeetAsVec(), ctx.player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
|
||||||
customGoalProcess.setGoal(goal);
|
customGoalProcess.setGoal(goal);
|
||||||
@@ -449,7 +557,11 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
if (block == null) {
|
if (block == null) {
|
||||||
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
|
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
|
||||||
if (waypoint == null) {
|
if (waypoint == null) {
|
||||||
logDirect("No locations for " + mining + " known, cancelling");
|
Goal goal = parseGoal(waypointType.split(" "));
|
||||||
|
if (goal != null) {
|
||||||
|
logDirect("Going to " + goal);
|
||||||
|
customGoalProcess.setGoalAndPath(goal);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -463,7 +575,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
Goal goal = waypoint.getTag() == Waypoint.Tag.BED ? new GoalGetToBlock(waypoint.getLocation()) : new GoalBlock(waypoint.getLocation());
|
||||||
customGoalProcess.setGoalAndPath(goal);
|
customGoalProcess.setGoalAndPath(goal);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -503,7 +615,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
while (moves.contains(null)) {
|
while (moves.contains(null)) {
|
||||||
moves.remove(null);
|
moves.remove(null);
|
||||||
}
|
}
|
||||||
moves.sort(Comparator.comparingDouble(Movement::getCost));
|
moves.sort(Comparator.comparingDouble(move -> move.getCost(new CalculationContext(baritone))));
|
||||||
for (Movement move : moves) {
|
for (Movement move : moves) {
|
||||||
String[] parts = move.getClass().toString().split("\\.");
|
String[] parts = move.getClass().toString().split("\\.");
|
||||||
double cost = move.getCost();
|
double cost = move.getCost();
|
||||||
@@ -521,6 +633,10 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int parseOrDefault(String str, int i) {
|
||||||
|
return str.equals("~") ? i : str.startsWith("~") ? Integer.parseInt(str.substring(1)) + i : Integer.parseInt(str);
|
||||||
|
}
|
||||||
|
|
||||||
private void log(List<ItemStack> stacks) {
|
private void log(List<ItemStack> stacks) {
|
||||||
for (ItemStack stack : stacks) {
|
for (ItemStack stack : stacks) {
|
||||||
if (!stack.isEmpty()) {
|
if (!stack.isEmpty()) {
|
||||||
@@ -528,4 +644,31 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Goal parseGoal(String[] params) {
|
||||||
|
Goal goal;
|
||||||
|
try {
|
||||||
|
switch (params.length) {
|
||||||
|
case 0:
|
||||||
|
goal = new GoalBlock(ctx.playerFeet());
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
goal = new GoalYLevel(Integer.parseInt(params[0]));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
goal = new GoalXZ(Integer.parseInt(params[0]), Integer.parseInt(params[1]));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
goal = new GoalBlock(new BlockPos(Integer.parseInt(params[0]), Integer.parseInt(params[1]), Integer.parseInt(params[2])));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logDirect("unable to understand lol");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
logDirect("unable to parse integer " + ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return goal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* 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.Baritone;
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.pathing.goals.GoalBlock;
|
||||||
|
import baritone.api.pathing.goals.GoalTwoBlocks;
|
||||||
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
import org.lwjgl.input.Mouse;
|
||||||
|
import org.lwjgl.util.glu.GLU;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
|
|
||||||
|
public class GuiClick extends GuiScreen {
|
||||||
|
|
||||||
|
// My name is Brady and I grant leijurv permission to use this pasted code
|
||||||
|
private final FloatBuffer MODELVIEW = BufferUtils.createFloatBuffer(16);
|
||||||
|
private final FloatBuffer PROJECTION = BufferUtils.createFloatBuffer(16);
|
||||||
|
private final IntBuffer VIEWPORT = BufferUtils.createIntBuffer(16);
|
||||||
|
private final FloatBuffer TO_WORLD_BUFFER = BufferUtils.createFloatBuffer(3);
|
||||||
|
|
||||||
|
private BlockPos clickStart;
|
||||||
|
private BlockPos currentMouseOver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesGuiPauseGame() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||||
|
int mx = Mouse.getX();
|
||||||
|
int my = Mouse.getY();
|
||||||
|
Vec3d near = toWorld(mx, my, 0);
|
||||||
|
Vec3d far = toWorld(mx, my, 1); // "Use 0.945 that's what stack overflow says" - leijurv
|
||||||
|
if (near != null && far != null) {
|
||||||
|
Vec3d viewerPos = new Vec3d(mc.getRenderManager().viewerPosX, mc.getRenderManager().viewerPosY, mc.getRenderManager().viewerPosZ);
|
||||||
|
RayTraceResult result = mc.world.rayTraceBlocks(near.add(viewerPos), far.add(viewerPos), false, false, true);
|
||||||
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
|
currentMouseOver = result.getBlockPos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mouseReleased(int mouseX, int mouseY, int mouseButton) {
|
||||||
|
if (mouseButton == 0) {
|
||||||
|
if (clickStart != null && !clickStart.equals(currentMouseOver)) {
|
||||||
|
((Baritone) BaritoneAPI.getProvider().getPrimaryBaritone()).getBuilderProcess().clearArea(clickStart, currentMouseOver);
|
||||||
|
clickStart = null;
|
||||||
|
} else {
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalTwoBlocks(currentMouseOver));
|
||||||
|
}
|
||||||
|
} else if (mouseButton == 1) {
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(currentMouseOver.up()));
|
||||||
|
}
|
||||||
|
clickStart = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
|
||||||
|
clickStart = currentMouseOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRender() {
|
||||||
|
GlStateManager.getFloat(GL_MODELVIEW_MATRIX, (FloatBuffer) MODELVIEW.clear());
|
||||||
|
GlStateManager.getFloat(GL_PROJECTION_MATRIX, (FloatBuffer) PROJECTION.clear());
|
||||||
|
GlStateManager.glGetInteger(GL_VIEWPORT, (IntBuffer) VIEWPORT.clear());
|
||||||
|
|
||||||
|
if (currentMouseOver != null) {
|
||||||
|
Entity e = mc.getRenderViewEntity();
|
||||||
|
// drawSingleSelectionBox WHEN?
|
||||||
|
PathRenderer.drawManySelectionBoxes(e, Collections.singletonList(currentMouseOver), Color.CYAN);
|
||||||
|
if (clickStart != null && !clickStart.equals(currentMouseOver)) {
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
|
||||||
|
GlStateManager.color(Color.RED.getColorComponents(null)[0], Color.RED.getColorComponents(null)[1], Color.RED.getColorComponents(null)[2], 0.4F);
|
||||||
|
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
|
||||||
|
GlStateManager.disableTexture2D();
|
||||||
|
GlStateManager.depthMask(false);
|
||||||
|
GlStateManager.disableDepth();
|
||||||
|
BetterBlockPos a = new BetterBlockPos(currentMouseOver);
|
||||||
|
BetterBlockPos b = new BetterBlockPos(clickStart);
|
||||||
|
PathRenderer.drawAABB(new AxisAlignedBB(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z), Math.max(a.x, b.x) + 1, Math.max(a.y, b.y) + 1, Math.max(a.z, b.z) + 1));
|
||||||
|
GlStateManager.enableDepth();
|
||||||
|
|
||||||
|
GlStateManager.depthMask(true);
|
||||||
|
GlStateManager.enableTexture2D();
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3d toWorld(double x, double y, double z) {
|
||||||
|
boolean result = GLU.gluUnProject((float) x, (float) y, (float) z, MODELVIEW, PROJECTION, VIEWPORT, (FloatBuffer) TO_WORLD_BUFFER.clear());
|
||||||
|
if (result) {
|
||||||
|
return new Vec3d(TO_WORLD_BUFFER.get(0), TO_WORLD_BUFFER.get(1), TO_WORLD_BUFFER.get(2));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,7 +50,7 @@ public interface Helper {
|
|||||||
* @param message The message to display in chat
|
* @param message The message to display in chat
|
||||||
*/
|
*/
|
||||||
default void logDebug(String message) {
|
default void logDebug(String message) {
|
||||||
if (!Baritone.settings().chatDebug.get()) {
|
if (!Baritone.settings().chatDebug.value) {
|
||||||
//System.out.println("Suppressed debug message:");
|
//System.out.println("Suppressed debug message:");
|
||||||
//System.out.println(message);
|
//System.out.println(message);
|
||||||
return;
|
return;
|
||||||
@@ -67,6 +67,6 @@ public interface Helper {
|
|||||||
ITextComponent component = MESSAGE_PREFIX.createCopy();
|
ITextComponent component = MESSAGE_PREFIX.createCopy();
|
||||||
component.getStyle().setColor(TextFormatting.GRAY);
|
component.getStyle().setColor(TextFormatting.GRAY);
|
||||||
component.appendSibling(new TextComponentString(" " + message));
|
component.appendSibling(new TextComponentString(" " + message));
|
||||||
Minecraft.getMinecraft().addScheduledTask(() -> Baritone.settings().logger.get().accept(component));
|
Minecraft.getMinecraft().addScheduledTask(() -> Baritone.settings().logger.value.accept(component));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ import baritone.api.utils.IInputOverrideHandler;
|
|||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.behavior.Behavior;
|
import baritone.behavior.Behavior;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
import net.minecraft.util.MovementInput;
|
|
||||||
import net.minecraft.util.MovementInputFromOptions;
|
import net.minecraft.util.MovementInputFromOptions;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -47,31 +45,12 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
|
|||||||
private final Map<Input, Boolean> inputForceStateMap = new HashMap<>();
|
private final Map<Input, Boolean> inputForceStateMap = new HashMap<>();
|
||||||
|
|
||||||
private final BlockBreakHelper blockBreakHelper;
|
private final BlockBreakHelper blockBreakHelper;
|
||||||
|
private final BlockPlaceHelper blockPlaceHelper;
|
||||||
|
|
||||||
public InputOverrideHandler(Baritone baritone) {
|
public InputOverrideHandler(Baritone baritone) {
|
||||||
super(baritone);
|
super(baritone);
|
||||||
this.blockBreakHelper = new BlockBreakHelper(baritone.getPlayerContext());
|
this.blockBreakHelper = new BlockBreakHelper(baritone.getPlayerContext());
|
||||||
}
|
this.blockPlaceHelper = new BlockPlaceHelper(baritone.getPlayerContext());
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not we are forcing down the specified {@link KeyBinding}.
|
|
||||||
*
|
|
||||||
* @param key The KeyBinding object
|
|
||||||
* @return Whether or not it is being forced down
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final Boolean isInputForcedDown(KeyBinding key) {
|
|
||||||
Input input = Input.getInputForBind(key);
|
|
||||||
if (input == null || !inControl()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (input == Input.CLICK_LEFT) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (input == Input.CLICK_RIGHT) {
|
|
||||||
return isInputForcedDown(Input.CLICK_RIGHT);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,19 +88,27 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
|
|||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
|
if (isInputForcedDown(Input.CLICK_LEFT)) {
|
||||||
|
setInputForceState(Input.CLICK_RIGHT, false);
|
||||||
MovementInput desired = inControl()
|
|
||||||
? new PlayerMovementInput(this)
|
|
||||||
: new MovementInputFromOptions(Minecraft.getMinecraft().gameSettings);
|
|
||||||
|
|
||||||
if (ctx.player().movementInput.getClass() != desired.getClass()) {
|
|
||||||
ctx.player().movementInput = desired; // only set it if it was previously incorrect
|
|
||||||
// gotta do it this way, or else it constantly thinks you're beginning a double tap W sprint lol
|
|
||||||
}
|
}
|
||||||
|
blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
|
||||||
|
blockPlaceHelper.tick(isInputForcedDown(Input.CLICK_RIGHT));
|
||||||
|
|
||||||
|
if (inControl()) {
|
||||||
|
if (ctx.player().movementInput.getClass() != PlayerMovementInput.class) {
|
||||||
|
ctx.player().movementInput = new PlayerMovementInput(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ctx.player().movementInput.getClass() == PlayerMovementInput.class) { // allow other movement inputs that aren't this one, e.g. for a freecam
|
||||||
|
ctx.player().movementInput = new MovementInputFromOptions(Minecraft.getMinecraft().gameSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// only set it if it was previously incorrect
|
||||||
|
// gotta do it this way, or else it constantly thinks you're beginning a double tap W sprint lol
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean inControl() {
|
private boolean inControl() {
|
||||||
|
// if we are not primary (a bot) we should set the movementinput even when idle (not pathing)
|
||||||
return baritone.getPathingBehavior().isPathing() || baritone != BaritoneAPI.getProvider().getPrimaryBaritone();
|
return baritone.getPathingBehavior().isPathing() || baritone != BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,10 +57,11 @@ public final class PathRenderer implements Helper {
|
|||||||
private PathRenderer() {}
|
private PathRenderer() {}
|
||||||
|
|
||||||
public static void render(RenderEvent event, PathingBehavior behavior) {
|
public static void render(RenderEvent event, PathingBehavior behavior) {
|
||||||
// System.out.println("Render passing");
|
|
||||||
// System.out.println(event.getPartialTicks());
|
|
||||||
float partialTicks = event.getPartialTicks();
|
float partialTicks = event.getPartialTicks();
|
||||||
Goal goal = behavior.getGoal();
|
Goal goal = behavior.getGoal();
|
||||||
|
if (mc.currentScreen instanceof GuiClick) {
|
||||||
|
((GuiClick) mc.currentScreen).onRender();
|
||||||
|
}
|
||||||
|
|
||||||
int thisPlayerDimension = behavior.baritone.getPlayerContext().world().provider.getDimensionType().getId();
|
int thisPlayerDimension = behavior.baritone.getPlayerContext().world().provider.getDimensionType().getId();
|
||||||
int currentRenderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId();
|
int currentRenderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId();
|
||||||
@@ -80,9 +81,9 @@ public final class PathRenderer implements Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (goal != null && Baritone.settings().renderGoal.value) {
|
if (goal != null && Baritone.settings().renderGoal.value) {
|
||||||
drawLitDankGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.get());
|
drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.value);
|
||||||
}
|
}
|
||||||
if (!Baritone.settings().renderPath.get()) {
|
if (!Baritone.settings().renderPath.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,28 +97,28 @@ public final class PathRenderer implements Helper {
|
|||||||
// Render the current path, if there is one
|
// Render the current path, if there is one
|
||||||
if (current != null && current.getPath() != null) {
|
if (current != null && current.getPath() != null) {
|
||||||
int renderBegin = Math.max(current.getPosition() - 3, 0);
|
int renderBegin = Math.max(current.getPosition() - 3, 0);
|
||||||
drawPath(current.getPath(), renderBegin, renderView, partialTicks, Baritone.settings().colorCurrentPath.get(), Baritone.settings().fadePath.get(), 10, 20);
|
drawPath(current.getPath(), renderBegin, renderView, partialTicks, Baritone.settings().colorCurrentPath.value, Baritone.settings().fadePath.value, 10, 20);
|
||||||
}
|
}
|
||||||
if (next != null && next.getPath() != null) {
|
if (next != null && next.getPath() != null) {
|
||||||
drawPath(next.getPath(), 0, renderView, partialTicks, Baritone.settings().colorNextPath.get(), Baritone.settings().fadePath.get(), 10, 20);
|
drawPath(next.getPath(), 0, renderView, partialTicks, Baritone.settings().colorNextPath.value, Baritone.settings().fadePath.value, 10, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
//long split = System.nanoTime();
|
//long split = System.nanoTime();
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
drawManySelectionBoxes(renderView, current.toBreak(), partialTicks, Baritone.settings().colorBlocksToBreak.get());
|
drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.value);
|
||||||
drawManySelectionBoxes(renderView, current.toPlace(), partialTicks, Baritone.settings().colorBlocksToPlace.get());
|
drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.value);
|
||||||
drawManySelectionBoxes(renderView, current.toWalkInto(), partialTicks, Baritone.settings().colorBlocksToWalkInto.get());
|
drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a path calculation currently running, render the path calculation process
|
// If there is a path calculation currently running, render the path calculation process
|
||||||
behavior.getInProgress().ifPresent(currentlyRunning -> {
|
behavior.getInProgress().ifPresent(currentlyRunning -> {
|
||||||
currentlyRunning.bestPathSoFar().ifPresent(p -> {
|
currentlyRunning.bestPathSoFar().ifPresent(p -> {
|
||||||
drawPath(p, 0, renderView, partialTicks, Baritone.settings().colorBestPathSoFar.get(), Baritone.settings().fadePath.get(), 10, 20);
|
drawPath(p, 0, renderView, partialTicks, Baritone.settings().colorBestPathSoFar.value, Baritone.settings().fadePath.value, 10, 20);
|
||||||
});
|
});
|
||||||
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
|
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
|
||||||
|
|
||||||
drawPath(mr, 0, renderView, partialTicks, Baritone.settings().colorMostRecentConsidered.get(), Baritone.settings().fadePath.get(), 10, 20);
|
drawPath(mr, 0, renderView, partialTicks, Baritone.settings().colorMostRecentConsidered.value, Baritone.settings().fadePath.value, 10, 20);
|
||||||
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), partialTicks, Baritone.settings().colorMostRecentConsidered.get());
|
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), Baritone.settings().colorMostRecentConsidered.value);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
//long end = System.nanoTime();
|
//long end = System.nanoTime();
|
||||||
@@ -131,10 +132,10 @@ public final class PathRenderer implements Helper {
|
|||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||||
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
|
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
|
||||||
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.get());
|
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
|
||||||
GlStateManager.disableTexture2D();
|
GlStateManager.disableTexture2D();
|
||||||
GlStateManager.depthMask(false);
|
GlStateManager.depthMask(false);
|
||||||
if (Baritone.settings().renderPathIgnoreDepth.get()) {
|
if (Baritone.settings().renderPathIgnoreDepth.value) {
|
||||||
GlStateManager.disableDepth();
|
GlStateManager.disableDepth();
|
||||||
}
|
}
|
||||||
List<BetterBlockPos> positions = path.positions();
|
List<BetterBlockPos> positions = path.positions();
|
||||||
@@ -174,10 +175,10 @@ public final class PathRenderer implements Helper {
|
|||||||
}
|
}
|
||||||
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], alpha);
|
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], alpha);
|
||||||
}
|
}
|
||||||
drawLine(player, x1, y1, z1, x2, y2, z2, partialTicks);
|
drawLine(player, x1, y1, z1, x2, y2, z2);
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
}
|
}
|
||||||
if (Baritone.settings().renderPathIgnoreDepth.get()) {
|
if (Baritone.settings().renderPathIgnoreDepth.value) {
|
||||||
GlStateManager.enableDepth();
|
GlStateManager.enableDepth();
|
||||||
}
|
}
|
||||||
//GlStateManager.color(0.0f, 0.0f, 0.0f, 0.4f);
|
//GlStateManager.color(0.0f, 0.0f, 0.0f, 0.4f);
|
||||||
@@ -186,10 +187,10 @@ public final class PathRenderer implements Helper {
|
|||||||
GlStateManager.disableBlend();
|
GlStateManager.disableBlend();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawLine(Entity player, double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z, float partialTicks) {
|
public static void drawLine(Entity player, double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z) {
|
||||||
double d0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double) partialTicks;
|
double d0 = mc.getRenderManager().viewerPosX;
|
||||||
double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) partialTicks;
|
double d1 = mc.getRenderManager().viewerPosY;
|
||||||
double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) partialTicks;
|
double d2 = mc.getRenderManager().viewerPosZ;
|
||||||
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
|
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
|
||||||
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
|
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
|
||||||
BUFFER.pos(bp2x + 0.5D - d0, bp2y + 0.5D - d1, bp2z + 0.5D - d2).endVertex();
|
BUFFER.pos(bp2x + 0.5D - d0, bp2y + 0.5D - d1, bp2z + 0.5D - d2).endVertex();
|
||||||
@@ -198,60 +199,33 @@ public final class PathRenderer implements Helper {
|
|||||||
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
|
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawManySelectionBoxes(Entity player, Collection<BlockPos> positions, float partialTicks, Color color) {
|
public static void drawManySelectionBoxes(Entity player, Collection<BlockPos> positions, Color color) {
|
||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
|
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
|
||||||
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
|
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
|
||||||
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.get());
|
GlStateManager.glLineWidth(Baritone.settings().pathRenderLineWidthPixels.value);
|
||||||
GlStateManager.disableTexture2D();
|
GlStateManager.disableTexture2D();
|
||||||
GlStateManager.depthMask(false);
|
GlStateManager.depthMask(false);
|
||||||
|
|
||||||
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.get()) {
|
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
|
||||||
GlStateManager.disableDepth();
|
GlStateManager.disableDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
float expand = 0.002F;
|
|
||||||
//BlockPos blockpos = movingObjectPositionIn.getBlockPos();
|
|
||||||
|
|
||||||
double renderPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double) partialTicks;
|
//BlockPos blockpos = movingObjectPositionIn.getBlockPos();
|
||||||
double renderPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) partialTicks;
|
BlockStateInterface bsi = new BlockStateInterface(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext()); // TODO this assumes same dimension between primary baritone and render view? is this safe?
|
||||||
double renderPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) partialTicks;
|
|
||||||
positions.forEach(pos -> {
|
positions.forEach(pos -> {
|
||||||
IBlockState state = BlockStateInterface.get(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext(), pos);
|
IBlockState state = bsi.get0(pos);
|
||||||
AxisAlignedBB toDraw;
|
AxisAlignedBB toDraw;
|
||||||
if (state.getBlock().equals(Blocks.AIR)) {
|
if (state.getBlock().equals(Blocks.AIR)) {
|
||||||
toDraw = Blocks.DIRT.getDefaultState().getSelectedBoundingBox(player.world, pos);
|
toDraw = Blocks.DIRT.getDefaultState().getSelectedBoundingBox(player.world, pos);
|
||||||
} else {
|
} else {
|
||||||
toDraw = state.getSelectedBoundingBox(player.world, pos);
|
toDraw = state.getSelectedBoundingBox(player.world, pos);
|
||||||
}
|
}
|
||||||
toDraw = toDraw.expand(expand, expand, expand).offset(-renderPosX, -renderPosY, -renderPosZ);
|
drawAABB(toDraw);
|
||||||
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
|
|
||||||
TESSELLATOR.draw();
|
|
||||||
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
|
|
||||||
TESSELLATOR.draw();
|
|
||||||
BUFFER.begin(GL_LINES, DefaultVertexFormats.POSITION);
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
|
|
||||||
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
|
|
||||||
TESSELLATOR.draw();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.get()) {
|
if (Baritone.settings().renderSelectionBoxesIgnoreDepth.value) {
|
||||||
GlStateManager.enableDepth();
|
GlStateManager.enableDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,11 +234,39 @@ public final class PathRenderer implements Helper {
|
|||||||
GlStateManager.disableBlend();
|
GlStateManager.disableBlend();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawLitDankGoalBox(Entity player, Goal goal, float partialTicks, Color color) {
|
public static void drawAABB(AxisAlignedBB aabb) {
|
||||||
double renderPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double) partialTicks;
|
float expand = 0.002F;
|
||||||
double renderPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) partialTicks;
|
AxisAlignedBB toDraw = aabb.expand(expand, expand, expand).offset(-mc.getRenderManager().viewerPosX, -mc.getRenderManager().viewerPosY, -mc.getRenderManager().viewerPosZ);
|
||||||
double renderPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) partialTicks;
|
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
|
||||||
|
TESSELLATOR.draw();
|
||||||
|
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
|
||||||
|
TESSELLATOR.draw();
|
||||||
|
BUFFER.begin(GL_LINES, DefaultVertexFormats.POSITION);
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.minZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.maxZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.maxX, toDraw.maxY, toDraw.maxZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.maxZ).endVertex();
|
||||||
|
BUFFER.pos(toDraw.minX, toDraw.maxY, toDraw.maxZ).endVertex();
|
||||||
|
TESSELLATOR.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawDankLitGoalBox(Entity player, Goal goal, float partialTicks, Color color) {
|
||||||
|
double renderPosX = mc.getRenderManager().viewerPosX;
|
||||||
|
double renderPosY = mc.getRenderManager().viewerPosY;
|
||||||
|
double renderPosZ = mc.getRenderManager().viewerPosZ;
|
||||||
double minX;
|
double minX;
|
||||||
double maxX;
|
double maxX;
|
||||||
double minZ;
|
double minZ;
|
||||||
@@ -295,10 +297,12 @@ public final class PathRenderer implements Helper {
|
|||||||
} else if (goal instanceof GoalXZ) {
|
} else if (goal instanceof GoalXZ) {
|
||||||
GoalXZ goalPos = (GoalXZ) goal;
|
GoalXZ goalPos = (GoalXZ) goal;
|
||||||
|
|
||||||
if (Baritone.settings().renderGoalXZBeacon.get()) {
|
if (Baritone.settings().renderGoalXZBeacon.value) {
|
||||||
|
glPushAttrib(GL_LIGHTING_BIT);
|
||||||
|
|
||||||
mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
|
mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
|
||||||
|
|
||||||
if (Baritone.settings().renderGoalIgnoreDepth.get()) {
|
if (Baritone.settings().renderGoalIgnoreDepth.value) {
|
||||||
GlStateManager.disableDepth();
|
GlStateManager.disableDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,9 +318,11 @@ public final class PathRenderer implements Helper {
|
|||||||
color.getColorComponents(null)
|
color.getColorComponents(null)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Baritone.settings().renderGoalIgnoreDepth.get()) {
|
if (Baritone.settings().renderGoalIgnoreDepth.value) {
|
||||||
GlStateManager.enableDepth();
|
GlStateManager.enableDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +337,7 @@ public final class PathRenderer implements Helper {
|
|||||||
maxY = 256 - renderPosY;
|
maxY = 256 - renderPosY;
|
||||||
} else if (goal instanceof GoalComposite) {
|
} else if (goal instanceof GoalComposite) {
|
||||||
for (Goal g : ((GoalComposite) goal).goals()) {
|
for (Goal g : ((GoalComposite) goal).goals()) {
|
||||||
drawLitDankGoalBox(player, g, partialTicks, color);
|
drawDankLitGoalBox(player, g, partialTicks, color);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@@ -341,10 +347,10 @@ public final class PathRenderer implements Helper {
|
|||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
|
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
|
||||||
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.6F);
|
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.6F);
|
||||||
GlStateManager.glLineWidth(Baritone.settings().goalRenderLineWidthPixels.get());
|
GlStateManager.glLineWidth(Baritone.settings().goalRenderLineWidthPixels.value);
|
||||||
GlStateManager.disableTexture2D();
|
GlStateManager.disableTexture2D();
|
||||||
GlStateManager.depthMask(false);
|
GlStateManager.depthMask(false);
|
||||||
if (Baritone.settings().renderGoalIgnoreDepth.get()) {
|
if (Baritone.settings().renderGoalIgnoreDepth.value) {
|
||||||
GlStateManager.disableDepth();
|
GlStateManager.disableDepth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +368,7 @@ public final class PathRenderer implements Helper {
|
|||||||
BUFFER.pos(minX, maxY, maxZ).endVertex();
|
BUFFER.pos(minX, maxY, maxZ).endVertex();
|
||||||
TESSELLATOR.draw();
|
TESSELLATOR.draw();
|
||||||
|
|
||||||
if (Baritone.settings().renderGoalIgnoreDepth.get()) {
|
if (Baritone.settings().renderGoalIgnoreDepth.value) {
|
||||||
GlStateManager.enableDepth();
|
GlStateManager.enableDepth();
|
||||||
}
|
}
|
||||||
GlStateManager.depthMask(true);
|
GlStateManager.depthMask(true);
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.utils;
|
||||||
|
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
|
|
||||||
|
public class PathingCommandContext extends PathingCommand {
|
||||||
|
public final CalculationContext desiredCalcContext;
|
||||||
|
|
||||||
|
public PathingCommandContext(Goal goal, PathingCommandType commandType, CalculationContext context) {
|
||||||
|
super(goal, commandType);
|
||||||
|
this.desiredCalcContext = context;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,16 +24,17 @@ import baritone.api.pathing.calc.IPathingControlManager;
|
|||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.process.IBaritoneProcess;
|
import baritone.api.process.IBaritoneProcess;
|
||||||
import baritone.api.process.PathingCommand;
|
import baritone.api.process.PathingCommand;
|
||||||
|
import baritone.api.process.PathingCommandType;
|
||||||
import baritone.behavior.PathingBehavior;
|
import baritone.behavior.PathingBehavior;
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class PathingControlManager implements IPathingControlManager {
|
public class PathingControlManager implements IPathingControlManager {
|
||||||
private final Baritone baritone;
|
private final Baritone baritone;
|
||||||
private final HashSet<IBaritoneProcess> processes; // unGh
|
private final HashSet<IBaritoneProcess> processes; // unGh
|
||||||
|
private final List<IBaritoneProcess> active;
|
||||||
private IBaritoneProcess inControlLastTick;
|
private IBaritoneProcess inControlLastTick;
|
||||||
private IBaritoneProcess inControlThisTick;
|
private IBaritoneProcess inControlThisTick;
|
||||||
private PathingCommand command;
|
private PathingCommand command;
|
||||||
@@ -41,13 +42,13 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
public PathingControlManager(Baritone baritone) {
|
public PathingControlManager(Baritone baritone) {
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
this.processes = new HashSet<>();
|
this.processes = new HashSet<>();
|
||||||
|
this.active = new ArrayList<>();
|
||||||
baritone.getGameEventHandler().registerEventListener(new AbstractGameEventListener() { // needs to be after all behavior ticks
|
baritone.getGameEventHandler().registerEventListener(new AbstractGameEventListener() { // needs to be after all behavior ticks
|
||||||
@Override
|
@Override
|
||||||
public void onTick(TickEvent event) {
|
public void onTick(TickEvent event) {
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.IN) {
|
||||||
return;
|
postTick();
|
||||||
}
|
}
|
||||||
postTick();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -62,6 +63,7 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
inControlLastTick = null;
|
inControlLastTick = null;
|
||||||
inControlThisTick = null;
|
inControlThisTick = null;
|
||||||
command = null;
|
command = null;
|
||||||
|
active.clear();
|
||||||
for (IBaritoneProcess proc : processes) {
|
for (IBaritoneProcess proc : processes) {
|
||||||
proc.onLostControl();
|
proc.onLostControl();
|
||||||
if (proc.isActive() && !proc.isTemporary()) { // it's okay only for a temporary thing (like combat pause) to maintain control even if you say to cancel
|
if (proc.isActive() && !proc.isTemporary()) { // it's okay only for a temporary thing (like combat pause) to maintain control even if you say to cancel
|
||||||
@@ -82,12 +84,19 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
|
|
||||||
public void preTick() {
|
public void preTick() {
|
||||||
inControlLastTick = inControlThisTick;
|
inControlLastTick = inControlThisTick;
|
||||||
|
inControlThisTick = null;
|
||||||
PathingBehavior p = baritone.getPathingBehavior();
|
PathingBehavior p = baritone.getPathingBehavior();
|
||||||
command = executeProcesses();
|
command = executeProcesses();
|
||||||
if (command == null) {
|
if (command == null) {
|
||||||
p.cancelSegmentIfSafe();
|
p.cancelSegmentIfSafe();
|
||||||
|
p.secretInternalSetGoal(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (inControlThisTick != inControlLastTick && command.commandType != PathingCommandType.REQUEST_PAUSE) {
|
||||||
|
// if control has changed, and the new process wants to do something
|
||||||
|
p.cancelSegmentIfSafe();
|
||||||
|
// get rid of the in progress stuff from the last process
|
||||||
|
}
|
||||||
switch (command.commandType) {
|
switch (command.commandType) {
|
||||||
case REQUEST_PAUSE:
|
case REQUEST_PAUSE:
|
||||||
p.requestPause();
|
p.requestPause();
|
||||||
@@ -98,18 +107,18 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
break;
|
break;
|
||||||
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
||||||
if (!p.isPathing() && !p.getInProgress().isPresent()) {
|
if (!p.isPathing() && !p.getInProgress().isPresent()) {
|
||||||
p.secretInternalSetGoalAndPath(command.goal);
|
p.secretInternalSetGoalAndPath(command);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REVALIDATE_GOAL_AND_PATH:
|
case REVALIDATE_GOAL_AND_PATH:
|
||||||
if (!p.isPathing() && !p.getInProgress().isPresent()) {
|
if (!p.isPathing() && !p.getInProgress().isPresent()) {
|
||||||
p.secretInternalSetGoalAndPath(command.goal);
|
p.secretInternalSetGoalAndPath(command);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SET_GOAL_AND_PATH:
|
case SET_GOAL_AND_PATH:
|
||||||
// now this i can do
|
// now this i can do
|
||||||
if (command.goal != null) {
|
if (command.goal != null) {
|
||||||
baritone.getPathingBehavior().secretInternalSetGoalAndPath(command.goal);
|
baritone.getPathingBehavior().secretInternalSetGoalAndPath(command);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -132,13 +141,13 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
// pwnage
|
// pwnage
|
||||||
p.softCancelIfSafe();
|
p.softCancelIfSafe();
|
||||||
}
|
}
|
||||||
p.secretInternalSetGoalAndPath(command.goal);
|
p.secretInternalSetGoalAndPath(command);
|
||||||
break;
|
break;
|
||||||
case REVALIDATE_GOAL_AND_PATH:
|
case REVALIDATE_GOAL_AND_PATH:
|
||||||
if (Baritone.settings().cancelOnGoalInvalidation.get() && (command.goal == null || revalidateGoal(command.goal))) {
|
if (Baritone.settings().cancelOnGoalInvalidation.value && (command.goal == null || revalidateGoal(command.goal))) {
|
||||||
p.softCancelIfSafe();
|
p.softCancelIfSafe();
|
||||||
}
|
}
|
||||||
p.secretInternalSetGoalAndPath(command.goal);
|
p.secretInternalSetGoalAndPath(command);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
@@ -171,12 +180,20 @@ public class PathingControlManager implements IPathingControlManager {
|
|||||||
|
|
||||||
|
|
||||||
public PathingCommand executeProcesses() {
|
public PathingCommand executeProcesses() {
|
||||||
Stream<IBaritoneProcess> inContention = processes.stream()
|
for (IBaritoneProcess process : processes) {
|
||||||
.filter(IBaritoneProcess::isActive)
|
if (process.isActive()) {
|
||||||
.sorted(Comparator.comparingDouble(IBaritoneProcess::priority).reversed());
|
if (!active.contains(process)) {
|
||||||
|
// put a newly active process at the very front of the queue
|
||||||
|
active.add(0, process);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
active.remove(process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ties are broken by which was added to the beginning of the list first
|
||||||
|
active.sort(Comparator.comparingDouble(IBaritoneProcess::priority).reversed());
|
||||||
|
|
||||||
|
Iterator<IBaritoneProcess> iterator = active.iterator();
|
||||||
Iterator<IBaritoneProcess> iterator = inContention.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
IBaritoneProcess proc = iterator.next();
|
IBaritoneProcess proc = iterator.next();
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class PlayerMovementInput extends MovementInput {
|
|||||||
this.moveStrafe = 0.0F;
|
this.moveStrafe = 0.0F;
|
||||||
this.moveForward = 0.0F;
|
this.moveForward = 0.0F;
|
||||||
|
|
||||||
jump = handler.isInputForcedDown(Input.JUMP); // oppa
|
jump = handler.isInputForcedDown(Input.JUMP); // oppa gangnam
|
||||||
|
|
||||||
if (this.forwardKeyDown = handler.isInputForcedDown(Input.MOVE_FORWARD)) {
|
if (this.forwardKeyDown = handler.isInputForcedDown(Input.MOVE_FORWARD)) {
|
||||||
this.moveForward++;
|
this.moveForward++;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user