Compare commits

..

33 Commits

Author SHA1 Message Date
Leijurv
9ce574266f Merge branch 'master' into benchmark 2019-01-17 12:24:23 -08:00
Leijurv
dcb93dab50 Merge branch 'master' into benchmark 2018-11-23 13:42:20 -08:00
Leijurv
f8c0b4c1c1 Merge branch 'master' into benchmark 2018-11-13 13:30:51 -08:00
Leijurv
c41f65d4f6 clean up benchmark branch 2018-09-27 11:38:32 -07:00
Leijurv
54811fb643 merge 2018-09-27 10:22:37 -07:00
Leijurv
92442dcdb9 total accounted time 2018-09-26 13:58:11 -07:00
Leijurv
68af1f3bb3 Merge branch 'master' into benchmark 2018-09-26 13:46:29 -07:00
Leijurv
a796e9c047 merge 2018-09-26 13:45:00 -07:00
Leijurv
2c32cadf18 count BetterBlockPos 2018-09-22 08:55:46 -07:00
Leijurv
32cd519bcf merge 2018-09-22 08:51:03 -07:00
Leijurv
88908d8776 more better block pos 2018-09-22 08:47:02 -07:00
Leijurv
79bd26968a count betterblockpos instantiation 2018-09-21 22:10:25 -07:00
Leijurv
2d288c7a47 Merge branch 'master' into benchmark 2018-09-21 21:58:26 -07:00
Leijurv
2c46458bc1 merge 2018-09-11 13:57:01 -07:00
Brady
9c37414e50 Merge branch 'master' into benchmark 2018-09-07 19:31:01 -05:00
Leijurv
fb667c3b4d merge 2018-09-04 15:41:35 -07:00
Leijurv
da07b63e0a measure 2018-08-31 12:57:38 -07:00
Leijurv
1fe262929e forgot print 2018-08-31 12:04:55 -07:00
Leijurv
0ee93aea23 cache chunk in BlockStateInterface 2018-08-31 11:51:43 -07:00
Leijurv
836b41a3aa num lookups check 2018-08-31 11:51:08 -07:00
Leijurv
c370461a24 merge 2018-08-31 11:45:45 -07:00
Leijurv
a753fe5df9 bench the whole loop 2018-08-29 14:46:58 -07:00
Leijurv
27aeba3f8b Merge branch 'master' into benchmark 2018-08-29 14:16:32 -07:00
Leijurv
141a9f92cb node map performance, fixes #107 2018-08-29 13:21:54 -07:00
Leijurv
5e4f0b47c5 merge 2018-08-29 12:24:45 -07:00
leijurv
d0a88987a8 format 2018-08-29 07:38:35 -07:00
leijurv
9cb199d40a also bench getnode 2018-08-28 21:31:16 -07:00
leijurv
a1d218b37a merge 2018-08-28 21:17:12 -07:00
leijurv
7ae1a9f6e4 3x faster cache check 2018-08-28 21:14:50 -07:00
leijurv
fd74fcabc0 way more bench checks 2018-08-28 21:10:56 -07:00
leijurv
4da155c0ed 20% improvement to cached chunk check performance 2018-08-28 21:10:41 -07:00
leijurv
7a3f7f9a9e Merge branch 'master' into benchmark 2018-08-28 20:51:42 -07:00
Leijurv
1212d34f91 rudimentary benchmark 2018-08-28 15:48:36 -07:00
90 changed files with 1858 additions and 2797 deletions

View File

@@ -9,7 +9,6 @@ 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

@@ -4,14 +4,13 @@
- **Block breaking** Baritone considers breaking blocks as part of its path. It also takes into account your current tool set and hot bar. For example, if you have a Eff V diamond pick, it may choose to mine through a stone barrier, while if you only had a wood pick it might be faster to climb over it.
- **Block placing** Baritone considers placing blocks as part of its path. This includes sneak-back-placing, pillaring, etc. It has a configurable penalty of placing a block (set to 1 second by default), to conserve its resources. The list of acceptable throwaway blocks is also configurable, and is cobble, dirt, or netherrack by default. <a href="https://www.youtube.com/watch?v=F6FbI1L9UmU">Example</a>
- **Falling** Baritone will fall up to 3 blocks onto solid ground (configurable, if you have Feather Falling and/or don't mind taking a little damage). If you have a water bucket on your hotbar, it will fall up to 23 blocks and place the bucket beneath it. It will fall an unlimited distance into existing still water.
- **Vines and ladders** Baritone understands how to climb and descend vines and ladders. There is experimental support for more advanced maneuvers, like strafing to a different ladder / vine column in midair (off by default, setting named `allowVines`). Baritone can break its fall by grabbing ladders / vines midair, and understands when that is and isn't possible.
- **Vines and ladders** Baritone understands how to climb and descend vines and ladders. There is experimental support for more advanced maneuvers, like strafing to a different ladder / vine column in midair (off by default, setting named `allowVines`).
- **Opening fence gates and doors**
- **Slabs and stairs**
- **Falling blocks** Baritone understands the costs of breaking blocks with falling blocks on top, and includes all of their break costs. Additionally, since it avoids breaking any blocks touching a liquid, it won't break the bottom of a gravel stack below a lava lake (anymore).
- **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:
@@ -22,9 +21,9 @@ Baritone uses A*, with some modifications:
- **Backtrack cost favoring** While calculating the next segment, Baritone favors backtracking its current segment. The cost is decreased heavily, but is still positive (this won't cause it to backtrack if it doesn't need to). This allows it to splice and jump onto the next segment as early as possible, if the next segment begins with a backtrack of the current one. <a href="https://www.youtube.com/watch?v=CGiMcb8-99Y">Example</a>
- **Backtrack detection and pausing** While path calculation happens on a separate thread, the main game thread has access to the latest node considered, and the best path so far (those are rendered light blue and dark blue respectively). When the current best path (rendered dark blue) passes through the player's current position on the current path segment, path execution is paused (if it's safe to do so), because there's no point continuing forward if we're about to turn around and go back that same way. Note that the current best path as reported by the path calculation thread takes into account the incremental cost backoff system, so it's accurate to what the path calculation thread will actually pick once it finishes.
# Chat control
- [Baritone chat control usage](USAGE.md)
# Configuring Baritone
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>.
To change a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `pathTimeoutMS 250`). It's case insensitive.
# Goals
The pathing goal can be set to any of these options:
@@ -47,6 +46,7 @@ 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

1
IMPACT.md Normal file
View File

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

96
INSTALL.md Normal file
View File

@@ -0,0 +1,96 @@
# Integration between Baritone and Impact
Impact 4.4 has Baritone included.
These instructions apply to Impact 4.3 (and potentially other hacked clients).
To run Baritone on Vanilla, just follow the instructions in the README (it's `./gradlew runClient`).
## An Introduction
There are some basic steps to getting Baritone setup with Impact.
- Acquiring a build of Baritone
- Placing Baritone in the libraries directory
- Modifying the Impact Profile JSON to run baritone
- How to use Baritone
## Acquiring a build of Baritone
There are two methods of acquiring a build of Baritone
### Official Release (Not always up to date)
https://github.com/cabaletta/baritone/releases
For Impact 4.3, there is no Baritone integration yet, so you will want `baritone-standalone-X.Y.Z.jar`.
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone . && docker run --rm cabaletta/baritone cat /code/dist/checksums.txt` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
### Building Baritone yourself
There are a few steps to this
- Clone this repository
- Setup the project as instructed in the README
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
command line
- Windows: ``gradlew build``
- Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
that contains all of the dependencies that are required from the game and some mods. This is where we will be
putting baritone.
- Locate the ``libraries`` folder, it should be in the Minecraft Installation Directory
- Create 3 new subdirectories starting from ``libraries``
- ``cabaletta``
- ``baritone``
- ``X.Y.Z``
- Copy the build of Baritone that was acquired earlier, and place it into the ``X.Y.Z`` folder
- The full path should look like ``<Minecraft>/libraries/cabaletta/baritone/X.Y.Z/baritone-X.Y.Z.jar``
## Modifying the Impact Profile JSON to run baritone
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
- Ensure your Minecraft launcher is closed
- Navigate back to the Minecraft Installation Directory
- Find the ``versions`` directory, and open in
- In here there should be a ``1.12.2-Impact_4.3`` folder.
- If you don't have any Impact folder or have a version older than 4.3, you can download Impact <a href="https://impactdevelopment.github.io">here</a>.
- Open the folder and inside there should be a file called ``1.12.2-Impact_4.3.json``
- Open the JSON file with a text editor that supports your system's line endings
- For example, Notepad on Windows likely will NOT work for this. You should instead use a Text Editor like
<a href="https://notepad-plus-plus.org/">Notepad++</a> if you're on Windows. (For other systems, I'm not sure
what would work the best so you may have to do some research.)
- Find the ``libraries`` array in the JSON. It should look something like this.
```
"libraries": [
{
"name": "net.minecraft:launchwrapper:1.12"
},
{
"name": "com.github.ImpactDevelopment:Impact:4.3-1.12.2",
"url": "https://impactdevelopment.github.io/maven/"
},
{
"name": "com.github.ImpactDeveloment:ClientAPI:3.0.2",
"url": "https://impactdevelopment.github.io/maven/"
},
...
```
- Create two new objects in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
```
{
"name": "cabaletta:baritone:X.Y.Z"
},
{
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.2",
"url": "https://impactdevelopment.github.io/maven/"
},
```
- Now find the ``"minecraftArguments": "..."`` text near the top.
- At the very end of the quotes where it says ``--tweakClass clientapi.load.ClientTweaker"``, add on the following so it looks like:
- ``--tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine"``
- If you didn't close your launcher for this step, restart it now.
- You can now launch Impact 4.3 as normal, and Baritone should start up
## How to use Baritone
Instructions on how to use Baritone are limited, and you may have to read a little bit of code (Really nothing much
just plain English), you can view that <a href="https://github.com/cabaletta/baritone#chat-control">here</a>.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -1,64 +1,65 @@
# Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases)
[![License](https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg)](LICENSE)
[![License](https://img.shields.io/badge/license-LGPL--3.0-green.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
[![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)
![](https://tokei.rs/b1/github/cabaletta/baritone?category=code)
![](https://tokei.rs/b1/github/cabaletta/baritone?category=files)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
[![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/)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.0.0--hotfix--4-brightgreen.svg)](https://impactdevelopment.github.io/)
[![KAMI integration](https://img.shields.io/badge/KAMI%20integration-v1.0.0-orange.svg)](https://github.com/zeroeightysix/KAMI/)
[![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)
[![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/)
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 [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 🦀
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
# Getting Started
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Here are some links to help to get started:
- [Features](FEATURES.md)
- [Installation & setup](SETUP.md)
- [Installation](INSTALL.md)
- [API Javadocs](https://baritone.leijurv.com/)
# Setup
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
- [Baritone chat control usage](USAGE.md)
Running Baritone:
# API
```
$ gradlew runClient
```
The API is heavily documented, you can find the Javadocs for the latest release [here](https://baritone.leijurv.com/).
Please note that usage of anything located outside of the ``baritone.api`` package is not supported by the API release
jar.
Building Baritone:
```
$ gradlew build
```
Below is an example of basic usage for changing some settings, and then pathing to a X/Z goal.
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:`.
# Chat control
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actually start pathing. Also try `mine diamond_ore`. `cancel` to cancel.
# API example
```
BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
```
@@ -67,7 +68,7 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd
## Can I use Baritone as a library in my custom utility client?
That's what it's for, sure! (As long as usage is in compliance with the LGPL 3 License)
Sure! (As long as usage is in compliance with the LGPL 3 License)
## How is it so fast?

View File

@@ -1,98 +0,0 @@
# Installation
## Prebuilt official releases
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `builder` branch for example, you'll have to build it yourself)
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone .` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
## Artifacts
Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
**The Forge release can simply be added as a Forge mod.**
If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar`
- **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features.
- **Forge API**: Same as API, but packaged for Forge. This should be used where another mod has a Baritone integration.
- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features.
- **Forge Standalone**: Same as Standalone, but packaged for Forge. This should be used when Baritone is your only Forge mod, or none of your other Forge mods integrate with Baritone.
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production.
## More Info
To replace out Impact 4.5's Baritone build with a customized one, build Baritone as above then copy `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.2/baritone-api-1.2.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.5/1.12.2-Impact_4.5.json`, find the line `"name": "cabaletta:baritone-api:1.2"`, remove the comma from the end, and **entirely remove the next line** (starts with `"url"`).
You can verify whether or not it worked by running `.b version` in chat (only valid in Impact). If it says `v1.2.0` then you didn't do it properly, and it's still running the version that came with 4.5.
## 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

View File

@@ -1,80 +0,0 @@
(assuming you already have Baritone [set up](SETUP.md))
# Prefix
Baritone commands can by default be typed in the chatbox. However if you make a typo, like typing "gola 10000 10000" instead of goal it goes into public chat, which is bad.
Therefore you can use a prefix before your messages.
On Baritone v1.1.0 and newer: The prefix is `#` by default. Anything beginning with `#` isn't sent, and is only interpreted by Baritone.
For older than v1.1.0, `#` must be enabled by toggling on the `prefix` setting.
**Only** in Impact is `.b` also a valid prefix. In 4.4, `#` does **not** work, neither does saying the commands directly in chat. `#` works by default in 4.5 (not 4.4).
Other clients like Kami and Asuna have their own custom things (like `-path`), and can disable direct chat control entirely.
# Commands
**All** of these commands may need a prefix before them, as above ^.
`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java#L53).
To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`.
Some common examples:
- `thisway 1000` then `path` to go in the direction you're facing for a thousand blocks
- `goal x y z` or `goal x z` or `goal y`, then `path` to go to a certain coordinate
- `goal` to set the goal to your player's feet
- `goal clear` to clear the goal
- `cancel` or `stop` to stop everything
- `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part)
- `mine diamond_ore` to mine diamond ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.)
- `follow playerName` to follow a player. `follow` to follow the entity you're looking at (only works if it hitting range). `followplayers` to follow any players in range (combine with Kill Aura for a fun time).
- `save waypointName` to save a waypoint. `goto waypointName` to go to it.
- `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120).
- `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start.
- `render` to rerender the world in case `renderCachedChunks` is being glitchy
- `version` to get the version of Baritone you're running
- `damn` daniel
For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/main/java/baritone/utils/ExampleBaritoneControl.java).
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>. If you find HTML easier to read than Javadoc, you can look <a href="https://baritone.leijurv.com/baritone/api/Settings.html#field.detail">here</a>.
There are about a hundred settings, but here are some fun / interesting / important ones that you might want to look at changing in normal usage of Baritone. The documentation for each can be found at the above links.
- `allowBreak`
- `allowSprint`
- `allowPlace`
- `allowParkour`
- `allowParkourPlace`
- `renderCachedChunks` (and `cachedChunksOpacity`) <-- very fun but you need a beefy computer
- `avoidance`
- `legitMine`
- `followRadius`
# Troubleshooting / common issues
## Baritone highlights a block in green but gets completely stuck? Also I'm using Baritone with Future?
Baritone is trying to right click to place a block there, but it can't since there's a conflicting mixin. Baritone can't force click right click when Future is also installed. Left click **does work** on recent Baritone even with Future, however. For now, turn off `allowPlace` and Baritone will only search for paths that don't require placing blocks to complete. `allowBreak` can remain on.
## Why doesn't Baritone respond to any of my chat commands?
This could be one of many things.
First, make sure it's actually installed. An easy way to check is seeing if it created the folder `baritone` in your Minecraft folder.
Second, make sure that you're using the prefix properly, and that chat control is enabled in the way you expect.
For example, Impact disables direct chat control. (i.e. anything typed in chat without a prefix will be ignored and sent publicly). **This is a saved setting**, so if you run Impact once, `chatControl` will be off from then on, **even in other clients**.
So you'll need to use the `#` prefix or edit `baritone/settings.txt` in your Minecraft folder to undo that (specifically, remove the line `chatControl false` then restart your client).
## Why can I do `.goto x z` in Impact but nowhere else? Why can I do `-path to x z` in KAMI but nowhere else?
These are custom commands that they added; those aren't from Baritone.
The equivalent you're looking for is `goal x z` then `path`.

View File

@@ -1,132 +1,119 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
group 'baritone'
version '1.2.2'
buildscript {
repositories {
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
}
maven {
name = 'SpongePowered'
url = 'http://repo.spongepowered.org/maven'
}
jcenter()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
}
}
import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
apply plugin: 'java'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = '1.8'
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
options.encoding = "UTF-8" // allow emoji in comments :^)
}
sourceSets {
launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
}
minecraft {
version = '1.12.2'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
}
repositories {
mavenCentral()
maven {
name = 'spongepowered-repo'
url = 'http://repo.spongepowered.org/maven/'
}
maven {
name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/'
}
}
dependencies {
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
testImplementation 'junit:junit:4.12'
}
mixin {
defaultObfuscationEnv searge
add sourceSets.launch, 'mixins.baritone.refmap.json'
}
javadoc {
options.addStringOption('Xwerror', '-quiet') // makes the build fail on travis when there is a javadoc error
options.linkSource true
options.encoding "UTF-8" // allow emoji in comments :^)
source = sourceSets.api.allJava
classpath += sourceSets.api.compileClasspath
}
jar {
from sourceSets.launch.output, sourceSets.api.output
preserveFileTimestamps = false
reproducibleFileOrder = true
manifest {
attributes(
'MixinConfigs': 'mixins.baritone.json',
'Implementation-Title': 'Baritone',
'Implementation-Version': version
)
}
}
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'
}
task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist)
/*
* 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/>.
*/
group 'baritone'
version '1.0.0-hotfix-2'
buildscript {
repositories {
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
}
maven {
name = 'SpongePowered'
url = 'http://repo.spongepowered.org/maven'
}
jcenter()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
}
}
import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
apply plugin: 'java'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = '1.8'
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
}
sourceSets {
launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
}
minecraft {
version = '1.12.2'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
}
repositories {
mavenCentral()
maven {
name = 'spongepowered-repo'
url = 'http://repo.spongepowered.org/maven/'
}
maven {
name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/'
}
}
dependencies {
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
testImplementation 'junit:junit:4.12'
}
mixin {
defaultObfuscationEnv notch
add sourceSets.launch, 'mixins.baritone.refmap.json'
}
javadoc {
source = sourceSets.api.allJava
classpath = sourceSets.api.compileClasspath
}
jar {
from sourceSets.launch.output, sourceSets.api.output
preserveFileTimestamps = false
reproducibleFileOrder = true
}
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'
}
task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist)

