Compare commits

..

94 Commits

Author SHA1 Message Date
Leijurv
fa75880626 v1.1.1 2019-02-05 08:25:30 -08:00
Leijurv
529895f970 was only needed for freecam anyway 2019-02-05 08:25:14 -08:00
Leijurv
3d5de440fd what a mess 2019-02-04 21:30:58 -08:00
Leijurv
568bb1b0e8 some forge info 2019-02-04 21:23:19 -08:00
Leijurv
b9ae8306dd v1.1.0 2019-02-04 20:11:55 -08:00
Leijurv
4aededff46 allow prefix and non prefix control at the same time 2019-02-04 19:57:01 -08:00
Leijurv
ed8f9863e3 spacing 3 2019-02-04 19:37:36 -08:00
Leijurv
e85de55c8f spacing 2 2019-02-04 19:36:16 -08:00
Leijurv
adbf927270 spacing 2019-02-04 19:35:22 -08:00
Leijurv
dfe171a5c2 forge 2019-02-04 19:34:44 -08:00
Leijurv
b55e449398 extra line 2019-02-04 19:01:50 -08:00
Leijurv
62b11c0a8a i'm legitimately sorry 2019-02-04 19:01:01 -08:00
Leijurv
90cb11f55e this is needed 2019-02-04 18:19:51 -08:00
Leijurv
40a66b0306 almost forge support 2019-02-04 18:05:05 -08:00
Leijurv
8c899698e0 explore for blocks, fixes #323 2019-02-04 16:27:32 -08:00
Leijurv
58fa1571f3 added more info 2019-02-04 15:43:02 -08:00
Leijurv
2cbe77aa04 many fixes 2019-02-04 15:24:27 -08:00
Leijurv
a0c2935580 Merge branch 'master' into mega-cancer-rendering 2019-02-04 14:52:30 -08:00
Leijurv
798f25ff81 dont glitch weirdly when failing a parkour jump 2019-02-04 13:52:11 -08:00
Leijurv
57b2e360ca dont include current movement cost while deciding when to plan ahead 2019-02-04 13:27:35 -08:00
Leijurv
ee23d59e11 now we can cache flowing water properly 2019-02-04 13:07:56 -08:00
Leijurv
04e7da9b73 lower walk into can be water, but not upper 2019-02-04 13:07:05 -08:00
Leijurv
5382d265f2 crucial performance optimization 2019-02-03 19:46:59 -08:00
Leijurv
0e1534613c appease codacy 2019-02-03 19:34:29 -08:00
Leijurv
d799fac688 epicer gradle output 2019-02-03 19:27:28 -08:00
Leijurv
913247996e smh my head. who right clicks gradle tasks?? 2019-02-02 14:23:01 -08:00
Leijurv
dc3bab26de 6 months =D 2019-02-01 22:54:14 -08:00
Leijurv
5c1cf050e2 im idiot 2019-01-31 20:27:14 -08:00
Leijurv
747bee41b7 holding control shouldnt make all bots sprint 2019-01-31 20:26:24 -08:00
Leijurv
246c00c773 dont repeat that 2019-01-31 19:19:44 -08:00
Leijurv
272dd79426 much needed pathing overhaul 2019-01-30 15:49:37 -08:00
Leijurv
b953da0341 more accurate isEmpty 2019-01-30 12:19:15 -08:00
Leijurv
c2a6445c9e Merge branch 'master' into mega-cancer-rendering 2019-01-30 12:07:58 -08:00
Leijurv
b177ae7ee6 proguard can just ignore GL14 reference actually 2019-01-30 11:57:54 -08:00
Leijurv
22bd5be5a9 explain 2019-01-30 11:54:38 -08:00
Leijurv
90fa347fc2 also get rid of warning in build stage 2019-01-30 11:54:02 -08:00
Leijurv
68a9a1439a maybe this will allow emoji 2019-01-30 11:45:03 -08:00
Leijurv
8947eff3b1 bsi might be old 2019-01-30 11:42:46 -08:00
Brady
06b3c5ddb5 LeijurvUtils 2019-01-30 12:42:26 -06:00
Leijurv
b4d307d4cc cherry pick some movement fixes from builder 2019-01-29 19:56:50 -08:00
Leijurv
1968f47fc9 add a setting to play with 2019-01-29 19:44:23 -08:00
Leijurv
9b42aa3634 damn you javadocs 2019-01-29 15:34:31 -08:00
Leijurv
9faa0ddc62 huge number of fixes 2019-01-29 15:22:54 -08:00
Leijurv
6a2cd9d3ba Merge branch 'master' into mega-cancer-rendering 2019-01-29 13:55:00 -08:00
Leijurv
9028564c10 only when the setting is enabled 2019-01-29 13:54:54 -08:00
Brady
8f2b23f8f9 Wew lad 2019-01-29 14:33:34 -06:00
Brady
b471d7419e Replace most of the @Inject usages for cancer render with @Redirect 2019-01-29 12:41:14 -06:00
Leijurv
5179cfc5ba semitransparency working 2019-01-28 21:28:26 -08:00
Leijurv
784b2f541d lol 2019-01-28 19:02:07 -08:00
Leijurv
735cf47c35 actually works 2019-01-28 17:34:14 -08:00
Leijurv
056742479e except without that 2019-01-28 16:06:34 -08:00
Leijurv
840b7e6987 misc fixes #315 2019-01-28 15:59:53 -08:00
Leijurv
a87772c98c remove that image once done 2019-01-28 12:16:45 -08:00
Leijurv
c15f1e8276 link source is cool 2019-01-28 12:06:26 -08:00
Leijurv
49148dfb7a add javadocs link 2019-01-28 11:57:58 -08:00
Leijurv
177f5de2bd yay travis checks javadocs now 2019-01-28 11:56:44 -08:00
Leijurv
96360ddb24 perhaps 2019-01-28 11:49:52 -08:00
Leijurv
f5f2e4970e make travis fail when javadoc doesn't compile 2019-01-28 11:37:02 -08:00
Leijurv
742256c130 more fun javadocs 2019-01-28 11:30:33 -08:00
Leijurv
b4a622d319 editing settings 2019-01-28 10:59:08 -08:00
Leijurv
b0c4752397 finalize all settings 2019-01-28 10:41:28 -08:00
Leijurv
bf78a4dfad whoops forgot that 2019-01-28 10:32:28 -08:00
Leijurv
8d7841b069 privatize 2019-01-27 19:34:12 -08:00
Leijurv
396eaa148c remove extra newline 2019-01-26 21:33:41 -08:00
Leijurv
2a244f1e53 those were a little over the top 2019-01-25 11:51:54 -08:00
Leijurv
f274f5a0ef windows is epic gamer 2019-01-24 21:00:44 -08:00
Leijurv
bb41883070 did someone say add another badge 2019-01-24 16:31:12 -08:00
Leijurv
fca5457ab9 gotta have closed issues too 2019-01-24 16:25:35 -08:00
Leijurv
4f355ed4a2 two more 2019-01-24 16:10:21 -08:00
Leijurv
b1452c714a b a d g e s 2019-01-24 16:06:58 -08:00
Brady
aba48cca53 Organize some markdown files 2019-01-24 15:21:16 -06:00
Brady
772d5fb0cc SETUP.md 2019-01-24 15:09:04 -06:00
Brady
6b6f8cadb2 Image tutorial epic haha 2019-01-24 15:06:01 -06:00
Brady
82ab79e915 CLI setup 2019-01-24 14:34:35 -06:00
Leijurv
863471b5f1 don't create a new bsi for every selection box every tick 2019-01-23 21:25:38 -08:00
Leijurv
314f280400 pigs 2019-01-22 17:26:00 -08:00
Brady
b75f4bf9a9 Reformat 2019-01-22 13:32:37 -06:00
Brady
253d67ce78 final final final final 2019-01-22 12:01:06 -06:00
Leijurv
1753bc18c1 forgehax 2019-01-21 23:32:41 -08:00
Leijurv
eceba13164 diss wwe 2019-01-20 16:26:23 -08:00
Leijurv
3c6c640f50 unused 2019-01-20 15:41:36 -08:00
Leijurv
30e3018966 trigger brady 2019-01-20 15:33:08 -08:00
Leijurv
5ab0bb3c0d nice round number 2019-01-20 13:53:55 -08:00
Leijurv
0de1517bd8 Merge pull request #316 from babbaj/master
Never send chat message when using prefix
2019-01-20 09:22:03 -08:00
babbaj
39c6d81b9e Never send chat message when using prefix 2019-01-20 06:20:49 -05:00
Leijurv
38c7f226cb brady is rart 2019-01-19 16:36:31 -08:00
Brady
f5446cc415 Fix SprintStateEvent 2019-01-19 12:12:26 -06:00
Brady
aa2e680568 Remove ManagedPlayerEvent 2019-01-19 12:10:49 -06:00
Leijurv
bc651cb774 add todo 2019-01-18 20:12:40 -08:00
Brady
20b03d0004 No more setSprinting 2019-01-18 13:43:19 -06:00
Leijurv
b005ce8e6b mega cancer render cached chunks 2019-01-17 18:54:37 -08:00
Brady
979b8b2663 Remove associatedWith in process and some more javadoc changes 2019-01-17 18:20:27 -06:00
Brady
69b1decbba leftClickWorkaround is no longer applicable 2019-01-17 18:04:12 -06:00
Brady
d32c92cbde Specificity time 2019-01-17 18:01:31 -06:00
64 changed files with 1136 additions and 710 deletions

View File

@@ -9,6 +9,7 @@ install:
- travis_retry docker build -t cabaletta/baritone .
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 cp baritone:/code/dist dist
- ls dist

View File

