Compare commits
293 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bb148844d | ||
|
|
7c9b812a5b | ||
|
|
9046eb500b | ||
|
|
011b7427e2 | ||
|
|
13caaf6fa7 | ||
|
|
a98677dbda | ||
|
|
afc639ab4b | ||
|
|
6c1f0d3711 | ||
|
|
e1e6a08eb2 | ||
|
|
7b21b0401d | ||
|
|
4c935fc447 | ||
|
|
3d221dcda4 | ||
|
|
ac6c413fb8 | ||
|
|
17a07ba85e | ||
|
|
ca6f7003a5 | ||
|
|
d402ba61cc | ||
|
|
081fae98c4 | ||
|
|
014d3b3a99 | ||
|
|
19fe29ad1e | ||
|
|
8bcbd0231e | ||
|
|
01c0e321b5 | ||
|
|
5f721b544e | ||
|
|
57d4a79496 | ||
|
|
9541a45451 | ||
|
|
bba4c09195 | ||
|
|
06c62029c5 | ||
|
|
6f251b64f1 | ||
|
|
551b6b88d2 | ||
|
|
07cbc47fb2 | ||
|
|
fe6ca97f21 | ||
|
|
1b481c6765 | ||
|
|
1c5e0b4d68 | ||
|
|
afebdce1f8 | ||
|
|
2ca4c3042a | ||
|
|
a8226ba4c8 | ||
|
|
bc849daccb | ||
|
|
e34b2d1392 | ||
|
|
f5b4de023f | ||
|
|
6dc7a7788e | ||
|
|
6bee5828a0 | ||
|
|
8a5cc5b17d | ||
|
|
4e563c6130 | ||
|
|
01cf3c67a6 | ||
|
|
36315c5151 | ||
|
|
9f951f261d | ||
|
|
4c8907c629 | ||
|
|
223791cea7 | ||
|
|
de6e96b952 | ||
|
|
0e51a73149 | ||
|
|
44a092cd94 | ||
|
|
7000b6cda2 | ||
|
|
7a17f7d253 | ||
|
|
821e73c1d3 | ||
|
|
784bc52d6d | ||
|
|
4338e34734 | ||
|
|
61147536e5 | ||
|
|
6b9737eb3f | ||
|
|
fe54372a53 | ||
|
|
21e9c0b7c1 | ||
|
|
8bf977060e | ||
|
|
074ec333cf | ||
|
|
d505ec4f9f | ||
|
|
9dd6856872 | ||
|
|
4d127acb9a | ||
|
|
ed4753e968 | ||
|
|
df900c9e64 | ||
|
|
93a090c56e | ||
|
|
8b43d93259 | ||
|
|
053662d0af | ||
|
|
af943a8253 | ||
|
|
8151444671 | ||
|
|
f32147d9d5 | ||
|
|
515e0364f7 | ||
|
|
09239f8180 | ||
|
|
0d9f233e33 | ||
|
|
e034437c63 | ||
|
|
72be046f34 | ||
|
|
3ba8824eb0 | ||
|
|
b51a261bd1 | ||
|
|
38602dd141 | ||
|
|
cdbec60da0 | ||
|
|
2b41012c5b | ||
|
|
6bb87d0a64 | ||
|
|
b16f9edd2c | ||
|
|
ce4b1e09ed | ||
|
|
1a4635df16 | ||
|
|
1390af20b6 | ||
|
|
1427cf57a8 | ||
|
|
d70243b4c0 | ||
|
|
8f63dd4ba6 | ||
|
|
01658286af | ||
|
|
aa90c8b7cd | ||
|
|
eba1011fd6 | ||
|
|
96a424c25a | ||
|
|
f4dd100345 | ||
|
|
c7e1c917c3 | ||
|
|
cd4205c361 | ||
|
|
b81bcf8c6d | ||
|
|
4259764b70 | ||
|
|
8f761f7dff | ||
|
|
cbbaf2aa2f | ||
|
|
dd9b84646a | ||
|
|
94131fd705 | ||
|
|
6d8914e6c9 | ||
|
|
63ee687cee | ||
|
|
ab779dc850 | ||
|
|
c2f35ae46f | ||
|
|
199e0e5ed3 | ||
|
|
a8155b4b0b | ||
|
|
fdd78cf110 | ||
|
|
afff6395d1 | ||
|
|
4d3d48e962 | ||
|
|
36290e4e53 | ||
|
|
fd6923dd28 | ||
|
|
9c64067d49 | ||
|
|
f4d2ea7923 | ||
|
|
ce3d3bb244 | ||
|
|
fa71e7d84f | ||
|
|
b0115b8b4c | ||
|
|
3902b2db3b | ||
|
|
4ff61f96df | ||
|
|
f998dce614 | ||
|
|
2b9084d2f3 | ||
|
|
b3605546ac | ||
|
|
96097ab726 | ||
|
|
be142d79bc | ||
|
|
0fd241a9ba | ||
|
|
7b192f17e8 | ||
|
|
cc015846d2 | ||
|
|
e785bd13f5 | ||
|
|
eb6c0a39ea | ||
|
|
86525f98ec | ||
|
|
8758c77ac0 | ||
|
|
dba496471e | ||
|
|
125facfbb6 | ||
|
|
94bf703dde | ||
|
|
14bb0a0a80 | ||
|
|
1ee6e04f00 | ||
|
|
ee6796d5e2 | ||
|
|
81d7f3c319 | ||
|
|
9822962d98 | ||
|
|
ce606f826b | ||
|
|
4c4bc8058b | ||
|
|
f0210f7c5f | ||
|
|
aef84eceb8 | ||
|
|
a6ea9ed3a6 | ||
|
|
0815e3c195 | ||
|
|
a1c03eb601 | ||
|
|
1e43563cc3 | ||
|
|
63f3f9123a | ||
|
|
4860d3bd18 | ||
|
|
7fa6593bdc | ||
|
|
e1dd580df8 | ||
|
|
f19e63d6e9 | ||
|
|
130873d91d | ||
|
|
9611cb9057 | ||
|
|
023aa78d8b | ||
|
|
39a231eae0 | ||
|
|
aca6922be0 | ||
|
|
1a52537d0c | ||
|
|
479b4e3349 | ||
|
|
a1e2b018a2 | ||
|
|
aa0f664cda | ||
|
|
2e2f4aee1b | ||
|
|
18474d872c | ||
|
|
44327c009a | ||
|
|
de554655a5 | ||
|
|
bd0c7b9391 | ||
|
|
8d32db5206 | ||
|
|
a6954aa719 | ||
|
|
b4d203ab99 | ||
|
|
bb924ad83f | ||
|
|
79da32cc60 | ||
|
|
c7fe9c3171 | ||
|
|
d70da4f37d | ||
|
|
ccc1b04e81 | ||
|
|
352e428890 | ||
|
|
4679e12588 | ||
|
|
16b74ff53c | ||
|
|
9297e98ac3 | ||
|
|
6861bfd4e6 | ||
|
|
0dd4834e18 | ||
|
|
da58988f01 | ||
|
|
b2f3880722 | ||
|
|
0293a76702 | ||
|
|
6a13e94c4f | ||
|
|
79d448e5f4 | ||
|
|
264b3db63c | ||
|
|
c8cd4b5f28 | ||
|
|
c9e81897a5 | ||
|
|
c738007538 | ||
|
|
da8bf6b1b3 | ||
|
|
1501d721e7 | ||
|
|
482d874af2 | ||
|
|
7dcd7384f1 | ||
|
|
2a5ef35794 | ||
|
|
0f09a46540 | ||
|
|
a6d4708ccf | ||
|
|
77303b4a62 | ||
|
|
0ffbb0c151 | ||
|
|
b521d7bee1 | ||
|
|
4e96c5e5ee | ||
|
|
e05010c9d2 | ||
|
|
d0a1c241a4 | ||
|
|
4ea8f23fc7 | ||
|
|
ec819220b7 | ||
|
|
54da0d24a3 | ||
|
|
58ebd5f9a6 | ||
|
|
d60a0bee9e | ||
|
|
e9e26c981a | ||
|
|
5f12f04e87 | ||
|
|
7b7be32ca7 | ||
|
|
a14166b1e2 | ||
|
|
166eb97c3f | ||
|
|
920ce745c2 | ||
|
|
c931cde3ae | ||
|
|
f7a577e163 | ||
|
|
9bf3a041d4 | ||
|
|
85eb7d8043 | ||
|
|
b338dcc9de | ||
|
|
7d9b8ee4f3 | ||
|
|
0f61aaafb8 | ||
|
|
0927e0e017 | ||
|
|
783a7cedc3 | ||
|
|
b1ee23ad50 | ||
|
|
9118e0b368 | ||
|
|
5a0ccac0a1 | ||
|
|
c8419dc362 | ||
|
|
9127ba2fce | ||
|
|
36858ca219 | ||
|
|
30469e2de2 | ||
|
|
79c433b14d | ||
|
|
bc419cfd1a | ||
|
|
09fbf675ec | ||
|
|
3d3a5f420e | ||
|
|
9c9c9d4387 | ||
|
|
82d09a536d | ||
|
|
6e49adea33 | ||
|
|
f85afdbc70 | ||
|
|
563028a5b3 | ||
|
|
d5c317b88b | ||
|
|
c59ec9da10 | ||
|
|
3a675836da | ||
|
|
7e0fc81246 | ||
|
|
f970f932c7 | ||
|
|
52d2741f52 | ||
|
|
7bc6765cac | ||
|
|
85b2aea6e9 | ||
|
|
c6ba5481d9 | ||
|
|
81f47d5632 | ||
|
|
9b1440ed2c | ||
|
|
2a8dcee028 | ||
|
|
277ba3643c | ||
|
|
e5fbaf60f3 | ||
|
|
0deb854e1b | ||
|
|
8268e3ec1b | ||
|
|
af91da6a28 | ||
|
|
9a15a65ad5 | ||
|
|
0cbe9f81c8 | ||
|
|
42afd2dd54 | ||
|
|
315929f31c | ||
|
|
358aa80280 | ||
|
|
1dd9e11994 | ||
|
|
5a8f02c944 | ||
|
|
f248a5b677 | ||
|
|
e4a49c5529 | ||
|
|
449b44ba50 | ||
|
|
a00eec402e | ||
|
|
717779f742 | ||
|
|
6f843bd24d | ||
|
|
d79fbea433 | ||
|
|
4d22c10ddb | ||
|
|
1ea92a6092 | ||
|
|
66eba84d06 | ||
|
|
92e39b5d1d | ||
|
|
0ddc47f473 | ||
|
|
ddfeca6947 | ||
|
|
6bd2e90cfd | ||
|
|
82505ddb01 | ||
|
|
2790d1d308 | ||
|
|
11e503a022 | ||
|
|
6fe49380ba | ||
|
|
1f2e267e3d | ||
|
|
4cf6783622 | ||
|
|
82d77a7bac | ||
|
|
841a927033 | ||
|
|
5a16561954 | ||
|
|
e2cc51908b | ||
|
|
1390e04435 | ||
|
|
84d961cbab | ||
|
|
87b9d3915c | ||
|
|
c38d17563d | ||
|
|
0c2af85ac0 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto
|
||||
1
.github/ISSUE_TEMPLATE.md
vendored
1
.github/ISSUE_TEMPLATE.md
vendored
@@ -1 +0,0 @@
|
||||
<!-- No UwU's or OwO's allowed -->
|
||||
25
.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Please file a separate report for each issue
|
||||
title: Please add a brief but descriptive title
|
||||
labels: bug
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
## Some information
|
||||
Operating system:
|
||||
Java version:
|
||||
Minecraft version:
|
||||
Baritone version:
|
||||
Forge mods (if used):
|
||||
|
||||
## Exception, error or logs
|
||||
You can find your logs in `%appdata%/.minecraft/logs/` (Windows) or `/Library/Application\ Support/minecraft/logs` (Mac).
|
||||
|
||||
## How to reproduce
|
||||
Add your steps to reproduce the issue/bug experienced here.
|
||||
|
||||
## Final checklist
|
||||
- [ ] I have included the version of Minecraft I'm running, baritone's version and forge mods (if used).
|
||||
- [ ] I have included logs, exceptions and / or steps to reproduce the issue.
|
||||
- [ ] I have not used any OwO's or UwU's in this issue.
|
||||
13
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
name: Question
|
||||
about: Please file a separate report for each question
|
||||
title: Please add a brief but descriptive title
|
||||
labels: question
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
## What do you need help with?
|
||||
With as much detail as possible, describe your question and what you may need help with.
|
||||
|
||||
## Final checklist
|
||||
- [ ] I have not used any OwO's or UwU's in this issue.
|
||||
19
.github/ISSUE_TEMPLATE/suggestion.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/suggestion.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Suggestion
|
||||
about: Please file a separate report for each suggestion
|
||||
title: Please add a brief but descriptive title
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
## Describe your suggestion
|
||||
With as much detail as possible, describe what your suggestion would do for Baritone.
|
||||
|
||||
## Settings
|
||||
If applicable, what settings/customizability should be offered to tweak the functionality of your suggestion.
|
||||
|
||||
## Context
|
||||
Describe how your suggestion would improve Baritone, or the reason behind it being added.
|
||||
|
||||
## Final checklist
|
||||
- [ ] I have not used any OwO's or UwU's in this issue.
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -11,6 +11,8 @@ build/
|
||||
classes/
|
||||
*.class
|
||||
|
||||
/out
|
||||
|
||||
# IntelliJ Files
|
||||
.idea/
|
||||
*.iml
|
||||
@@ -18,4 +20,4 @@ classes/
|
||||
|
||||
# Copyright Files
|
||||
!/.idea/copyright/Baritone.xml
|
||||
!/.idea/copyright/profiles_settings.xml
|
||||
!/.idea/copyright/profiles_settings.xml
|
||||
|
||||
@@ -10,7 +10,7 @@ install:
|
||||
|
||||
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 "/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 runAutoTest; cat /code/autotest/success"
|
||||
- docker cp baritone:/code/dist dist
|
||||
- ls dist
|
||||
- cat dist/checksums.txt
|
||||
|
||||
41
README.md
41
README.md
@@ -1,37 +1,44 @@
|
||||
# Baritone
|
||||
[](https://travis-ci.com/cabaletta/baritone)
|
||||
[](https://github.com/cabaletta/baritone/releases)
|
||||
[](https://travis-ci.com/cabaletta/baritone/)
|
||||
[](https://github.com/cabaletta/baritone/releases/)
|
||||
[](LICENSE)
|
||||
[](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/releases/)
|
||||
[](https://github.com/cabaletta/baritone/tree/master/)
|
||||
[](https://github.com/cabaletta/baritone/tree/1.13.2/)
|
||||
[](https://github.com/cabaletta/baritone/tree/1.14.4/)
|
||||
[](https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md)
|
||||
[](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://github.com/cabaletta/baritone/graphs/contributors/)
|
||||
[](https://github.com/cabaletta/baritone/commit/)
|
||||
[](https://impactdevelopment.github.io/)
|
||||
[](https://impactdevelopment.github.io/)
|
||||
[](https://github.com/fr1kin/ForgeHax/)
|
||||
[](https://gitlab.com/emc-mods-indrit/baritone_api)
|
||||
[](https://wweclient.com/)
|
||||
[](https://github.com/zeroeightysix/KAMI/)
|
||||
[](https://futureclient.net/)
|
||||
[](https://github.com/fr1kin/ForgeHax)
|
||||
[](http://forthebadge.com)
|
||||
[](http://forthebadge.com)
|
||||
[](http://forthebadge.com/)
|
||||
[](http://forthebadge.com/)
|
||||
|
||||
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.
|
||||
|
||||
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||
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).
|
||||
The easiest way to install Baritone is to install [Impact](https://impactdevelopment.github.io/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* forge api jar from [releases](https://github.com/cabaletta/baritone/releases). Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
|
||||
|
||||
Have committed at least once a day for the last 8 months =D 🦀
|
||||
For 1.14.4, [click here](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1). Or [with optifine](https://github.com/cabaletta/baritone/issues/797).
|
||||
|
||||
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 and 1.13.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 from Aug 1 2018 to Aug 1 2019.
|
||||
|
||||
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
|
||||
|
||||
@@ -47,7 +54,7 @@ Here are some links to help to get started:
|
||||
|
||||
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
|
||||
|
||||
- [Baritone chat control usage](USAGE.md)
|
||||
- [Usage (chat control)](USAGE.md)
|
||||
|
||||
# API
|
||||
|
||||
@@ -68,11 +75,11 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd
|
||||
|
||||
## Can I use Baritone as a library in my custom utility client?
|
||||
|
||||
That's what it's for, 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.0 License)
|
||||
|
||||
## 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?
|
||||
|
||||
|
||||
8
SETUP.md
8
SETUP.md
@@ -1,10 +1,18 @@
|
||||
# Installation
|
||||
|
||||
The easiest way to install Baritone is to install [Impact](https://impactdevelopment.github.io/), which comes with Baritone.
|
||||
|
||||
For 1.14.4, [click here](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1).
|
||||
|
||||
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
|
||||
|
||||
## 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 `backfill-2` branch for example, you'll have to build it yourself)
|
||||
|
||||
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
|
||||
|
||||
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2
|
||||
|
||||
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).
|
||||
|
||||
45
USAGE.md
45
USAGE.md
@@ -2,49 +2,44 @@
|
||||
|
||||
# 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.
|
||||
Baritone's chat control prefix is `#` by default. In Impact, you can also use `.b` as a prefix. (for example, `.b click` instead of `#click`)
|
||||
|
||||
Baritone commands can also 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, so using `#` is suggested.
|
||||
|
||||
To disable direct chat control (with no prefix), turn off the `chatControl` setting. To disable chat control with the `#` prefix, turn off the `prefixControl` setting. In Impact, `.b` cannot be disabled. Be careful that you don't leave yourself with all control methods disabled (if you do, reset your settings by deleting the file `minecraft/baritone/settings.txt` and relaunching).
|
||||
|
||||
# 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).
|
||||
`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java#L47).
|
||||
|
||||
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 x y z` or `goal x z` or `goal y`, then `path` to set a goal to a certain coordinate then path to it
|
||||
- `goto x y z` or `goto x z` or `goto y` to go to a certain coordinate (in a single step, starts going immediately)
|
||||
- `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. left click and drag to clear an area.
|
||||
- `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).
|
||||
- `click` to click your destination on the screen. Right click path to on top of the block, left click to path into it (either at foot level or eye level), and left click and drag to clear all blocks from an area.
|
||||
- `follow playerName` to follow a player. `followplayers` to follow any players in range (combine with Kill Aura for a fun time). `followentities` to follow any entities. `followentity pig` to follow entities of a specific type.
|
||||
- `save waypointName` to save a waypoint. `goto waypointName` to go to it.
|
||||
- `build` to build a schematic. `build blah` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah x y z` to set the origin. Any of those can be relative to your player (`~ 69 ~-420` would build at x=player x, y=69, z=player z-420).
|
||||
- `schematica` to build the schematic that is currently open in schematica
|
||||
- `tunnel` to dig just straight ahead and make a tunnel
|
||||
- `farm` to automatically harvest, replant, or bone meal crops
|
||||
- `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120).
|
||||
- `explore x z` to explore the world from the origin of x,z. Leave out x and z to default to player feet. This will continually path towards the closest chunk to the origin that it's never seen before. `explorefilter filter.json` with optional invert can be used to load in a list of chunks to load.
|
||||
- `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
|
||||
- `build` to build a schematic. `build blah` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah x y z` to set the origin. Any of those can be relative to your player (`~ 69 ~-420` would build at x=player x, y=69, z=player z-420).
|
||||
|
||||
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).
|
||||
|
||||
For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/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>.
|
||||
|
||||
@@ -54,10 +49,18 @@ There are about a hundred settings, but here are some fun / interesting / import
|
||||
- `allowPlace`
|
||||
- `allowParkour`
|
||||
- `allowParkourPlace`
|
||||
- `blockPlacementPenalty`
|
||||
- `renderCachedChunks` (and `cachedChunksOpacity`) <-- very fun but you need a beefy computer
|
||||
- `avoidance`
|
||||
- `avoidance` (avoidance of mobs / mob spawners)
|
||||
- `legitMine`
|
||||
- `followRadius`
|
||||
- `backfill` (fill in tunnels behind you)
|
||||
- `buildInLayers`
|
||||
- `buildRepeatDistance` and `buildRepeatDirection`
|
||||
- `worldExploringChunkOffset`
|
||||
- `acceptableThrowawayItems`
|
||||
- `blocksToAvoidBreaking`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
93
build.gradle
93
build.gradle
@@ -16,33 +16,33 @@
|
||||
*/
|
||||
|
||||
group 'baritone'
|
||||
version '1.2.6'
|
||||
version '1.4.0'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
name = 'forge'
|
||||
url = 'http://files.minecraftforge.net/maven'
|
||||
}
|
||||
maven {
|
||||
name = 'SpongePowered'
|
||||
url = 'http://repo.spongepowered.org/maven'
|
||||
name = 'impactdevelopment-repo'
|
||||
url = 'https://impactdevelopment.github.io/maven/'
|
||||
}
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
|
||||
classpath group: 'com.github.ImpactDevelopment', name: 'ForgeGradle', version: '3.0.115'
|
||||
classpath group: 'com.github.ImpactDevelopment', name: 'MixinGradle', version: '0.6.2'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import baritone.gradle.task.CreateDistTask
|
||||
import baritone.gradle.task.ProguardTask
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: 'org.spongepowered.mixin'
|
||||
|
||||
sourceCompatibility = targetCompatibility = '1.8'
|
||||
@@ -52,19 +52,75 @@ compileJava {
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
api {
|
||||
compileClasspath += main.compileClasspath
|
||||
}
|
||||
main {
|
||||
compileClasspath += api.output
|
||||
}
|
||||
test {
|
||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
}
|
||||
launch {
|
||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
}
|
||||
|
||||
schematica_api {
|
||||
compileClasspath += main.compileClasspath
|
||||
}
|
||||
|
||||
main {
|
||||
compileClasspath += schematica_api.output
|
||||
}
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = '1.12.2'
|
||||
mappings = 'stable_39'
|
||||
tweakClass = 'baritone.launch.BaritoneTweaker'
|
||||
runDir = 'run'
|
||||
task sourceJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.api.allSource
|
||||
}
|
||||
|
||||
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
|
||||
makeObfSourceJar = true
|
||||
minecraft {
|
||||
mappings channel: 'snapshot', version: '20190814-1.14.3'
|
||||
reobfMappings 'notch'
|
||||
|
||||
runs {
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
source sourceSets.launch
|
||||
|
||||
main 'baritone.launch.LaunchTesting'
|
||||
|
||||
environment 'assetIndex', '{asset_index}'
|
||||
environment 'assetDirectory', downloadAssets.output
|
||||
environment 'nativesDirectory', extractNatives.output
|
||||
|
||||
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
jvmArgs "-XstartOnFirstThread"
|
||||
}
|
||||
}
|
||||
|
||||
autoTest {
|
||||
workingDirectory project.file('autotest')
|
||||
source sourceSets.launch
|
||||
|
||||
main 'baritone.launch.LaunchTesting'
|
||||
|
||||
environment 'assetIndex', '{asset_index}'
|
||||
environment 'assetDirectory', downloadAssets.output
|
||||
environment 'nativesDirectory', extractNatives.output
|
||||
|
||||
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
|
||||
environment 'BARITONE_AUTO_TEST', 'true'
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
jvmArgs "-XstartOnFirstThread"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -82,6 +138,12 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft 'com.github.ImpactDevelopment:Vanilla:1.14.4'
|
||||
|
||||
runtime launchCompile('net.minecraft:launchwrapper:1.12') {
|
||||
exclude module: 'lwjgl'
|
||||
}
|
||||
runtime launchCompile('org.ow2.asm:asm-debug-all:5.2')
|
||||
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
|
||||
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
|
||||
// Mixin includes a lot of dependencies that are too up-to-date
|
||||
@@ -91,6 +153,7 @@ dependencies {
|
||||
exclude module: 'commons-io'
|
||||
exclude module: 'log4j-core'
|
||||
}
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
|
||||
@@ -40,17 +40,13 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
||||
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
||||
|
||||
TEMP_LIBRARY_DIR = "tempLibraries/",
|
||||
|
||||
ARTIFACT_STANDARD = "%s-%s.jar",
|
||||
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
||||
ARTIFACT_API = "%s-api-%s.jar",
|
||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
|
||||
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
|
||||
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
|
||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
|
||||
|
||||
protected String artifactName, artifactVersion;
|
||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, proguardOut;
|
||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
|
||||
|
||||
protected void verifyArtifacts() throws IllegalStateException {
|
||||
this.artifactName = getProject().getName();
|
||||
@@ -60,8 +56,6 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
|
||||
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);
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@ public class CreateDistTask extends BaritoneGradleTask {
|
||||
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
|
||||
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
|
||||
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
|
||||
Path dir = getRelativeFile("dist/");
|
||||
@@ -58,11 +56,9 @@ public class CreateDistTask extends BaritoneGradleTask {
|
||||
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
|
||||
Files.copy(this.artifactStandalonePath, standalone, 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"
|
||||
List<String> shasum = Stream.of(api, forgeApi, standalone, forgeStandalone, unoptimized)
|
||||
List<String> shasum = Stream.of(api, standalone, unoptimized)
|
||||
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
@@ -18,26 +18,18 @@
|
||||
package baritone.gradle.task;
|
||||
|
||||
import baritone.gradle.util.Determinizer;
|
||||
import baritone.gradle.util.MappingType;
|
||||
import baritone.gradle.util.ReobfWrapper;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.gradle.api.NamedDomainObjectContainer;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.internal.plugins.DefaultConvention;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.internal.Pair;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
@@ -49,18 +41,12 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
*/
|
||||
public class ProguardTask extends BaritoneGradleTask {
|
||||
|
||||
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
|
||||
|
||||
@Input
|
||||
private String url;
|
||||
|
||||
@Input
|
||||
private String extract;
|
||||
|
||||
private List<String> requiredLibraries;
|
||||
|
||||
private File mixin;
|
||||
|
||||
@TaskAction
|
||||
protected void exec() throws Exception {
|
||||
super.verifyArtifacts();
|
||||
@@ -70,7 +56,6 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
downloadProguard();
|
||||
extractProguard();
|
||||
generateConfigs();
|
||||
acquireDependencies();
|
||||
proguardApi();
|
||||
proguardStandalone();
|
||||
cleanup();
|
||||
@@ -81,7 +66,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
Files.delete(this.artifactUnoptimizedPath);
|
||||
}
|
||||
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
|
||||
}
|
||||
|
||||
private void downloadProguard() throws Exception {
|
||||
@@ -114,6 +99,19 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
|
||||
template.add(2, "-libraryjars '" + out + "'");
|
||||
|
||||
// Discover all of the libraries that we will need to acquire from gradle
|
||||
acquireDependencies().forEach(f -> {
|
||||
if (f.toString().endsWith("-recomp.jar")) {
|
||||
// remove MCP mapped jar
|
||||
return;
|
||||
}
|
||||
if (f.toString().endsWith("client-extra.jar")) {
|
||||
// go from the extra to the original downloaded client
|
||||
f = new File(f.getParentFile(), "client.jar");
|
||||
}
|
||||
template.add(2, "-libraryjars '" + f + "'");
|
||||
});
|
||||
|
||||
// API config doesn't require any changes from the changes that we made to the template
|
||||
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
|
||||
|
||||
@@ -121,165 +119,20 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
List<String> standalone = new ArrayList<>(template);
|
||||
standalone.removeIf(s -> s.contains("# this is the keep api"));
|
||||
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
|
||||
|
||||
// Discover all of the libraries that we will need to acquire from gradle
|
||||
this.requiredLibraries = new ArrayList<>();
|
||||
template.forEach(line -> {
|
||||
if (!line.startsWith("#")) {
|
||||
Matcher m = TEMP_LIBRARY_PATTERN.matcher(line);
|
||||
if (m.find()) {
|
||||
this.requiredLibraries.add(m.group(1));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void acquireDependencies() throws Exception {
|
||||
|
||||
// Create a map of all of the dependencies that we are able to access in this project
|
||||
// Likely a better way to do this, I just pair the dependency with the first valid configuration
|
||||
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
|
||||
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
|
||||
config.getAllDependencies().forEach(dependency ->
|
||||
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
|
||||
|
||||
// Create the directory if it doesn't already exist
|
||||
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
|
||||
if (!Files.exists(tempLibraries)) {
|
||||
Files.createDirectory(tempLibraries);
|
||||
}
|
||||
|
||||
// Iterate the required libraries to copy them to tempLibraries
|
||||
for (String lib : this.requiredLibraries) {
|
||||
// copy from the forgegradle cache
|
||||
if (lib.equals("minecraft")) {
|
||||
Path cachedJar = getMinecraftJar();
|
||||
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
|
||||
// TODO: maybe try not to copy every time
|
||||
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find a configuration/dependency pair that matches the desired library
|
||||
Pair<Configuration, Dependency> pair = null;
|
||||
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
|
||||
if (entry.getKey().startsWith(lib)) {
|
||||
pair = entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// The pair must be non-null
|
||||
Objects.requireNonNull(pair);
|
||||
|
||||
// Find the library jar file, and copy it to tempLibraries
|
||||
for (File file : pair.getLeft().files(pair.getRight())) {
|
||||
if (file.getName().startsWith(lib)) {
|
||||
if (lib.contains("mixin")) {
|
||||
mixin = file;
|
||||
}
|
||||
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
|
||||
private Path getMinecraftJar() throws Exception {
|
||||
MappingType mappingType;
|
||||
try {
|
||||
mappingType = getMappingType();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to get mapping type, assuming NOTCH.");
|
||||
mappingType = MappingType.NOTCH;
|
||||
}
|
||||
|
||||
String suffix;
|
||||
switch (mappingType) {
|
||||
case NOTCH:
|
||||
suffix = "";
|
||||
break;
|
||||
case SEARGE:
|
||||
suffix = "-srgBin";
|
||||
break;
|
||||
case CUSTOM:
|
||||
throw new IllegalStateException("Custom mappings not supported!");
|
||||
default:
|
||||
throw new IllegalStateException("Unknown mapping type: " + mappingType);
|
||||
}
|
||||
|
||||
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
|
||||
Object extension = convention.getAsMap().get("minecraft");
|
||||
Objects.requireNonNull(extension);
|
||||
|
||||
// for some reason cant use Class.forName
|
||||
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
|
||||
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
|
||||
f_replacer.setAccessible(true);
|
||||
Object replacer = f_replacer.get(extension);
|
||||
Class<?> class_replacementProvider = replacer.getClass();
|
||||
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
|
||||
replacement_replaceMap.setAccessible(true);
|
||||
|
||||
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
|
||||
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
|
||||
String mcVersion = replacements.get("MC_VERSION").toString();
|
||||
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
|
||||
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
|
||||
|
||||
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
|
||||
|
||||
String jarPath;
|
||||
if (mappingType == MappingType.SEARGE) {
|
||||
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
|
||||
} else {
|
||||
jarPath = baseDir + fullJarName;
|
||||
}
|
||||
jarPath = jarPath
|
||||
.replace("/", File.separator)
|
||||
.replace("\\", File.separator); // hecking regex
|
||||
|
||||
return new File(jarPath).toPath();
|
||||
}
|
||||
|
||||
// throws IllegalStateException if mapping type is ambiguous or it fails to find it
|
||||
private MappingType getMappingType() {
|
||||
// if it fails to find this then its probably a forgegradle version problem
|
||||
Set<Object> reobf = (NamedDomainObjectContainer<Object>) this.getProject().getExtensions().getByName("reobf");
|
||||
|
||||
List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
|
||||
long mappingTypesUsed = mappingTypes.size();
|
||||
if (mappingTypesUsed == 0) {
|
||||
throw new IllegalStateException("Failed to find mapping type (no jar task?)");
|
||||
}
|
||||
if (mappingTypesUsed > 1) {
|
||||
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
|
||||
}
|
||||
|
||||
return mappingTypes.get(0);
|
||||
}
|
||||
|
||||
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
|
||||
return reobf.stream()
|
||||
.map(ReobfWrapper::new)
|
||||
.map(ReobfWrapper::getMappingType)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
private Stream<File> acquireDependencies() {
|
||||
return getProject().getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().findByName("launch").getRuntimeClasspath().getFiles().stream().filter(File::isFile);
|
||||
}
|
||||
|
||||
private void proguardApi() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
|
||||
}
|
||||
|
||||
private void proguardStandalone() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
|
||||
@@ -22,7 +22,10 @@ import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
@@ -36,7 +39,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class Determinizer {
|
||||
|
||||
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
|
||||
public static void determinize(String inputPath, String outputPath) throws IOException {
|
||||
System.out.println("Running Determinizer");
|
||||
System.out.println(" Input path: " + inputPath);
|
||||
System.out.println(" Output path: " + outputPath);
|
||||
@@ -63,30 +66,10 @@ public class Determinizer {
|
||||
if (entry.getName().endsWith(".refmap.json")) {
|
||||
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
|
||||
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 {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +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.gradle.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* All credits go to AsmLibGradle and its contributors.
|
||||
*
|
||||
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/ReobfWrapper.java">Original Source</a>
|
||||
*/
|
||||
public class ReobfWrapper {
|
||||
|
||||
private final Object instance;
|
||||
private final Class<?> type;
|
||||
|
||||
public ReobfWrapper(Object instance) {
|
||||
this.instance = instance;
|
||||
Objects.requireNonNull(instance);
|
||||
this.type = instance.getClass();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
try {
|
||||
Field nameField = type.getDeclaredField("name");
|
||||
nameField.setAccessible(true);
|
||||
return (String) nameField.get(this.instance);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public MappingType getMappingType() {
|
||||
try {
|
||||
Field enumField = type.getDeclaredField("mappingType");
|
||||
enumField.setAccessible(true);
|
||||
Enum<?> aEnum = (Enum<?>) enumField.get(this.instance);
|
||||
MappingType mappingType = MappingType.values()[aEnum.ordinal()];
|
||||
if (!aEnum.name().equals(mappingType.name())) {
|
||||
throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)");
|
||||
}
|
||||
return mappingType;
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
scripts/proguard.pro
vendored
54
scripts/proguard.pro
vendored
@@ -14,6 +14,8 @@
|
||||
|
||||
# lwjgl is weird
|
||||
-dontwarn org.lwjgl.**
|
||||
# also lwjgl lol
|
||||
-dontwarn module-info
|
||||
|
||||
-keep class baritone.api.** { *; } # this is the keep api
|
||||
|
||||
@@ -31,54 +33,10 @@
|
||||
# need to keep mixin names
|
||||
-keep class baritone.launch.** { *; }
|
||||
|
||||
# copy all necessary libraries into tempLibraries to build
|
||||
|
||||
# The correct jar will be copied from the forgegradle cache based on the mapping type being compiled with
|
||||
-libraryjars 'tempLibraries/minecraft.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
|
||||
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
|
||||
-libraryjars 'tempLibraries/codecwav-20101023.jar'
|
||||
-libraryjars 'tempLibraries/commons-codec-1.10.jar'
|
||||
-libraryjars 'tempLibraries/commons-compress-1.8.1.jar'
|
||||
-libraryjars 'tempLibraries/commons-io-2.5.jar'
|
||||
-libraryjars 'tempLibraries/commons-lang3-3.5.jar'
|
||||
-libraryjars 'tempLibraries/commons-logging-1.1.3.jar'
|
||||
-libraryjars 'tempLibraries/fastutil-7.1.0.jar'
|
||||
-libraryjars 'tempLibraries/gson-2.8.0.jar'
|
||||
-libraryjars 'tempLibraries/guava-21.0.jar'
|
||||
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
|
||||
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
|
||||
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
|
||||
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
|
||||
-libraryjars 'tempLibraries/jna-4.4.0.jar'
|
||||
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
|
||||
-libraryjars 'tempLibraries/jsr305-3.0.1.jar'
|
||||
-libraryjars 'tempLibraries/jutils-1.0.0.jar'
|
||||
-libraryjars 'tempLibraries/libraryjavasound-20101123.jar'
|
||||
-libraryjars 'tempLibraries/librarylwjglopenal-20100824.jar'
|
||||
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
|
||||
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
|
||||
|
||||
# startsWith is used to check the library, and mac/linux differ in which version they use
|
||||
# this is FINE
|
||||
-libraryjars 'tempLibraries/lwjgl-.jar'
|
||||
-libraryjars 'tempLibraries/lwjgl_util-.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
|
||||
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
|
||||
-libraryjars 'tempLibraries/patchy-1.1.jar'
|
||||
-libraryjars 'tempLibraries/platform-3.4.0.jar'
|
||||
-libraryjars 'tempLibraries/realms-1.10.22.jar'
|
||||
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
|
||||
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
|
||||
-libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
|
||||
|
||||
|
||||
#try to keep usage of schematica in separate classes
|
||||
-keep class baritone.utils.schematic.schematica.**
|
||||
#proguard doesnt like it when it cant find our fake schematica classes
|
||||
-dontwarn baritone.utils.schematic.schematica.**
|
||||
|
||||
|
||||
# Keep - Applications. Keep all application classes, along with their 'main'
|
||||
|
||||
@@ -128,5 +128,8 @@ public interface IBaritone {
|
||||
*/
|
||||
IEventBus getGameEventHandler();
|
||||
|
||||
/**
|
||||
* Open click
|
||||
*/
|
||||
void openClick();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package baritone.api;
|
||||
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -43,19 +43,19 @@ public interface IBaritoneProvider {
|
||||
* returned by {@link #getPrimaryBaritone()}.
|
||||
*
|
||||
* @return All active {@link IBaritone} instances.
|
||||
* @see #getBaritoneForPlayer(EntityPlayerSP)
|
||||
* @see #getBaritoneForPlayer(ClientPlayerEntity)
|
||||
*/
|
||||
List<IBaritone> getAllBaritones();
|
||||
|
||||
/**
|
||||
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
|
||||
* Provides the {@link IBaritone} instance for a given {@link ClientPlayerEntity}. This will likely be
|
||||
* replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when
|
||||
* {@code bot-system} is merged into {@code master}.
|
||||
*
|
||||
* @param player The player
|
||||
* @return The {@link IBaritone} instance.
|
||||
*/
|
||||
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
|
||||
default IBaritone getBaritoneForPlayer(ClientPlayerEntity player) {
|
||||
for (IBaritone baritone : getAllBaritones()) {
|
||||
if (player.equals(baritone.getPlayerContext().player())) {
|
||||
return baritone;
|
||||
|
||||
@@ -20,10 +20,10 @@ package baritone.api;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.TypeUtils;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -84,7 +84,7 @@ public final class Settings {
|
||||
/**
|
||||
* Walking on water uses up hunger really quick, so penalize it
|
||||
*/
|
||||
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
|
||||
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D);
|
||||
|
||||
/**
|
||||
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
|
||||
@@ -124,6 +124,13 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* This should be monetized it's so good
|
||||
* <p>
|
||||
* Defaults to true, but only actually takes effect if allowParkour is also true
|
||||
*/
|
||||
public final Setting<Boolean> allowParkourAscend = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Allow descending diagonally
|
||||
* <p>
|
||||
@@ -144,10 +151,10 @@ public final class Settings {
|
||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||
*/
|
||||
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||
Item.getItemFromBlock(Blocks.DIRT),
|
||||
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
||||
Item.getItemFromBlock(Blocks.NETHERRACK),
|
||||
Item.getItemFromBlock(Blocks.STONE)
|
||||
Blocks.DIRT.asItem(),
|
||||
Blocks.COBBLESTONE.asItem(),
|
||||
Blocks.NETHERRACK.asItem(),
|
||||
Blocks.STONE.asItem()
|
||||
)));
|
||||
|
||||
/**
|
||||
@@ -160,15 +167,25 @@ public final class Settings {
|
||||
/**
|
||||
* Blocks that Baritone is not allowed to break
|
||||
*/
|
||||
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(
|
||||
// e.g. crafting table, beds
|
||||
));
|
||||
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
|
||||
Blocks.CRAFTING_TABLE,
|
||||
Blocks.FURNACE,
|
||||
Blocks.CHEST,
|
||||
Blocks.TRAPPED_CHEST
|
||||
)));
|
||||
|
||||
/**
|
||||
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
|
||||
* <p>
|
||||
* I.E. it will never trigger cascading sand / gravel falls
|
||||
*/
|
||||
public final Setting<Boolean> avoidUpdatingFallingBlocks = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
* Never turn this on lol
|
||||
* Almost never turn this on lol
|
||||
*/
|
||||
public final Setting<Boolean> allowVines = new Setting<>(false);
|
||||
|
||||
@@ -204,11 +221,28 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> sprintAscends = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
|
||||
* <p>
|
||||
* This helps with speed at >=20m/s
|
||||
*/
|
||||
public final Setting<Boolean> overshootTraverse = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* When breaking blocks for a movement, wait until all falling blocks have settled before continuing
|
||||
*/
|
||||
public final Setting<Boolean> pauseMiningForFallingBlocks = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* How many ticks between right clicks are allowed. Default in game is 4
|
||||
*/
|
||||
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
|
||||
|
||||
/**
|
||||
* How many degrees to randomize the yaw every tick. Set to 0 to disable
|
||||
*/
|
||||
public final Setting<Double> randomLooking = new Setting<>(2d);
|
||||
|
||||
/**
|
||||
* This is the big A* setting.
|
||||
* As long as your cost heuristic is an *underestimate*, it's guaranteed to find you the best path.
|
||||
@@ -522,6 +556,8 @@ public final class Settings {
|
||||
|
||||
/**
|
||||
* Exclusively use cached chunks for pathing
|
||||
* <p>
|
||||
* Never turn this on
|
||||
*/
|
||||
public final Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
|
||||
|
||||
@@ -552,7 +588,7 @@ public final class Settings {
|
||||
public final Setting<Boolean> renderCachedChunks = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* 0.0f = not visible, fully transparent
|
||||
* 0.0f = not visible, fully transparent (instead of setting this to 0, turn off renderCachedChunks)
|
||||
* 1.0f = fully opaque
|
||||
*/
|
||||
public final Setting<Float> cachedChunksOpacity = new Setting<>(0.5f);
|
||||
@@ -567,6 +603,16 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* When a new segment is calculated that doesn't overlap with the current one, but simply begins where the current segment ends,
|
||||
* splice it on and make a longer combined path. If this setting is off, any planned segment will not be spliced and will instead
|
||||
* be the "next path" in PathingBehavior, and will only start after this one ends. Turning this off hurts planning ahead,
|
||||
* because the next segment will exist even if it's very short.
|
||||
*
|
||||
* @see #planningTickLookahead
|
||||
*/
|
||||
public final Setting<Boolean> splicePath = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful
|
||||
*/
|
||||
@@ -606,7 +652,14 @@ public final class Settings {
|
||||
public final Setting<Integer> exploreChunkSetMinimumSize = new Setting<>(10);
|
||||
|
||||
/**
|
||||
* Replant nether wart
|
||||
* Attempt to maintain Y coordinate while exploring
|
||||
* <p>
|
||||
* -1 to disable
|
||||
*/
|
||||
public final Setting<Integer> exploreMaintainY = new Setting<>(64);
|
||||
|
||||
/**
|
||||
* Replant nether wart while farming
|
||||
*/
|
||||
public final Setting<Boolean> replantNetherWart = new Setting<>(false);
|
||||
|
||||
@@ -623,14 +676,30 @@ public final class Settings {
|
||||
public final Setting<Boolean> buildInLayers = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* How far to move before repeating the build. -1 for the size of the build in that axis. 0 to disable
|
||||
* false = build from bottom to top
|
||||
* <p>
|
||||
* true = build from top to bottom
|
||||
*/
|
||||
public final Setting<Integer> buildRepeatDistance = new Setting<>(0);
|
||||
public final Setting<Boolean> layerOrder = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* What direction to repeat the build in
|
||||
* How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely
|
||||
*/
|
||||
public final Setting<EnumFacing> buildRepeatDirection = new Setting<>(EnumFacing.NORTH);
|
||||
public final Setting<Vec3i> buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
|
||||
|
||||
/**
|
||||
* Allow standing above a block while mining it, in BuilderProcess
|
||||
* <p>
|
||||
* Experimental
|
||||
*/
|
||||
public final Setting<Boolean> breakFromAbove = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* As well as breaking from above, set a goal to up and to the side of all blocks to break.
|
||||
* <p>
|
||||
* Never turn this on without also turning on breakFromAbove.
|
||||
*/
|
||||
public final Setting<Boolean> goalBreakFromAbove = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
||||
@@ -717,13 +786,6 @@ public final class Settings {
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Turn this on if your exploration filter is enormous, you don't want it to check if it's done,
|
||||
* and you are just fine with it just hanging on completion
|
||||
@@ -757,7 +819,12 @@ public final class Settings {
|
||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||
* {@link Setting#value};
|
||||
*/
|
||||
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
|
||||
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getInstance().ingameGUI.getChatGUI()::printChatMessage);
|
||||
|
||||
/**
|
||||
* The size of the box that is rendered when the current goal is a GoalYLevel
|
||||
*/
|
||||
public final Setting<Double> yLevelBoxSize = new Setting<>(15D);
|
||||
|
||||
/**
|
||||
* The color of the current path
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package baritone.api.cache;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
@@ -26,9 +26,9 @@ import net.minecraft.util.math.BlockPos;
|
||||
*/
|
||||
public interface IBlockTypeAccess {
|
||||
|
||||
IBlockState getBlock(int x, int y, int z);
|
||||
BlockState getBlock(int x, int y, int z);
|
||||
|
||||
default IBlockState getBlock(BlockPos pos) {
|
||||
default BlockState getBlock(BlockPos pos) {
|
||||
return getBlock(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package baritone.api.event.events;
|
||||
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.IPacket;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -31,9 +31,9 @@ public final class PacketEvent {
|
||||
|
||||
private final EventState state;
|
||||
|
||||
private final Packet<?> packet;
|
||||
private final IPacket<?> packet;
|
||||
|
||||
public PacketEvent(NetworkManager networkManager, EventState state, Packet<?> packet) {
|
||||
public PacketEvent(NetworkManager networkManager, EventState state, IPacket<?> packet) {
|
||||
this.networkManager = networkManager;
|
||||
this.state = state;
|
||||
this.packet = packet;
|
||||
@@ -47,12 +47,12 @@ public final class PacketEvent {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public final Packet<?> getPacket() {
|
||||
public final IPacket<?> getPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <T extends Packet<?>> T cast() {
|
||||
public final <T extends IPacket<?>> T cast() {
|
||||
return (T) this.packet;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package baritone.api.event.events;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -76,7 +75,7 @@ public final class RotationMoveEvent {
|
||||
/**
|
||||
* Called when the player jumps.
|
||||
*
|
||||
* @see EntityLivingBase#jump
|
||||
* @see LivingEntity#jump
|
||||
*/
|
||||
JUMP
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
package baritone.api.event.events;
|
||||
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -29,14 +29,14 @@ public final class WorldEvent {
|
||||
/**
|
||||
* The new world that is being loaded. {@code null} if being unloaded.
|
||||
*/
|
||||
private final WorldClient world;
|
||||
private final ClientWorld world;
|
||||
|
||||
/**
|
||||
* The state of the event
|
||||
*/
|
||||
private final EventState state;
|
||||
|
||||
public WorldEvent(WorldClient world, EventState state) {
|
||||
public WorldEvent(ClientWorld world, EventState state) {
|
||||
this.world = world;
|
||||
this.state = state;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public final class WorldEvent {
|
||||
/**
|
||||
* @return The new world that is being loaded. {@code null} if being unloaded.
|
||||
*/
|
||||
public final WorldClient getWorld() {
|
||||
public final ClientWorld getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,12 @@
|
||||
package baritone.api.event.listener;
|
||||
|
||||
import baritone.api.event.events.*;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiGameOver;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.gui.screen.DeathScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.network.Packet;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -45,7 +43,7 @@ public interface IGameEventListener {
|
||||
* Run once per game tick from before and after the player rotation is sent to the server.
|
||||
*
|
||||
* @param event The event
|
||||
* @see EntityPlayerSP#onUpdate()
|
||||
* @see ClientPlayerEntity#tick()
|
||||
*/
|
||||
void onPlayerUpdate(PlayerUpdateEvent event);
|
||||
|
||||
@@ -53,7 +51,7 @@ public interface IGameEventListener {
|
||||
* Runs whenever the client player sends a message to the server.
|
||||
*
|
||||
* @param event The event
|
||||
* @see EntityPlayerSP#sendChatMessage(String)
|
||||
* @see ClientPlayerEntity#sendChatMessage(String)
|
||||
*/
|
||||
void onSendChatMessage(ChatEvent event);
|
||||
|
||||
@@ -61,14 +59,11 @@ public interface IGameEventListener {
|
||||
* Runs before and after whenever a chunk is either loaded, unloaded, or populated.
|
||||
*
|
||||
* @param event The event
|
||||
* @see WorldClient#doPreChunk(int, int, boolean)
|
||||
*/
|
||||
void onChunkEvent(ChunkEvent event);
|
||||
|
||||
/**
|
||||
* Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on.
|
||||
* <p>
|
||||
* <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13
|
||||
* Runs once per world render pass.
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
@@ -78,7 +73,7 @@ public interface IGameEventListener {
|
||||
* Runs before and after whenever a new world is loaded
|
||||
*
|
||||
* @param event The event
|
||||
* @see Minecraft#loadWorld(WorldClient, String)
|
||||
* @see Minecraft#loadWorld(ClientWorld, Screen)
|
||||
*/
|
||||
void onWorldEvent(WorldEvent event);
|
||||
|
||||
@@ -87,7 +82,6 @@ public interface IGameEventListener {
|
||||
*
|
||||
* @param event The event
|
||||
* @see Packet
|
||||
* @see GenericFutureListener
|
||||
*/
|
||||
void onSendPacket(PacketEvent event);
|
||||
|
||||
@@ -96,7 +90,6 @@ public interface IGameEventListener {
|
||||
*
|
||||
* @param event The event
|
||||
* @see Packet
|
||||
* @see GenericFutureListener
|
||||
*/
|
||||
void onReceivePacket(PacketEvent event);
|
||||
|
||||
@@ -110,10 +103,10 @@ public interface IGameEventListener {
|
||||
void onPlayerRotationMove(RotationMoveEvent event);
|
||||
|
||||
/**
|
||||
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate}
|
||||
* Called whenever the sprint keybind state is checked in {@link ClientPlayerEntity#livingTick}
|
||||
*
|
||||
* @param event The event
|
||||
* @see EntityPlayerSP#onLivingUpdate()
|
||||
* @see ClientPlayerEntity#livingTick()
|
||||
*/
|
||||
void onPlayerSprintState(SprintStateEvent event);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ public class GoalStrictDirection implements Goal {
|
||||
public final int dx;
|
||||
public final int dz;
|
||||
|
||||
public GoalStrictDirection(BlockPos origin, EnumFacing direction) {
|
||||
public GoalStrictDirection(BlockPos origin, Direction direction) {
|
||||
x = origin.getX();
|
||||
y = origin.getY();
|
||||
z = origin.getZ();
|
||||
|
||||
@@ -29,7 +29,7 @@ public class GoalYLevel implements Goal, ActionCosts {
|
||||
/**
|
||||
* The target Y level
|
||||
*/
|
||||
private final int level;
|
||||
public final int level;
|
||||
|
||||
public GoalYLevel(int level) {
|
||||
this.level = level;
|
||||
|
||||
@@ -50,10 +50,12 @@ public interface IBuilderProcess extends IBaritoneProcess {
|
||||
boolean build(String name, File schematic, Vec3i origin);
|
||||
|
||||
default boolean build(String schematicFile, BlockPos origin) {
|
||||
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
|
||||
File file = new File(new File(Minecraft.getInstance().gameDir, "schematics"), schematicFile);
|
||||
return build(schematicFile, file, origin);
|
||||
}
|
||||
|
||||
void buildOpenSchematic();
|
||||
|
||||
void pause();
|
||||
|
||||
void resume();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
@@ -61,6 +61,8 @@ public final class BetterBlockPos extends BlockPos {
|
||||
}
|
||||
|
||||
public static long longHash(int x, int y, int z) {
|
||||
// TODO use the same thing as BlockPos.fromLong();
|
||||
// invertibility would be incredibly useful
|
||||
/*
|
||||
* This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name)
|
||||
*
|
||||
@@ -99,10 +101,10 @@ public final class BetterBlockPos extends BlockPos {
|
||||
// this is unimaginably faster than blockpos.up
|
||||
// that literally calls
|
||||
// this.up(1)
|
||||
// which calls this.offset(EnumFacing.UP, 1)
|
||||
// which calls this.offset(Direction.UP, 1)
|
||||
// which does return n == 0 ? this : new BlockPos(this.getX() + facing.getXOffset() * n, this.getY() + facing.getYOffset() * n, this.getZ() + facing.getZOffset() * n);
|
||||
|
||||
// how many function calls is that? up(), up(int), offset(EnumFacing, int), new BlockPos, getX, getXOffset, getY, getYOffset, getZ, getZOffset
|
||||
// how many function calls is that? up(), up(int), offset(Direction, int), new BlockPos, getX, getXOffset, getY, getYOffset, getZ, getZOffset
|
||||
// that's ten.
|
||||
// this is one function call.
|
||||
return new BetterBlockPos(x, y + 1, z);
|
||||
@@ -127,13 +129,13 @@ public final class BetterBlockPos extends BlockPos {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BetterBlockPos offset(EnumFacing dir) {
|
||||
public BetterBlockPos offset(Direction dir) {
|
||||
Vec3i vec = dir.getDirectionVec();
|
||||
return new BetterBlockPos(x + vec.getX(), y + vec.getY(), z + vec.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BetterBlockPos offset(EnumFacing dir, int dist) {
|
||||
public BetterBlockPos offset(Direction dir, int dist) {
|
||||
if (dist == 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.block.AirBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -28,7 +30,7 @@ public class BlockUtils {
|
||||
private static transient Map<String, Block> resourceCache = new HashMap<>();
|
||||
|
||||
public static String blockToString(Block block) {
|
||||
ResourceLocation loc = Block.REGISTRY.getNameForObject(block);
|
||||
ResourceLocation loc = Registry.BLOCK.getKey(block);
|
||||
String name = loc.getPath(); // normally, only write the part after the minecraft:
|
||||
if (!loc.getNamespace().equals("minecraft")) {
|
||||
// Baritone is running on top of forge with mods installed, perhaps?
|
||||
@@ -52,7 +54,10 @@ public class BlockUtils {
|
||||
if (resourceCache.containsKey(name)) {
|
||||
return null; // cached as null
|
||||
}
|
||||
block = Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
|
||||
block = Registry.BLOCK.getOrDefault(ResourceLocation.tryCreate(name.contains(":") ? name : "minecraft:" + name));
|
||||
if (block instanceof AirBlock && !name.equals("air")) {
|
||||
block = null;
|
||||
}
|
||||
Map<String, Block> copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification
|
||||
copy.put(name, block);
|
||||
resourceCache = copy;
|
||||
|
||||
@@ -32,48 +32,26 @@ import baritone.api.process.ICustomGoalProcess;
|
||||
import baritone.api.process.IGetToBlockProcess;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.event.ClickEvent;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNumeric;
|
||||
|
||||
public class ExampleBaritoneControl implements Helper, AbstractGameEventListener {
|
||||
|
||||
private static final String HELP_MSG =
|
||||
"baritone - Output settings into chat\n" +
|
||||
"settings - Same as baritone\n" +
|
||||
"goal - Create a goal (one number is '<Y>', two is '<X> <Z>', three is '<X> <Y> <Z>, 'clear' to clear)\n" +
|
||||
"path - Go towards goal\n" +
|
||||
"repack - (debug) Repacks chunk cache\n" +
|
||||
"rescan - (debug) Same as repack\n" +
|
||||
"axis - Paths towards the closest axis or diagonal axis, at y=120\n" +
|
||||
"cancel - Cancels current path\n" +
|
||||
"forcecancel - sudo cancel (only use if very glitched, try toggling 'pause' first)\n" +
|
||||
"gc - Calls System.gc();\n" +
|
||||
"invert - Runs away from the goal instead of towards it\n" +
|
||||
"follow - Follows a player 'follow username'\n" +
|
||||
"reloadall - (debug) Reloads chunk cache\n" +
|
||||
"saveall - (debug) Saves chunk cache\n" +
|
||||
"find - (debug) outputs how many blocks of a certain type are within the cache\n" +
|
||||
"mine - Paths to and mines specified blocks 'mine x_ore y_ore ...'\n" +
|
||||
"thisway - Creates a goal X blocks where you're facing\n" +
|
||||
"list - Lists waypoints under a category\n" +
|
||||
"get - Same as list\n" +
|
||||
"show - Same as list\n" +
|
||||
"save - Saves a waypoint (works but don't try to make sense of it)\n" +
|
||||
"goto - Paths towards specified block or waypoint\n" +
|
||||
"spawn - Paths towards world spawn or your most recent bed right-click\n" +
|
||||
"sethome - Sets \"home\"\n" +
|
||||
"home - Paths towards \"home\" \n" +
|
||||
"costs - (debug) all movement costs from current location\n" +
|
||||
"damn - Daniel\n" +
|
||||
"Go to https://github.com/cabaletta/baritone/blob/master/USAGE.md for more information";
|
||||
|
||||
private static final String COMMAND_PREFIX = "#";
|
||||
|
||||
public final IBaritone baritone;
|
||||
@@ -144,9 +122,12 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
|
||||
for (String line : HELP_MSG.split("\n")) {
|
||||
logDirect(line);
|
||||
}
|
||||
ITextComponent component = MESSAGE_PREFIX.shallowCopy();
|
||||
component.getStyle().setColor(TextFormatting.GRAY);
|
||||
StringTextComponent helpLink = new StringTextComponent(" Click here for instructions on how to use Baritone (https://github.com/cabaletta/baritone/blob/master/USAGE.md)");
|
||||
helpLink.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/cabaletta/baritone/blob/master/USAGE.md"));
|
||||
component.appendSibling(helpLink);
|
||||
BaritoneAPI.getSettings().logger.value.accept(component);
|
||||
return true;
|
||||
}
|
||||
if (msg.contains(" ")) {
|
||||
@@ -195,6 +176,16 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
logDirect("Goal: " + goal);
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("crash")) {
|
||||
StringBuilder meme = new StringBuilder();
|
||||
CrashReport rep = new CrashReport("Manually triggered debug crash", new Throwable());
|
||||
mc.addGraphicsAndWorldToCrashReport(rep);
|
||||
rep.getSectionsInStringBuilder(meme);
|
||||
System.out.println(meme);
|
||||
logDirect(meme.toString());
|
||||
logDirect("ok");
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("path")) {
|
||||
if (pathingBehavior.getGoal() == null) {
|
||||
logDirect("No goal.");
|
||||
@@ -207,23 +198,6 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*if (msg.equals("fullpath")) {
|
||||
if (pathingBehavior.getGoal() == null) {
|
||||
logDirect("No goal.");
|
||||
} else {
|
||||
logDirect("Started segmented calculator");
|
||||
SegmentedCalculator.calculateSegmentsThreaded(pathingBehavior.pathStart(), pathingBehavior.getGoal(), new CalculationContext(baritone, true), ipath -> {
|
||||
logDirect("Found a path");
|
||||
logDirect("Ends at " + ipath.getDest());
|
||||
logDirect("Length " + ipath.length());
|
||||
logDirect("Estimated time " + ipath.ticksRemainingFrom(0));
|
||||
pathingBehavior.secretCursedFunctionDoNotCall(ipath); // it's okay when *I* do it
|
||||
}, () -> {
|
||||
logDirect("Path calculation failed, no path");
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}*/
|
||||
if (msg.equals("proc")) {
|
||||
Optional<IBaritoneProcess> proc = baritone.getPathingControlManager().mostRecentInControl();
|
||||
if (!proc.isPresent()) {
|
||||
@@ -248,13 +222,13 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("repack") || msg.equals("rescan")) {
|
||||
ChunkProviderClient cli = (ChunkProviderClient) ctx.world().getChunkProvider();
|
||||
ClientChunkProvider cli = (ClientChunkProvider) ctx.world().getChunkProvider();
|
||||
int playerChunkX = ctx.playerFeet().getX() >> 4;
|
||||
int playerChunkZ = ctx.playerFeet().getZ() >> 4;
|
||||
int count = 0;
|
||||
for (int x = playerChunkX - 40; x <= playerChunkX + 40; x++) {
|
||||
for (int z = playerChunkZ - 40; z <= playerChunkZ + 40; z++) {
|
||||
Chunk chunk = cli.getLoadedChunk(x, z);
|
||||
Chunk chunk = cli.getChunk(x, z, null, false);
|
||||
if (chunk != null) {
|
||||
count++;
|
||||
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().queueForPacking(chunk);
|
||||
@@ -270,7 +244,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
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));
|
||||
origin = new BlockPos(parseOrDefault(coords[1], ctx.playerFeet().x, 1), parseOrDefault(coords[2], ctx.playerFeet().y, 1), parseOrDefault(coords[3], ctx.playerFeet().z, 1));
|
||||
} catch (Exception ex) {
|
||||
file = msg.substring(5).trim() + ".schematic";
|
||||
origin = ctx.playerFeet();
|
||||
@@ -280,6 +254,10 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
logDirect(success ? "Loaded" : "Unable to load");
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("schematica")) {
|
||||
baritone.getBuilderProcess().buildOpenSchematic();
|
||||
return true;
|
||||
}
|
||||
if (msg.equals("come")) {
|
||||
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(Helper.mc.getRenderViewEntity())));
|
||||
logDirect("Coming");
|
||||
@@ -332,7 +310,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
if (suffix.isEmpty()) {
|
||||
// clear the area from the current goal to here
|
||||
Goal goal = baritone.getPathingBehavior().getGoal();
|
||||
if (goal == null || !(goal instanceof GoalBlock)) {
|
||||
if (!(goal instanceof GoalBlock)) {
|
||||
logDirect("Need to specify goal of opposite corner");
|
||||
return true;
|
||||
}
|
||||
@@ -376,7 +354,8 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
}
|
||||
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);
|
||||
int dist = (Minecraft.getInstance().gameSettings.renderDistanceChunks + 1) * 16;
|
||||
Minecraft.getInstance().worldRenderer.markBlockRangeForRenderUpdate(pf.x - dist, pf.y - 256, pf.z - dist, pf.x + dist, pf.y + 256, pf.z + dist);
|
||||
logDirect("okay");
|
||||
return true;
|
||||
}
|
||||
@@ -385,17 +364,6 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
logDirect("farming");
|
||||
return true;
|
||||
}
|
||||
// this literally doesn't work, memory is disabled lol
|
||||
/*if (msg.equals("echest")) {
|
||||
Optional<List<ItemStack>> contents = baritone.getMemoryBehavior().echest();
|
||||
if (contents.isPresent()) {
|
||||
logDirect("echest contents:");
|
||||
log(contents.get());
|
||||
} else {
|
||||
logDirect("echest contents unknown");
|
||||
}
|
||||
return true;
|
||||
}*/
|
||||
if (msg.equals("chests")) {
|
||||
for (Map.Entry<BlockPos, IRememberedInventory> entry : baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet()) {
|
||||
logDirect(entry.getKey() + "");
|
||||
@@ -403,20 +371,43 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("followentities")) {
|
||||
baritone.getFollowProcess().follow(Entity.class::isInstance);
|
||||
logDirect("Following any entities");
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("followplayers")) {
|
||||
baritone.getFollowProcess().follow(EntityPlayer.class::isInstance); // O P P A
|
||||
baritone.getFollowProcess().follow(PlayerEntity.class::isInstance); // O P P A
|
||||
logDirect("Following any players");
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("followentity")) {
|
||||
String name = msg.substring(12).trim();
|
||||
Optional<Entity> toFollow = Optional.empty();
|
||||
for (Entity entity : ctx.entities()) {
|
||||
String entityName = entity.getName().getFormattedText().trim().toLowerCase();
|
||||
if ((entityName.contains(name) || name.contains(entityName)) && !(entity instanceof ItemEntity || entity instanceof PlayerEntity)) { // We dont want it following players while `#follow` exists.
|
||||
toFollow = Optional.of(entity);
|
||||
}
|
||||
}
|
||||
if (!toFollow.isPresent()) {
|
||||
logDirect("Entity not found");
|
||||
return true;
|
||||
}
|
||||
Entity effectivelyFinal = toFollow.get();
|
||||
baritone.getFollowProcess().follow(effectivelyFinal::equals);
|
||||
logDirect("Following entity " + toFollow.get());
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("follow")) {
|
||||
String name = msg.substring(6).trim();
|
||||
Optional<Entity> toFollow = Optional.empty();
|
||||
if (name.length() == 0) {
|
||||
toFollow = ctx.getSelectedEntity();
|
||||
} else {
|
||||
for (EntityPlayer pl : ctx.world().playerEntities) {
|
||||
String theirName = pl.getName().trim().toLowerCase();
|
||||
if (!theirName.equals(ctx.player().getName().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
|
||||
for (PlayerEntity pl : ctx.world().getPlayers()) {
|
||||
String theirName = pl.getName().getString().trim().toLowerCase();
|
||||
if (!theirName.equals(ctx.player().getName().getString().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
|
||||
toFollow = Optional.of(pl);
|
||||
}
|
||||
}
|
||||
@@ -426,7 +417,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
return true;
|
||||
}
|
||||
Entity effectivelyFinal = toFollow.get();
|
||||
baritone.getFollowProcess().follow(x -> effectivelyFinal.equals(x));
|
||||
baritone.getFollowProcess().follow(effectivelyFinal::equals);
|
||||
logDirect("Following " + toFollow.get());
|
||||
return true;
|
||||
}
|
||||
@@ -437,7 +428,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
// means that entries in blah.json are NOT already explored
|
||||
String path = msg.substring("explorefilter".length()).trim();
|
||||
String[] parts = path.split(" ");
|
||||
Path path1 = Minecraft.getMinecraft().gameDir.toPath().resolve(parts[0]);
|
||||
Path path1 = Minecraft.getInstance().gameDir.toPath().resolve(parts[0]);
|
||||
boolean invert = parts.length > 1;
|
||||
try {
|
||||
baritone.getExploreProcess().applyJsonFilter(path1, invert);
|
||||
@@ -581,6 +572,17 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("delete")) {
|
||||
String name = msg.substring(6).trim();
|
||||
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getTag() == IWaypoint.Tag.USER && w.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
|
||||
if (waypoint == null) {
|
||||
logDirect("No user defined position under the name '" + name + "' found.");
|
||||
return true;
|
||||
}
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().removeWaypoint(waypoint);
|
||||
logDirect("Deleted user defined position under name '" + name + "'.");
|
||||
return true;
|
||||
}
|
||||
if (msg.startsWith("goto")) {
|
||||
String waypointType = msg.substring(4).trim();
|
||||
if (waypointType.endsWith("s") && IWaypoint.Tag.fromString(waypointType.substring(0, waypointType.length() - 1)) != null) {
|
||||
@@ -649,38 +651,20 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// this is completely impossible from api
|
||||
/*if (msg.equals("costs")) {
|
||||
List<Movement> moves = Stream.of(Moves.values()).map(x -> x.apply0(new CalculationContext(baritone), ctx.playerFeet())).collect(Collectors.toCollection(ArrayList::new));
|
||||
while (moves.contains(null)) {
|
||||
moves.remove(null);
|
||||
}
|
||||
moves.sort(Comparator.comparingDouble(move -> move.getCost(new CalculationContext(baritone))));
|
||||
for (Movement move : moves) {
|
||||
String[] parts = move.getClass().toString().split("\\.");
|
||||
double cost = move.getCost();
|
||||
String strCost = cost + "";
|
||||
if (cost >= ActionCosts.COST_INF) {
|
||||
strCost = "IMPOSSIBLE";
|
||||
}
|
||||
logDirect(parts[parts.length - 1] + " " + move.getDest().getX() + "," + move.getDest().getY() + "," + move.getDest().getZ() + " " + strCost);
|
||||
}
|
||||
return true;
|
||||
}*/
|
||||
if (msg.equals("damn")) {
|
||||
logDirect("daniel");
|
||||
}
|
||||
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 int parseOrDefault(String str, int i, double dimensionFactor) {
|
||||
return str.equals("~") ? i : str.startsWith("~") ? (int) (Integer.parseInt(str.substring(1)) * dimensionFactor) + i : (int) (Integer.parseInt(str) * dimensionFactor);
|
||||
}
|
||||
|
||||
private void log(List<ItemStack> stacks) {
|
||||
for (ItemStack stack : stacks) {
|
||||
if (!stack.isEmpty()) {
|
||||
logDirect(stack.getCount() + "x " + stack.getDisplayName() + "@" + stack.getItemDamage());
|
||||
logDirect(stack.getCount() + "x " + stack.getDisplayName() + "@" + stack.getDamage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -688,18 +672,24 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
private Goal parseGoal(String[] params) {
|
||||
Goal goal;
|
||||
try {
|
||||
switch (params.length) {
|
||||
BetterBlockPos playerFeet = ctx.playerFeet();
|
||||
|
||||
int length = params.length - 1; // length has to be smaller when a dimension parameter is added
|
||||
if (params.length < 1 || (isNumeric(params[params.length - 1]) || params[params.length - 1].startsWith("~"))) {
|
||||
length = params.length;
|
||||
}
|
||||
switch (length) {
|
||||
case 0:
|
||||
goal = new GoalBlock(ctx.playerFeet());
|
||||
goal = new GoalBlock(playerFeet);
|
||||
break;
|
||||
case 1:
|
||||
goal = new GoalYLevel(Integer.parseInt(params[0]));
|
||||
goal = new GoalYLevel(parseOrDefault(params[0], playerFeet.y, 1));
|
||||
break;
|
||||
case 2:
|
||||
goal = new GoalXZ(Integer.parseInt(params[0]), Integer.parseInt(params[1]));
|
||||
goal = new GoalXZ(parseOrDefault(params[0], playerFeet.x, calculateDimensionFactor(params[params.length - 1])), parseOrDefault(params[1], playerFeet.z, calculateDimensionFactor(params[params.length - 1])));
|
||||
break;
|
||||
case 3:
|
||||
goal = new GoalBlock(new BlockPos(Integer.parseInt(params[0]), Integer.parseInt(params[1]), Integer.parseInt(params[2])));
|
||||
goal = new GoalBlock(new BlockPos(parseOrDefault(params[0], playerFeet.x, calculateDimensionFactor(params[params.length - 1])), parseOrDefault(params[1], playerFeet.y, 1), parseOrDefault(params[2], playerFeet.z, calculateDimensionFactor(params[params.length - 1]))));
|
||||
break;
|
||||
default:
|
||||
logDirect("unable to understand lol");
|
||||
@@ -711,4 +701,23 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
}
|
||||
return goal;
|
||||
}
|
||||
|
||||
|
||||
private double calculateDimensionFactor(String to) {
|
||||
return Math.pow(8, ctx.world().dimension.getType().getId() - getDimensionByName(to.toLowerCase()).getId());
|
||||
}
|
||||
|
||||
private DimensionType getDimensionByName(String name) {
|
||||
if ("the_end".contains(name)) {
|
||||
return DimensionType.THE_END;
|
||||
}
|
||||
if ("the_overworld".contains(name) || "surface".contains(name)) {
|
||||
return DimensionType.OVERWORLD;
|
||||
}
|
||||
if ("the_nether".contains(name) || "hell".contains(name)) {
|
||||
return DimensionType.THE_NETHER;
|
||||
}
|
||||
return ctx.world().dimension.getType();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ package baritone.api.utils;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ public interface Helper {
|
||||
*/
|
||||
Helper HELPER = new Helper() {};
|
||||
|
||||
ITextComponent MESSAGE_PREFIX = new TextComponentString(String.format(
|
||||
ITextComponent MESSAGE_PREFIX = new StringTextComponent(String.format(
|
||||
"%s[%sBaritone%s]%s",
|
||||
TextFormatting.DARK_PURPLE,
|
||||
TextFormatting.LIGHT_PURPLE,
|
||||
@@ -42,7 +42,7 @@ public interface Helper {
|
||||
TextFormatting.GRAY
|
||||
));
|
||||
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
/**
|
||||
* Send a message to chat only if chatDebug is on
|
||||
@@ -64,9 +64,9 @@ public interface Helper {
|
||||
* @param message The message to display in chat
|
||||
*/
|
||||
default void logDirect(String message) {
|
||||
ITextComponent component = MESSAGE_PREFIX.createCopy();
|
||||
ITextComponent component = MESSAGE_PREFIX.shallowCopy();
|
||||
component.getStyle().setColor(TextFormatting.GRAY);
|
||||
component.appendSibling(new TextComponentString(" " + message));
|
||||
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
|
||||
component.appendSibling(new StringTextComponent(" " + message));
|
||||
Minecraft.getInstance().execute(() -> BaritoneAPI.getSettings().logger.value.accept(component));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,15 +18,16 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.cache.IWorldData;
|
||||
import net.minecraft.block.BlockSlab;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -34,12 +35,21 @@ import java.util.Optional;
|
||||
*/
|
||||
public interface IPlayerContext {
|
||||
|
||||
EntityPlayerSP player();
|
||||
ClientPlayerEntity player();
|
||||
|
||||
IPlayerController playerController();
|
||||
|
||||
World world();
|
||||
|
||||
default Iterable<Entity> entities() {
|
||||
return ((ClientWorld) world()).getAllEntities();
|
||||
}
|
||||
|
||||
default Stream<Entity> entitiesStream() {
|
||||
return StreamSupport.stream(entities().spliterator(), false);
|
||||
}
|
||||
|
||||
|
||||
IWorldData worldData();
|
||||
|
||||
RayTraceResult objectMouseOver();
|
||||
@@ -47,7 +57,7 @@ public interface IPlayerContext {
|
||||
default BetterBlockPos playerFeet() {
|
||||
// TODO find a better way to deal with soul sand!!!!!
|
||||
BetterBlockPos feet = new BetterBlockPos(player().posX, player().posY + 0.1251, player().posZ);
|
||||
if (world().getBlockState(feet).getBlock() instanceof BlockSlab) {
|
||||
if (world().getBlockState(feet).getBlock() instanceof SlabBlock) {
|
||||
return feet.up();
|
||||
}
|
||||
return feet;
|
||||
@@ -72,8 +82,8 @@ public interface IPlayerContext {
|
||||
*/
|
||||
default Optional<BlockPos> getSelectedBlock() {
|
||||
RayTraceResult result = objectMouseOver();
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
return Optional.of(result.getBlockPos());
|
||||
if (result != null && result.getType() == RayTraceResult.Type.BLOCK) {
|
||||
return Optional.of(((BlockRayTraceResult) result).getPos());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -89,8 +99,8 @@ public interface IPlayerContext {
|
||||
*/
|
||||
default Optional<Entity> getSelectedEntity() {
|
||||
RayTraceResult result = objectMouseOver();
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.ENTITY) {
|
||||
return Optional.of(result.entityHit);
|
||||
if (result != null && result.getType() == RayTraceResult.Type.ENTITY) {
|
||||
return Optional.of(((EntityRayTraceResult) result).getEntity());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -17,14 +17,15 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.ClickType;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.container.ClickType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.World;
|
||||
@@ -35,11 +36,11 @@ import net.minecraft.world.World;
|
||||
*/
|
||||
public interface IPlayerController {
|
||||
|
||||
boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side);
|
||||
boolean onPlayerDamageBlock(BlockPos pos, Direction side);
|
||||
|
||||
void resetBlockRemoving();
|
||||
|
||||
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
|
||||
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, PlayerEntity player);
|
||||
|
||||
void setGameType(GameType type);
|
||||
|
||||
@@ -49,7 +50,7 @@ public interface IPlayerController {
|
||||
return this.getGameType().isCreative() ? 5.0F : 4.5F;
|
||||
}
|
||||
|
||||
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
|
||||
ActionResultType processRightClickBlock(ClientPlayerEntity player, World world, Hand hand, BlockRayTraceResult result);
|
||||
|
||||
EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand);
|
||||
ActionResultType processRightClick(ClientPlayerEntity player, World world, Hand hand);
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
/**
|
||||
* Basic representation of a schematic. Provides the dimensions and
|
||||
@@ -45,7 +45,7 @@ public interface ISchematic {
|
||||
return x >= 0 && x < widthX() && y >= 0 && y < heightY() && z >= 0 && z < lengthZ();
|
||||
}
|
||||
|
||||
default int size(EnumFacing.Axis axis) {
|
||||
default int size(Direction.Axis axis) {
|
||||
switch (axis) {
|
||||
case X:
|
||||
return widthX();
|
||||
@@ -66,7 +66,7 @@ public interface ISchematic {
|
||||
* @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);
|
||||
BlockState desiredState(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* @return The width (X axis length) of this schematic
|
||||
@@ -82,4 +82,4 @@ public interface ISchematic {
|
||||
* @return The length (Z axis length) of this schematic
|
||||
*/
|
||||
int lengthZ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,21 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Need a non obfed chunkpos that we can load using GSON
|
||||
*/
|
||||
public class MyChunkPos {
|
||||
|
||||
@SerializedName("x")
|
||||
public int x;
|
||||
|
||||
@SerializedName("z")
|
||||
public int z;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return x + ", " + z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.RayTraceContext;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
@@ -40,13 +41,13 @@ public final class RayTraceUtils {
|
||||
* @return The calculated raytrace result
|
||||
*/
|
||||
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
|
||||
Vec3d start = entity.getPositionEyes(1.0F);
|
||||
Vec3d start = entity.getEyePosition(1.0F);
|
||||
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
||||
Vec3d end = start.add(
|
||||
direction.x * blockReachDistance,
|
||||
direction.y * blockReachDistance,
|
||||
direction.z * blockReachDistance
|
||||
);
|
||||
return entity.world.rayTraceBlocks(start, end, false, false, true);
|
||||
return entity.world.rayTraceBlocks(new RayTraceContext(start, end, RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, entity));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ public class Rotation {
|
||||
public Rotation(float yaw, float pitch) {
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
if (Float.isInfinite(yaw) || Float.isNaN(yaw) || Float.isInfinite(pitch) || Float.isNaN(pitch)) {
|
||||
throw new IllegalStateException(yaw + " " + pitch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,11 +19,14 @@ package baritone.api.utils;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FireBlock;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -134,7 +137,7 @@ public final class RotationUtils {
|
||||
* @param ctx Context for the viewing entity
|
||||
* @param pos The target block position
|
||||
* @return The optional rotation
|
||||
* @see #reachable(EntityPlayerSP, BlockPos, double)
|
||||
* @see #reachable(ClientPlayerEntity, BlockPos, double)
|
||||
*/
|
||||
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos) {
|
||||
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
|
||||
@@ -152,9 +155,9 @@ public final class RotationUtils {
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
|
||||
public static Optional<Rotation> reachable(ClientPlayerEntity entity, BlockPos pos, double blockReachDistance) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
|
||||
if (pos.equals(baritone.getPlayerContext().getSelectedBlock().orElse(null))) {
|
||||
if (baritone.getPlayerContext().isLookingAt(pos)) {
|
||||
/*
|
||||
* why add 0.0001?
|
||||
* to indicate that we actually have a desired pitch
|
||||
@@ -173,12 +176,15 @@ public final class RotationUtils {
|
||||
return possibleRotation;
|
||||
}
|
||||
|
||||
IBlockState state = entity.world.getBlockState(pos);
|
||||
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
||||
BlockState state = entity.world.getBlockState(pos);
|
||||
VoxelShape shape = state.getShape(entity.world, pos);
|
||||
if (shape.isEmpty()) {
|
||||
shape = VoxelShapes.fullCube();
|
||||
}
|
||||
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
||||
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
||||
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
||||
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
||||
double xDiff = shape.getStart(Direction.Axis.X) * sideOffset.x + shape.getEnd(Direction.Axis.X) * (1 - sideOffset.x);
|
||||
double yDiff = shape.getStart(Direction.Axis.Y) * sideOffset.y + shape.getEnd(Direction.Axis.Y) * (1 - sideOffset.y);
|
||||
double zDiff = shape.getStart(Direction.Axis.Z) * sideOffset.z + shape.getEnd(Direction.Axis.Z) * (1 - sideOffset.z);
|
||||
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
@@ -199,14 +205,14 @@ public final class RotationUtils {
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
||||
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
|
||||
Rotation rotation = calcRotationFromVec3d(entity.getEyePosition(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
|
||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
||||
//System.out.println(result);
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
if (result.getBlockPos().equals(pos)) {
|
||||
if (result != null && result.getType() == RayTraceResult.Type.BLOCK) {
|
||||
if (((BlockRayTraceResult) result).getPos().equals(pos)) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) {
|
||||
if (entity.world.getBlockState(pos).getBlock() instanceof FireBlock && ((BlockRayTraceResult) result).getPos().equals(pos.down())) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,12 @@ package baritone.api.utils;
|
||||
|
||||
import baritone.api.Settings;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
@@ -29,23 +33,24 @@ import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraft.client.Minecraft.getMinecraft;
|
||||
|
||||
public class SettingsUtil {
|
||||
|
||||
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
|
||||
private static final Path SETTINGS_PATH = Minecraft.getInstance().gameDir.toPath().resolve("baritone").resolve("settings.txt");
|
||||
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
|
||||
|
||||
|
||||
private static boolean isComment(String line) {
|
||||
return line.startsWith("#") || line.startsWith("//");
|
||||
}
|
||||
@@ -80,6 +85,8 @@ public class SettingsUtil {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
} catch (NoSuchFileException ignored) {
|
||||
System.out.println("Baritone settings file not found, resetting.");
|
||||
} catch (Exception ex) {
|
||||
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
|
||||
ex.printStackTrace();
|
||||
@@ -153,11 +160,11 @@ public class SettingsUtil {
|
||||
|
||||
private final Settings.Setting<?> setting;
|
||||
|
||||
public ParserContext(Settings.Setting<?> setting) {
|
||||
private ParserContext(Settings.Setting<?> setting) {
|
||||
this.setting = setting;
|
||||
}
|
||||
|
||||
final Settings.Setting<?> getSetting() {
|
||||
private Settings.Setting<?> getSetting() {
|
||||
return this.setting;
|
||||
}
|
||||
}
|
||||
@@ -169,12 +176,17 @@ public class SettingsUtil {
|
||||
INTEGER(Integer.class, Integer::parseInt),
|
||||
FLOAT(Float.class, Float::parseFloat),
|
||||
LONG(Long.class, Long::parseLong),
|
||||
ENUMFACING(EnumFacing.class, EnumFacing::byName),
|
||||
ENUMFACING(Direction.class, Direction::byName),
|
||||
COLOR(
|
||||
Color.class,
|
||||
str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
|
||||
color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue()
|
||||
),
|
||||
VEC3I(
|
||||
Vec3i.class,
|
||||
str -> new Vec3i(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
|
||||
vec -> vec.getX() + "," + vec.getY() + "," + vec.getZ()
|
||||
),
|
||||
BLOCK(
|
||||
Block.class,
|
||||
str -> BlockUtils.stringToBlockRequired(str.trim()),
|
||||
@@ -182,15 +194,14 @@ public class SettingsUtil {
|
||||
),
|
||||
ITEM(
|
||||
Item.class,
|
||||
str -> Item.getByNameOrId(str.trim()),
|
||||
item -> Item.REGISTRY.getNameForObject(item).toString()
|
||||
str -> Registry.ITEM.getOrDefault(new ResourceLocation(str.trim())), // TODO this now returns AIR on failure instead of null, is that an issue?
|
||||
item -> Registry.ITEM.getKey(item).toString()
|
||||
),
|
||||
LIST() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
|
||||
return Arrays.stream(raw.split(","))
|
||||
.map(s -> parser.parse(context, s))
|
||||
.collect(Collectors.toList());
|
||||
@@ -234,7 +245,9 @@ public class SettingsUtil {
|
||||
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
return this.parser.apply(raw);
|
||||
Object parsed = this.parser.apply(raw);
|
||||
Objects.requireNonNull(parsed);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FireBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
@@ -42,12 +43,18 @@ public final class VecUtils {
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
|
||||
IBlockState b = world.getBlockState(pos);
|
||||
AxisAlignedBB bbox = b.getBoundingBox(world, pos);
|
||||
double xDiff = (bbox.minX + bbox.maxX) / 2;
|
||||
double yDiff = (bbox.minY + bbox.maxY) / 2;
|
||||
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
|
||||
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
|
||||
BlockState b = world.getBlockState(pos);
|
||||
VoxelShape shape = b.getCollisionShape(world, pos);
|
||||
if (shape.isEmpty()) {
|
||||
return getBlockPosCenter(pos);
|
||||
}
|
||||
double xDiff = (shape.getStart(Direction.Axis.X) + shape.getEnd(Direction.Axis.X)) / 2;
|
||||
double yDiff = (shape.getStart(Direction.Axis.Y) + shape.getEnd(Direction.Axis.Y)) / 2;
|
||||
double zDiff = (shape.getStart(Direction.Axis.Z) + shape.getEnd(Direction.Axis.Z)) / 2;
|
||||
if (Double.isNaN(xDiff) || Double.isNaN(yDiff) || Double.isNaN(zDiff)) {
|
||||
throw new IllegalStateException(b + " " + pos + " " + shape);
|
||||
}
|
||||
if (b.getBlock() instanceof FireBlock) {//look at bottom of fire when putting it out
|
||||
yDiff = 0;
|
||||
}
|
||||
return new Vec3d(
|
||||
|
||||
105
src/launch/java/baritone/launch/LaunchTesting.java
Normal file
105
src/launch/java/baritone/launch/LaunchTesting.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mojang.authlib.Agent;
|
||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Based on GradleStart from ForgeGradle 2.3
|
||||
*
|
||||
* @author Brady
|
||||
* @since 3/11/2019
|
||||
*/
|
||||
public class LaunchTesting {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Map<String, String> arguments = new HashMap<>();
|
||||
|
||||
hackNatives();
|
||||
arguments.put("version", "BaritownedDeveloperEnvironment");
|
||||
arguments.put("assetIndex", System.getenv("assetIndex"));
|
||||
arguments.put("assetsDir", System.getenv().getOrDefault("assetDirectory", "assets"));
|
||||
arguments.put("accessToken", "FML");
|
||||
arguments.put("userProperties", "{}");
|
||||
arguments.put("tweakClass", System.getenv("tweakClass"));
|
||||
String password = System.getenv("password");
|
||||
if (password != null && !password.isEmpty()) {
|
||||
attemptLogin(arguments, System.getenv("username"), System.getenv("password"));
|
||||
}
|
||||
|
||||
List<String> argsArray = new ArrayList<>();
|
||||
arguments.forEach((k, v) -> {
|
||||
argsArray.add("--" + k);
|
||||
argsArray.add(v);
|
||||
});
|
||||
|
||||
Launch.main(argsArray.toArray(new String[0]));
|
||||
}
|
||||
|
||||
private static void hackNatives() {
|
||||
String paths = System.getProperty("java.library.path");
|
||||
String nativesDir = System.getenv().get("nativesDirectory");
|
||||
|
||||
if (Strings.isNullOrEmpty(paths))
|
||||
paths = nativesDir;
|
||||
else
|
||||
paths += File.pathSeparator + nativesDir;
|
||||
|
||||
System.setProperty("java.library.path", paths);
|
||||
|
||||
// hack the classloader now.
|
||||
try {
|
||||
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
|
||||
sysPathsField.setAccessible(true);
|
||||
sysPathsField.set(null, null);
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
private static void attemptLogin(Map<String, String> argMap, String username, String password) {
|
||||
YggdrasilUserAuthentication auth = (YggdrasilUserAuthentication) (new YggdrasilAuthenticationService(Proxy.NO_PROXY, "1")).createUserAuthentication(Agent.MINECRAFT);
|
||||
auth.setUsername(username);
|
||||
auth.setPassword(password);
|
||||
|
||||
try {
|
||||
auth.logIn();
|
||||
} catch (AuthenticationException var4) {
|
||||
throw new RuntimeException(var4);
|
||||
}
|
||||
|
||||
argMap.put("accessToken", auth.getAuthenticatedToken());
|
||||
argMap.put("uuid", auth.getSelectedProfile().getId().toString().replace("-", ""));
|
||||
argMap.put("username", auth.getSelectedProfile().getName());
|
||||
argMap.put("userType", auth.getUserType().getName());
|
||||
argMap.put("userProperties", (new GsonBuilder()).registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(auth.getUserProperties()));
|
||||
}
|
||||
}
|
||||
92
src/launch/java/baritone/launch/mixins/MixinChunkArray.java
Normal file
92
src/launch/java/baritone/launch/mixins/MixinChunkArray.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.utils.accessor.IChunkArray;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
|
||||
@Mixin(targets = "net.minecraft.client.multiplayer.ClientChunkProvider$ChunkArray")
|
||||
public abstract class MixinChunkArray implements IChunkArray {
|
||||
@Shadow
|
||||
private AtomicReferenceArray<Chunk> chunks;
|
||||
@Shadow
|
||||
private int viewDistance;
|
||||
@Shadow
|
||||
private int sideLength;
|
||||
@Shadow
|
||||
private int centerX;
|
||||
@Shadow
|
||||
private int centerZ;
|
||||
@Shadow
|
||||
private int loaded;
|
||||
|
||||
@Shadow
|
||||
protected abstract boolean inView(int x, int z);
|
||||
|
||||
@Shadow
|
||||
protected abstract int getIndex(int x, int z);
|
||||
|
||||
@Shadow
|
||||
protected abstract void replace(int index, Chunk chunk);
|
||||
|
||||
@Override
|
||||
public int centerX() {
|
||||
return centerX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int centerZ() {
|
||||
return centerZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int viewDistance() {
|
||||
return viewDistance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtomicReferenceArray<Chunk> getChunks() {
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(IChunkArray other) {
|
||||
centerX = other.centerX();
|
||||
centerZ = other.centerZ();
|
||||
|
||||
AtomicReferenceArray<Chunk> copyingFrom = other.getChunks();
|
||||
for (int k = 0; k < copyingFrom.length(); ++k) {
|
||||
Chunk chunk = copyingFrom.get(k);
|
||||
if (chunk != null) {
|
||||
ChunkPos chunkpos = chunk.getPos();
|
||||
if (inView(chunkpos.x, chunkpos.z)) {
|
||||
int index = getIndex(chunkpos.x, chunkpos.z);
|
||||
if (chunks.get(index) != null) {
|
||||
throw new IllegalStateException("Doing this would mutate the client's REAL loaded chunks?!");
|
||||
}
|
||||
replace(index, chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +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.utils.accessor.IChunkProviderClient;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(ChunkProviderClient.class)
|
||||
public class MixinChunkProviderClient implements IChunkProviderClient {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Long2ObjectMap<Chunk> loadedChunks;
|
||||
|
||||
@Override
|
||||
public Long2ObjectMap<Chunk> loadedChunks() {
|
||||
return this.loadedChunks;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +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.utils.accessor.IChunkProviderServer;
|
||||
import net.minecraft.world.chunk.storage.IChunkLoader;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/4/2018
|
||||
*/
|
||||
@Mixin(ChunkProviderServer.class)
|
||||
public class MixinChunkProviderServer implements IChunkProviderServer {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private IChunkLoader chunkLoader;
|
||||
|
||||
@Override
|
||||
public IChunkLoader getChunkLoader() {
|
||||
return this.chunkLoader;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +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.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();
|
||||
}
|
||||
}
|
||||
@@ -1,57 +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.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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.utils.accessor.IChunkArray;
|
||||
import baritone.utils.accessor.IClientChunkProvider;
|
||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Mixin(ClientChunkProvider.class)
|
||||
public class MixinClientChunkProvider implements IClientChunkProvider {
|
||||
|
||||
@Shadow
|
||||
private ClientWorld world;
|
||||
|
||||
@Override
|
||||
public ClientChunkProvider createThreadSafeCopy() {
|
||||
IChunkArray arr = extractReferenceArray();
|
||||
ClientChunkProvider result = new ClientChunkProvider(world, arr.viewDistance() - 3); // -3 because its adds 3 for no reason lmao
|
||||
IChunkArray copyArr = ((IClientChunkProvider) result).extractReferenceArray();
|
||||
copyArr.copyFrom(arr);
|
||||
if (copyArr.viewDistance() != arr.viewDistance()) {
|
||||
throw new IllegalStateException(copyArr.viewDistance() + " " + arr.viewDistance());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunkArray extractReferenceArray() {
|
||||
for (Field f : ClientChunkProvider.class.getDeclaredFields()) {
|
||||
if (IChunkArray.class.isAssignableFrom(f.getType())) {
|
||||
try {
|
||||
return (IChunkArray) f.get(this);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(Arrays.toString(ClientChunkProvider.class.getDeclaredFields()));
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,10 @@ import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.ChunkEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.network.play.server.SPacketChunkData;
|
||||
import net.minecraft.network.play.server.SPacketCombatEvent;
|
||||
import net.minecraft.client.network.play.ClientPlayNetHandler;
|
||||
import net.minecraft.network.play.server.SChunkDataPacket;
|
||||
import net.minecraft.network.play.server.SCombatPacket;
|
||||
import net.minecraft.network.play.server.SUnloadChunkPacket;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@@ -33,14 +34,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
* @author Brady
|
||||
* @since 8/3/2018
|
||||
*/
|
||||
@Mixin(NetHandlerPlayClient.class)
|
||||
public class MixinNetHandlerPlayClient {
|
||||
@Mixin(ClientPlayNetHandler.class)
|
||||
public class MixinClientPlayNetHandler {
|
||||
|
||||
@Inject(
|
||||
// unused lol
|
||||
/*@Inject(
|
||||
method = "handleChunkData",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/chunk/Chunk.read(Lnet/minecraft/network/PacketBuffer;IZ)V"
|
||||
target = "net/minecraft/client/multiplayer/ChunkProviderClient.func_212474_a(IILnet/minecraft/network/PacketBuffer;IZ)Lnet/minecraft/world/chunk/Chunk;"
|
||||
)
|
||||
)
|
||||
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
@@ -56,15 +58,15 @@ public class MixinNetHandlerPlayClient {
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
@Inject(
|
||||
method = "handleChunkData",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
private void postHandleChunkData(SChunkDataPacket packetIn, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
||||
if (ibaritone.getPlayerContext().player().connection == (ClientPlayNetHandler) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
@@ -77,16 +79,44 @@ public class MixinNetHandlerPlayClient {
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "processChunkUnload",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preChunkUnload(SUnloadChunkPacket packet, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player().connection == (ClientPlayNetHandler) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(EventState.PRE, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "processChunkUnload",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postChunkUnload(SUnloadChunkPacket packet, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player().connection == (ClientPlayNetHandler) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(EventState.POST, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "handleCombatEvent",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/Minecraft.displayGuiScreen(Lnet/minecraft/client/gui/GuiScreen;)V"
|
||||
target = "net/minecraft/client/Minecraft.displayGuiScreen(Lnet/minecraft/client/gui/screen/Screen;)V"
|
||||
)
|
||||
)
|
||||
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
|
||||
private void onPlayerDeath(SCombatPacket packetIn, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
||||
if (ibaritone.getPlayerContext().player().connection == (ClientPlayNetHandler) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onPlayerDeath();
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,9 @@ import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.SprintStateEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.behavior.LookBehavior;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.entity.player.PlayerCapabilities;
|
||||
import net.minecraft.entity.player.PlayerAbilities;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@@ -37,8 +37,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
* @author Brady
|
||||
* @since 8/1/2018
|
||||
*/
|
||||
@Mixin(EntityPlayerSP.class)
|
||||
public class MixinEntityPlayerSP {
|
||||
@Mixin(ClientPlayerEntity.class)
|
||||
public class MixinClientPlayerEntity {
|
||||
|
||||
@Inject(
|
||||
method = "sendChatMessage",
|
||||
@@ -47,7 +47,7 @@ public class MixinEntityPlayerSP {
|
||||
)
|
||||
private void sendChatMessage(String msg, CallbackInfo ci) {
|
||||
ChatEvent event = new ChatEvent(msg);
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
@@ -58,46 +58,46 @@ public class MixinEntityPlayerSP {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "onUpdate",
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z",
|
||||
target = "net/minecraft/client/entity/player/ClientPlayerEntity.isPassenger()Z",
|
||||
shift = At.Shift.BY,
|
||||
by = -3
|
||||
)
|
||||
)
|
||||
private void onPreUpdate(CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this);
|
||||
if (baritone != null) {
|
||||
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "onUpdate",
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V",
|
||||
target = "net/minecraft/client/entity/player/ClientPlayerEntity.onUpdateWalkingPlayer()V",
|
||||
shift = At.Shift.BY,
|
||||
by = 2
|
||||
)
|
||||
)
|
||||
private void onPostUpdate(CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this);
|
||||
if (baritone != null) {
|
||||
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "onLivingUpdate",
|
||||
method = "livingTick",
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
|
||||
target = "net/minecraft/entity/player/PlayerAbilities.allowFlying:Z"
|
||||
)
|
||||
)
|
||||
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||
private boolean isAllowFlying(PlayerAbilities capabilities) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this);
|
||||
if (baritone == null) {
|
||||
return capabilities.allowFlying;
|
||||
}
|
||||
@@ -105,14 +105,14 @@ public class MixinEntityPlayerSP {
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "onLivingUpdate",
|
||||
method = "livingTick",
|
||||
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);
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this);
|
||||
if (baritone == null) {
|
||||
return keyBinding.isKeyDown();
|
||||
}
|
||||
@@ -135,7 +135,7 @@ public class MixinEntityPlayerSP {
|
||||
)
|
||||
)
|
||||
private void updateRidden(CallbackInfo cb) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this);
|
||||
if (baritone != null) {
|
||||
((LookBehavior) baritone.getLookBehavior()).pig();
|
||||
}
|
||||
60
src/launch/java/baritone/launch/mixins/MixinEntity.java
Normal file
60
src/launch/java/baritone/launch/mixins/MixinEntity.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.player.ClientPlayerEntity;
|
||||
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.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public class MixinEntity {
|
||||
|
||||
@Shadow
|
||||
private float rotationYaw;
|
||||
|
||||
float yawRestore;
|
||||
|
||||
@Inject(
|
||||
method = "moveRelative",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void moveRelativeHead(CallbackInfo info) {
|
||||
this.yawRestore = this.rotationYaw;
|
||||
// noinspection ConstantConditions
|
||||
if (!ClientPlayerEntity.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this) == null) {
|
||||
return;
|
||||
}
|
||||
RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
|
||||
BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent);
|
||||
this.rotationYaw = motionUpdateRotationEvent.getYaw();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "moveRelative",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void moveRelativeReturn(CallbackInfo info) {
|
||||
this.rotationYaw = this.yawRestore;
|
||||
}
|
||||
}
|
||||
@@ -17,27 +17,32 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import baritone.utils.accessor.IEntityRenderManager;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/4/2018
|
||||
*/
|
||||
@Mixin(AnvilChunkLoader.class)
|
||||
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
|
||||
|
||||
@Mixin(EntityRendererManager.class)
|
||||
public class MixinEntityRenderManager implements IEntityRenderManager {
|
||||
@Shadow
|
||||
@Final
|
||||
private File chunkSaveLocation;
|
||||
private double renderPosX;
|
||||
@Shadow
|
||||
private double renderPosY;
|
||||
@Shadow
|
||||
private double renderPosZ;
|
||||
|
||||
@Override
|
||||
public File getChunkSaveLocation() {
|
||||
return this.chunkSaveLocation;
|
||||
public double renderPosX() {
|
||||
return renderPosX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double renderPosY() {
|
||||
return renderPosY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double renderPosZ() {
|
||||
return renderPosZ;
|
||||
}
|
||||
}
|
||||
@@ -20,24 +20,24 @@ package baritone.launch.mixins;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.RenderEvent;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(EntityRenderer.class)
|
||||
public class MixinEntityRenderer {
|
||||
@Mixin(GameRenderer.class)
|
||||
public class MixinGameRenderer {
|
||||
|
||||
@Inject(
|
||||
method = "renderWorldPass",
|
||||
method = "updateCameraAndRender(FJ)V",
|
||||
at = @At(
|
||||
value = "INVOKE_STRING",
|
||||
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
||||
target = "Lnet/minecraft/profiler/IProfiler;endStartSection(Ljava/lang/String;)V",
|
||||
args = {"ldc=hand"}
|
||||
)
|
||||
)
|
||||
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||
private void renderWorldPass(float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
||||
}
|
||||
@@ -20,9 +20,11 @@ package baritone.launch.mixins;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.RotationMoveEvent;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -36,17 +38,16 @@ import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
||||
* @author Brady
|
||||
* @since 9/10/2018
|
||||
*/
|
||||
@Mixin(EntityLivingBase.class)
|
||||
public abstract class MixinEntityLivingBase extends Entity {
|
||||
@Mixin(LivingEntity.class)
|
||||
public abstract class MixinLivingEntity extends Entity {
|
||||
|
||||
/**
|
||||
* Event called to override the movement direction when jumping
|
||||
*/
|
||||
private RotationMoveEvent jumpRotationEvent;
|
||||
|
||||
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
|
||||
super(worldIn);
|
||||
this.jumpRotationEvent = jumpRotationEvent;
|
||||
public MixinLivingEntity(EntityType<?> entityTypeIn, World worldIn) {
|
||||
super(entityTypeIn, worldIn);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -55,8 +56,8 @@ public abstract class MixinEntityLivingBase extends Entity {
|
||||
)
|
||||
private void preMoveRelative(CallbackInfo ci) {
|
||||
// noinspection ConstantConditions
|
||||
if (EntityPlayerSP.class.isInstance(this)) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||
if (ClientPlayerEntity.class.isInstance(this)) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this);
|
||||
if (baritone != null) {
|
||||
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw);
|
||||
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
||||
@@ -69,34 +70,15 @@ public abstract class MixinEntityLivingBase extends Entity {
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = GETFIELD,
|
||||
target = "net/minecraft/entity/EntityLivingBase.rotationYaw:F"
|
||||
target = "net/minecraft/entity/LivingEntity.rotationYaw:F"
|
||||
)
|
||||
)
|
||||
private float overrideYaw(EntityLivingBase self) {
|
||||
if (self instanceof EntityPlayerSP && BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) != null) {
|
||||
private float overrideYaw(LivingEntity self) {
|
||||
if (self instanceof ClientPlayerEntity && BaritoneAPI.getProvider().getBaritoneForPlayer((ClientPlayerEntity) (Object) this) != null) {
|
||||
return this.jumpRotationEvent.getYaw();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
58
src/launch/java/baritone/launch/mixins/MixinLootContext.java
Normal file
58
src/launch/java/baritone/launch/mixins/MixinLootContext.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.process.MineProcess;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraft.world.storage.loot.LootContext;
|
||||
import net.minecraft.world.storage.loot.LootTableManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(LootContext.Builder.class)
|
||||
public class MixinLootContext {
|
||||
@Redirect(
|
||||
method = "build",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/server/ServerWorld.getServer()Lnet/minecraft/server/MinecraftServer;"
|
||||
)
|
||||
)
|
||||
private MinecraftServer getServer(ServerWorld world) {
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
return world.getServer();
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "build",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/server/MinecraftServer.getLootTableManager()Lnet/minecraft/world/storage/loot/LootTableManager;"
|
||||
)
|
||||
)
|
||||
private LootTableManager getLootTableManager(MinecraftServer server) {
|
||||
if (server == null) {
|
||||
return MineProcess.getManager();
|
||||
}
|
||||
return server.getLootTableManager();
|
||||
}
|
||||
}
|
||||
@@ -26,13 +26,13 @@ import baritone.api.event.events.WorldEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.utils.BaritoneAutoTest;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import org.spongepowered.asm.lib.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -50,9 +50,9 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
public class MixinMinecraft {
|
||||
|
||||
@Shadow
|
||||
public EntityPlayerSP player;
|
||||
public ClientPlayerEntity player;
|
||||
@Shadow
|
||||
public WorldClient world;
|
||||
public ClientWorld world;
|
||||
|
||||
@Inject(
|
||||
method = "init",
|
||||
@@ -78,7 +78,7 @@ public class MixinMinecraft {
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.GETFIELD,
|
||||
target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;",
|
||||
target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/screen/Screen;",
|
||||
ordinal = 5,
|
||||
shift = At.Shift.BY,
|
||||
by = -3
|
||||
@@ -97,10 +97,10 @@ public class MixinMinecraft {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
||||
method = "loadWorld(Lnet/minecraft/client/world/ClientWorld;)V",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||
private void preLoadWorld(ClientWorld world, CallbackInfo ci) {
|
||||
// If we're unloading the world but one doesn't exist, ignore it
|
||||
if (this.world == null && world == null) {
|
||||
return;
|
||||
@@ -117,10 +117,10 @@ public class MixinMinecraft {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
||||
method = "loadWorld(Lnet/minecraft/client/world/ClientWorld;)V",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||
private void postLoadWorld(ClientWorld world, CallbackInfo ci) {
|
||||
// still fire event for both null, as that means we've just finished exiting a world
|
||||
|
||||
// mc.world changing is only the primary baritone
|
||||
@@ -137,37 +137,24 @@ public class MixinMinecraft {
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.GETFIELD,
|
||||
target = "net/minecraft/client/gui/GuiScreen.allowUserInput:Z"
|
||||
target = "net/minecraft/client/gui/screen/Screen.passEvents:Z"
|
||||
)
|
||||
)
|
||||
private boolean isAllowUserInput(GuiScreen screen) {
|
||||
private boolean passEvents(Screen screen) {
|
||||
// allow user input is only the primary baritone
|
||||
return (BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getCurrent() != null && player != null) || screen.allowUserInput;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "clickMouse",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/multiplayer/PlayerControllerMP.clickBlock(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z"
|
||||
),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void onBlockBreak(CallbackInfo ci, BlockPos pos) {
|
||||
// clickMouse is only for the main player
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.START_BREAK));
|
||||
return (BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getCurrent() != null && player != null) || screen.passEvents;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "rightClickMouse",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/entity/EntityPlayerSP.swingArm(Lnet/minecraft/util/EnumHand;)V"
|
||||
target = "net/minecraft/client/entity/player/ClientPlayerEntity.swingArm(Lnet/minecraft/util/Hand;)V"
|
||||
),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void onBlockUse(CallbackInfo ci, EnumHand var1[], int var2, int var3, EnumHand enumhand, ItemStack itemstack, BlockPos blockpos, int i, EnumActionResult enumactionresult) {
|
||||
private void onBlockUse(CallbackInfo ci, Hand var1[], int var2, int var3, Hand enumhand, ItemStack itemstack, BlockRayTraceResult raytrace, int i, ActionResultType enumactionresult) {
|
||||
// rightClickMouse is only for the main player
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(raytrace.getPos(), BlockInteractEvent.Type.USE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import net.minecraft.network.EnumPacketDirection;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.PacketDirection;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -47,14 +47,14 @@ public class MixinNetworkManager {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private EnumPacketDirection direction;
|
||||
private PacketDirection direction;
|
||||
|
||||
@Inject(
|
||||
method = "dispatchPacket",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
private void preDispatchPacket(IPacket<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
|
||||
if (this.direction != PacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ public class MixinNetworkManager {
|
||||
method = "dispatchPacket",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
private void postDispatchPacket(IPacket<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
|
||||
if (this.direction != PacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -85,11 +85,11 @@ public class MixinNetworkManager {
|
||||
method = "channelRead0",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/network/Packet.processPacket(Lnet/minecraft/network/INetHandler;)V"
|
||||
target = "net/minecraft/network/NetworkManager.processPacket(Lnet/minecraft/network/IPacket;Lnet/minecraft/network/INetHandler;)V"
|
||||
)
|
||||
)
|
||||
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
private void preProcessPacket(ChannelHandlerContext context, IPacket<?> packet, CallbackInfo ci) {
|
||||
if (this.direction != PacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
@@ -103,8 +103,8 @@ public class MixinNetworkManager {
|
||||
method = "channelRead0",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||
if (!this.channel.isOpen() || this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
private void postProcessPacket(ChannelHandlerContext context, IPacket<?> packet, CallbackInfo ci) {
|
||||
if (!this.channel.isOpen() || this.direction != PacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
|
||||
@@ -1,89 +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.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);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.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();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.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();
|
||||
}
|
||||
}
|
||||
@@ -1,75 +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.IBaritone;
|
||||
import baritone.api.event.events.ChunkEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/2/2018
|
||||
*/
|
||||
@Mixin(WorldClient.class)
|
||||
public class MixinWorldClient {
|
||||
|
||||
@Inject(
|
||||
method = "doPreChunk",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.PRE,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "doPreChunk",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,21 +8,17 @@
|
||||
"maxShiftBy": 2
|
||||
},
|
||||
"client": [
|
||||
"MixinAnvilChunkLoader",
|
||||
"MixinBlockPos",
|
||||
"MixinChunkProviderClient",
|
||||
"MixinChunkProviderServer",
|
||||
"MixinChunkRenderContainer",
|
||||
"MixinChunkRenderWorker",
|
||||
"MixinEntityLivingBase",
|
||||
"MixinEntityPlayerSP",
|
||||
"MixinEntityRenderer",
|
||||
"MixinChunkArray",
|
||||
"MixinClientChunkProvider",
|
||||
"MixinClientPlayerEntity",
|
||||
"MixinClientPlayNetHandler",
|
||||
"MixinEntity",
|
||||
"MixinEntityRenderManager",
|
||||
"MixinGameRenderer",
|
||||
"MixinLivingEntity",
|
||||
"MixinLootContext",
|
||||
"MixinMinecraft",
|
||||
"MixinNetHandlerPlayClient",
|
||||
"MixinNetworkManager",
|
||||
"MixinRenderChunk",
|
||||
"MixinRenderList",
|
||||
"MixinVboRenderList",
|
||||
"MixinWorldClient"
|
||||
"MixinNetworkManager"
|
||||
]
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public class Baritone implements IBaritone {
|
||||
static {
|
||||
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||
|
||||
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||
dir = new File(Minecraft.getInstance().gameDir, "baritone");
|
||||
if (!Files.exists(dir.toPath())) {
|
||||
try {
|
||||
Files.createDirectories(dir.toPath());
|
||||
@@ -148,12 +148,12 @@ public class Baritone implements IBaritone {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomGoalProcess getCustomGoalProcess() { // Iffy
|
||||
public CustomGoalProcess getCustomGoalProcess() {
|
||||
return this.customGoalProcess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetToBlockProcess getGetToBlockProcess() { // Iffy
|
||||
public GetToBlockProcess getGetToBlockProcess() {
|
||||
return this.getToBlockProcess;
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ public class Baritone implements IBaritone {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
Helper.mc.addScheduledTask(() -> Helper.mc.displayGuiScreen(new GuiClick()));
|
||||
Helper.mc.execute(() -> Helper.mc.displayGuiScreen(new GuiClick()));
|
||||
} catch (Exception ignored) {}
|
||||
}).start();
|
||||
}
|
||||
@@ -234,4 +234,4 @@ public class Baritone implements IBaritone {
|
||||
public static Executor getExecutor() {
|
||||
return threadPool;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.util.List;
|
||||
public final class BaritoneProvider implements IBaritoneProvider {
|
||||
|
||||
private final Baritone primary = new Baritone();
|
||||
private final List<IBaritone> all = Collections.singletonList(primary);
|
||||
|
||||
@Override
|
||||
public IBaritone getPrimaryBaritone() {
|
||||
@@ -40,8 +41,7 @@ public final class BaritoneProvider implements IBaritoneProvider {
|
||||
|
||||
@Override
|
||||
public List<IBaritone> getAllBaritones() {
|
||||
// TODO return a CopyOnWriteArrayList
|
||||
return Collections.singletonList(primary);
|
||||
return all;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,10 +21,10 @@ import baritone.Baritone;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.utils.ToolSet;
|
||||
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.inventory.ClickType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.inventory.container.ClickType;
|
||||
import net.minecraft.item.*;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.OptionalInt;
|
||||
import java.util.Random;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class InventoryBehavior extends Behavior {
|
||||
public final class InventoryBehavior extends Behavior {
|
||||
public InventoryBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
@@ -46,14 +46,14 @@ public class InventoryBehavior extends Behavior {
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
return;
|
||||
}
|
||||
if (ctx.player().openContainer != ctx.player().inventoryContainer) {
|
||||
if (ctx.player().openContainer != ctx.player().container) {
|
||||
// we have a crafting table or a chest or something open
|
||||
return;
|
||||
}
|
||||
if (firstValidThrowaway() >= 9) { // aka there are none on the hotbar, but there are some in main inventory
|
||||
swapWithHotBar(firstValidThrowaway(), 8);
|
||||
}
|
||||
int pick = bestToolAgainst(Blocks.STONE, ItemPickaxe.class);
|
||||
int pick = bestToolAgainst(Blocks.STONE, PickaxeItem.class);
|
||||
if (pick >= 9) {
|
||||
swapWithHotBar(pick, 0);
|
||||
}
|
||||
@@ -88,7 +88,7 @@ public class InventoryBehavior extends Behavior {
|
||||
}
|
||||
|
||||
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().container.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player());
|
||||
}
|
||||
|
||||
private int firstValidThrowaway() { // TODO offhand idk
|
||||
@@ -101,7 +101,7 @@ public class InventoryBehavior extends Behavior {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int bestToolAgainst(Block against, Class<? extends ItemTool> klass) {
|
||||
private int bestToolAgainst(Block against, Class<? extends ToolItem> klass) {
|
||||
NonNullList<ItemStack> invy = ctx.player().inventory.mainInventory;
|
||||
int bestInd = -1;
|
||||
double bestSpeed = -1;
|
||||
@@ -131,8 +131,8 @@ public class InventoryBehavior extends Behavior {
|
||||
}
|
||||
|
||||
public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
|
||||
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z);
|
||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && ((ItemBlock) stack.getItem()).getBlock().equals(maybe.getBlock()))) {
|
||||
BlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z);
|
||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof BlockItem && ((BlockItem) stack.getItem()).getBlock().equals(maybe.getBlock()))) {
|
||||
return true; // gotem
|
||||
}
|
||||
for (Item item : Baritone.settings().acceptableThrowawayItems.value) {
|
||||
@@ -144,7 +144,7 @@ public class InventoryBehavior extends Behavior {
|
||||
}
|
||||
|
||||
public boolean throwaway(boolean select, Predicate<? super ItemStack> desired) {
|
||||
EntityPlayerSP p = ctx.player();
|
||||
ClientPlayerEntity p = ctx.player();
|
||||
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||
for (byte i = 0; i < 9; i++) {
|
||||
ItemStack item = inv.get(i);
|
||||
@@ -168,7 +168,7 @@ public class InventoryBehavior extends Behavior {
|
||||
// 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 (item.isEmpty() || item.getItem() instanceof PickaxeItem) {
|
||||
if (select) {
|
||||
p.inventory.currentItem = i;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,6 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
|
||||
/**
|
||||
* Target's values are as follows:
|
||||
* <p>
|
||||
* getFirst() -> yaw
|
||||
* getSecond() -> pitch
|
||||
*/
|
||||
private Rotation target;
|
||||
|
||||
@@ -53,6 +50,13 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
@Override
|
||||
public void updateTarget(Rotation target, boolean force) {
|
||||
this.target = target;
|
||||
if (!force) {
|
||||
double rand = Math.random() - 0.5;
|
||||
if (Math.abs(rand) < 0.1) {
|
||||
rand *= 4;
|
||||
}
|
||||
this.target = new Rotation(this.target.getYaw() + (float) (rand * Baritone.settings().randomLooking.value), this.target.getPitch());
|
||||
}
|
||||
this.force = force || !Baritone.settings().freeLook.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,26 +20,10 @@ package baritone.behavior;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.Waypoint;
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.api.event.events.PacketEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.cache.ContainerMemory;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockBed;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.block.BedBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.client.CPacketCloseWindow;
|
||||
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
|
||||
import net.minecraft.network.play.server.SPacketCloseWindow;
|
||||
import net.minecraft.network.play.server.SPacketOpenWindow;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityLockable;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -54,111 +38,13 @@ import java.util.*;
|
||||
*/
|
||||
public final class MemoryBehavior extends Behavior {
|
||||
|
||||
private final List<FutureInventory> futureInventories = new ArrayList<>(); // this is per-bot
|
||||
|
||||
private Integer enderChestWindowId; // nae nae
|
||||
|
||||
public MemoryBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onTick(TickEvent event) {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
enderChestWindowId = null;
|
||||
futureInventories.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||
if (event.getState() == EventState.PRE) {
|
||||
updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onSendPacket(PacketEvent event) {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
Packet p = event.getPacket();
|
||||
|
||||
if (event.getState() == EventState.PRE) {
|
||||
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
|
||||
CPacketPlayerTryUseItemOnBlock packet = event.cast();
|
||||
|
||||
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
|
||||
// if tileEntity is an ender chest, we don't need to do anything. ender chests are treated the same regardless of what coordinate right clicked
|
||||
|
||||
// Ensure the TileEntity is a container of some sort
|
||||
if (tileEntity instanceof TileEntityLockable) {
|
||||
|
||||
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
|
||||
int size = lockable.getSizeInventory();
|
||||
BlockPos position = tileEntity.getPos();
|
||||
BlockPos adj = neighboringConnectedBlock(position);
|
||||
System.out.println(position + " " + adj);
|
||||
if (adj != null) {
|
||||
size *= 2; // double chest or double trapped chest
|
||||
if (adj.getX() < position.getX() || adj.getZ() < position.getZ()) {
|
||||
position = adj; // standardize on the lower coordinate, regardless of which side of the large chest we right clicked
|
||||
}
|
||||
}
|
||||
|
||||
this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), position));
|
||||
}
|
||||
}
|
||||
|
||||
if (p instanceof CPacketCloseWindow) {
|
||||
getCurrent().save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onReceivePacket(PacketEvent event) {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
Packet p = event.getPacket();
|
||||
|
||||
if (event.getState() == EventState.PRE) {
|
||||
if (p instanceof SPacketOpenWindow) {
|
||||
SPacketOpenWindow packet = event.cast();
|
||||
// Remove any entries that were created over a second ago, this should make up for INSANE latency
|
||||
futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
|
||||
|
||||
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
|
||||
System.out.println(packet.getWindowTitle());
|
||||
if (packet.getWindowTitle() instanceof TextComponentTranslation && ((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
|
||||
// title is not customized (i.e. this isn't just a renamed shulker)
|
||||
enderChestWindowId = packet.getWindowId();
|
||||
return;
|
||||
}
|
||||
futureInventories.stream()
|
||||
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
||||
.findFirst().ifPresent(matched -> {
|
||||
// Remove the future inventory
|
||||
futureInventories.remove(matched);
|
||||
|
||||
// Setup the remembered inventory
|
||||
getCurrentContainer().setup(matched.pos, packet.getWindowId(), packet.getSlotCount());
|
||||
});
|
||||
}
|
||||
|
||||
if (p instanceof SPacketCloseWindow) {
|
||||
getCurrent().save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockInteract(BlockInteractEvent event) {
|
||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
|
||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BedBlock) {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||
}
|
||||
}
|
||||
@@ -168,85 +54,6 @@ public final class MemoryBehavior extends Behavior {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet()));
|
||||
}
|
||||
|
||||
|
||||
private void updateInventory() {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
int windowId = ctx.player().openContainer.windowId;
|
||||
if (enderChestWindowId != null) {
|
||||
if (windowId == enderChestWindowId) {
|
||||
getCurrent().contents = ctx.player().openContainer.getInventory().subList(0, 27);
|
||||
} else {
|
||||
getCurrent().save();
|
||||
enderChestWindowId = null;
|
||||
}
|
||||
}
|
||||
if (getCurrentContainer() != null) {
|
||||
getCurrentContainer().getInventoryFromWindow(windowId).ifPresent(inventory -> inventory.updateFromOpenWindow(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
private ContainerMemory getCurrentContainer() {
|
||||
if (baritone.getWorldProvider().getCurrentWorld() == null) {
|
||||
return null;
|
||||
}
|
||||
return (ContainerMemory) baritone.getWorldProvider().getCurrentWorld().getContainerMemory();
|
||||
}
|
||||
|
||||
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
||||
BlockStateInterface bsi = baritone.bsi;
|
||||
Block block = bsi.get0(in).getBlock();
|
||||
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
||||
return null; // other things that have contents, but can be placed adjacent without combining
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BlockPos adj = in.offset(EnumFacing.byHorizontalIndex(i));
|
||||
if (bsi.get0(adj).getBlock() == block) {
|
||||
return adj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An inventory that we are not yet fully aware of, but are expecting to exist at some point in the future.
|
||||
*/
|
||||
private static final class FutureInventory {
|
||||
|
||||
/**
|
||||
* The time that we initially expected the inventory to be provided, in milliseconds
|
||||
*/
|
||||
private final long time;
|
||||
|
||||
/**
|
||||
* The amount of slots in the inventory
|
||||
*/
|
||||
private final int slots;
|
||||
|
||||
/**
|
||||
* The type of inventory
|
||||
*/
|
||||
private final String type;
|
||||
|
||||
/**
|
||||
* The position of the inventory container
|
||||
*/
|
||||
private final BlockPos pos;
|
||||
|
||||
private FutureInventory(long time, int slots, String type, BlockPos pos) {
|
||||
this.time = time;
|
||||
this.slots = slots;
|
||||
this.type = type;
|
||||
this.pos = pos;
|
||||
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + pos);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<List<ItemStack>> echest() {
|
||||
return Optional.ofNullable(getCurrent().contents).map(Collections::unmodifiableList);
|
||||
}
|
||||
|
||||
public EnderChestMemory getCurrent() {
|
||||
Path path = baritone.getWorldProvider().getCurrentWorld().directory;
|
||||
return EnderChestMemory.getByServerAndPlayer(path.getParent(), ctx.player().getUniqueID());
|
||||
|
||||
@@ -65,7 +65,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
|
||||
private boolean lastAutoJump;
|
||||
|
||||
private BlockPos expectedSegmentStart;
|
||||
private BetterBlockPos expectedSegmentStart;
|
||||
|
||||
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
|
||||
|
||||
@@ -135,7 +135,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
) {
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,7 +194,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
current.onTick();
|
||||
return;
|
||||
}
|
||||
current = current.trySplice(next);
|
||||
if (Baritone.settings().splicePath.value) {
|
||||
current = current.trySplice(next);
|
||||
}
|
||||
if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) {
|
||||
next = null;
|
||||
}
|
||||
@@ -337,7 +338,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
|
||||
// just cancel the current path
|
||||
public void secretInternalSegmentCancel() {
|
||||
private void secretInternalSegmentCancel() {
|
||||
queuePathEvent(PathEvent.CANCELED);
|
||||
synchronized (pathPlanLock) {
|
||||
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
|
||||
@@ -359,12 +360,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
}
|
||||
|
||||
/*public void secretCursedFunctionDoNotCall(IPath path) {
|
||||
synchronized (pathPlanLock) {
|
||||
current = new PathExecutor(this, path);
|
||||
}
|
||||
}*/
|
||||
|
||||
public CalculationContext secretInternalGetCalculationContext() {
|
||||
return context;
|
||||
}
|
||||
@@ -493,7 +488,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
}
|
||||
if (talkAboutIt && current != null && current.getPath() != null) {
|
||||
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
||||
if (goal.isInGoal(current.getPath().getDest())) {
|
||||
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||
} else {
|
||||
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||
@@ -506,7 +501,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
});
|
||||
}
|
||||
|
||||
public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
|
||||
private static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
|
||||
Goal transformed = goal;
|
||||
if (Baritone.settings().simplifyUnloadedYCoord.value && goal instanceof IGoalRenderPos) {
|
||||
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||
|
||||
162
src/main/java/baritone/cache/CachedChunk.java
vendored
162
src/main/java/baritone/cache/CachedChunk.java
vendored
@@ -19,13 +19,17 @@ package baritone.cache;
|
||||
|
||||
import baritone.api.utils.BlockUtils;
|
||||
import baritone.utils.pathing.PathingBlockType;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -33,64 +37,77 @@ import java.util.*;
|
||||
*/
|
||||
public final class CachedChunk {
|
||||
|
||||
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
|
||||
public static final ImmutableSet<Block> BLOCKS_TO_KEEP_TRACK_OF = ImmutableSet.of(
|
||||
Blocks.ENDER_CHEST,
|
||||
Blocks.FURNACE,
|
||||
Blocks.CHEST,
|
||||
Blocks.TRAPPED_CHEST,
|
||||
Blocks.END_PORTAL,
|
||||
Blocks.END_PORTAL_FRAME,
|
||||
Blocks.SPAWNER,
|
||||
Blocks.BARRIER,
|
||||
Blocks.OBSERVER,
|
||||
Blocks.WHITE_SHULKER_BOX,
|
||||
Blocks.ORANGE_SHULKER_BOX,
|
||||
Blocks.MAGENTA_SHULKER_BOX,
|
||||
Blocks.LIGHT_BLUE_SHULKER_BOX,
|
||||
Blocks.YELLOW_SHULKER_BOX,
|
||||
Blocks.LIME_SHULKER_BOX,
|
||||
Blocks.PINK_SHULKER_BOX,
|
||||
Blocks.GRAY_SHULKER_BOX,
|
||||
Blocks.LIGHT_GRAY_SHULKER_BOX,
|
||||
Blocks.CYAN_SHULKER_BOX,
|
||||
Blocks.PURPLE_SHULKER_BOX,
|
||||
Blocks.BLUE_SHULKER_BOX,
|
||||
Blocks.BROWN_SHULKER_BOX,
|
||||
Blocks.GREEN_SHULKER_BOX,
|
||||
Blocks.RED_SHULKER_BOX,
|
||||
Blocks.BLACK_SHULKER_BOX,
|
||||
Blocks.NETHER_PORTAL,
|
||||
Blocks.HOPPER,
|
||||
Blocks.BEACON,
|
||||
Blocks.BREWING_STAND,
|
||||
|
||||
static {
|
||||
HashSet<Block> temp = new HashSet<>();
|
||||
//temp.add(Blocks.DIAMOND_ORE);
|
||||
temp.add(Blocks.DIAMOND_BLOCK);
|
||||
//temp.add(Blocks.COAL_ORE);
|
||||
temp.add(Blocks.COAL_BLOCK);
|
||||
//temp.add(Blocks.IRON_ORE);
|
||||
temp.add(Blocks.IRON_BLOCK);
|
||||
//temp.add(Blocks.GOLD_ORE);
|
||||
temp.add(Blocks.GOLD_BLOCK);
|
||||
temp.add(Blocks.EMERALD_ORE);
|
||||
temp.add(Blocks.EMERALD_BLOCK);
|
||||
|
||||
temp.add(Blocks.ENDER_CHEST);
|
||||
temp.add(Blocks.FURNACE);
|
||||
temp.add(Blocks.CHEST);
|
||||
temp.add(Blocks.TRAPPED_CHEST);
|
||||
temp.add(Blocks.END_PORTAL);
|
||||
temp.add(Blocks.END_PORTAL_FRAME);
|
||||
temp.add(Blocks.MOB_SPAWNER);
|
||||
temp.add(Blocks.BARRIER);
|
||||
temp.add(Blocks.OBSERVER);
|
||||
temp.add(Blocks.WHITE_SHULKER_BOX);
|
||||
temp.add(Blocks.ORANGE_SHULKER_BOX);
|
||||
temp.add(Blocks.MAGENTA_SHULKER_BOX);
|
||||
temp.add(Blocks.LIGHT_BLUE_SHULKER_BOX);
|
||||
temp.add(Blocks.YELLOW_SHULKER_BOX);
|
||||
temp.add(Blocks.LIME_SHULKER_BOX);
|
||||
temp.add(Blocks.PINK_SHULKER_BOX);
|
||||
temp.add(Blocks.GRAY_SHULKER_BOX);
|
||||
temp.add(Blocks.SILVER_SHULKER_BOX);
|
||||
temp.add(Blocks.CYAN_SHULKER_BOX);
|
||||
temp.add(Blocks.PURPLE_SHULKER_BOX);
|
||||
temp.add(Blocks.BLUE_SHULKER_BOX);
|
||||
temp.add(Blocks.BROWN_SHULKER_BOX);
|
||||
temp.add(Blocks.GREEN_SHULKER_BOX);
|
||||
temp.add(Blocks.RED_SHULKER_BOX);
|
||||
temp.add(Blocks.BLACK_SHULKER_BOX);
|
||||
temp.add(Blocks.PORTAL);
|
||||
temp.add(Blocks.HOPPER);
|
||||
temp.add(Blocks.BEACON);
|
||||
temp.add(Blocks.BREWING_STAND);
|
||||
temp.add(Blocks.SKULL);
|
||||
temp.add(Blocks.ENCHANTING_TABLE);
|
||||
temp.add(Blocks.ANVIL);
|
||||
temp.add(Blocks.LIT_FURNACE);
|
||||
temp.add(Blocks.BED);
|
||||
temp.add(Blocks.DRAGON_EGG);
|
||||
temp.add(Blocks.JUKEBOX);
|
||||
temp.add(Blocks.END_GATEWAY);
|
||||
temp.add(Blocks.WEB);
|
||||
temp.add(Blocks.NETHER_WART);
|
||||
temp.add(Blocks.LADDER);
|
||||
temp.add(Blocks.VINE);
|
||||
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
|
||||
}
|
||||
// TODO: Maybe add a predicate for blocks to keep track of?
|
||||
// This should really not need to happen
|
||||
Blocks.CREEPER_HEAD,
|
||||
Blocks.CREEPER_WALL_HEAD,
|
||||
Blocks.DRAGON_HEAD,
|
||||
Blocks.DRAGON_WALL_HEAD,
|
||||
Blocks.PLAYER_HEAD,
|
||||
Blocks.PLAYER_WALL_HEAD,
|
||||
Blocks.ZOMBIE_HEAD,
|
||||
Blocks.ZOMBIE_WALL_HEAD,
|
||||
Blocks.SKELETON_SKULL,
|
||||
Blocks.SKELETON_WALL_SKULL,
|
||||
Blocks.WITHER_SKELETON_SKULL,
|
||||
Blocks.WITHER_SKELETON_WALL_SKULL,
|
||||
Blocks.ENCHANTING_TABLE,
|
||||
Blocks.ANVIL,
|
||||
Blocks.WHITE_BED,
|
||||
Blocks.ORANGE_BED,
|
||||
Blocks.MAGENTA_BED,
|
||||
Blocks.LIGHT_BLUE_BED,
|
||||
Blocks.YELLOW_BED,
|
||||
Blocks.LIME_BED,
|
||||
Blocks.PINK_BED,
|
||||
Blocks.GRAY_BED,
|
||||
Blocks.LIGHT_GRAY_BED,
|
||||
Blocks.CYAN_BED,
|
||||
Blocks.PURPLE_BED,
|
||||
Blocks.BLUE_BED,
|
||||
Blocks.BROWN_BED,
|
||||
Blocks.GREEN_BED,
|
||||
Blocks.RED_BED,
|
||||
Blocks.BLACK_BED,
|
||||
Blocks.DRAGON_EGG,
|
||||
Blocks.JUKEBOX,
|
||||
Blocks.END_GATEWAY,
|
||||
Blocks.COBWEB,
|
||||
Blocks.NETHER_WART,
|
||||
Blocks.LADDER,
|
||||
Blocks.VINE
|
||||
);
|
||||
|
||||
/**
|
||||
* The size of the chunk data in bits. Equal to 16 KiB.
|
||||
@@ -126,7 +143,7 @@ public final class CachedChunk {
|
||||
/**
|
||||
* The block names of each surface level block for generating an overview
|
||||
*/
|
||||
private final IBlockState[] overview;
|
||||
private final BlockState[] overview;
|
||||
|
||||
private final int[] heightMap;
|
||||
|
||||
@@ -134,7 +151,7 @@ public final class CachedChunk {
|
||||
|
||||
public final long cacheTimestamp;
|
||||
|
||||
CachedChunk(int x, int z, BitSet data, IBlockState[] overview, Map<String, List<BlockPos>> specialBlockLocations, long cacheTimestamp) {
|
||||
CachedChunk(int x, int z, BitSet data, BlockState[] overview, Map<String, List<BlockPos>> specialBlockLocations, long cacheTimestamp) {
|
||||
validateSize(data);
|
||||
|
||||
this.x = x;
|
||||
@@ -161,7 +178,7 @@ public final class CachedChunk {
|
||||
}
|
||||
}
|
||||
|
||||
public final IBlockState getBlock(int x, int y, int z, int dimension) {
|
||||
public final BlockState getBlock(int x, int y, int z, int dimension) {
|
||||
int index = getPositionIndex(x, y, z);
|
||||
PathingBlockType type = getType(index);
|
||||
int internalPos = z << 4 | x;
|
||||
@@ -170,8 +187,8 @@ public final class CachedChunk {
|
||||
|
||||
// we have this exact block, it's a surface block
|
||||
/*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())) {
|
||||
throw new IllegalStateException("failed " + Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
||||
if (!Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
||||
throw new IllegalStateException("failed " + Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
||||
}*/
|
||||
return overview[internalPos];
|
||||
}
|
||||
@@ -182,8 +199,17 @@ public final class CachedChunk {
|
||||
}
|
||||
}
|
||||
|
||||
if (type == PathingBlockType.SOLID && y == 127 && dimension == -1) {
|
||||
return Blocks.BEDROCK.getDefaultState();
|
||||
if (type == PathingBlockType.SOLID) {
|
||||
if (y == 127 && dimension == -1) {
|
||||
// nether roof is always unbreakable
|
||||
return Blocks.BEDROCK.getDefaultState();
|
||||
}
|
||||
if (y < 5 && dimension == 0) {
|
||||
// solid blocks below 5 are commonly bedrock
|
||||
// however, returning bedrock always would be a little yikes
|
||||
// discourage paths that include breaking blocks below 5 a little more heavily just so that it takes paths breaking what's known to be stone (at 5 or above) instead of what could maybe be bedrock (below 5)
|
||||
return Blocks.OBSIDIAN.getDefaultState();
|
||||
}
|
||||
}
|
||||
return ChunkPacker.pathingTypeToBlock(type, dimension);
|
||||
}
|
||||
@@ -208,7 +234,7 @@ public final class CachedChunk {
|
||||
}
|
||||
}
|
||||
|
||||
public final IBlockState[] getOverview() {
|
||||
public final BlockState[] getOverview() {
|
||||
return overview;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ package baritone.cache;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.ICachedRegion;
|
||||
import baritone.api.utils.BlockUtils;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.io.*;
|
||||
@@ -75,7 +75,7 @@ public final class CachedRegion implements ICachedRegion {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBlockState getBlock(int x, int y, int z) {
|
||||
public final BlockState getBlock(int x, int y, int z) {
|
||||
CachedChunk chunk = chunks[x >> 4][z >> 4];
|
||||
if (chunk != null) {
|
||||
return chunk.getBlock(x & 15, y, z & 15, dimension);
|
||||
@@ -216,7 +216,7 @@ public final class CachedRegion implements ICachedRegion {
|
||||
boolean[][] present = new boolean[32][32];
|
||||
BitSet[][] bitSets = new BitSet[32][32];
|
||||
Map<String, List<BlockPos>>[][] location = new Map[32][32];
|
||||
IBlockState[][][] overview = new IBlockState[32][32][];
|
||||
BlockState[][][] overview = new BlockState[32][32][];
|
||||
long[][] cacheTimestamp = new long[32][32];
|
||||
for (int x = 0; x < 32; x++) {
|
||||
for (int z = 0; z < 32; z++) {
|
||||
@@ -227,7 +227,7 @@ public final class CachedRegion implements ICachedRegion {
|
||||
in.readFully(bytes);
|
||||
bitSets[x][z] = BitSet.valueOf(bytes);
|
||||
location[x][z] = new HashMap<>();
|
||||
overview[x][z] = new IBlockState[256];
|
||||
overview[x][z] = new BlockState[256];
|
||||
present[x][z] = true;
|
||||
break;
|
||||
case CHUNK_NOT_PRESENT:
|
||||
|
||||
@@ -303,6 +303,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
} catch (Throwable th) {
|
||||
// in the case of an exception, keep consuming from the queue so as not to leak memory
|
||||
th.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
src/main/java/baritone/cache/ChunkPacker.java
vendored
46
src/main/java/baritone/cache/ChunkPacker.java
vendored
@@ -21,15 +21,16 @@ import baritone.api.utils.BlockUtils;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.pathing.PathingBlockType;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.chunk.BlockStateContainer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static baritone.utils.BlockStateInterface.getFromChunk;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/3/2018
|
||||
@@ -44,9 +45,9 @@ public final class ChunkPacker {
|
||||
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
||||
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
||||
try {
|
||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
|
||||
for (int y0 = 0; y0 < 16; y0++) {
|
||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
ChunkSection extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
if (extendedblockstorage == null) {
|
||||
// any 16x16x16 area that's all air will have null storage
|
||||
// for example, in an ocean biome, with air from y=64 to y=256
|
||||
@@ -58,7 +59,7 @@ public final class ChunkPacker {
|
||||
// since a bitset is initialized to all zero, and air is saved as zeros
|
||||
continue;
|
||||
}
|
||||
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||
BlockStateContainer<BlockState> bsc = extendedblockstorage.getData();
|
||||
int yReal = y0 << 4;
|
||||
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
||||
// for better cache locality, iterate in that order
|
||||
@@ -67,7 +68,7 @@ public final class ChunkPacker {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||
IBlockState state = bsc.get(x, y1, z);
|
||||
BlockState state = bsc.get(x, y1, z);
|
||||
boolean[] bits = getPathingBlockType(state, chunk, x, y, z).getBits();
|
||||
bitSet.set(index, bits[0]);
|
||||
bitSet.set(index + 1, bits[1]);
|
||||
@@ -85,43 +86,44 @@ public final class ChunkPacker {
|
||||
}
|
||||
//long end = System.nanoTime() / 1000000L;
|
||||
//System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z);
|
||||
IBlockState[] blocks = new IBlockState[256];
|
||||
BlockState[] blocks = new BlockState[256];
|
||||
|
||||
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 y = 255; y >= 0; y--) {
|
||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||
if (bitSet.get(index) || bitSet.get(index + 1)) {
|
||||
blocks[z << 4 | x] = chunk.getBlockState(x, y, z);
|
||||
blocks[z << 4 | x] = getFromChunk(chunk, x, y, z);
|
||||
continue https;
|
||||
}
|
||||
}
|
||||
blocks[z << 4 | x] = Blocks.AIR.getDefaultState();
|
||||
}
|
||||
}
|
||||
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
|
||||
return new CachedChunk(chunk.getPos().x, chunk.getPos().z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
|
||||
private static PathingBlockType getPathingBlockType(BlockState state, Chunk chunk, int x, int y, int z) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) {
|
||||
if (MovementHelper.isWater(state)) {
|
||||
// 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 != 15 && MovementHelper.possiblyFlowing(chunk.getBlockState(x + 1, y, z)))
|
||||
|| (x != 0 && MovementHelper.possiblyFlowing(chunk.getBlockState(x - 1, y, z)))
|
||||
|| (z != 15 && MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z + 1)))
|
||||
|| (z != 0 && MovementHelper.possiblyFlowing(chunk.getBlockState(x, y, z - 1)))
|
||||
(x != 15 && MovementHelper.possiblyFlowing(getFromChunk(chunk, x + 1, y, z)))
|
||||
|| (x != 0 && MovementHelper.possiblyFlowing(getFromChunk(chunk, x - 1, y, z)))
|
||||
|| (z != 15 && MovementHelper.possiblyFlowing(getFromChunk(chunk, x, y, z + 1)))
|
||||
|| (z != 0 && MovementHelper.possiblyFlowing(getFromChunk(chunk, x, y, z - 1)))
|
||||
) {
|
||||
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) {
|
||||
Vec3d flow = state.getFluidState().getFlow(chunk.getWorld(), new BlockPos(x + chunk.getPos().x << 4, y, z + chunk.getPos().z << 4));
|
||||
if (flow.x != 0.0 || flow.z != 0.0) {
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
return PathingBlockType.AVOID;
|
||||
@@ -129,21 +131,21 @@ public final class ChunkPacker {
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
|
||||
if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) {
|
||||
if (MovementHelper.avoidWalkingInto(state) || MovementHelper.isBottomSlab(state)) {
|
||||
return PathingBlockType.AVOID;
|
||||
}
|
||||
// We used to do an AABB check here
|
||||
// however, this failed in the nether when you were near a nether fortress
|
||||
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape
|
||||
// this caused a nullpointerexception when we saved chunks on unload, because they were unable to check their neighbors
|
||||
if (block == Blocks.AIR || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
|
||||
if (block instanceof AirBlock || block instanceof TallGrassBlock || block instanceof DoublePlantBlock || block instanceof FlowerBlock) {
|
||||
return PathingBlockType.AIR;
|
||||
}
|
||||
|
||||
return PathingBlockType.SOLID;
|
||||
}
|
||||
|
||||
public static IBlockState pathingTypeToBlock(PathingBlockType type, int dimension) {
|
||||
public static BlockState pathingTypeToBlock(PathingBlockType type, int dimension) {
|
||||
switch (type) {
|
||||
case AIR:
|
||||
return Blocks.AIR.getDefaultState();
|
||||
|
||||
@@ -29,6 +29,7 @@ import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
@@ -45,6 +46,8 @@ public class ContainerMemory implements IContainerMemory {
|
||||
this.saveTo = saveTo;
|
||||
try {
|
||||
read(Files.readAllBytes(saveTo));
|
||||
} catch (NoSuchFileException ignored) {
|
||||
inventories.clear();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
inventories.clear();
|
||||
|
||||
21
src/main/java/baritone/cache/WorldProvider.java
vendored
21
src/main/java/baritone/cache/WorldProvider.java
vendored
@@ -20,10 +20,9 @@ package baritone.cache;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||
import baritone.utils.accessor.IChunkProviderServer;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -55,18 +54,16 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
*
|
||||
* @param dimension The ID of the world's dimension
|
||||
*/
|
||||
public final void initWorld(int dimension) {
|
||||
public final void initWorld(DimensionType dimension) {
|
||||
File directory;
|
||||
File readme;
|
||||
|
||||
IntegratedServer integratedServer = mc.getIntegratedServer();
|
||||
|
||||
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
|
||||
if (integratedServer != null) {
|
||||
WorldServer localServerWorld = integratedServer.getWorld(dimension);
|
||||
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
|
||||
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
|
||||
directory = loader.getChunkSaveLocation();
|
||||
if (mc.isSingleplayer()) {
|
||||
ServerWorld localServerWorld = integratedServer.getWorld(dimension);
|
||||
directory = dimension.getDirectory(localServerWorld.getSaveHandler().getWorldDirectory());
|
||||
|
||||
// Gets the "depth" of this directory relative the the game's run directory, 2 is the location of the world
|
||||
if (directory.toPath().relativize(mc.gameDir.toPath()).getNameCount() != 2) {
|
||||
@@ -77,7 +74,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
directory = new File(directory, "baritone");
|
||||
readme = directory;
|
||||
} else { // Otherwise, the server must be remote...
|
||||
String folderName = mc.getCurrentServerData().serverIP;
|
||||
String folderName = mc.isConnectedToRealms() ? "realms" : mc.getCurrentServerData().serverIP;
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
folderName = folderName.replace(":", "_");
|
||||
}
|
||||
@@ -92,7 +89,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
} catch (IOException ignored) {}
|
||||
|
||||
// We will actually store the world data in a subfolder: "DIM<id>"
|
||||
Path dir = new File(directory, "DIM" + dimension).toPath();
|
||||
Path dir = new File(directory, "DIM" + dimension.getId()).toPath();
|
||||
if (!Files.exists(dir)) {
|
||||
try {
|
||||
Files.createDirectories(dir);
|
||||
@@ -101,7 +98,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
|
||||
System.out.println("Baritone world data dir: " + dir);
|
||||
synchronized (worldCache) {
|
||||
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
|
||||
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
src/main/java/baritone/cache/WorldScanner.java
vendored
24
src/main/java/baritone/cache/WorldScanner.java
vendored
@@ -20,13 +20,13 @@ package baritone.cache;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.multiplayer.ClientChunkProvider;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.chunk.BlockStateContainer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.IntStream;
|
||||
@@ -46,7 +46,7 @@ public enum WorldScanner implements IWorldScanner {
|
||||
if (blocks.isEmpty()) {
|
||||
return res;
|
||||
}
|
||||
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
|
||||
ClientChunkProvider chunkProvider = (ClientChunkProvider) ctx.world().getChunkProvider();
|
||||
|
||||
int maxSearchRadiusSq = maxSearchRadius * maxSearchRadius;
|
||||
int playerChunkX = ctx.playerFeet().getX() >> 4;
|
||||
@@ -70,7 +70,7 @@ public enum WorldScanner implements IWorldScanner {
|
||||
foundChunks = true;
|
||||
int chunkX = xoff + playerChunkX;
|
||||
int chunkZ = zoff + playerChunkZ;
|
||||
Chunk chunk = chunkProvider.getLoadedChunk(chunkX, chunkZ);
|
||||
Chunk chunk = chunkProvider.getChunk(chunkX, chunkZ, null, false);
|
||||
if (chunk == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -96,8 +96,8 @@ public enum WorldScanner implements IWorldScanner {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
|
||||
Chunk chunk = chunkProvider.getLoadedChunk(pos.x, pos.z);
|
||||
ClientChunkProvider chunkProvider = (ClientChunkProvider) ctx.world().getChunkProvider();
|
||||
Chunk chunk = chunkProvider.getChunk(pos.x, pos.z, null, false);
|
||||
int playerY = ctx.playerFeet().getY();
|
||||
|
||||
if (chunk == null || chunk.isEmpty()) {
|
||||
@@ -110,22 +110,22 @@ public enum WorldScanner implements IWorldScanner {
|
||||
}
|
||||
|
||||
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, List<Block> search, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
|
||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
|
||||
boolean foundWithinY = false;
|
||||
for (int yIndex = 0; yIndex < 16; yIndex++) {
|
||||
int y0 = coordinateIterationOrder[yIndex];
|
||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
if (extendedblockstorage == null) {
|
||||
ChunkSection section = chunkInternalStorageArray[y0];
|
||||
if (section == null || ChunkSection.isEmpty(section)) {
|
||||
continue;
|
||||
}
|
||||
int yReal = y0 << 4;
|
||||
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||
BlockStateContainer<BlockState> bsc = section.getData();
|
||||
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
||||
// for better cache locality, iterate in that order
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
IBlockState state = bsc.get(x, y, z);
|
||||
BlockState state = bsc.get(x, y, z);
|
||||
if (search.contains(state.getBlock())) {
|
||||
int yy = yReal | y;
|
||||
if (result.size() >= max) {
|
||||
|
||||
@@ -51,6 +51,7 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
try {
|
||||
baritone.bsi = new BlockStateInterface(baritone.getPlayerContext(), true);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
baritone.bsi = null;
|
||||
}
|
||||
} else {
|
||||
@@ -84,7 +85,7 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
// to make sure the chunk being unloaded is already loaded.
|
||||
boolean isPreUnload = state == EventState.PRE
|
||||
&& type == ChunkEvent.Type.UNLOAD
|
||||
&& world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
|
||||
&& world.getChunkProvider().getChunk(event.getX(), event.getZ(), null, false) != null;
|
||||
|
||||
if (isPostPopulate || isPreUnload) {
|
||||
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
|
||||
@@ -109,7 +110,7 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
if (event.getState() == EventState.POST) {
|
||||
cache.closeWorld();
|
||||
if (event.getWorld() != null) {
|
||||
cache.initWorld(event.getWorld().provider.getDimensionType().getId());
|
||||
cache.initWorld(event.getWorld().getDimension().getType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
|
||||
int timeCheckInterval = 1 << 6;
|
||||
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.value; // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
||||
double minimumImprovement = Baritone.settings().minimumImprovementRepropagation.value ? MIN_IMPROVEMENT : 0;
|
||||
Moves[] allMoves = Moves.values();
|
||||
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) {
|
||||
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)
|
||||
@@ -86,8 +87,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
|
||||
if (slowPath) {
|
||||
try {
|
||||
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.value);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
PathNode currentNode = openSet.removeLowest();
|
||||
mostRecentConsidered = currentNode;
|
||||
@@ -96,7 +96,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
|
||||
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
|
||||
}
|
||||
for (Moves moves : Moves.values()) {
|
||||
for (Moves moves : allMoves) {
|
||||
int newX = currentNode.x + moves.xOffset;
|
||||
int newZ = currentNode.z + moves.zOffset;
|
||||
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !calcContext.isLoaded(newX, newZ)) {
|
||||
|
||||
@@ -127,7 +127,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
|
||||
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_SEGMENT, path);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Helper.HELPER.logDebug("Pathing exception: " + e);
|
||||
Helper.HELPER.logDirect("Pathing exception: " + e);
|
||||
e.printStackTrace();
|
||||
return new PathCalculationResult(PathCalculationResult.Type.EXCEPTION);
|
||||
} finally {
|
||||
|
||||
@@ -72,31 +72,12 @@ class Path extends PathBase {
|
||||
this.start = new BetterBlockPos(start.x, start.y, start.z);
|
||||
this.end = new BetterBlockPos(end.x, end.y, end.z);
|
||||
this.numNodes = numNodes;
|
||||
this.path = new ArrayList<>();
|
||||
this.movements = new ArrayList<>();
|
||||
this.nodes = new ArrayList<>();
|
||||
this.goal = goal;
|
||||
this.context = context;
|
||||
assemblePath(end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Goal getGoal() {
|
||||
return goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles this path given the end node.
|
||||
*
|
||||
* @param end The end node
|
||||
*/
|
||||
private void assemblePath(PathNode end) {
|
||||
if (!path.isEmpty() || !movements.isEmpty()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
PathNode current = end;
|
||||
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
|
||||
LinkedList<PathNode> tempNodes = new LinkedList();
|
||||
LinkedList<PathNode> tempNodes = new LinkedList<>();
|
||||
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
||||
// Instead, do it into a linked list, then convert at the end
|
||||
while (current != null) {
|
||||
@@ -107,8 +88,13 @@ class Path extends PathBase {
|
||||
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
|
||||
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
||||
// to performantly do that conversion since it knows the length.
|
||||
path.addAll(tempPath);
|
||||
nodes.addAll(tempNodes);
|
||||
this.path = new ArrayList<>(tempPath);
|
||||
this.nodes = new ArrayList<>(tempNodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Goal getGoal() {
|
||||
return goal;
|
||||
}
|
||||
|
||||
private boolean assembleMovements() {
|
||||
|
||||
@@ -25,12 +25,12 @@ import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.ToolSet;
|
||||
import baritone.utils.pathing.BetterWorldBorder;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -58,6 +58,7 @@ public class CalculationContext {
|
||||
public final boolean allowParkour;
|
||||
public final boolean allowParkourPlace;
|
||||
public final boolean allowJumpAt256;
|
||||
public final boolean allowParkourAscend;
|
||||
public final boolean assumeWalkOnWater;
|
||||
public final boolean allowDiagonalDescend;
|
||||
public final boolean allowDownward;
|
||||
@@ -77,19 +78,20 @@ public class CalculationContext {
|
||||
public CalculationContext(IBaritone baritone, boolean forUseOnAnotherThread) {
|
||||
this.safeForThreadedUse = forUseOnAnotherThread;
|
||||
this.baritone = baritone;
|
||||
EntityPlayerSP player = baritone.getPlayerContext().player();
|
||||
ClientPlayerEntity player = baritone.getPlayerContext().player();
|
||||
this.world = baritone.getPlayerContext().world();
|
||||
this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld();
|
||||
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread);
|
||||
this.toolSet = new ToolSet(player);
|
||||
this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway();
|
||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && PlayerInventory.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.getDimension().isNether();
|
||||
this.canSprint = Baritone.settings().allowSprint.value && player.getFoodStats().getFoodLevel() > 6;
|
||||
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.value;
|
||||
this.allowBreak = Baritone.settings().allowBreak.value;
|
||||
this.allowParkour = Baritone.settings().allowParkour.value;
|
||||
this.allowParkourPlace = Baritone.settings().allowParkourPlace.value;
|
||||
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
|
||||
this.allowParkourAscend = Baritone.settings().allowParkourAscend.value;
|
||||
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
|
||||
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
|
||||
this.allowDownward = Baritone.settings().allowDownward.value;
|
||||
@@ -115,7 +117,7 @@ public class CalculationContext {
|
||||
return baritone;
|
||||
}
|
||||
|
||||
public IBlockState get(int x, int y, int z) {
|
||||
public BlockState get(int x, int y, int z) {
|
||||
return bsi.get0(x, y, z); // laughs maniacally
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ public class CalculationContext {
|
||||
return bsi.isLoaded(x, z);
|
||||
}
|
||||
|
||||
public IBlockState get(BlockPos pos) {
|
||||
public BlockState get(BlockPos pos) {
|
||||
return get(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,24 +17,24 @@
|
||||
|
||||
package baritone.pathing.movement;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.pathing.movement.IMovement;
|
||||
import baritone.api.pathing.movement.MovementStatus;
|
||||
import baritone.api.utils.*;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class Movement implements IMovement, MovementHelper {
|
||||
|
||||
public 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 Direction[] HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP = {Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST, Direction.DOWN};
|
||||
|
||||
protected final IBaritone baritone;
|
||||
protected final IPlayerContext ctx;
|
||||
@@ -61,6 +61,8 @@ public abstract class Movement implements IMovement, MovementHelper {
|
||||
public List<BlockPos> toPlaceCached = null;
|
||||
public List<BlockPos> toWalkIntoCached = null;
|
||||
|
||||
private Set<BetterBlockPos> validPositionsCached = null;
|
||||
|
||||
private Boolean calculatedWhileLoaded;
|
||||
|
||||
protected Movement(IBaritone baritone, BetterBlockPos src, BetterBlockPos dest, BetterBlockPos[] toBreak, BetterBlockPos toPlace) {
|
||||
@@ -98,6 +100,20 @@ public abstract class Movement implements IMovement, MovementHelper {
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
protected abstract Set<BetterBlockPos> calculateValidPositions();
|
||||
|
||||
public Set<BetterBlockPos> getValidPositions() {
|
||||
if (validPositionsCached == null) {
|
||||
validPositionsCached = calculateValidPositions();
|
||||
Objects.requireNonNull(validPositionsCached);
|
||||
}
|
||||
return validPositionsCached;
|
||||
}
|
||||
|
||||
protected boolean playerInValidPosition() {
|
||||
return getValidPositions().contains(ctx.playerFeet()) || getValidPositions().contains(((PathingBehavior) baritone.getPathingBehavior()).pathStart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the execution of the latest Movement
|
||||
* State, and offers a Status to the calling class.
|
||||
@@ -106,12 +122,13 @@ public abstract class Movement implements IMovement, MovementHelper {
|
||||
*/
|
||||
@Override
|
||||
public MovementStatus update() {
|
||||
ctx.player().capabilities.isFlying = false;
|
||||
ctx.player().abilities.isFlying = false;
|
||||
currentState = updateState(currentState);
|
||||
if (MovementHelper.isLiquid(ctx, ctx.playerFeet())) {
|
||||
currentState.setInput(Input.JUMP, true);
|
||||
}
|
||||
if (ctx.player().isEntityInsideOpaqueBlock()) {
|
||||
ctx.getSelectedBlock().ifPresent(pos -> MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, pos)));
|
||||
currentState.setInput(Input.CLICK_LEFT, true);
|
||||
}
|
||||
|
||||
@@ -140,14 +157,17 @@ public abstract class Movement implements IMovement, MovementHelper {
|
||||
}
|
||||
boolean somethingInTheWay = false;
|
||||
for (BetterBlockPos blockPos : positionsToBreak) {
|
||||
if (!MovementHelper.canWalkThrough(ctx, blockPos) && !(BlockStateInterface.getBlock(ctx, blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
|
||||
if (!ctx.world().getEntitiesWithinAABB(FallingBlockEntity.class, new AxisAlignedBB(0, 0, 0, 1, 1.1, 1).offset(blockPos)).isEmpty() && Baritone.settings().pauseMiningForFallingBlocks.value) {
|
||||
return false;
|
||||
}
|
||||
if (!MovementHelper.canWalkThrough(ctx, blockPos)) { // can't break air, so don't try
|
||||
somethingInTheWay = true;
|
||||
MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos));
|
||||
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance());
|
||||
if (reachable.isPresent()) {
|
||||
Rotation rotTowardsBlock = reachable.get();
|
||||
MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos));
|
||||
state.setTarget(new MovementState.MovementTarget(rotTowardsBlock, true));
|
||||
if (Objects.equals(ctx.getSelectedBlock().orElse(null), blockPos) || ctx.playerRotations().isReallyCloseTo(rotTowardsBlock)) {
|
||||
if (ctx.isLookingAt(blockPos) || ctx.playerRotations().isReallyCloseTo(rotTowardsBlock)) {
|
||||
state.setInput(Input.CLICK_LEFT, true);
|
||||
}
|
||||
return false;
|
||||
@@ -156,7 +176,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
||||
//i'm doing it anyway
|
||||
//i dont care if theres snow in the way!!!!!!!
|
||||
//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().getEyePosition(1.0F),
|
||||
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
|
||||
|
||||
@@ -27,17 +27,19 @@ import baritone.pathing.movement.MovementState.MovementTarget;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.ToolSet;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.fluid.*;
|
||||
import net.minecraft.pathfinding.PathType;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.properties.SlabType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
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;
|
||||
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP;
|
||||
|
||||
/**
|
||||
* Static helpers for cost calculation
|
||||
@@ -46,17 +48,32 @@ import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN____SO
|
||||
*/
|
||||
public interface MovementHelper extends ActionCosts, Helper {
|
||||
|
||||
static boolean avoidBreaking(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||
static boolean avoidBreaking(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
|
||||
Block b = state.getBlock();
|
||||
return b == Blocks.ICE // ice becomes water, and water can mess up the path
|
||||
|| b instanceof BlockSilverfish // obvious reasons
|
||||
|| b instanceof SilverfishBlock // obvious reasons
|
||||
// call context.get directly with x,y,z. no need to make 5 new BlockPos for no reason
|
||||
|| bsi.get0(x, y + 1, z).getBlock() instanceof BlockLiquid//don't break anything touching liquid on any side
|
||||
|| bsi.get0(x + 1, y, z).getBlock() instanceof BlockLiquid
|
||||
|| bsi.get0(x - 1, y, z).getBlock() instanceof BlockLiquid
|
||||
|| bsi.get0(x, y, z + 1).getBlock() instanceof BlockLiquid
|
||||
|| bsi.get0(x, y, z - 1).getBlock() instanceof BlockLiquid
|
||||
|| Baritone.settings().blocksToAvoidBreaking.value.contains(b);
|
||||
|| avoidAdjacentBreaking(bsi, x, y + 1, z, true)
|
||||
|| avoidAdjacentBreaking(bsi, x + 1, y, z, false)
|
||||
|| avoidAdjacentBreaking(bsi, x - 1, y, z, false)
|
||||
|| avoidAdjacentBreaking(bsi, x, y, z + 1, false)
|
||||
|| avoidAdjacentBreaking(bsi, x, y, z - 1, false);
|
||||
}
|
||||
|
||||
static boolean avoidAdjacentBreaking(BlockStateInterface bsi, int x, int y, int z, boolean directlyAbove) {
|
||||
// returns true if you should avoid breaking a block that's adjacent to this one (e.g. lava that will start flowing if you give it a path)
|
||||
// this is only called for north, south, east, west, and up. this is NOT called for down.
|
||||
// we assume that it's ALWAYS okay to break the block thats ABOVE liquid
|
||||
BlockState state = bsi.get0(x, y, z);
|
||||
Block block = state.getBlock();
|
||||
if (!directlyAbove // it is fine to mine a block that has a falling block directly above, this (the cost of breaking the stacked fallings) is included in cost calculations
|
||||
// therefore if directlyAbove is true, we will actually ignore if this is falling
|
||||
&& block instanceof FallingBlock // obviously, this check is only valid for falling blocks
|
||||
&& Baritone.settings().avoidUpdatingFallingBlocks.value // and if the setting is enabled
|
||||
&& FallingBlock.canFallThrough(bsi.get0(x, y - 1, z))) { // and if it would fall (i.e. it's unsupported)
|
||||
return true; // dont break a block that is adjacent to unsupported gravel because it can cause really weird stuff
|
||||
}
|
||||
return !state.getFluidState().isEmpty();
|
||||
}
|
||||
|
||||
static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) {
|
||||
@@ -67,27 +84,27 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return canWalkThrough(bsi, x, y, z, bsi.get0(x, y, z));
|
||||
}
|
||||
|
||||
static boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||
static boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.AIR) { // early return for most common case
|
||||
if (block instanceof AirBlock) { // early return for most common case
|
||||
return true;
|
||||
}
|
||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull || block instanceof BlockTrapDoor) {
|
||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.COBWEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof AbstractSkullBlock || block == Blocks.BUBBLE_COLUMN || block instanceof ShulkerBoxBlock || block instanceof SlabBlock || block instanceof TrapDoorBlock) {
|
||||
return false;
|
||||
}
|
||||
if (Baritone.settings().blocksToAvoid.value.contains(block)) {
|
||||
return false;
|
||||
}
|
||||
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
|
||||
if (block instanceof DoorBlock || block instanceof FenceGateBlock) {
|
||||
// Because there's no nice method in vanilla to check if a door is openable or not, we just have to assume
|
||||
// that anything that isn't an iron door isn't openable, ignoring that some doors introduced in mods can't
|
||||
// be opened by just interacting.
|
||||
return block != Blocks.IRON_DOOR;
|
||||
}
|
||||
if (block == Blocks.CARPET) {
|
||||
if (block instanceof CarpetBlock) {
|
||||
return canWalkOn(bsi, x, y - 1, z);
|
||||
}
|
||||
if (block instanceof BlockSnow) {
|
||||
if (block instanceof SnowBlock) {
|
||||
// we've already checked doors and fence gates
|
||||
// so the only remaining dynamic isPassables are snow and trapdoor
|
||||
// if they're cached as a top block, we don't know their metadata
|
||||
@@ -97,7 +114,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
}
|
||||
// the check in BlockSnow.isPassable is layers < 5
|
||||
// while actually, we want < 3 because 3 or greater makes it impassable in a 2 high ceiling
|
||||
if (state.getValue(BlockSnow.LAYERS) >= 3) {
|
||||
if (state.get(SnowBlock.LAYERS) >= 3) {
|
||||
return false;
|
||||
}
|
||||
// ok, it's low enough we could walk through it, but is it supported?
|
||||
@@ -106,20 +123,21 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (isFlowing(x, y, z, state, bsi)) {
|
||||
return false; // Don't walk through flowing liquids
|
||||
}
|
||||
if (block instanceof BlockLiquid) {
|
||||
IFluidState fluidState = state.getFluidState();
|
||||
if (fluidState.getFluid() instanceof WaterFluid) {
|
||||
if (Baritone.settings().assumeWalkOnWater.value) {
|
||||
return false;
|
||||
}
|
||||
IBlockState up = bsi.get0(x, y + 1, z);
|
||||
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
||||
BlockState up = bsi.get0(x, y + 1, z);
|
||||
if (!up.getFluidState().isEmpty() || up.getBlock() instanceof LilyPadBlock) {
|
||||
return false;
|
||||
}
|
||||
return block == Blocks.WATER || block == Blocks.FLOWING_WATER;
|
||||
return true;
|
||||
}
|
||||
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
|
||||
// has already been accounted for above
|
||||
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
|
||||
return block.isPassable(null, null);
|
||||
return state.allowsMovement(null, BlockPos.ZERO, PathType.LAND); // workaround for future compatibility =P
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,32 +154,33 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return fullyPassable(context.get(x, y, z));
|
||||
}
|
||||
|
||||
static boolean fullyPassable(IBlockState state) {
|
||||
static boolean fullyPassable(BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.AIR) { // early return for most common case
|
||||
if (block instanceof AirBlock) { // early return for most common case
|
||||
return true;
|
||||
}
|
||||
// exceptions - blocks that are isPassable true, but we can't actually jump through
|
||||
if (block == Blocks.FIRE
|
||||
|| block == Blocks.TRIPWIRE
|
||||
|| block == Blocks.WEB
|
||||
|| block == Blocks.COBWEB
|
||||
|| block == Blocks.VINE
|
||||
|| block == Blocks.LADDER
|
||||
|| block == Blocks.COCOA
|
||||
|| block instanceof BlockDoor
|
||||
|| block instanceof BlockFenceGate
|
||||
|| block instanceof BlockSnow
|
||||
|| block instanceof BlockLiquid
|
||||
|| block instanceof BlockTrapDoor
|
||||
|| block instanceof BlockEndPortal
|
||||
|| block instanceof BlockSkull) {
|
||||
|| block instanceof DoorBlock
|
||||
|| block instanceof FenceGateBlock
|
||||
|| block instanceof SnowBlock
|
||||
|| !state.getFluidState().isEmpty()
|
||||
|| block instanceof TrapDoorBlock
|
||||
|| block instanceof EndPortalBlock
|
||||
|| block instanceof SkullBlock
|
||||
|| block instanceof ShulkerBoxBlock) {
|
||||
return false;
|
||||
}
|
||||
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
||||
return block.isPassable(null, null);
|
||||
return state.allowsMovement(null, null, PathType.LAND);
|
||||
}
|
||||
|
||||
static boolean isReplacable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
||||
static boolean isReplacable(int x, int y, int z, BlockState state, BlockStateInterface bsi) {
|
||||
// for MovementTraverse and MovementAscend
|
||||
// block double plant defaults to true when the block doesn't match, so don't need to check that case
|
||||
// all other overrides just return true or false
|
||||
@@ -173,20 +192,19 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* }
|
||||
*/
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.AIR || isWater(block)) {
|
||||
if (block instanceof AirBlock) {
|
||||
// early return for common cases hehe
|
||||
return true;
|
||||
}
|
||||
if (block instanceof BlockSnow) {
|
||||
if (block instanceof SnowBlock) {
|
||||
// as before, default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
|
||||
if (!bsi.worldContainsLoadedChunk(x, z)) {
|
||||
return true;
|
||||
}
|
||||
return state.getValue(BlockSnow.LAYERS) == 1;
|
||||
return state.get(SnowBlock.LAYERS) == 1;
|
||||
}
|
||||
if (block instanceof BlockDoublePlant) {
|
||||
BlockDoublePlant.EnumPlantType kek = state.getValue(BlockDoublePlant.VARIANT);
|
||||
return kek == BlockDoublePlant.EnumPlantType.FERN || kek == BlockDoublePlant.EnumPlantType.GRASS;
|
||||
if (block == Blocks.LARGE_FERN || block == Blocks.TALL_GRASS) {
|
||||
return true;
|
||||
}
|
||||
return state.getMaterial().isReplaceable();
|
||||
}
|
||||
@@ -196,12 +214,12 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return false;
|
||||
}
|
||||
|
||||
IBlockState state = BlockStateInterface.get(ctx, doorPos);
|
||||
if (!(state.getBlock() instanceof BlockDoor)) {
|
||||
BlockState state = BlockStateInterface.get(ctx, doorPos);
|
||||
if (!(state.getBlock() instanceof DoorBlock)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return isHorizontalBlockPassable(doorPos, state, playerPos, BlockDoor.OPEN);
|
||||
return isHorizontalBlockPassable(doorPos, state, playerPos, DoorBlock.OPEN);
|
||||
}
|
||||
|
||||
static boolean isGatePassable(IPlayerContext ctx, BlockPos gatePos, BlockPos playerPos) {
|
||||
@@ -209,27 +227,27 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return false;
|
||||
}
|
||||
|
||||
IBlockState state = BlockStateInterface.get(ctx, gatePos);
|
||||
if (!(state.getBlock() instanceof BlockFenceGate)) {
|
||||
BlockState state = BlockStateInterface.get(ctx, gatePos);
|
||||
if (!(state.getBlock() instanceof FenceGateBlock)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return state.getValue(BlockFenceGate.OPEN);
|
||||
return state.get(FenceGateBlock.OPEN);
|
||||
}
|
||||
|
||||
static boolean isHorizontalBlockPassable(BlockPos blockPos, IBlockState blockState, BlockPos playerPos, PropertyBool propertyOpen) {
|
||||
static boolean isHorizontalBlockPassable(BlockPos blockPos, BlockState blockState, BlockPos playerPos, BooleanProperty propertyOpen) {
|
||||
if (playerPos.equals(blockPos)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EnumFacing.Axis facing = blockState.getValue(BlockHorizontal.FACING).getAxis();
|
||||
boolean open = blockState.getValue(propertyOpen);
|
||||
Direction.Axis facing = blockState.get(HorizontalBlock.HORIZONTAL_FACING).getAxis();
|
||||
boolean open = blockState.get(propertyOpen);
|
||||
|
||||
EnumFacing.Axis playerFacing;
|
||||
Direction.Axis playerFacing;
|
||||
if (playerPos.north().equals(blockPos) || playerPos.south().equals(blockPos)) {
|
||||
playerFacing = EnumFacing.Axis.Z;
|
||||
playerFacing = Direction.Axis.Z;
|
||||
} else if (playerPos.east().equals(blockPos) || playerPos.west().equals(blockPos)) {
|
||||
playerFacing = EnumFacing.Axis.X;
|
||||
playerFacing = Direction.Axis.X;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -237,14 +255,15 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return (facing == playerFacing) == open;
|
||||
}
|
||||
|
||||
static boolean avoidWalkingInto(Block block) {
|
||||
return block instanceof BlockLiquid
|
||||
|| block instanceof BlockDynamicLiquid
|
||||
|| block == Blocks.MAGMA
|
||||
static boolean avoidWalkingInto(BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
return !state.getFluidState().isEmpty()
|
||||
|| block == Blocks.MAGMA_BLOCK
|
||||
|| block == Blocks.CACTUS
|
||||
|| block == Blocks.FIRE
|
||||
|| block == Blocks.END_PORTAL
|
||||
|| block == Blocks.WEB;
|
||||
|| block == Blocks.COBWEB
|
||||
|| block == Blocks.BUBBLE_COLUMN;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,14 +278,14 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @param state The state of the block at the specified location
|
||||
* @return Whether or not the specified block can be walked on
|
||||
*/
|
||||
static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||
static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.AIR || block == Blocks.MAGMA) {
|
||||
if (block instanceof AirBlock || block == Blocks.MAGMA_BLOCK || block == Blocks.BUBBLE_COLUMN) {
|
||||
// early return for most common case (air)
|
||||
// plus magma, which is a normal cube but it hurts you
|
||||
return false;
|
||||
}
|
||||
if (state.isBlockNormalCube()) {
|
||||
if (isBlockNormalCube(state)) {
|
||||
return true;
|
||||
}
|
||||
if (block == Blocks.LADDER || (block == Blocks.VINE && Baritone.settings().allowVines.value)) { // TODO reconsider this
|
||||
@@ -278,40 +297,38 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
|
||||
return true;
|
||||
}
|
||||
if (isWater(block)) {
|
||||
if (isWater(state)) {
|
||||
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
|
||||
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
|
||||
Block up = bsi.get0(x, y + 1, z).getBlock();
|
||||
if (up == Blocks.WATERLILY || up == Blocks.CARPET) {
|
||||
BlockState upState = bsi.get0(x, y + 1, z);
|
||||
Block up = upState.getBlock();
|
||||
if (up == Blocks.LILY_PAD || up instanceof CarpetBlock) {
|
||||
return true;
|
||||
}
|
||||
if (isFlowing(x, y, z, state, bsi) || block == Blocks.FLOWING_WATER) {
|
||||
if (isFlowing(x, y, z, state, bsi) || upState.getFluidState().getFluid() == Fluids.FLOWING_WATER) {
|
||||
// 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.value;
|
||||
return isWater(upState) && !Baritone.settings().assumeWalkOnWater.value;
|
||||
}
|
||||
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
|
||||
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
|
||||
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.value;
|
||||
return isWater(upState) ^ Baritone.settings().assumeWalkOnWater.value;
|
||||
}
|
||||
if (Baritone.settings().assumeWalkOnLava.value && isLava(block) && !isFlowing(x, y, z, state, bsi)) {
|
||||
if (Baritone.settings().assumeWalkOnLava.value && isLava(state) && !isFlowing(x, y, z, state, bsi)) {
|
||||
return true;
|
||||
}
|
||||
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
|
||||
if (block == Blocks.GLASS || block instanceof StainedGlassBlock) {
|
||||
return true;
|
||||
}
|
||||
if (block instanceof BlockSlab) {
|
||||
if (block instanceof SlabBlock) {
|
||||
if (!Baritone.settings().allowWalkOnBottomSlab.value) {
|
||||
if (((BlockSlab) block).isDouble()) {
|
||||
return true;
|
||||
}
|
||||
return state.getValue(BlockSlab.HALF) != BlockSlab.EnumBlockHalf.BOTTOM;
|
||||
return state.get(SlabBlock.TYPE) != SlabType.BOTTOM;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return block instanceof BlockStairs;
|
||||
return block instanceof StairsBlock;
|
||||
}
|
||||
|
||||
static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos, IBlockState state) {
|
||||
static boolean canWalkOn(IPlayerContext ctx, BetterBlockPos pos, BlockState state) {
|
||||
return canWalkOn(new BlockStateInterface(ctx), pos.x, pos.y, pos.z, state);
|
||||
}
|
||||
|
||||
@@ -339,20 +356,23 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return canPlaceAgainst(new BlockStateInterface(ctx), pos);
|
||||
}
|
||||
|
||||
static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||
static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z, BlockState state) {
|
||||
// can we look at the center of a side face of this block and likely be able to place?
|
||||
// (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;
|
||||
return isBlockNormalCube(state) || state.getBlock() == Blocks.GLASS || state.getBlock() instanceof StainedGlassBlock;
|
||||
}
|
||||
|
||||
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
||||
return getMiningDurationTicks(context, x, y, z, context.get(x, y, z), includeFalling);
|
||||
}
|
||||
|
||||
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, BlockState state, boolean includeFalling) {
|
||||
Block block = state.getBlock();
|
||||
if (!canWalkThrough(context.bsi, x, y, z, state)) {
|
||||
if (!state.getFluidState().isEmpty()) {
|
||||
return COST_INF;
|
||||
}
|
||||
double mult = context.breakCostMultiplierAt(x, y, z);
|
||||
if (mult >= COST_INF) {
|
||||
return COST_INF;
|
||||
@@ -360,21 +380,16 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
if (avoidBreaking(context.bsi, x, y, z, state)) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (block instanceof BlockLiquid) {
|
||||
return COST_INF;
|
||||
}
|
||||
double m = Blocks.CRAFTING_TABLE.equals(block) ? 10 : 1; // TODO see if this is still necessary. it's from MineBot when we wanted to penalize breaking its crafting table
|
||||
double strVsBlock = context.toolSet.getStrVsBlock(state);
|
||||
if (strVsBlock <= 0) {
|
||||
return COST_INF;
|
||||
}
|
||||
|
||||
double result = m / strVsBlock;
|
||||
double result = 1 / strVsBlock;
|
||||
result += context.breakBlockAdditionalCost;
|
||||
result *= mult;
|
||||
if (includeFalling) {
|
||||
IBlockState above = context.get(x, y + 1, z);
|
||||
if (above.getBlock() instanceof BlockFalling) {
|
||||
BlockState above = context.get(x, y + 1, z);
|
||||
if (above.getBlock() instanceof FallingBlock) {
|
||||
result += getMiningDurationTicks(context, x, y + 1, z, above, true);
|
||||
}
|
||||
}
|
||||
@@ -383,10 +398,9 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
return 0; // we won't actually mine it, so don't check fallings above
|
||||
}
|
||||
|
||||
static boolean isBottomSlab(IBlockState state) {
|
||||
return state.getBlock() instanceof BlockSlab
|
||||
&& !((BlockSlab) state.getBlock()).isDouble()
|
||||
&& state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM;
|
||||
static boolean isBottomSlab(BlockState state) {
|
||||
return state.getBlock() instanceof SlabBlock
|
||||
&& state.get(SlabBlock.TYPE) == SlabType.BOTTOM;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,7 +409,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @param ctx The player context
|
||||
* @param b the blockstate to mine
|
||||
*/
|
||||
static void switchToBestToolFor(IPlayerContext ctx, IBlockState b) {
|
||||
static void switchToBestToolFor(IPlayerContext ctx, BlockState b) {
|
||||
switchToBestToolFor(ctx, b, new ToolSet(ctx.player()));
|
||||
}
|
||||
|
||||
@@ -406,7 +420,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @param b the blockstate to mine
|
||||
* @param ts previously calculated ToolSet
|
||||
*/
|
||||
static void switchToBestToolFor(IPlayerContext ctx, IBlockState b, ToolSet ts) {
|
||||
static void switchToBestToolFor(IPlayerContext ctx, BlockState b, ToolSet ts) {
|
||||
ctx.player().inventory.currentItem = ts.getBestSlot(b.getBlock());
|
||||
}
|
||||
|
||||
@@ -423,11 +437,12 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* Returns whether or not the specified block is
|
||||
* water, regardless of whether or not it is flowing.
|
||||
*
|
||||
* @param b The block
|
||||
* @param state The block state
|
||||
* @return Whether or not the block is water
|
||||
*/
|
||||
static boolean isWater(Block b) {
|
||||
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
|
||||
static boolean isWater(BlockState state) {
|
||||
Fluid f = state.getFluidState().getFluid();
|
||||
return f == Fluids.WATER || f == Fluids.FLOWING_WATER;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -439,11 +454,12 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @return Whether or not the block is water
|
||||
*/
|
||||
static boolean isWater(IPlayerContext ctx, BlockPos bp) {
|
||||
return isWater(BlockStateInterface.getBlock(ctx, bp));
|
||||
return isWater(BlockStateInterface.get(ctx, bp));
|
||||
}
|
||||
|
||||
static boolean isLava(Block b) {
|
||||
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
|
||||
static boolean isLava(BlockState state) {
|
||||
Fluid f = state.getFluidState().getFluid();
|
||||
return f == Fluids.LAVA || f == Fluids.FLOWING_LAVA;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -454,20 +470,25 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
* @return Whether or not the block is a liquid
|
||||
*/
|
||||
static boolean isLiquid(IPlayerContext ctx, BlockPos p) {
|
||||
return BlockStateInterface.getBlock(ctx, p) instanceof BlockLiquid;
|
||||
return isLiquid(BlockStateInterface.get(ctx, p));
|
||||
}
|
||||
|
||||
static boolean possiblyFlowing(IBlockState state) {
|
||||
// Will be IFluidState in 1.13
|
||||
return state.getBlock() instanceof BlockLiquid
|
||||
&& state.getValue(BlockLiquid.LEVEL) != 0;
|
||||
static boolean isLiquid(BlockState blockState) {
|
||||
return !blockState.getFluidState().isEmpty();
|
||||
}
|
||||
|
||||
static boolean isFlowing(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
||||
if (!(state.getBlock() instanceof BlockLiquid)) {
|
||||
static boolean possiblyFlowing(BlockState state) {
|
||||
IFluidState fluidState = state.getFluidState();
|
||||
return fluidState.getFluid() instanceof FlowingFluid
|
||||
&& fluidState.getFluid().getLevel(fluidState) != 8;
|
||||
}
|
||||
|
||||
static boolean isFlowing(int x, int y, int z, BlockState state, BlockStateInterface bsi) {
|
||||
IFluidState fluidState = state.getFluidState();
|
||||
if (!(fluidState.getFluid() instanceof FlowingFluid)) {
|
||||
return false;
|
||||
}
|
||||
if (state.getValue(BlockLiquid.LEVEL) != 0) {
|
||||
if (fluidState.getFluid().getLevel(fluidState) != 8) {
|
||||
return true;
|
||||
}
|
||||
return possiblyFlowing(bsi.get0(x + 1, y, z))
|
||||
@@ -476,6 +497,16 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
|| possiblyFlowing(bsi.get0(x, y, z - 1));
|
||||
}
|
||||
|
||||
static boolean isBlockNormalCube(BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block instanceof BambooBlock
|
||||
|| block instanceof MovingPistonBlock
|
||||
|| block instanceof ScaffoldingBlock
|
||||
|| block instanceof ShulkerBoxBlock) {
|
||||
return false;
|
||||
}
|
||||
return Block.isOpaque(state.getCollisionShape(null, null));
|
||||
}
|
||||
|
||||
static PlaceResult attemptToPlaceABlock(MovementState state, IBaritone baritone, BlockPos placeAt, boolean preferDown) {
|
||||
IPlayerContext ctx = baritone.getPlayerContext();
|
||||
@@ -486,7 +517,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
found = true;
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[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(false, placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
|
||||
Helper.HELPER.logDebug("bb pls get me some blocks. dirt, netherrack, cobble");
|
||||
@@ -494,11 +525,11 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
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 faceY = (placeAt.getY() + against1.getY() + 0.5D) * 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)) {
|
||||
if (res != null && res.getType() == RayTraceResult.Type.BLOCK && ((BlockRayTraceResult) res).getPos().equals(against1) && ((BlockRayTraceResult) res).getPos().offset(((BlockRayTraceResult) res).getFace()).equals(placeAt)) {
|
||||
state.setTarget(new MovementState.MovementTarget(place, true));
|
||||
found = true;
|
||||
|
||||
@@ -512,7 +543,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
||||
}
|
||||
if (ctx.getSelectedBlock().isPresent()) {
|
||||
BlockPos selectedBlock = ctx.getSelectedBlock().get();
|
||||
EnumFacing side = ctx.objectMouseOver().sideHit;
|
||||
Direction side = ((BlockRayTraceResult) ctx.objectMouseOver()).getFace();
|
||||
// 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))) {
|
||||
((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(true, placeAt.getX(), placeAt.getY(), placeAt.getZ());
|
||||
|
||||
@@ -20,6 +20,8 @@ package baritone.pathing.movement;
|
||||
import baritone.api.pathing.movement.MovementStatus;
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.api.utils.input.Input;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -20,7 +20,7 @@ package baritone.pathing.movement;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.pathing.movement.movements.*;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
/**
|
||||
* An enum of all possible movements attached to all possible directions they could be taken in
|
||||
@@ -225,7 +225,7 @@ public enum Moves {
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
MutableMoveResult res = new MutableMoveResult();
|
||||
apply(context, src.x, src.y, src.z, res);
|
||||
return new MovementDiagonal(context.getBaritone(), src, EnumFacing.NORTH, EnumFacing.EAST, res.y - src.y);
|
||||
return new MovementDiagonal(context.getBaritone(), src, Direction.NORTH, Direction.EAST, res.y - src.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -239,7 +239,7 @@ public enum Moves {
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
MutableMoveResult res = new MutableMoveResult();
|
||||
apply(context, src.x, src.y, src.z, res);
|
||||
return new MovementDiagonal(context.getBaritone(), src, EnumFacing.NORTH, EnumFacing.WEST, res.y - src.y);
|
||||
return new MovementDiagonal(context.getBaritone(), src, Direction.NORTH, Direction.WEST, res.y - src.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -253,7 +253,7 @@ public enum Moves {
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
MutableMoveResult res = new MutableMoveResult();
|
||||
apply(context, src.x, src.y, src.z, res);
|
||||
return new MovementDiagonal(context.getBaritone(), src, EnumFacing.SOUTH, EnumFacing.EAST, res.y - src.y);
|
||||
return new MovementDiagonal(context.getBaritone(), src, Direction.SOUTH, Direction.EAST, res.y - src.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -267,7 +267,7 @@ public enum Moves {
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
MutableMoveResult res = new MutableMoveResult();
|
||||
apply(context, src.x, src.y, src.z, res);
|
||||
return new MovementDiagonal(context.getBaritone(), src, EnumFacing.SOUTH, EnumFacing.WEST, res.y - src.y);
|
||||
return new MovementDiagonal(context.getBaritone(), src, Direction.SOUTH, Direction.WEST, res.y - src.y);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -276,51 +276,51 @@ public enum Moves {
|
||||
}
|
||||
},
|
||||
|
||||
PARKOUR_NORTH(0, 0, -4, true, false) {
|
||||
PARKOUR_NORTH(0, 0, -4, true, true) {
|
||||
@Override
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
return MovementParkour.cost(context, src, EnumFacing.NORTH);
|
||||
return MovementParkour.cost(context, src, Direction.NORTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
|
||||
MovementParkour.cost(context, x, y, z, EnumFacing.NORTH, result);
|
||||
MovementParkour.cost(context, x, y, z, Direction.NORTH, result);
|
||||
}
|
||||
},
|
||||
|
||||
PARKOUR_SOUTH(0, 0, +4, true, false) {
|
||||
PARKOUR_SOUTH(0, 0, +4, true, true) {
|
||||
@Override
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
return MovementParkour.cost(context, src, EnumFacing.SOUTH);
|
||||
return MovementParkour.cost(context, src, Direction.SOUTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
|
||||
MovementParkour.cost(context, x, y, z, EnumFacing.SOUTH, result);
|
||||
MovementParkour.cost(context, x, y, z, Direction.SOUTH, result);
|
||||
}
|
||||
},
|
||||
|
||||
PARKOUR_EAST(+4, 0, 0, true, false) {
|
||||
PARKOUR_EAST(+4, 0, 0, true, true) {
|
||||
@Override
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
return MovementParkour.cost(context, src, EnumFacing.EAST);
|
||||
return MovementParkour.cost(context, src, Direction.EAST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
|
||||
MovementParkour.cost(context, x, y, z, EnumFacing.EAST, result);
|
||||
MovementParkour.cost(context, x, y, z, Direction.EAST, result);
|
||||
}
|
||||
},
|
||||
|
||||
PARKOUR_WEST(-4, 0, 0, true, false) {
|
||||
PARKOUR_WEST(-4, 0, 0, true, true) {
|
||||
@Override
|
||||
public Movement apply0(CalculationContext context, BetterBlockPos src) {
|
||||
return MovementParkour.cost(context, src, EnumFacing.WEST);
|
||||
return MovementParkour.cost(context, src, Direction.WEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) {
|
||||
MovementParkour.cost(context, x, y, z, EnumFacing.WEST, result);
|
||||
MovementParkour.cost(context, x, y, z, Direction.WEST, result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@ import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.BlockFalling;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.FallingBlock;
|
||||
import net.minecraft.util.Direction;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementAscend extends Movement {
|
||||
|
||||
@@ -51,8 +53,19 @@ public class MovementAscend extends Movement {
|
||||
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
BetterBlockPos prior = new BetterBlockPos(src.subtract(getDirection()).up()); // sometimes we back up to place the block, also sprint ascends, also skip descend to straight ascend
|
||||
return ImmutableSet.of(src,
|
||||
src.up(),
|
||||
dest,
|
||||
prior,
|
||||
prior.up()
|
||||
);
|
||||
}
|
||||
|
||||
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||
IBlockState toPlace = context.get(destX, y, destZ);
|
||||
BlockState toPlace = context.get(destX, y, destZ);
|
||||
double additionalPlacementCost = 0;
|
||||
if (!MovementHelper.canWalkOn(context.bsi, destX, y, destZ, toPlace)) {
|
||||
additionalPlacementCost = context.costOfPlacingAt(destX, y, destZ);
|
||||
@@ -64,9 +77,9 @@ public class MovementAscend extends Movement {
|
||||
}
|
||||
boolean foundPlaceOption = false;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
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 againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
|
||||
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 againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
|
||||
if (againstX == x && againstZ == z) { // we might be able to backplace now, but it doesn't matter because it will have been broken by the time we'd need to use it
|
||||
continue;
|
||||
}
|
||||
@@ -79,26 +92,26 @@ public class MovementAscend extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
}
|
||||
IBlockState srcUp2 = context.get(x, y + 2, z); // used lower down anyway
|
||||
if (context.get(x, y + 3, z).getBlock() instanceof BlockFalling && (MovementHelper.canWalkThrough(context.bsi, x, y + 1, z) || !(srcUp2.getBlock() instanceof BlockFalling))) {//it would fall on us and possibly suffocate us
|
||||
BlockState srcUp2 = context.get(x, y + 2, z); // used lower down anyway
|
||||
if (context.get(x, y + 3, z).getBlock() instanceof FallingBlock && (MovementHelper.canWalkThrough(context.bsi, x, y + 1, z) || !(srcUp2.getBlock() instanceof FallingBlock))) {//it would fall on us and possibly suffocate us
|
||||
// HOWEVER, we assume that we're standing in the start position
|
||||
// that means that src and src.up(1) are both air
|
||||
// maybe they aren't now, but they will be by the time this starts
|
||||
// if the lower one is can't walk through and the upper one is falling, that means that by standing on src
|
||||
// (the presupposition of this Movement)
|
||||
// we have necessarily already cleared the entire BlockFalling stack
|
||||
// we have necessarily already cleared the entire FallingBlock stack
|
||||
// on top of our head
|
||||
|
||||
// as in, if we have a block, then two BlockFallings on top of it
|
||||
// as in, if we have a block, then two FallingBlocks on top of it
|
||||
// and that block is x, y+1, z, and we'd have to clear it to even start this movement
|
||||
// we don't need to worry about those BlockFallings because we've already cleared them
|
||||
// we don't need to worry about those FallingBlocks because we've already cleared them
|
||||
return COST_INF;
|
||||
// you may think we only need to check srcUp2, not srcUp
|
||||
// however, in the scenario where glitchy world gen where unsupported sand / gravel generates
|
||||
// it's possible srcUp is AIR from the start, and srcUp2 is falling
|
||||
// and in that scenario, when we arrive and break srcUp2, that lets srcUp3 fall on us and suffocate us
|
||||
}
|
||||
IBlockState srcDown = context.get(x, y - 1, z);
|
||||
BlockState srcDown = context.get(x, y - 1, z);
|
||||
if (srcDown.getBlock() == Blocks.LADDER || srcDown.getBlock() == Blocks.VINE) {
|
||||
return COST_INF;
|
||||
}
|
||||
@@ -143,6 +156,10 @@ public class MovementAscend extends Movement {
|
||||
|
||||
@Override
|
||||
public MovementState updateState(MovementState state) {
|
||||
if (ctx.playerFeet().y < src.y) {
|
||||
// this check should run even when in preparing state (breaking blocks)
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
super.updateState(state);
|
||||
// TODO incorporate some behavior from ActionClimb (specifically how it waited until it was at most 1.2 blocks away before starting to jump
|
||||
// for efficiency in ascending minimal height staircases, which is just repeated MovementAscend, so that it doesn't bonk its head on the ceiling repeatedly)
|
||||
@@ -150,15 +167,11 @@ public class MovementAscend extends Movement {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (ctx.playerFeet().equals(dest)) {
|
||||
if (ctx.playerFeet().equals(dest) || ctx.playerFeet().equals(dest.add(getDirection().down()))) {
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
}
|
||||
|
||||
if (ctx.playerFeet().y < src.y) {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
|
||||
IBlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace);
|
||||
BlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace);
|
||||
if (!MovementHelper.canWalkOn(ctx, positionToPlace, jumpingOnto)) {
|
||||
ticksWithoutPlacement++;
|
||||
if (MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), false) == PlaceResult.READY_TO_PLACE) {
|
||||
@@ -189,7 +202,7 @@ public class MovementAscend extends Movement {
|
||||
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 lateralMotion = xAxis * ctx.player().motionZ + zAxis * ctx.player().motionX;
|
||||
double lateralMotion = xAxis * ctx.player().getMotion().z + zAxis * ctx.player().getMotion().x;
|
||||
if (Math.abs(lateralMotion) > 0.1) {
|
||||
return state;
|
||||
}
|
||||
@@ -211,7 +224,7 @@ public class MovementAscend extends Movement {
|
||||
public boolean headBonkClear() {
|
||||
BetterBlockPos startUp = src.up(2);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BetterBlockPos check = startUp.offset(EnumFacing.byHorizontalIndex(i));
|
||||
BetterBlockPos check = startUp.offset(Direction.byHorizontalIndex(i));
|
||||
if (!MovementHelper.canWalkThrough(ctx, check)) {
|
||||
// We might bonk our head
|
||||
return false;
|
||||
|
||||
@@ -29,14 +29,17 @@ import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockFalling;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.FallingBlock;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementDescend extends Movement {
|
||||
|
||||
private int numTicks = 0;
|
||||
@@ -61,9 +64,14 @@ public class MovementDescend extends Movement {
|
||||
return result.cost;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
return ImmutableSet.of(src, dest.up(), dest);
|
||||
}
|
||||
|
||||
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
|
||||
double totalCost = 0;
|
||||
IBlockState destDown = context.get(destX, y - 1, destZ);
|
||||
BlockState destDown = context.get(destX, y - 1, destZ);
|
||||
totalCost += MovementHelper.getMiningDurationTicks(context, destX, y - 1, destZ, destDown, false);
|
||||
if (totalCost >= COST_INF) {
|
||||
return;
|
||||
@@ -92,7 +100,7 @@ public class MovementDescend extends Movement {
|
||||
//A is plausibly breakable by either descend or fall
|
||||
//C, D, etc determine the length of the fall
|
||||
|
||||
IBlockState below = context.get(destX, y - 2, destZ);
|
||||
BlockState below = context.get(destX, y - 2, destZ);
|
||||
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 2, destZ, below)) {
|
||||
dynamicFallCost(context, x, y, z, destX, destZ, totalCost, below, res);
|
||||
return;
|
||||
@@ -115,8 +123,8 @@ public class MovementDescend extends Movement {
|
||||
res.cost = totalCost;
|
||||
}
|
||||
|
||||
public static boolean dynamicFallCost(CalculationContext context, int x, int y, int z, int destX, int destZ, double frontBreak, IBlockState below, MutableMoveResult res) {
|
||||
if (frontBreak != 0 && context.get(destX, y + 2, destZ).getBlock() instanceof BlockFalling) {
|
||||
public static boolean dynamicFallCost(CalculationContext context, int x, int y, int z, int destX, int destZ, double frontBreak, BlockState below, MutableMoveResult res) {
|
||||
if (frontBreak != 0 && context.get(destX, y + 2, destZ).getBlock() instanceof FallingBlock) {
|
||||
// if frontBreak is 0 we can actually get through this without updating the falling block and making it actually fall
|
||||
// but if frontBreak is nonzero, we're breaking blocks in front, so don't let anything fall through this column,
|
||||
// and potentially replace the water we're going to fall into
|
||||
@@ -134,10 +142,10 @@ public class MovementDescend extends Movement {
|
||||
// this check prevents it from getting the block at y=-1 and crashing
|
||||
return false;
|
||||
}
|
||||
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
||||
BlockState 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
|
||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
|
||||
if (MovementHelper.isWater(ontoBlock.getBlock())) {
|
||||
if (MovementHelper.isWater(ontoBlock)) {
|
||||
if (!MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
|
||||
return false;
|
||||
}
|
||||
@@ -214,9 +222,9 @@ public class MovementDescend extends Movement {
|
||||
if (safeMode()) {
|
||||
double destX = (src.getX() + 0.5) * 0.17 + (dest.getX() + 0.5) * 0.83;
|
||||
double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83;
|
||||
EntityPlayerSP player = ctx.player();
|
||||
ClientPlayerEntity player = ctx.player();
|
||||
state.setTarget(new MovementState.MovementTarget(
|
||||
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
|
||||
new Rotation(RotationUtils.calcRotationFromVec3d(player.getEyePosition(1.0F),
|
||||
new Vec3d(destX, dest.getY(), destZ),
|
||||
new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch),
|
||||
false
|
||||
@@ -248,7 +256,7 @@ public class MovementDescend extends Movement {
|
||||
return true;
|
||||
}
|
||||
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.get(ctx, into.up(y)))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,25 +28,27 @@ import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementDiagonal extends Movement {
|
||||
|
||||
private static final double SQRT_2 = Math.sqrt(2);
|
||||
|
||||
public MovementDiagonal(IBaritone baritone, BetterBlockPos start, EnumFacing dir1, EnumFacing dir2, int dy) {
|
||||
public MovementDiagonal(IBaritone baritone, BetterBlockPos start, Direction dir1, Direction dir2, int dy) {
|
||||
this(baritone, start, start.offset(dir1), start.offset(dir2), dir2, dy);
|
||||
// super(start, start.offset(dir1).offset(dir2), new BlockPos[]{start.offset(dir1), start.offset(dir1).up(), start.offset(dir2), start.offset(dir2).up(), start.offset(dir1).offset(dir2), start.offset(dir1).offset(dir2).up()}, new BlockPos[]{start.offset(dir1).offset(dir2).down()});
|
||||
}
|
||||
|
||||
private MovementDiagonal(IBaritone baritone, BetterBlockPos start, BetterBlockPos dir1, BetterBlockPos dir2, EnumFacing drr2, int dy) {
|
||||
private MovementDiagonal(IBaritone baritone, BetterBlockPos start, BetterBlockPos dir1, BetterBlockPos dir2, Direction drr2, int dy) {
|
||||
this(baritone, start, dir1.offset(drr2).up(dy), dir1, dir2);
|
||||
}
|
||||
|
||||
@@ -64,12 +66,22 @@ public class MovementDiagonal extends Movement {
|
||||
return result.cost;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
BetterBlockPos diagA = new BetterBlockPos(src.x, src.y, dest.z);
|
||||
BetterBlockPos diagB = new BetterBlockPos(dest.x, src.y, src.z);
|
||||
if (dest.y != src.y) { // only if allowDiagonalDescend
|
||||
return ImmutableSet.of(src, dest.up(), diagA, diagB, dest, diagA.down(), diagB.down());
|
||||
}
|
||||
return ImmutableSet.of(src, dest, diagA, diagB);
|
||||
}
|
||||
|
||||
public static void cost(CalculationContext context, int x, int y, int z, int destX, int destZ, MutableMoveResult res) {
|
||||
IBlockState destInto = context.get(destX, y, destZ);
|
||||
BlockState destInto = context.get(destX, y, destZ);
|
||||
if (!MovementHelper.canWalkThrough(context.bsi, destX, y, destZ, destInto) || !MovementHelper.canWalkThrough(context.bsi, destX, y + 1, destZ)) {
|
||||
return;
|
||||
}
|
||||
IBlockState destWalkOn = context.get(destX, y - 1, destZ);
|
||||
BlockState destWalkOn = context.get(destX, y - 1, destZ);
|
||||
boolean descend = false;
|
||||
if (!MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destWalkOn)) {
|
||||
descend = true;
|
||||
@@ -91,16 +103,16 @@ public class MovementDiagonal extends Movement {
|
||||
if (fromDown == Blocks.SOUL_SAND) {
|
||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||
}
|
||||
Block cuttingOver1 = context.get(x, y - 1, destZ).getBlock();
|
||||
if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
|
||||
BlockState cuttingOver1 = context.get(x, y - 1, destZ);
|
||||
if (cuttingOver1.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver1)) {
|
||||
return;
|
||||
}
|
||||
Block cuttingOver2 = context.get(destX, y - 1, z).getBlock();
|
||||
if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
|
||||
BlockState cuttingOver2 = context.get(destX, y - 1, z);
|
||||
if (cuttingOver2.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver2)) {
|
||||
return;
|
||||
}
|
||||
IBlockState pb0 = context.get(x, y, destZ);
|
||||
IBlockState pb2 = context.get(destX, y, z);
|
||||
BlockState pb0 = context.get(x, y, destZ);
|
||||
BlockState pb2 = context.get(destX, y, z);
|
||||
double optionA = MovementHelper.getMiningDurationTicks(context, x, y, destZ, pb0, false);
|
||||
double optionB = MovementHelper.getMiningDurationTicks(context, destX, y, z, pb2, false);
|
||||
if (optionA != 0 && optionB != 0) {
|
||||
@@ -108,14 +120,14 @@ public class MovementDiagonal extends Movement {
|
||||
// so no need to check pb1 as well, might as well return early here
|
||||
return;
|
||||
}
|
||||
IBlockState pb1 = context.get(x, y + 1, destZ);
|
||||
BlockState pb1 = context.get(x, y + 1, destZ);
|
||||
optionA += MovementHelper.getMiningDurationTicks(context, x, y + 1, destZ, pb1, true);
|
||||
if (optionA != 0 && optionB != 0) {
|
||||
// same deal, if pb1 makes optionA nonzero and option B already was nonzero, pb3 can't affect the result
|
||||
return;
|
||||
}
|
||||
IBlockState pb3 = context.get(destX, y + 1, z);
|
||||
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3.getBlock()))) {
|
||||
BlockState pb3 = context.get(destX, y + 1, z);
|
||||
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3))) {
|
||||
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
|
||||
return;
|
||||
}
|
||||
@@ -124,13 +136,14 @@ public class MovementDiagonal extends Movement {
|
||||
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
|
||||
return;
|
||||
}
|
||||
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1.getBlock()))) {
|
||||
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1))) {
|
||||
// and now that option B is fully calculated, see if we can edge around that way
|
||||
return;
|
||||
}
|
||||
boolean water = false;
|
||||
Block startIn = context.getBlock(x, y, z);
|
||||
if (MovementHelper.isWater(startIn) || MovementHelper.isWater(destInto.getBlock())) {
|
||||
BlockState startState = context.get(x, y, z);
|
||||
Block startIn = startState.getBlock();
|
||||
if (MovementHelper.isWater(startState) || MovementHelper.isWater(destInto)) {
|
||||
// Ignore previous multiplier
|
||||
// Whatever we were walking on (possibly soul sand) doesn't matter as we're actually floating on water
|
||||
// Not even touching the blocks below
|
||||
@@ -171,8 +184,9 @@ public class MovementDiagonal extends Movement {
|
||||
}
|
||||
|
||||
if (ctx.playerFeet().equals(dest)) {
|
||||
state.setStatus(MovementStatus.SUCCESS);
|
||||
return state;
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
} else if (!playerInValidPosition() && !(MovementHelper.isLiquid(ctx, src) && getValidPositions().contains(ctx.playerFeet().up()))) {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
if (sprint()) {
|
||||
state.setInput(Input.SPRINT, true);
|
||||
@@ -181,7 +195,7 @@ public class MovementDiagonal extends Movement {
|
||||
return state;
|
||||
}
|
||||
|
||||
public boolean sprint() {
|
||||
private boolean sprint() {
|
||||
if (MovementHelper.isLiquid(ctx, ctx.playerFeet()) && !Baritone.settings().sprintInWater.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -24,9 +24,12 @@ import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementDownward extends Movement {
|
||||
|
||||
@@ -47,6 +50,11 @@ public class MovementDownward extends Movement {
|
||||
return cost(context, src.x, src.y, src.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
return ImmutableSet.of(src, dest);
|
||||
}
|
||||
|
||||
public static double cost(CalculationContext context, int x, int y, int z) {
|
||||
if (!context.allowDownward) {
|
||||
return COST_INF;
|
||||
@@ -54,7 +62,7 @@ public class MovementDownward extends Movement {
|
||||
if (!MovementHelper.canWalkOn(context.bsi, x, y - 2, z)) {
|
||||
return COST_INF;
|
||||
}
|
||||
IBlockState down = context.get(x, y - 1, z);
|
||||
BlockState down = context.get(x, y - 1, z);
|
||||
Block downBlock = down.getBlock();
|
||||
if (downBlock == Blocks.LADDER || downBlock == Blocks.VINE) {
|
||||
return LADDER_DOWN_ONE_COST;
|
||||
@@ -73,6 +81,8 @@ public class MovementDownward extends Movement {
|
||||
|
||||
if (ctx.playerFeet().equals(dest)) {
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
} else if (!playerInValidPosition()) {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
double diffX = ctx.player().posX - (dest.getX() + 0.5);
|
||||
double diffZ = ctx.player().posZ - (dest.getZ() + 0.5);
|
||||
|
||||
@@ -31,18 +31,21 @@ import baritone.pathing.movement.MovementState;
|
||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLadder;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.LadderBlock;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.fluid.WaterFluid;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementFall extends Movement {
|
||||
|
||||
@@ -63,6 +66,16 @@ public class MovementFall extends Movement {
|
||||
return result.cost;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
Set<BetterBlockPos> set = new HashSet<>();
|
||||
set.add(src);
|
||||
for (int y = src.y - dest.y; y >= 0; y--) {
|
||||
set.add(dest.up(y));
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
private boolean willPlaceBucket() {
|
||||
CalculationContext context = new CalculationContext(baritone);
|
||||
MutableMoveResult result = new MutableMoveResult();
|
||||
@@ -79,10 +92,11 @@ public class MovementFall extends Movement {
|
||||
BlockPos playerFeet = ctx.playerFeet();
|
||||
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations());
|
||||
Rotation targetRotation = null;
|
||||
Block destBlock = ctx.world().getBlockState(dest).getBlock();
|
||||
boolean isWater = destBlock == Blocks.WATER || destBlock == Blocks.FLOWING_WATER;
|
||||
BlockState destState = ctx.world().getBlockState(dest);
|
||||
Block destBlock = destState.getBlock();
|
||||
boolean isWater = destState.getFluidState().getFluid() instanceof WaterFluid;
|
||||
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
|
||||
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) {
|
||||
if (!PlayerInventory.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().getDimension().isNether()) {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
|
||||
@@ -103,15 +117,15 @@ public class MovementFall extends Movement {
|
||||
}
|
||||
if (playerFeet.equals(dest) && (ctx.player().posY - playerFeet.getY() < 0.094 || isWater)) { // 0.094 because lilypads
|
||||
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 (PlayerInventory.isHotbar(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().getMotion().y >= 0) {
|
||||
return state.setInput(Input.CLICK_RIGHT, true);
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
} else {
|
||||
if (ctx.player().motionY >= 0) {
|
||||
if (ctx.player().getMotion().y >= 0) {
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
} // don't else return state; we need to stay centered because this water might be flowing under the surface
|
||||
}
|
||||
@@ -120,13 +134,13 @@ public class MovementFall extends Movement {
|
||||
}
|
||||
}
|
||||
Vec3d destCenter = VecUtils.getBlockPosCenter(dest); // we are moving to the 0.5 center not the edge (like if we were falling on a ladder)
|
||||
if (Math.abs(ctx.player().posX + ctx.player().motionX - destCenter.x) > 0.1 || Math.abs(ctx.player().posZ + ctx.player().motionZ - destCenter.z) > 0.1) {
|
||||
if (!ctx.player().onGround && Math.abs(ctx.player().motionY) > 0.4) {
|
||||
if (Math.abs(ctx.player().posX + ctx.player().getMotion().x - destCenter.x) > 0.1 || Math.abs(ctx.player().posZ + ctx.player().getMotion().z - destCenter.z) > 0.1) {
|
||||
if (!ctx.player().onGround && Math.abs(ctx.player().getMotion().y) > 0.4) {
|
||||
state.setInput(Input.SNEAK, true);
|
||||
}
|
||||
state.setInput(Input.MOVE_FORWARD, true);
|
||||
}
|
||||
Vec3i avoid = Optional.ofNullable(avoid()).map(EnumFacing::getDirectionVec).orElse(null);
|
||||
Vec3i avoid = Optional.ofNullable(avoid()).map(Direction::getDirectionVec).orElse(null);
|
||||
if (avoid == null) {
|
||||
avoid = src.subtract(dest);
|
||||
} else {
|
||||
@@ -144,11 +158,11 @@ public class MovementFall extends Movement {
|
||||
return state;
|
||||
}
|
||||
|
||||
private EnumFacing avoid() {
|
||||
private Direction avoid() {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
IBlockState state = ctx.world().getBlockState(ctx.playerFeet().down(i));
|
||||
BlockState state = ctx.world().getBlockState(ctx.playerFeet().down(i));
|
||||
if (state.getBlock() == Blocks.LADDER) {
|
||||
return state.getValue(BlockLadder.FACING);
|
||||
return state.get(LadderBlock.FACING);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -28,33 +28,39 @@ import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.block.BlockStairs;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.StairsBlock;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.fluid.WaterFluid;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementParkour extends Movement {
|
||||
|
||||
private static final BetterBlockPos[] EMPTY = new BetterBlockPos[]{};
|
||||
|
||||
private final EnumFacing direction;
|
||||
private final Direction direction;
|
||||
private final int dist;
|
||||
private final boolean ascend;
|
||||
|
||||
private MovementParkour(IBaritone baritone, BetterBlockPos src, int dist, EnumFacing dir) {
|
||||
super(baritone, src, src.offset(dir, dist), EMPTY, src.offset(dir, dist).down());
|
||||
private MovementParkour(IBaritone baritone, BetterBlockPos src, int dist, Direction dir, boolean ascend) {
|
||||
super(baritone, src, src.offset(dir, dist).up(ascend ? 1 : 0), EMPTY, src.offset(dir, dist).down(ascend ? 0 : 1));
|
||||
this.direction = dir;
|
||||
this.dist = dist;
|
||||
this.ascend = ascend;
|
||||
}
|
||||
|
||||
public static MovementParkour cost(CalculationContext context, BetterBlockPos src, EnumFacing direction) {
|
||||
public static MovementParkour cost(CalculationContext context, BetterBlockPos src, Direction direction) {
|
||||
MutableMoveResult res = new MutableMoveResult();
|
||||
cost(context, src.x, src.y, src.z, direction, res);
|
||||
int dist = Math.abs(res.x - src.x) + Math.abs(res.z - src.z);
|
||||
return new MovementParkour(context.getBaritone(), src, dist, direction);
|
||||
return new MovementParkour(context.getBaritone(), src, dist, direction, res.y > src.y);
|
||||
}
|
||||
|
||||
public static void cost(CalculationContext context, int x, int y, int z, EnumFacing dir, MutableMoveResult res) {
|
||||
public static void cost(CalculationContext context, int x, int y, int z, Direction dir, MutableMoveResult res) {
|
||||
if (!context.allowParkour) {
|
||||
return;
|
||||
}
|
||||
@@ -68,12 +74,12 @@ public class MovementParkour extends Movement {
|
||||
// most common case at the top -- the adjacent block isn't air
|
||||
return;
|
||||
}
|
||||
IBlockState adj = context.get(x + xDiff, y - 1, z + zDiff);
|
||||
BlockState adj = context.get(x + xDiff, y - 1, z + zDiff);
|
||||
if (MovementHelper.canWalkOn(context.bsi, x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
|
||||
// second most common case -- we could just traverse not parkour
|
||||
return;
|
||||
}
|
||||
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
|
||||
if (MovementHelper.avoidWalkingInto(adj) && !(adj.getFluidState().getFluid() instanceof WaterFluid)) { // magma sucks
|
||||
return;
|
||||
}
|
||||
if (!MovementHelper.fullyPassable(context, x + xDiff, y + 1, z + zDiff)) {
|
||||
@@ -85,8 +91,8 @@ public class MovementParkour extends Movement {
|
||||
if (!MovementHelper.fullyPassable(context, x, y + 2, z)) {
|
||||
return;
|
||||
}
|
||||
IBlockState standingOn = context.get(x, y - 1, z);
|
||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn) || standingOn.getBlock() instanceof BlockLiquid) {
|
||||
BlockState standingOn = context.get(x, y - 1, z);
|
||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof StairsBlock || MovementHelper.isBottomSlab(standingOn) || standingOn.getFluidState().getFluid() != Fluids.EMPTY) {
|
||||
return;
|
||||
}
|
||||
int maxJump;
|
||||
@@ -100,19 +106,36 @@ public class MovementParkour extends Movement {
|
||||
}
|
||||
}
|
||||
for (int i = 2; i <= maxJump; i++) {
|
||||
// TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly?
|
||||
for (int y2 = 0; y2 < 4; y2++) {
|
||||
if (!MovementHelper.fullyPassable(context, x + xDiff * i, y + y2, z + zDiff * i)) {
|
||||
return;
|
||||
}
|
||||
int destX = x + xDiff * i;
|
||||
int destZ = z + zDiff * i;
|
||||
if (!MovementHelper.fullyPassable(context, destX, y + 1, destZ)) {
|
||||
return;
|
||||
}
|
||||
IBlockState landingOn = context.bsi.get0(x + xDiff * i, y - 1, z + zDiff * i);
|
||||
if (!MovementHelper.fullyPassable(context, destX, y + 2, destZ)) {
|
||||
return;
|
||||
}
|
||||
BlockState destInto = context.bsi.get0(destX, y, destZ);
|
||||
if (!MovementHelper.fullyPassable(destInto)) {
|
||||
if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) {
|
||||
res.x = destX;
|
||||
res.y = y + 1;
|
||||
res.z = destZ;
|
||||
res.cost = i * SPRINT_ONE_BLOCK_COST + context.jumpPenalty;
|
||||
}
|
||||
return;
|
||||
}
|
||||
BlockState landingOn = context.bsi.get0(destX, y - 1, destZ);
|
||||
// farmland needs to be canwalkon otherwise farm can never work at all, but we want to specifically disallow ending a jumy on farmland haha
|
||||
if (landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context.bsi, x + xDiff * i, y - 1, z + zDiff * i, landingOn)) {
|
||||
res.x = x + xDiff * i;
|
||||
res.y = y;
|
||||
res.z = z + zDiff * i;
|
||||
res.cost = costFromJumpDistance(i) + context.jumpPenalty;
|
||||
if (landingOn.getBlock() != Blocks.FARMLAND && MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, landingOn)) {
|
||||
if (checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) {
|
||||
res.x = destX;
|
||||
res.y = y;
|
||||
res.z = destZ;
|
||||
res.cost = costFromJumpDistance(i) + context.jumpPenalty;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!MovementHelper.fullyPassable(context, destX, y + 3, destZ)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -129,14 +152,17 @@ public class MovementParkour extends Movement {
|
||||
if (placeCost >= COST_INF) {
|
||||
return;
|
||||
}
|
||||
IBlockState toReplace = context.get(destX, y - 1, destZ);
|
||||
BlockState toReplace = context.get(destX, y - 1, destZ);
|
||||
if (!MovementHelper.isReplacable(destX, y - 1, destZ, toReplace, context.bsi)) {
|
||||
return;
|
||||
}
|
||||
if (!checkOvershootSafety(context.bsi, destX + xDiff, y, destZ + zDiff)) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
||||
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
||||
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
|
||||
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
||||
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
||||
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
|
||||
if (againstX == x + xDiff * 3 && againstZ == z + zDiff * 3) { // we can't turn around that fast
|
||||
continue;
|
||||
}
|
||||
@@ -150,6 +176,11 @@ public class MovementParkour extends Movement {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkOvershootSafety(BlockStateInterface bsi, int x, int y, int z) {
|
||||
// we're going to walk into these two blocks after the landing of the parkour anyway, so make sure they aren't avoidWalkingInto
|
||||
return !MovementHelper.avoidWalkingInto(bsi.get0(x, y, z)) && !MovementHelper.avoidWalkingInto(bsi.get0(x, y + 1, z));
|
||||
}
|
||||
|
||||
private static double costFromJumpDistance(int dist) {
|
||||
switch (dist) {
|
||||
case 2:
|
||||
@@ -168,12 +199,23 @@ public class MovementParkour extends Movement {
|
||||
public double calculateCost(CalculationContext context) {
|
||||
MutableMoveResult res = new MutableMoveResult();
|
||||
cost(context, src.x, src.y, src.z, direction, res);
|
||||
if (res.x != dest.x || res.z != dest.z) {
|
||||
if (res.x != dest.x || res.y != dest.y || res.z != dest.z) {
|
||||
return COST_INF;
|
||||
}
|
||||
return res.cost;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
Set<BetterBlockPos> set = new HashSet<>();
|
||||
for (int i = 0; i <= dist; i++) {
|
||||
for (int y = 0; y < 2; y++) {
|
||||
set.add(src.offset(direction, i).up(y));
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean safeToCancel(MovementState state) {
|
||||
// once this movement is instantiated, the state is default to PREPPING
|
||||
@@ -188,16 +230,12 @@ public class MovementParkour extends Movement {
|
||||
if (state.getStatus() != MovementStatus.RUNNING) {
|
||||
return state;
|
||||
}
|
||||
if (ctx.player().isHandActive()) {
|
||||
logDebug("Pausing parkour since hand is active");
|
||||
return state;
|
||||
}
|
||||
if (ctx.playerFeet().y < src.y) {
|
||||
// we have fallen
|
||||
logDebug("sorry");
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
if (dist >= 4) {
|
||||
if (dist >= 4 || ascend) {
|
||||
state.setInput(Input.SPRINT, true);
|
||||
}
|
||||
MovementHelper.moveTowards(ctx, state, dest);
|
||||
@@ -212,12 +250,13 @@ public class MovementParkour extends Movement {
|
||||
state.setStatus(MovementStatus.SUCCESS);
|
||||
}
|
||||
} 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 - src.y > 0.0001) {
|
||||
if (!MovementHelper.canWalkOn(ctx, dest.down()) && !ctx.player().onGround && MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), true) == PlaceResult.READY_TO_PLACE) {
|
||||
// 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
|
||||
state.setInput(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
if (dist == 3) { // this is a 2 block gap, dest = src + direction * 3
|
||||
// prevent jumping too late by checking for ascend
|
||||
if (dist == 3 && !ascend) { // this is a 2 block gap, dest = src + direction * 3
|
||||
double xDiff = (src.x + 0.5) - ctx.player().posX;
|
||||
double zDiff = (src.z + 0.5) - ctx.player().posZ;
|
||||
double distFromStart = Math.max(Math.abs(xDiff), Math.abs(zDiff));
|
||||
|
||||
@@ -30,14 +30,13 @@ import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.state.properties.SlabType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementPillar extends Movement {
|
||||
|
||||
@@ -50,29 +49,35 @@ public class MovementPillar extends Movement {
|
||||
return cost(context, src.x, src.y, src.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
return ImmutableSet.of(src, dest);
|
||||
}
|
||||
|
||||
public static double cost(CalculationContext context, int x, int y, int z) {
|
||||
Block from = context.get(x, y, z).getBlock();
|
||||
BlockState fromState = context.get(x, y, z);
|
||||
Block from = fromState.getBlock();
|
||||
boolean ladder = from == Blocks.LADDER || from == Blocks.VINE;
|
||||
IBlockState fromDown = context.get(x, y - 1, z);
|
||||
BlockState fromDown = context.get(x, y - 1, z);
|
||||
if (!ladder) {
|
||||
if (fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE) {
|
||||
return COST_INF; // can't pillar from a ladder or vine onto something that isn't also climbable
|
||||
}
|
||||
if (fromDown.getBlock() instanceof BlockSlab && !((BlockSlab) fromDown.getBlock()).isDouble() && fromDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
|
||||
if (fromDown.getBlock() instanceof SlabBlock && fromDown.get(SlabBlock.TYPE) == SlabType.BOTTOM) {
|
||||
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
|
||||
}
|
||||
}
|
||||
if (from == Blocks.VINE && !hasAgainst(context, x, y, z)) { // TODO this vine can't be climbed, but we could place a pillar still since vines are replacable, no? perhaps the pillar jump would be impossible because of the slowdown actually.
|
||||
return COST_INF;
|
||||
}
|
||||
IBlockState toBreak = context.get(x, y + 2, z);
|
||||
BlockState toBreak = context.get(x, y + 2, z);
|
||||
Block toBreakBlock = toBreak.getBlock();
|
||||
if (toBreakBlock instanceof BlockFenceGate) { // see issue #172
|
||||
if (toBreakBlock instanceof FenceGateBlock) { // see issue #172
|
||||
return COST_INF;
|
||||
}
|
||||
Block srcUp = null;
|
||||
if (MovementHelper.isWater(toBreakBlock) && MovementHelper.isWater(from)) { // TODO should this also be allowed if toBreakBlock is air?
|
||||
srcUp = context.get(x, y + 1, z).getBlock();
|
||||
BlockState srcUp = null;
|
||||
if (MovementHelper.isWater(toBreak) && MovementHelper.isWater(fromState)) { // TODO should this also be allowed if toBreakBlock is air?
|
||||
srcUp = context.get(x, y + 1, z);
|
||||
if (MovementHelper.isWater(srcUp)) {
|
||||
return LADDER_UP_ONE_COST; // allow ascending pillars of water, but only if we're already in one
|
||||
}
|
||||
@@ -84,11 +89,11 @@ public class MovementPillar extends Movement {
|
||||
if (placeCost >= COST_INF) {
|
||||
return COST_INF;
|
||||
}
|
||||
if (fromDown.getBlock() == Blocks.AIR) {
|
||||
if (fromDown.getBlock() instanceof AirBlock) {
|
||||
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 ((MovementHelper.isLiquid(fromState) && !MovementHelper.canPlaceAgainst(context.bsi, x, y - 1, z, fromDown)) || (MovementHelper.isLiquid(fromDown) && context.assumeWalkOnWater)) {
|
||||
// otherwise, if we're standing in water, we cannot pillar
|
||||
// if we're standing on water and assumeWalkOnWater is true, we cannot pillar
|
||||
// if we're standing on water and assumeWalkOnWater is false, we must have ascended to here, or sneak backplaced, so it is possible to pillar again
|
||||
@@ -102,20 +107,20 @@ public class MovementPillar extends Movement {
|
||||
if (toBreakBlock == Blocks.LADDER || toBreakBlock == Blocks.VINE) {
|
||||
hardness = 0; // we won't actually need to break the ladder / vine because we're going to use it
|
||||
} else {
|
||||
IBlockState check = context.get(x, y + 3, z); // the block on top of the one we're going to break, could it fall on us?
|
||||
if (check.getBlock() instanceof BlockFalling) {
|
||||
BlockState check = context.get(x, y + 3, z); // the block on top of the one we're going to break, could it fall on us?
|
||||
if (check.getBlock() instanceof FallingBlock) {
|
||||
// see MovementAscend's identical check for breaking a falling block above our head
|
||||
if (srcUp == null) {
|
||||
srcUp = context.get(x, y + 1, z).getBlock();
|
||||
srcUp = context.get(x, y + 1, z);
|
||||
}
|
||||
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp instanceof BlockFalling)) {
|
||||
if (!(toBreakBlock instanceof FallingBlock) || !(srcUp.getBlock() instanceof FallingBlock)) {
|
||||
return COST_INF;
|
||||
}
|
||||
}
|
||||
// this is commented because it may have had a purpose, but it's very unclear what it was. it's from the minebot era.
|
||||
//if (!MovementHelper.canWalkOn(chkPos, check) || MovementHelper.canWalkThrough(chkPos, check)) {//if the block above where we want to break is not a full block, don't do it
|
||||
// TODO why does canWalkThrough mean this action is COST_INF?
|
||||
// BlockFalling makes sense, and !canWalkOn deals with weird cases like if it were lava
|
||||
// FallingBlock makes sense, and !canWalkOn deals with weird cases like if it were lava
|
||||
// but I don't understand why canWalkThrough makes it impossible
|
||||
// return COST_INF;
|
||||
//}
|
||||
@@ -129,23 +134,23 @@ public class MovementPillar extends Movement {
|
||||
}
|
||||
|
||||
public static boolean hasAgainst(CalculationContext context, int x, int y, int z) {
|
||||
return context.get(x + 1, y, z).isBlockNormalCube() ||
|
||||
context.get(x - 1, y, z).isBlockNormalCube() ||
|
||||
context.get(x, y, z + 1).isBlockNormalCube() ||
|
||||
context.get(x, y, z - 1).isBlockNormalCube();
|
||||
return MovementHelper.isBlockNormalCube(context.get(x + 1, y, z)) ||
|
||||
MovementHelper.isBlockNormalCube(context.get(x - 1, y, z)) ||
|
||||
MovementHelper.isBlockNormalCube(context.get(x, y, z + 1)) ||
|
||||
MovementHelper.isBlockNormalCube(context.get(x, y, z - 1));
|
||||
}
|
||||
|
||||
public static BlockPos getAgainst(CalculationContext context, BetterBlockPos vine) {
|
||||
if (context.get(vine.north()).isBlockNormalCube()) {
|
||||
if (MovementHelper.isBlockNormalCube(context.get(vine.north()))) {
|
||||
return vine.north();
|
||||
}
|
||||
if (context.get(vine.south()).isBlockNormalCube()) {
|
||||
if (MovementHelper.isBlockNormalCube(context.get(vine.south()))) {
|
||||
return vine.south();
|
||||
}
|
||||
if (context.get(vine.east()).isBlockNormalCube()) {
|
||||
if (MovementHelper.isBlockNormalCube(context.get(vine.east()))) {
|
||||
return vine.east();
|
||||
}
|
||||
if (context.get(vine.west()).isBlockNormalCube()) {
|
||||
if (MovementHelper.isBlockNormalCube(context.get(vine.west()))) {
|
||||
return vine.west();
|
||||
}
|
||||
return null;
|
||||
@@ -162,8 +167,8 @@ public class MovementPillar extends Movement {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
|
||||
IBlockState fromDown = BlockStateInterface.get(ctx, src);
|
||||
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(ctx, dest)) {
|
||||
BlockState fromDown = BlockStateInterface.get(ctx, src);
|
||||
if (MovementHelper.isWater(fromDown) && MovementHelper.isWater(ctx, dest)) {
|
||||
// stay centered while swimming up a water column
|
||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()), false));
|
||||
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
||||
@@ -177,7 +182,7 @@ public class MovementPillar extends Movement {
|
||||
}
|
||||
boolean ladder = fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE;
|
||||
boolean vine = fromDown.getBlock() == Blocks.VINE;
|
||||
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
||||
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getEyePosition(1.0F),
|
||||
VecUtils.getBlockPosCenter(positionToPlace),
|
||||
new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch));
|
||||
if (!ladder) {
|
||||
@@ -186,7 +191,7 @@ public class MovementPillar extends Movement {
|
||||
|
||||
boolean blockIsThere = MovementHelper.canWalkOn(ctx, src) || ladder;
|
||||
if (ladder) {
|
||||
BlockPos against = vine ? getAgainst(new CalculationContext(baritone), src) : src.offset(fromDown.getValue(BlockLadder.FACING).getOpposite());
|
||||
BlockPos against = vine ? getAgainst(new CalculationContext(baritone), src) : src.offset(fromDown.get(LadderBlock.FACING).getOpposite());
|
||||
if (against == null) {
|
||||
logDebug("Unable to climb vines");
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
@@ -219,7 +224,7 @@ public class MovementPillar extends Movement {
|
||||
double diffX = ctx.player().posX - (dest.getX() + 0.5);
|
||||
double diffZ = ctx.player().posZ - (dest.getZ() + 0.5);
|
||||
double dist = Math.sqrt(diffX * diffX + diffZ * diffZ);
|
||||
double flatMotion = Math.sqrt(ctx.player().motionX * ctx.player().motionX + ctx.player().motionZ * ctx.player().motionZ);
|
||||
double flatMotion = Math.sqrt(ctx.player().getMotion().x * ctx.player().getMotion().x + ctx.player().getMotion().z * ctx.player().getMotion().z);
|
||||
if (dist > 0.17) {//why 0.17? because it seemed like a good number, that's why
|
||||
//[explanation added after baritone port lol] also because it needs to be less than 0.2 because of the 0.3 sneak limit
|
||||
//and 0.17 is reasonably less than 0.2
|
||||
@@ -236,18 +241,17 @@ public class MovementPillar extends Movement {
|
||||
|
||||
|
||||
if (!blockIsThere) {
|
||||
IBlockState frState = BlockStateInterface.get(ctx, src);
|
||||
BlockState frState = BlockStateInterface.get(ctx, 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));
|
||||
}
|
||||
if (!(fr instanceof AirBlock || frState.getMaterial().isReplaceable())) {
|
||||
RotationUtils.reachable(ctx.player(), src, ctx.playerController().getBlockReachDistance())
|
||||
.map(rot -> new MovementState.MovementTarget(rot, true))
|
||||
.ifPresent(state::setTarget);
|
||||
state.setInput(Input.JUMP, false); // breaking is like 5x slower when you're jumping
|
||||
state.setInput(Input.CLICK_LEFT, true);
|
||||
blockIsThere = false;
|
||||
} 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) {
|
||||
} else if (ctx.player().isSneaking() && (ctx.isLookingAt(src.down()) || ctx.isLookingAt(src)) && ctx.player().posY > dest.getY() + 0.1) {
|
||||
state.setInput(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +30,15 @@ import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.fluid.WaterFluid;
|
||||
import net.minecraft.state.properties.SlabType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class MovementTraverse extends Movement {
|
||||
|
||||
@@ -60,15 +62,21 @@ public class MovementTraverse extends Movement {
|
||||
return cost(context, src.x, src.y, src.z, dest.x, dest.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BetterBlockPos> calculateValidPositions() {
|
||||
return ImmutableSet.of(src, dest);
|
||||
}
|
||||
|
||||
public static double cost(CalculationContext context, int x, int y, int z, int destX, int destZ) {
|
||||
IBlockState pb0 = context.get(destX, y + 1, destZ);
|
||||
IBlockState pb1 = context.get(destX, y, destZ);
|
||||
IBlockState destOn = context.get(destX, y - 1, destZ);
|
||||
Block srcDown = context.getBlock(x, y - 1, z);
|
||||
BlockState pb0 = context.get(destX, y + 1, destZ);
|
||||
BlockState pb1 = context.get(destX, y, destZ);
|
||||
BlockState destOn = context.get(destX, y - 1, destZ);
|
||||
BlockState down = context.get(x, y - 1, z);
|
||||
Block srcDown = down.getBlock();
|
||||
if (MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
|
||||
double WC = WALK_ONE_BLOCK_COST;
|
||||
boolean water = false;
|
||||
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
|
||||
if (MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1)) {
|
||||
WC = context.waterWalkSpeed;
|
||||
water = true;
|
||||
} else {
|
||||
@@ -105,8 +113,8 @@ public class MovementTraverse extends Movement {
|
||||
return COST_INF;
|
||||
}
|
||||
if (MovementHelper.isReplacable(destX, y - 1, destZ, destOn, context.bsi)) {
|
||||
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
|
||||
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
|
||||
boolean throughWater = MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1);
|
||||
if (MovementHelper.isWater(destOn) && throughWater) {
|
||||
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
|
||||
return COST_INF;
|
||||
}
|
||||
@@ -121,9 +129,9 @@ public class MovementTraverse extends Movement {
|
||||
double hardness2 = MovementHelper.getMiningDurationTicks(context, destX, y + 1, destZ, pb0, true); // only include falling on the upper block to break
|
||||
double WC = throughWater ? context.waterWalkSpeed : WALK_ONE_BLOCK_COST;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
||||
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
||||
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
|
||||
int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
|
||||
int againstY = y - 1 + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getYOffset();
|
||||
int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
|
||||
if (againstX == x && againstZ == z) { // this would be a backplace
|
||||
continue;
|
||||
}
|
||||
@@ -132,10 +140,10 @@ public class MovementTraverse extends Movement {
|
||||
}
|
||||
}
|
||||
// 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 SlabBlock && down.get(SlabBlock.TYPE) != SlabType.DOUBLE)) {
|
||||
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 (down.getFluidState() instanceof WaterFluid) {
|
||||
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
|
||||
@@ -148,8 +156,8 @@ public class MovementTraverse extends Movement {
|
||||
@Override
|
||||
public MovementState updateState(MovementState state) {
|
||||
super.updateState(state);
|
||||
IBlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
|
||||
IBlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
|
||||
BlockState pb0 = BlockStateInterface.get(ctx, positionsToBreak[0]);
|
||||
BlockState pb1 = BlockStateInterface.get(ctx, positionsToBreak[1]);
|
||||
if (state.getStatus() != MovementStatus.RUNNING) {
|
||||
// if the setting is enabled
|
||||
if (!Baritone.settings().walkWhileBreaking.value) {
|
||||
@@ -160,10 +168,10 @@ public class MovementTraverse extends Movement {
|
||||
return state;
|
||||
}
|
||||
// and if it's fine to walk into the blocks in front
|
||||
if (MovementHelper.avoidWalkingInto(pb0.getBlock())) {
|
||||
if (MovementHelper.avoidWalkingInto(pb0)) {
|
||||
return state;
|
||||
}
|
||||
if (MovementHelper.avoidWalkingInto(pb1.getBlock())) {
|
||||
if (MovementHelper.avoidWalkingInto(pb1)) {
|
||||
return state;
|
||||
}
|
||||
// and we aren't already pressed up against the block
|
||||
@@ -171,18 +179,23 @@ public class MovementTraverse extends Movement {
|
||||
if (dist < 0.83) {
|
||||
return state;
|
||||
}
|
||||
if (!state.getTarget().getRotation().isPresent()) {
|
||||
// this can happen rarely when the server lags and doesn't send the falling sand entity until you've already walked through the block and are now mining the next one
|
||||
return state;
|
||||
}
|
||||
|
||||
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
|
||||
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
|
||||
float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest), ctx.playerRotations()).getYaw();
|
||||
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
|
||||
if ((pb0.isFullCube() || pb0.getBlock() instanceof BlockAir && (pb1.isFullCube() || pb1.getBlock() instanceof BlockAir))) {
|
||||
if ((MovementHelper.isBlockNormalCube(pb0) || pb0.getBlock() instanceof AirBlock && (MovementHelper.isBlockNormalCube(pb1) || pb1.getBlock() instanceof AirBlock))) {
|
||||
// in the meantime, before we're right up against the block, we can break efficiently at this angle
|
||||
pitchToBreak = 26;
|
||||
}
|
||||
|
||||
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
|
||||
return state.setInput(Input.MOVE_FORWARD, true).setInput(Input.SPRINT, true);
|
||||
return state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true))
|
||||
.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
|
||||
@@ -191,46 +204,43 @@ public class MovementTraverse extends Movement {
|
||||
Block fd = BlockStateInterface.get(ctx, src.down()).getBlock();
|
||||
boolean ladder = fd == Blocks.LADDER || fd == Blocks.VINE;
|
||||
|
||||
boolean door = pb0.getBlock() instanceof BlockDoor || pb1.getBlock() instanceof BlockDoor;
|
||||
if (door) {
|
||||
boolean isDoorActuallyBlockingUs = false;
|
||||
if (pb0.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(ctx, src, dest)) {
|
||||
isDoorActuallyBlockingUs = true;
|
||||
} else if (pb1.getBlock() instanceof BlockDoor && !MovementHelper.isDoorPassable(ctx, dest, src)) {
|
||||
isDoorActuallyBlockingUs = true;
|
||||
}
|
||||
if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
|
||||
if (pb0.getBlock() instanceof DoorBlock || pb1.getBlock() instanceof DoorBlock) {
|
||||
boolean notPassable = pb0.getBlock() instanceof DoorBlock && !MovementHelper.isDoorPassable(ctx, src, dest) || pb1.getBlock() instanceof DoorBlock && !MovementHelper.isDoorPassable(ctx, dest, src);
|
||||
boolean canOpen = !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()));
|
||||
|
||||
if (notPassable && canOpen) {
|
||||
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), positionsToBreak[0]), ctx.playerRotations()), true))
|
||||
.setInput(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (pb0.getBlock() instanceof BlockFenceGate || pb1.getBlock() instanceof BlockFenceGate) {
|
||||
BlockPos blocked = null;
|
||||
if (!MovementHelper.isGatePassable(ctx, positionsToBreak[0], src.up())) {
|
||||
blocked = positionsToBreak[0];
|
||||
} else if (!MovementHelper.isGatePassable(ctx, positionsToBreak[1], src)) {
|
||||
blocked = positionsToBreak[1];
|
||||
}
|
||||
|
||||
if (pb0.getBlock() instanceof FenceGateBlock || pb1.getBlock() instanceof FenceGateBlock) {
|
||||
BlockPos blocked = !MovementHelper.isGatePassable(ctx, positionsToBreak[0], src.up()) ? positionsToBreak[0]
|
||||
: !MovementHelper.isGatePassable(ctx, positionsToBreak[1], src) ? positionsToBreak[1]
|
||||
: null;
|
||||
if (blocked != null) {
|
||||
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), blocked), ctx.playerRotations()), true))
|
||||
.setInput(Input.CLICK_RIGHT, true);
|
||||
Optional<Rotation> rotation = RotationUtils.reachable(ctx, blocked);
|
||||
if (rotation.isPresent()) {
|
||||
return state.setTarget(new MovementState.MovementTarget(rotation.get(), true)).setInput(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isTheBridgeBlockThere = MovementHelper.canWalkOn(ctx, positionToPlace) || ladder;
|
||||
BlockPos whereAmI = ctx.playerFeet();
|
||||
if (whereAmI.getY() != dest.getY() && !ladder) {
|
||||
BlockPos feet = ctx.playerFeet();
|
||||
if (feet.getY() != dest.getY() && !ladder) {
|
||||
logDebug("Wrong Y coordinate");
|
||||
if (whereAmI.getY() < dest.getY()) {
|
||||
state.setInput(Input.JUMP, true);
|
||||
if (feet.getY() < dest.getY()) {
|
||||
return state.setInput(Input.JUMP, true);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
if (isTheBridgeBlockThere) {
|
||||
if (ctx.playerFeet().equals(dest)) {
|
||||
if (feet.equals(dest)) {
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
}
|
||||
if (Baritone.settings().overshootTraverse.value && (feet.equals(dest.add(getDirection())) || feet.equals(dest.add(getDirection()).add(getDirection())))) {
|
||||
return state.setStatus(MovementStatus.SUCCESS);
|
||||
}
|
||||
Block low = BlockStateInterface.get(ctx, src).getBlock();
|
||||
@@ -241,23 +251,23 @@ public class MovementTraverse extends Movement {
|
||||
return state;
|
||||
}
|
||||
BlockPos into = dest.subtract(src).add(dest);
|
||||
Block intoBelow = BlockStateInterface.get(ctx, into).getBlock();
|
||||
Block intoAbove = BlockStateInterface.get(ctx, into.up()).getBlock();
|
||||
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, ctx.playerFeet()) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
|
||||
BlockState intoBelow = BlockStateInterface.get(ctx, into);
|
||||
BlockState intoAbove = BlockStateInterface.get(ctx, into.up());
|
||||
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, feet) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
|
||||
state.setInput(Input.SPRINT, true);
|
||||
}
|
||||
|
||||
IBlockState destDown = BlockStateInterface.get(ctx, dest.down());
|
||||
BlockState destDown = BlockStateInterface.get(ctx, dest.down());
|
||||
BlockPos against = positionsToBreak[0];
|
||||
if (whereAmI.getY() != dest.getY() && ladder && (destDown.getBlock() == Blocks.VINE || destDown.getBlock() == Blocks.LADDER)) {
|
||||
against = destDown.getBlock() == Blocks.VINE ? MovementPillar.getAgainst(new CalculationContext(baritone), dest.down()) : dest.offset(destDown.getValue(BlockLadder.FACING).getOpposite());
|
||||
if (feet.getY() != dest.getY() && ladder && (destDown.getBlock() == Blocks.VINE || destDown.getBlock() == Blocks.LADDER)) {
|
||||
against = destDown.getBlock() == Blocks.VINE ? MovementPillar.getAgainst(new CalculationContext(baritone), dest.down()) : dest.offset(destDown.get(LadderBlock.FACING).getOpposite());
|
||||
}
|
||||
MovementHelper.moveTowards(ctx, state, against);
|
||||
return state;
|
||||
} else {
|
||||
wasTheBridgeBlockAlwaysThere = false;
|
||||
Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock();
|
||||
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
|
||||
Block standingOn = BlockStateInterface.get(ctx, feet.down()).getBlock();
|
||||
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof SlabBlock) { // 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);
|
||||
@@ -294,7 +304,7 @@ public class MovementTraverse extends Movement {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (whereAmI.equals(dest)) {
|
||||
if (feet.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
|
||||
// Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI);
|
||||
double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D;
|
||||
@@ -313,7 +323,7 @@ public class MovementTraverse extends Movement {
|
||||
} else {
|
||||
state.setTarget(new MovementState.MovementTarget(backToFace, true));
|
||||
}
|
||||
if (Objects.equals(ctx.getSelectedBlock().orElse(null), goalLook)) {
|
||||
if (ctx.isLookingAt(goalLook)) {
|
||||
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());
|
||||
|
||||
@@ -32,8 +32,7 @@ import baritone.pathing.movement.Movement;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.movements.*;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.util.Tuple;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
@@ -44,8 +43,7 @@ import java.util.*;
|
||||
import static baritone.api.pathing.movement.MovementStatus.*;
|
||||
|
||||
/**
|
||||
* Behavior to execute a precomputed path. Does not (yet) deal with path segmentation or stitching
|
||||
* or cutting (jumping onto the next path if it starts with a backtrack of this path's ending)
|
||||
* Behavior to execute a precomputed path
|
||||
*
|
||||
* @author leijurv
|
||||
*/
|
||||
@@ -100,14 +98,13 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
if (pathPosition >= path.length()) {
|
||||
return true; // stop bugging me, I'm done
|
||||
}
|
||||
BetterBlockPos whereShouldIBe = path.positions().get(pathPosition);
|
||||
Movement movement = (Movement) path.movements().get(pathPosition);
|
||||
BetterBlockPos whereAmI = ctx.playerFeet();
|
||||
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 (whereAmI.equals(path.positions().get(i))) {
|
||||
logDebug("Skipping back " + (pathPosition - i) + " steps, to " + i);
|
||||
if (!movement.getValidPositions().contains(whereAmI)) {
|
||||
for (int i = 0; i < pathPosition && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
|
||||
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
|
||||
int previousPos = pathPosition;
|
||||
pathPosition = Math.max(i - 1, 0); // previous step might not actually be done
|
||||
pathPosition = i;
|
||||
for (int j = pathPosition; j <= previousPos; j++) {
|
||||
path.movements().get(j).reset();
|
||||
}
|
||||
@@ -116,9 +113,9 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
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)
|
||||
for (int i = pathPosition + 3; i < path.length() - 1; 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
|
||||
if (whereAmI.equals(path.positions().get(i))) {
|
||||
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
|
||||
if (i - pathPosition > 2) {
|
||||
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
|
||||
}
|
||||
@@ -133,7 +130,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
Tuple<Double, BlockPos> status = closestPathPos(path);
|
||||
if (possiblyOffPath(status, MAX_DIST_FROM_PATH)) {
|
||||
ticksAway++;
|
||||
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getFirst() + ". Threshold: " + MAX_DIST_FROM_PATH);
|
||||
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getA() + ". Threshold: " + MAX_DIST_FROM_PATH);
|
||||
if (ticksAway > MAX_TICKS_AWAY) {
|
||||
logDebug("Too far away from path for too long, cancelling path");
|
||||
cancel();
|
||||
@@ -147,38 +144,6 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
cancel();
|
||||
return false;
|
||||
}
|
||||
//this commented block is literally cursed.
|
||||
/*Out.log(actions.get(pathPosition));
|
||||
if (pathPosition < actions.size() - 1) {//if there are two ActionBridges in a row and they are at right angles, walk diagonally. This makes it so you walk at 45 degrees along a zigzag path instead of doing inefficient zigging and zagging
|
||||
if ((actions.get(pathPosition) instanceof ActionBridge) && (actions.get(pathPosition + 1) instanceof ActionBridge)) {
|
||||
ActionBridge curr = (ActionBridge) actions.get(pathPosition);
|
||||
ActionBridge next = (ActionBridge) actions.get(pathPosition + 1);
|
||||
if (curr.dx() != next.dx() || curr.dz() != next.dz()) {//two movement are not parallel, so this is a right angle
|
||||
if (curr.amIGood() && next.amIGood()) {//nothing in the way
|
||||
BlockPos cornerToCut1 = new BlockPos(next.to.getX() - next.from.getX() + curr.from.getX(), next.to.getY(), next.to.getZ() - next.from.getZ() + curr.from.getZ());
|
||||
BlockPos cornerToCut2 = cornerToCut1.up();
|
||||
//Block corner1 = Baritone.get(cornerToCut1).getBlock();
|
||||
//Block corner2 = Baritone.get(cornerToCut2).getBlock();
|
||||
//Out.gui("Cutting conner " + cornerToCut1 + " " + corner1, Out.Mode.Debug);
|
||||
if (!Action.avoidWalkingInto(cornerToCut1) && !Action.avoidWalkingInto(cornerToCut2)) {
|
||||
double x = (next.from.getX() + next.to.getX() + 1.0D) * 0.5D;
|
||||
double z = (next.from.getZ() + next.to.getZ() + 1.0D) * 0.5D;
|
||||
MovementManager.clearMovement();
|
||||
if (!MovementManager.forward && curr.oneInTen != null && curr.oneInTen) {
|
||||
MovementManager.clearMovement();
|
||||
MovementManager.forward = LookManager.lookAtCoords(x, 0, z, false);
|
||||
} else {
|
||||
MovementManager.moveTowardsCoords(x, 0, z);
|
||||
}
|
||||
if (MovementManager.forward && !MovementManager.backward) {
|
||||
thePlayer.setSprinting(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
//long start = System.nanoTime() / 1000000L;
|
||||
BlockStateInterface bsi = new BlockStateInterface(ctx);
|
||||
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
|
||||
@@ -205,10 +170,10 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
HashSet<BlockPos> newPlace = new HashSet<>();
|
||||
HashSet<BlockPos> newWalkInto = new HashSet<>();
|
||||
for (int i = pathPosition; i < path.movements().size(); i++) {
|
||||
Movement movement = (Movement) path.movements().get(i);
|
||||
newBreak.addAll(movement.toBreak(bsi));
|
||||
newPlace.addAll(movement.toPlace(bsi));
|
||||
newWalkInto.addAll(movement.toWalkInto(bsi));
|
||||
Movement m = (Movement) path.movements().get(i);
|
||||
newBreak.addAll(m.toBreak(bsi));
|
||||
newPlace.addAll(m.toPlace(bsi));
|
||||
newWalkInto.addAll(m.toWalkInto(bsi));
|
||||
}
|
||||
toBreak = newBreak;
|
||||
toPlace = newPlace;
|
||||
@@ -219,7 +184,14 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
if (end - start > 0) {
|
||||
System.out.println("Recalculating break and place took " + (end - start) + "ms");
|
||||
}*/
|
||||
IMovement movement = path.movements().get(pathPosition);
|
||||
if (pathPosition < path.movements().size() - 1) {
|
||||
IMovement next = path.movements().get(pathPosition + 1);
|
||||
if (!behavior.baritone.bsi.worldContainsLoadedChunk(next.getDest().x, next.getDest().z)) {
|
||||
logDebug("Pausing since destination is at edge of loaded chunks");
|
||||
clearKeys();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
boolean canCancel = movement.safeToCancel();
|
||||
if (costEstimateIndex == null || costEstimateIndex != pathPosition) {
|
||||
costEstimateIndex = pathPosition;
|
||||
@@ -233,7 +205,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
}
|
||||
}
|
||||
}
|
||||
double currentCost = ((Movement) movement).recalculateCost(behavior.secretInternalGetCalculationContext());
|
||||
double currentCost = movement.recalculateCost(behavior.secretInternalGetCalculationContext());
|
||||
if (currentCost >= ActionCosts.COST_INF && canCancel) {
|
||||
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
|
||||
cancel();
|
||||
@@ -285,11 +257,13 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
private Tuple<Double, BlockPos> closestPathPos(IPath path) {
|
||||
double best = -1;
|
||||
BlockPos bestPos = null;
|
||||
for (BlockPos pos : path.positions()) {
|
||||
double dist = VecUtils.entityDistanceToCenter(ctx.player(), pos);
|
||||
if (dist < best || best == -1) {
|
||||
best = dist;
|
||||
bestPos = pos;
|
||||
for (IMovement movement : path.movements()) {
|
||||
for (BlockPos pos : ((Movement) movement).getValidPositions()) {
|
||||
double dist = VecUtils.entityDistanceToCenter(ctx.player(), pos);
|
||||
if (dist < best || best == -1) {
|
||||
best = dist;
|
||||
bestPos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Tuple<>(best, bestPos);
|
||||
@@ -329,7 +303,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
}
|
||||
|
||||
private boolean possiblyOffPath(Tuple<Double, BlockPos> status, double leniency) {
|
||||
double distanceFromPath = status.getFirst();
|
||||
double distanceFromPath = status.getA();
|
||||
if (distanceFromPath > leniency) {
|
||||
// when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path
|
||||
if (path.movements().get(pathPosition) instanceof MovementFall) {
|
||||
@@ -349,12 +323,12 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
* @return Whether or not it was possible to snap to the current player feet
|
||||
*/
|
||||
public boolean snipsnapifpossible() {
|
||||
if (!ctx.player().onGround && !(ctx.world().getBlockState(ctx.playerFeet()).getBlock() instanceof BlockLiquid)) {
|
||||
if (!ctx.player().onGround && ctx.world().getFluidState(ctx.playerFeet()).isEmpty()) {
|
||||
// if we're falling in the air, and not in water, don't splice
|
||||
return false;
|
||||
} else {
|
||||
// we are either onGround or in liquid
|
||||
if (ctx.player().motionY < -0.1) {
|
||||
if (ctx.player().getMotion().y < -0.1) {
|
||||
// if we are strictly moving downwards (not stationary)
|
||||
// we could be falling through water, which could be unsafe to splice
|
||||
return false; // so don't
|
||||
@@ -452,7 +426,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
if (current instanceof MovementFall) {
|
||||
Tuple<Vec3d, BlockPos> data = overrideFall((MovementFall) current);
|
||||
if (data != null) {
|
||||
BlockPos fallDest = data.getSecond();
|
||||
BetterBlockPos fallDest = new BetterBlockPos(data.getB());
|
||||
if (!path.positions().contains(fallDest)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
@@ -463,7 +437,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
return true;
|
||||
}
|
||||
clearKeys();
|
||||
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getFirst(), ctx.playerRotations()), false);
|
||||
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getA(), ctx.playerRotations()), false);
|
||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true);
|
||||
return true;
|
||||
}
|
||||
@@ -555,10 +529,10 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)).getBlock())) {
|
||||
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)))) {
|
||||
return false;
|
||||
}
|
||||
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2)).getBlock()); // codacy smh my head
|
||||
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2))); // codacy smh my head
|
||||
}
|
||||
|
||||
private static boolean canSprintFromDescendInto(IPlayerContext ctx, IMovement current, IMovement next) {
|
||||
@@ -610,7 +584,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
||||
ret.costEstimateIndex = costEstimateIndex;
|
||||
ret.ticksOnCurrent = ticksOnCurrent;
|
||||
return ret;
|
||||
}).orElse(cutIfTooLong());
|
||||
}).orElseGet(this::cutIfTooLong); // dont actually call cutIfTooLong every tick if we won't actually use it, use a method reference
|
||||
}
|
||||
|
||||
private PathExecutor cutIfTooLong() {
|
||||
|
||||
@@ -26,18 +26,17 @@ import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BackfillProcess extends BaritoneProcessHelper {
|
||||
public final class BackfillProcess extends BaritoneProcessHelper {
|
||||
|
||||
public HashMap<BlockPos, IBlockState> blocksToReplace = new HashMap<>();
|
||||
public HashMap<BlockPos, BlockState> blocksToReplace = new HashMap<>();
|
||||
|
||||
public BackfillProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
@@ -85,12 +84,14 @@ public class BackfillProcess extends BaritoneProcessHelper {
|
||||
// patience
|
||||
baritone.getLookBehavior().updateTarget(fake.getTarget().getRotation().get(), true);
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.DEFER); // cede to other process
|
||||
}
|
||||
|
||||
public void amIBreakingABlockHMMMMMMM() {
|
||||
private void amIBreakingABlockHMMMMMMM() {
|
||||
if (!ctx.getSelectedBlock().isPresent()) {
|
||||
return;
|
||||
}
|
||||
@@ -102,9 +103,9 @@ public class BackfillProcess extends BaritoneProcessHelper {
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter(pos -> ctx.world().getBlockState(pos).getBlock() == Blocks.AIR)
|
||||
.filter(pos -> ctx.world().mayPlace(Blocks.DIRT, pos, false, EnumFacing.UP, null))
|
||||
.filter(pos -> baritone.getBuilderProcess().placementPlausible(pos, Blocks.DIRT.getDefaultState()))
|
||||
.filter(pos -> !partOfCurrentMovement(pos))
|
||||
.sorted(Comparator.<BlockPos>comparingDouble(ctx.player()::getDistanceSq).reversed())
|
||||
.sorted(Comparator.<BlockPos>comparingDouble(ctx.playerFeet()::distanceSq).reversed())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -35,27 +35,35 @@ 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.init.Blocks;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import baritone.utils.schematic.schematica.SchematicaHelper;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.block.AirBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.FlowingFluidBlock;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Tuple;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
|
||||
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 final class BuilderProcess extends BaritoneProcessHelper implements IBuilderProcess {
|
||||
|
||||
private HashSet<BetterBlockPos> incorrectPositions;
|
||||
private LongOpenHashSet observedCompleted; // positions that are completed even if they're out of render distance and we can't make sure right now
|
||||
private String name;
|
||||
private ISchematic realSchematic;
|
||||
private ISchematic schematic;
|
||||
@@ -76,6 +84,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
this.origin = origin;
|
||||
this.paused = false;
|
||||
this.layer = 0;
|
||||
this.observedCompleted = new LongOpenHashSet();
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
@@ -88,7 +97,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
|
||||
@Override
|
||||
public boolean build(String name, File schematic, Vec3i origin) {
|
||||
NBTTagCompound tag;
|
||||
CompoundNBT tag;
|
||||
try (FileInputStream fileIn = new FileInputStream(schematic)) {
|
||||
tag = CompressedStreamTools.readCompressed(fileIn);
|
||||
} catch (IOException e) {
|
||||
@@ -102,6 +111,20 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildOpenSchematic() {
|
||||
if (SchematicaHelper.isSchematicaPresent()) {
|
||||
Optional<Tuple<ISchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
|
||||
if (schematic.isPresent()) {
|
||||
this.build(schematic.get().getA().toString(), schematic.get().getA(), schematic.get().getB());
|
||||
} else {
|
||||
logDirect("No schematic currently open");
|
||||
}
|
||||
} else {
|
||||
logDirect("Schematica is not present");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -110,7 +133,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
build("clear area", new AirSchematic(widthX, heightY, lengthZ), origin);
|
||||
}
|
||||
|
||||
private static ISchematic parse(NBTTagCompound schematic) {
|
||||
private static ISchematic parse(CompoundNBT schematic) {
|
||||
return new Schematic(schematic);
|
||||
}
|
||||
|
||||
@@ -119,35 +142,38 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return schematic != null;
|
||||
}
|
||||
|
||||
public IBlockState placeAt(int x, int y, int z) {
|
||||
public BlockState 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) {
|
||||
BlockState state = schematic.desiredState(x - origin.getX(), y - origin.getY(), z - origin.getZ());
|
||||
if (state.getBlock() instanceof AirBlock) {
|
||||
return null;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
public Optional<Tuple<BetterBlockPos, Rotation>> toBreakNearPlayer(BuilderCalculationContext bcc) {
|
||||
private Optional<Tuple<BetterBlockPos, Rotation>> toBreakNearPlayer(BuilderCalculationContext bcc) {
|
||||
BetterBlockPos center = ctx.playerFeet();
|
||||
BetterBlockPos pathStart = baritone.getPathingBehavior().pathStart();
|
||||
for (int dx = -5; dx <= 5; dx++) {
|
||||
for (int dy = 0; dy <= 5; dy++) {
|
||||
for (int dy = Baritone.settings().breakFromAbove.value ? -1 : 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 (dy == -1 && x == pathStart.x && z == pathStart.z) {
|
||||
continue; // dont mine what we're supported by, but not directly standing on
|
||||
}
|
||||
BlockState 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)) {
|
||||
BlockState curr = bcc.bsi.get0(x, y, z);
|
||||
if (!(curr.getBlock() instanceof AirBlock) && !(curr.getBlock() == Blocks.WATER || curr.getBlock() == Blocks.LAVA) && !valid(curr, desired)) {
|
||||
BetterBlockPos pos = new BetterBlockPos(x, y, z);
|
||||
Optional<Rotation> rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
|
||||
if (rot.isPresent()) {
|
||||
@@ -163,10 +189,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
public class Placement {
|
||||
private final int hotbarSelection;
|
||||
private final BlockPos placeAgainst;
|
||||
private final EnumFacing side;
|
||||
private final Direction side;
|
||||
private final Rotation rot;
|
||||
|
||||
public Placement(int hotbarSelection, BlockPos placeAgainst, EnumFacing side, Rotation rot) {
|
||||
public Placement(int hotbarSelection, BlockPos placeAgainst, Direction side, Rotation rot) {
|
||||
this.hotbarSelection = hotbarSelection;
|
||||
this.placeAgainst = placeAgainst;
|
||||
this.side = side;
|
||||
@@ -174,7 +200,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<Placement> searchForPlacables(BuilderCalculationContext bcc, List<IBlockState> desirableOnHotbar) {
|
||||
private Optional<Placement> searchForPlacables(BuilderCalculationContext bcc, List<BlockState> desirableOnHotbar) {
|
||||
BetterBlockPos center = ctx.playerFeet();
|
||||
for (int dx = -5; dx <= 5; dx++) {
|
||||
for (int dy = -5; dy <= 1; dy++) {
|
||||
@@ -182,13 +208,13 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
int x = center.x + dx;
|
||||
int y = center.y + dy;
|
||||
int z = center.z + dz;
|
||||
IBlockState desired = bcc.getSchematic(x, y, z);
|
||||
BlockState desired = bcc.getSchematic(x, y, z);
|
||||
if (desired == null) {
|
||||
continue; // irrelevant
|
||||
}
|
||||
IBlockState curr = bcc.bsi.get0(x, y, z);
|
||||
BlockState 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) {
|
||||
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() instanceof AirBlock) {
|
||||
continue;
|
||||
}
|
||||
desirableOnHotbar.add(desired);
|
||||
@@ -203,24 +229,32 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<Placement> possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) {
|
||||
for (EnumFacing against : EnumFacing.values()) {
|
||||
public boolean placementPlausible(BlockPos pos, BlockState state) {
|
||||
VoxelShape voxelshape = state.getCollisionShape(ctx.world(), pos);
|
||||
return voxelshape.isEmpty() || ctx.world().checkNoEntityCollision(null, voxelshape.withOffset(pos.getX(), pos.getY(), pos.getZ()));
|
||||
}
|
||||
|
||||
private Optional<Placement> possibleToPlace(BlockState toPlace, int x, int y, int z, BlockStateInterface bsi) {
|
||||
for (Direction against : Direction.values()) {
|
||||
BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against);
|
||||
IBlockState placeAgainstState = bsi.get0(placeAgainstPos);
|
||||
BlockState 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)) {
|
||||
if (!toPlace.isValidPosition(ctx.world(), new BetterBlockPos(x, y, z))) {
|
||||
continue;
|
||||
}
|
||||
AxisAlignedBB aabb = placeAgainstState.getBoundingBox(ctx.world(), placeAgainstPos);
|
||||
if (!placementPlausible(new BetterBlockPos(x, y, z), toPlace)) {
|
||||
continue;
|
||||
}
|
||||
AxisAlignedBB aabb = placeAgainstState.getShape(ctx.world(), placeAgainstPos).getBoundingBox();
|
||||
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()) {
|
||||
if (result != null && result.getType() == RayTraceResult.Type.BLOCK && ((BlockRayTraceResult) result).getPos().equals(placeAgainstPos) && ((BlockRayTraceResult) result).getFace() == against.getOpposite()) {
|
||||
OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot);
|
||||
if (hotbar.isPresent()) {
|
||||
return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot));
|
||||
@@ -231,11 +265,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
public OptionalInt hasAnyItemThatWouldPlace(IBlockState desired, RayTraceResult result, Rotation rot) {
|
||||
private OptionalInt hasAnyItemThatWouldPlace(BlockState 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)) {
|
||||
if (stack.isEmpty() || !(stack.getItem() instanceof BlockItem)) {
|
||||
continue;
|
||||
}
|
||||
float originalYaw = ctx.player().rotationYaw;
|
||||
@@ -243,18 +276,22 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
// 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(
|
||||
BlockItemUseContext meme = new BlockItemUseContext(new ItemUseContext(
|
||||
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(),
|
||||
Hand.MAIN_HAND,
|
||||
stack,
|
||||
(BlockRayTraceResult) result
|
||||
) {}); // that {} gives us access to a protected constructor lmfao
|
||||
BlockState wouldBePlaced = ((BlockItem) stack.getItem()).getBlock().getStateForPlacement(meme);
|
||||
ctx.player().rotationYaw = originalYaw;
|
||||
ctx.player().rotationPitch = originalPitch;
|
||||
if (wouldBePlaced == null) {
|
||||
continue;
|
||||
}
|
||||
if (!meme.canPlace()) {
|
||||
continue;
|
||||
}
|
||||
if (valid(wouldBePlaced, desired)) {
|
||||
return OptionalInt.of(i);
|
||||
}
|
||||
@@ -262,7 +299,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
private static Vec3d[] aabbSideMultipliers(EnumFacing side) {
|
||||
private static Vec3d[] aabbSideMultipliers(Direction 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)};
|
||||
@@ -295,12 +332,29 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
if (realSchematic == null) {
|
||||
realSchematic = schematic;
|
||||
}
|
||||
ISchematic realSchematic = this.realSchematic; // wrap this properly, dont just have the inner class refer to the builderprocess.this
|
||||
int minYInclusive;
|
||||
int maxYInclusive;
|
||||
// layer = 0 should be nothing
|
||||
// layer = realSchematic.heightY() should be everything
|
||||
if (Baritone.settings().layerOrder.value) { // top to bottom
|
||||
maxYInclusive = realSchematic.heightY() - 1;
|
||||
minYInclusive = realSchematic.heightY() - layer;
|
||||
} else {
|
||||
maxYInclusive = layer - 1;
|
||||
minYInclusive = 0;
|
||||
}
|
||||
schematic = new ISchematic() {
|
||||
@Override
|
||||
public IBlockState desiredState(int x, int y, int z) {
|
||||
public BlockState desiredState(int x, int y, int z) {
|
||||
return realSchematic.desiredState(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inSchematic(int x, int y, int z) {
|
||||
return ISchematic.super.inSchematic(x, y, z) && y >= minYInclusive && y <= maxYInclusive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int widthX() {
|
||||
return realSchematic.widthX();
|
||||
@@ -308,7 +362,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
|
||||
@Override
|
||||
public int heightY() {
|
||||
return layer;
|
||||
return realSchematic.heightY();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -324,29 +378,26 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
layer++;
|
||||
return onTick(calcFailed, isSafeToCancel);
|
||||
}
|
||||
int distance = Baritone.settings().buildRepeatDistance.value;
|
||||
EnumFacing direction = Baritone.settings().buildRepeatDirection.value;
|
||||
if (distance == 0) {
|
||||
Vec3i repeat = Baritone.settings().buildRepeat.value;
|
||||
if (repeat.equals(new Vec3i(0, 0, 0))) {
|
||||
logDirect("Done building");
|
||||
onLostControl();
|
||||
return null;
|
||||
}
|
||||
// build repeat time
|
||||
if (distance == -1) {
|
||||
distance = schematic.size(direction.getAxis());
|
||||
}
|
||||
layer = 0;
|
||||
origin = new BlockPos(origin).offset(direction, distance);
|
||||
logDirect("Repeating build " + distance + " blocks to the " + direction + ", new origin is " + origin);
|
||||
origin = new BlockPos(origin).add(repeat);
|
||||
logDirect("Repeating build in vector " + repeat + ", new origin is " + origin);
|
||||
return onTick(calcFailed, isSafeToCancel);
|
||||
}
|
||||
trim(bcc);
|
||||
trim();
|
||||
|
||||
Optional<Tuple<BetterBlockPos, Rotation>> toBreak = toBreakNearPlayer(bcc);
|
||||
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();
|
||||
Rotation rot = toBreak.get().getB();
|
||||
BetterBlockPos pos = toBreak.get().getA();
|
||||
baritone.getLookBehavior().updateTarget(rot, true);
|
||||
MovementHelper.switchToBestToolFor(ctx, bcc.get(pos));
|
||||
if (ctx.player().isSneaking()) {
|
||||
@@ -360,25 +411,25 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
List<IBlockState> desirableOnHotbar = new ArrayList<>();
|
||||
List<BlockState> 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 ((ctx.isLookingAt(toPlace.get().placeAgainst) && ctx.objectMouseOver().sideHit.equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||
if ((ctx.isLookingAt(toPlace.get().placeAgainst) && ((BlockRayTraceResult) ctx.objectMouseOver()).getFace().equals(toPlace.get().side)) || ctx.playerRotations().isReallyCloseTo(rot)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
|
||||
List<IBlockState> approxPlacable = placable(36);
|
||||
List<BlockState> approxPlacable = placable(36);
|
||||
if (Baritone.settings().allowInventory.value) {
|
||||
ArrayList<Integer> usefulSlots = new ArrayList<>();
|
||||
List<IBlockState> noValidHotbarOption = new ArrayList<>();
|
||||
List<BlockState> noValidHotbarOption = new ArrayList<>();
|
||||
outer:
|
||||
for (IBlockState desired : desirableOnHotbar) {
|
||||
for (BlockState desired : desirableOnHotbar) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (valid(approxPlacable.get(i), desired)) {
|
||||
usefulSlots.add(i);
|
||||
@@ -390,7 +441,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
|
||||
outer:
|
||||
for (int i = 9; i < 36; i++) {
|
||||
for (IBlockState desired : noValidHotbarOption) {
|
||||
for (BlockState desired : noValidHotbarOption) {
|
||||
if (valid(approxPlacable.get(i), desired)) {
|
||||
baritone.getInventoryBehavior().attemptToPutOnHotbar(i, usefulSlots::contains);
|
||||
break outer;
|
||||
@@ -399,7 +450,6 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
@@ -412,7 +462,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc);
|
||||
}
|
||||
|
||||
public boolean recalc(BuilderCalculationContext bcc) {
|
||||
private boolean recalc(BuilderCalculationContext bcc) {
|
||||
if (incorrectPositions == null) {
|
||||
incorrectPositions = new HashSet<>();
|
||||
fullRecalc(bcc);
|
||||
@@ -427,15 +477,15 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return !incorrectPositions.isEmpty();
|
||||
}
|
||||
|
||||
public void trim(BuilderCalculationContext bcc) {
|
||||
private void trim() {
|
||||
HashSet<BetterBlockPos> copy = new HashSet<>(incorrectPositions);
|
||||
copy.removeIf(pos -> pos.distanceSq(ctx.player().posX, ctx.player().posY, ctx.player().posZ) > 200);
|
||||
copy.removeIf(pos -> pos.distanceSq(new BlockPos(ctx.player())) > 200);
|
||||
if (!copy.isEmpty()) {
|
||||
incorrectPositions = copy;
|
||||
}
|
||||
}
|
||||
|
||||
public void recalcNearby(BuilderCalculationContext bcc) {
|
||||
private void recalcNearby(BuilderCalculationContext bcc) {
|
||||
BetterBlockPos center = ctx.playerFeet();
|
||||
for (int dx = -5; dx <= 5; dx++) {
|
||||
for (int dy = -5; dy <= 5; dy++) {
|
||||
@@ -443,13 +493,16 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
int x = center.x + dx;
|
||||
int y = center.y + dy;
|
||||
int z = center.z + dz;
|
||||
IBlockState desired = bcc.getSchematic(x, y, z);
|
||||
BlockState desired = bcc.getSchematic(x, y, z);
|
||||
if (desired != null) {
|
||||
// we care about this position
|
||||
BetterBlockPos pos = new BetterBlockPos(x, y, z);
|
||||
if (valid(bcc.bsi.get0(x, y, z), desired)) {
|
||||
incorrectPositions.remove(new BetterBlockPos(x, y, z));
|
||||
incorrectPositions.remove(pos);
|
||||
observedCompleted.add(BetterBlockPos.longHash(pos));
|
||||
} else {
|
||||
incorrectPositions.add(new BetterBlockPos(x, y, z));
|
||||
incorrectPositions.add(pos);
|
||||
observedCompleted.remove(BetterBlockPos.longHash(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -457,31 +510,78 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
}
|
||||
}
|
||||
|
||||
public void fullRecalc(BuilderCalculationContext bcc) {
|
||||
private 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) && !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()));
|
||||
if (!schematic.inSchematic(x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
int blockX = x + origin.getX();
|
||||
int blockY = y + origin.getY();
|
||||
int blockZ = z + origin.getZ();
|
||||
if (bcc.bsi.worldContainsLoadedChunk(blockX, blockZ)) { // check if its in render distance, not if its in cache
|
||||
// we can directly observe this block, it is in render distance
|
||||
if (valid(bcc.bsi.get0(blockX, blockY, blockZ), schematic.desiredState(x, y, z))) {
|
||||
observedCompleted.add(BetterBlockPos.longHash(blockX, blockY, blockZ));
|
||||
} else {
|
||||
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
|
||||
observedCompleted.remove(BetterBlockPos.longHash(blockX, blockY, blockZ));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// this is not in render distance
|
||||
if (!observedCompleted.contains(BetterBlockPos.longHash(blockX, blockY, blockZ))) {
|
||||
// and we've never seen this position be correct
|
||||
// therefore mark as incorrect
|
||||
incorrectPositions.add(new BetterBlockPos(blockX, blockY, blockZ));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
private Goal assemble(BuilderCalculationContext bcc, List<BlockState> approxPlacable) {
|
||||
List<BetterBlockPos> placable = new ArrayList<>();
|
||||
List<BetterBlockPos> breakable = new ArrayList<>();
|
||||
List<BetterBlockPos> sourceLiquids = new ArrayList<>();
|
||||
incorrectPositions.forEach(pos -> {
|
||||
BlockState state = bcc.bsi.get0(pos);
|
||||
if (state.getBlock() instanceof AirBlock) {
|
||||
if (approxPlacable.contains(bcc.getSchematic(pos.x, pos.y, pos.z))) {
|
||||
placable.add(pos);
|
||||
}
|
||||
} else {
|
||||
if (state.getBlock() instanceof FlowingFluidBlock) {
|
||||
// if the block itself is JUST a liquid (i.e. not just a waterlogged block), we CANNOT break it
|
||||
// TODO for 1.13 make sure that this only matches pure water, not waterlogged blocks
|
||||
if (!MovementHelper.possiblyFlowing(state)) {
|
||||
// if it's a source block then we want to replace it with a throwaway
|
||||
sourceLiquids.add(pos);
|
||||
}
|
||||
} else {
|
||||
breakable.add(pos);
|
||||
}
|
||||
}
|
||||
});
|
||||
List<Goal> toBreak = new ArrayList<>();
|
||||
breakable.forEach(pos -> toBreak.add(breakGoal(pos, bcc)));
|
||||
List<Goal> toPlace = new ArrayList<>();
|
||||
placable.forEach(pos -> {
|
||||
if (!placable.contains(pos.down()) && !placable.contains(pos.down(2))) {
|
||||
toPlace.add(placementGoal(pos, bcc));
|
||||
}
|
||||
});
|
||||
sourceLiquids.forEach(pos -> toPlace.add(new GoalBlock(pos.up())));
|
||||
|
||||
if (toPlace.length != 0) {
|
||||
return new JankyGoalComposite(new GoalComposite(toPlace), new GoalComposite(toBreak));
|
||||
if (!toPlace.isEmpty()) {
|
||||
return new JankyGoalComposite(new GoalComposite(toPlace.toArray(new Goal[0])), new GoalComposite(toBreak.toArray(new Goal[0])));
|
||||
}
|
||||
if (toBreak.length == 0) {
|
||||
if (toBreak.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return new GoalComposite(toBreak);
|
||||
return new GoalComposite(toBreak.toArray(new Goal[0]));
|
||||
}
|
||||
|
||||
public static class JankyGoalComposite implements Goal {
|
||||
@@ -527,19 +627,34 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
}
|
||||
}
|
||||
|
||||
public Goal placementgoal(BlockPos pos, BuilderCalculationContext bcc) {
|
||||
if (ctx.world().getBlockState(pos).getBlock() != Blocks.AIR) {
|
||||
private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) {
|
||||
if (!(ctx.world().getBlockState(pos).getBlock() instanceof AirBlock)) { // TODO can this even happen?
|
||||
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)) {
|
||||
boolean allowSameLevel = !(ctx.world().getBlockState(pos.up()).getBlock() instanceof AirBlock);
|
||||
for (Direction facing : Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP) {
|
||||
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && placementPlausible(pos, bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ()))) {
|
||||
return new GoalAdjacent(pos, allowSameLevel);
|
||||
}
|
||||
}
|
||||
return new GoalPlace(pos);
|
||||
}
|
||||
|
||||
private Goal breakGoal(BlockPos pos, BuilderCalculationContext bcc) {
|
||||
if (Baritone.settings().goalBreakFromAbove.value && bcc.bsi.get0(pos.up()).getBlock() instanceof AirBlock && bcc.bsi.get0(pos.up(2)).getBlock() instanceof AirBlock) { // TODO maybe possible without the up(2) check?
|
||||
return new JankyGoalComposite(new GoalBreak(pos), new GoalGetToBlock(pos.up()) {
|
||||
@Override
|
||||
public boolean isInGoal(int x, int y, int z) {
|
||||
if (y > this.y || (x == this.x && y == this.y && z == this.z)) {
|
||||
return false;
|
||||
}
|
||||
return super.isInGoal(x, y, z);
|
||||
}
|
||||
});
|
||||
}
|
||||
return new GoalBreak(pos);
|
||||
}
|
||||
|
||||
public static class GoalAdjacent extends GoalGetToBlock {
|
||||
private boolean allowSameLevel;
|
||||
|
||||
@@ -586,6 +701,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
realSchematic = null;
|
||||
layer = 0;
|
||||
paused = false;
|
||||
observedCompleted = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -593,28 +709,34 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
return paused ? "Builder Paused" : "Building " + name;
|
||||
}
|
||||
|
||||
public List<IBlockState> placable(int size) {
|
||||
List<IBlockState> result = new ArrayList<>();
|
||||
private List<BlockState> placable(int size) {
|
||||
List<BlockState> 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)) {
|
||||
if (stack.isEmpty() || !(stack.getItem() instanceof BlockItem)) {
|
||||
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()));
|
||||
result.add(((BlockItem) stack.getItem()).getBlock().getStateForPlacement(new BlockItemUseContext(new ItemUseContext(ctx.world(), ctx.player(), Hand.MAIN_HAND, stack, new BlockRayTraceResult(new Vec3d(ctx.player().posX, ctx.player().posY, ctx.player().posZ), Direction.UP, ctx.playerFeet(), false)) {})));
|
||||
// </toxic cloud>
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean valid(IBlockState current, IBlockState desired) {
|
||||
private boolean valid(BlockState current, BlockState desired) {
|
||||
if (desired == null) {
|
||||
return true;
|
||||
}
|
||||
if (current.getBlock() instanceof AirBlock && desired.getBlock() instanceof AirBlock) {
|
||||
return true;
|
||||
}
|
||||
// TODO more complicated comparison logic I guess
|
||||
return desired == null || current.equals(desired);
|
||||
return current.equals(desired);
|
||||
}
|
||||
|
||||
public class BuilderCalculationContext extends CalculationContext {
|
||||
private final List<IBlockState> placable;
|
||||
private final List<BlockState> placable;
|
||||
private final ISchematic schematic;
|
||||
private final int originX;
|
||||
private final int originY;
|
||||
@@ -632,7 +754,7 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
this.backtrackCostFavoringCoefficient = 1;
|
||||
}
|
||||
|
||||
private IBlockState getSchematic(int x, int y, int z) {
|
||||
private BlockState 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 {
|
||||
@@ -645,10 +767,10 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
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);
|
||||
BlockState 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) {
|
||||
if (sch.getBlock() instanceof AirBlock) {
|
||||
// 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
|
||||
@@ -679,9 +801,9 @@ public class BuilderProcess extends BaritoneProcessHelper implements IBuilderPro
|
||||
if (!allowBreak || isPossiblyProtected(x, y, z)) {
|
||||
return COST_INF;
|
||||
}
|
||||
IBlockState sch = getSchematic(x, y, z);
|
||||
BlockState sch = getSchematic(x, y, z);
|
||||
if (sch != null) {
|
||||
if (sch.getBlock() == Blocks.AIR) {
|
||||
if (sch.getBlock() instanceof AirBlock) {
|
||||
// it should be air
|
||||
// regardless of current contents, we can break it
|
||||
return 1;
|
||||
|
||||
@@ -29,7 +29,7 @@ import baritone.utils.BaritoneProcessHelper;
|
||||
*
|
||||
* @author leijurv
|
||||
*/
|
||||
public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess {
|
||||
public final class CustomGoalProcess extends BaritoneProcessHelper implements ICustomGoalProcess {
|
||||
|
||||
/**
|
||||
* The current goal
|
||||
|
||||
@@ -22,6 +22,7 @@ import baritone.api.cache.ICachedWorld;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalComposite;
|
||||
import baritone.api.pathing.goals.GoalXZ;
|
||||
import baritone.api.pathing.goals.GoalYLevel;
|
||||
import baritone.api.process.IExploreProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
@@ -40,12 +41,14 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExploreProcess extends BaritoneProcessHelper implements IExploreProcess {
|
||||
public final class ExploreProcess extends BaritoneProcessHelper implements IExploreProcess {
|
||||
|
||||
private BlockPos explorationOrigin;
|
||||
|
||||
private IChunkFilter filter;
|
||||
|
||||
private int distanceCompleted;
|
||||
|
||||
public ExploreProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
@@ -58,6 +61,7 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
@Override
|
||||
public void explore(int centerX, int centerZ) {
|
||||
explorationOrigin = new BlockPos(centerX, 0, centerZ);
|
||||
distanceCompleted = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,7 +87,7 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
return null;
|
||||
}
|
||||
IChunkFilter filter = calcFilter();
|
||||
if (!Baritone.settings().disableCompletionCheck.value && filter.finished()) {
|
||||
if (!Baritone.settings().disableCompletionCheck.value && filter.countRemain() == 0) {
|
||||
logDirect("Explored all chunks");
|
||||
onLostControl();
|
||||
return null;
|
||||
@@ -99,13 +103,17 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
private Goal[] closestUncachedChunks(BlockPos center, IChunkFilter filter) {
|
||||
int chunkX = center.getX() >> 4;
|
||||
int chunkZ = center.getZ() >> 4;
|
||||
for (int dist = 0; ; dist++) {
|
||||
List<BlockPos> centers = new ArrayList<>();
|
||||
int count = Math.min(filter.countRemain(), Baritone.settings().exploreChunkSetMinimumSize.value);
|
||||
List<BlockPos> centers = new ArrayList<>();
|
||||
int renderDistance = Baritone.settings().worldExploringChunkOffset.value;
|
||||
for (int dist = distanceCompleted; ; 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);
|
||||
int zval = dist - Math.abs(dx);
|
||||
for (int mult = 0; mult < 2; mult++) {
|
||||
int dz = (mult * 2 - 1) * zval; // dz can be either -zval or zval
|
||||
int trueDist = Math.abs(dx) + Math.abs(dz);
|
||||
if (trueDist != dist) {
|
||||
continue; // not considering this one just yet in our expanding search
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
switch (filter.isAlreadyExplored(chunkX + dx, chunkZ + dz)) {
|
||||
case UNKNOWN:
|
||||
@@ -114,10 +122,11 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
break; // note: this breaks the switch not the for
|
||||
case EXPLORED:
|
||||
continue; // note: this continues the for
|
||||
default:
|
||||
}
|
||||
int centerX = (chunkX + dx) * 16 + 8;
|
||||
int centerZ = (chunkZ + dz) * 18 + 8;
|
||||
int offset = 16 * Baritone.settings().worldExploringChunkOffset.value;
|
||||
int centerX = ((chunkX + dx) << 4) + 8;
|
||||
int centerZ = ((chunkZ + dz) << 4) + 8;
|
||||
int offset = renderDistance << 4;
|
||||
if (dx < 0) {
|
||||
centerX -= offset;
|
||||
} else {
|
||||
@@ -131,12 +140,34 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
centers.add(new BlockPos(centerX, 0, centerZ));
|
||||
}
|
||||
}
|
||||
if (centers.size() > Baritone.settings().exploreChunkSetMinimumSize.value) {
|
||||
return centers.stream().map(pos -> new GoalXZ(pos.getX(), pos.getZ())).toArray(Goal[]::new);
|
||||
if (dist % 10 == 0) {
|
||||
count = Math.min(filter.countRemain(), Baritone.settings().exploreChunkSetMinimumSize.value);
|
||||
}
|
||||
if (centers.size() >= count) {
|
||||
return centers.stream().map(pos -> createGoal(pos.getX(), pos.getZ())).toArray(Goal[]::new);
|
||||
}
|
||||
if (centers.isEmpty()) {
|
||||
// we have explored everything from 0 to dist inclusive
|
||||
// next time we should start our check at dist+1
|
||||
distanceCompleted = dist + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Goal createGoal(int x, int z) {
|
||||
if (Baritone.settings().exploreMaintainY.value == -1) {
|
||||
return new GoalXZ(x, z);
|
||||
}
|
||||
// don't use a goalblock because we still want isInGoal to return true if X and Z are correct
|
||||
// we just want to try and maintain Y on the way there, not necessarily end at that specific Y
|
||||
return new GoalXZ(x, z) {
|
||||
@Override
|
||||
public double heuristic(int x, int y, int z) {
|
||||
return super.heuristic(x, y, z) + GoalYLevel.calculate(Baritone.settings().exploreMaintainY.value, y);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private enum Status {
|
||||
EXPLORED, NOT_EXPLORED, UNKNOWN;
|
||||
}
|
||||
@@ -144,7 +175,7 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
private interface IChunkFilter {
|
||||
Status isAlreadyExplored(int chunkX, int chunkZ);
|
||||
|
||||
boolean finished();
|
||||
int countRemain();
|
||||
}
|
||||
|
||||
private class BaritoneChunkCache implements IChunkFilter {
|
||||
@@ -168,8 +199,8 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finished() {
|
||||
return false;
|
||||
public int countRemain() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,21 +234,25 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finished() {
|
||||
public int countRemain() {
|
||||
if (!invert) {
|
||||
// if invert is false, anything not on the list is uncached
|
||||
return false;
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
// but if invert is true, anything not on the list IS assumed cached
|
||||
// so we are done if everything on our list is cached!
|
||||
int countRemain = 0;
|
||||
BaritoneChunkCache bcc = new BaritoneChunkCache();
|
||||
for (MyChunkPos pos : positions) {
|
||||
if (bcc.isAlreadyExplored(pos.x, pos.z) != Status.EXPLORED) {
|
||||
// either waiting for it or dont have it at all
|
||||
return false;
|
||||
countRemain++;
|
||||
if (countRemain >= Baritone.settings().exploreChunkSetMinimumSize.value) {
|
||||
return countRemain;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // we have everything cached
|
||||
return countRemain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,8 +274,8 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finished() {
|
||||
return a.finished() || b.finished();
|
||||
public int countRemain() {
|
||||
return Math.min(a.countRemain(), b.countRemain());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,6 +286,6 @@ public class ExploreProcess extends BaritoneProcessHelper implements IExplorePro
|
||||
|
||||
@Override
|
||||
public String displayName0() {
|
||||
return "Exploring around " + explorationOrigin + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin, calcFilter()));
|
||||
return "Exploring around " + explorationOrigin + ", distance completed " + distanceCompleted + ", currently going to " + new GoalComposite(closestUncachedChunks(explorationOrigin, calcFilter()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import baritone.api.pathing.goals.GoalComposite;
|
||||
import baritone.api.process.IFarmProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.utils.RayTraceUtils;
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.api.utils.input.Input;
|
||||
@@ -31,16 +32,15 @@ import baritone.cache.WorldScanner;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.EnumDyeColor;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemDye;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -50,10 +50,13 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
public final class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
|
||||
private boolean active;
|
||||
|
||||
private List<BlockPos> locations;
|
||||
private int tickCount;
|
||||
|
||||
private static final List<Item> FARMLAND_PLANTABLE = Arrays.asList(
|
||||
Items.BEETROOT_SEEDS,
|
||||
Items.MELON_SEEDS,
|
||||
@@ -65,20 +68,19 @@ public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
|
||||
private static final List<Item> PICKUP_DROPPED = Arrays.asList(
|
||||
Items.BEETROOT_SEEDS,
|
||||
Items.WHEAT,
|
||||
Items.BEETROOT,
|
||||
Items.MELON_SEEDS,
|
||||
Items.MELON,
|
||||
Items.MELON_SLICE,
|
||||
Blocks.MELON.asItem(),
|
||||
Items.WHEAT_SEEDS,
|
||||
Items.WHEAT,
|
||||
Items.PUMPKIN_SEEDS,
|
||||
Blocks.PUMPKIN.asItem(),
|
||||
Items.POTATO,
|
||||
Items.CARROT,
|
||||
Items.BEETROOT,
|
||||
Item.getItemFromBlock(Blocks.PUMPKIN),
|
||||
Item.getItemFromBlock(Blocks.MELON_BLOCK),
|
||||
Items.NETHER_WART,
|
||||
Items.REEDS,
|
||||
Item.getItemFromBlock(Blocks.CACTUS)
|
||||
Blocks.SUGAR_CANE.asItem(),
|
||||
Blocks.CACTUS.asItem()
|
||||
);
|
||||
|
||||
public FarmProcess(Baritone baritone) {
|
||||
@@ -93,47 +95,48 @@ public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
@Override
|
||||
public void farm() {
|
||||
active = true;
|
||||
locations = null;
|
||||
}
|
||||
|
||||
private enum Harvest {
|
||||
WHEAT((BlockCrops) Blocks.WHEAT),
|
||||
CARROTS((BlockCrops) Blocks.CARROTS),
|
||||
POTATOES((BlockCrops) Blocks.POTATOES),
|
||||
BEETROOT((BlockCrops) Blocks.BEETROOTS),
|
||||
WHEAT((CropsBlock) Blocks.WHEAT),
|
||||
CARROTS((CropsBlock) Blocks.CARROTS),
|
||||
POTATOES((CropsBlock) Blocks.POTATOES),
|
||||
BEETROOT((CropsBlock) Blocks.BEETROOTS),
|
||||
PUMPKIN(Blocks.PUMPKIN, state -> true),
|
||||
MELON(Blocks.MELON_BLOCK, state -> true),
|
||||
NETHERWART(Blocks.NETHER_WART, state -> state.getValue(BlockNetherWart.AGE) >= 3),
|
||||
SUGARCANE(Blocks.REEDS, null) {
|
||||
MELON(Blocks.MELON, state -> true),
|
||||
NETHERWART(Blocks.NETHER_WART, state -> state.get(NetherWartBlock.AGE) >= 3),
|
||||
SUGARCANE(Blocks.SUGAR_CANE, null) {
|
||||
@Override
|
||||
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
return world.getBlockState(pos.down()).getBlock() instanceof BlockReed;
|
||||
public boolean readyToHarvest(World world, BlockPos pos, BlockState state) {
|
||||
return world.getBlockState(pos.down()).getBlock() instanceof SugarCaneBlock;
|
||||
}
|
||||
},
|
||||
CACTUS(Blocks.CACTUS, null) {
|
||||
@Override
|
||||
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
return world.getBlockState(pos.down()).getBlock() instanceof BlockCactus;
|
||||
public boolean readyToHarvest(World world, BlockPos pos, BlockState state) {
|
||||
return world.getBlockState(pos.down()).getBlock() instanceof CactusBlock;
|
||||
}
|
||||
};
|
||||
public final Block block;
|
||||
public final Predicate<IBlockState> readyToHarvest;
|
||||
public final Predicate<BlockState> readyToHarvest;
|
||||
|
||||
Harvest(BlockCrops blockCrops) {
|
||||
Harvest(CropsBlock blockCrops) {
|
||||
this(blockCrops, blockCrops::isMaxAge);
|
||||
// max age is 7 for wheat, carrots, and potatoes, but 3 for beetroot
|
||||
}
|
||||
|
||||
Harvest(Block block, Predicate<IBlockState> readyToHarvest) {
|
||||
Harvest(Block block, Predicate<BlockState> readyToHarvest) {
|
||||
this.block = block;
|
||||
this.readyToHarvest = readyToHarvest;
|
||||
}
|
||||
|
||||
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
public boolean readyToHarvest(World world, BlockPos pos, BlockState state) {
|
||||
return readyToHarvest.test(state);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean readyForHarvest(World world, BlockPos pos, IBlockState state) {
|
||||
private boolean readyForHarvest(World world, BlockPos pos, BlockState state) {
|
||||
for (Harvest harvest : Harvest.values()) {
|
||||
if (harvest.block == state.getBlock()) {
|
||||
return harvest.readyToHarvest(world, pos, state);
|
||||
@@ -147,7 +150,7 @@ public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
}
|
||||
|
||||
private boolean isBoneMeal(ItemStack stack) {
|
||||
return !stack.isEmpty() && stack.getItem() instanceof ItemDye && EnumDyeColor.byDyeDamage(stack.getMetadata()) == EnumDyeColor.WHITE;
|
||||
return !stack.isEmpty() && stack.getItem().equals(Items.BONE_MEAL);
|
||||
}
|
||||
|
||||
private boolean isNetherWart(ItemStack stack) {
|
||||
@@ -164,16 +167,19 @@ public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
if (Baritone.settings().replantNetherWart.value) {
|
||||
scan.add(Blocks.SOUL_SAND);
|
||||
}
|
||||
|
||||
List<BlockPos> locations = WorldScanner.INSTANCE.scanChunkRadius(ctx, scan, 256, 10, 4);
|
||||
|
||||
if (Baritone.settings().mineGoalUpdateInterval.value != 0 && tickCount++ % Baritone.settings().mineGoalUpdateInterval.value == 0) {
|
||||
Baritone.getExecutor().execute(() -> locations = WorldScanner.INSTANCE.scanChunkRadius(ctx, scan, 256, 10, 10));
|
||||
}
|
||||
if (locations == null) {
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
List<BlockPos> toBreak = new ArrayList<>();
|
||||
List<BlockPos> openFarmland = new ArrayList<>();
|
||||
List<BlockPos> bonemealable = new ArrayList<>();
|
||||
List<BlockPos> openSoulsand = new ArrayList<>();
|
||||
for (BlockPos pos : locations) {
|
||||
IBlockState state = ctx.world().getBlockState(pos);
|
||||
boolean airAbove = ctx.world().getBlockState(pos.up()).getBlock() instanceof BlockAir;
|
||||
BlockState state = ctx.world().getBlockState(pos);
|
||||
boolean airAbove = ctx.world().getBlockState(pos.up()).getBlock() instanceof AirBlock;
|
||||
if (state.getBlock() == Blocks.FARMLAND) {
|
||||
if (airAbove) {
|
||||
openFarmland.add(pos);
|
||||
@@ -216,11 +222,14 @@ public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
boolean soulsand = openSoulsand.contains(pos);
|
||||
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance());
|
||||
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) {
|
||||
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
||||
if (ctx.isLookingAt(pos)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance());
|
||||
if (result instanceof BlockRayTraceResult && ((BlockRayTraceResult) result).getFace() == Direction.UP) {
|
||||
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
||||
if (ctx.isLookingAt(pos)) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
}
|
||||
for (BlockPos pos : bonemealable) {
|
||||
@@ -259,9 +268,9 @@ public class FarmProcess extends BaritoneProcessHelper implements IFarmProcess {
|
||||
goalz.add(new GoalBlock(pos));
|
||||
}
|
||||
}
|
||||
for (Entity entity : ctx.world().loadedEntityList) {
|
||||
if (entity instanceof EntityItem && entity.onGround) {
|
||||
EntityItem ei = (EntityItem) entity;
|
||||
for (Entity entity : ctx.entities()) {
|
||||
if (entity instanceof ItemEntity && entity.onGround) {
|
||||
ItemEntity ei = (ItemEntity) entity;
|
||||
if (PICKUP_DROPPED.contains(ei.getItem().getItem())) {
|
||||
// +0.1 because of farmland's 0.9375 dummy height lol
|
||||
goalz.add(new GoalBlock(new BlockPos(entity.posX, entity.posY + 0.1, entity.posZ)));
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Follow an entity
|
||||
@@ -72,17 +71,21 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
||||
if (entity == null) {
|
||||
return false;
|
||||
}
|
||||
if (entity.isDead) {
|
||||
if (!entity.isAlive()) {
|
||||
return false;
|
||||
}
|
||||
if (entity.equals(ctx.player())) {
|
||||
return false;
|
||||
}
|
||||
return ctx.world().loadedEntityList.contains(entity);
|
||||
return ctx.entitiesStream().anyMatch(entity::equals);
|
||||
}
|
||||
|
||||
private void scanWorld() {
|
||||
cache = Stream.of(ctx.world().loadedEntityList, ctx.world().playerEntities).flatMap(List::stream).filter(this::followable).filter(this.filter).distinct().collect(Collectors.toCollection(ArrayList::new));
|
||||
cache = ctx.entitiesStream()
|
||||
.filter(this::followable)
|
||||
.filter(this.filter)
|
||||
.distinct()
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,15 +26,16 @@ import baritone.api.utils.Rotation;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.inventory.ContainerPlayer;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.inventory.container.PlayerContainer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
|
||||
public final class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
|
||||
|
||||
private Block gettingTo;
|
||||
private List<BlockPos> knownLocations;
|
||||
@@ -42,6 +43,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
private BlockPos start;
|
||||
|
||||
private int tickCount = 0;
|
||||
private int arrivalTickCount = 0;
|
||||
|
||||
public GetToBlockProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
@@ -53,6 +55,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
gettingTo = block;
|
||||
start = ctx.playerFeet();
|
||||
blacklist = new ArrayList<>();
|
||||
arrivalTickCount = 0;
|
||||
rescan(new ArrayList<>(), new CalculationContext(baritone));
|
||||
}
|
||||
|
||||
@@ -119,7 +122,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
// blacklist the closest block and its adjacent blocks
|
||||
public synchronized boolean blacklistClosest() {
|
||||
List<BlockPos> newBlacklist = new ArrayList<>();
|
||||
knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add);
|
||||
knownLocations.stream().min(Comparator.comparingDouble(ctx.playerFeet()::distanceSq)).ifPresent(newBlacklist::add);
|
||||
outer:
|
||||
while (true) {
|
||||
for (BlockPos known : knownLocations) {
|
||||
@@ -178,7 +181,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
if (walkIntoInsteadOfAdjacent(gettingTo)) {
|
||||
return new GoalTwoBlocks(pos);
|
||||
}
|
||||
if (blockOnTopMustBeRemoved(gettingTo) && baritone.bsi.get0(pos.up()).isBlockNormalCube()) {
|
||||
if (blockOnTopMustBeRemoved(gettingTo) && MovementHelper.isBlockNormalCube(baritone.bsi.get0(pos.up()))) { // TODO this should be the check for chest openability
|
||||
return new GoalBlock(pos.up());
|
||||
}
|
||||
return new GoalGetToBlock(pos);
|
||||
@@ -192,10 +195,14 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
if (knownLocations.contains(ctx.getSelectedBlock().orElse(null))) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); // TODO find some way to right click even if we're in an ESC menu
|
||||
System.out.println(ctx.player().openContainer);
|
||||
if (!(ctx.player().openContainer instanceof ContainerPlayer)) {
|
||||
if (!(ctx.player().openContainer instanceof PlayerContainer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (arrivalTickCount++ > 20) {
|
||||
logDirect("Right click timed out");
|
||||
return true;
|
||||
}
|
||||
return false; // trying to right click, will do it next tick or so
|
||||
}
|
||||
}
|
||||
@@ -207,7 +214,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
|
||||
if (!Baritone.settings().enterPortal.value) {
|
||||
return false;
|
||||
}
|
||||
return block == Blocks.PORTAL;
|
||||
return block == Blocks.NETHER_PORTAL;
|
||||
}
|
||||
|
||||
private boolean rightClickOnArrival(Block block) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user