View File

@@ -17,6 +17,8 @@
package baritone.gradle.task;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.gradle.api.DefaultTask;
import java.io.File;
@@ -24,6 +26,7 @@ import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
/**
* @author Brady
@@ -31,6 +34,8 @@ import java.nio.file.Paths;
*/
class BaritoneGradleTask extends DefaultTask {
protected static final JsonParser PARSER = new JsonParser();
protected static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
@@ -40,28 +45,26 @@ class BaritoneGradleTask extends DefaultTask {
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar",
VERSION_MANIFEST = "version_manifest.json",
TEMP_LIBRARY_DIR = "tempLibraries/",
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
protected String artifactName, artifactVersion;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, proguardOut;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
protected void verifyArtifacts() throws IllegalStateException {
this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString();
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
@@ -92,4 +95,8 @@ class BaritoneGradleTask extends DefaultTask {
protected Path getBuildFile(String file) {
return getRelativeFile("build/libs/" + file);
}
protected JsonElement readJson(List<String> lines) {
return PARSER.parse(String.join("\n", lines));
}
}

View File

@@ -42,11 +42,9 @@ public class CreateDistTask extends BaritoneGradleTask {
super.verifyArtifacts();
// Define the distribution file paths
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
Path forgeApi = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_API));
Path forgeStandalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_STANDALONE));
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
// NIO will not automatically create directories
Path dir = getRelativeFile("dist/");
@@ -55,14 +53,12 @@ public class CreateDistTask extends BaritoneGradleTask {
}
// Copy build jars to dist/
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
Files.copy(this.artifactForgeApiPath, forgeApi, REPLACE_EXISTING);
Files.copy(this.artifactForgeStandalonePath, forgeStandalone, REPLACE_EXISTING);
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
// Calculate all checksums and format them like "shasum"
List<String> shasum = Stream.of(api, forgeApi, standalone, forgeStandalone, unoptimized)
List<String> shasum = Stream.of(api, standalone, unoptimized)
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());

View File

@@ -59,8 +59,6 @@ public class ProguardTask extends BaritoneGradleTask {
private List<String> requiredLibraries;
private File mixin;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
@@ -81,7 +79,7 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
}
private void downloadProguard() throws Exception {
@@ -175,16 +173,10 @@ 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
@@ -272,14 +264,12 @@ public class ProguardTask extends BaritoneGradleTask {
private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
}
private void cleanup() {
@@ -308,8 +298,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(), System.out);
this.printOutputLog(p.getErrorStream(), System.err);
this.printOutputLog(p.getInputStream());
this.printOutputLog(p.getErrorStream());
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor();
@@ -318,12 +308,12 @@ public class ProguardTask extends BaritoneGradleTask {
}
}
private void printOutputLog(InputStream stream, PrintStream outerr) {
private void printOutputLog(InputStream stream) {
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line;
while ((line = reader.readLine()) != null) {
outerr.println(line);
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();

View File

@@ -22,7 +22,10 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -36,7 +39,7 @@ import java.util.stream.Collectors;
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
public static void determinize(String inputPath, String outputPath) throws IOException {
System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
@@ -63,30 +66,10 @@ public class Determinizer {
if (entry.getName().endsWith(".refmap.json")) {
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
jos.write(writeSorted(object).getBytes());
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
copy(jarFile.getInputStream(entry), cancer);
String manifest = new String(cancer.toByteArray());
if (!manifest.contains("baritone.launch.BaritoneTweaker")) {
throw new IllegalStateException("unable to replace");
}
manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
jos.write(manifest.getBytes());
} else {
copy(jarFile.getInputStream(entry), jos);
}
}
if (toInclude.isPresent()) {
try (JarFile mixin = new JarFile(toInclude.get())) {
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
continue;
}
jos.putNextEntry(entry);
copy(mixin.getInputStream(entry), jos);
}
}
}
jos.finish();
}
}

View File

@@ -1,6 +1,6 @@
#Tue Jul 31 21:56:56 PDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
#Tue Jul 31 21:56:56 PDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip

168
gradlew.bat vendored
View File

@@ -1,84 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -12,15 +12,15 @@
-flattenpackagehierarchy
-repackageclasses 'baritone'
# lwjgl is weird
-dontwarn org.lwjgl.**
-keep class baritone.api.** { *; } # this is the keep api
# service provider needs these class names
-keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider
# hack
-keep class baritone.utils.ExampleBaritoneControl { *; } # have to include this string to remove this keep in the standalone build: # this is the keep api
# setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings {
public <fields>;

View File

@@ -1,19 +1,19 @@
/*
* 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/>.
*/
rootProject.name = 'baritone'
/*
* 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/>.
*/
rootProject.name = 'baritone'

View File

@@ -23,7 +23,9 @@ import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Exposes the {@link IBaritoneProvider} instance and the {@link Settings} instance for API usage.
* API exposure for various things implemented in Baritone.
* <p>
* W.I.P
*
* @author Brady
* @since 9/23/2018

View File

@@ -22,7 +22,10 @@ import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IWorldProvider;
import baritone.api.event.listener.IEventBus;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.*;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IFollowProcess;
import baritone.api.process.IGetToBlockProcess;
import baritone.api.process.IMineProcess;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.IPlayerContext;
@@ -33,19 +36,10 @@ import baritone.api.utils.IPlayerContext;
public interface IBaritone {
/**
* Call as soon as Minecraft is ready, initializes all of the processes, behaviors, etc. This will
* only effectively be ran once, any additional calls are redundant because the initialization state
* is saved.
* <p>
* Or whenever your overeager utility client wants.
* @return The {@link IFollowProcess} instance
* @see IFollowProcess
*/
void init();
/**
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior
*/
IPathingBehavior getPathingBehavior();
IFollowProcess getFollowProcess();
/**
* @return The {@link ILookBehavior} instance
@@ -53,12 +47,6 @@ public interface IBaritone {
*/
ILookBehavior getLookBehavior();
/**
* @return The {@link IFollowProcess} instance
* @see IFollowProcess
*/
IFollowProcess getFollowProcess();
/**
* @return The {@link IMineProcess} instance
* @see IMineProcess
@@ -66,16 +54,10 @@ public interface IBaritone {
IMineProcess getMineProcess();
/**
* @return The {@link ICustomGoalProcess} instance
* @see ICustomGoalProcess
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior
*/
ICustomGoalProcess getCustomGoalProcess();
/**
* @return The {@link IGetToBlockProcess} instance
* @see IGetToBlockProcess
*/
IGetToBlockProcess getGetToBlockProcess();
IPathingBehavior getPathingBehavior();
/**
* @return The {@link IWorldProvider} instance
@@ -83,30 +65,15 @@ public interface IBaritone {
*/
IWorldProvider getWorldProvider();
/**
* Returns the {@link IPathingControlManager} for this {@link IBaritone} instance, which is responsible
* for managing the {@link IBaritoneProcess}es which control the {@link IPathingBehavior} state.
*
* @return The {@link IPathingControlManager} instance
* @see IPathingControlManager
*/
IPathingControlManager getPathingControlManager();
/**
* @return The {@link IInputOverrideHandler} instance
* @see IInputOverrideHandler
*/
IInputOverrideHandler getInputOverrideHandler();
/**
* @return The {@link IPlayerContext} instance
* @see IPlayerContext
*/
ICustomGoalProcess getCustomGoalProcess();
IGetToBlockProcess getGetToBlockProcess();
IPlayerContext getPlayerContext();
/**
* @return The {@link IEventBus} instance
* @see IEventBus
*/
IEventBus getGameEventHandler();
}

View File