@@ -11,6 +11,7 @@
- **Avoiding dangerous blocks** Obviously, it knows not to walk through fire or on magma, not to corner over lava (that deals some damage), not to break any blocks touching a liquid (it might drown), etc.
- **Parkour** Sprint jumping over 1, 2, or 3 block gaps
- **Parkour place** Sprint jumping over a 3 block gap and placing the block to land on while executing the jump. It's really cool.
- **Pigs** It can sort of control pigs. I wouldn't rely on it though.
# Pathing method
Baritone uses A*, with some modifications:
@@ -46,7 +47,6 @@ Things it doesn't have yet
See <a href="https://github.com/cabaletta/baritone/issues">issues</a> for more.
Things it may not ever have, from most likely to least likely =(
- Pigs
- Boats
- Horses (2x3 path instead of 1x2)
- Elytra

View File

@@ -1 +0,0 @@
Impact 4.4 is out. See <a href="INSTALL.md">INSTALL.md</a>

View File

@@ -1,11 +1,10 @@
# Integration between Baritone and Impact
Impact 4.4 has Baritone included.
These instructions apply to Impact 4.3 (and potentially other hacked clients).
These instructions apply to Impact 4.3 (and potentially other "hacked clients").
To run Baritone on Vanilla, just follow the instructions in the README (it's `./gradlew runClient`).
## An Introduction
There are some basic steps to getting Baritone setup with Impact.
- Acquiring a build of Baritone
@@ -26,14 +25,7 @@ Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMe
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone . && docker run --rm cabaletta/baritone cat /code/dist/checksums.txt` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
### Building Baritone yourself
There are a few steps to this
- Clone this repository
- Setup the project as instructed in the README
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
command line
- Windows: ``gradlew build``
- Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
You can either build Baritone through a command line or through IntelliJ's UI, information on that can be found [here](SETUP.md#building).
## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>

View File

@@ -6,60 +6,56 @@
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
[![Known Vulnerabilities](https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle)](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Issues](https://img.shields.io/github/issues/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues/)
[![GitHub issues-closed](https://img.shields.io/github/issues-closed/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed)
[![Pull Requests](https://img.shields.io/github/issues-pr/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/pulls/)
![Code size](https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg)
![GitHub repo size](https://img.shields.io/github/repo-size/cabaletta/baritone.svg)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.0.0--hotfix--4-brightgreen.svg)](https://impactdevelopment.github.io/)
[![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/)
[![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/)
[![Asuna integration](https://img.shields.io/badge/Asuna%20integration-builder%20branch-brightgreen.svg)](https://github.com/EmotionalLove/Asuna/)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.0.0--hotfix--4-green.svg)](https://impactdevelopment.github.io/)
[![KAMI integration](https://img.shields.io/badge/KAMI%20integration-v1.0.0-orange.svg)](https://github.com/zeroeightysix/KAMI/)
[![Asuna integration](https://img.shields.io/badge/Asuna%20integration-v1.0.0-orange.svg)](https://github.com/EmotionalLove/Asuna/)
[![Future integration](https://img.shields.io/badge/Future%20integration-%3F%3F%3F-red.svg)](https://futureclient.net/)
[![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-v1.0.0%3F%3F%20smh%20license%20violations-orange.svg)](https://wweclient.com/)
[![Future integration](https://img.shields.io/badge/Future%20integration-Soon™%3F%3F%3F-red.svg)](https://futureclient.net/)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20integration-Soon™-red.svg)](https://github.com/fr1kin/ForgeHax)
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, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Have committed at least once a day for the last 6 months =D 🦀
Here are some links to help to get started:
- [Features](FEATURES.md)
- [Setup](SETUP.md)
- [Installation](INSTALL.md)
# Setup
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Running Baritone:
```
$ gradlew runClient
```
Building Baritone:
```
$ gradlew build
```
To replace out Impact 4.4's Baritone build with a customized one, switch to the `impact4.4-compat` branch, build Baritone as above then copy `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
- Select the "Minecraft Client" launch config
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
- [Javadocs](https://baritone.leijurv.com/)
# Chat control
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actually start pathing. Also try `mine diamond_ore`. `cancel` to cancel.
On v1.1.0 and newer: Put a `#` in front so that if you make a typo it doesn't go into public chat (anything beginning with `#` isn't sent).
For older than v1.1.0, `#` must be enabled by toggling on the `prefix` setting.
**Only** in Impact is `.b` also a valid prefix
# API example
```
BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
```

88
SETUP.md Normal file
View File

@@ -0,0 +1,88 @@
# Setup
## Prebuilt
[Releases](https://github.com/cabaletta/baritone/releases)
Not always completely up to date with latest features.
The forge release (currently `baritone-forge-1.1.0.jar`) can simply be added as a Forge mod. However, it is not fully compatible with the latest version of Forge. `freeLook` was broken in Forge 14.23.4.2744. You should use Forge 14.23.4.2743 or **older** with Baritone. Newer versions of Forge "work", sort of, but Baritone's movement becomes unreliable and `freeLook` must be off.
## Build it yourself
- Clone or download Baritone
![Image](https://i.imgur.com/kbqBtoN.png)
- If you choose to download, make sure you extract the ZIP archive.
- Follow one of the instruction sets below, based on your preference
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Setting up the Environment:
```
$ gradlew setupDecompWorkspace
$ gradlew --refresh-dependencies
```
Running Baritone:
```
$ gradlew runClient
```
For information on how to build baritone, see [Building Baritone](#building-baritone)
## IntelliJ
- Open the project in IntelliJ as a Gradle project
![Image](https://i.imgur.com/jw7Q6vY.png)
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
![Image](https://i.imgur.com/QEfVvWP.png)
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
![Image](https://i.imgur.com/3V7EdWr.png)
- Select the "Minecraft Client" launch config
![Image](https://i.imgur.com/1qz2QGV.png)
- Click on ``Edit Configurations...`` from the same dropdown and select the "Minecraft Client" config
![Image](https://i.imgur.com/s4ly0ZF.png)
- In `Edit Configurations...` you need to select `baritone_launch` for `Use classpath of module:`.
![Image](https://i.imgur.com/hrLhG9u.png)
# Building
Make sure that you have properly [setup](#setup) the environment before trying to build it.
## Command Line
```
$ gradlew build
```
## IntelliJ
- Navigate to the gradle tasks on the right tab as follows
![Image](https://i.imgur.com/PE6r9iN.png)
- Double click on **build** to run it
## Artifacts
Building Baritone will result in 4 artifacts created in the ``dist`` directory.
- **Forge**: Forge mod
- **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features.
- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features.
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production.
## More Info
To replace out Impact 4.4's Baritone build with a customized one, switch to the `impact4.4-compat` branch, build Baritone as above then copy `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).

View File

@@ -16,7 +16,7 @@
*/
group 'baritone'
version '1.0.0-hotfix-2'
version '1.1.1'
buildscript {
repositories {
@@ -48,6 +48,7 @@ apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = '1.8'
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
options.encoding = "UTF-8" // allow emoji in comments :^)
}
sourceSets {
@@ -94,13 +95,16 @@ dependencies {
}
mixin {
defaultObfuscationEnv notch
defaultObfuscationEnv searge
add sourceSets.launch, 'mixins.baritone.refmap.json'
}
javadoc {
source = sourceSets.api.allJava
classpath = sourceSets.api.compileClasspath
options.addStringOption('Xwerror', '-quiet') // makes the build fail on travis when there is a javadoc error
options.linkSource true
options.encoding "UTF-8" // allow emoji in comments :^)
source += sourceSets.api.allJava
classpath += sourceSets.api.compileClasspath
}
jar {
@@ -109,6 +113,14 @@ jar {
reproducibleFileOrder = true
}
jar {
manifest {
attributes(
'MixinConfigs': 'mixins.baritone.json'
)
}
}
task proguard(type: ProguardTask) {
url 'https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip'
extract 'proguard6.0.3/lib/proguard.jar'

View File

@@ -52,10 +52,11 @@ class BaritoneGradleTask extends DefaultTask {
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE = "%s-forge-%s.jar";
protected String artifactName, artifactVersion;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgePath, proguardOut;
protected void verifyArtifacts() throws IllegalStateException {
this.artifactName = getProject().getName();
@@ -65,6 +66,7 @@ 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.artifactForgePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);

View File

@@ -45,6 +45,7 @@ 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 forge = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE));
// NIO will not automatically create directories
Path dir = getRelativeFile("dist/");
@@ -56,9 +57,10 @@ 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.artifactForgePath, forge, REPLACE_EXISTING);
// Calculate all checksums and format them like "shasum"
List<String> shasum = Stream.of(api, standalone, unoptimized)
List<String> shasum = Stream.of(api, standalone, unoptimized, forge)
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());

View File

@@ -59,6 +59,8 @@ public class ProguardTask extends BaritoneGradleTask {
private List<String> requiredLibraries;
private File mixin;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
@@ -71,6 +73,7 @@ public class ProguardTask extends BaritoneGradleTask {
acquireDependencies();
proguardApi();
proguardStandalone();
createForge();
cleanup();
}
@@ -79,7 +82,7 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
}
private void downloadProguard() throws Exception {
@@ -173,10 +176,16 @@ public class ProguardTask extends BaritoneGradleTask {
// 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
@@ -264,12 +273,16 @@ public class ProguardTask extends BaritoneGradleTask {
private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
}
private void createForge() throws Exception {
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgePath.toString(), Optional.of(mixin));
}
private void cleanup() {
@@ -298,8 +311,8 @@ public class ProguardTask extends BaritoneGradleTask {
.start();
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
this.printOutputLog(p.getInputStream());
this.printOutputLog(p.getErrorStream());
this.printOutputLog(p.getInputStream(), System.out);
this.printOutputLog(p.getErrorStream(), System.err);
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor();
@@ -308,12 +321,12 @@ public class ProguardTask extends BaritoneGradleTask {
}
}
private void printOutputLog(InputStream stream) {
private void printOutputLog(InputStream stream, PrintStream outerr) {
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
outerr.println(line);
}
} catch (Exception e) {
e.printStackTrace();

View File

@@ -22,10 +22,7 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -39,7 +36,7 @@ import java.util.stream.Collectors;
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath) throws IOException {
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
@@ -66,10 +63,30 @@ 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();
}
}

View File

@@ -12,6 +12,9 @@
-flattenpackagehierarchy
-repackageclasses 'baritone'
# lwjgl is weird
-dontwarn org.lwjgl.opengl.GL14
-keep class baritone.api.** { *; } # this is the keep api
# service provider needs these class names

View File

@@ -33,67 +33,67 @@ import java.util.function.Consumer;
*
* @author leijurv
*/
public class Settings {
public final class Settings {
/**
* Allow Baritone to break blocks
*/
public Setting<Boolean> allowBreak = new Setting<>(true);
public final Setting<Boolean> allowBreak = new Setting<>(true);
/**
* Allow Baritone to sprint
*/
public Setting<Boolean> allowSprint = new Setting<>(true);
public final Setting<Boolean> allowSprint = new Setting<>(true);
/**
* Allow Baritone to place blocks
*/
public Setting<Boolean> allowPlace = new Setting<>(true);
public final Setting<Boolean> allowPlace = new Setting<>(true);
/**
* Allow Baritone to move items in your inventory to your hotbar
*/
public Setting<Boolean> allowInventory = new Setting<>(false);
public final Setting<Boolean> allowInventory = new Setting<>(false);
/**
* It doesn't actually take twenty ticks to place a block, this cost is so high
* because we want to generally conserve blocks which might be limited
*/
public Setting<Double> blockPlacementPenalty = new Setting<>(20D);
public final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
/**
* This is just a tiebreaker to make it less likely to break blocks if it can avoid it.
* For example, fire has a break cost of 0, this makes it nonzero, so all else being equal
* it will take an otherwise equivalent route that doesn't require it to put out fire.
*/
public Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
public final Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
/**
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) beacuse it uses hunger
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) because it uses hunger
*/
public Setting<Double> jumpPenalty = new Setting<>(2D);
public final Setting<Double> jumpPenalty = new Setting<>(2D);
/**
* Walking on water uses up hunger really quick, so penalize it
*/
public Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
/**
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
* Reliability: questionable.
*/
public Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
public final Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
/**
* Allow Baritone to assume it can walk on still water just like any other block.
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
*/
public Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
/**
* Assume step functionality; don't jump on an Ascend.
*/
public Setting<Boolean> assumeStep = new Setting<>(false);
public final Setting<Boolean> assumeStep = new Setting<>(false);
/**
* Assume safe walk functionality; don't sneak on a backplace traverse.
@@ -102,14 +102,14 @@ public class Settings {
* it won't sneak right click, it'll just right click, which means it'll open the chest instead of placing
* against it. That's why this defaults to off.
*/
public Setting<Boolean> assumeSafeWalk = new Setting<>(false);
public final Setting<Boolean> assumeSafeWalk = new Setting<>(false);
/**
* If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
* <p>
* Defaults to false because this fails on NCP
* Defaults to false because this fails on constantiam
*/
public Setting<Boolean> allowJumpAt256 = new Setting<>(false);
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
/**
* Allow descending diagonally
@@ -118,12 +118,12 @@ public class Settings {
* <p>
* For a generic "take some risks" mode I'd turn on this one, parkour, and parkour place.
*/
public Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
/**
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
*/
public Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
Item.getItemFromBlock(Blocks.DIRT),
Item.getItemFromBlock(Blocks.COBBLESTONE),
Item.getItemFromBlock(Blocks.NETHERRACK)
@@ -132,31 +132,37 @@ public class Settings {
/**
* 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
*/
public Setting<Boolean> allowVines = new Setting<>(false);
public final Setting<Boolean> allowVines = new Setting<>(false);
/**
* Slab behavior is complicated, disable this for higher path reliability. Leave enabled if you have bottom slabs
* everywhere in your base.
*/
public Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
public final Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
/**
* You know what it is
* <p>
* But it's very unreliable and falls off when cornering like all the time so.
* <p>
* It also overshoots the landing pretty much always (making contact with the next block over), so be careful
*/
public Setting<Boolean> allowParkour = new Setting<>(false);
public final Setting<Boolean> allowParkour = new Setting<>(false);
/**
* Like parkour, but even more unreliable!
* Actually pretty reliable.
* <p>
* Doesn't make it any more dangerous compared to just normal allowParkour th
*/
public Setting<Boolean> allowParkourPlace = new Setting<>(false);
public final Setting<Boolean> allowParkourPlace = new Setting<>(false);
/**
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
*/
public Setting<Boolean> considerPotionEffects = new Setting<>(true);
public final Setting<Boolean> considerPotionEffects = new Setting<>(true);
/**
* This is the big A* setting.
@@ -173,131 +179,137 @@ public class Settings {
* <p>
* Finding the optimal path is worth it, so it's the default.
*/
public Setting<Double> costHeuristic = new Setting<>(3.563);
public final Setting<Double> costHeuristic = new Setting<>(3.563);
// a bunch of obscure internal A* settings that you probably don't want to change
/**
* The maximum number of times it will fetch outside loaded or cached chunks before assuming that
* pathing has reached the end of the known area, and should therefore stop.
*/
public Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
public final Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
/**
* Set to 1.0 to effectively disable this feature
*
* @see <a href="https://github.com/cabaletta/baritone/issues/18">Issue #18</a>
*/
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
public final Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
/**
* Toggle the following 4 settings
* <p>
* They have a noticable performance impact, so they default off
* They have a noticeable performance impact, so they default off
* <p>
* Specifically, building up the avoidance map on the main thread before pathing starts actually takes a noticeable
* amount of time, especially when there are a lot of mobs around, and your game jitters for like 200ms while doing so
*/
public Setting<Boolean> avoidance = new Setting<>(false);
public final Setting<Boolean> avoidance = new Setting<>(false);
/**
* Set to 1.0 to effectively disable this feature
* <p>
* Set below 1.0 to go out of your way to walk near mob spawners
*/
public Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
public Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
/**
* Set to 1.0 to effectively disable this feature
* <p>
* Set below 1.0 to go out of your way to walk near mobs
*/
public Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
public final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
public Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
/**
* When running a goto towards a container block (chest, ender chest, furnace, etc),
* right click and open it once you arrive.
*/
public Setting<Boolean> rightClickContainerOnArrival = new Setting<>(true);
public final Setting<Boolean> rightClickContainerOnArrival = new Setting<>(true);
/**
* When running a goto towards a nether portal block, walk all the way into the portal
* instead of stopping one block before.
*/
public Setting<Boolean> enterPortal = new Setting<>(true);
public final Setting<Boolean> enterPortal = new Setting<>(true);
/**
* Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
* and there's no point.
*/
public Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
public final Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
/**
* After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
* entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
* <p>
* This is much safer to leave off now, and makes pathing more efficient. More explanation in the issue.
*
* @see <a href="https://github.com/cabaletta/baritone/issues/144">Issue #144</a>
* @see <a href="https://github.com/cabaletta/baritone/issues/114">Issue #114</a>
*/
public Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
public final Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
/**
* If a movement's cost increases by more than this amount between calculation and execution (due to changes
* in the environment / world), cancel and recalculate
*/
public Setting<Double> maxCostIncrease = new Setting<>(10D);
public final Setting<Double> maxCostIncrease = new Setting<>(10D);
/**
* Stop 5 movements before anything that made the path COST_INF.
* For example, if lava has spread across the path, don't walk right up to it then recalculate, it might
* still be spreading lol
*/
public Setting<Integer> costVerificationLookahead = new Setting<>(5);
public final Setting<Integer> costVerificationLookahead = new Setting<>(5);
/**
* Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
*/
public Setting<Double> pathCutoffFactor = new Setting<>(0.9);
public final Setting<Double> pathCutoffFactor = new Setting<>(0.9);
/**
* Only apply static cutoff for paths of at least this length (in terms of number of movements)
*/
public Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
public final Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
/**
* Start planning the next path once the remaining movements tick estimates sum up to less than this value
*/
public Setting<Integer> planningTickLookAhead = new Setting<>(150);
public final Setting<Integer> planningTickLookAhead = new Setting<>(150);
/**
* Default size of the Long2ObjectOpenHashMap used in pathing
*/
public Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
public final Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
/**
* Load factor coefficient for the Long2ObjectOpenHashMap used in pathing
* <p>
* Decrease for faster map operations, but higher memory usage
*/
public Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
public final Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
/**
* How far are you allowed to fall onto solid ground (without a water bucket)?
* 3 won't deal any damage. But if you just want to get down the mountain quickly and you have
* Feather Falling IV, you might set it a bit higher, like 4 or 5.
*/
public Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
public final Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
/**
* How far are you allowed to fall onto solid ground (with a water bucket)?
* It's not that reliable, so I've set it below what would kill an unarmored player (23)
*/
public Setting<Integer> maxFallHeightBucket = new Setting<>(20);
public final Setting<Integer> maxFallHeightBucket = new Setting<>(20);
/**
* Is it okay to sprint through a descend followed by a diagonal?
* The player overshoots the landing, but not enough to fall off. And the diagonal ensures that there isn't
* lava or anything that's !canWalkInto in that space, so it's technically safe, just a little sketchy.
*/
public Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
public final Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
/**
* If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
@@ -306,131 +318,133 @@ public class Settings {
* of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away,
* your Y coordinate's accuracy doesn't matter at all until you get much much closer.
*/
public Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
public final Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
/**
* If a movement takes this many ticks more than its initial cost estimate, cancel it
*/
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
public final Setting<Integer> movementTimeoutTicks = new Setting<>(100);
/**
* Pathing ends after this amount of time, but only if a path has been found
* <p>
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
*/
public Setting<Long> primaryTimeoutMS = new Setting<>(500L);
public final Setting<Long> primaryTimeoutMS = new Setting<>(500L);
/**
* Pathing can never take longer than this, even if that means failing to find any path at all
*/
public Setting<Long> failureTimeoutMS = new Setting<>(2000L);
public final Setting<Long> failureTimeoutMS = new Setting<>(2000L);
/**
* Planning ahead while executing a segment ends after this amount of time, but only if a path has been found
* <p>
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
*/
public Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
public final Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
/**
* Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all
*/
public Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
public final Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
/**
* For debugging, consider nodes much much slower
*/
public Setting<Boolean> slowPath = new Setting<>(false);
public final Setting<Boolean> slowPath = new Setting<>(false);
/**
* Milliseconds between each node
*/
public Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
public final Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
/**
* The alternative timeout number when slowPath is on
*/
public Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
/**
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
*/
public Setting<Boolean> chunkCaching = new Setting<>(true);
public final Setting<Boolean> chunkCaching = new Setting<>(true);
/**
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
* <p>
* Temporarily disabled, see issue #248
* Temporarily disabled
*
* @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
*/
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
/**
* Print all the debug messages to chat
*/
public Setting<Boolean> chatDebug = new Setting<>(true);
public final Setting<Boolean> chatDebug = new Setting<>(true);
/**
* Allow chat based control of Baritone. Most likely should be disabled when Baritone is imported for use in
* something else
*/
public Setting<Boolean> chatControl = new Setting<>(true);
public final Setting<Boolean> chatControl = new Setting<>(true);
/**
* A second override over chatControl to force it on
*/
public Setting<Boolean> removePrefix = new Setting<>(false);
public final Setting<Boolean> removePrefix = new Setting<>(false);
/**
* Render the path
*/
public Setting<Boolean> renderPath = new Setting<>(true);
public final Setting<Boolean> renderPath = new Setting<>(true);
/**
* Render the goal
*/
public Setting<Boolean> renderGoal = new Setting<>(true);
public final Setting<Boolean> renderGoal = new Setting<>(true);
/**
* Ignore depth when rendering the goal
*/
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
public final Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
/**
* Renders X/Z type Goals with the vanilla beacon beam effect. Combining this with
* {@link #renderGoalIgnoreDepth} will cause strange render clipping.
*/
public Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
public final Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
/**
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
*/
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
public final Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
/**
* Ignore depth when rendering the path
*/
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
public final Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
/**
* Line width of the path when rendered, in pixels
*/
public Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
public final Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
/**
* Line width of the goal when rendered, in pixels
*/
public Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
public final Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
/**
* Start fading out the path at 20 movements ahead, and stop rendering it entirely 30 movements ahead.
* Improves FPS.
*/
public Setting<Boolean> fadePath = new Setting<>(false);
public final Setting<Boolean> fadePath = new Setting<>(false);
/**
* Move without having to force the client-sided rotations
*/
public Setting<Boolean> freeLook = new Setting<>(true);
public final Setting<Boolean> freeLook = new Setting<>(true);
/**
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
@@ -438,48 +452,67 @@ public class Settings {
* At the moment this will silently set the player's rotations when using freeLook so you're not sprinting in
* directions other than forward, which is picken up by more "advanced" anticheats like AAC, but not NCP.
*/
public Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
public final Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
/**
* Exclusively use cached chunks for pathing
*/
public Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
public final Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
/**
* 😎 Render cached chunks as semitransparent.
* <p>
* Can be very useful on servers with low render distance. After enabling, you may need to reload the world in order for it to have an effect
* (e.g. disconnect and reconnect, enter then exit the nether, die and respawn, etc). This may literally kill your FPS and CPU because
* every chunk gets recompiled twice as much as normal, since the cached version comes into range, then the normal one comes from the server for real.
* <p>
* Note that flowing water is cached as AVOID, which is rendered as lava. As you get closer, you may therefore see lava falls being replaced with water falls.
* <p>
* SOLID is rendered as stone in the overworld, netherrack in the nether, and end stone in the end
*/
public Setting<Boolean> renderCachedChunks = new Setting<>(false);
/**
* 0.0f = not visible, fully transparent
* 1.0f = fully opaque
*/
public Setting<Float> cachedChunksOpacity = new Setting<>(0.5f);
/**
* Whether or not to use the "#" command prefix
*/
public Setting<Boolean> prefix = new Setting<>(false);
/**
* {@code true}: can mine blocks when in inventory, chat, or tabbed away in ESC menu
*/
public Setting<Boolean> leftClickWorkaround = new Setting<>(true);
public final Setting<Boolean> prefixControl = new Setting<>(true);
/**
* Don't stop walking forward when you need to break blocks in your way
*/
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
public final Setting<Boolean> walkWhileBreaking = new Setting<>(true);
/**
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
* If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful
*/
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
public final Setting<Integer> maxPathHistoryLength = new Setting<>(300);
/**
* If the current path is too long, cut off this many movements from the beginning.
*/
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
public final Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
/**
* Rescan for the goal once every 5 ticks.
* Set to 0 to disable.
*/
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
public final Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
/**
* When GetToBlock doesn't know any locations for the desired block, explore randomly instead of giving up.
*/
public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
/**
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
*/
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
public final Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
/**
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
@@ -494,54 +527,54 @@ public class Settings {
* <p>
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
*/
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
public final Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
/**
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
*/
public Setting<Integer> axisHeight = new Setting<>(120);
public final Setting<Integer> axisHeight = new Setting<>(120);
/**
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
* Disallow MineBehavior from using X-Ray to see where the ores are. Turn this option on to force it to mine "legit"
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
* couldn't. If you don't want it to look like you're X-Raying, turn this off
* couldn't. If you don't want it to look like you're X-Raying, turn this on
*/
public Setting<Boolean> legitMine = new Setting<>(false);
public final Setting<Boolean> legitMine = new Setting<>(false);
/**
* What Y level to go to for legit strip mining
*/
public Setting<Integer> legitMineYLevel = new Setting<>(11);
public final Setting<Integer> legitMineYLevel = new Setting<>(11);
/**
* When mining block of a certain type, try to mine two at once instead of one.
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
* If the block below is also a goal block, set GoalBlock to the position one down instead of GoalTwoBlocks
*/
public Setting<Boolean> forceInternalMining = new Setting<>(true);
public final Setting<Boolean> forceInternalMining = new Setting<>(true);
/**
* Modification to the previous setting, only has effect if forceInternalMining is true
* If true, only apply the previous setting if the block adjacent to the goal isn't air.
*/
public Setting<Boolean> internalMiningAirException = new Setting<>(true);
public final Setting<Boolean> internalMiningAirException = new Setting<>(true);
/**
* The actual GoalNear is set this distance away from the entity you're following
* <p>
* For example, set followOffsetDistance to 5 and followRadius to 0 to always stay precisely 5 blocks north of your follow target.
*/
public Setting<Double> followOffsetDistance = new Setting<>(0D);
public final Setting<Double> followOffsetDistance = new Setting<>(0D);
/**
* The actual GoalNear is set in this direction from the entity you're following
* The actual GoalNear is set in this direction from the entity you're following. This value is in degrees.
*/
public Setting<Float> followOffsetDirection = new Setting<>(0F);
public final Setting<Float> followOffsetDirection = new Setting<>(0F);
/**
* The radius (for the GoalNear) of how close to your target position you actually have to be
*/
public Setting<Integer> followRadius = new Setting<>(3);
public final Setting<Integer> followRadius = new Setting<>(3);
/**
* Cached chunks (regardless of if they're in RAM or saved to disk) expire and are deleted after this number of seconds
@@ -563,54 +596,55 @@ public class Settings {
* has to build up that cache from scratch. But after it's gone through an area just once, the next time will have zero
* backtracking, since the entire area is now known and cached.
*/
public Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
public final Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
/**
* The function that is called when Baritone will log to chat. This function can be added to
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value};
*/
public Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
/**
* The color of the current path
*/
public Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
public final Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
/**
* The color of the next path
*/
public Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
public final Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
/**
* The color of the blocks to break
*/
public Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
public final Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
/**
* The color of the blocks to place
*/
public Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
public final Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
/**
* The color of the blocks to walk into
*/
public Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
public final Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
/**
* The color of the best path so far
*/
public Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
public final Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
/**
* The color of the path to the most recent considered node
*/
public Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
public final Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
/**
* The color of the goal box
*/
public Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
public final Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
/**
* A map of lowercase setting field names to their respective setting

View File

@@ -37,7 +37,26 @@ public interface IPathingBehavior extends IBehavior {
*
* @return The estimated remaining ticks in the current segment.
*/
Optional<Double> ticksRemainingInSegment();
default Optional<Double> ticksRemainingInSegment() {
return ticksRemainingInSegment(true);
}
/**
* Returns the estimated remaining ticks in the current pathing
* segment. Given that the return type is an optional, {@link Optional#empty()}
* will be returned in the case that there is no current segment being pathed.
*
* @param includeCurrentMovement whether or not to include the entirety of the cost of the currently executing movement in the total
* @return The estimated remaining ticks in the current segment.
*/
default Optional<Double> ticksRemainingInSegment(boolean includeCurrentMovement) {
IPathExecutor current = getCurrent();
if (current == null) {
return Optional.empty();
}
int start = includeCurrentMovement ? current.getPosition() : current.getPosition() + 1;
return Optional.of(current.getPath().ticksRemainingFrom(start));
}
/**
* @return The current pathing goal
@@ -47,7 +66,9 @@ public interface IPathingBehavior extends IBehavior {
/**
* @return Whether or not a path is currently being executed.
*/
boolean isPathing();
default boolean isPathing() {
return getCurrent() != null;
}
/**
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.

View File

@@ -17,22 +17,20 @@
package baritone.api.event.events;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import baritone.api.event.events.type.Cancellable;
/**
* @author Brady
* @since 8/1/2018
*/
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
public final class ChatEvent extends Cancellable {
/**
* The message being sent
*/
private final String message;
public ChatEvent(EntityPlayerSP player, String message) {
super(player);
public ChatEvent(String message) {
this.message = message;
}

View File

@@ -18,22 +18,19 @@
package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* @author Brady
* @since 8/21/2018
*/
public final class PlayerUpdateEvent extends ManagedPlayerEvent {
public final class PlayerUpdateEvent {
/**
* The state of the event
*/
private final EventState state;
public PlayerUpdateEvent(EntityPlayerSP player, EventState state) {
super(player);
public PlayerUpdateEvent(EventState state) {
this.state = state;
}

View File

@@ -17,8 +17,6 @@
package baritone.api.event.events;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
@@ -26,7 +24,7 @@ import net.minecraft.entity.EntityLivingBase;
* @author Brady
* @since 8/21/2018
*/
public final class RotationMoveEvent extends ManagedPlayerEvent {
public final class RotationMoveEvent {
/**
* The type of event
@@ -38,8 +36,7 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
*/
private float yaw;
public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
super(player);
public RotationMoveEvent(Type type, float yaw) {
this.type = type;
this.yaw = yaw;
}

View File

@@ -0,0 +1,35 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events;
/**
* @author Brady
* @since 1/18/2019
*/
public final class SprintStateEvent {
private Boolean state;
public final void setState(boolean state) {
this.state = state;
}
public final Boolean getState() {
return this.state;
}
}

View File

@@ -1,61 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events.type;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* An event that has a reference to a locally managed player.
*
* @author Brady
* @since 10/11/2018
*/
public class ManagedPlayerEvent {
protected final EntityPlayerSP player;
public ManagedPlayerEvent(EntityPlayerSP player) {
this.player = player;
}
public final EntityPlayerSP getPlayer() {
return this.player;
}
public static class Cancellable extends ManagedPlayerEvent implements ICancellable {
/**
* Whether or not this event has been cancelled
*/
private boolean cancelled;
public Cancellable(EntityPlayerSP player) {
super(player);
}
@Override
public final void cancel() {
this.cancelled = true;
}
@Override
public final boolean isCancelled() {
return this.cancelled;
}
}
}

View File

@@ -57,6 +57,9 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override
default void onPlayerRotationMove(RotationMoveEvent event) {}
@Override
default void onPlayerSprintState(SprintStateEvent event) {}
@Override
default void onBlockInteract(BlockInteractEvent event) {}

View File

@@ -109,6 +109,14 @@ public interface IGameEventListener {
*/
void onPlayerRotationMove(RotationMoveEvent event);
/**
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate}
*
* @param event The event
* @see EntityPlayerSP#onLivingUpdate()
*/
void onPlayerSprintState(SprintStateEvent event);
/**
* Called when the local player interacts with a block, whether it is breaking or opening/placing.
*

View File

@@ -22,10 +22,26 @@ import baritone.api.process.PathingCommand;
import java.util.Optional;
/**
* @author leijurv
*/
public interface IPathingControlManager {
/**
* Registers a process with this pathing control manager. See {@link IBaritoneProcess} for more details.
*
* @param process The process
* @see IBaritoneProcess
*/
void registerProcess(IBaritoneProcess process);
/**
* @return The most recent {@link IBaritoneProcess} that had control
*/
Optional<IBaritoneProcess> mostRecentInControl();
/**
* @return The most recent pathing command executed
*/
Optional<PathingCommand> mostRecentCommand();
}

View File

@@ -26,4 +26,6 @@ import baritone.api.pathing.calc.IPath;
public interface IPathExecutor {
IPath getPath();
int getPosition();
}

View File

@@ -17,7 +17,6 @@
package baritone.api.process;
import baritone.api.IBaritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.PathEvent;
@@ -25,8 +24,10 @@ import baritone.api.event.events.PathEvent;
* A process that can control the PathingBehavior.
* <p>
* Differences between a baritone process and a behavior:
* Only one baritone process can be active at a time
* PathingBehavior can only be controlled by a process
* <ul>
* <li>Only one baritone process can be active at a time</li>
* <li>PathingBehavior can only be controlled by a process</li>
* </ul>
* <p>
* That's it actually
*
@@ -83,13 +84,6 @@ public interface IBaritoneProcess {
*/
double priority();
/**
* Returns which bot this process is associated with. (5000000iq forward thinking)
*
* @return The Bot associated with this process
*/
IBaritone associatedWith();
/**
* Returns a user-friendly name for this process. Suitable for a HUD.
*

View File

@@ -35,15 +35,6 @@ public final class BetterBlockPos extends BlockPos {
public final int x;
public final int y;
public final int z;
public static long numCreated;
static {
numCreated = 0;
}
{
numCreated++;
}
public BetterBlockPos(int x, int y, int z) {
super(x, y, z);

View File

@@ -0,0 +1,48 @@
/*
* 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 org.lwjgl.opengl.GL14;
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;
import static org.lwjgl.opengl.GL11.*;
@Mixin(ChunkRenderContainer.class)
public class MixinChunkRenderContainer {
@Inject(
method = "preRenderChunk",
at = @At("HEAD")
)
private void preRenderChunk(RenderChunk renderChunkIn, CallbackInfo ci) {
if (Baritone.settings().renderCachedChunks.get() && Minecraft.getMinecraft().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
GlStateManager.enableAlpha();
GlStateManager.enableBlend();
GL14.glBlendColor(0, 0, 0, Baritone.settings().cachedChunksOpacity.get());
GlStateManager.tryBlendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
}
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.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.get()) {
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);
}
}

View File

@@ -52,7 +52,7 @@ public class MixinEntity {
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
this.motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
}
}

View File

@@ -55,7 +55,7 @@ public abstract class MixinEntityLivingBase extends Entity {
private void preMoveRelative(CallbackInfo ci) {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
}
}

View File

@@ -18,11 +18,15 @@
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.ChatEvent;
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.settings.KeyBinding;
import net.minecraft.entity.player.PlayerCapabilities;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -43,7 +47,7 @@ public class MixinEntityPlayerSP {
cancellable = true
)
private void sendChatMessage(String msg, CallbackInfo ci) {
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
ChatEvent event = new ChatEvent(msg);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onSendChatMessage(event);
if (event.isCancelled()) {
ci.cancel();
@@ -60,7 +64,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPreUpdate(CallbackInfo ci) {
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
}
@Inject(
@@ -73,7 +77,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPostUpdate(CallbackInfo ci) {
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
}
@Redirect(
@@ -87,4 +91,35 @@ public class MixinEntityPlayerSP {
IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior();
return !pathingBehavior.isPathing() && capabilities.allowFlying;
}
@Redirect(
method = "onLivingUpdate",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"
)
)
private boolean isKeyDown(KeyBinding keyBinding) {
SprintStateEvent event = new SprintStateEvent();
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
baritone.getGameEventHandler().onPlayerSprintState(event);
if (event.getState() != null) {
return event.getState();
}
if (baritone != BaritoneAPI.getProvider().getPrimaryBaritone()) {
// hitting control shouldn't make all bots sprint
return false;
}
return keyBinding.isKeyDown();
}
@Inject(
method = "updateRidden",
at = @At(
value = "HEAD"
)
)
private void updateRidden(CallbackInfo cb) {
((LookBehavior) BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getLookBehavior()).pig();
}
}

View File

@@ -18,7 +18,6 @@
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.utils.Helper;
import net.minecraft.client.settings.KeyBinding;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -34,7 +33,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public class MixinKeyBinding {
@Shadow
public int pressTime;
private int pressTime;
@Inject(
method = "isKeyDown",
@@ -49,7 +48,7 @@ public class MixinKeyBinding {
}
}
@Inject(
/*@Inject(
method = "isPressed",
at = @At("HEAD"),
cancellable = true
@@ -57,12 +56,12 @@ public class MixinKeyBinding {
private void isPressed(CallbackInfoReturnable<Boolean> cir) {
// only the primary baritone forces keys
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
if (force != null && force == false) { // <-- cursed
if (force != null && !force) { // <-- cursed
if (pressTime > 0) {
Helper.HELPER.logDirect("You're trying to press this mouse button but I won't let you");
pressTime--;
}
cir.setReturnValue(force); // :sunglasses:
}
}
}*/
}

View File

@@ -0,0 +1,88 @@
/*
* 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.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.get()) {
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.get()) {
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);
}
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static org.lwjgl.opengl.GL11.*;
@Mixin(RenderList.class)
public class MixinRenderList {
@Inject(
method = "renderChunkLayer",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/GlStateManager.popMatrix()V"
)
)
private void renderChunkLayer(CallbackInfo info) {
if (Baritone.settings().renderCachedChunks.get()) {
// 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);
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static org.lwjgl.opengl.GL11.*;
@Mixin(VboRenderList.class)
public class MixinVboRenderList {
@Inject(
method = "renderChunkLayer",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/GlStateManager.popMatrix()V"
)
)
private void renderChunkLayer(CallbackInfo info) {
if (Baritone.settings().renderCachedChunks.get()) {
// 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);
}
}
}

View File

@@ -12,6 +12,8 @@
"MixinBlockPos",
"MixinChunkProviderClient",
"MixinChunkProviderServer",
"MixinChunkRenderContainer",
"MixinChunkRenderWorker",
"MixinEntity",
"MixinEntityLivingBase",
"MixinEntityPlayerSP",
@@ -20,6 +22,9 @@
"MixinMinecraft",
"MixinNetHandlerPlayClient",
"MixinNetworkManager",
"MixinRenderChunk",
"MixinRenderList",
"MixinVboRenderList",
"MixinWorldClient"
]
}

View File

@@ -29,10 +29,7 @@ import baritone.process.CustomGoalProcess;
import baritone.process.FollowProcess;
import baritone.process.GetToBlockProcess;
import baritone.process.MineProcess;
import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import baritone.utils.InputOverrideHandler;
import baritone.utils.PathingControlManager;
import baritone.utils.*;
import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
@@ -89,6 +86,8 @@ public class Baritone implements IBaritone {
private IPlayerContext playerContext;
private WorldProvider worldProvider;
public BlockStateInterface bsi;
Baritone() {
this.gameEventHandler = new GameEventHandler(this);
}

View File

@@ -95,6 +95,12 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
}
}
public void pig() {
if (this.target != null) {
ctx.player().rotationYaw = this.target.getYaw();
}
}
@Override
public void onPlayerRotationMove(RotationMoveEvent event) {
if (this.target != null && !this.force) {

View File

@@ -48,6 +48,8 @@ import java.nio.file.Path;
import java.util.*;
/**
* doesn't work for horse inventories :^)
*
* @author Brady
* @since 8/6/2018
*/
@@ -107,7 +109,6 @@ public final class MemoryBehavior extends Behavior {
}
if (p instanceof CPacketCloseWindow) {
updateInventory();
getCurrent().save();
}
}
@@ -142,7 +143,6 @@ public final class MemoryBehavior extends Behavior {
}
if (p instanceof SPacketCloseWindow) {
updateInventory();
getCurrent().save();
}
}

View File

@@ -19,10 +19,7 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.PathEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.*;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ;
@@ -33,13 +30,11 @@ import baritone.pathing.calc.AStarPathFinder;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.CutoffPath;
import baritone.pathing.path.PathExecutor;
import baritone.utils.Helper;
import baritone.utils.PathRenderer;
import baritone.utils.pathing.Favoring;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.ArrayList;
import java.util.Comparator;
@@ -98,6 +93,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
dispatchEvents();
}
@Override
public void onPlayerSprintState(SprintStateEvent event) {
if (current != null) {
event.setState(current.isSprinting());
}
}
private void tickPath() {
if (pauseRequestedLastTick && safeToCancel) {
pauseRequestedLastTick = false;
@@ -122,7 +124,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
next = null;
return;
}
if (next != null && !next.getPath().positions().contains(ctx.playerFeet())) {
if (next != null && !next.getPath().positions().contains(ctx.playerFeet()) && !next.getPath().positions().contains(pathStart())) { // can contain either one
// if the current path failed, we may not actually be on the next one, so make sure
logDebug("Discarding next path as it does not contain current position");
// for example if we had a nicely planned ahead path that starts where current ends
@@ -138,16 +140,27 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
current = next;
next = null;
current.onTick();
current.onTick(); // don't waste a tick doing nothing, get started right away
return;
}
// at this point, current just ended, but we aren't in the goal and have no plan for the future
synchronized (pathCalcLock) {
if (inProgress != null) {
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
// if we aren't calculating right now
return;
// we are calculating
// are we calculating the right thing though? 🤔
BetterBlockPos calcFrom = inProgress.getStart();
// if current just succeeded, we should be standing in calcFrom, so that's cool and good
// but if current just failed, we should discard this calculation since it doesn't start from where we're standing
if (calcFrom.equals(ctx.playerFeet()) || calcFrom.equals(pathStart())) {
// cool and good
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
return;
}
// oh noes
inProgress.cancel(); // cancellation doesn't dispatch any events
inProgress = null; // this is safe since we hold both locks
}
// we aren't calculating
queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true);
}
@@ -177,11 +190,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return;
}
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
// and this path dosen't get us all the way there
// and this path doesn't get us all the way there
return;
}
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
// and this path has 5 seconds or less left
if (ticksRemainingInSegment(false).get() < Baritone.settings().planningTickLookAhead.get()) {
// and this path has 7.5 seconds or less left
// don't include the current movement so a very long last movement (e.g. descend) doesn't trip it up
// if we actually included current, it wouldn't start planning ahead until the last movement was done, if the last movement took more than 7.5 seconds on its own
logDebug("Path almost over. Planning ahead...");
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
findPathInNewThread(current.getPath().getDest(), false);
@@ -207,14 +222,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
}
@Override
public Optional<Double> ticksRemainingInSegment() {
if (current == null) {
return Optional.empty();
}
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
}
public void secretInternalSetGoal(Goal goal) {
this.goal = goal;
}
@@ -244,11 +251,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return Optional.ofNullable(inProgress);
}
@Override
public boolean isPathing() {
return this.current != null;
}
public boolean isSafeToCancel() {
return current == null || safeToCancel;
}
@@ -271,7 +273,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (doIt) {
secretInternalSegmentCancel();
}
baritone.getPathingControlManager().cancelEverything();
baritone.getPathingControlManager().cancelEverything(); // regardless of if we can stop the current segment, we can still stop the processes
return doIt;
}
@@ -307,7 +309,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
public void forceCancel() { // NOT exposed on public api
cancelEverything();
secretInternalSegmentCancel();
inProgress = null;
synchronized (pathCalcLock) {
inProgress = null;
}
}
/**
@@ -430,33 +434,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout);
Optional<IPath> path = calcResult.getPath();
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
path = path.map(p -> {
IPath result = p.cutoffAtLoadedChunks(context.bsi);
if (result instanceof CutoffPath) {
logDebug("Cutting off path at edge of loaded chunks");
logDebug("Length decreased by " + (p.length() - result.length()));
} else {
logDebug("Path ends within loaded chunks");
}
return result;
});
}
Optional<PathExecutor> executor = path.map(p -> {
IPath result = p.staticCutoff(goal);
if (result instanceof CutoffPath) {
logDebug("Static cutoff " + p.length() + " to " + result.length());
}
return result;
}).map(p -> new PathExecutor(this, p));
synchronized (pathPlanLock) {
Optional<PathExecutor> executor = calcResult.getPath().map(p -> new PathExecutor(PathingBehavior.this, p));
if (current == null) {
if (executor.isPresent()) {
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);

View File

@@ -124,12 +124,13 @@ public final class ChunkPacker {
private static PathingBlockType getPathingBlockType(IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) {
if ((block == Blocks.WATER || block == Blocks.FLOWING_WATER) && !MovementHelper.isFlowing(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
return PathingBlockType.WATER;
}
if (MovementHelper.avoidWalkingInto(block) || block == Blocks.FLOWING_WATER || MovementHelper.isBottomSlab(state)) {
if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) {
return PathingBlockType.AVOID;
}
// We used to do an AABB check here

View File

@@ -24,6 +24,7 @@ import baritone.utils.accessor.IAnvilChunkLoader;
import baritone.utils.accessor.IChunkProviderServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.world.WorldServer;
import org.apache.commons.lang3.SystemUtils;
import java.io.File;
import java.io.FileOutputStream;
@@ -76,7 +77,11 @@ public class WorldProvider implements IWorldProvider, Helper {
directory = new File(directory, "baritone");
readme = directory;
} else { // Otherwise, the server must be remote...
directory = new File(Baritone.getDir(), mc.getCurrentServerData().serverIP);
String folderName = mc.getCurrentServerData().serverIP;
if (SystemUtils.IS_OS_WINDOWS) {
folderName = folderName.replace(":", "_");
}
directory = new File(Baritone.getDir(), folderName);
readme = Baritone.getDir();
}

View File

@@ -23,6 +23,7 @@ import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.IEventBus;
import baritone.api.event.listener.IGameEventListener;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@@ -46,6 +47,13 @@ public final class GameEventHandler implements IEventBus, Helper {
@Override
public final void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.IN) {
try {
baritone.bsi = new BlockStateInterface(baritone.getPlayerContext(), true);
} catch (Exception ex) {}
} else {
baritone.bsi = null;
}
listeners.forEach(l -> l.onTick(event));
}
@@ -121,6 +129,11 @@ public final class GameEventHandler implements IEventBus, Helper {
listeners.forEach(l -> l.onPlayerRotationMove(event));
}
@Override
public void onPlayerSprintState(SprintStateEvent event) {
listeners.forEach(l -> l.onPlayerSprintState(event));
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
listeners.forEach(l -> l.onBlockInteract(event));

View File

@@ -25,15 +25,10 @@ import baritone.api.utils.BetterBlockPos;
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Moves;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.pathing.BetterWorldBorder;
import baritone.utils.pathing.Favoring;
import baritone.utils.pathing.MutableMoveResult;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;
/**
@@ -41,7 +36,7 @@ import java.util.Optional;
*
* @author leijurv
*/
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
public final class AStarPathFinder extends AbstractNodeCostSearch {
private final Favoring favoring;
private final CalculationContext calcContext;
@@ -59,14 +54,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
startNode.combinedCost = startNode.estimatedCostToGoal;
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
openSet.insert(startNode);
bestSoFar = new PathNode[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
for (int i = 0; i < bestHeuristicSoFar.length; i++) {
bestHeuristicSoFar[i] = startNode.estimatedCostToGoal;
bestSoFar[i] = startNode;
}
MutableMoveResult res = new MutableMoveResult();
Favoring favored = favoring;
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world.getWorldBorder());
long startTime = System.currentTimeMillis();
boolean slowPath = Baritone.settings().slowPath.get();
@@ -79,34 +72,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
int numNodes = 0;
int numMovementsConsidered = 0;
int numEmptyChunk = 0;
boolean favoring = !favored.isEmpty();
boolean isFavoring = !favoring.isEmpty();
int timeCheckInterval = 1 << 6;
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
long[] timeConsumed = new long[Moves.values().length];
int[] count = new int[Moves.values().length];
int[] stateLookup = new int[Moves.values().length];
long[] posCreation = new long[Moves.values().length];
long heapRemove = 0;
int heapRemoveCount = 0;
long heapAdd = 0;
int heapAddCount = 0;
long heapUpdate = 0;
int heapUpdateCount = 0;
long chunk = 0;
int chunkCount = 0;
long goalCheck = 0;
int goalCheckCount = 0;
long getNode = 0;
int getNodeCount = 0;
int startVal = BlockStateInterface.numTimesChunkSucceeded;
int startVal2 = BlockStateInterface.numBlockStateLookups;
long startVal3 = BetterBlockPos.numCreated;
double minimumImprovement = Baritone.settings().minimumImprovementRepropagation.get() ? MIN_IMPROVEMENT : 0;
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)
@@ -120,21 +89,14 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
} catch (InterruptedException ex) {
}
}
long before = System.nanoTime();
PathNode currentNode = openSet.removeLowest();
long t = System.nanoTime();
heapRemove += t - before;
heapRemoveCount++;
mostRecentConsidered = currentNode;
numNodes++;
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered");
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
}
goalCheck += System.nanoTime() - t;
goalCheckCount++;
for (Moves moves : Moves.values()) {
long s = System.nanoTime();
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)) {
@@ -142,9 +104,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
numEmptyChunk++;
}
long costStart = System.nanoTime();
chunk += costStart - s;
chunkCount++;
continue;
}
if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) {
@@ -153,19 +112,8 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
if (currentNode.y + moves.yOffset > 256 || currentNode.y + moves.yOffset < 0) {
continue;
}
long costStart = System.nanoTime();
chunk += costStart - s;
chunkCount++;
// TODO cache cost
int numLookupsBefore = BlockStateInterface.numBlockStateLookups;
long numCreatedBefore = BetterBlockPos.numCreated;
res.reset();
moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res);
long costEnd = System.nanoTime();
stateLookup[moves.ordinal()] += BlockStateInterface.numBlockStateLookups - numLookupsBefore;
posCreation[moves.ordinal()] += BetterBlockPos.numCreated - numCreatedBefore;
timeConsumed[moves.ordinal()] += costEnd - costStart;
count[moves.ordinal()]++;
numMovementsConsidered++;
double actionCost = res.cost;
if (actionCost >= ActionCosts.COST_INF) {
@@ -185,47 +133,27 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
}
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (favoring) {
if (isFavoring) {
// see issue #18
actionCost *= favored.calculate(hashCode);
actionCost *= favoring.calculate(hashCode);
}
long st = System.nanoTime();
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
getNode += System.nanoTime() - st;
getNodeCount++;
double tentativeCost = currentNode.cost + actionCost;
if (tentativeCost < neighbor.cost) {
double improvementBy = neighbor.cost - tentativeCost;
// there are floating point errors caused by random combinations of traverse and diagonal over a flat area
// that means that sometimes there's a cost improvement of like 10 ^ -16
// it's not worth the time to update the costs, decrease-key the heap, potentially repropagate, etc
if (improvementBy < 0.01 && minimumImprovementRepropagation) {
// who cares about a hundredth of a tick? that's half a millisecond for crying out loud!
continue;
}
if (neighbor.cost - tentativeCost > minimumImprovement) {
neighbor.previous = currentNode;
neighbor.cost = tentativeCost;
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
if (neighbor.isOpen()) {
long bef = System.nanoTime();
openSet.update(neighbor);
heapUpdate += System.nanoTime() - bef;
heapUpdateCount++;
} else {
long bef = System.nanoTime();
openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there
heapAdd += System.nanoTime() - bef;
heapAddCount++;
}
for (int i = 0; i < bestSoFar.length; i++) {
for (int i = 0; i < COEFFICIENTS.length; i++) {
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
if (heuristic < bestHeuristicSoFar[i]) {
if (bestHeuristicSoFar[i] - heuristic < 0.01 && minimumImprovementRepropagation) {
continue;
}
if (bestHeuristicSoFar[i] - heuristic > minimumImprovement) {
bestHeuristicSoFar[i] = heuristic;
bestSoFar[i] = neighbor;
if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
if (failing && getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
failing = false;
}
}
@@ -233,36 +161,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
}
}
}
int numBlockState = BlockStateInterface.numBlockStateLookups - startVal2;
int numSucc = BlockStateInterface.numTimesChunkSucceeded - startVal;
long numSuccc = BetterBlockPos.numCreated - startVal3;
long totalAccountedTimeMS = 0;
totalAccountedTimeMS += heapRemove / 1000000;
totalAccountedTimeMS += heapAdd / 1000000;
totalAccountedTimeMS += heapUpdate / 1000000;
totalAccountedTimeMS += chunk / 1000000;
totalAccountedTimeMS += getNode / 1000000;
totalAccountedTimeMS += goalCheck / 1000000;
System.out.println("Out of " + numBlockState + " block state lookups, " + numSucc + " were in the same chunk as the previous and could be cached");
System.out.println("Instantiated " + numSuccc + " BetterBlockPos objects");
System.out.println("Remove " + (heapRemove / heapRemoveCount) + " " + heapRemove / 1000000 + "ms " + heapRemoveCount);
System.out.println("Add " + (heapAdd / heapAddCount) + " " + heapAdd / 1000000 + "ms " + heapAddCount);
System.out.println("Update " + (heapUpdate / heapUpdateCount) + " " + heapUpdate / 1000000 + "ms " + heapUpdateCount);
System.out.println("Chunk " + (chunk / chunkCount) + " " + chunk / 1000000 + "ms " + chunkCount);
System.out.println("GetNode " + (getNode / getNodeCount) + " " + getNode / 1000000 + "ms " + getNodeCount);
System.out.println("GoalCheck " + (goalCheck / goalCheckCount) + " " + goalCheck / 1000000 + "ms " + goalCheckCount);
ArrayList<Moves> moves = new ArrayList<>(Arrays.asList(Moves.values()));
moves.sort(Comparator.comparingLong(k -> timeConsumed[k.ordinal()] / count[k.ordinal()]));
for (Moves move : moves) {
int num = count[move.ordinal()];
long nanoTime = timeConsumed[move.ordinal()];
totalAccountedTimeMS += nanoTime / 1000000;
System.out.println(nanoTime / num + " " + move + " " + nanoTime / 1000000 + "ms " + num);
System.out.println(stateLookup[move.ordinal()] / num + " " + stateLookup[move.ordinal()]);
System.out.println(posCreation[move.ordinal()] / num + " " + posCreation[move.ordinal()]);
}
System.out.println("Total accounted time: " + totalAccountedTimeMS);
if (cancelRequested) {
return Optional.empty();
}
@@ -270,28 +168,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
System.out.println("Open set size: " + openSet.size());
System.out.println("PathNode map size: " + mapSize());
System.out.println((int) (numNodes * 1.0 / ((System.currentTimeMillis() - startTime) / 1000F)) + " nodes per second");
double bestDist = 0;
for (int i = 0; i < bestSoFar.length; i++) {
if (bestSoFar[i] == null) {
continue;
}
double dist = getDistFromStartSq(bestSoFar[i]);
if (dist > bestDist) {
bestDist = dist;
}
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, A* cost coefficient " + COEFFICIENTS[i] + ", " + numMovementsConsidered + " movements considered");
if (COEFFICIENTS[i] >= 3) {
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
System.out.println("But I'm going to do it anyway, because yolo");
}
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, calcContext));
}
Optional<IPath> result = bestSoFar(true, numNodes);
if (result.isPresent()) {
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered");
}
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
logDebug("No path found =(");
return Optional.empty();
return result;
}
}

View File

@@ -34,7 +34,7 @@ import java.util.Optional;
*
* @author leijurv
*/
public abstract class AbstractNodeCostSearch implements IPathFinder {
public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
protected final int startX;
protected final int startY;
@@ -53,7 +53,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
protected PathNode mostRecentConsidered;
protected PathNode[] bestSoFar;
protected final PathNode[] bestSoFar = new PathNode[COEFFICIENTS.length];
private volatile boolean isFinished;
@@ -63,13 +63,23 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
* This is really complicated and hard to explain. I wrote a comment in the old version of MineBot but it was so
* long it was easier as a Google Doc (because I could insert charts).
*
* @see <a href="https://docs.google.com/document/d/1WVHHXKXFdCR1Oz__KtK8sFqyvSwJN_H4lftkHFgmzlc/edit"></a>
* @see <a href="https://docs.google.com/document/d/1WVHHXKXFdCR1Oz__KtK8sFqyvSwJN_H4lftkHFgmzlc/edit">here</a>
*/
protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10}; // big TODO tune
protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10};
/**
* If a path goes less than 5 blocks and doesn't make it to its goal, it's not worth considering.
*/
protected final static double MIN_DIST_PATH = 5;
protected static final double MIN_DIST_PATH = 5;
/**
* there are floating point errors caused by random combinations of traverse and diagonal over a flat area
* that means that sometimes there's a cost improvement of like 10 ^ -16
* it's not worth the time to update the costs, decrease-key the heap, potentially repropagate, etc
* <p>
* who cares about a hundredth of a tick? that's half a millisecond for crying out loud!
*/
protected static final double MIN_IMPROVEMENT = 0.01;
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) {
this.startX = startX;
@@ -92,13 +102,25 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
cancelRequested = false;
try {
IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null);
isFinished = true;
if (cancelRequested) {
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path);
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION);
}
if (path == null) {
return new PathCalculationResult(PathCalculationResult.Type.FAILURE);
}
int previousLength = path.length();
path = path.cutoffAtLoadedChunks(context.bsi);
if (path.length() < previousLength) {
Helper.HELPER.logDebug("Cutting off path at edge of loaded chunks");
Helper.HELPER.logDebug("Length decreased by " + (previousLength - path.length()));
} else {
Helper.HELPER.logDebug("Path ends within loaded chunks");
}
previousLength = path.length();
path = path.staticCutoff(goal);
if (path.length() < previousLength) {
Helper.HELPER.logDebug("Static cutoff " + previousLength + " to " + path.length());
}
if (goal.isInGoal(path.getDest())) {
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_TO_GOAL, path);
} else {
@@ -158,25 +180,43 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context));
}
protected int mapSize() {
return map.size();
}
@Override
public Optional<IPath> bestPathSoFar() {
return bestSoFar(false, 0);
}
protected Optional<IPath> bestSoFar(boolean logInfo, int numNodes) {
if (startNode == null || bestSoFar == null) {
return Optional.empty();
}
for (int i = 0; i < bestSoFar.length; i++) {
double bestDist = 0;
for (int i = 0; i < COEFFICIENTS.length; i++) {
if (bestSoFar[i] == null) {
continue;
}
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context));
double dist = getDistFromStartSq(bestSoFar[i]);
if (dist > bestDist) {
bestDist = dist;
}
if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
if (logInfo) {
if (COEFFICIENTS[i] >= 3) {
System.out.println("Warning: cost coefficient is greater than three! Probably means that");
System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)");
System.out.println("But I'm going to do it anyway, because yolo");
}
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
logDebug("A* cost coefficient " + COEFFICIENTS[i]);
}
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, context));
}
}
// instead of returning bestSoFar[0], be less misleading
// if it actually won't find any path, don't make them think it will by rendering a dark blue that will never actually happen
if (logInfo) {
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
logDebug("No path found =(");
}
return Optional.empty();
}
@@ -189,4 +229,12 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
public final Goal getGoal() {
return goal;
}
public BetterBlockPos getStart() {
return new BetterBlockPos(startX, startY, startZ);
}
protected int mapSize() {
return map.size();
}
}

View File

@@ -123,7 +123,7 @@ public abstract class Movement implements IMovement, MovementHelper {
baritone.getLookBehavior().updateTarget(
rotation,
currentState.getTarget().hasToForceRotations()));
baritone.getInputOverrideHandler().clearAllKeys();
currentState.getInputStates().forEach((input, forced) -> {
baritone.getInputOverrideHandler().setInputForceState(input, forced);
});

View File

@@ -18,7 +18,9 @@
package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.*;
import baritone.api.utils.input.Input;
import baritone.pathing.movement.MovementState.MovementTarget;
@@ -35,6 +37,10 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP;
/**
* Static helpers for cost calculation
@@ -485,4 +491,48 @@ public interface MovementHelper extends ActionCosts, Helper {
return state.getBlock() instanceof BlockLiquid
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
static PlaceResult attemptToPlaceABlock(MovementState state, IBaritone baritone, BlockPos placeAt, boolean preferDown) {
IPlayerContext ctx = baritone.getPlayerContext();
boolean found = false;
for (int i = 0; i < 5; i++) {
BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
//if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
if (!throwaway(ctx, true)) {
Helper.HELPER.logDebug("bb pls get me some blocks. dirt or cobble");
state.setStatus(MovementStatus.UNREACHABLE);
return PlaceResult.NO_OPTION;
}
double faceX = (placeAt.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (placeAt.getY() + against1.getY() + 1.0D) * 0.5D;
double faceZ = (placeAt.getZ() + against1.getZ() + 1.0D) * 0.5D;
Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance());
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) {
state.setTarget(new MovementState.MovementTarget(place, true));
found = true;
if (!preferDown) {
// if preferDown is true, we want the last option
// if preferDown is false, we want the first
break;
}
}
}
}
if (ctx.getSelectedBlock().isPresent()) {
BlockPos selectedBlock = ctx.getSelectedBlock().get();
EnumFacing side = ctx.objectMouseOver().sideHit;
// only way for selectedBlock.equals(placeAt) to be true is if it's replacable
if (selectedBlock.equals(placeAt) || (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(placeAt))) {
return PlaceResult.READY_TO_PLACE;
}
}
return found ? PlaceResult.ATTEMPTING : PlaceResult.NO_OPTION;
}
enum PlaceResult {
READY_TO_PLACE, ATTEMPTING, NO_OPTION;
}
}

View File

@@ -21,7 +21,6 @@ import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.input.Input;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
@@ -32,10 +31,6 @@ import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.Objects;
public class MovementAscend extends Movement {
@@ -162,55 +157,30 @@ public class MovementAscend extends Movement {
IBlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace);
if (!MovementHelper.canWalkOn(ctx, positionToPlace, jumpingOnto)) {
for (int i = 0; i < 5; i++) {
BlockPos anAgainst = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
if (anAgainst.equals(src)) {
continue;
}
if (MovementHelper.canPlaceAgainst(ctx, anAgainst)) {
if (!MovementHelper.throwaway(ctx, true)) {//get ready to place a throwaway block
return state.setStatus(MovementStatus.UNREACHABLE);
}
double faceX = (dest.getX() + anAgainst.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + anAgainst.getY()) * 0.5D;
double faceZ = (dest.getZ() + anAgainst.getZ() + 1.0D) * 0.5D;
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()), true));
EnumFacing side = ctx.objectMouseOver().sideHit;
ctx.getSelectedBlock().ifPresent(selectedBlock -> {
if (Objects.equals(selectedBlock, anAgainst) && selectedBlock.offset(side).equals(positionToPlace)) {
ticksWithoutPlacement++;
state.setInput(Input.SNEAK, true);
if (ctx.player().isSneaking()) {
state.setInput(Input.CLICK_RIGHT, true);
}
if (ticksWithoutPlacement > 10) {
// After 10 ticks without placement, we might be standing in the way, move back
state.setInput(Input.MOVE_BACK, true);
}
} else {
state.setInput(Input.CLICK_LEFT, true); // break whatever replaceable block is in the way
}
//System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
});
return state;
ticksWithoutPlacement++;
if (MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), false) == PlaceResult.READY_TO_PLACE) {
state.setInput(Input.SNEAK, true);
if (ctx.player().isSneaking()) {
state.setInput(Input.CLICK_RIGHT, true);
}
}
return state.setStatus(MovementStatus.UNREACHABLE);
if (ticksWithoutPlacement > 10) {
// After 10 ticks without placement, we might be standing in the way, move back
state.setInput(Input.MOVE_BACK, true);
}
return state;
}
MovementHelper.moveTowards(ctx, state, dest);
if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(BlockStateInterface.get(ctx, src.down()))) {
return state; // don't jump while walking from a non double slab into a bottom slab
}
if (Baritone.settings().assumeStep.get()) {
if (Baritone.settings().assumeStep.get() || ctx.playerFeet().equals(src.up())) {
// no need to hit space if we're already jumping
return state;
}
if (ctx.playerFeet().equals(src.up())) {
return state; // no need to hit space if we're already jumping
}
if (headBonkClear()) {
return state.setInput(Input.JUMP, true);
}

View File

@@ -137,7 +137,7 @@ public class MovementDescend extends Movement {
IBlockState ontoBlock = context.get(destX, newY, destZ);
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
if (ontoBlock.getBlock() == Blocks.WATER && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) {
if ((ontoBlock.getBlock() == Blocks.WATER || ontoBlock.getBlock() == Blocks.FLOWING_WATER) && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) {
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
// however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works)
if (context.assumeWalkOnWater) {
@@ -157,9 +157,6 @@ public class MovementDescend extends Movement {
res.cost = tentativeCost;// TODO incorporate water swim up cost?
return false;
}
if (ontoBlock.getBlock() == Blocks.FLOWING_WATER) {
return false;
}
if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) {
// if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know
// this effectively "resets" our falling speed
@@ -177,13 +174,6 @@ public class MovementDescend extends Movement {
if (MovementHelper.isBottomSlab(ontoBlock)) {
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
}
if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
res.x = destX;
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
res.z = destZ;
res.cost = tentativeCost + context.placeBlockCost;
return true;
}
if (unprotectedFallHeight <= context.maxFallHeightNoWater + 1) {
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
res.x = destX;
@@ -191,6 +181,13 @@ public class MovementDescend extends Movement {
res.z = destZ;
res.cost = tentativeCost;
return false;
}
if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
res.x = destX;
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
res.z = destZ;
res.cost = tentativeCost + context.placeBlockCost;
return true;
} else {
return false;
}
@@ -235,8 +232,7 @@ public class MovementDescend extends Movement {
if (numTicks++ < 20) {
MovementHelper.moveTowards(ctx, state, fakeDest);
if (fromStart > 1.25) {
state.setInput(Input.MOVE_FORWARD, false);
state.setInput(Input.MOVE_BACK, true);
state.getTarget().rotation = new Rotation(state.getTarget().rotation.getYaw() + 180F, state.getTarget().rotation.getPitch());
}
} else {
MovementHelper.moveTowards(ctx, state, dest);

View File

@@ -114,7 +114,7 @@ public class MovementDiagonal extends Movement {
return;
}
IBlockState pb3 = context.get(destX, y + 1, z);
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) {
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3.getBlock()))) {
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
return;
}
@@ -123,7 +123,7 @@ 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()) && pb1.getBlock() != Blocks.WATER))) {
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1.getBlock()))) {
// and now that option B is fully calculated, see if we can edge around that way
return;
}

View File

@@ -30,6 +30,7 @@ import baritone.pathing.movement.MovementHelper;
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;
@@ -79,7 +80,9 @@ public class MovementFall extends Movement {
BlockPos playerFeet = ctx.playerFeet();
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest));
Rotation targetRotation = null;
if (!MovementHelper.isWater(ctx, dest) && willPlaceBucket() && !playerFeet.equals(dest)) {
Block destBlock = ctx.world().getBlockState(dest).getBlock();
boolean isWater = destBlock == Blocks.WATER || destBlock == Blocks.FLOWING_WATER;
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) {
return state.setStatus(MovementStatus.UNREACHABLE);
}
@@ -100,8 +103,8 @@ public class MovementFall extends Movement {
} else {
state.setTarget(new MovementTarget(toDest, false));
}
if (playerFeet.equals(dest) && (ctx.player().posY - playerFeet.getY() < 0.094 || MovementHelper.isWater(ctx, dest))) { // 0.094 because lilypads
if (MovementHelper.isWater(ctx, dest)) {
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))) {
ctx.player().inventory.currentItem = ctx.player().inventory.getSlotFor(STACK_BUCKET_EMPTY);
if (ctx.player().motionY >= 0) {
@@ -132,7 +135,7 @@ public class MovementFall extends Movement {
double dist = Math.abs(avoid.getX() * (destCenter.x - avoid.getX() / 2.0 - ctx.player().posX)) + Math.abs(avoid.getZ() * (destCenter.z - avoid.getZ() / 2.0 - ctx.player().posZ));
if (dist < 0.6) {
state.setInput(Input.MOVE_FORWARD, true);
} else {
} else if (!ctx.player().onGround) {
state.setInput(Input.SNEAK, false);
}
}

View File

@@ -20,9 +20,6 @@ package baritone.pathing.movement.movements;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.input.Input;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
@@ -35,9 +32,6 @@ import net.minecraft.block.BlockStairs;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
public class MovementParkour extends Movement {
@@ -193,6 +187,11 @@ public class MovementParkour extends Movement {
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) {
state.setInput(Input.SPRINT, true);
}
@@ -209,35 +208,9 @@ public class MovementParkour extends Movement {
}
} else if (!ctx.playerFeet().equals(src)) {
if (ctx.playerFeet().equals(src.offset(direction)) || ctx.player().posY - ctx.playerFeet().getY() > 0.0001) {
if (!MovementHelper.canWalkOn(ctx, dest.down()) && !ctx.player().onGround) {
BlockPos positionToPlace = dest.down();
for (int i = 4; i >= 0; i--) { // go in the opposite order to check DOWN before all horizontals -- down is preferable because you don't have to look to the side while in midair, which could mess up the trajectory
BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
if (against1.up().equals(src.offset(direction, 3))) { // we can't turn around that fast
continue;
}
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
if (!MovementHelper.throwaway(ctx, true)) {//get ready to place a throwaway block
return state.setStatus(MovementStatus.UNREACHABLE);
}
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + against1.getY()) * 0.5D;
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance());
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(dest.down())) {
state.setTarget(new MovementState.MovementTarget(place, true));
break;
}
}
}
ctx.getSelectedBlock().ifPresent(selectedBlock -> {
EnumFacing side = ctx.objectMouseOver().sideHit;
if (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(dest.down())) {
state.setInput(Input.CLICK_RIGHT, true);
}
});
if (!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
double xDiff = (src.x + 0.5) - ctx.player().posX;

View File

@@ -35,6 +35,8 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.Objects;
public class MovementPillar extends Movement {
public MovementPillar(IBaritone baritone, BetterBlockPos start, BetterBlockPos end) {
@@ -224,7 +226,7 @@ public class MovementPillar extends Movement {
if (!(fr instanceof BlockAir || fr.isReplaceable(ctx.world(), src))) {
state.setInput(Input.CLICK_LEFT, true);
blockIsThere = false;
} else if (ctx.player().isSneaking()) { // 1 tick after we're able to place
} else if (ctx.player().isSneaking() && (Objects.equals(src.down(), ctx.objectMouseOver().getBlockPos()) || Objects.equals(src, ctx.objectMouseOver().getBlockPos()))) {
state.setInput(Input.CLICK_RIGHT, true);
}
}

View File

@@ -36,7 +36,6 @@ import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@@ -136,7 +135,7 @@ 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())) {
return COST_INF; // can't sneak and backplace against soul sand or half slabs =/
return COST_INF; // can't sneak and backplace against soul sand or half slabs (regardless of whether it's top half or bottom half) =/
}
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
return COST_INF; // this is obviously impossible
@@ -247,53 +246,47 @@ public class MovementTraverse extends Movement {
return state;
} else {
wasTheBridgeBlockAlwaysThere = false;
for (int i = 0; i < 5; i++) {
BlockPos against1 = dest.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
if (against1.equals(src)) {
continue;
}
against1 = against1.down();
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
if (!MovementHelper.throwaway(ctx, true)) { // get ready to place a throwaway block
logDebug("bb pls get me some blocks. dirt or cobble");
return state.setStatus(MovementStatus.UNREACHABLE);
}
if (!Baritone.settings().assumeSafeWalk.get()) {
state.setInput(Input.SNEAK, true);
}
Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock();
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
double dist = Math.max(Math.abs(dest.getX() + 0.5 - ctx.player().posX), Math.abs(dest.getZ() + 0.5 - ctx.player().posZ));
if (dist < 0.85) { // 0.5 + 0.3 + epsilon
MovementHelper.moveTowards(ctx, state, dest);
return state.setInput(Input.MOVE_FORWARD, false)
.setInput(Input.MOVE_BACK, true);
}
}
state.setInput(Input.MOVE_BACK, false);
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + against1.getY()) * 0.5D;
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()), true));
EnumFacing side = ctx.objectMouseOver().sideHit;
if (Objects.equals(ctx.getSelectedBlock().orElse(null), against1) && (ctx.player().isSneaking() || Baritone.settings().assumeSafeWalk.get()) && ctx.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
return state.setInput(Input.CLICK_RIGHT, true);
}
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
return state.setInput(Input.CLICK_LEFT, true);
Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock();
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
double dist = Math.max(Math.abs(dest.getX() + 0.5 - ctx.player().posX), Math.abs(dest.getZ() + 0.5 - ctx.player().posZ));
if (dist < 0.85) { // 0.5 + 0.3 + epsilon
MovementHelper.moveTowards(ctx, state, dest);
return state.setInput(Input.MOVE_FORWARD, false)
.setInput(Input.MOVE_BACK, true);
}
}
if (!Baritone.settings().assumeSafeWalk.get()) {
double dist1 = Math.max(Math.abs(ctx.player().posX - (dest.getX() + 0.5D)), Math.abs(ctx.player().posZ - (dest.getZ() + 0.5D)));
PlaceResult p = MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), false);
if ((p == PlaceResult.READY_TO_PLACE || dist1 < 0.6) && !Baritone.settings().assumeSafeWalk.get()) {
state.setInput(Input.SNEAK, true);
}
switch (p) {
case READY_TO_PLACE: {
if (ctx.player().isSneaking() || Baritone.settings().assumeSafeWalk.get()) {
state.setInput(Input.CLICK_RIGHT, true);
}
return state;
}
case ATTEMPTING: {
if (dist1 > 0.83) {
// might need to go forward a bit
float yaw = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()).getYaw();
if (Math.abs(state.getTarget().rotation.getYaw() - yaw) < 0.1) {
// but only if our attempted place is straight ahead
return state.setInput(Input.MOVE_FORWARD, true);
}
} else if (ctx.playerRotations().isReallyCloseTo(state.getTarget().rotation)) {
// well i guess theres something in the way
return state.setInput(Input.CLICK_LEFT, true);
}
return state;
}
default:
break;
}
if (whereAmI.equals(dest)) {
// If 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);
if (!MovementHelper.throwaway(ctx, true)) {// get ready to place a throwaway block
logDebug("bb pls get me some blocks. dirt or cobble");
return state.setStatus(MovementStatus.UNREACHABLE);
}
double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + src.getY() - 1.0D) * 0.5D;
double faceZ = (dest.getZ() + src.getZ() + 1.0D) * 0.5D;
@@ -302,25 +295,26 @@ public class MovementTraverse extends Movement {
Rotation backToFace = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
float pitch = backToFace.getPitch();
double dist = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ));
if (dist < 0.29) {
double dist2 = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ));
if (dist2 < 0.29) { // see issue #208
float yaw = RotationUtils.calcRotationFromVec3d(VecUtils.getBlockPosCenter(dest), ctx.playerHead(), ctx.playerRotations()).getYaw();
state.setTarget(new MovementState.MovementTarget(new Rotation(yaw, pitch), true));
state.setInput(Input.MOVE_BACK, true);
} else {
state.setTarget(new MovementState.MovementTarget(backToFace, true));
}
state.setInput(Input.SNEAK, true);
if (Objects.equals(ctx.getSelectedBlock().orElse(null), goalLook)) {
return state.setInput(Input.CLICK_RIGHT, true); // wait to right click until we are able to place
}
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());
return state.setInput(Input.CLICK_LEFT, true);
} else {
MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
if (ctx.playerRotations().isReallyCloseTo(state.getTarget().rotation)) {
state.setInput(Input.CLICK_LEFT, true);
}
return state;
// TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
}
MovementHelper.moveTowards(ctx, state, positionsToBreak[0]);
return state;
// TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block
}
}
@@ -342,4 +336,4 @@ public class MovementTraverse extends Movement {
}
return super.prepared(state);
}
}
}

View File

@@ -79,6 +79,8 @@ public class PathExecutor implements IPathExecutor, Helper {
private PathingBehavior behavior;
private IPlayerContext ctx;
private boolean sprintNextTick;
public PathExecutor(PathingBehavior behavior, IPath path) {
this.behavior = behavior;
this.ctx = behavior.ctx;
@@ -247,6 +249,8 @@ public class PathExecutor implements IPathExecutor, Helper {
return true;
}
if (!movement.calculatedWhileLoaded() && currentCost - currentMovementOriginalCostEstimate > Baritone.settings().maxCostIncrease.get() && canCancel) {
// don't do this if the movement was calculated while loaded
// that means that this isn't a cache error, it's just part of the path interfering with a later part
logDebug("Original cost " + currentMovementOriginalCostEstimate + " current cost " + currentCost + ". Cancelling.");
cancel();
return true;
@@ -269,7 +273,10 @@ public class PathExecutor implements IPathExecutor, Helper {
onTick();
return true;
} else {
sprintIfRequested();
sprintNextTick = shouldSprintNextTick();
if (!sprintNextTick) {
ctx.player().setSprinting(false); // letting go of control doesn't make you stop sprinting actually
}
ticksOnCurrent++;
if (ticksOnCurrent > currentMovementOriginalCostEstimate + Baritone.settings().movementTimeoutTicks.get()) {
// only cancel if the total time has exceeded the initial estimate
@@ -371,58 +378,50 @@ public class PathExecutor implements IPathExecutor, Helper {
return true;
}
private void sprintIfRequested() {
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
if (!new CalculationContext(behavior.baritone).canSprint) {
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
ctx.player().setSprinting(false);
return;
}
// if the movement requested sprinting, then we're done
if (behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT)) {
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
if (!ctx.player().isSprinting()) {
ctx.player().setSprinting(true);
}
return;
}
private boolean shouldSprintNextTick() {
boolean requested = behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT);
// we'll take it from here, no need for minecraft to see we're holding down control and sprint for us
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false);
// first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint
if (!new CalculationContext(behavior.baritone).canSprint) {
return false;
}
// if the movement requested sprinting, then we're done
if (requested) {
return true;
}
// however, descend doesn't request sprinting, beceause it doesn't know the context of what movement comes after it
IMovement current = path.movements().get(pathPosition);
if (current instanceof MovementDescend && pathPosition < path.length() - 2) {
if (current instanceof MovementDescend) {
if (((MovementDescend) current).safeMode()) {
logDebug("Sprinting would be unsafe");
ctx.player().setSprinting(false);
return;
return false;
}
IMovement next = path.movements().get(pathPosition + 1);
if (next instanceof MovementAscend && current.getDirection().up().equals(next.getDirection().down())) {
// a descend then an ascend in the same direction
if (!ctx.player().isSprinting()) {
ctx.player().setSprinting(true);
}
pathPosition++;
// okay to skip clearKeys and / or onChangeInPathPosition here since this isn't possible to repeat, since it's asymmetric
logDebug("Skipping descend to straight ascend");
return;
}
if (canSprintInto(ctx, current, next)) {
if (ctx.playerFeet().equals(current.getDest())) {
if (pathPosition < path.length() - 2) {
IMovement next = path.movements().get(pathPosition + 1);
if (next instanceof MovementAscend && current.getDirection().up().equals(next.getDirection().down())) {
// a descend then an ascend in the same direction
pathPosition++;
onChangeInPathPosition();
// okay to skip clearKeys and / or onChangeInPathPosition here since this isn't possible to repeat, since it's asymmetric
logDebug("Skipping descend to straight ascend");
return true;
}
if (!ctx.player().isSprinting()) {
ctx.player().setSprinting(true);
if (canSprintInto(ctx, current, next)) {
if (ctx.playerFeet().equals(current.getDest())) {
pathPosition++;
onChangeInPathPosition();
onTick();
}
return true;
}
return;
//logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));
}
//logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));
}
if (current instanceof MovementAscend && pathPosition != 0) {
IMovement prev = path.movements().get(pathPosition - 1);
@@ -430,14 +429,11 @@ public class PathExecutor implements IPathExecutor, Helper {
BlockPos center = current.getSrc().up();
if (ctx.player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, false);
if (!ctx.player().isSprinting()) {
ctx.player().setSprinting(true);
}
return;
return true;
}
}
}
ctx.player().setSprinting(false);
return false;
}
private static boolean canSprintInto(IPlayerContext ctx, IMovement current, IMovement next) {
@@ -467,6 +463,7 @@ public class PathExecutor implements IPathExecutor, Helper {
failed = true;
}
@Override
public int getPosition() {
return pathPosition;
}
@@ -532,4 +529,8 @@ public class PathExecutor implements IPathExecutor, Helper {
public Set<BlockPos> toWalkInto() {
return Collections.unmodifiableSet(toWalkInto);
}
public boolean isSprinting() {
return sprintNextTick;
}
}

View File

@@ -18,10 +18,7 @@
package baritone.process;
import baritone.Baritone;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalGetToBlock;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.api.pathing.goals.*;
import baritone.api.process.IGetToBlockProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
@@ -44,6 +41,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
private Block gettingTo;
private List<BlockPos> knownLocations;
private BlockPos start;
private int tickCount = 0;
@@ -55,6 +53,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
public void getToBlock(Block block) {
onLostControl();
gettingTo = block;
start = ctx.playerFeet();
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
@@ -69,6 +68,14 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
if (knownLocations.isEmpty()) {
if (Baritone.settings().exploreForBlocks.get()) {
return new PathingCommand(new GoalRunAway(1, start) {
@Override
public boolean isInGoal(int x, int y, int z) {
return false;
}
}, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
}
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
if (isSafeToCancel) {
onLostControl();
@@ -106,6 +113,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
public void onLostControl() {
gettingTo = null;
knownLocations = null;
start = null;
baritone.getInputOverrideHandler().clearAllKeys();
}

View File

@@ -94,14 +94,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
if (Baritone.settings().legitMine.get()) {
addNearby();
}
Goal goal = updateGoal();
if (goal == null) {
PathingCommand command = updateGoal();
if (command == null) {
// none in range
// maybe say something in chat? (ahem impact)
cancel();
return null;
}
return new PathingCommand(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
return command;
}
@Override
@@ -114,17 +114,18 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return "Mine " + mining;
}
private Goal updateGoal() {
private PathingCommand updateGoal() {
boolean legit = Baritone.settings().legitMine.get();
List<BlockPos> locs = knownOreLocations;
if (!locs.isEmpty()) {
List<BlockPos> locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT);
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new));
knownOreLocations = locs2;
return goal;
return new PathingCommand(goal, legit ? PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType.REVALIDATE_GOAL_AND_PATH);
}
// we don't know any ore locations at the moment
if (!Baritone.settings().legitMine.get()) {
if (!legit) {
return null;
}
// only in non-Xray mode (aka legit mode) do we do this
@@ -149,7 +150,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
};
}
return branchPointRunaway;
return new PathingCommand(branchPointRunaway, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
}
private void rescan(List<BlockPos> already, CalculationContext context) {

View File

@@ -34,11 +34,6 @@ public abstract class BaritoneProcessHelper implements IBaritoneProcess, Helper
baritone.getPathingControlManager().registerProcess(this);
}
@Override
public Baritone associatedWith() {
return baritone;
}
@Override
public boolean isTemporary() {
return false;

View File

@@ -40,10 +40,9 @@ import net.minecraft.world.chunk.Chunk;
*/
public class BlockStateInterface {
public static int numBlockStateLookups = 0;
public static int numTimesChunkSucceeded = 0;
private final Long2ObjectMap<Chunk> loadedChunks;
private final WorldData worldData;
private Chunk prev = null;
private CachedRegion prevCached = null;
@@ -92,7 +91,7 @@ public class BlockStateInterface {
}
public IBlockState get0(int x, int y, int z) { // Mickey resigned
numBlockStateLookups++;
// Invalid vertical position
if (y < 0 || y >= 256) {
return AIR;
@@ -107,7 +106,6 @@ public class BlockStateInterface {
// which is a Long2ObjectOpenHashMap.get
// see issue #113
if (cached != null && cached.x == x >> 4 && cached.z == z >> 4) {
numTimesChunkSucceeded++;
return cached.getBlockState(x, y, z);
}
Chunk chunk = loadedChunks.get(ChunkPos.asLong(x >> 4, z >> 4));

View File

@@ -24,6 +24,7 @@ import baritone.api.cache.IWaypoint;
import baritone.api.event.events.ChatEvent;
import baritone.api.pathing.goals.*;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import baritone.behavior.Behavior;
import baritone.behavior.PathingBehavior;
@@ -35,6 +36,7 @@ import baritone.pathing.movement.Moves;
import baritone.process.CustomGoalProcess;
import baritone.utils.pathing.SegmentedCalculator;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
@@ -77,28 +79,33 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
"costs - (debug) all movement costs from current location\n" +
"damn - Daniel ";
private static final String COMMAND_PREFIX = "#";
public ExampleBaritoneControl(Baritone baritone) {
super(baritone);
}
@Override
public void onSendChatMessage(ChatEvent event) {
if (!Baritone.settings().chatControl.get() && !Baritone.settings().removePrefix.get()) {
return;
}
String msg = event.getMessage();
if (Baritone.settings().prefix.get()) {
if (!msg.startsWith("#")) {
if (Baritone.settings().prefixControl.get()) {
if (msg.startsWith(COMMAND_PREFIX)) {
if (!runCommand(msg.substring(COMMAND_PREFIX.length()))) {
logDirect("Invalid command");
}
event.cancel(); // always cancel if using prefixControl
return;
}
msg = msg.substring(1);
}
if (!Baritone.settings().chatControl.get() && !Baritone.settings().removePrefix.get()) {
return;
}
if (runCommand(msg)) {
event.cancel();
}
}
public boolean runCommand(String msg0) {
public boolean runCommand(String msg0) { // you may think this can be private, but impcat calls it from .b =)
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
@@ -121,7 +128,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
for (String line : HELP_MSG.split("\n")) {
logDirect(line);
}
return false;
return true;
}
if (msg.contains(" ")) {
String[] data = msg.split(" ");
@@ -284,6 +291,12 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Baritone settings reset");
return true;
}
if (msg.equals("render")) {
BetterBlockPos pf = ctx.playerFeet();
Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500);
logDirect("okay");
return true;
}
if (msg.equals("echest")) {
Optional<List<ItemStack>> contents = baritone.getMemoryBehavior().echest();
if (contents.isPresent()) {

View File

@@ -216,8 +216,9 @@ public final class PathRenderer implements Helper {
double renderPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double) partialTicks;
double renderPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) partialTicks;
double renderPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) partialTicks;
BlockStateInterface bsi = new BlockStateInterface(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext()); // TODO this assumes same dimension between primary baritone and render view? is this safe?
positions.forEach(pos -> {
IBlockState state = BlockStateInterface.get(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext(), pos);
IBlockState state = bsi.get0(pos);
AxisAlignedBB toDraw;
if (state.getBlock().equals(Blocks.AIR)) {
toDraw = Blocks.DIRT.getDefaultState().getSelectedBoundingBox(player.world, pos);

View File

@@ -135,6 +135,7 @@ public class ToolSet {
* Calculates how long would it take to mine the specified block given the best tool
* in this toolset is used. A negative value is returned if the specified block is unbreakable.
*
* @param item the item to mine it with
* @param state the blockstate to be mined
* @return how long it would take in ticks
*/

View File

@@ -17,6 +17,7 @@
package baritone.utils.pathing;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
@@ -27,6 +28,9 @@ import net.minecraft.util.math.BlockPos;
public abstract class PathBase implements IPath {
@Override
public PathBase cutoffAtLoadedChunks(Object bsi0) { // <-- cursed cursed cursed
if (!Baritone.settings().cutoffAtLoadBoundary.get()) {
return this;
}
BlockStateInterface bsi = (BlockStateInterface) bsi0;
for (int i = 0; i < positions().size(); i++) {
BlockPos pos = positions().get(i);

View File

@@ -27,7 +27,7 @@ import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
/**
* Implementation of {@link IPlayerContext} that provides information about the local player.
* Implementation of {@link IPlayerContext} that provides information about the primary player.
*
* @author Brady
* @since 11/12/2018

View File

@@ -27,6 +27,8 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.GameType;
/**
* Implementation of {@link IPlayerController} that chains to the primary player controller's methods
*
* @author Brady
* @since 12/14/2018
*/