@@ -23,9 +23,7 @@ import net.minecraft.client.entity.EntityPlayerSP;
import java.util.List;
/**
* Provides the present {@link IBaritone} instances
*
* @author leijurv
* @author Leijurv
*/
public interface IBaritoneProvider {
@@ -49,8 +47,7 @@ public interface IBaritoneProvider {
/**
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
* replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when
* {@code bot-system} is merged into {@code master}.
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
*
* @param player The player
* @return The {@link IBaritone} instance.
@@ -61,7 +58,7 @@ public interface IBaritoneProvider {
return baritone;
}
}
return null;
throw new IllegalStateException("No baritone for player " + player);
}
/**

View File

@@ -17,7 +17,6 @@
package baritone.api;
import baritone.api.utils.SettingsUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
@@ -30,71 +29,71 @@ import java.util.List;
import java.util.function.Consumer;
/**
* Baritone's settings. Settings apply to all Baritone instances.
* Baritone's settings
*
* @author leijurv
*/
public final class Settings {
public class Settings {
/**
* Allow Baritone to break blocks
*/
public final Setting<Boolean> allowBreak = new Setting<>(true);
public Setting<Boolean> allowBreak = new Setting<>(true);
/**
* Allow Baritone to sprint
*/
public final Setting<Boolean> allowSprint = new Setting<>(true);
public Setting<Boolean> allowSprint = new Setting<>(true);
/**
* Allow Baritone to place blocks
*/
public final Setting<Boolean> allowPlace = new Setting<>(true);
public Setting<Boolean> allowPlace = new Setting<>(true);
/**
* Allow Baritone to move items in your inventory to your hotbar
*/
public final Setting<Boolean> allowInventory = new Setting<>(false);
public 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 final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
public 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 final Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
public Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
/**
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) because it uses hunger
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) beacuse it uses hunger
*/
public final Setting<Double> jumpPenalty = new Setting<>(2D);
public Setting<Double> jumpPenalty = new Setting<>(2D);
/**
* Walking on water uses up hunger really quick, so penalize it
*/
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
public Setting<Double> walkOnWaterOnePenalty = new Setting<>(5D);
/**
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
* Reliability: questionable.
*/
public final Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
public 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 final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
public Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
/**
* Assume step functionality; don't jump on an Ascend.
*/
public final Setting<Boolean> assumeStep = new Setting<>(false);
public Setting<Boolean> assumeStep = new Setting<>(false);
/**
* Assume safe walk functionality; don't sneak on a backplace traverse.
@@ -103,14 +102,14 @@ public final 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 final Setting<Boolean> assumeSafeWalk = new Setting<>(false);
public 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 constantiam
* Defaults to false because this fails on NCP
*/
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
public Setting<Boolean> allowJumpAt256 = new Setting<>(false);
/**
* Allow descending diagonally
@@ -119,12 +118,12 @@ public final class Settings {
* <p>
* For a generic "take some risks" mode I'd turn on this one, parkour, and parkour place.
*/
public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
public Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
/**
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
*/
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
public Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
Item.getItemFromBlock(Blocks.DIRT),
Item.getItemFromBlock(Blocks.COBBLESTONE),
Item.getItemFromBlock(Blocks.NETHERRACK)
@@ -133,47 +132,31 @@ public final 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 final Setting<Boolean> allowVines = new Setting<>(false);
public 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 final Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
public 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 final Setting<Boolean> allowParkour = new Setting<>(false);
public Setting<Boolean> allowParkour = new Setting<>(false);
/**
* Actually pretty reliable.
* <p>
* Doesn't make it any more dangerous compared to just normal allowParkour th
* Like parkour, but even more unreliable!
*/
public final Setting<Boolean> allowParkourPlace = new Setting<>(false);
public Setting<Boolean> allowParkourPlace = new Setting<>(false);
/**
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
*/
public final Setting<Boolean> considerPotionEffects = new Setting<>(true);
/**
* Sprint and jump a block early on ascends wherever possible
*/
public final Setting<Boolean> sprintAscends = new Setting<>(true);
/**
* How many ticks between right clicks are allowed. Default in game is 4
*/
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
public Setting<Boolean> considerPotionEffects = new Setting<>(true);
/**
* This is the big A* setting.
@@ -190,139 +173,131 @@ public final class Settings {
* <p>
* Finding the optimal path is worth it, so it's the default.
*/
public final Setting<Double> costHeuristic = new Setting<>(3.563);
public 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 final Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
public 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 final Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
/**
* Toggle the following 4 settings
* <p>
* 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
* They have a noticable performance impact, so they default off
*/
public final Setting<Boolean> avoidance = new Setting<>(false);
public 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 final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
public Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
public 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 final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
public Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
public 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 final Setting<Boolean> rightClickContainerOnArrival = new Setting<>(true);
public 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 final Setting<Boolean> enterPortal = new Setting<>(true);
public 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 final Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
public 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/114">Issue #114</a>
* @see <a href="https://github.com/cabaletta/baritone/issues/144">Issue #144</a>
*/
public final Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
public 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 final Setting<Double> maxCostIncrease = new Setting<>(10D);
public 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 final Setting<Integer> costVerificationLookahead = new Setting<>(5);
public 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 final Setting<Double> pathCutoffFactor = new Setting<>(0.9);
public 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 final Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
public 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 final Setting<Integer> planningTickLookahead = new Setting<>(150);
public Setting<Integer> planningTickLookAhead = new Setting<>(150);
/**
* Default size of the Long2ObjectOpenHashMap used in pathing
*/
public final Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
public 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 final Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
public 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 final Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
public 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 final Setting<Integer> maxFallHeightBucket = new Setting<>(20);
public 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.
* <p>
* Note: this is *not* related to the allowDiagonalDescend setting, that is a completely different thing.
*/
public final Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
public 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
@@ -331,140 +306,131 @@ public final 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 final Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
public Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
/**
* If a movement takes this many ticks more than its initial cost estimate, cancel it
*/
public final Setting<Integer> movementTimeoutTicks = new Setting<>(100);
public 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 final Setting<Long> primaryTimeoutMS = new Setting<>(500L);
public 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 final Setting<Long> failureTimeoutMS = new Setting<>(2000L);
public 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 final Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
public 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 final Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
public Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
/**
* For debugging, consider nodes much much slower
*/
public final Setting<Boolean> slowPath = new Setting<>(false);
public Setting<Boolean> slowPath = new Setting<>(false);
/**
* Milliseconds between each node
*/
public final Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
public Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
/**
* The alternative timeout number when slowPath is on
*/
public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
public 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 final Setting<Boolean> chunkCaching = new Setting<>(true);
public 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 <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
* Temporarily disabled, see issue #248
*/
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
/**
* Remember the contents of containers (chests, echests, furnaces)
* <p>
* Really buggy since the packet stuff is multithreaded badly thanks to brady
*/
public final Setting<Boolean> containerMemory = new Setting<>(false);
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
/**
* Print all the debug messages to chat
*/
public final Setting<Boolean> chatDebug = new Setting<>(false);
public 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 final Setting<Boolean> chatControl = new Setting<>(true);
public Setting<Boolean> chatControl = new Setting<>(true);
/**
* A second override over chatControl to force it on
*/
public final Setting<Boolean> removePrefix = new Setting<>(false);
public Setting<Boolean> removePrefix = new Setting<>(false);
/**
* Render the path
*/
public final Setting<Boolean> renderPath = new Setting<>(true);
public Setting<Boolean> renderPath = new Setting<>(true);
/**
* Render the goal
*/
public final Setting<Boolean> renderGoal = new Setting<>(true);
public Setting<Boolean> renderGoal = new Setting<>(true);
/**
* Ignore depth when rendering the goal
*/
public final Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
public 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 final Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
public Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
/**
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
*/
public final Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
/**
* Ignore depth when rendering the path
*/
public final Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
/**
* Line width of the path when rendered, in pixels
*/
public final Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
public Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
/**
* Line width of the goal when rendered, in pixels
*/
public final Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
public 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 final Setting<Boolean> fadePath = new Setting<>(false);
public Setting<Boolean> fadePath = new Setting<>(false);
/**
* Move without having to force the client-sided rotations
*/
public final Setting<Boolean> freeLook = new Setting<>(true);
public Setting<Boolean> freeLook = new Setting<>(true);
/**
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
@@ -472,78 +438,48 @@ public final 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 final Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
public Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
/**
* Exclusively use cached chunks for pathing
*/
public final Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
/**
* Continue sprinting while in water
*/
public final Setting<Boolean> sprintInWater = new Setting<>(true);
/**
* When GetToBlockProcess fails to calculate a path, instead of just giving up, mark the closest instances
* of that block as "unreachable" and go towards the next closest
*/
public final Setting<Boolean> blacklistOnGetToBlockFailure = new Setting<>(true);
/**
* 😎 Render cached chunks as semitransparent. Doesn't work with OptiFine 😭 Rarely randomly crashes, see <a href="https://github.com/cabaletta/baritone/issues/327">this issue</a>.
* <p>
* Can be very useful on servers with low render distance. After enabling, you may need to reload the world in order for it to have an effect
* (e.g. disconnect and reconnect, enter then exit the nether, die and respawn, etc). This may literally kill your FPS and CPU because
* every chunk gets recompiled twice as much as normal, since the cached version comes into range, then the normal one comes from the server for real.
* <p>
* Note that flowing water is cached as AVOID, which is rendered as lava. As you get closer, you may therefore see lava falls being replaced with water falls.
* <p>
* SOLID is rendered as stone in the overworld, netherrack in the nether, and end stone in the end
*/
public final Setting<Boolean> renderCachedChunks = new Setting<>(false);
/**
* 0.0f = not visible, fully transparent
* 1.0f = fully opaque
*/
public final Setting<Float> cachedChunksOpacity = new Setting<>(0.5f);
public Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
/**
* Whether or not to use the "#" command prefix
*/
public final Setting<Boolean> prefixControl = new Setting<>(true);
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);
/**
* Don't stop walking forward when you need to break blocks in your way
*/
public final Setting<Boolean> walkWhileBreaking = new Setting<>(true);
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
/**
* If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
*/
public final Setting<Integer> maxPathHistoryLength = new Setting<>(300);
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
/**
* If the current path is too long, cut off this many movements from the beginning.
*/
public final Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
/**
* Rescan for the goal once every 5 ticks.
* Set to 0 to disable.
*/
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);
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
/**
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
*/
public final Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
/**
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
@@ -558,67 +494,54 @@ public final 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 final Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
/**
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
*/
public final Setting<Integer> axisHeight = new Setting<>(120);
public Setting<Integer> axisHeight = new Setting<>(120);
/**
* Disallow MineBehavior from using X-Ray to see where the ores are. Turn this option on to force it to mine "legit"
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
* couldn't. If you don't want it to look like you're X-Raying, turn this on
* couldn't. If you don't want it to look like you're X-Raying, turn this off
*/
public final Setting<Boolean> legitMine = new Setting<>(false);
public Setting<Boolean> legitMine = new Setting<>(false);
/**
* What Y level to go to for legit strip mining
*/
public final Setting<Integer> legitMineYLevel = new Setting<>(11);
/**
* Magically see ores that are separated diagonally from existing ores. Basically like mining around the ores that it finds
* in case there's one there touching it diagonally, except it checks it un-legit-ly without having the mine blocks to see it.
* You can decide whether this looks plausible or not.
* <p>
* This is disabled because it results in some weird behavior. For example, it can """see""" the top block of a vein of iron_ore
* through a lava lake. This isn't an issue normally since it won't consider anything touching lava, so it just ignores it.
* However, this setting expands that and allows it to see the entire vein so it'll mine under the lava lake to get the iron that
* it can reach without mining blocks adjacent to lava. This really defeats the purpose of legitMine since a player could never
* do that lol, so thats one reason why its disabled
*/
public final Setting<Boolean> legitMineIncludeDiagonals = new Setting<>(false);
public Setting<Integer> legitMineYLevel = new Setting<>(11);
/**
* When mining block of a certain type, try to mine two at once instead of one.
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
* If the block below is also a goal block, set GoalBlock to the position one down instead of GoalTwoBlocks
*/
public final Setting<Boolean> forceInternalMining = new Setting<>(true);
public 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 final Setting<Boolean> internalMiningAirException = new Setting<>(true);
public 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 final Setting<Double> followOffsetDistance = new Setting<>(0D);
public Setting<Double> followOffsetDistance = new Setting<>(0D);
/**
* The actual GoalNear is set in this direction from the entity you're following. This value is in degrees.
* The actual GoalNear is set in this direction from the entity you're following
*/
public final Setting<Float> followOffsetDirection = new Setting<>(0F);
public Setting<Float> followOffsetDirection = new Setting<>(0F);
/**
* The radius (for the GoalNear) of how close to your target position you actually have to be
*/
public final Setting<Integer> followRadius = new Setting<>(3);
public 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
@@ -640,55 +563,54 @@ public final 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 final Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
public 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 final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
public Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
/**
* The color of the current path
*/
public final Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
public Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
/**
* The color of the next path
*/
public final Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
public Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
/**
* The color of the blocks to break
*/
public final Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
public Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
/**
* The color of the blocks to place
*/
public final Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
public Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
/**
* The color of the blocks to walk into
*/
public final Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
public Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
/**
* The color of the best path so far
*/
public final Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
public Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
/**
* The color of the path to the most recent considered node
*/
public final Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
public Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
/**
* The color of the goal box
*/
public final Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
public Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
/**
* A map of lowercase setting field names to their respective setting
@@ -700,7 +622,13 @@ public final class Settings {
*/
public final List<Setting<?>> allSettings;
public final class Setting<T> {
public void reset() {
for (Setting setting : allSettings) {
setting.value = setting.defaultValue;
}
}
public class Setting<T> {
public T value;
public final T defaultValue;
private String name;
@@ -729,13 +657,8 @@ public final class Settings {
return klass;
}
@Override
public String toString() {
return SettingsUtil.settingToString(this);
}
public void reset() {
value = defaultValue;
return name + ": " + value;
}
}

View File

@@ -18,13 +18,8 @@
package baritone.api.behavior;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.event.listener.IGameEventListener;
/**
* A behavior is simply a type that is able to listen to events.
*
* @see IGameEventListener
*
* @author Brady
* @since 9/23/2018
*/

View File

@@ -37,26 +37,7 @@ public interface IPathingBehavior extends IBehavior {
*
* @return The estimated remaining ticks in the current segment.
*/
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));
}
Optional<Double> ticksRemainingInSegment();
/**
* @return The current pathing goal
@@ -66,9 +47,7 @@ public interface IPathingBehavior extends IBehavior {
/**
* @return Whether or not a path is currently being executed.
*/
default boolean isPathing() {
return getCurrent() != null;
}
boolean isPathing();
/**
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.

View File

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

View File

@@ -18,19 +18,22 @@
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 {
public final class PlayerUpdateEvent extends ManagedPlayerEvent {
/**
* The state of the event
*/
private final EventState state;
public PlayerUpdateEvent(EventState state) {
public PlayerUpdateEvent(EntityPlayerSP player, EventState state) {
super(player);
this.state = state;
}

View File

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

View File

@@ -1,35 +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;
/**
* @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

@@ -0,0 +1,61 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.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,9 +57,6 @@ 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,14 +109,6 @@ 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,26 +22,10 @@ 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,6 +26,4 @@ import baritone.api.pathing.calc.IPath;
public interface IPathExecutor {
IPath getPath();
int getPosition();
}

View File

@@ -17,6 +17,7 @@
package baritone.api.process;
import baritone.api.IBaritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.PathEvent;
@@ -24,10 +25,8 @@ import baritone.api.event.events.PathEvent;
* A process that can control the PathingBehavior.
* <p>
* Differences between a baritone process and a behavior:
* <ul>
* <li>Only one baritone process can be active at a time</li>
* <li>PathingBehavior can only be controlled by a process</li>
* </ul>
* Only one baritone process can be active at a time
* PathingBehavior can only be controlled by a process
* <p>
* That's it actually
*
@@ -84,6 +83,13 @@ 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,6 +35,15 @@ 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

@@ -19,6 +19,7 @@ package baritone.api.utils;
import baritone.api.behavior.IBehavior;
import baritone.api.utils.input.Input;
import net.minecraft.client.settings.KeyBinding;
/**
* @author Brady
@@ -26,6 +27,8 @@ import baritone.api.utils.input.Input;
*/
public interface IInputOverrideHandler extends IBehavior {
Boolean isInputForcedDown(KeyBinding key);
boolean isInputForcedDown(Input input);
void setInputForceState(Input input, boolean forced);

View File

@@ -17,17 +17,12 @@
package baritone.api.utils;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
/**
* @author Brady
@@ -48,6 +43,4 @@ public interface IPlayerController {
default double getBlockReachDistance() {
return this.getGameType().isCreative() ? 5.0F : 4.5F;
}
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
}

View File

@@ -117,12 +117,8 @@ public class Rotation {
* @return are they really close
*/
public boolean isReallyCloseTo(Rotation other) {
return yawIsReallyClose(other) && Math.abs(this.pitch - other.pitch) < 0.01;
}
public boolean yawIsReallyClose(Rotation other) {
float yawDiff = Math.abs(normalizeYaw(yaw) - normalizeYaw(other.yaw)); // you cant fool me
return (yawDiff < 0.01 || yawDiff > 359.99);
float yawDiff = Math.abs(this.yaw - other.yaw); // you cant fool me
return (yawDiff < 0.01 || yawDiff > 359.9) && Math.abs(this.pitch - other.pitch) < 0.01;
}
/**
@@ -151,9 +147,4 @@ public class Rotation {
}
return newYaw;
}
@Override
public String toString() {
return "Yaw: " + yaw + ", Pitch: " + pitch;
}
}

View File

@@ -78,9 +78,6 @@ public final class RotationUtils {
* @return The wrapped angles
*/
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
if (current.yawIsReallyClose(target)) {
return new Rotation(current.getYaw(), target.getPitch());
}
return target.subtract(current).normalize().add(current);
}
@@ -105,7 +102,7 @@ public final class RotationUtils {
* @param dest The destination position
* @return The rotation from the origin to the destination
*/
private static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
double yaw = MathHelper.atan2(delta[0], -delta[2]);
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
@@ -199,7 +196,7 @@ public final class RotationUtils {
* @return The optional rotation
*/
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
//System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {

View File

@@ -27,8 +27,10 @@ import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
@@ -87,8 +89,22 @@ public class SettingsUtil {
public static synchronized void save(Settings settings) {
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
for (Settings.Setting setting : modifiedSettings(settings)) {
out.write(settingToString(setting) + "\n");
for (Settings.Setting setting : settings.allSettings) {
if (setting.get() == null) {
System.out.println("NULL SETTING?" + setting.getName());
continue;
}
if (setting.getName().equals("logger")) {
continue; // NO
}
if (setting.value == setting.defaultValue) {
continue;
}
SettingsIO io = map.get(setting.getValueClass());
if (io == null) {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting + " " + setting.getName());
}
out.write(setting.getName() + " " + io.toString.apply(setting.get()) + "\n");
}
} catch (Exception ex) {
System.out.println("Exception thrown while saving Baritone settings!");
@@ -96,36 +112,7 @@ public class SettingsUtil {
}
}
public static List<Settings.Setting> modifiedSettings(Settings settings) {
List<Settings.Setting> modified = new ArrayList<>();
for (Settings.Setting setting : settings.allSettings) {
if (setting.get() == null) {
System.out.println("NULL SETTING?" + setting.getName());
continue;
}
if (setting.getName().equals("logger")) {
continue; // NO
}
if (setting.value == setting.defaultValue) {
continue;
}
modified.add(setting);
}
return modified;
}
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
if (setting.getName().equals("logger")) {
return "logger";
}
SettingsIO io = map.get(setting.getValueClass());
if (io == null) {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
}
return setting.getName() + " " + io.toString.apply(setting.get());
}
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
private static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
Settings.Setting setting = settings.byLowerName.get(settingName);
if (setting == null) {
throw new IllegalStateException("No setting by that name");

View File

@@ -1,52 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ChunkRenderContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.chunk.RenderChunk;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.GL14;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import static org.lwjgl.opengl.GL11.*;
@Mixin(ChunkRenderContainer.class)
public class MixinChunkRenderContainer {
@Redirect( // avoid creating CallbackInfo at all costs; this is called 40k times per second
method = "preRenderChunk",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/chunk/RenderChunk.getPosition()Lnet/minecraft/util/math/BlockPos;"
)
)
private BlockPos getPosition(RenderChunk renderChunkIn) {
if (Baritone.settings().renderCachedChunks.get() && Minecraft.getMinecraft().getIntegratedServer() == null && 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);
}
return renderChunkIn.getPosition();
}
}

View File

@@ -1,57 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.utils.IPlayerContext;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.chunk.ChunkRenderWorker;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ChunkRenderWorker.class)
public abstract class MixinChunkRenderWorker {
@Shadow
protected abstract boolean isChunkExisting(BlockPos pos, World worldIn);
@Redirect(
method = "processTask",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/chunk/ChunkRenderWorker.isChunkExisting(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/World;)Z"
)
)
private boolean isChunkExisting(ChunkRenderWorker worker, BlockPos pos, World world) {
if (Baritone.settings().renderCachedChunks.get() && Minecraft.getMinecraft().getIntegratedServer() == null) {
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
IPlayerContext ctx = baritone.getPlayerContext();
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
return baritone.bsi.isLoaded(pos.getX(), pos.getZ()) || this.isChunkExisting(pos, world);
}
}
return this.isChunkExisting(pos, world);
}
}

View File

@@ -0,0 +1,74 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.RotationMoveEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
/**
* @author Brady
* @since 8/21/2018
*/
@Mixin(Entity.class)
public class MixinEntity {
@Shadow
public float rotationYaw;
/**
* Event called to override the movement direction when walking
*/
private RotationMoveEvent motionUpdateRotationEvent;
@Inject(
method = "moveRelative",
at = @At("HEAD")
)
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
}
}
@Redirect(
method = "moveRelative",
at = @At(
value = "FIELD",
opcode = GETFIELD,
target = "net/minecraft/entity/Entity.rotationYaw:F"
)
)
private float overrideYaw(Entity self) {
if (self instanceof EntityPlayerSP) {
return this.motionUpdateRotationEvent.getYaw();
}
return self.rotationYaw;
}
}

View File

@@ -18,7 +18,6 @@
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.RotationMoveEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
@@ -56,11 +55,8 @@ public abstract class MixinEntityLivingBase extends Entity {
private void preMoveRelative(CallbackInfo ci) {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw);
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
}
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
}
}
@@ -73,30 +69,9 @@ public abstract class MixinEntityLivingBase extends Entity {
)
)
private float overrideYaw(EntityLivingBase self) {
if (self instanceof EntityPlayerSP && BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) != null) {
if (self instanceof EntityPlayerSP) {
return this.jumpRotationEvent.getYaw();
}
return self.rotationYaw;
}
@Redirect(
method = "travel",
at = @At(
value = "INVOKE",
target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V"
)
)
private void travel(EntityLivingBase self, float strafe, float up, float forward, float friction) {
// noinspection ConstantConditions
if (!EntityPlayerSP.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) == null) {
moveRelative(strafe, up, forward, friction);
return;
}
RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent);
float originalYaw = this.rotationYaw;
this.rotationYaw = motionUpdateRotationEvent.getYaw();
this.moveRelative(strafe, up, forward, friction);
this.rotationYaw = originalYaw;
}
}

View File

@@ -18,14 +18,11 @@
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;
@@ -46,12 +43,8 @@ public class MixinEntityPlayerSP {
cancellable = true
)
private void sendChatMessage(String msg, CallbackInfo ci) {
ChatEvent event = new ChatEvent(msg);
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone == null) {
return;
}
baritone.getGameEventHandler().onSendChatMessage(event);
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onSendChatMessage(event);
if (event.isCancelled()) {
ci.cancel();
}
@@ -67,10 +60,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPreUpdate(CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
}
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
}
@Inject(
@@ -83,10 +73,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPostUpdate(CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
}
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
}
@Redirect(
@@ -97,47 +84,7 @@ public class MixinEntityPlayerSP {
)
)
private boolean isAllowFlying(PlayerCapabilities capabilities) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone == null) {
return capabilities.allowFlying;
}
return !baritone.getPathingBehavior().isPathing() && capabilities.allowFlying;
}
@Redirect(
method = "onLivingUpdate",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"
)
)
private boolean isKeyDown(KeyBinding keyBinding) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone == null) {
return keyBinding.isKeyDown();
}
SprintStateEvent event = new SprintStateEvent();
baritone.getGameEventHandler().onPlayerSprintState(event);
if (event.getState() != null) {
return event.getState();
}
if (baritone != BaritoneAPI.getProvider().getPrimaryBaritone()) {
// hitting control shouldn't make all bots sprint
return false;
}
return keyBinding.isKeyDown();
}
@Inject(
method = "updateRidden",
at = @At(
value = "HEAD"
)
)
private void updateRidden(CallbackInfo cb) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
((LookBehavior) baritone.getLookBehavior()).pig();
}
IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior();
return !pathingBehavior.isPathing() && capabilities.allowFlying;
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.utils.Helper;
import net.minecraft.client.settings.KeyBinding;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* @author Brady
* @since 7/31/2018
*/
@Mixin(KeyBinding.class)
public class MixinKeyBinding {
@Shadow
public int pressTime;
@Inject(
method = "isKeyDown",
at = @At("HEAD"),
cancellable = true
)
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
// only the primary baritone forces keys
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
if (force != null) {
cir.setReturnValue(force); // :sunglasses:
}
}
@Inject(
method = "isPressed",
at = @At("HEAD"),
cancellable = true
)
private void isPressed(CallbackInfoReturnable<Boolean> cir) {
// only the primary baritone forces keys
Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this);
if (force != null && force == false) { // <-- cursed
if (pressTime > 0) {
Helper.HELPER.logDirect("You're trying to press this mouse button but I won't let you");
pressTime--;
}
cir.setReturnValue(force); // :sunglasses:
}
}
}

View File

@@ -1,89 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.utils.IPlayerContext;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.chunk.RenderChunk;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkCache;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
/**
* @author Brady
* @since 1/29/2019
*/
@Mixin(RenderChunk.class)
public class MixinRenderChunk {
@Redirect(
method = "rebuildChunk",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/ChunkCache.isEmpty()Z"
)
)
private boolean isEmpty(ChunkCache chunkCache) {
if (!chunkCache.isEmpty()) {
return false;
}
if (Baritone.settings().renderCachedChunks.get() && Minecraft.getMinecraft().getIntegratedServer() == null) {
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
IPlayerContext ctx = baritone.getPlayerContext();
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
BlockPos position = ((RenderChunk) (Object) this).getPosition();
// RenderChunk extends from -1,-1,-1 to +16,+16,+16
// then the constructor of ChunkCache extends it one more (presumably to get things like the connected status of fences? idk)
// so if ANY of the adjacent chunks are loaded, we are unempty
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
if (baritone.bsi.isLoaded(16 * dx + position.getX(), 16 * dz + position.getZ())) {
return false;
}
}
}
}
}
return true;
}
@Redirect(
method = "rebuildChunk",
at = @At(
value = "INVOKE",
target = "net/minecraft/world/ChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
)
)
private IBlockState getBlockState(ChunkCache chunkCache, BlockPos pos) {
if (Baritone.settings().renderCachedChunks.get() && Minecraft.getMinecraft().getIntegratedServer() == null) {
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
IPlayerContext ctx = baritone.getPlayerContext();
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
return baritone.bsi.get0(pos);
}
}
return chunkCache.getBlockState(pos);
}
}

View File

@@ -1,47 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import static org.lwjgl.opengl.GL11.*;
@Mixin(RenderList.class)
public class MixinRenderList {
@Redirect( // avoid creating CallbackInfo at all costs; this is called 40k times per second
method = "renderChunkLayer",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/GlStateManager.popMatrix()V"
)
)
private void popMatrix() {
if (Baritone.settings().renderCachedChunks.get() && Minecraft.getMinecraft().getIntegratedServer() == null) {
// reset the blend func to normal (not dependent on constant alpha)
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
}
GlStateManager.popMatrix();
}
}

View File

@@ -1,47 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.VboRenderList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import static org.lwjgl.opengl.GL11.*;
@Mixin(VboRenderList.class)
public class MixinVboRenderList {
@Redirect( // avoid creating CallbackInfo at all costs; this is called 40k times per second
method = "renderChunkLayer",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/GlStateManager.popMatrix()V"
)
)
private void popMatrix() {
if (Baritone.settings().renderCachedChunks.get() && Minecraft.getMinecraft().getIntegratedServer() == null) {
// reset the blend func to normal (not dependent on constant alpha)
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
}
GlStateManager.popMatrix();
}
}

View File

@@ -12,17 +12,14 @@
"MixinBlockPos",
"MixinChunkProviderClient",
"MixinChunkProviderServer",
"MixinChunkRenderContainer",
"MixinChunkRenderWorker",
"MixinEntity",
"MixinEntityLivingBase",
"MixinEntityPlayerSP",
"MixinEntityRenderer",
"MixinKeyBinding",
"MixinMinecraft",
"MixinNetHandlerPlayClient",
"MixinNetworkManager",
"MixinRenderChunk",
"MixinRenderList",
"MixinVboRenderList",
"MixinWorldClient"
]
}

View File

@@ -1,211 +1,211 @@
/*
* 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;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.IEventBus;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.event.GameEventHandler;
import baritone.process.CustomGoalProcess;
import baritone.process.FollowProcess;
import baritone.process.GetToBlockProcess;
import baritone.process.MineProcess;
import baritone.utils.*;
import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author Brady
* @since 7/31/2018
*/
public class Baritone implements IBaritone {
private static ThreadPoolExecutor threadPool;
private static File dir;
static {
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
if (!Files.exists(dir.toPath())) {
try {
Files.createDirectories(dir.toPath());
} catch (IOException ignored) {}
}
}
/**
* Whether or not {@link Baritone#init()} has been called yet
*/
private boolean initialized;
private GameEventHandler gameEventHandler;
private List<Behavior> behaviors;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private InputOverrideHandler inputOverrideHandler;
private FollowProcess followProcess;
private MineProcess mineProcess;
private GetToBlockProcess getToBlockProcess;
private CustomGoalProcess customGoalProcess;
private PathingControlManager pathingControlManager;
private IPlayerContext playerContext;
private WorldProvider worldProvider;
public BlockStateInterface bsi;
Baritone() {
this.gameEventHandler = new GameEventHandler(this);
}
@Override
public synchronized void init() {
if (initialized) {
return;
}
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = PrimaryPlayerContext.INSTANCE;
this.behaviors = new ArrayList<>();
{
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
memoryBehavior = new MemoryBehavior(this);
new InventoryBehavior(this);
inputOverrideHandler = new InputOverrideHandler(this);
new ExampleBaritoneControl(this);
}
this.pathingControlManager = new PathingControlManager(this);
{
followProcess = new FollowProcess(this);
mineProcess = new MineProcess(this);
customGoalProcess = new CustomGoalProcess(this); // very high iq
getToBlockProcess = new GetToBlockProcess(this);
}
this.worldProvider = new WorldProvider();
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
}
this.initialized = true;
}
@Override
public PathingControlManager getPathingControlManager() {
return this.pathingControlManager;
}
public List<Behavior> getBehaviors() {
return this.behaviors;
}
public void registerBehavior(Behavior behavior) {
this.behaviors.add(behavior);
this.gameEventHandler.registerEventListener(behavior);
}
@Override
public InputOverrideHandler getInputOverrideHandler() {
return this.inputOverrideHandler;
}
@Override
public CustomGoalProcess getCustomGoalProcess() { // Iffy
return this.customGoalProcess;
}
@Override
public GetToBlockProcess getGetToBlockProcess() { // Iffy
return this.getToBlockProcess;
}
@Override
public IPlayerContext getPlayerContext() {
return this.playerContext;
}
public MemoryBehavior getMemoryBehavior() {
return this.memoryBehavior;
}
@Override
public FollowProcess getFollowProcess() {
return this.followProcess;
}
@Override
public LookBehavior getLookBehavior() {
return this.lookBehavior;
}
@Override
public MineProcess getMineProcess() {
return this.mineProcess;
}
@Override
public PathingBehavior getPathingBehavior() {
return this.pathingBehavior;
}
@Override
public WorldProvider getWorldProvider() {
return this.worldProvider;
}
@Override
public IEventBus getGameEventHandler() {
return this.gameEventHandler;
}
public static Settings settings() {
return BaritoneAPI.getSettings();
}
public static File getDir() {
return dir;
}
public static Executor getExecutor() {
return threadPool;
}
}
/*
* 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;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.IEventBus;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.event.GameEventHandler;
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.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author Brady
* @since 7/31/2018
*/
public class Baritone implements IBaritone {
private static ThreadPoolExecutor threadPool;
private static File dir;
static {
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
if (!Files.exists(dir.toPath())) {
try {
Files.createDirectories(dir.toPath());
} catch (IOException ignored) {}
}
}
/**
* Whether or not {@link Baritone#init()} has been called yet
*/
private boolean initialized;
private GameEventHandler gameEventHandler;
private List<Behavior> behaviors;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private InputOverrideHandler inputOverrideHandler;
private FollowProcess followProcess;
private MineProcess mineProcess;
private GetToBlockProcess getToBlockProcess;
private CustomGoalProcess customGoalProcess;
private PathingControlManager pathingControlManager;
private IPlayerContext playerContext;
private WorldProvider worldProvider;
Baritone() {
this.gameEventHandler = new GameEventHandler(this);
}
public synchronized void init() {
if (initialized) {
return;
}
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = PrimaryPlayerContext.INSTANCE;
this.behaviors = new ArrayList<>();
{
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
memoryBehavior = new MemoryBehavior(this);
new InventoryBehavior(this);
inputOverrideHandler = new InputOverrideHandler(this);
new ExampleBaritoneControl(this);
}
this.pathingControlManager = new PathingControlManager(this);
{
followProcess = new FollowProcess(this);
mineProcess = new MineProcess(this);
customGoalProcess = new CustomGoalProcess(this); // very high iq
getToBlockProcess = new GetToBlockProcess(this);
}
this.worldProvider = new WorldProvider();
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
}
this.initialized = true;
}
@Override
public PathingControlManager getPathingControlManager() {
return this.pathingControlManager;
}
public List<Behavior> getBehaviors() {
return this.behaviors;
}
public void registerBehavior(Behavior behavior) {
this.behaviors.add(behavior);
this.gameEventHandler.registerEventListener(behavior);
}
@Override
public InputOverrideHandler getInputOverrideHandler() {
return this.inputOverrideHandler;
}
@Override
public CustomGoalProcess getCustomGoalProcess() { // Iffy
return this.customGoalProcess;
}
@Override
public GetToBlockProcess getGetToBlockProcess() { // Iffy
return this.getToBlockProcess;
}
@Override
public IPlayerContext getPlayerContext() {
return this.playerContext;
}
public MemoryBehavior getMemoryBehavior() {
return this.memoryBehavior;
}
@Override
public FollowProcess getFollowProcess() {
return this.followProcess;
}
@Override
public LookBehavior getLookBehavior() {
return this.lookBehavior;
}
@Override
public MineProcess getMineProcess() {
return this.mineProcess;
}
@Override
public PathingBehavior getPathingBehavior() {
return this.pathingBehavior;
}
@Override
public WorldProvider getWorldProvider() {
return this.worldProvider;
}
@Override
public IEventBus getGameEventHandler() {
return this.gameEventHandler;
}
public static Settings settings() {
return BaritoneAPI.getSettings();
}
public static File getDir() {
return dir;
}
public static Executor getExecutor() {
return threadPool;
}
}

View File

@@ -95,21 +95,15 @@ 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) {
if (this.target != null && !this.force) {
event.setYaw(this.target.getYaw());
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
// Also the type has to be MOTION_UPDATE because that is called after JUMP
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE && !this.force) {
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
this.target = null;
}
}

View File

@@ -48,8 +48,6 @@ import java.nio.file.Path;
import java.util.*;
/**
* doesn't work for horse inventories :^)
*
* @author Brady
* @since 8/6/2018
*/
@@ -65,9 +63,6 @@ public final class MemoryBehavior extends Behavior {
@Override
public synchronized void onTick(TickEvent event) {
if (!Baritone.settings().containerMemory.get()) {
return;
}
if (event.getType() == TickEvent.Type.OUT) {
enderChestWindowId = null;
futureInventories.clear();
@@ -83,9 +78,6 @@ public final class MemoryBehavior extends Behavior {
@Override
public synchronized void onSendPacket(PacketEvent event) {
if (!Baritone.settings().containerMemory.get()) {
return;
}
Packet p = event.getPacket();
if (event.getState() == EventState.PRE) {
@@ -115,6 +107,7 @@ public final class MemoryBehavior extends Behavior {
}
if (p instanceof CPacketCloseWindow) {
updateInventory();
getCurrent().save();
}
}
@@ -122,9 +115,6 @@ public final class MemoryBehavior extends Behavior {
@Override
public synchronized void onReceivePacket(PacketEvent event) {
if (!Baritone.settings().containerMemory.get()) {
return;
}
Packet p = event.getPacket();
if (event.getState() == EventState.PRE) {
@@ -152,6 +142,7 @@ public final class MemoryBehavior extends Behavior {
}
if (p instanceof SPacketCloseWindow) {
updateInventory();
getCurrent().save();
}
}
@@ -171,9 +162,6 @@ public final class MemoryBehavior extends Behavior {
private void updateInventory() {
if (!Baritone.settings().containerMemory.get()) {
return;
}
int windowId = ctx.player().openContainer.windowId;
if (enderChestWindowId != null) {
if (windowId == enderChestWindowId) {

View File

@@ -19,7 +19,10 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.*;
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.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ;
@@ -30,11 +33,13 @@ 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;
@@ -61,8 +66,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
private boolean lastAutoJump;
private BlockPos expectedSegmentStart;
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
public PathingBehavior(Baritone baritone) {
@@ -90,19 +93,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
baritone.getPathingControlManager().cancelEverything();
return;
}
expectedSegmentStart = pathStart();
baritone.getPathingControlManager().preTick();
tickPath();
dispatchEvents();
}
@Override
public void onPlayerSprintState(SprintStateEvent event) {
if (current != null) {
event.setState(current.isSprinting());
}
}
private void tickPath() {
if (pauseRequestedLastTick && safeToCancel) {
pauseRequestedLastTick = false;
@@ -114,27 +109,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
cancelRequested = false;
baritone.getInputOverrideHandler().clearAllKeys();
}
if (current == null) {
return;
}
safeToCancel = current.onTick();
synchronized (pathPlanLock) {
synchronized (pathCalcLock) {
if (inProgress != null) {
// we are calculating
// are we calculating the right thing though? 🤔
BetterBlockPos calcFrom = inProgress.getStart();
Optional<IPath> currentBest = inProgress.bestPathSoFar();
if ((current == null || !current.getPath().getDest().equals(calcFrom)) // if current ends in inProgress's start, then we're ok
&& !calcFrom.equals(ctx.playerFeet()) && !calcFrom.equals(expectedSegmentStart) // if current starts in our playerFeet or pathStart, then we're ok
&& (!currentBest.isPresent() || (!currentBest.get().positions().contains(ctx.playerFeet()) && !currentBest.get().positions().contains(expectedSegmentStart))) // if
) {
// when it was *just* started, currentBest will be empty so we need to also check calcFrom since that's always present
inProgress.cancel(); // cancellation doesn't dispatch any events
inProgress = null; // this is safe since we hold both locks
}
}
}
if (current == null) {
return;
}
safeToCancel = current.onTick();
if (current.failed() || current.finished()) {
current = null;
if (goal == null || goal.isInGoal(ctx.playerFeet())) {
@@ -143,7 +122,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
next = null;
return;
}
if (next != null && !next.getPath().positions().contains(ctx.playerFeet()) && !next.getPath().positions().contains(expectedSegmentStart)) { // can contain either one
if (next != null && !next.getPath().positions().contains(ctx.playerFeet())) {
// 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
@@ -159,18 +138,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
current = next;
next = null;
current.onTick(); // don't waste a tick doing nothing, get started right away
current.onTick();
return;
}
// at this point, current just ended, but we aren't in the goal and have no plan for the future
synchronized (pathCalcLock) {
if (inProgress != null) {
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
// if we aren't calculating right now
return;
}
// we aren't calculating
queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(expectedSegmentStart, true);
findPathInNewThread(pathStart(), true);
}
return;
}
@@ -198,13 +177,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return;
}
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
// and this path doesn't get us all the way there
// and this path dosen't get us all the way there
return;
}
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
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
// and this path has 5 seconds or less left
logDebug("Path almost over. Planning ahead...");
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
findPathInNewThread(current.getPath().getDest(), false);
@@ -230,6 +207,14 @@ 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;
}
@@ -259,6 +244,11 @@ 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;
}
@@ -281,7 +271,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (doIt) {
secretInternalSegmentCancel();
}
baritone.getPathingControlManager().cancelEverything(); // regardless of if we can stop the current segment, we can still stop the processes
baritone.getPathingControlManager().cancelEverything();
return doIt;
}
@@ -306,22 +296,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
public void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED);
synchronized (pathPlanLock) {
if (current != null) {
current = null;
next = null;
baritone.getInputOverrideHandler().clearAllKeys();
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
}
current = null;
next = null;
}
baritone.getInputOverrideHandler().clearAllKeys();
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
}
public void forceCancel() { // NOT exposed on public api
cancelEverything();
secretInternalSegmentCancel();
synchronized (pathCalcLock) {
inProgress = null;
}
inProgress = null;
}
/**
@@ -345,7 +331,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return false;
}
queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(expectedSegmentStart, true);
findPathInNewThread(pathStart(), true);
return true;
}
}
@@ -385,7 +371,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
if (MovementHelper.canWalkOn(ctx, possibleSupport.down()) && MovementHelper.canWalkThrough(ctx, possibleSupport) && MovementHelper.canWalkThrough(ctx, possibleSupport.up())) {
// this is plausible
//logDebug("Faking path start assuming player is standing off the edge of a block");
logDebug("Faking path start assuming player is standing off the edge of a block");
return possibleSupport;
}
}
@@ -394,7 +380,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
// !onGround
// we're in the middle of a jump
if (MovementHelper.canWalkOn(ctx, feet.down().down())) {
//logDebug("Faking path start assuming player is midair and falling");
logDebug("Faking path start assuming player is midair and falling");
return feet.down();
}
}
@@ -444,16 +430,37 @@ 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()) {
if (executor.get().getPath().positions().contains(expectedSegmentStart)) {
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
current = executor.get();
} else {
logDebug("Warning: discarding orphan path segment with incorrect start");
}
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
current = executor.get();
} else {
if (calcResult.getType() != PathCalculationResult.Type.CANCELLATION && calcResult.getType() != PathCalculationResult.Type.EXCEPTION) {
// don't dispatch CALC_FAILED on cancellation
@@ -463,12 +470,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} else {
if (next == null) {
if (executor.isPresent()) {
if (executor.get().getPath().getSrc().equals(current.getPath().getDest())) {
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
next = executor.get();
} else {
logDebug("Warning: discarding orphan next segment with incorrect start");
}
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
next = executor.get();
} else {
queuePathEvent(PathEvent.NEXT_CALC_FAILED);
}

View File

@@ -85,7 +85,6 @@ public final class CachedChunk {
temp.add(Blocks.END_GATEWAY);
temp.add(Blocks.WEB);
temp.add(Blocks.NETHER_WART);
temp.add(Blocks.LADDER);
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
}

View File

@@ -45,7 +45,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
/**
* The maximum number of regions in any direction from (0,0)
*/
private static final int REGION_MAX = 30_000_000 / 512 + 1;
private static final int REGION_MAX = 58594;
/**
* A map of all of the cached regions.

View File

@@ -19,7 +19,10 @@ package baritone.cache;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.pathing.PathingBlockType;
import net.minecraft.block.*;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation;
@@ -70,7 +73,7 @@ public final class ChunkPacker {
for (int x = 0; x < 16; x++) {
int index = CachedChunk.getPositionIndex(x, y, z);
IBlockState state = bsc.get(x, y1, z);
boolean[] bits = getPathingBlockType(state, chunk, x, y, z).getBits();
boolean[] bits = getPathingBlockType(state).getBits();
bitSet.set(index, bits[0]);
bitSet.set(index + 1, bits[1]);
Block block = state.getBlock();
@@ -119,21 +122,14 @@ public final class ChunkPacker {
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
}
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
private static PathingBlockType getPathingBlockType(IBlockState state) {
Block block = state.getBlock();
if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) {
if (block == Blocks.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
if (!MovementHelper.possiblyFlowing(state)) {
return PathingBlockType.WATER;
}
if (BlockLiquid.getSlopeAngle(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4), state.getMaterial(), state) != -1000.0F) {
return PathingBlockType.AVOID;
}
return PathingBlockType.WATER;
}
if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) {
if (MovementHelper.avoidWalkingInto(block) || block == Blocks.FLOWING_WATER || MovementHelper.isBottomSlab(state)) {
return PathingBlockType.AVOID;
}
// We used to do an AABB check here

View File

@@ -17,7 +17,6 @@
package baritone.cache;
import baritone.Baritone;
import baritone.api.cache.IContainerMemory;
import baritone.api.cache.IRememberedInventory;
import baritone.api.utils.IPlayerContext;
@@ -70,9 +69,6 @@ public class ContainerMemory implements IContainerMemory {
}
public synchronized void save() throws IOException {
if (!Baritone.settings().containerMemory.get()) {
return;
}
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
PacketBuffer out = new PacketBuffer(buf);
out.writeInt(inventories.size());

View File

@@ -24,7 +24,6 @@ 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;
@@ -77,11 +76,7 @@ public class WorldProvider implements IWorldProvider, Helper {
directory = new File(directory, "baritone");
readme = directory;
} else { // Otherwise, the server must be remote...
String folderName = mc.getCurrentServerData().serverIP;
if (SystemUtils.IS_OS_WINDOWS) {
folderName = folderName.replace(":", "_");
}
directory = new File(Baritone.getDir(), folderName);
directory = new File(Baritone.getDir(), mc.getCurrentServerData().serverIP);
readme = Baritone.getDir();
}

View File

@@ -23,7 +23,6 @@ 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;
@@ -47,15 +46,6 @@ 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) {
baritone.bsi = null;
}
} else {
baritone.bsi = null;
}
listeners.forEach(l -> l.onTick(event));
}
@@ -131,11 +121,6 @@ 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,10 +25,15 @@ 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;
/**
@@ -36,7 +41,7 @@ import java.util.Optional;
*
* @author leijurv
*/
public final class AStarPathFinder extends AbstractNodeCostSearch {
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
private final Favoring favoring;
private final CalculationContext calcContext;
@@ -54,12 +59,14 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
startNode.combinedCost = startNode.estimatedCostToGoal;
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
openSet.insert(startNode);
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
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];
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();
@@ -72,10 +79,34 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
int numNodes = 0;
int numMovementsConsidered = 0;
int numEmptyChunk = 0;
boolean isFavoring = !favoring.isEmpty();
boolean favoring = !favored.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
double minimumImprovement = Baritone.settings().minimumImprovementRepropagation.get() ? MIN_IMPROVEMENT : 0;
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;
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)
@@ -89,14 +120,21 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
} 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)) {
@@ -104,6 +142,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
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)) {
@@ -112,8 +153,19 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
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) {
@@ -133,27 +185,47 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
}
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (isFavoring) {
if (favoring) {
// see issue #18
actionCost *= favoring.calculate(hashCode);
actionCost *= favored.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 (neighbor.cost - tentativeCost > minimumImprovement) {
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;
}
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 < COEFFICIENTS.length; i++) {
for (int i = 0; i < bestSoFar.length; i++) {
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
if (bestHeuristicSoFar[i] - heuristic > minimumImprovement) {
if (heuristic < bestHeuristicSoFar[i]) {
if (bestHeuristicSoFar[i] - heuristic < 0.01 && minimumImprovementRepropagation) {
continue;
}
bestHeuristicSoFar[i] = heuristic;
bestSoFar[i] = neighbor;
if (failing && getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
failing = false;
}
}
@@ -161,6 +233,36 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
}
}
}
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();
}
@@ -168,10 +270,28 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
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");
Optional<IPath> result = bestSoFar(true, numNodes);
if (result.isPresent()) {
logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered");
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));
}
}
return result;
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();
}
}

View File

@@ -34,7 +34,7 @@ import java.util.Optional;
*
* @author leijurv
*/
public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
public abstract class AbstractNodeCostSearch implements IPathFinder {
protected final int startX;
protected final int startY;
@@ -53,7 +53,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
protected PathNode mostRecentConsidered;
protected final PathNode[] bestSoFar = new PathNode[COEFFICIENTS.length];
protected PathNode[] bestSoFar;
private volatile boolean isFinished;
@@ -63,23 +63,13 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
* 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">here</a>
* @see <a href="https://docs.google.com/document/d/1WVHHXKXFdCR1Oz__KtK8sFqyvSwJN_H4lftkHFgmzlc/edit"></a>
*/
protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10};
protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10}; // big TODO tune
/**
* If a path goes less than 5 blocks and doesn't make it to its goal, it's not worth considering.
*/
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;
protected final static double MIN_DIST_PATH = 5;
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) {
this.startX = startX;
@@ -102,25 +92,13 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
cancelRequested = false;
try {
IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null);
isFinished = true;
if (cancelRequested) {
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION);
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path);
}
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 {
@@ -180,43 +158,25 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context));
}
@Override
public Optional<IPath> bestPathSoFar() {
return bestSoFar(false, 0);
protected int mapSize() {
return map.size();
}
protected Optional<IPath> bestSoFar(boolean logInfo, int numNodes) {
@Override
public Optional<IPath> bestPathSoFar() {
if (startNode == null || bestSoFar == null) {
return Optional.empty();
}
double bestDist = 0;
for (int i = 0; i < COEFFICIENTS.length; i++) {
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
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));
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));
}
}
// 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();
}
@@ -229,12 +189,4 @@ public abstract class AbstractNodeCostSearch implements IPathFinder, Helper {
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);
});
@@ -160,7 +160,7 @@ public abstract class Movement implements IMovement, MovementHelper {
//i dont care if theres snow in the way!!!!!!!
//you dont own me!!!!
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(blockPos), ctx.playerRotations()), true)
VecUtils.getBlockPosCenter(blockPos)), true)
);
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
state.setInput(Input.CLICK_LEFT, true);

View File

@@ -18,9 +18,7 @@
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;
@@ -37,12 +35,6 @@ 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 java.util.Optional;
import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP;
/**
* Static helpers for cost calculation
@@ -76,7 +68,7 @@ public interface MovementHelper extends ActionCosts, Helper {
if (block == Blocks.AIR) { // early return for most common case
return true;
}
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull) {
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA) {
return false;
}
if (block instanceof BlockDoor || block instanceof BlockFenceGate) {
@@ -109,7 +101,7 @@ public interface MovementHelper extends ActionCosts, Helper {
}
throw new IllegalStateException();
}
if (isFlowing(x, y, z, state, bsi)) {
if (isFlowing(state)) {
return false; // Don't walk through flowing liquids
}
if (block instanceof BlockLiquid) {
@@ -159,8 +151,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|| block instanceof BlockSnow
|| block instanceof BlockLiquid
|| block instanceof BlockTrapDoor
|| block instanceof BlockEndPortal
|| block instanceof BlockSkull) {
|| block instanceof BlockEndPortal) {
return false;
}
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
@@ -288,10 +279,10 @@ public interface MovementHelper extends ActionCosts, Helper {
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
Block up = bsi.get0(x, y + 1, z).getBlock();
if (up == Blocks.WATERLILY || up == Blocks.CARPET) {
if (up == Blocks.WATERLILY) {
return true;
}
if (isFlowing(x, y, z, state, bsi) || block == Blocks.FLOWING_WATER) {
if (isFlowing(state) || block == Blocks.FLOWING_WATER) {
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
return isWater(up) && !Baritone.settings().assumeWalkOnWater.get();
}
@@ -442,10 +433,11 @@ public interface MovementHelper extends ActionCosts, Helper {
}
static void moveTowards(IPlayerContext ctx, MovementState state, BlockPos pos) {
EntityPlayerSP player = ctx.player();
state.setTarget(new MovementTarget(
new Rotation(RotationUtils.calcRotationFromVec3d(ctx.playerHead(),
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(pos),
ctx.playerRotations()).getYaw(), ctx.player().rotationPitch),
new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch),
false
)).setInput(Input.MOVE_FORWARD, true);
}
@@ -488,72 +480,9 @@ public interface MovementHelper extends ActionCosts, Helper {
return BlockStateInterface.getBlock(ctx, p) instanceof BlockLiquid;
}
static boolean possiblyFlowing(IBlockState state) {
static boolean isFlowing(IBlockState state) {
// Will be IFluidState in 1.13
return state.getBlock() instanceof BlockLiquid
&& state.getValue(BlockLiquid.LEVEL) != 0;
}
static boolean isFlowing(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
if (!(state.getBlock() instanceof BlockLiquid)) {
return false;
}
if (state.getValue(BlockLiquid.LEVEL) != 0) {
return true;
}
return possiblyFlowing(bsi.get0(x + 1, y, z))
|| possiblyFlowing(bsi.get0(x - 1, y, z))
|| possiblyFlowing(bsi.get0(x, y, z + 1))
|| possiblyFlowing(bsi.get0(x, y, z - 1));
}
static PlaceResult attemptToPlaceABlock(MovementState state, IBaritone baritone, BlockPos placeAt, boolean preferDown) {
IPlayerContext ctx = baritone.getPlayerContext();
Optional<Rotation> direct = RotationUtils.reachable(ctx, placeAt); // we assume that if there is a block there, it must be replacable
boolean found = false;
if (direct.isPresent()) {
state.setTarget(new MovementState.MovementTarget(direct.get(), true));
found = true;
}
for (int i = 0; i < 5; i++) {
BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
if (MovementHelper.canPlaceAgainst(ctx, against1)) {
//if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block
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,6 +21,7 @@ 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;
@@ -31,6 +32,10 @@ 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 {
@@ -157,45 +162,63 @@ public class MovementAscend extends Movement {
IBlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace);
if (!MovementHelper.canWalkOn(ctx, positionToPlace, jumpingOnto)) {
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);
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;
}
}
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;
return state.setStatus(MovementStatus.UNREACHABLE);
}
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() || ctx.playerFeet().equals(src.up())) {
// no need to hit space if we're already jumping
if (Baritone.settings().assumeStep.get()) {
return state;
}
int xAxis = Math.abs(src.getX() - dest.getX()); // either 0 or 1
int zAxis = Math.abs(src.getZ() - dest.getZ()); // either 0 or 1
double flatDistToNext = xAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + zAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
double sideDist = zAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + xAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
double lateralMotion = xAxis * ctx.player().motionZ + zAxis * ctx.player().motionX;
if (Math.abs(lateralMotion) > 0.1) {
return state;
if (ctx.playerFeet().equals(src.up())) {
return state; // no need to hit space if we're already jumping
}
if (headBonkClear()) {
return state.setInput(Input.JUMP, true);
}
int xAxis = Math.abs(src.getX() - dest.getX()); // either 0 or 1
int zAxis = Math.abs(src.getZ() - dest.getZ()); // either 0 or 1
double flatDistToNext = xAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + zAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
double sideDist = zAxis * Math.abs((dest.getX() + 0.5D) - ctx.player().posX) + xAxis * Math.abs((dest.getZ() + 0.5D) - ctx.player().posZ);
// System.out.println(flatDistToNext + " " + sideDist);
if (flatDistToNext > 1.2 || sideDist > 0.2) {
return state;
@@ -207,7 +230,7 @@ public class MovementAscend extends Movement {
return state.setInput(Input.JUMP, true);
}
public boolean headBonkClear() {
private boolean headBonkClear() {
BetterBlockPos startUp = src.up(2);
for (int i = 0; i < 4; i++) {
BetterBlockPos check = startUp.offset(EnumFacing.byHorizontalIndex(i));

View File

@@ -137,13 +137,13 @@ 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 || ontoBlock.getBlock() == Blocks.FLOWING_WATER) && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) {
if (ontoBlock.getBlock() == Blocks.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) {
return false; // TODO fix
}
if (MovementHelper.isFlowing(destX, newY, destZ, ontoBlock, context.bsi)) {
if (MovementHelper.isFlowing(ontoBlock)) {
return false; // TODO flowing check required here?
}
if (!MovementHelper.canWalkOn(context.bsi, destX, newY - 1, destZ)) {
@@ -157,6 +157,9 @@ 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
@@ -174,6 +177,13 @@ 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;
@@ -181,13 +191,6 @@ 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;
}
@@ -210,8 +213,8 @@ public class MovementDescend extends Movement {
}*/
}
if (safeMode()) {
double destX = (src.getX() + 0.5) * 0.17 + (dest.getX() + 0.5) * 0.83;
double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83;
double destX = (src.getX() + 0.5) * 0.19 + (dest.getX() + 0.5) * 0.81;
double destZ = (src.getZ() + 0.5) * 0.19 + (dest.getZ() + 0.5) * 0.81;
EntityPlayerSP player = ctx.player();
state.setTarget(new MovementState.MovementTarget(
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
@@ -232,7 +235,8 @@ public class MovementDescend extends Movement {
if (numTicks++ < 20) {
MovementHelper.moveTowards(ctx, state, fakeDest);
if (fromStart > 1.25) {
state.getTarget().rotation = new Rotation(state.getTarget().rotation.getYaw() + 180F, state.getTarget().rotation.getPitch());
state.setInput(Input.MOVE_FORWARD, false);
state.setInput(Input.MOVE_BACK, true);
}
} else {
MovementHelper.moveTowards(ctx, state, dest);
@@ -245,10 +249,6 @@ public class MovementDescend extends Movement {
// (dest - src) + dest is offset 1 more in the same direction
// so it's the block we'd need to worry about running into if we decide to sprint straight through this descend
BlockPos into = dest.subtract(src.down()).add(dest);
if (skipToAscend()) {
// if dest extends into can't walk through, but the two above are can walk through, then we can overshoot and glitch in that weird way
return true;
}
for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(ctx, into.up(y)))) {
return true;
@@ -256,9 +256,4 @@ public class MovementDescend extends Movement {
}
return false;
}
public boolean skipToAscend() {
BlockPos into = dest.subtract(src.down()).add(dest);
return !MovementHelper.canWalkThrough(ctx, new BetterBlockPos(into)) && MovementHelper.canWalkThrough(ctx, new BetterBlockPos(into).up()) && MovementHelper.canWalkThrough(ctx, new BetterBlockPos(into).up(2));
}
}

View File

@@ -17,7 +17,6 @@
package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
@@ -115,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()))) {
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) {
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
return;
}
@@ -124,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()))) {
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER))) {
// and now that option B is fully calculated, see if we can edge around that way
return;
}
@@ -174,25 +173,13 @@ public class MovementDiagonal extends Movement {
state.setStatus(MovementStatus.SUCCESS);
return state;
}
if (sprint()) {
if (!MovementHelper.isLiquid(ctx, ctx.playerFeet())) {
state.setInput(Input.SPRINT, true);
}
MovementHelper.moveTowards(ctx, state, dest);
return state;
}
public boolean sprint() {
if (MovementHelper.isLiquid(ctx, ctx.playerFeet()) && !Baritone.settings().sprintInWater.get()) {
return false;
}
for (int i = 0; i < 4; i++) {
if (!MovementHelper.canWalkThrough(ctx, positionsToBreak[i])) {
return false;
}
}
return true;
}
@Override
protected boolean prepared(MovementState state) {
return true;

View File

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

View File

@@ -20,6 +20,9 @@ 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;
@@ -28,11 +31,13 @@ import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
public class MovementParkour extends Movement {
@@ -86,7 +91,7 @@ public class MovementParkour extends Movement {
return;
}
IBlockState standingOn = context.get(x, y - 1, z);
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn) || standingOn.getBlock() instanceof BlockLiquid) {
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn)) {
return;
}
int maxJump;
@@ -188,11 +193,6 @@ 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,9 +209,35 @@ 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 && 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 (!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 (dist == 3) { // this is a 2 block gap, dest = src + direction * 3
double xDiff = (src.x + 0.5) - ctx.player().posX;

View File

@@ -35,8 +35,6 @@ 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) {
@@ -151,7 +149,7 @@ public class MovementPillar extends Movement {
IBlockState fromDown = BlockStateInterface.get(ctx, src);
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(ctx, dest)) {
// stay centered while swimming up a water column
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()), false));
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest)), false));
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
if (Math.abs(ctx.player().posX - destCenter.x) > 0.2 || Math.abs(ctx.player().posZ - destCenter.z) > 0.2) {
state.setInput(Input.MOVE_FORWARD, true);
@@ -226,7 +224,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() && (Objects.equals(src.down(), ctx.objectMouseOver().getBlockPos()) || Objects.equals(src, ctx.objectMouseOver().getBlockPos())) && ctx.player().posY > dest.getY() + 0.1) {
} else if (ctx.player().isSneaking()) { // 1 tick after we're able to place
state.setInput(Input.CLICK_RIGHT, true);
}
}

View File

@@ -36,6 +36,7 @@ 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;
@@ -135,7 +136,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 (regardless of whether it's top half or bottom half) =/
return COST_INF; // can't sneak and backplace against soul sand or half slabs =/
}
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
return COST_INF; // this is obviously impossible
@@ -174,11 +175,11 @@ public class MovementTraverse extends Movement {
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest), ctx.playerRotations()).getYaw();
float yawToDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), dest)).getYaw();
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
return state.setInput(Input.MOVE_FORWARD, true).setInput(Input.SPRINT, true);
return state.setInput(Input.MOVE_FORWARD, true);
}
//sneak may have been set to true in the PREPPING state while mining an adjacent block
@@ -198,7 +199,7 @@ public class MovementTraverse extends Movement {
isDoorActuallyBlockingUs = true;
}
if (isDoorActuallyBlockingUs && !(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), positionsToBreak[0]), ctx.playerRotations()), true))
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), positionsToBreak[0])), true))
.setInput(Input.CLICK_RIGHT, true);
}
}
@@ -212,7 +213,7 @@ public class MovementTraverse extends Movement {
}
if (blocked != null) {
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), blocked), ctx.playerRotations()), true))
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.calculateBlockCenter(ctx.world(), blocked)), true))
.setInput(Input.CLICK_RIGHT, true);
}
}
@@ -234,7 +235,7 @@ public class MovementTraverse extends Movement {
BlockPos into = dest.subtract(src).add(dest);
Block intoBelow = BlockStateInterface.get(ctx, into).getBlock();
Block intoAbove = BlockStateInterface.get(ctx, into.up()).getBlock();
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, ctx.playerFeet()) || Baritone.settings().sprintInWater.get()) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
if (wasTheBridgeBlockAlwaysThere && !MovementHelper.isLiquid(ctx, ctx.playerFeet()) && !MovementHelper.avoidWalkingInto(intoBelow) && !MovementHelper.avoidWalkingInto(intoAbove)) {
state.setInput(Input.SPRINT, true);
}
Block destDown = BlockStateInterface.get(ctx, dest.down()).getBlock();
@@ -246,47 +247,53 @@ public class MovementTraverse extends Movement {
return state;
} else {
wasTheBridgeBlockAlwaysThere = false;
Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock();
if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118
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);
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;
}
}
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);
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);
}
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);
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);
}
} 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;
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);
}
default:
break;
}
if (!Baritone.settings().assumeSafeWalk.get()) {
state.setInput(Input.SNEAK, true);
}
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;
@@ -295,26 +302,25 @@ public class MovementTraverse extends Movement {
Rotation backToFace = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
float pitch = backToFace.getPitch();
double dist2 = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ));
if (dist2 < 0.29) { // see issue #208
double dist = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ));
if (dist < 0.29) {
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());
if (ctx.playerRotations().isReallyCloseTo(state.getTarget().rotation)) {
state.setInput(Input.CLICK_LEFT, true);
}
return state.setInput(Input.CLICK_LEFT, true);
} else {
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
}
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
}
}
@@ -336,4 +342,4 @@ public class MovementTraverse extends Movement {
}
return super.prepared(state);
}
}
}

View File

@@ -25,7 +25,6 @@ import baritone.api.pathing.movement.MovementStatus;
import baritone.api.pathing.path.IPathExecutor;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.api.utils.input.Input;
import baritone.behavior.PathingBehavior;
@@ -40,8 +39,6 @@ import net.minecraft.block.BlockLiquid;
import net.minecraft.init.Blocks;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import java.util.*;
@@ -82,8 +79,6 @@ 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;
@@ -106,31 +101,39 @@ public class PathExecutor implements IPathExecutor, Helper {
}
BetterBlockPos whereShouldIBe = path.positions().get(pathPosition);
BetterBlockPos whereAmI = ctx.playerFeet();
if (!whereShouldIBe.equals(whereAmI) && !Blocks.AIR.equals(BlockStateInterface.getBlock(ctx, whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
for (int i = 0; i < pathPosition - 1 && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
if (whereAmI.equals(path.positions().get(i))) {
logDebug("Skipping back " + (pathPosition - i) + " steps, to " + i);
int previousPos = pathPosition;
pathPosition = Math.max(i - 1, 0); // previous step might not actually be done
for (int j = pathPosition; j <= previousPos; j++) {
path.movements().get(j).reset();
}
onChangeInPathPosition();
onTick();
return false;
}
if (!whereShouldIBe.equals(whereAmI)) {
if (pathPosition == 0 && whereAmI.equals(whereShouldIBe.up()) && Math.abs(ctx.player().motionY) < 0.1 && !(path.movements().get(0) instanceof MovementAscend) && !(path.movements().get(0) instanceof MovementPillar)) {
// avoid the Wrong Y coordinate bug
// TODO add a timer here
new MovementDownward(behavior.baritone, whereAmI, whereShouldIBe).update();
return false;
}
for (int i = pathPosition + 3; i < path.length(); i++) { //dont check pathPosition+1. the movement tells us when it's done (e.g. sneak placing)
// also don't check pathPosition+2 because reasons
if (whereAmI.equals(path.positions().get(i))) {
if (i - pathPosition > 2) {
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
if (!Blocks.AIR.equals(BlockStateInterface.getBlock(ctx, whereAmI.down()))) {//do not skip if standing on air, because our position isn't stable to skip
for (int i = 0; i < pathPosition - 1 && i < path.length(); i++) {//this happens for example when you lag out and get teleported back a couple blocks
if (whereAmI.equals(path.positions().get(i))) {
logDebug("Skipping back " + (pathPosition - i) + " steps, to " + i);
int previousPos = pathPosition;
pathPosition = Math.max(i - 1, 0); // previous step might not actually be done
for (int j = pathPosition; j <= previousPos; j++) {
path.movements().get(j).reset();
}
onChangeInPathPosition();
return false;
}
}
for (int i = pathPosition + 3; i < path.length(); i++) { //dont check pathPosition+1. the movement tells us when it's done (e.g. sneak placing)
// also don't check pathPosition+2 because reasons
if (whereAmI.equals(path.positions().get(i))) {
if (i - pathPosition > 2) {
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
}
//System.out.println("Double skip sundae");
pathPosition = i - 1;
onChangeInPathPosition();
return false;
}
//System.out.println("Double skip sundae");
pathPosition = i - 1;
onChangeInPathPosition();
onTick();
return false;
}
}
}
@@ -190,17 +193,17 @@ public class PathExecutor implements IPathExecutor, Helper {
continue;
}
Movement m = (Movement) path.movements().get(i);
List<BlockPos> prevBreak = m.toBreak(bsi);
List<BlockPos> prevPlace = m.toPlace(bsi);
List<BlockPos> prevWalkInto = m.toWalkInto(bsi);
HashSet<BlockPos> prevBreak = new HashSet<>(m.toBreak(bsi));
HashSet<BlockPos> prevPlace = new HashSet<>(m.toPlace(bsi));
HashSet<BlockPos> prevWalkInto = new HashSet<>(m.toWalkInto(bsi));
m.resetBlockCache();
if (!prevBreak.equals(m.toBreak(bsi))) {
if (!prevBreak.equals(new HashSet<>(m.toBreak(bsi)))) {
recalcBP = true;
}
if (!prevPlace.equals(m.toPlace(bsi))) {
if (!prevPlace.equals(new HashSet<>(m.toPlace(bsi)))) {
recalcBP = true;
}
if (!prevWalkInto.equals(m.toWalkInto(bsi))) {
if (!prevWalkInto.equals(new HashSet<>(m.toWalkInto(bsi)))) {
recalcBP = true;
}
}
@@ -244,8 +247,6 @@ 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;
@@ -268,10 +269,7 @@ public class PathExecutor implements IPathExecutor, Helper {
onTick();
return true;
} else {
sprintNextTick = shouldSprintNextTick();
if (!sprintNextTick) {
ctx.player().setSprinting(false); // letting go of control doesn't make you stop sprinting actually
}
sprintIfRequested();
ticksOnCurrent++;
if (ticksOnCurrent > currentMovementOriginalCostEstimate + Baritone.settings().movementTimeoutTicks.get()) {
// only cancel if the total time has exceeded the initial estimate
@@ -373,69 +371,58 @@ public class PathExecutor implements IPathExecutor, Helper {
return true;
}
private boolean shouldSprintNextTick() {
boolean requested = behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT);
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;
}
// 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;
}
// 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) {
// traverse requests sprinting, so we need to do this check first
if (current instanceof MovementTraverse && pathPosition < path.length() - 3) {
IMovement next = path.movements().get(pathPosition + 1);
if (next instanceof MovementAscend && sprintableAscend(ctx, (MovementTraverse) current, (MovementAscend) next, path.movements().get(pathPosition + 2))) {
if (skipNow(ctx, current)) {
logDebug("Skipping traverse to straight ascend");
pathPosition++;
onChangeInPathPosition();
onTick();
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true);
return true;
} else {
logDebug("Too far to the side to safely sprint ascend");
}
}
}
// if the movement requested sprinting, then we're done
if (requested) {
return true;
}
// however, descend and ascend don't request sprinting, because they don't know the context of what movement comes after it
if (current instanceof MovementDescend) {
if (((MovementDescend) current).safeMode() && !((MovementDescend) current).skipToAscend()) {
if (((MovementDescend) current).safeMode()) {
logDebug("Sprinting would be unsafe");
return false;
ctx.player().setSprinting(false);
return;
}
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
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())) {
pathPosition++;
onChangeInPathPosition();
onTick();
// okay to skip clearKeys and / or onChangeInPathPosition here since this isn't possible to repeat, since it's asymmetric
logDebug("Skipping descend to straight ascend");
return true;
}
if (canSprintFromDescendInto(ctx, current, next)) {
if (ctx.playerFeet().equals(current.getDest())) {
pathPosition++;
onChangeInPathPosition();
onTick();
}
return true;
if (!ctx.player().isSprinting()) {
ctx.player().setSprinting(true);
}
//logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection()));
return;
}
//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);
@@ -443,126 +430,17 @@ 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);
return true;
if (!ctx.player().isSprinting()) {
ctx.player().setSprinting(true);
}
return;
}
}
if (pathPosition < path.length() - 2 && prev instanceof MovementTraverse && sprintableAscend(ctx, (MovementTraverse) prev, (MovementAscend) current, path.movements().get(pathPosition + 1))) {
return true;
}
}
if (current instanceof MovementFall) {
Tuple<Vec3d, BlockPos> data = overrideFall((MovementFall) current);
if (data != null) {
BlockPos fallDest = data.getSecond();
if (!path.positions().contains(fallDest)) {
throw new IllegalStateException();
}
if (ctx.playerFeet().equals(fallDest)) {
pathPosition = path.positions().indexOf(fallDest);
onChangeInPathPosition();
onTick();
return true;
}
clearKeys();
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getFirst(), ctx.playerRotations()), false);
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true);
return true;
}
}
return false;
ctx.player().setSprinting(false);
}
private Tuple<Vec3d, BlockPos> overrideFall(MovementFall movement) {
Vec3i dir = movement.getDirection();
if (dir.getY() < -3) {
return null;
}
if (!movement.toBreakCached.isEmpty()) {
return null; // it's breaking
}
Vec3i flatDir = new Vec3i(dir.getX(), 0, dir.getZ());
int i;
outer:
for (i = pathPosition + 1; i < path.length() - 1 && i < pathPosition + 3; i++) {
IMovement next = path.movements().get(i);
if (!(next instanceof MovementTraverse)) {
break;
}
if (!flatDir.equals(next.getDirection())) {
break;
}
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z);
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
break outer;
}
}
if (!MovementHelper.canWalkOn(ctx, next.getDest().down())) {
break;
}
}
i--;
if (i == pathPosition) {
return null; // no valid extension exists
}
double len = i - pathPosition - 0.4;
return new Tuple<>(
new Vec3d(flatDir.getX() * len + movement.getDest().x + 0.5, movement.getDest().y, flatDir.getZ() * len + movement.getDest().z + 0.5),
movement.getDest().add(flatDir.getX() * (i - pathPosition), 0, flatDir.getZ() * (i - pathPosition)));
}
private static boolean skipNow(IPlayerContext ctx, IMovement current) {
double offTarget = Math.abs(current.getDirection().getX() * (current.getSrc().z + 0.5D - ctx.player().posZ)) + Math.abs(current.getDirection().getZ() * (current.getSrc().x + 0.5D - ctx.player().posX));
if (offTarget > 0.1) {
return false;
}
// we are centered
BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2);
if (MovementHelper.fullyPassable(ctx.world().getBlockState(headBonk))) {
return true;
}
// wait 0.3
double flatDist = Math.abs(current.getDirection().getX() * (headBonk.getX() + 0.5D - ctx.player().posX)) + Math.abs(current.getDirection().getZ() * (headBonk.getZ() + 0.5 - ctx.player().posZ));
return flatDist > 0.8;
}
private static boolean sprintableAscend(IPlayerContext ctx, MovementTraverse current, MovementAscend next, IMovement nextnext) {
if (!Baritone.settings().sprintAscends.get()) {
return false;
}
if (!current.getDirection().equals(next.getDirection().down())) {
return false;
}
if (nextnext.getDirection().getX() != next.getDirection().getX() || nextnext.getDirection().getZ() != next.getDirection().getZ()) {
return false;
}
if (!MovementHelper.canWalkOn(ctx, current.getDest().down())) {
return false;
}
if (!MovementHelper.canWalkOn(ctx, next.getDest().down())) {
return false;
}
if (!next.toBreakCached.isEmpty()) {
return false; // it's breaking
}
for (int x = 0; x < 2; x++) {
for (int y = 0; y < 3; y++) {
BlockPos chk = current.getSrc().up(y);
if (x == 1) {
chk = chk.add(current.getDirection());
}
if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) {
return false;
}
}
}
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)).getBlock())) {
return false;
}
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2)).getBlock()); // codacy smh my head
}
private static boolean canSprintFromDescendInto(IPlayerContext ctx, IMovement current, IMovement next) {
private static boolean canSprintInto(IPlayerContext ctx, IMovement current, IMovement next) {
if (next instanceof MovementDescend && next.getDirection().equals(current.getDirection())) {
return true;
}
@@ -589,7 +467,6 @@ public class PathExecutor implements IPathExecutor, Helper {
failed = true;
}
@Override
public int getPosition() {
return pathPosition;
}
@@ -655,8 +532,4 @@ public class PathExecutor implements IPathExecutor, Helper {
public Set<BlockPos> toWalkInto() {
return Collections.unmodifiableSet(toWalkInto);
}
public boolean isSprinting() {
return sprintNextTick;
}
}

View File

@@ -55,9 +55,6 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
if (this.state == State.NONE) {
this.state = State.GOAL_SET;
}
if (this.state == State.EXECUTING) {
this.state = State.PATH_REQUESTED;
}
}
@Override
@@ -84,7 +81,7 @@ public class CustomGoalProcess extends BaritoneProcessHelper implements ICustomG
}
return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL);
case PATH_REQUESTED:
PathingCommand ret = new PathingCommand(this.goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
PathingCommand ret = new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH);
this.state = State.EXECUTING;
return ret;
case EXECUTING:

View File

@@ -18,7 +18,10 @@
package baritone.process;
import baritone.Baritone;
import baritone.api.pathing.goals.*;
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.process.IGetToBlockProcess;
import baritone.api.process.PathingCommand;
import baritone.api.process.PathingCommandType;
@@ -32,14 +35,15 @@ import net.minecraft.init.Blocks;
import net.minecraft.inventory.ContainerPlayer;
import net.minecraft.util.math.BlockPos;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBlockProcess {
private Block gettingTo;
private List<BlockPos> knownLocations;
private List<BlockPos> blacklist; // locations we failed to calc to
private BlockPos start;
private int tickCount = 0;
@@ -51,8 +55,6 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
public void getToBlock(Block block) {
onLostControl();
gettingTo = block;
start = ctx.playerFeet();
blacklist = new ArrayList<>();
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
@@ -62,38 +64,23 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
}
@Override
public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (knownLocations == null) {
rescan(new ArrayList<>(), new CalculationContext(baritone));
}
if (knownLocations.isEmpty()) {
if (Baritone.settings().exploreForBlocks.get() && !calcFailed) {
return new PathingCommand(new GoalRunAway(1, start) {
@Override
public boolean isInGoal(int x, int y, int z) {
return false;
}
}, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
}
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
if (isSafeToCancel) {
onLostControl();
}
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
Goal goal = new GoalComposite(knownLocations.stream().map(this::createGoal).toArray(Goal[]::new));
if (calcFailed) {
if (Baritone.settings().blacklistOnGetToBlockFailure.get()) {
logDirect("Unable to find any path to " + gettingTo + ", blacklisting presumably unreachable closest instances");
blacklistClosest();
return onTick(false, isSafeToCancel); // gamer moment
} else {
logDirect("Unable to find any path to " + gettingTo + ", canceling GetToBlock");
if (isSafeToCancel) {
onLostControl();
}
return new PathingCommand(goal, PathingCommandType.CANCEL_AND_SET_GOAL);
logDirect("Unable to find any path to " + gettingTo + ", canceling GetToBlock");
if (isSafeToCancel) {
onLostControl();
}
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
@@ -101,61 +88,24 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
CalculationContext context = new CalculationContext(baritone, true);
Baritone.getExecutor().execute(() -> rescan(current, context));
}
Goal goal = new GoalComposite(knownLocations.stream().map(this::createGoal).toArray(Goal[]::new));
if (goal.isInGoal(ctx.playerFeet()) && isSafeToCancel) {
// we're there
if (rightClickOnArrival(gettingTo)) {
if (rightClick()) {
onLostControl();
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
} else {
onLostControl();
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
}
return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
}
// blacklist the closest block and its adjacent blocks
public synchronized void blacklistClosest() {
List<BlockPos> newBlacklist = new ArrayList<>();
knownLocations.stream().min(Comparator.comparingDouble(ctx.player()::getDistanceSq)).ifPresent(newBlacklist::add);
outer:
while (true) {
for (BlockPos known : knownLocations) {
for (BlockPos blacklist : newBlacklist) {
if (areAdjacent(known, blacklist)) { // directly adjacent
newBlacklist.add(known);
knownLocations.remove(known);
continue outer;
}
}
}
// i can't do break; (codacy gets mad), and i can't do if(true){break}; (codacy gets mad)
// so i will do this
switch (newBlacklist.size()) {
default:
break outer;
}
}
logDebug("Blacklisting unreachable locations " + newBlacklist);
blacklist.addAll(newBlacklist);
}
// safer than direct double comparison from distanceSq
private boolean areAdjacent(BlockPos posA, BlockPos posB) {
int diffX = Math.abs(posA.getX() - posB.getX());
int diffY = Math.abs(posA.getY() - posB.getY());
int diffZ = Math.abs(posA.getZ() - posB.getZ());
return (diffX + diffY + diffZ) == 1;
}
@Override
public synchronized void onLostControl() {
public void onLostControl() {
gettingTo = null;
knownLocations = null;
start = null;
blacklist = null;
baritone.getInputOverrideHandler().clearAllKeys();
}
@@ -164,20 +114,12 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
return "Get To Block " + gettingTo;
}
private synchronized void rescan(List<BlockPos> known, CalculationContext context) {
List<BlockPos> positions = MineProcess.searchWorld(context, Collections.singletonList(gettingTo), 64, known);
positions.removeIf(blacklist::contains);
knownLocations = positions;
private void rescan(List<BlockPos> known, CalculationContext context) {
knownLocations = MineProcess.searchWorld(context, Collections.singletonList(gettingTo), 64, known);
}
private Goal createGoal(BlockPos pos) {
if (walkIntoInsteadOfAdjacent(gettingTo)) {
return new GoalTwoBlocks(pos);
}
if (blockOnTopMustBeRemoved(gettingTo) && baritone.bsi.get0(pos.up()).isBlockNormalCube()) {
return new GoalBlock(pos.up());
}
return new GoalGetToBlock(pos);
return walkIntoInsteadOfAdjacent(gettingTo) ? new GoalTwoBlocks(pos) : new GoalGetToBlock(pos);
}
private boolean rightClick() {
@@ -212,12 +154,4 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
}
return block == Blocks.CRAFTING_TABLE || block == Blocks.FURNACE || block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
}
private boolean blockOnTopMustBeRemoved(Block block) {
if (!rightClickOnArrival(block)) { // only if we plan to actually open it on arrival
return false;
}
// only these chests; you can open a crafting table or furnace even with a block on top
return block == Blocks.ENDER_CHEST || block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST;
}
}

View File

@@ -94,14 +94,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
if (Baritone.settings().legitMine.get()) {
addNearby();
}
PathingCommand command = updateGoal();
if (command == null) {
Goal goal = updateGoal();
if (goal == null) {
// none in range
// maybe say something in chat? (ahem impact)
cancel();
return null;
}
return command;
return new PathingCommand(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
}
@Override
@@ -114,18 +114,17 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return "Mine " + mining;
}
private PathingCommand updateGoal() {
boolean legit = Baritone.settings().legitMine.get();
private Goal updateGoal() {
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 new PathingCommand(goal, legit ? PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType.REVALIDATE_GOAL_AND_PATH);
return goal;
}
// we don't know any ore locations at the moment
if (!legit) {
if (!Baritone.settings().legitMine.get()) {
return null;
}
// only in non-Xray mode (aka legit mode) do we do this
@@ -150,7 +149,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
};
}
return new PathingCommand(branchPointRunaway, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
return branchPointRunaway;
}
private void rescan(List<BlockPos> already, CalculationContext context) {
@@ -228,7 +227,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return prune(ctx, locs, mining, max);
}
private void addNearby() {
public void addNearby() {
knownOreLocations.addAll(droppedItemsScan(mining, ctx.world()));
BlockPos playerFeet = ctx.playerFeet();
BlockStateInterface bsi = new BlockStateInterface(ctx);
@@ -239,11 +238,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
// crucial to only add blocks we can see because otherwise this
// is an x-ray and it'll get caught
if (mining.contains(bsi.get0(x, y, z).getBlock())) {
BlockPos pos = new BlockPos(x, y, z);
if ((Baritone.settings().legitMineIncludeDiagonals.get() && knownOreLocations.stream().anyMatch(ore -> ore.distanceSq(pos) <= 2 /* sq means this is pytha dist <= sqrt(2) */)) || RotationUtils.reachable(ctx.player(), pos, fakedBlockReachDistance).isPresent()) {
knownOreLocations.add(pos);
}
if (mining.contains(bsi.get0(x, y, z).getBlock()) && RotationUtils.reachable(ctx.player(), new BlockPos(x, y, z), fakedBlockReachDistance).isPresent()) {
knownOreLocations.add(new BlockPos(x, y, z));
}
}
}
@@ -253,19 +249,12 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
public static List<BlockPos> prune(CalculationContext ctx, List<BlockPos> locs2, List<Block> mining, int max) {
List<BlockPos> dropped = droppedItemsScan(mining, ctx.world);
dropped.removeIf(drop -> {
for (BlockPos pos : locs2) {
if (pos.distanceSq(drop) <= 9 && mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) && MineProcess.plausibleToBreak(ctx.bsi, pos)) { // TODO maybe drop also has to be supported? no lava below?
return true;
}
}
return false;
});
List<BlockPos> locs = locs2
.stream()
.distinct()
// remove any that are within loaded chunks that aren't actually what we want
.filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || mining.contains(ctx.getBlock(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos))
// remove any that are implausible to mine (encased in bedrock, or touching lava)

View File

@@ -115,9 +115,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
}
// Setup Baritone's pathing goal and (if needed) begin pathing
if (!BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().isActive()) {
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(GOAL);
}
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(GOAL);
// If we have reached our goal, print a message and safely close the game
if (GOAL.isInGoal(ctx.playerFeet())) {

View File

@@ -34,6 +34,11 @@ 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

@@ -31,7 +31,7 @@ public final class BlockBreakHelper implements Helper {
private boolean didBreakLastTick;
private final IPlayerContext playerContext;
private IPlayerContext playerContext;
public BlockBreakHelper(IPlayerContext playerContext) {
this.playerContext = playerContext;

View File

@@ -1,53 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.Baritone;
import baritone.api.utils.IPlayerContext;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
public class BlockPlaceHelper implements Helper {
private final IPlayerContext ctx;
private int rightClickTimer;
public BlockPlaceHelper(IPlayerContext playerContext) {
this.ctx = playerContext;
}
public void tick(boolean rightClickRequested) {
if (rightClickTimer > 0) {
rightClickTimer--;
return;
}
RayTraceResult mouseOver = ctx.objectMouseOver();
BlockPos pos = mouseOver.getBlockPos();
if (!rightClickRequested || ctx.player().isRowingBoat() || pos == null || mouseOver.typeOfHit != RayTraceResult.Type.BLOCK) {
return;
}
rightClickTimer = Baritone.settings().rightClickSpeed.get();
for (EnumHand hand : EnumHand.values()) {
if (ctx.playerController().processRightClickBlock(ctx.player(), ctx.world(), pos, mouseOver.sideHit, mouseOver.hitVec, hand) == EnumActionResult.SUCCESS) {
ctx.player().swingArm(hand);
return;
}
}
}
}

View File

@@ -40,9 +40,10 @@ 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;
@@ -91,7 +92,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;
@@ -106,6 +107,7 @@ 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,7 +24,6 @@ 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;
@@ -36,7 +35,6 @@ 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,10 +75,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
"sethome - Sets \"home\"\n" +
"home - Paths towards \"home\" \n" +
"costs - (debug) all movement costs from current location\n" +
"damn - Daniel\n" +
"Go to https://github.com/cabaletta/baritone/blob/master/USAGE.md for more information";
private static final String COMMAND_PREFIX = "#";
"damn - Daniel ";
public ExampleBaritoneControl(Baritone baritone) {
super(baritone);
@@ -88,23 +83,22 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
@Override
public void onSendChatMessage(ChatEvent event) {
String msg = event.getMessage();
if (Baritone.settings().prefixControl.get() && msg.startsWith(COMMAND_PREFIX)) {
if (!runCommand(msg.substring(COMMAND_PREFIX.length()))) {
logDirect("Invalid command");
}
event.cancel(); // always cancel if using prefixControl
return;
}
if (!Baritone.settings().chatControl.get() && !Baritone.settings().removePrefix.get()) {
return;
}
String msg = event.getMessage();
if (Baritone.settings().prefix.get()) {
if (!msg.startsWith("#")) {
return;
}
msg = msg.substring(1);
}
if (runCommand(msg)) {
event.cancel();
}
}
public boolean runCommand(String msg0) { // you may think this can be private, but impcat calls it from .b =)
public boolean runCommand(String msg0) {
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
PathingBehavior pathingBehavior = baritone.getPathingBehavior();
CustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
@@ -117,58 +111,44 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
}
if (msg.equals("baritone") || msg.equals("modifiedsettings") || msg.startsWith("settings m") || msg.equals("modified")) {
logDirect("All settings that have been modified from their default values:");
for (Settings.Setting<?> setting : SettingsUtil.modifiedSettings(Baritone.settings())) {
if (msg.equals("baritone") || msg.equals("settings")) {
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
logDirect(setting.toString());
}
return true;
}
if (msg.startsWith("settings")) {
String rest = msg.substring("settings".length());
try {
int page = Integer.parseInt(rest.trim());
int min = page * 10;
int max = Math.min(Baritone.settings().allSettings.size(), (page + 1) * 10);
logDirect("Settings " + min + " to " + (max - 1) + ":");
for (int i = min; i < max; i++) {
logDirect(Baritone.settings().allSettings.get(i).toString());
}
} catch (Exception ex) { // NumberFormatException | ArrayIndexOutOfBoundsException and probably some others I'm forgetting lol
ex.printStackTrace();
logDirect("All settings:");
for (Settings.Setting<?> setting : Baritone.settings().allSettings) {
logDirect(setting.toString());
}
logDirect("To get one page of ten settings at a time, do settings <num>");
}
return true;
}
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
for (String line : HELP_MSG.split("\n")) {
logDirect(line);
}
return true;
return false;
}
if (msg.contains(" ")) {
String settingName = msg.substring(0, msg.indexOf(' '));
String settingValue = msg.substring(msg.indexOf(' ') + 1);
Settings.Setting setting = Baritone.settings().byLowerName.get(settingName);
if (setting != null) {
if (settingValue.equals("reset")) {
logDirect("Resetting setting " + settingName + " to default value.");
setting.reset();
} else {
String[] data = msg.split(" ");
if (data.length == 2) {
Settings.Setting setting = Baritone.settings().byLowerName.get(data[0]);
if (setting != null) {
try {
SettingsUtil.parseAndApply(Baritone.settings(), settingName, settingValue);
} catch (Exception ex) {
logDirect("Unable to parse setting");
if (setting.value.getClass() == Long.class) {
setting.value = Long.parseLong(data[1]);
}
if (setting.value.getClass() == Integer.class) {
setting.value = Integer.parseInt(data[1]);
}
if (setting.value.getClass() == Double.class) {
setting.value = Double.parseDouble(data[1]);
}
if (setting.value.getClass() == Float.class) {
setting.value = Float.parseFloat(data[1]);
}
} catch (NumberFormatException e) {
logDirect("Unable to parse " + data[1]);
return true;
}
SettingsUtil.save(Baritone.settings());
logDirect(setting.toString());
return true;
}
SettingsUtil.save(Baritone.settings());
logDirect(setting.toString());
return true;
}
}
if (Baritone.settings().byLowerName.containsKey(msg)) {
@@ -178,19 +158,36 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
if (msg.startsWith("goal")) {
String rest = msg.substring(4).trim();
String[] params = msg.substring(4).trim().split(" ");
if (params[0].equals("")) {
params = new String[]{};
}
Goal goal;
if (rest.equals("clear") || rest.equals("none")) {
goal = null;
} else {
String[] params = rest.split(" ");
if (params[0].equals("")) {
params = new String[]{};
}
goal = parseGoal(params);
if (goal == null) {
return true;
try {
switch (params.length) {
case 0:
goal = new GoalBlock(ctx.playerFeet());
break;
case 1:
if (params[0].equals("clear") || params[0].equals("none")) {
goal = null;
} else {
goal = new GoalYLevel(Integer.parseInt(params[0]));
}
break;
case 2:
goal = new GoalXZ(Integer.parseInt(params[0]), Integer.parseInt(params[1]));
break;
case 3:
goal = new GoalBlock(new BlockPos(Integer.parseInt(params[0]), Integer.parseInt(params[1]), Integer.parseInt(params[2])));
break;
default:
logDirect("unable to understand lol");
return true;
}
} catch (NumberFormatException ex) {
logDirect("unable to parse integer " + ex);
return true;
}
customGoalProcess.setGoal(goal);
logDirect("Goal: " + goal);
@@ -225,15 +222,6 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
return true;
}
if (msg.equals("version")) {
String version = ExampleBaritoneControl.class.getPackage().getImplementationVersion();
if (version == null) {
logDirect("No version detected. Either dev environment or broken install.");
} else {
logDirect("You are using Baritone v" + version);
}
return true;
}
if (msg.equals("repack") || msg.equals("rescan")) {
ChunkProviderClient cli = (ChunkProviderClient) ctx.world().getChunkProvider();
int playerChunkX = ctx.playerFeet().getX() >> 4;
@@ -251,12 +239,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Queued " + count + " chunks for repacking");
return true;
}
if (msg.equals("come")) {
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(mc.getRenderViewEntity())));
logDirect("Coming");
return true;
}
if (msg.equals("axis") || msg.equals("highway")) {
if (msg.equals("axis")) {
customGoalProcess.setGoalAndPath(new GoalAxis());
return true;
}
@@ -297,19 +280,10 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
return true;
}
if (msg.equals("reset")) {
for (Settings.Setting setting : Baritone.settings().allSettings) {
setting.reset();
}
SettingsUtil.save(Baritone.settings());
Baritone.settings().reset();
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()) {
@@ -407,17 +381,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
return true;
}
if (msg.equals("click")) {
new Thread(() -> {
try {
Thread.sleep(100);
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClickMeme()));
} catch (Exception ignored) {}
}).start();
logDirect("aight dude");
return true;
}
if (msg.startsWith("thisway") || msg.startsWith("forward")) {
if (msg.startsWith("thisway")) {
try {
Goal goal = GoalXZ.fromDirection(ctx.playerFeetAsVec(), ctx.player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
customGoalProcess.setGoal(goal);
@@ -485,11 +449,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
if (block == null) {
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
if (waypoint == null) {
Goal goal = parseGoal(waypointType.split(" "));
if (goal != null) {
logDirect("Going to " + goal);
customGoalProcess.setGoalAndPath(goal);
}
logDirect("No locations for " + mining + " known, cancelling");
return true;
}
} else {
@@ -568,31 +528,4 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
}
}
private Goal parseGoal(String[] params) {
Goal goal;
try {
switch (params.length) {
case 0:
goal = new GoalBlock(ctx.playerFeet());
break;
case 1:
goal = new GoalYLevel(Integer.parseInt(params[0]));
break;
case 2:
goal = new GoalXZ(Integer.parseInt(params[0]), Integer.parseInt(params[1]));
break;
case 3:
goal = new GoalBlock(new BlockPos(Integer.parseInt(params[0]), Integer.parseInt(params[1]), Integer.parseInt(params[2])));
break;
default:
logDirect("unable to understand lol");
return null;
}
} catch (NumberFormatException ex) {
logDirect("unable to parse integer " + ex);
return null;
}
return goal;
}
}

View File

@@ -1,102 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.api.BaritoneAPI;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalTwoBlocks;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.util.glu.GLU;
import java.awt.*;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Collections;
import static org.lwjgl.opengl.GL11.*;
public class GuiClickMeme extends GuiScreen {
// My name is Brady and I grant Leijurv permission to use this pasted code
private final FloatBuffer MODELVIEW = BufferUtils.createFloatBuffer(16);
private final FloatBuffer PROJECTION = BufferUtils.createFloatBuffer(16);
private final IntBuffer VIEWPORT = BufferUtils.createIntBuffer(16);
private final FloatBuffer TO_SCREEN_BUFFER = BufferUtils.createFloatBuffer(3);
private final FloatBuffer TO_WORLD_BUFFER = BufferUtils.createFloatBuffer(3);
private BlockPos meme;
@Override
public boolean doesGuiPauseGame() {
return false;
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
int mx = Mouse.getX();
int my = Mouse.getY();
Vec3d near = toWorld(mx, my, 0);
Vec3d far = toWorld(mx, my, 1); // "Use 0.945 that's what stack overflow says" - Leijurv
if (near != null && far != null) {
Vec3d viewerPos = new Vec3d(mc.getRenderManager().viewerPosX, mc.getRenderManager().viewerPosY, mc.getRenderManager().viewerPosZ);
RayTraceResult result = mc.world.rayTraceBlocks(near.add(viewerPos), far.add(viewerPos), false, false, true);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
meme = result.getBlockPos();
}
}
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
super.mouseClicked(mouseX, mouseY, mouseButton);
if (mouseButton == 0) {
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalTwoBlocks(meme));
} else if (mouseButton == 1) {
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalBlock(meme.up()));
}
}
public void onRender(float partialTicks) {
GlStateManager.getFloat(GL_MODELVIEW_MATRIX, (FloatBuffer) MODELVIEW.clear());
GlStateManager.getFloat(GL_PROJECTION_MATRIX, (FloatBuffer) PROJECTION.clear());
GlStateManager.glGetInteger(GL_VIEWPORT, (IntBuffer) VIEWPORT.clear());
if (meme != null) {
Entity e = mc.getRenderViewEntity();
// drawSingleSelectionBox WHEN?
PathRenderer.drawManySelectionBoxes(e, Collections.singletonList(meme), Color.CYAN);
}
}
public Vec3d toWorld(double x, double y, double z) {
boolean result = GLU.gluUnProject((float) x, (float) y, (float) z, MODELVIEW, PROJECTION, VIEWPORT, (FloatBuffer) TO_WORLD_BUFFER.clear());
if (result) {
return new Vec3d(TO_WORLD_BUFFER.get(0), TO_WORLD_BUFFER.get(1), TO_WORLD_BUFFER.get(2));
}
return null;
}
}

View File

@@ -1,72 +1,72 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.Baritone;
import net.minecraft.client.Minecraft;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
/**
* @author Brady
* @since 8/1/2018
*/
public interface Helper {
/**
* Instance of {@link Helper}. Used for static-context reference.
*/
Helper HELPER = new Helper() {};
ITextComponent MESSAGE_PREFIX = new TextComponentString(String.format(
"%s[%sBaritone%s]%s",
TextFormatting.DARK_PURPLE,
TextFormatting.LIGHT_PURPLE,
TextFormatting.DARK_PURPLE,
TextFormatting.GRAY
));
Minecraft mc = Minecraft.getMinecraft();
/**
* Send a message to chat only if chatDebug is on
*
* @param message The message to display in chat
*/
default void logDebug(String message) {
if (!Baritone.settings().chatDebug.get()) {
//System.out.println("Suppressed debug message:");
//System.out.println(message);
return;
}
logDirect(message);
}
/**
* Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a direct response to a chat command)
*
* @param message The message to display in chat
*/
default void logDirect(String message) {
ITextComponent component = MESSAGE_PREFIX.createCopy();
component.getStyle().setColor(TextFormatting.GRAY);
component.appendSibling(new TextComponentString(" " + message));
Minecraft.getMinecraft().addScheduledTask(() -> Baritone.settings().logger.get().accept(component));
}
}
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.Baritone;
import net.minecraft.client.Minecraft;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
/**
* @author Brady
* @since 8/1/2018
*/
public interface Helper {
/**
* Instance of {@link Helper}. Used for static-context reference.
*/
Helper HELPER = new Helper() {};
ITextComponent MESSAGE_PREFIX = new TextComponentString(String.format(
"%s[%sBaritone%s]%s",
TextFormatting.DARK_PURPLE,
TextFormatting.LIGHT_PURPLE,
TextFormatting.DARK_PURPLE,
TextFormatting.GRAY
));
Minecraft mc = Minecraft.getMinecraft();
/**
* Send a message to chat only if chatDebug is on
*
* @param message The message to display in chat
*/
default void logDebug(String message) {
if (!Baritone.settings().chatDebug.get()) {
//System.out.println("Suppressed debug message:");
//System.out.println(message);
return;
}
logDirect(message);
}
/**
* Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a direct response to a chat command)
*
* @param message The message to display in chat
*/
default void logDirect(String message) {
ITextComponent component = MESSAGE_PREFIX.createCopy();
component.getStyle().setColor(TextFormatting.GRAY);
component.appendSibling(new TextComponentString(" " + message));
Minecraft.getMinecraft().addScheduledTask(() -> Baritone.settings().logger.get().accept(component));
}
}

View File

@@ -1,118 +1,131 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.TickEvent;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.input.Input;
import baritone.behavior.Behavior;
import net.minecraft.client.Minecraft;
import net.minecraft.util.MovementInputFromOptions;
import java.util.HashMap;
import java.util.Map;
/**
* An interface with the game's control system allowing the ability to
* force down certain controls, having the same effect as if we were actually
* physically forcing down the assigned key.
*
* @author Brady
* @since 7/31/2018
*/
public final class InputOverrideHandler extends Behavior implements IInputOverrideHandler {
/**
* Maps inputs to whether or not we are forcing their state down.
*/
private final Map<Input, Boolean> inputForceStateMap = new HashMap<>();
private final BlockBreakHelper blockBreakHelper;
private final BlockPlaceHelper blockPlaceHelper;
public InputOverrideHandler(Baritone baritone) {
super(baritone);
this.blockBreakHelper = new BlockBreakHelper(baritone.getPlayerContext());
this.blockPlaceHelper = new BlockPlaceHelper(baritone.getPlayerContext());
}
/**
* Returns whether or not we are forcing down the specified {@link Input}.
*
* @param input The input
* @return Whether or not it is being forced down
*/
@Override
public final boolean isInputForcedDown(Input input) {
return input == null ? false : this.inputForceStateMap.getOrDefault(input, false);
}
/**
* Sets whether or not the specified {@link Input} is being forced down.
*
* @param input The {@link Input}
* @param forced Whether or not the state is being forced
*/
@Override
public final void setInputForceState(Input input, boolean forced) {
this.inputForceStateMap.put(input, forced);
}
/**
* Clears the override state for all keys
*/
@Override
public final void clearAllKeys() {
this.inputForceStateMap.clear();
}
@Override
public final void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
return;
}
if (isInputForcedDown(Input.CLICK_LEFT)) {
setInputForceState(Input.CLICK_RIGHT, false);
}
blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
blockPlaceHelper.tick(isInputForcedDown(Input.CLICK_RIGHT));
if (inControl()) {
if (ctx.player().movementInput.getClass() != PlayerMovementInput.class) {
ctx.player().movementInput = new PlayerMovementInput(this);
}
} else {
if (ctx.player().movementInput.getClass() == PlayerMovementInput.class) { // allow other movement inputs that aren't this one, e.g. for a freecam
ctx.player().movementInput = new MovementInputFromOptions(Minecraft.getMinecraft().gameSettings);
}
}
// only set it if it was previously incorrect
// gotta do it this way, or else it constantly thinks you're beginning a double tap W sprint lol
}
private boolean inControl() {
// if we are not primary (a bot) we should set the movementinput even when idle (not pathing)
return baritone.getPathingBehavior().isPathing() || baritone != BaritoneAPI.getProvider().getPrimaryBaritone();
}
public BlockBreakHelper getBlockBreakHelper() {
return blockBreakHelper;
}
}
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.TickEvent;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.input.Input;
import baritone.behavior.Behavior;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.util.MovementInput;
import net.minecraft.util.MovementInputFromOptions;
import java.util.HashMap;
import java.util.Map;
/**
* An interface with the game's control system allowing the ability to
* force down certain controls, having the same effect as if we were actually
* physically forcing down the assigned key.
*
* @author Brady
* @since 7/31/2018
*/
public final class InputOverrideHandler extends Behavior implements IInputOverrideHandler {
/**
* Maps inputs to whether or not we are forcing their state down.
*/
private final Map<Input, Boolean> inputForceStateMap = new HashMap<>();
private final BlockBreakHelper blockBreakHelper;
public InputOverrideHandler(Baritone baritone) {
super(baritone);
this.blockBreakHelper = new BlockBreakHelper(baritone.getPlayerContext());
}
/**
* Returns whether or not we are forcing down the specified {@link KeyBinding}.
*
* @param key The KeyBinding object
* @return Whether or not it is being forced down
*/
@Override
public final Boolean isInputForcedDown(KeyBinding key) {
Input input = Input.getInputForBind(key);
if (input == null || !inControl()) {
return null;
}
if (input == Input.CLICK_LEFT) {
return false;
}
if (input == Input.CLICK_RIGHT) {
return isInputForcedDown(Input.CLICK_RIGHT);
}
return null;
}
/**
* Returns whether or not we are forcing down the specified {@link Input}.
*
* @param input The input
* @return Whether or not it is being forced down
*/
@Override
public final boolean isInputForcedDown(Input input) {
return input == null ? false : this.inputForceStateMap.getOrDefault(input, false);
}
/**
* Sets whether or not the specified {@link Input} is being forced down.
*
* @param input The {@link Input}
* @param forced Whether or not the state is being forced
*/
@Override
public final void setInputForceState(Input input, boolean forced) {
this.inputForceStateMap.put(input, forced);
}
/**
* Clears the override state for all keys
*/
@Override
public final void clearAllKeys() {
this.inputForceStateMap.clear();
}
@Override
public final void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
return;
}
blockBreakHelper.tick(isInputForcedDown(Input.CLICK_LEFT));
MovementInput desired = inControl()
? new PlayerMovementInput(this)
: new MovementInputFromOptions(Minecraft.getMinecraft().gameSettings);
if (ctx.player().movementInput.getClass() != desired.getClass()) {
ctx.player().movementInput = desired; // only set it if it was previously incorrect
// gotta do it this way, or else it constantly thinks you're beginning a double tap W sprint lol
}
}
private boolean inControl() {
return baritone.getPathingBehavior().isPathing() || baritone != BaritoneAPI.getProvider().getPrimaryBaritone();
}
public BlockBreakHelper getBlockBreakHelper() {
return blockBreakHelper;
}
}

View File

@@ -57,11 +57,10 @@ public final class PathRenderer implements Helper {
private PathRenderer() {}
public static void render(RenderEvent event, PathingBehavior behavior) {
// System.out.println("Render passing");
// System.out.println(event.getPartialTicks());
float partialTicks = event.getPartialTicks();
Goal goal = behavior.getGoal();
if (mc.currentScreen instanceof GuiClickMeme) {
((GuiClickMeme) mc.currentScreen).onRender(partialTicks);
}
int thisPlayerDimension = behavior.baritone.getPlayerContext().world().provider.getDimensionType().getId();
int currentRenderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId();
@@ -81,7 +80,7 @@ public final class PathRenderer implements Helper {
}
if (goal != null && Baritone.settings().renderGoal.value) {
drawDankLitGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.get());
drawLitDankGoalBox(renderView, goal, partialTicks, Baritone.settings().colorGoalBox.get());
}
if (!Baritone.settings().renderPath.get()) {
return;
@@ -105,9 +104,9 @@ public final class PathRenderer implements Helper {
//long split = System.nanoTime();
if (current != null) {
drawManySelectionBoxes(renderView, current.toBreak(), Baritone.settings().colorBlocksToBreak.get());
drawManySelectionBoxes(renderView, current.toPlace(), Baritone.settings().colorBlocksToPlace.get());
drawManySelectionBoxes(renderView, current.toWalkInto(), Baritone.settings().colorBlocksToWalkInto.get());
drawManySelectionBoxes(renderView, current.toBreak(), partialTicks, Baritone.settings().colorBlocksToBreak.get());
drawManySelectionBoxes(renderView, current.toPlace(), partialTicks, Baritone.settings().colorBlocksToPlace.get());
drawManySelectionBoxes(renderView, current.toWalkInto(), partialTicks, Baritone.settings().colorBlocksToWalkInto.get());
}
// If there is a path calculation currently running, render the path calculation process
@@ -118,7 +117,7 @@ public final class PathRenderer implements Helper {
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
drawPath(mr, 0, renderView, partialTicks, Baritone.settings().colorMostRecentConsidered.get(), Baritone.settings().fadePath.get(), 10, 20);
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), Baritone.settings().colorMostRecentConsidered.get());
drawManySelectionBoxes(renderView, Collections.singletonList(mr.getDest()), partialTicks, Baritone.settings().colorMostRecentConsidered.get());
});
});
//long end = System.nanoTime();
@@ -175,7 +174,7 @@ public final class PathRenderer implements Helper {
}
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], alpha);
}
drawLine(player, x1, y1, z1, x2, y2, z2);
drawLine(player, x1, y1, z1, x2, y2, z2, partialTicks);
tessellator.draw();
}
if (Baritone.settings().renderPathIgnoreDepth.get()) {
@@ -187,10 +186,10 @@ public final class PathRenderer implements Helper {
GlStateManager.disableBlend();
}
public static void drawLine(Entity player, double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z) {
double d0 = mc.getRenderManager().viewerPosX;
double d1 = mc.getRenderManager().viewerPosY;
double d2 = mc.getRenderManager().viewerPosZ;
public static void drawLine(Entity player, double bp1x, double bp1y, double bp1z, double bp2x, double bp2y, double bp2z, float partialTicks) {
double d0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double) partialTicks;
double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double) partialTicks;
double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double) partialTicks;
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
BUFFER.pos(bp2x + 0.5D - d0, bp2y + 0.5D - d1, bp2z + 0.5D - d2).endVertex();
@@ -199,7 +198,7 @@ public final class PathRenderer implements Helper {
BUFFER.pos(bp1x + 0.5D - d0, bp1y + 0.5D - d1, bp1z + 0.5D - d2).endVertex();
}
public static void drawManySelectionBoxes(Entity player, Collection<BlockPos> positions, Color color) {
public static void drawManySelectionBoxes(Entity player, Collection<BlockPos> positions, float partialTicks, Color color) {
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GlStateManager.color(color.getColorComponents(null)[0], color.getColorComponents(null)[1], color.getColorComponents(null)[2], 0.4F);
@@ -213,16 +212,19 @@ public final class PathRenderer implements Helper {
float expand = 0.002F;
//BlockPos blockpos = movingObjectPositionIn.getBlockPos();
BlockStateInterface bsi = new BlockStateInterface(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext()); // TODO this assumes same dimension between primary baritone and render view? is this safe?
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;
positions.forEach(pos -> {
IBlockState state = bsi.get0(pos);
IBlockState state = BlockStateInterface.get(BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext(), pos);
AxisAlignedBB toDraw;
if (state.getBlock().equals(Blocks.AIR)) {
toDraw = Blocks.DIRT.getDefaultState().getSelectedBoundingBox(player.world, pos);
} else {
toDraw = state.getSelectedBoundingBox(player.world, pos);
}
toDraw = toDraw.expand(expand, expand, expand).offset(-mc.getRenderManager().viewerPosX, -mc.getRenderManager().viewerPosY, -mc.getRenderManager().viewerPosZ);
toDraw = toDraw.expand(expand, expand, expand).offset(-renderPosX, -renderPosY, -renderPosZ);
BUFFER.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION);
BUFFER.pos(toDraw.minX, toDraw.minY, toDraw.minZ).endVertex();
BUFFER.pos(toDraw.maxX, toDraw.minY, toDraw.minZ).endVertex();
@@ -258,10 +260,11 @@ public final class PathRenderer implements Helper {
GlStateManager.disableBlend();
}
public static void drawDankLitGoalBox(Entity player, Goal goal, float partialTicks, Color color) {
double renderPosX = mc.getRenderManager().viewerPosX;
double renderPosY = mc.getRenderManager().viewerPosY;
double renderPosZ = mc.getRenderManager().viewerPosZ;
public static void drawLitDankGoalBox(Entity player, Goal goal, float partialTicks, Color color) {
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;
double minX;
double maxX;
double minZ;
@@ -293,8 +296,6 @@ public final class PathRenderer implements Helper {
GoalXZ goalPos = (GoalXZ) goal;
if (Baritone.settings().renderGoalXZBeacon.get()) {
glPushAttrib(GL_LIGHTING_BIT);
mc.getTextureManager().bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
if (Baritone.settings().renderGoalIgnoreDepth.get()) {
@@ -316,8 +317,6 @@ public final class PathRenderer implements Helper {
if (Baritone.settings().renderGoalIgnoreDepth.get()) {
GlStateManager.enableDepth();
}
glPopAttrib();
return;
}
@@ -332,7 +331,7 @@ public final class PathRenderer implements Helper {
maxY = 256 - renderPosY;
} else if (goal instanceof GoalComposite) {
for (Goal g : ((GoalComposite) goal).goals()) {
drawDankLitGoalBox(player, g, partialTicks, color);
drawLitDankGoalBox(player, g, partialTicks, color);
}
return;
} else {

View File

@@ -82,7 +82,6 @@ public class PathingControlManager implements IPathingControlManager {
public void preTick() {
inControlLastTick = inControlThisTick;
inControlThisTick = null;
PathingBehavior p = baritone.getPathingBehavior();
command = executeProcesses();
if (command == null) {

View File

@@ -31,7 +31,7 @@ public class PlayerMovementInput extends MovementInput {
this.moveStrafe = 0.0F;
this.moveForward = 0.0F;
jump = handler.isInputForcedDown(Input.JUMP); // oppa gangnam
jump = handler.isInputForcedDown(Input.JUMP); // oppa
if (this.forwardKeyDown = handler.isInputForcedDown(Input.MOVE_FORWARD)) {
this.moveForward++;

View File

@@ -135,7 +135,6 @@ 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,7 +17,6 @@
package baritone.utils.pathing;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
@@ -28,9 +27,6 @@ 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

@@ -21,14 +21,13 @@ import baritone.api.BaritoneAPI;
import baritone.api.cache.IWorldData;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.IPlayerController;
import baritone.api.utils.RayTraceUtils;
import baritone.utils.Helper;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
/**
* Implementation of {@link IPlayerContext} that provides information about the primary player.
* Implementation of {@link IPlayerContext} that provides information about the local player.
*
* @author Brady
* @since 11/12/2018
@@ -59,6 +58,6 @@ public enum PrimaryPlayerContext implements IPlayerContext, Helper {
@Override
public RayTraceResult objectMouseOver() {
return RayTraceUtils.rayTraceTowards(player(), playerRotations(), playerController().getBlockReachDistance());
return mc.objectMouseOver;
}
}

View File

@@ -19,22 +19,14 @@ package baritone.utils.player;
import baritone.api.utils.IPlayerController;
import baritone.utils.Helper;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
/**
* Implementation of {@link IPlayerController} that chains to the primary player controller's methods
*
* @author Brady
* @since 12/14/2018
*/
@@ -66,10 +58,4 @@ public enum PrimaryPlayerController implements IPlayerController, Helper {
public GameType getGameType() {
return mc.playerController.getCurrentGameType();
}
@Override
public EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand) {
// primaryplayercontroller is always in a WorldClient so this is ok
return mc.playerController.processRightClickBlock(player, (WorldClient) world, pos, direction, vec, hand);
}
}