Compare commits
213 Commits
v1.0.0-hotfix-4
...
tenor
| Author | SHA1 | Date | |
|---|---|---|---|
| 060741bfdc | |||
| 2a21a1ca18 | |||
| 8ece179912 | |||
| c79f40a5f1 | |||
| 3b7e1adf24 | |||
| 01bec5d8f9 | |||
| 82c64d4d06 | |||
| 11e44acf65 | |||
| c73751ef98 | |||
| 16fec4a1a0 | |||
| 81c95a2d43 | |||
| 07970f803f | |||
| 5ae4f23886 | |||
| f222980a1a | |||
| 7f1fb2a8fe | |||
| c57f65f832 | |||
| 85a6ec022e | |||
| c1032da828 | |||
| 9c5274dde4 | |||
| 002c678b4a | |||
| 806c2a4af1 | |||
| 038533c33f | |||
| 50d4b5b4ed | |||
| 7632d667c9 | |||
| c5ecb9bb9b | |||
| e0d894d296 | |||
| 27c818f873 | |||
| fdd758bc90 | |||
| 3a2620192b | |||
| c423d5f575 | |||
| 5aa78cd478 | |||
| 84cd4b1acb | |||
| b705279153 | |||
| d854750ee8 | |||
| 81a9b71429 | |||
| 4502adda28 | |||
| a98c5d7d99 | |||
| c81a00268a | |||
| dd47e20070 | |||
| 81ecc209d3 | |||
| f05613147e | |||
| 6ed8d617cd | |||
| b228f4c6fb | |||
| 70f8d1d4ae | |||
| 0d7131413a | |||
| b5a4e65fbf | |||
| 7c51106d27 | |||
| 1e9786d5b9 | |||
| 4b8c85f8a6 | |||
| aed8dae175 | |||
| 8db26af36c | |||
| cfa874982c | |||
| 2a674cb869 | |||
| fb971301a4 | |||
| 3bb16de67e | |||
| 033da7e737 | |||
| 14650f93c5 | |||
| e5184efdaa | |||
| d95a72f2cc | |||
| 0dc67593bb | |||
| 2e180e81ed | |||
| 0b11057449 | |||
| 16e3fd9305 | |||
| 186652a8d8 | |||
| 18d8cfb6de | |||
| 4fb6c71174 | |||
| f99befd307 | |||
| 9ad35dbf28 | |||
| dfb49179c5 | |||
| 3c913a7b85 | |||
| f01cf669e8 | |||
| 2d87033f49 | |||
| f014e42aa4 | |||
| 12bbd57a24 | |||
| 46de72e28c | |||
| 689dc74330 | |||
| 6caae889b7 | |||
| ce0e8b4cd1 | |||
| 737c632227 | |||
| 04e87c9810 | |||
| 57c0613843 | |||
| f5d0143b09 | |||
| 237f1846d3 | |||
| f6dee1ecb7 | |||
| f808fc9802 | |||
| 8385bc35ed | |||
| 80d6d7fd58 | |||
| b56cdcda52 | |||
| ea81cd76ca | |||
| c3a3670785 | |||
| e4045e1343 | |||
| 5a52cea415 | |||
| 933b295c40 | |||
| ce6ec00a89 | |||
| b53f3925a4 | |||
| e93fd596ff | |||
| 57b60c734b | |||
| c74ccaafbf | |||
| f6891feb64 | |||
| 2675852dbe | |||
| 0302c6f14b | |||
| a0dd43244c | |||
| 3ccb0c74c6 | |||
| f9270a7ed0 | |||
| d79d56c2f9 | |||
| a8f09a7fe9 | |||
| 94bf8d4bbd | |||
| 5e2f40a322 | |||
| 17161fd576 | |||
| d3db551cc9 | |||
| 72058c792a | |||
| ef5e3ab06e | |||
| 71e7f0a04c | |||
| bae34e5b80 | |||
| 1ab3e61984 | |||
| e81b6d4d96 | |||
| 87a44e4093 | |||
| d082d25253 | |||
| 83f14b10bb | |||
| 7fecd1a5dd | |||
| 0ce4107d56 | |||
| 66769365d0 | |||
| e3cb164723 | |||
| 903b1b16a4 | |||
| e81d0a0b1b | |||
| 51243f0981 | |||
| fad5a6deac | |||
| 355443e440 | |||
| 45e4239b26 | |||
| a83074e773 | |||
| f854d886d1 | |||
| 73d4e9bbb9 | |||
| 232644feb0 | |||
| 1c80950a70 | |||
| 0bd46e88a5 | |||
| b054e9dbe8 | |||
| 3ddf6b2335 | |||
| 1a1686b7c3 | |||
| dd08b2c825 | |||
| a2a60e9847 | |||
| 13505a052f | |||
| f2dcdda9b3 | |||
| 1cf6768e27 | |||
| dc6389c46f | |||
| 7dc89b0190 | |||
| 5b395ce3da | |||
| 40da7b3734 | |||
| 842e50adb9 | |||
| 96da078219 | |||
| 4a1951b027 | |||
| 83348e6b3c | |||
| a1778f401f | |||
| 9c93d3a474 | |||
| cbc8a6d45b | |||
| 382c7e7888 | |||
| ae200a56b0 | |||
| c50af5acfd | |||
| 527691a2ec | |||
| a182c22d36 | |||
| aac0d623fa | |||
| 604ef2bb64 | |||
| 6ca7f47bf9 | |||
| a1b71219cb | |||
| d59c7cb7a8 | |||
| d121ca182f | |||
| 2aee91be10 | |||
| 99da815f49 | |||
| ebd3ce42d0 | |||
| fdee1b9453 | |||
| 472e89239c | |||
| 5692e79e02 | |||
| 52246e41c8 | |||
| 2da3222115 | |||
| 4d0bfce712 | |||
| cb153e039b | |||
| 8aa5a6756a | |||
| 23286dd8b8 | |||
| 30408384c6 | |||
| e11e3dfd86 | |||
| 2c39cd06ed | |||
| 75a224cef1 | |||
| 0373f1875f | |||
| fffd016008 | |||
| f286c400a3 | |||
| c0e0f8dc2a | |||
| ffb044ffc6 | |||
| 1c4f029bf4 | |||
| 6812d2ba7d | |||
| c0b5d60715 | |||
| c814874cb6 | |||
| cd3aef47a5 | |||
| 338fdb509a | |||
| 660efe5e16 | |||
| 58a2965fea | |||
| e017238aca | |||
| 890dbec852 | |||
| 24bb0c541c | |||
| e7a09c34ea | |||
| 9642950b54 | |||
| f76736a378 | |||
| 91c6baead1 | |||
| e81b01a8f3 | |||
| f2a45b9eeb | |||
| 5e2ccdac08 | |||
| 473f872d2f | |||
| 3d03f15749 | |||
| 15e91c7c7c | |||
| 5089c62ada | |||
| 7c69a188f6 | |||
| ef6b36b2cc | |||
| f2f806669c | |||
| c887b27df9 | |||
| e1bb8fd570 |
+36
@@ -0,0 +1,36 @@
|
|||||||
|
# Baritone Comms Protocol
|
||||||
|
|
||||||
|
## Data Types
|
||||||
|
|
||||||
|
| Name | Descriptor | Java |
|
||||||
|
|------------|-----------------------------------------------------------|-----------------------------|
|
||||||
|
| coordinate | Big endian 8-byte floating point number | [readDouble], [writeDouble] |
|
||||||
|
| string | unsigned short (length) followed by UTF-8 character bytes | [readUTF], [writeUTF] |
|
||||||
|
|
||||||
|
## Inbound
|
||||||
|
|
||||||
|
Allows the server to execute a chat command on behalf of the client's player
|
||||||
|
|
||||||
|
### Chat
|
||||||
|
|
||||||
|
| Name | Type |
|
||||||
|
|---------|--------|
|
||||||
|
| Message | string |
|
||||||
|
|
||||||
|
## Outbound
|
||||||
|
|
||||||
|
Update the player position with the server
|
||||||
|
|
||||||
|
### Status
|
||||||
|
|
||||||
|
| Name | Type |
|
||||||
|
|------|------------|
|
||||||
|
| X | coordinate |
|
||||||
|
| Y | coordinate |
|
||||||
|
| Z | coordinate |
|
||||||
|
|
||||||
|
<!-- External links -->
|
||||||
|
[readUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readUTF()
|
||||||
|
[writeUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeUTF(java.lang.String)
|
||||||
|
[readDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readDouble()
|
||||||
|
[writeDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeDouble(double)
|
||||||
@@ -7,11 +7,13 @@
|
|||||||
[](https://github.com/cabaletta/baritone/issues)
|
[](https://github.com/cabaletta/baritone/issues)
|
||||||
[](https://minecraft.gamepedia.com/1.12.2)
|
[](https://minecraft.gamepedia.com/1.12.2)
|
||||||
|
|
||||||
A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
A Minecraft pathfinder bot.
|
||||||
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
|
||||||
|
|
||||||
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
|
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
|
||||||
|
|
||||||
|
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||||
|
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||||
|
|
||||||
Here are some links to help to get started:
|
Here are some links to help to get started:
|
||||||
|
|
||||||
- [Features](FEATURES.md)
|
- [Features](FEATURES.md)
|
||||||
@@ -36,12 +38,11 @@ Building Baritone:
|
|||||||
$ gradlew build
|
$ gradlew build
|
||||||
```
|
```
|
||||||
|
|
||||||
For example, to replace out Impact 4.4's Baritone build with a customized one, build Baritone as above then copy `dist/baritone-api-$VERSION.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
|
For example, 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
|
## IntelliJ's Gradle UI
|
||||||
- Open the project in IntelliJ as a Gradle project
|
- Open the project in IntelliJ as a Gradle project
|
||||||
- Run the Gradle task `setupDecompWorkspace`
|
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
|
||||||
- Run the Gradle task `genIntellijRuns`
|
|
||||||
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
|
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
|
||||||
- Select the "Minecraft Client" launch config
|
- Select the "Minecraft Client" launch config
|
||||||
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
|
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
|
||||||
@@ -57,13 +58,12 @@ Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actu
|
|||||||
BaritoneAPI.getSettings().allowSprint.value = true;
|
BaritoneAPI.getSettings().allowSprint.value = true;
|
||||||
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
|
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
|
||||||
|
|
||||||
BaritoneAPI.getPathingBehavior().setGoal(new GoalXZ(10000, 20000));
|
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
|
||||||
BaritoneAPI.getPathingBehavior().path();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
|
|
||||||
## Can I use Baritone as a library in my hacked client?
|
## Can I use Baritone as a library in my custom utility client?
|
||||||
|
|
||||||
Sure! (As long as usage is in compliance with the LGPL 3 License)
|
Sure! (As long as usage is in compliance with the LGPL 3 License)
|
||||||
|
|
||||||
|
|||||||
+12
-2
@@ -51,14 +51,24 @@ compileJava {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
comms {}
|
||||||
|
main {
|
||||||
|
compileClasspath += comms.compileClasspath + comms.output
|
||||||
|
}
|
||||||
launch {
|
launch {
|
||||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||||
}
|
}
|
||||||
|
tenor {
|
||||||
|
compileClasspath += comms.compileClasspath + comms.output
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
compileClasspath += tenor.compileClasspath + tenor.output
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
version = '1.12.2'
|
version = '1.12.2'
|
||||||
mappings = 'snapshot_20180731'
|
mappings = 'stable_39'
|
||||||
tweakClass = 'baritone.launch.BaritoneTweaker'
|
tweakClass = 'baritone.launch.BaritoneTweaker'
|
||||||
runDir = 'run'
|
runDir = 'run'
|
||||||
|
|
||||||
@@ -99,7 +109,7 @@ mixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
from sourceSets.launch.output, sourceSets.api.output
|
from sourceSets.comms.output, sourceSets.launch.output, sourceSets.api.output
|
||||||
preserveFileTimestamps = false
|
preserveFileTimestamps = false
|
||||||
reproducibleFileOrder = true
|
reproducibleFileOrder = true
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -19,7 +19,7 @@
|
|||||||
-keep class baritone.api.IBaritoneProvider
|
-keep class baritone.api.IBaritoneProvider
|
||||||
|
|
||||||
# hack
|
# hack
|
||||||
-keep class baritone.utils.ExampleBaritoneControl { *; }
|
-keep class baritone.utils.ExampleBaritoneControl { *; } # have to include this string to remove this keep in the standalone build: # this is the keep api
|
||||||
|
|
||||||
# setting names are reflected from field names, so keep field names
|
# setting names are reflected from field names, so keep field names
|
||||||
-keepclassmembers class baritone.api.Settings {
|
-keepclassmembers class baritone.api.Settings {
|
||||||
|
|||||||
@@ -17,10 +17,6 @@
|
|||||||
|
|
||||||
package baritone.api;
|
package baritone.api;
|
||||||
|
|
||||||
import baritone.api.behavior.*;
|
|
||||||
import baritone.api.cache.IWorldProvider;
|
|
||||||
import baritone.api.cache.IWorldScanner;
|
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
|
||||||
import baritone.api.utils.SettingsUtil;
|
import baritone.api.utils.SettingsUtil;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -36,51 +32,23 @@ import java.util.ServiceLoader;
|
|||||||
*/
|
*/
|
||||||
public final class BaritoneAPI {
|
public final class BaritoneAPI {
|
||||||
|
|
||||||
private static final IBaritoneProvider baritone;
|
private static final IBaritoneProvider provider;
|
||||||
private static final Settings settings;
|
private static final Settings settings;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
|
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
|
||||||
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();
|
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();
|
||||||
baritone = instances.next();
|
provider = instances.next();
|
||||||
|
|
||||||
settings = new Settings();
|
settings = new Settings();
|
||||||
SettingsUtil.readAndApply(settings);
|
SettingsUtil.readAndApply(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IFollowBehavior getFollowBehavior() {
|
public static IBaritoneProvider getProvider() {
|
||||||
return baritone.getFollowBehavior();
|
return BaritoneAPI.provider;
|
||||||
}
|
|
||||||
|
|
||||||
public static ILookBehavior getLookBehavior() {
|
|
||||||
return baritone.getLookBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IMemoryBehavior getMemoryBehavior() {
|
|
||||||
return baritone.getMemoryBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IMineBehavior getMineBehavior() {
|
|
||||||
return baritone.getMineBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IPathingBehavior getPathingBehavior() {
|
|
||||||
return baritone.getPathingBehavior();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Settings getSettings() {
|
public static Settings getSettings() {
|
||||||
return settings;
|
return BaritoneAPI.settings;
|
||||||
}
|
|
||||||
|
|
||||||
public static IWorldProvider getWorldProvider() {
|
|
||||||
return baritone.getWorldProvider();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IWorldScanner getWorldScanner() {
|
|
||||||
return baritone.getWorldScanner();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void registerEventListener(IGameEventListener listener) {
|
|
||||||
baritone.registerEventListener(listener);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import baritone.api.behavior.ILookBehavior;
|
||||||
|
import baritone.api.behavior.IMemoryBehavior;
|
||||||
|
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.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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 9/29/2018
|
||||||
|
*/
|
||||||
|
public interface IBaritone {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IFollowProcess} instance
|
||||||
|
* @see IFollowProcess
|
||||||
|
*/
|
||||||
|
IFollowProcess getFollowProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link ILookBehavior} instance
|
||||||
|
* @see ILookBehavior
|
||||||
|
*/
|
||||||
|
ILookBehavior getLookBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IMemoryBehavior} instance
|
||||||
|
* @see IMemoryBehavior
|
||||||
|
*/
|
||||||
|
IMemoryBehavior getMemoryBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IMineProcess} instance
|
||||||
|
* @see IMineProcess
|
||||||
|
*/
|
||||||
|
IMineProcess getMineProcess();
|
||||||
|
|
||||||
|
IPathingControlManager getPathingControlManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IPathingBehavior} instance
|
||||||
|
* @see IPathingBehavior
|
||||||
|
*/
|
||||||
|
IPathingBehavior getPathingBehavior();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IWorldProvider} instance
|
||||||
|
* @see IWorldProvider
|
||||||
|
*/
|
||||||
|
IWorldProvider getWorldProvider();
|
||||||
|
|
||||||
|
IInputOverrideHandler getInputOverrideHandler();
|
||||||
|
|
||||||
|
ICustomGoalProcess getCustomGoalProcess();
|
||||||
|
|
||||||
|
IGetToBlockProcess getGetToBlockProcess();
|
||||||
|
|
||||||
|
IPlayerContext getPlayerContext();
|
||||||
|
|
||||||
|
IEventBus getGameEventHandler();
|
||||||
|
}
|
||||||
@@ -17,70 +17,55 @@
|
|||||||
|
|
||||||
package baritone.api;
|
package baritone.api;
|
||||||
|
|
||||||
import baritone.api.behavior.*;
|
|
||||||
import baritone.api.cache.IWorldProvider;
|
|
||||||
import baritone.api.cache.IWorldScanner;
|
import baritone.api.cache.IWorldScanner;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Leijurv
|
||||||
* @since 9/29/2018
|
|
||||||
*/
|
*/
|
||||||
public interface IBaritoneProvider {
|
public interface IBaritoneProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see IFollowBehavior
|
* Returns the primary {@link IBaritone} instance. This instance is persistent, and
|
||||||
|
* is represented by the local player that is created by the game itself, not a "bot"
|
||||||
|
* player through Baritone.
|
||||||
*
|
*
|
||||||
* @return The {@link IFollowBehavior} instance
|
* @return The primary {@link IBaritone} instance.
|
||||||
*/
|
*/
|
||||||
IFollowBehavior getFollowBehavior();
|
IBaritone getPrimaryBaritone();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ILookBehavior
|
* Returns all of the active {@link IBaritone} instances. This includes the local one
|
||||||
|
* returned by {@link #getPrimaryBaritone()}.
|
||||||
*
|
*
|
||||||
* @return The {@link ILookBehavior} instance
|
* @return All active {@link IBaritone} instances.
|
||||||
|
* @see #getBaritoneForPlayer(EntityPlayerSP)
|
||||||
*/
|
*/
|
||||||
ILookBehavior getLookBehavior();
|
List<IBaritone> getAllBaritones();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see IMemoryBehavior
|
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
|
||||||
|
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
|
||||||
*
|
*
|
||||||
* @return The {@link IMemoryBehavior} instance
|
* @param player The player
|
||||||
|
* @return The {@link IBaritone} instance.
|
||||||
*/
|
*/
|
||||||
IMemoryBehavior getMemoryBehavior();
|
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
|
||||||
|
for (IBaritone baritone : getAllBaritones()) {
|
||||||
|
if (player.equals(baritone.getPlayerContext().player())) {
|
||||||
|
return baritone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("No baritone for player " + player);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see IMineBehavior
|
* Returns the {@link IWorldScanner} instance. This is not a type returned by
|
||||||
|
* {@link IBaritone} implementation, because it is not linked with {@link IBaritone}.
|
||||||
*
|
*
|
||||||
* @return The {@link IMineBehavior} instance
|
* @return The {@link IWorldScanner} instance.
|
||||||
*/
|
|
||||||
IMineBehavior getMineBehavior();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IPathingBehavior
|
|
||||||
*
|
|
||||||
* @return The {@link IPathingBehavior} instance
|
|
||||||
*/
|
|
||||||
IPathingBehavior getPathingBehavior();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IWorldProvider
|
|
||||||
*
|
|
||||||
* @return The {@link IWorldProvider} instance
|
|
||||||
*/
|
|
||||||
IWorldProvider getWorldProvider();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see IWorldScanner
|
|
||||||
*
|
|
||||||
* @return The {@link IWorldScanner} instance
|
|
||||||
*/
|
*/
|
||||||
IWorldScanner getWorldScanner();
|
IWorldScanner getWorldScanner();
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a {@link IGameEventListener} with Baritone's "event bus".
|
|
||||||
*
|
|
||||||
* @param listener The listener
|
|
||||||
*/
|
|
||||||
void registerEventListener(IGameEventListener listener);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import net.minecraft.util.text.ITextComponent;
|
|||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.List;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,14 +247,28 @@ public class Settings {
|
|||||||
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
|
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pathing can never take longer than this
|
* Pathing ends after this amount of time, but only if a path has been found
|
||||||
|
* <p>
|
||||||
|
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
|
||||||
*/
|
*/
|
||||||
public Setting<Long> pathTimeoutMS = new Setting<>(2000L);
|
public Setting<Long> primaryTimeoutMS = new Setting<>(500L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Planning ahead while executing a segment can never take longer than this
|
* Pathing can never take longer than this, even if that means failing to find any path at all
|
||||||
*/
|
*/
|
||||||
public Setting<Long> planAheadTimeoutMS = new Setting<>(4000L);
|
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 Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all
|
||||||
|
*/
|
||||||
|
public Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For debugging, consider nodes much much slower
|
* For debugging, consider nodes much much slower
|
||||||
@@ -276,6 +290,13 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public 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 issue #248
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print all the debug messages to chat
|
* Print all the debug messages to chat
|
||||||
*/
|
*/
|
||||||
@@ -305,17 +326,17 @@ public class Settings {
|
|||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the goal
|
* Ignore depth when rendering the goal
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(false);
|
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
|
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(false);
|
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore depth when rendering the path
|
* Ignore depth when rendering the path
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(false);
|
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Line width of the path when rendered, in pixels
|
* Line width of the path when rendered, in pixels
|
||||||
@@ -370,12 +391,27 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
|
||||||
|
*/
|
||||||
|
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the current path is too long, cut off this many movements from the beginning.
|
||||||
|
*/
|
||||||
|
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rescan for the goal once every 5 ticks.
|
* Rescan for the goal once every 5 ticks.
|
||||||
* Set to 0 to disable.
|
* Set to 0 to disable.
|
||||||
*/
|
*/
|
||||||
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
||||||
|
*/
|
||||||
|
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -389,7 +425,7 @@ public class Settings {
|
|||||||
* <p>
|
* <p>
|
||||||
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
|
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
|
||||||
*/
|
*/
|
||||||
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(false);
|
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
||||||
|
|||||||
@@ -18,10 +18,9 @@
|
|||||||
package baritone.api.behavior;
|
package baritone.api.behavior;
|
||||||
|
|
||||||
import baritone.api.event.listener.AbstractGameEventListener;
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
import baritone.api.utils.interfaces.Toggleable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
*/
|
*/
|
||||||
public interface IBehavior extends AbstractGameEventListener, Toggleable {}
|
public interface IBehavior extends AbstractGameEventListener {}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public interface ILookBehavior extends IBehavior {
|
|||||||
* otherwise, it should be {@code false};
|
* otherwise, it should be {@code false};
|
||||||
*
|
*
|
||||||
* @param rotation The target rotations
|
* @param rotation The target rotations
|
||||||
* @param force Whether or not to "force" the rotations
|
* @param force Whether or not to "force" the rotations
|
||||||
*/
|
*/
|
||||||
void updateTarget(Rotation rotation, boolean force);
|
void updateTarget(Rotation rotation, boolean force);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,35 +39,25 @@ public interface IPathingBehavior extends IBehavior {
|
|||||||
*/
|
*/
|
||||||
Optional<Double> ticksRemainingInSegment();
|
Optional<Double> ticksRemainingInSegment();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the pathing goal.
|
|
||||||
*
|
|
||||||
* @param goal The pathing goal
|
|
||||||
*/
|
|
||||||
void setGoal(Goal goal);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The current pathing goal
|
* @return The current pathing goal
|
||||||
*/
|
*/
|
||||||
Goal getGoal();
|
Goal getGoal();
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins pathing. Calculation will start in a new thread, and once completed,
|
|
||||||
* movement will commence. Returns whether or not the operation was successful.
|
|
||||||
*
|
|
||||||
* @return Whether or not the operation was successful
|
|
||||||
*/
|
|
||||||
boolean path();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Whether or not a path is currently being executed.
|
* @return Whether or not a path is currently being executed.
|
||||||
*/
|
*/
|
||||||
boolean isPathing();
|
boolean isPathing();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the pathing behavior or the current path calculation.
|
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
|
||||||
|
* <p>
|
||||||
|
* Basically, "MAKE IT STOP".
|
||||||
|
*
|
||||||
|
* @return Whether or not the pathing behavior was canceled. All processes are guaranteed to be canceled, but the
|
||||||
|
* PathingBehavior might be in the middle of an uncancelable action like a parkour jump
|
||||||
*/
|
*/
|
||||||
void cancel();
|
boolean cancelEverything();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current path, from the current path executor, if there is one.
|
* Returns the current path, from the current path executor, if there is one.
|
||||||
@@ -81,7 +71,7 @@ public interface IPathingBehavior extends IBehavior {
|
|||||||
/**
|
/**
|
||||||
* @return The current path finder being executed
|
* @return The current path finder being executed
|
||||||
*/
|
*/
|
||||||
Optional<IPathFinder> getPathFinder();
|
Optional<? extends IPathFinder> getInProgress();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The current path executor
|
* @return The current path executor
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 2:01 AM
|
* @since 8/4/2018
|
||||||
*/
|
*/
|
||||||
public interface IBlockTypeAccess {
|
public interface IBlockTypeAccess {
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -29,11 +29,10 @@ public interface ICachedRegion extends IBlockTypeAccess {
|
|||||||
* however, the block coordinates should in on a scale from 0 to 511 (inclusive)
|
* however, the block coordinates should in on a scale from 0 to 511 (inclusive)
|
||||||
* because region sizes are 512x512 blocks.
|
* because region sizes are 512x512 blocks.
|
||||||
*
|
*
|
||||||
* @see ICachedWorld#isCached(int, int)
|
|
||||||
*
|
|
||||||
* @param blockX The block X coordinate
|
* @param blockX The block X coordinate
|
||||||
* @param blockZ The block Z coordinate
|
* @param blockZ The block Z coordinate
|
||||||
* @return Whether or not the specified XZ location is cached
|
* @return Whether or not the specified XZ location is cached
|
||||||
|
* @see ICachedWorld#isCached(int, int)
|
||||||
*/
|
*/
|
||||||
boolean isCached(int blockX, int blockZ);
|
boolean isCached(int blockX, int blockZ);
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -61,12 +61,14 @@ public interface ICachedWorld {
|
|||||||
* information that is returned by this method may not be up to date, because
|
* information that is returned by this method may not be up to date, because
|
||||||
* older cached chunks can contain data that is much more likely to have changed.
|
* older cached chunks can contain data that is much more likely to have changed.
|
||||||
*
|
*
|
||||||
* @param block The special block to search for
|
* @param block The special block to search for
|
||||||
* @param maximum The maximum number of position results to receive
|
* @param maximum The maximum number of position results to receive
|
||||||
|
* @param centerX The x block coordinate center of the search
|
||||||
|
* @param centerZ The z block coordinate center of the search
|
||||||
* @param maxRegionDistanceSq The maximum region distance, squared
|
* @param maxRegionDistanceSq The maximum region distance, squared
|
||||||
* @return The locations found that match the special block
|
* @return The locations found that match the special block
|
||||||
*/
|
*/
|
||||||
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq);
|
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads all of the cached regions in this world from disk. Anything that is not saved
|
* Reloads all of the cached regions in this world from disk. Anything that is not saved
|
||||||
|
|||||||
@@ -50,19 +50,17 @@ public interface IWaypointCollection {
|
|||||||
/**
|
/**
|
||||||
* Gets all of the waypoints that have the specified tag
|
* Gets all of the waypoints that have the specified tag
|
||||||
*
|
*
|
||||||
* @see IWaypointCollection#getAllWaypoints()
|
|
||||||
*
|
|
||||||
* @param tag The tag
|
* @param tag The tag
|
||||||
* @return All of the waypoints with the specified tag
|
* @return All of the waypoints with the specified tag
|
||||||
|
* @see IWaypointCollection#getAllWaypoints()
|
||||||
*/
|
*/
|
||||||
Set<IWaypoint> getByTag(IWaypoint.Tag tag);
|
Set<IWaypoint> getByTag(IWaypoint.Tag tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all of the waypoints in this collection, regardless of the tag.
|
* Gets all of the waypoints in this collection, regardless of the tag.
|
||||||
*
|
*
|
||||||
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
|
|
||||||
*
|
|
||||||
* @return All of the waypoints in this collection
|
* @return All of the waypoints in this collection
|
||||||
|
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
|
||||||
*/
|
*/
|
||||||
Set<IWaypoint> getAllWaypoints();
|
Set<IWaypoint> getAllWaypoints();
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.api.cache;
|
package baritone.api.cache;
|
||||||
|
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ public interface IWorldScanner {
|
|||||||
/**
|
/**
|
||||||
* Scans the world, up to the specified max chunk radius, for the specified blocks.
|
* Scans the world, up to the specified max chunk radius, for the specified blocks.
|
||||||
*
|
*
|
||||||
|
* @param ctx The {@link IPlayerContext} containing player and world info that the
|
||||||
|
* scan is based upon
|
||||||
* @param blocks The blocks to scan for
|
* @param blocks The blocks to scan for
|
||||||
* @param max The maximum number of blocks to scan before cutoff
|
* @param max The maximum number of blocks to scan before cutoff
|
||||||
* @param yLevelThreshold If a block is found within this Y level, the current result will be
|
* @param yLevelThreshold If a block is found within this Y level, the current result will be
|
||||||
@@ -38,5 +41,5 @@ public interface IWorldScanner {
|
|||||||
* @param maxSearchRadius The maximum chunk search radius
|
* @param maxSearchRadius The maximum chunk search radius
|
||||||
* @return The matching block positions
|
* @return The matching block positions
|
||||||
*/
|
*/
|
||||||
List<BlockPos> scanChunkRadius(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
|
List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import net.minecraft.client.entity.EntityPlayerSP;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018 6:39 PM
|
* @since 8/1/2018
|
||||||
*/
|
*/
|
||||||
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
|
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import baritone.api.event.events.type.EventState;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/2/2018 12:32 AM
|
* @since 8/2/2018
|
||||||
*/
|
*/
|
||||||
public final class ChunkEvent {
|
public final class ChunkEvent {
|
||||||
|
|
||||||
@@ -94,7 +94,16 @@ public final class ChunkEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* When the chunk is being populated with blocks, tile entities, etc.
|
* When the chunk is being populated with blocks, tile entities, etc.
|
||||||
|
* <p>
|
||||||
|
* And it's a full chunk
|
||||||
*/
|
*/
|
||||||
POPULATE
|
POPULATE_FULL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the chunk is being populated with blocks, tile entities, etc.
|
||||||
|
* <p>
|
||||||
|
* And it's a partial chunk
|
||||||
|
*/
|
||||||
|
POPULATE_PARTIAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import net.minecraft.network.Packet;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/6/2018 9:31 PM
|
* @since 8/6/2018
|
||||||
*/
|
*/
|
||||||
public final class PacketEvent {
|
public final class PacketEvent {
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package baritone.api.event.events;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/5/2018 12:28 AM
|
* @since 8/5/2018
|
||||||
*/
|
*/
|
||||||
public final class RenderEvent {
|
public final class RenderEvent {
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package baritone.api.event.events;
|
package baritone.api.event.events;
|
||||||
|
|
||||||
import baritone.api.event.events.type.EventState;
|
|
||||||
import baritone.api.event.events.type.ManagedPlayerEvent;
|
import baritone.api.event.events.type.ManagedPlayerEvent;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@@ -35,21 +34,30 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
|
|||||||
private final Type type;
|
private final Type type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The state of the event
|
* The yaw rotation
|
||||||
*/
|
*/
|
||||||
private final EventState state;
|
private float yaw;
|
||||||
|
|
||||||
public RotationMoveEvent(EntityPlayerSP player, EventState state, Type type) {
|
public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
|
||||||
super(player);
|
super(player);
|
||||||
this.state = state;
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.yaw = yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The state of the event
|
* Set the yaw movement rotation
|
||||||
|
*
|
||||||
|
* @param yaw Yaw rotation
|
||||||
*/
|
*/
|
||||||
public final EventState getState() {
|
public final void setYaw(float yaw) {
|
||||||
return this.state;
|
this.yaw = yaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The yaw rotation
|
||||||
|
*/
|
||||||
|
public final float getYaw() {
|
||||||
|
return this.yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import net.minecraft.client.multiplayer.WorldClient;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 3:13 AM
|
* @since 8/4/2018
|
||||||
*/
|
*/
|
||||||
public final class WorldEvent {
|
public final class WorldEvent {
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package baritone.api.event.events.type;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018 6:41 PM
|
* @since 8/1/2018
|
||||||
*/
|
*/
|
||||||
public class Cancellable implements ICancellable {
|
public class Cancellable implements ICancellable {
|
||||||
|
|
||||||
|
|||||||
@@ -19,19 +19,17 @@ package baritone.api.event.events.type;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/2/2018 12:34 AM
|
* @since 8/2/2018
|
||||||
*/
|
*/
|
||||||
public enum EventState {
|
public enum EventState {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that whatever movement the event is being
|
* Before the dispatching of what the event is targetting
|
||||||
* dispatched as a result of is about to occur.
|
|
||||||
*/
|
*/
|
||||||
PRE,
|
PRE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that whatever movement the event is being
|
* After the dispatching of what the event is targetting
|
||||||
* dispatched as a result of has already occurred.
|
|
||||||
*/
|
*/
|
||||||
POST
|
POST
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import baritone.api.event.events.*;
|
|||||||
*
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @see IGameEventListener
|
* @see IGameEventListener
|
||||||
* @since 8/1/2018 6:29 PM
|
* @since 8/1/2018
|
||||||
*/
|
*/
|
||||||
public interface AbstractGameEventListener extends IGameEventListener {
|
public interface AbstractGameEventListener extends IGameEventListener {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of {@link IGameEventListener} that can have additional listeners
|
||||||
|
* registered so that they receive the events that are dispatched to this
|
||||||
|
* listener.
|
||||||
|
*
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/14/2018
|
||||||
|
*/
|
||||||
|
public interface IEventBus extends IGameEventListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the specified {@link IGameEventListener} to this event bus
|
||||||
|
*
|
||||||
|
* @param listener The listener
|
||||||
|
*/
|
||||||
|
void registerEventListener(IGameEventListener listener);
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ import net.minecraft.util.text.ITextComponent;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 11:05 PM
|
* @since 7/31/2018
|
||||||
*/
|
*/
|
||||||
public interface IGameEventListener {
|
public interface IGameEventListener {
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ import baritone.api.Settings;
|
|||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,7 +53,9 @@ public interface IPath {
|
|||||||
* This path is actually going to be executed in the world. Do whatever additional processing is required.
|
* This path is actually going to be executed in the world. Do whatever additional processing is required.
|
||||||
* (as opposed to Path objects that are just constructed every frame for rendering)
|
* (as opposed to Path objects that are just constructed every frame for rendering)
|
||||||
*/
|
*/
|
||||||
default void postProcess() {}
|
default IPath postProcess() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
|
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
|
||||||
@@ -100,7 +104,7 @@ public interface IPath {
|
|||||||
* Returns the estimated number of ticks to complete the path from the given node index.
|
* Returns the estimated number of ticks to complete the path from the given node index.
|
||||||
*
|
*
|
||||||
* @param pathPosition The index of the node we're calculating from
|
* @param pathPosition The index of the node we're calculating from
|
||||||
* @return The estimated number of ticks remaining frm the given position
|
* @return The estimated number of ticks remaining from the given position
|
||||||
*/
|
*/
|
||||||
default double ticksRemainingFrom(int pathPosition) {
|
default double ticksRemainingFrom(int pathPosition) {
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
@@ -111,26 +115,68 @@ public interface IPath {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the estimated amount of time needed to complete this path from start to finish
|
||||||
|
*
|
||||||
|
* @return The estimated amount of time, in ticks
|
||||||
|
*/
|
||||||
|
default double totalTicks() {
|
||||||
|
return ticksRemainingFrom(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
|
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
|
||||||
* implementation just returns this path, without the intended functionality.
|
* implementation just returns this path, without the intended functionality.
|
||||||
*
|
*
|
||||||
* @return The result of this cut-off operation
|
* @return The result of this cut-off operation
|
||||||
*/
|
*/
|
||||||
default IPath cutoffAtLoadedChunks() {
|
default IPath cutoffAtLoadedChunks(World world) {
|
||||||
return this;
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cuts off this path using the min length and cutoff factor settings, and returns the resulting path.
|
* Cuts off this path using the min length and cutoff factor settings, and returns the resulting path.
|
||||||
* Default implementation just returns this path, without the intended functionality.
|
* Default implementation just returns this path, without the intended functionality.
|
||||||
*
|
*
|
||||||
|
* @return The result of this cut-off operation
|
||||||
* @see Settings#pathCutoffMinimumLength
|
* @see Settings#pathCutoffMinimumLength
|
||||||
* @see Settings#pathCutoffFactor
|
* @see Settings#pathCutoffFactor
|
||||||
*
|
|
||||||
* @return The result of this cut-off operation
|
|
||||||
*/
|
*/
|
||||||
default IPath staticCutoff(Goal destination) {
|
default IPath staticCutoff(Goal destination) {
|
||||||
return this;
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
||||||
|
*/
|
||||||
|
default void sanityCheck() {
|
||||||
|
List<BetterBlockPos> path = positions();
|
||||||
|
List<IMovement> movements = movements();
|
||||||
|
if (!getSrc().equals(path.get(0))) {
|
||||||
|
throw new IllegalStateException("Start node does not equal first path element");
|
||||||
|
}
|
||||||
|
if (!getDest().equals(path.get(path.size() - 1))) {
|
||||||
|
throw new IllegalStateException("End node does not equal last path element");
|
||||||
|
}
|
||||||
|
if (path.size() != movements.size() + 1) {
|
||||||
|
throw new IllegalStateException("Size of path array is unexpected");
|
||||||
|
}
|
||||||
|
HashSet<BetterBlockPos> seenSoFar = new HashSet<>();
|
||||||
|
for (int i = 0; i < path.size() - 1; i++) {
|
||||||
|
BetterBlockPos src = path.get(i);
|
||||||
|
BetterBlockPos dest = path.get(i + 1);
|
||||||
|
IMovement movement = movements.get(i);
|
||||||
|
if (!src.equals(movement.getSrc())) {
|
||||||
|
throw new IllegalStateException("Path source is not equal to the movement source");
|
||||||
|
}
|
||||||
|
if (!dest.equals(movement.getDest())) {
|
||||||
|
throw new IllegalStateException("Path destination is not equal to the movement destination");
|
||||||
|
}
|
||||||
|
if (seenSoFar.contains(src)) {
|
||||||
|
throw new IllegalStateException("Path doubles back on itself, making a loop");
|
||||||
|
}
|
||||||
|
seenSoFar.add(src);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package baritone.api.pathing.calc;
|
package baritone.api.pathing.calc;
|
||||||
|
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.utils.PathCalculationResult;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ public interface IPathFinder {
|
|||||||
*
|
*
|
||||||
* @return The final path
|
* @return The final path
|
||||||
*/
|
*/
|
||||||
Optional<IPath> calculate(long timeout);
|
PathCalculationResult calculate(long primaryTimeout, long failureTimeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
|
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.pathing.calc;
|
||||||
|
|
||||||
|
import baritone.api.process.IBaritoneProcess;
|
||||||
|
import baritone.api.process.PathingCommand;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface IPathingControlManager {
|
||||||
|
void registerProcess(IBaritoneProcess process);
|
||||||
|
|
||||||
|
Optional<IBaritoneProcess> mostRecentInControl();
|
||||||
|
|
||||||
|
Optional<PathingCommand> mostRecentCommand();
|
||||||
|
}
|
||||||
@@ -17,10 +17,7 @@
|
|||||||
|
|
||||||
package baritone.api.pathing.goals;
|
package baritone.api.pathing.goals;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A composite of many goals, any one of which satisfies the composite.
|
* A composite of many goals, any one of which satisfies the composite.
|
||||||
@@ -40,14 +37,6 @@ public class GoalComposite implements Goal {
|
|||||||
this.goals = goals;
|
this.goals = goals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GoalComposite(BlockPos... blocks) {
|
|
||||||
this(Arrays.asList(blocks));
|
|
||||||
}
|
|
||||||
|
|
||||||
public GoalComposite(Collection<BlockPos> blocks) {
|
|
||||||
this(blocks.stream().map(GoalBlock::new).toArray(Goal[]::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(int x, int y, int z) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
for (Goal goal : goals) {
|
for (Goal goal : goals) {
|
||||||
|
|||||||
@@ -48,10 +48,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
|||||||
int xDiff = x - this.x;
|
int xDiff = x - this.x;
|
||||||
int yDiff = y - this.y;
|
int yDiff = y - this.y;
|
||||||
int zDiff = z - this.z;
|
int zDiff = z - this.z;
|
||||||
if (yDiff < 0) {
|
return Math.abs(xDiff) + Math.abs(yDiff < 0 ? yDiff + 1 : yDiff) + Math.abs(zDiff) <= 1;
|
||||||
yDiff++;
|
|
||||||
}
|
|
||||||
return Math.abs(xDiff) + Math.abs(yDiff) + Math.abs(zDiff) <= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,7 +56,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
|||||||
int xDiff = x - this.x;
|
int xDiff = x - this.x;
|
||||||
int yDiff = y - this.y;
|
int yDiff = y - this.y;
|
||||||
int zDiff = z - this.z;
|
int zDiff = z - this.z;
|
||||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -32,16 +32,26 @@ public class GoalRunAway implements Goal {
|
|||||||
|
|
||||||
private final double distanceSq;
|
private final double distanceSq;
|
||||||
|
|
||||||
|
private final Integer maintainY;
|
||||||
|
|
||||||
public GoalRunAway(double distance, BlockPos... from) {
|
public GoalRunAway(double distance, BlockPos... from) {
|
||||||
|
this(distance, null, from);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GoalRunAway(double distance, Integer maintainY, BlockPos... from) {
|
||||||
if (from.length == 0) {
|
if (from.length == 0) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.distanceSq = distance * distance;
|
this.distanceSq = distance * distance;
|
||||||
|
this.maintainY = maintainY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInGoal(int x, int y, int z) {
|
public boolean isInGoal(int x, int y, int z) {
|
||||||
|
if (maintainY != null && maintainY != y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (BlockPos p : from) {
|
for (BlockPos p : from) {
|
||||||
int diffX = x - p.getX();
|
int diffX = x - p.getX();
|
||||||
int diffZ = z - p.getZ();
|
int diffZ = z - p.getZ();
|
||||||
@@ -62,11 +72,19 @@ public class GoalRunAway implements Goal {
|
|||||||
min = h;
|
min = h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -min;
|
min = -min;
|
||||||
|
if (maintainY != null) {
|
||||||
|
min = min * 0.6 + GoalYLevel.calculate(maintainY, y) * 1.5;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "GoalRunAwayFrom" + Arrays.asList(from);
|
if (maintainY != null) {
|
||||||
|
return "GoalRunAwayFromMaintainY y=" + maintainY + ", " + Arrays.asList(from);
|
||||||
|
} else {
|
||||||
|
return "GoalRunAwayFrom" + Arrays.asList(from);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,10 +63,7 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
|
|||||||
int xDiff = x - this.x;
|
int xDiff = x - this.x;
|
||||||
int yDiff = y - this.y;
|
int yDiff = y - this.y;
|
||||||
int zDiff = z - this.z;
|
int zDiff = z - this.z;
|
||||||
if (yDiff < 0) {
|
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
|
||||||
yDiff++;
|
|
||||||
}
|
|
||||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import baritone.api.IBaritone;
|
||||||
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
|
import baritone.api.event.events.PathEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A process that can control the PathingBehavior.
|
||||||
|
* <p>
|
||||||
|
* Differences between a baritone process and a behavior:
|
||||||
|
* Only one baritone process can be active at a time
|
||||||
|
* PathingBehavior can only be controlled by a process
|
||||||
|
* <p>
|
||||||
|
* That's it actually
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public interface IBaritoneProcess {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Would this process like to be in control?
|
||||||
|
*
|
||||||
|
* @return Whether or not this process would like to be in contorl.
|
||||||
|
*/
|
||||||
|
boolean isActive();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when this process is in control of pathing; Returns what Baritone should do.
|
||||||
|
*
|
||||||
|
* @param calcFailed {@code true} if this specific process was in control last tick,
|
||||||
|
* and there was a {@link PathEvent#CALC_FAILED} event last tick
|
||||||
|
* @param isSafeToCancel {@code true} if a {@link PathingCommandType#REQUEST_PAUSE} would happen this tick, and
|
||||||
|
* {@link IPathingBehavior} wouldn't actually tick. {@code false} if the PathExecutor reported
|
||||||
|
* pausing would be unsafe at the end of the last tick. Effectively "could request cancel or
|
||||||
|
* pause and have it happen right away"
|
||||||
|
* @return What the {@link IPathingBehavior} should do
|
||||||
|
*/
|
||||||
|
PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not this process should be treated as "temporary".
|
||||||
|
* <p>
|
||||||
|
* If a process is temporary, it doesn't call {@link #onLostControl} on the processes that aren't execute because of it.
|
||||||
|
* <p>
|
||||||
|
* For example, {@code CombatPauserProcess} and {@code PauseForAutoEatProcess} should return {@code true} always,
|
||||||
|
* and should return {@link #isActive} {@code true} only if there's something in range this tick, or if the player would like
|
||||||
|
* to start eating this tick. {@code PauseForAutoEatProcess} should only actually right click once onTick is called with
|
||||||
|
* {@code isSafeToCancel} true though.
|
||||||
|
*
|
||||||
|
* @return Whethor or not if this control is temporary
|
||||||
|
*/
|
||||||
|
boolean isTemporary();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if {@link #isActive} returned {@code true}, but another non-temporary
|
||||||
|
* process has control. Effectively the same as cancel. You want control but you
|
||||||
|
* don't get it.
|
||||||
|
*/
|
||||||
|
void onLostControl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine which Process gains control if multiple are reporting {@link #isActive()}. The one
|
||||||
|
* that returns the highest value will be given control.
|
||||||
|
*
|
||||||
|
* @return A double representing the priority
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @return A display name that's suitable for a HUD
|
||||||
|
*/
|
||||||
|
String displayName();
|
||||||
|
}
|
||||||
+23
-27
@@ -15,40 +15,36 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.api.utils.interfaces;
|
package baritone.api.process;
|
||||||
|
|
||||||
/**
|
import baritone.api.pathing.goals.Goal;
|
||||||
* @author Brady
|
|
||||||
* @since 8/20/2018
|
public interface ICustomGoalProcess extends IBaritoneProcess {
|
||||||
*/
|
|
||||||
public interface Toggleable {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the enabled state of this {@link Toggleable}.
|
* Sets the pathing goal
|
||||||
*
|
*
|
||||||
* @return The new state.
|
* @param goal The new goal
|
||||||
*/
|
*/
|
||||||
boolean toggle();
|
void setGoal(Goal goal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the enabled state of this {@link Toggleable}.
|
* Starts path calculation and execution.
|
||||||
|
*/
|
||||||
|
void path();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current goal
|
||||||
|
*/
|
||||||
|
Goal getGoal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the goal and begins the path execution.
|
||||||
*
|
*
|
||||||
* @return The new state.
|
* @param goal The new goal
|
||||||
*/
|
*/
|
||||||
boolean setEnabled(boolean enabled);
|
default void setGoalAndPath(Goal goal) {
|
||||||
|
this.setGoal(goal);
|
||||||
/**
|
this.path();
|
||||||
* @return Whether or not this {@link Toggleable} object is enabled
|
}
|
||||||
*/
|
|
||||||
boolean isEnabled();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the state changes from disabled to enabled
|
|
||||||
*/
|
|
||||||
default void onEnable() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the state changes from enabled to disabled
|
|
||||||
*/
|
|
||||||
default void onDisable() {}
|
|
||||||
}
|
}
|
||||||
+15
-8
@@ -15,30 +15,37 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.api.behavior;
|
package baritone.api.process;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
*/
|
*/
|
||||||
public interface IFollowBehavior extends IBehavior {
|
public interface IFollowProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the follow target to the specified entity;
|
* Set the follow target to any entities matching this predicate
|
||||||
*
|
*
|
||||||
* @param entity The entity to follow
|
* @param filter the predicate
|
||||||
*/
|
*/
|
||||||
void follow(Entity entity);
|
void follow(Predicate<Entity> filter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The entity that is currently being followed
|
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
|
||||||
*/
|
*/
|
||||||
Entity following();
|
List<Entity> following();
|
||||||
|
|
||||||
|
Predicate<Entity> currentFilter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the follow behavior, this will clear the current follow target.
|
* Cancels the follow behavior, this will clear the current follow target.
|
||||||
*/
|
*/
|
||||||
void cancel();
|
default void cancel() {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* but it rescans the world every once in a while so it doesn't get fooled by its cache
|
||||||
|
*/
|
||||||
|
public interface IGetToBlockProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
|
void getToBlock(Block block);
|
||||||
|
}
|
||||||
+11
-9
@@ -15,7 +15,7 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.api.behavior;
|
package baritone.api.process;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ import net.minecraft.block.Block;
|
|||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/23/2018
|
* @since 9/23/2018
|
||||||
*/
|
*/
|
||||||
public interface IMineBehavior extends IBehavior {
|
public interface IMineProcess extends IBaritoneProcess {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin to search for and mine the specified blocks until
|
* Begin to search for and mine the specified blocks until
|
||||||
@@ -31,9 +31,9 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
* are mined. This is based on the first target block to mine.
|
* are mined. This is based on the first target block to mine.
|
||||||
*
|
*
|
||||||
* @param quantity The number of items to get from blocks mined
|
* @param quantity The number of items to get from blocks mined
|
||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
void mine(int quantity, String... blocks);
|
void mineByName(int quantity, String... blocks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin to search for and mine the specified blocks until
|
* Begin to search for and mine the specified blocks until
|
||||||
@@ -41,7 +41,7 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
* are mined. This is based on the first target block to mine.
|
* are mined. This is based on the first target block to mine.
|
||||||
*
|
*
|
||||||
* @param quantity The number of items to get from blocks mined
|
* @param quantity The number of items to get from blocks mined
|
||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
void mine(int quantity, Block... blocks);
|
void mine(int quantity, Block... blocks);
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
*
|
*
|
||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
default void mine(String... blocks) {
|
default void mineByName(String... blocks) {
|
||||||
this.mine(0, blocks);
|
mineByName(0, blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,11 +60,13 @@ public interface IMineBehavior extends IBehavior {
|
|||||||
* @param blocks The blocks to mine
|
* @param blocks The blocks to mine
|
||||||
*/
|
*/
|
||||||
default void mine(Block... blocks) {
|
default void mine(Block... blocks) {
|
||||||
this.mine(0, blocks);
|
mine(0, blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the current mining task
|
* Cancels the current mining task
|
||||||
*/
|
*/
|
||||||
void cancel();
|
default void cancel() {
|
||||||
|
onLostControl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public class PathingCommand {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target goal, may be {@code null}.
|
||||||
|
*/
|
||||||
|
public final Goal goal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The command type.
|
||||||
|
*
|
||||||
|
* @see PathingCommandType
|
||||||
|
*/
|
||||||
|
public final PathingCommandType commandType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link PathingCommand}.
|
||||||
|
*
|
||||||
|
* @param goal The target goal, may be {@code null}.
|
||||||
|
* @param commandType The command type, cannot be {@code null}.
|
||||||
|
* @throws NullPointerException if {@code commandType} is {@code null}.
|
||||||
|
* @see Goal
|
||||||
|
* @see PathingCommandType
|
||||||
|
*/
|
||||||
|
public PathingCommand(Goal goal, PathingCommandType commandType) {
|
||||||
|
Objects.requireNonNull(commandType);
|
||||||
|
|
||||||
|
this.goal = goal;
|
||||||
|
this.commandType = commandType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.process;
|
||||||
|
|
||||||
|
import baritone.api.Settings;
|
||||||
|
|
||||||
|
public enum PathingCommandType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal and path.
|
||||||
|
* <p>
|
||||||
|
* If you use this alongside a {@code null} goal, it will continue along its current path and current goal.
|
||||||
|
*/
|
||||||
|
SET_GOAL_AND_PATH,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has no effect on the current goal or path, just requests a pause
|
||||||
|
*/
|
||||||
|
REQUEST_PAUSE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal (regardless of {@code null}), and request a cancel of the current path (when safe)
|
||||||
|
*/
|
||||||
|
CANCEL_AND_SET_GOAL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal and path.
|
||||||
|
* <p>
|
||||||
|
* If {@link Settings#cancelOnGoalInvalidation} is {@code true}, revalidate the
|
||||||
|
* current goal, and cancel if it's no longer valid, or if the new goal is {@code null}.
|
||||||
|
*/
|
||||||
|
REVALIDATE_GOAL_AND_PATH,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the goal and path.
|
||||||
|
* <p>
|
||||||
|
* Cancel the current path if the goals are not equal
|
||||||
|
*/
|
||||||
|
FORCE_REVALIDATE_GOAL_AND_PATH
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import baritone.api.behavior.IBehavior;
|
||||||
|
import baritone.api.utils.input.Input;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/12/2018
|
||||||
|
*/
|
||||||
|
public interface IInputOverrideHandler extends IBehavior {
|
||||||
|
|
||||||
|
default boolean isInputForcedDown(KeyBinding key) {
|
||||||
|
return isInputForcedDown(Input.getInputForBind(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isInputForcedDown(Input input);
|
||||||
|
|
||||||
|
void setInputForceState(Input input, boolean forced);
|
||||||
|
|
||||||
|
void clearAllKeys();
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import baritone.api.cache.IWorldData;
|
||||||
|
import net.minecraft.block.BlockSlab;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/12/2018
|
||||||
|
*/
|
||||||
|
public interface IPlayerContext {
|
||||||
|
|
||||||
|
EntityPlayerSP player();
|
||||||
|
|
||||||
|
PlayerControllerMP playerController();
|
||||||
|
|
||||||
|
World world();
|
||||||
|
|
||||||
|
IWorldData worldData();
|
||||||
|
|
||||||
|
RayTraceResult objectMouseOver();
|
||||||
|
|
||||||
|
default BetterBlockPos playerFeet() {
|
||||||
|
// TODO find a better way to deal with soul sand!!!!!
|
||||||
|
BetterBlockPos feet = new BetterBlockPos(player().posX, player().posY + 0.1251, player().posZ);
|
||||||
|
if (world().getBlockState(feet).getBlock() instanceof BlockSlab) {
|
||||||
|
return feet.up();
|
||||||
|
}
|
||||||
|
return feet;
|
||||||
|
}
|
||||||
|
|
||||||
|
default Vec3d playerFeetAsVec() {
|
||||||
|
return new Vec3d(player().posX, player().posY, player().posZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Vec3d playerHead() {
|
||||||
|
return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Rotation playerRotations() {
|
||||||
|
return new Rotation(player().rotationYaw, player().rotationPitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block that the crosshair is currently placed over. Updated once per tick.
|
||||||
|
*
|
||||||
|
* @return The position of the highlighted block
|
||||||
|
*/
|
||||||
|
default Optional<BlockPos> getSelectedBlock() {
|
||||||
|
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
|
return Optional.of(objectMouseOver().getBlockPos());
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the entity that the crosshair is currently placed over. Updated once per tick.
|
||||||
|
*
|
||||||
|
* @return The entity
|
||||||
|
*/
|
||||||
|
default Optional<Entity> getSelectedEntity() {
|
||||||
|
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) {
|
||||||
|
return Optional.of(objectMouseOver().entityHit);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import baritone.api.pathing.calc.IPath;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class PathCalculationResult {
|
||||||
|
|
||||||
|
private final IPath path;
|
||||||
|
private final Type type;
|
||||||
|
|
||||||
|
public PathCalculationResult(Type type) {
|
||||||
|
this(type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathCalculationResult(Type type, IPath path) {
|
||||||
|
this.path = path;
|
||||||
|
this.type = type;
|
||||||
|
if (type == null) {
|
||||||
|
throw new IllegalArgumentException("come on");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Optional<IPath> getPath() {
|
||||||
|
return Optional.ofNullable(this.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Type getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
SUCCESS_TO_GOAL,
|
||||||
|
SUCCESS_SEGMENT,
|
||||||
|
FAILURE,
|
||||||
|
CANCELLATION,
|
||||||
|
EXCEPTION,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,56 +17,18 @@
|
|||||||
|
|
||||||
package baritone.api.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/25/2018
|
* @since 8/25/2018
|
||||||
*/
|
*/
|
||||||
public final class RayTraceUtils {
|
public final class RayTraceUtils {
|
||||||
/**
|
|
||||||
* The {@link Minecraft} instance
|
|
||||||
*/
|
|
||||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
|
|
||||||
private RayTraceUtils() {}
|
private RayTraceUtils() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulates a "vanilla" raytrace. A RayTraceResult returned by this method
|
|
||||||
* will be that of the next render pass given that the local player's yaw and
|
|
||||||
* pitch match the specified yaw and pitch values. This is particularly useful
|
|
||||||
* when you would like to simulate a "legit" raytrace with certainty that the only
|
|
||||||
* thing to achieve the desired outcome (whether it is hitting and entity or placing
|
|
||||||
* a block) can be done just by modifying user input.
|
|
||||||
*
|
|
||||||
* @param yaw The yaw to raytrace with
|
|
||||||
* @param pitch The pitch to raytrace with
|
|
||||||
* @return The calculated raytrace result
|
|
||||||
*/
|
|
||||||
public static RayTraceResult simulateRayTrace(float yaw, float pitch) {
|
|
||||||
RayTraceResult oldTrace = mc.objectMouseOver;
|
|
||||||
float oldYaw = mc.player.rotationYaw;
|
|
||||||
float oldPitch = mc.player.rotationPitch;
|
|
||||||
|
|
||||||
mc.player.rotationYaw = yaw;
|
|
||||||
mc.player.rotationPitch = pitch;
|
|
||||||
|
|
||||||
mc.entityRenderer.getMouseOver(1.0F);
|
|
||||||
RayTraceResult result = mc.objectMouseOver;
|
|
||||||
mc.objectMouseOver = oldTrace;
|
|
||||||
|
|
||||||
mc.player.rotationYaw = oldYaw;
|
|
||||||
mc.player.rotationPitch = oldPitch;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a block raytrace with the specified rotations. This should only be used when
|
* Performs a block raytrace with the specified rotations. This should only be used when
|
||||||
* any entity collisions can be ignored, because this method will not recognize if an
|
* any entity collisions can be ignored, because this method will not recognize if an
|
||||||
@@ -75,39 +37,14 @@ public final class RayTraceUtils {
|
|||||||
* @param rotation The rotation to raytrace towards
|
* @param rotation The rotation to raytrace towards
|
||||||
* @return The calculated raytrace result
|
* @return The calculated raytrace result
|
||||||
*/
|
*/
|
||||||
public static RayTraceResult rayTraceTowards(Rotation rotation) {
|
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
|
||||||
double blockReachDistance = mc.playerController.getBlockReachDistance();
|
Vec3d start = entity.getPositionEyes(1.0F);
|
||||||
Vec3d start = mc.player.getPositionEyes(1.0F);
|
|
||||||
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
||||||
Vec3d end = start.add(
|
Vec3d end = start.add(
|
||||||
direction.x * blockReachDistance,
|
direction.x * blockReachDistance,
|
||||||
direction.y * blockReachDistance,
|
direction.y * blockReachDistance,
|
||||||
direction.z * blockReachDistance
|
direction.z * blockReachDistance
|
||||||
);
|
);
|
||||||
return mc.world.rayTraceBlocks(start, end, false, false, true);
|
return entity.world.rayTraceBlocks(start, end, false, false, true);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the block that the crosshair is currently placed over. Updated once per render tick.
|
|
||||||
*
|
|
||||||
* @return The position of the highlighted block
|
|
||||||
*/
|
|
||||||
public static Optional<BlockPos> getSelectedBlock() {
|
|
||||||
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
|
|
||||||
return Optional.of(mc.objectMouseOver.getBlockPos());
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the entity that the crosshair is currently placed over. Updated once per render tick.
|
|
||||||
*
|
|
||||||
* @return The entity
|
|
||||||
*/
|
|
||||||
public static Optional<Entity> getSelectedEntity() {
|
|
||||||
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) {
|
|
||||||
return Optional.of(mc.objectMouseOver.entityHit);
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class Rotation {
|
|||||||
public Rotation clamp() {
|
public Rotation clamp() {
|
||||||
return new Rotation(
|
return new Rotation(
|
||||||
this.yaw,
|
this.yaw,
|
||||||
RotationUtils.clampPitch(this.pitch)
|
clampPitch(this.pitch)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ public class Rotation {
|
|||||||
*/
|
*/
|
||||||
public Rotation normalize() {
|
public Rotation normalize() {
|
||||||
return new Rotation(
|
return new Rotation(
|
||||||
RotationUtils.normalizeYaw(this.yaw),
|
normalizeYaw(this.yaw),
|
||||||
this.pitch
|
this.pitch
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -105,8 +105,35 @@ public class Rotation {
|
|||||||
*/
|
*/
|
||||||
public Rotation normalizeAndClamp() {
|
public Rotation normalizeAndClamp() {
|
||||||
return new Rotation(
|
return new Rotation(
|
||||||
RotationUtils.normalizeYaw(this.yaw),
|
normalizeYaw(this.yaw),
|
||||||
RotationUtils.clampPitch(this.pitch)
|
clampPitch(this.pitch)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamps the specified pitch value between -90 and 90.
|
||||||
|
*
|
||||||
|
* @param pitch The input pitch
|
||||||
|
* @return The clamped pitch
|
||||||
|
*/
|
||||||
|
public static float clampPitch(float pitch) {
|
||||||
|
return Math.max(-90, Math.min(90, pitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the specified yaw value between -180 and 180.
|
||||||
|
*
|
||||||
|
* @param yaw The input yaw
|
||||||
|
* @return The normalized yaw
|
||||||
|
*/
|
||||||
|
public static float normalizeYaw(float yaw) {
|
||||||
|
float newYaw = yaw % 360F;
|
||||||
|
if (newYaw < -180F) {
|
||||||
|
newYaw += 360F;
|
||||||
|
}
|
||||||
|
if (newYaw >= 180F) {
|
||||||
|
newYaw -= 360F;
|
||||||
|
}
|
||||||
|
return newYaw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
|
|
||||||
package baritone.api.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import net.minecraft.block.BlockFire;
|
import net.minecraft.block.BlockFire;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
|
|
||||||
@@ -31,11 +33,6 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public final class RotationUtils {
|
public final class RotationUtils {
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Minecraft} instance
|
|
||||||
*/
|
|
||||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constant that a degree value is multiplied by to get the equivalent radian value
|
* Constant that a degree value is multiplied by to get the equivalent radian value
|
||||||
*/
|
*/
|
||||||
@@ -60,33 +57,6 @@ public final class RotationUtils {
|
|||||||
|
|
||||||
private RotationUtils() {}
|
private RotationUtils() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clamps the specified pitch value between -90 and 90.
|
|
||||||
*
|
|
||||||
* @param pitch The input pitch
|
|
||||||
* @return The clamped pitch
|
|
||||||
*/
|
|
||||||
public static float clampPitch(float pitch) {
|
|
||||||
return Math.max(-90, Math.min(90, pitch));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalizes the specified yaw value between -180 and 180.
|
|
||||||
*
|
|
||||||
* @param yaw The input yaw
|
|
||||||
* @return The normalized yaw
|
|
||||||
*/
|
|
||||||
public static float normalizeYaw(float yaw) {
|
|
||||||
float newYaw = yaw % 360F;
|
|
||||||
if (newYaw < -180F) {
|
|
||||||
newYaw += 360F;
|
|
||||||
}
|
|
||||||
if (newYaw >= 180F) {
|
|
||||||
newYaw -= 360F;
|
|
||||||
}
|
|
||||||
return newYaw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
|
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
|
||||||
*
|
*
|
||||||
@@ -168,8 +138,9 @@ public final class RotationUtils {
|
|||||||
* @param pos The target block position
|
* @param pos The target block position
|
||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachable(Entity entity, BlockPos pos) {
|
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
|
||||||
if (pos.equals(RayTraceUtils.getSelectedBlock().orElse(null))) {
|
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
|
||||||
|
if (pos.equals(baritone.getPlayerContext().getSelectedBlock().orElse(null))) {
|
||||||
/*
|
/*
|
||||||
* why add 0.0001?
|
* why add 0.0001?
|
||||||
* to indicate that we actually have a desired pitch
|
* to indicate that we actually have a desired pitch
|
||||||
@@ -182,19 +153,19 @@ public final class RotationUtils {
|
|||||||
*/
|
*/
|
||||||
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
|
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
|
||||||
}
|
}
|
||||||
Optional<Rotation> possibleRotation = reachableCenter(entity, pos);
|
Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance);
|
||||||
//System.out.println("center: " + possibleRotation);
|
//System.out.println("center: " + possibleRotation);
|
||||||
if (possibleRotation.isPresent()) {
|
if (possibleRotation.isPresent()) {
|
||||||
return possibleRotation;
|
return possibleRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
IBlockState state = mc.world.getBlockState(pos);
|
IBlockState state = entity.world.getBlockState(pos);
|
||||||
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
||||||
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
||||||
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
||||||
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
||||||
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
||||||
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
|
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
|
||||||
if (possibleRotation.isPresent()) {
|
if (possibleRotation.isPresent()) {
|
||||||
return possibleRotation;
|
return possibleRotation;
|
||||||
}
|
}
|
||||||
@@ -212,9 +183,9 @@ public final class RotationUtils {
|
|||||||
* @param offsetPos The position of the block with the offset applied.
|
* @param offsetPos The position of the block with the offset applied.
|
||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos) {
|
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
||||||
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
|
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
|
||||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
||||||
//System.out.println(result);
|
//System.out.println(result);
|
||||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
if (result.getBlockPos().equals(pos)) {
|
if (result.getBlockPos().equals(pos)) {
|
||||||
@@ -235,7 +206,7 @@ public final class RotationUtils {
|
|||||||
* @param pos The target block position
|
* @param pos The target block position
|
||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos) {
|
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance) {
|
||||||
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(pos));
|
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,21 +19,17 @@ package baritone.api.utils;
|
|||||||
|
|
||||||
import net.minecraft.block.BlockFire;
|
import net.minecraft.block.BlockFire;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 10/13/2018
|
* @since 10/13/2018
|
||||||
*/
|
*/
|
||||||
public final class VecUtils {
|
public final class VecUtils {
|
||||||
/**
|
|
||||||
* The {@link Minecraft} instance
|
|
||||||
*/
|
|
||||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
|
||||||
|
|
||||||
private VecUtils() {}
|
private VecUtils() {}
|
||||||
|
|
||||||
@@ -44,9 +40,9 @@ public final class VecUtils {
|
|||||||
* @return The center of the block's bounding box
|
* @return The center of the block's bounding box
|
||||||
* @see #getBlockPosCenter(BlockPos)
|
* @see #getBlockPosCenter(BlockPos)
|
||||||
*/
|
*/
|
||||||
public static Vec3d calculateBlockCenter(BlockPos pos) {
|
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
|
||||||
IBlockState b = mc.world.getBlockState(pos);
|
IBlockState b = world.getBlockState(pos);
|
||||||
AxisAlignedBB bbox = b.getBoundingBox(mc.world, pos);
|
AxisAlignedBB bbox = b.getBoundingBox(world, pos);
|
||||||
double xDiff = (bbox.minX + bbox.maxX) / 2;
|
double xDiff = (bbox.minX + bbox.maxX) / 2;
|
||||||
double yDiff = (bbox.minY + bbox.maxY) / 2;
|
double yDiff = (bbox.minY + bbox.maxY) / 2;
|
||||||
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
|
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
|
||||||
@@ -68,7 +64,7 @@ public final class VecUtils {
|
|||||||
*
|
*
|
||||||
* @param pos The block position
|
* @param pos The block position
|
||||||
* @return The assumed center of the position
|
* @return The assumed center of the position
|
||||||
* @see #calculateBlockCenter(BlockPos)
|
* @see #calculateBlockCenter(World, BlockPos)
|
||||||
*/
|
*/
|
||||||
public static Vec3d getBlockPosCenter(BlockPos pos) {
|
public static Vec3d getBlockPosCenter(BlockPos pos) {
|
||||||
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.utils.input;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.settings.GameSettings;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link Enum} representing the inputs that control the player's
|
||||||
|
* behavior. This includes moving, interacting with blocks, jumping,
|
||||||
|
* sneaking, and sprinting.
|
||||||
|
*/
|
||||||
|
public enum Input {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The move forward input
|
||||||
|
*/
|
||||||
|
MOVE_FORWARD(s -> s.keyBindForward),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The move back input
|
||||||
|
*/
|
||||||
|
MOVE_BACK(s -> s.keyBindBack),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The move left input
|
||||||
|
*/
|
||||||
|
MOVE_LEFT(s -> s.keyBindLeft),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The move right input
|
||||||
|
*/
|
||||||
|
MOVE_RIGHT(s -> s.keyBindRight),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attack input
|
||||||
|
*/
|
||||||
|
CLICK_LEFT(s -> s.keyBindAttack),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The use item input
|
||||||
|
*/
|
||||||
|
CLICK_RIGHT(s -> s.keyBindUseItem),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The jump input
|
||||||
|
*/
|
||||||
|
JUMP(s -> s.keyBindJump),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sneak input
|
||||||
|
*/
|
||||||
|
SNEAK(s -> s.keyBindSneak),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sprint input
|
||||||
|
*/
|
||||||
|
SPRINT(s -> s.keyBindSprint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of {@link KeyBinding} to {@link Input}. Values should be queried through {@link #getInputForBind(KeyBinding)}
|
||||||
|
*/
|
||||||
|
private static final Map<KeyBinding, Input> bindToInputMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual game {@link KeyBinding} being forced.
|
||||||
|
*/
|
||||||
|
private final KeyBinding keyBinding;
|
||||||
|
|
||||||
|
Input(Function<GameSettings, KeyBinding> keyBindingMapper) {
|
||||||
|
/*
|
||||||
|
|
||||||
|
Here, a Function is used because referring to a static field in this enum for the game instance,
|
||||||
|
as it was before, wouldn't be possible in an Enum constructor unless the static field was in an
|
||||||
|
interface that this class implemented. (Helper acted as this interface) I didn't feel like making
|
||||||
|
an interface with a game instance field just to not have to do this.
|
||||||
|
|
||||||
|
*/
|
||||||
|
this.keyBinding = keyBindingMapper.apply(Minecraft.getMinecraft().gameSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The actual game {@link KeyBinding} being forced.
|
||||||
|
*/
|
||||||
|
public final KeyBinding getKeyBinding() {
|
||||||
|
return this.keyBinding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the {@link Input} constant that is associated with the specified {@link KeyBinding}.
|
||||||
|
*
|
||||||
|
* @param binding The {@link KeyBinding} to find the associated {@link Input} for
|
||||||
|
* @return The {@link Input} associated with the specified {@link KeyBinding}
|
||||||
|
*/
|
||||||
|
public static Input getInputForBind(KeyBinding binding) {
|
||||||
|
return bindToInputMap.computeIfAbsent(binding, b -> Arrays.stream(values()).filter(input -> input.keyBinding == b).findFirst().orElse(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do you not like having a blocking "receiveMessage" thingy?
|
||||||
|
* <p>
|
||||||
|
* Do you prefer just being able to get a list of all messages received since the last tick?
|
||||||
|
* <p>
|
||||||
|
* If so, this class is for you!
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public class BufferedConnection implements IConnection {
|
||||||
|
private final IConnection wrapped;
|
||||||
|
private final LinkedBlockingQueue<iMessage> queue;
|
||||||
|
private volatile transient IOException thrownOnRead;
|
||||||
|
|
||||||
|
public BufferedConnection(IConnection wrapped) {
|
||||||
|
this(wrapped, Integer.MAX_VALUE); // LinkedBlockingQueue accepts this as "no limit"
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedConnection(IConnection wrapped, int maxInternalQueueSize) {
|
||||||
|
this.wrapped = wrapped;
|
||||||
|
this.queue = new LinkedBlockingQueue<>();
|
||||||
|
this.thrownOnRead = null;
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
while (thrownOnRead == null) {
|
||||||
|
queue.put(wrapped.receiveMessage());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
thrownOnRead = e;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
thrownOnRead = new IOException("Interrupted while enqueueing", e);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(iMessage message) throws IOException {
|
||||||
|
wrapped.sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public iMessage receiveMessage() {
|
||||||
|
throw new UnsupportedOperationException("BufferedConnection can only be read from non-blockingly");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
wrapped.close();
|
||||||
|
thrownOnRead = new EOFException("Closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<iMessage> receiveMessagesNonBlocking() throws IOException {
|
||||||
|
ArrayList<iMessage> msgs = new ArrayList<>();
|
||||||
|
queue.drainTo(msgs); // preserves order -- first message received will be first in this arraylist
|
||||||
|
if (msgs.isEmpty() && thrownOnRead != null) {
|
||||||
|
IOException up = new IOException("BufferedConnection wrapped", thrownOnRead);
|
||||||
|
throw up;
|
||||||
|
}
|
||||||
|
return msgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleAllPendingMessages(IMessageListener listener) throws IOException {
|
||||||
|
receiveMessagesNonBlocking().forEach(msg -> msg.handle(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedConnection makeBuffered(IConnection conn) {
|
||||||
|
if (conn instanceof BufferedConnection) {
|
||||||
|
return (BufferedConnection) conn;
|
||||||
|
} else {
|
||||||
|
return new BufferedConnection(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public enum ConstructingDeserializer implements MessageDeserializer {
|
||||||
|
INSTANCE;
|
||||||
|
private final List<Class<? extends iMessage>> MSGS;
|
||||||
|
|
||||||
|
ConstructingDeserializer() {
|
||||||
|
MSGS = new ArrayList<>();
|
||||||
|
// imagine doing something in reflect but it's actually concise and you don't need to catch 42069 different exceptions. huh.
|
||||||
|
for (Method m : IMessageListener.class.getDeclaredMethods()) {
|
||||||
|
if (m.getName().equals("handle")) {
|
||||||
|
MSGS.add((Class<? extends iMessage>) m.getParameterTypes()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized iMessage deserialize(DataInputStream in) throws IOException {
|
||||||
|
int type = ((int) in.readByte()) & 0xff;
|
||||||
|
try {
|
||||||
|
return MSGS.get(type).getConstructor(DataInputStream.class).newInstance(in);
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException ex) {
|
||||||
|
throw new IOException("Unknown message type " + type, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getHeader(Class<? extends iMessage> klass) {
|
||||||
|
return (byte) MSGS.indexOf(klass);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface IConnection {
|
||||||
|
void sendMessage(iMessage message) throws IOException;
|
||||||
|
|
||||||
|
iMessage receiveMessage() throws IOException;
|
||||||
|
|
||||||
|
void close();
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cabaletta.comms;
|
||||||
|
|
||||||
|
import cabaletta.comms.downward.MessageChat;
|
||||||
|
import cabaletta.comms.downward.MessageComputationRequest;
|
||||||
|
import cabaletta.comms.upward.MessageComputationResponse;
|
||||||
|
import cabaletta.comms.upward.MessageStatus;
|
||||||
|
|
||||||
|
public interface IMessageListener {
|
||||||
|
default void handle(MessageStatus message) {
|
||||||
|
unhandled(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void handle(MessageChat message) {
|
||||||
|
unhandled(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void handle(MessageComputationRequest message) {
|
||||||
|
unhandled(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void handle(MessageComputationResponse message) {
|
||||||
|
unhandled(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void unhandled(iMessage msg) {
|
||||||
|
// can override this to throw UnsupportedOperationException, if you want to make sure you're handling everything
|
||||||
|
// default is to silently ignore messages without handlers
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface MessageDeserializer {
|
||||||
|
iMessage deserialize(DataInputStream in) throws IOException;
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do you want a socket to localhost without actually making a gross real socket to localhost?
|
||||||
|
*/
|
||||||
|
public class Pipe<T extends iMessage> {
|
||||||
|
private final LinkedBlockingQueue<Optional<iMessage>> AtoB;
|
||||||
|
private final LinkedBlockingQueue<Optional<iMessage>> BtoA;
|
||||||
|
private final PipedConnection A;
|
||||||
|
private final PipedConnection B;
|
||||||
|
private volatile boolean closed;
|
||||||
|
|
||||||
|
public Pipe() {
|
||||||
|
this.AtoB = new LinkedBlockingQueue<>();
|
||||||
|
this.BtoA = new LinkedBlockingQueue<>();
|
||||||
|
this.A = new PipedConnection(BtoA, AtoB);
|
||||||
|
this.B = new PipedConnection(AtoB, BtoA);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PipedConnection getA() {
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PipedConnection getB() {
|
||||||
|
return B;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PipedConnection implements IConnection {
|
||||||
|
private final LinkedBlockingQueue<Optional<iMessage>> in;
|
||||||
|
private final LinkedBlockingQueue<Optional<iMessage>> out;
|
||||||
|
|
||||||
|
private PipedConnection(LinkedBlockingQueue<Optional<iMessage>> in, LinkedBlockingQueue<Optional<iMessage>> out) {
|
||||||
|
this.in = in;
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(iMessage message) throws IOException {
|
||||||
|
if (closed) {
|
||||||
|
throw new EOFException("Closed");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
out.put(Optional.of(message));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// this can never happen since the LinkedBlockingQueues are not constructed with a maximum capacity, see above
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public iMessage receiveMessage() throws IOException {
|
||||||
|
if (closed) {
|
||||||
|
throw new EOFException("Closed");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Optional<iMessage> t = in.take();
|
||||||
|
if (!t.isPresent()) {
|
||||||
|
throw new EOFException("Closed");
|
||||||
|
}
|
||||||
|
return t.get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// again, cannot happen
|
||||||
|
// but we have to throw something
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
closed = true;
|
||||||
|
try {
|
||||||
|
AtoB.put(Optional.empty()); // unstick threads
|
||||||
|
BtoA.put(Optional.empty());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class SerializedConnection implements IConnection {
|
||||||
|
private final DataInputStream in;
|
||||||
|
private final DataOutputStream out;
|
||||||
|
private final MessageDeserializer deserializer;
|
||||||
|
|
||||||
|
public SerializedConnection(InputStream in, OutputStream out) {
|
||||||
|
this(ConstructingDeserializer.INSTANCE, in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerializedConnection(MessageDeserializer d, InputStream in, OutputStream out) {
|
||||||
|
this.in = new DataInputStream(in);
|
||||||
|
this.out = new DataOutputStream(out);
|
||||||
|
this.deserializer = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void sendMessage(iMessage message) throws IOException {
|
||||||
|
message.writeHeader(out);
|
||||||
|
message.write(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public iMessage receiveMessage() throws IOException {
|
||||||
|
return deserializer.deserialize(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class SocketConnection extends SerializedConnection {
|
||||||
|
public SocketConnection(Socket s) throws IOException {
|
||||||
|
super(s.getInputStream(), s.getOutputStream());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cabaletta.comms.downward;
|
||||||
|
|
||||||
|
import cabaletta.comms.IMessageListener;
|
||||||
|
import cabaletta.comms.iMessage;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MessageChat implements iMessage {
|
||||||
|
|
||||||
|
public final String msg;
|
||||||
|
|
||||||
|
public MessageChat(DataInputStream in) throws IOException {
|
||||||
|
this.msg = in.readUTF();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageChat(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
out.writeUTF(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(IMessageListener listener) {
|
||||||
|
listener.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms.downward;
|
||||||
|
|
||||||
|
import cabaletta.comms.IMessageListener;
|
||||||
|
import cabaletta.comms.iMessage;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MessageComputationRequest implements iMessage {
|
||||||
|
public final long computationID;
|
||||||
|
public final int startX;
|
||||||
|
public final int startY;
|
||||||
|
public final int startZ;
|
||||||
|
public final String goal; // TODO find a better way to do this lol
|
||||||
|
|
||||||
|
public MessageComputationRequest(DataInputStream in) throws IOException {
|
||||||
|
this.computationID = in.readLong();
|
||||||
|
this.startX = in.readInt();
|
||||||
|
this.startY = in.readInt();
|
||||||
|
this.startZ = in.readInt();
|
||||||
|
this.goal = in.readUTF();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageComputationRequest(long computationID, int startX, int startY, int startZ, String goal) {
|
||||||
|
this.computationID = computationID;
|
||||||
|
this.startX = startX;
|
||||||
|
this.startY = startY;
|
||||||
|
this.startZ = startZ;
|
||||||
|
this.goal = goal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
out.writeLong(computationID);
|
||||||
|
out.writeInt(startX);
|
||||||
|
out.writeInt(startY);
|
||||||
|
out.writeUTF(goal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(IMessageListener listener) {
|
||||||
|
listener.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hell yeah
|
||||||
|
* <p>
|
||||||
|
* <p>
|
||||||
|
* dumb android users cant read this file
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @author leijurv
|
||||||
|
*/
|
||||||
|
public interface iMessage {
|
||||||
|
void write(DataOutputStream out) throws IOException;
|
||||||
|
|
||||||
|
default void writeHeader(DataOutputStream out) throws IOException {
|
||||||
|
out.writeByte(getHeader());
|
||||||
|
}
|
||||||
|
|
||||||
|
default byte getHeader() {
|
||||||
|
return ConstructingDeserializer.INSTANCE.getHeader(getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle(IMessageListener listener);
|
||||||
|
}
|
||||||
@@ -0,0 +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 cabaletta.comms.upward;
|
||||||
|
|
||||||
|
import cabaletta.comms.IMessageListener;
|
||||||
|
import cabaletta.comms.iMessage;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MessageComputationResponse implements iMessage {
|
||||||
|
public final long computationID;
|
||||||
|
public final int pathLength;
|
||||||
|
public final double pathCost;
|
||||||
|
public final boolean endsInGoal;
|
||||||
|
public final int endX;
|
||||||
|
public final int endY;
|
||||||
|
public final int endZ;
|
||||||
|
|
||||||
|
public MessageComputationResponse(DataInputStream in) throws IOException {
|
||||||
|
this.computationID = in.readLong();
|
||||||
|
this.pathLength = in.readInt();
|
||||||
|
this.pathCost = in.readDouble();
|
||||||
|
this.endsInGoal = in.readBoolean();
|
||||||
|
this.endX = in.readInt();
|
||||||
|
this.endY = in.readInt();
|
||||||
|
this.endZ = in.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageComputationResponse(long computationID, int pathLength, double pathCost, boolean endsInGoal, int endX, int endY, int endZ) {
|
||||||
|
this.computationID = computationID;
|
||||||
|
this.pathLength = pathLength;
|
||||||
|
this.pathCost = pathCost;
|
||||||
|
this.endsInGoal = endsInGoal;
|
||||||
|
this.endX = endX;
|
||||||
|
this.endY = endY;
|
||||||
|
this.endZ = endZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
out.writeLong(computationID);
|
||||||
|
out.writeInt(pathLength);
|
||||||
|
out.writeDouble(pathCost);
|
||||||
|
out.writeBoolean(endsInGoal);
|
||||||
|
out.writeInt(endX);
|
||||||
|
out.writeInt(endY);
|
||||||
|
out.writeInt(endZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(IMessageListener listener) {
|
||||||
|
listener.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* 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 cabaletta.comms.upward;
|
||||||
|
|
||||||
|
import cabaletta.comms.IMessageListener;
|
||||||
|
import cabaletta.comms.iMessage;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MessageStatus implements iMessage {
|
||||||
|
|
||||||
|
public final double x;
|
||||||
|
public final double y;
|
||||||
|
public final double z;
|
||||||
|
public final float yaw;
|
||||||
|
public final float pitch;
|
||||||
|
public final boolean onGround;
|
||||||
|
public final float health;
|
||||||
|
public final float saturation;
|
||||||
|
public final int foodLevel;
|
||||||
|
public final int pathStartX;
|
||||||
|
public final int pathStartY;
|
||||||
|
public final int pathStartZ;
|
||||||
|
public final boolean hasCurrentSegment;
|
||||||
|
public final boolean hasNextSegment;
|
||||||
|
public final boolean calcInProgress;
|
||||||
|
public final double ticksRemainingInCurrent;
|
||||||
|
public final boolean calcFailedLastTick;
|
||||||
|
public final boolean safeToCancel;
|
||||||
|
public final String currentGoal;
|
||||||
|
public final String currentProcess;
|
||||||
|
|
||||||
|
public MessageStatus(DataInputStream in) throws IOException {
|
||||||
|
this.x = in.readDouble();
|
||||||
|
this.y = in.readDouble();
|
||||||
|
this.z = in.readDouble();
|
||||||
|
this.yaw = in.readFloat();
|
||||||
|
this.pitch = in.readFloat();
|
||||||
|
this.onGround = in.readBoolean();
|
||||||
|
this.health = in.readFloat();
|
||||||
|
this.saturation = in.readFloat();
|
||||||
|
this.foodLevel = in.readInt();
|
||||||
|
this.pathStartX = in.readInt();
|
||||||
|
this.pathStartY = in.readInt();
|
||||||
|
this.pathStartZ = in.readInt();
|
||||||
|
this.hasCurrentSegment = in.readBoolean();
|
||||||
|
this.hasNextSegment = in.readBoolean();
|
||||||
|
this.calcInProgress = in.readBoolean();
|
||||||
|
this.ticksRemainingInCurrent = in.readDouble();
|
||||||
|
this.calcFailedLastTick = in.readBoolean();
|
||||||
|
this.safeToCancel = in.readBoolean();
|
||||||
|
this.currentGoal = in.readUTF();
|
||||||
|
this.currentProcess = in.readUTF();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageStatus(double x, double y, double z, float yaw, float pitch, boolean onGround, float health, float saturation, int foodLevel, int pathStartX, int pathStartY, int pathStartZ, boolean hasCurrentSegment, boolean hasNextSegment, boolean calcInProgress, double ticksRemainingInCurrent, boolean calcFailedLastTick, boolean safeToCancel, String currentGoal, String currentProcess) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.yaw = yaw;
|
||||||
|
this.pitch = pitch;
|
||||||
|
this.onGround = onGround;
|
||||||
|
this.health = health;
|
||||||
|
this.saturation = saturation;
|
||||||
|
this.foodLevel = foodLevel;
|
||||||
|
this.pathStartX = pathStartX;
|
||||||
|
this.pathStartY = pathStartY;
|
||||||
|
this.pathStartZ = pathStartZ;
|
||||||
|
this.hasCurrentSegment = hasCurrentSegment;
|
||||||
|
this.hasNextSegment = hasNextSegment;
|
||||||
|
this.calcInProgress = calcInProgress;
|
||||||
|
this.ticksRemainingInCurrent = ticksRemainingInCurrent;
|
||||||
|
this.calcFailedLastTick = calcFailedLastTick;
|
||||||
|
this.safeToCancel = safeToCancel;
|
||||||
|
this.currentGoal = currentGoal;
|
||||||
|
this.currentProcess = currentProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(DataOutputStream out) throws IOException {
|
||||||
|
out.writeDouble(x);
|
||||||
|
out.writeDouble(y);
|
||||||
|
out.writeDouble(z);
|
||||||
|
out.writeFloat(yaw);
|
||||||
|
out.writeFloat(pitch);
|
||||||
|
out.writeBoolean(onGround);
|
||||||
|
out.writeFloat(health);
|
||||||
|
out.writeFloat(saturation);
|
||||||
|
out.writeInt(foodLevel);
|
||||||
|
out.writeInt(pathStartX);
|
||||||
|
out.writeInt(pathStartY);
|
||||||
|
out.writeInt(pathStartZ);
|
||||||
|
out.writeBoolean(hasCurrentSegment);
|
||||||
|
out.writeBoolean(hasNextSegment);
|
||||||
|
out.writeBoolean(calcInProgress);
|
||||||
|
out.writeDouble(ticksRemainingInCurrent);
|
||||||
|
out.writeBoolean(calcFailedLastTick);
|
||||||
|
out.writeBoolean(safeToCancel);
|
||||||
|
out.writeUTF(currentGoal);
|
||||||
|
out.writeUTF(currentProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(IMessageListener listener) {
|
||||||
|
listener.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 9:59 PM
|
* @since 7/31/2018
|
||||||
*/
|
*/
|
||||||
public class BaritoneTweaker extends SimpleTweaker {
|
public class BaritoneTweaker extends SimpleTweaker {
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ import java.io.File;
|
|||||||
@Mixin(AnvilChunkLoader.class)
|
@Mixin(AnvilChunkLoader.class)
|
||||||
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
|
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
|
||||||
|
|
||||||
@Shadow @Final private File chunkSaveLocation;
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private File chunkSaveLocation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public File getChunkSaveLocation() {
|
public File getChunkSaveLocation() {
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ public class MixinBlockPos extends Vec3i {
|
|||||||
super(xIn, yIn, zIn);
|
super(xIn, yIn, zIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purpose of this was to ensure a friendly name for when we print raw
|
||||||
|
* block positions to chat in the context of an obfuscated environment.
|
||||||
|
*
|
||||||
|
* @return a string representation of the object.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
|
import baritone.utils.accessor.IChunkProviderClient;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
@Mixin(ChunkProviderClient.class)
|
||||||
|
public class MixinChunkProviderClient implements IChunkProviderClient {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private Long2ObjectMap<Chunk> loadedChunks;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long2ObjectMap<Chunk> loadedChunks() {
|
||||||
|
return this.loadedChunks;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,9 @@ import org.spongepowered.asm.mixin.Shadow;
|
|||||||
@Mixin(ChunkProviderServer.class)
|
@Mixin(ChunkProviderServer.class)
|
||||||
public class MixinChunkProviderServer implements IChunkProviderServer {
|
public class MixinChunkProviderServer implements IChunkProviderServer {
|
||||||
|
|
||||||
@Shadow @Final private IChunkLoader chunkLoader;
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private IChunkLoader chunkLoader;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkLoader getChunkLoader() {
|
public IChunkLoader getChunkLoader() {
|
||||||
|
|||||||
@@ -17,16 +17,19 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
import baritone.api.event.events.RotationMoveEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
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.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/21/2018
|
* @since 8/21/2018
|
||||||
@@ -34,23 +37,38 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public class MixinEntity {
|
public class MixinEntity {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public float rotationYaw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called to override the movement direction when walking
|
||||||
|
*/
|
||||||
|
private RotationMoveEvent motionUpdateRotationEvent;
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "moveRelative",
|
method = "moveRelative",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
||||||
Entity _this = (Entity) (Object) this;
|
// noinspection ConstantConditions
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
if (EntityPlayerSP.class.isInstance(this)) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE));
|
this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
|
||||||
|
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Redirect(
|
||||||
method = "moveRelative",
|
method = "moveRelative",
|
||||||
at = @At("RETURN")
|
at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
opcode = GETFIELD,
|
||||||
|
target = "net/minecraft/entity/Entity.rotationYaw:F"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
private void postMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
private float overrideYaw(Entity self) {
|
||||||
Entity _this = (Entity) (Object) this;
|
if (self instanceof EntityPlayerSP) {
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
return this.motionUpdateRotationEvent.getYaw();
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE));
|
}
|
||||||
|
return self.rotationYaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,43 +17,61 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
import baritone.api.event.events.RotationMoveEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/10/2018
|
* @since 9/10/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(EntityLivingBase.class)
|
@Mixin(EntityLivingBase.class)
|
||||||
public class MixinEntityLivingBase {
|
public abstract class MixinEntityLivingBase extends Entity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event called to override the movement direction when jumping
|
||||||
|
*/
|
||||||
|
private RotationMoveEvent jumpRotationEvent;
|
||||||
|
|
||||||
|
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
|
||||||
|
super(worldIn);
|
||||||
|
this.jumpRotationEvent = jumpRotationEvent;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "jump",
|
method = "jump",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preJump(CallbackInfo ci) {
|
private void preMoveRelative(CallbackInfo ci) {
|
||||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
// noinspection ConstantConditions
|
||||||
// This uses Class.isInstance instead of instanceof since proguard optimizes out the instanceof (since MixinEntityLivingBase could never be instanceof EntityLivingBase in normal java)
|
if (EntityPlayerSP.class.isInstance(this)) {
|
||||||
// but proguard isn't smart enough to optimize out this Class.isInstance =)
|
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Redirect(
|
||||||
method = "jump",
|
method = "jump",
|
||||||
at = @At("RETURN")
|
at = @At(
|
||||||
|
value = "FIELD",
|
||||||
|
opcode = GETFIELD,
|
||||||
|
target = "net/minecraft/entity/EntityLivingBase.rotationYaw:F"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
private void postJump(CallbackInfo ci) {
|
private float overrideYaw(EntityLivingBase self) {
|
||||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
if (self instanceof EntityPlayerSP) {
|
||||||
// See above
|
return this.jumpRotationEvent.getYaw();
|
||||||
if (EntityPlayerSP.class.isInstance(_this))
|
}
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
|
return self.rotationYaw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.behavior.IPathingBehavior;
|
||||||
import baritone.api.event.events.ChatEvent;
|
import baritone.api.event.events.ChatEvent;
|
||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.behavior.PathingBehavior;
|
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.player.PlayerCapabilities;
|
import net.minecraft.entity.player.PlayerCapabilities;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -32,7 +32,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018 5:06 PM
|
* @since 8/1/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(EntityPlayerSP.class)
|
@Mixin(EntityPlayerSP.class)
|
||||||
public class MixinEntityPlayerSP {
|
public class MixinEntityPlayerSP {
|
||||||
@@ -44,7 +44,7 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
private void sendChatMessage(String msg, CallbackInfo ci) {
|
private void sendChatMessage(String msg, CallbackInfo ci) {
|
||||||
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
|
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
|
||||||
Baritone.INSTANCE.getGameEventHandler().onSendChatMessage(event);
|
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onSendChatMessage(event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void onPreUpdate(CallbackInfo ci) {
|
private void onPreUpdate(CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
|
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -73,7 +73,7 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void onPostUpdate(CallbackInfo ci) {
|
private void onPostUpdate(CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
|
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(
|
@Redirect(
|
||||||
@@ -84,7 +84,7 @@ public class MixinEntityPlayerSP {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
||||||
PathingBehavior pathingBehavior = Baritone.INSTANCE.getPathingBehavior();
|
IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior();
|
||||||
return (!pathingBehavior.isEnabled() || !pathingBehavior.isPathing()) && capabilities.allowFlying;
|
return !pathingBehavior.isPathing() && capabilities.allowFlying;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.RenderEvent;
|
import baritone.api.event.events.RenderEvent;
|
||||||
import net.minecraft.client.renderer.EntityRenderer;
|
import net.minecraft.client.renderer.EntityRenderer;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -33,10 +34,12 @@ public class MixinEntityRenderer {
|
|||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE_STRING",
|
value = "INVOKE_STRING",
|
||||||
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
||||||
args = { "ldc=hand" }
|
args = {"ldc=hand"}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -26,7 +26,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 11:44 PM
|
* @since 7/31/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(KeyBinding.class)
|
@Mixin(KeyBinding.class)
|
||||||
public class MixinKeyBinding {
|
public class MixinKeyBinding {
|
||||||
@@ -37,7 +37,8 @@ public class MixinKeyBinding {
|
|||||||
cancellable = true
|
cancellable = true
|
||||||
)
|
)
|
||||||
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
|
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
|
||||||
if (Baritone.INSTANCE.getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
|
// only the primary baritone forces keys
|
||||||
|
if (BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
|
||||||
cir.setReturnValue(true);
|
cir.setReturnValue(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.BlockInteractEvent;
|
import baritone.api.event.events.BlockInteractEvent;
|
||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.api.event.events.WorldEvent;
|
import baritone.api.event.events.WorldEvent;
|
||||||
@@ -42,7 +44,7 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 10:51 PM
|
* @since 7/31/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
public class MixinMinecraft {
|
public class MixinMinecraft {
|
||||||
@@ -57,7 +59,7 @@ public class MixinMinecraft {
|
|||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postInit(CallbackInfo ci) {
|
private void postInit(CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.init();
|
((Baritone) BaritoneAPI.getProvider().getPrimaryBaritone()).init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -83,13 +85,15 @@ public class MixinMinecraft {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void runTick(CallbackInfo ci) {
|
private void runTick(CallbackInfo ci) {
|
||||||
Minecraft mc = (Minecraft) (Object) this;
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onTick(new TickEvent(
|
|
||||||
EventState.PRE,
|
TickEvent.Type type = ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().world() != null
|
||||||
(mc.player != null && mc.world != null)
|
? TickEvent.Type.IN
|
||||||
? TickEvent.Type.IN
|
: TickEvent.Type.OUT;
|
||||||
: TickEvent.Type.OUT
|
|
||||||
));
|
ibaritone.getGameEventHandler().onTick(new TickEvent(EventState.PRE, type));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -97,7 +101,8 @@ public class MixinMinecraft {
|
|||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void runTickKeyboard(CallbackInfo ci) {
|
private void runTickKeyboard(CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onProcessKeyBinds();
|
// keyboard input is only the primary baritone
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onProcessKeyBinds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -110,7 +115,9 @@ public class MixinMinecraft {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
// mc.world changing is only the primary baritone
|
||||||
|
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onWorldEvent(
|
||||||
new WorldEvent(
|
new WorldEvent(
|
||||||
world,
|
world,
|
||||||
EventState.PRE
|
EventState.PRE
|
||||||
@@ -125,7 +132,8 @@ public class MixinMinecraft {
|
|||||||
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||||
// still fire event for both null, as that means we've just finished exiting a world
|
// still fire event for both null, as that means we've just finished exiting a world
|
||||||
|
|
||||||
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
// mc.world changing is only the primary baritone
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onWorldEvent(
|
||||||
new WorldEvent(
|
new WorldEvent(
|
||||||
world,
|
world,
|
||||||
EventState.POST
|
EventState.POST
|
||||||
@@ -142,7 +150,8 @@ public class MixinMinecraft {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private boolean isAllowUserInput(GuiScreen screen) {
|
private boolean isAllowUserInput(GuiScreen screen) {
|
||||||
return (Baritone.INSTANCE.getPathingBehavior().getCurrent() != null && Baritone.INSTANCE.getPathingBehavior().isEnabled() && player != null) || screen.allowUserInput;
|
// allow user input is only the primary baritone
|
||||||
|
return (BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getCurrent() != null && player != null) || screen.allowUserInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -154,7 +163,8 @@ public class MixinMinecraft {
|
|||||||
locals = LocalCapture.CAPTURE_FAILHARD
|
locals = LocalCapture.CAPTURE_FAILHARD
|
||||||
)
|
)
|
||||||
private void onBlockBreak(CallbackInfo ci, BlockPos pos) {
|
private void onBlockBreak(CallbackInfo ci, BlockPos pos) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.BREAK));
|
// clickMouse is only for the main player
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.BREAK));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -166,6 +176,7 @@ public class MixinMinecraft {
|
|||||||
locals = LocalCapture.CAPTURE_FAILHARD
|
locals = LocalCapture.CAPTURE_FAILHARD
|
||||||
)
|
)
|
||||||
private void onBlockUse(CallbackInfo ci, EnumHand var1[], int var2, int var3, EnumHand enumhand, ItemStack itemstack, BlockPos blockpos, int i, EnumActionResult enumactionresult) {
|
private void onBlockUse(CallbackInfo ci, EnumHand var1[], int var2, int var3, EnumHand enumhand, ItemStack itemstack, BlockPos blockpos, int i, EnumActionResult enumactionresult) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
|
// rightClickMouse is only for the main player
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.ChunkEvent;
|
import baritone.api.event.events.ChunkEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||||
@@ -30,7 +31,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/3/2018 12:54 AM
|
* @since 8/3/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(NetHandlerPlayClient.class)
|
@Mixin(NetHandlerPlayClient.class)
|
||||||
public class MixinNetHandlerPlayClient {
|
public class MixinNetHandlerPlayClient {
|
||||||
@@ -43,14 +44,18 @@ public class MixinNetHandlerPlayClient {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
new ChunkEvent(
|
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
||||||
EventState.PRE,
|
ibaritone.getGameEventHandler().onChunkEvent(
|
||||||
ChunkEvent.Type.POPULATE,
|
new ChunkEvent(
|
||||||
packetIn.getChunkX(),
|
EventState.PRE,
|
||||||
packetIn.getChunkZ()
|
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
|
||||||
)
|
packetIn.getChunkX(),
|
||||||
);
|
packetIn.getChunkZ()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -58,14 +63,18 @@ public class MixinNetHandlerPlayClient {
|
|||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
|
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
new ChunkEvent(
|
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
||||||
EventState.POST,
|
ibaritone.getGameEventHandler().onChunkEvent(
|
||||||
ChunkEvent.Type.POPULATE,
|
new ChunkEvent(
|
||||||
packetIn.getChunkX(),
|
EventState.POST,
|
||||||
packetIn.getChunkZ()
|
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
|
||||||
)
|
packetIn.getChunkX(),
|
||||||
);
|
packetIn.getChunkZ()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -76,6 +85,10 @@ public class MixinNetHandlerPlayClient {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
|
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPlayerDeath();
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
||||||
|
ibaritone.getGameEventHandler().onPlayerDeath();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.PacketEvent;
|
import baritone.api.event.events.PacketEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
@@ -36,7 +37,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/6/2018 9:30 PM
|
* @since 8/6/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(NetworkManager.class)
|
@Mixin(NetworkManager.class)
|
||||||
public class MixinNetworkManager {
|
public class MixinNetworkManager {
|
||||||
@@ -53,8 +54,14 @@ public class MixinNetworkManager {
|
|||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||||
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, inPacket));
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||||
|
ibaritone.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, inPacket));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,8 +70,14 @@ public class MixinNetworkManager {
|
|||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||||
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, inPacket));
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||||
|
ibaritone.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, inPacket));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,8 +89,14 @@ public class MixinNetworkManager {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||||
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));}
|
return;
|
||||||
|
}
|
||||||
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||||
|
ibaritone.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -85,8 +104,13 @@ public class MixinNetworkManager {
|
|||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
private void postProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||||
if (this.channel.isOpen() && this.direction == EnumPacketDirection.CLIENTBOUND) {
|
if (!this.channel.isOpen() || this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, packet));
|
return;
|
||||||
|
}
|
||||||
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||||
|
ibaritone.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, packet));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.ChunkEvent;
|
import baritone.api.event.events.ChunkEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
@@ -28,7 +29,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/2/2018 12:41 AM
|
* @since 8/2/2018
|
||||||
*/
|
*/
|
||||||
@Mixin(WorldClient.class)
|
@Mixin(WorldClient.class)
|
||||||
public class MixinWorldClient {
|
public class MixinWorldClient {
|
||||||
@@ -38,14 +39,19 @@ public class MixinWorldClient {
|
|||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
new ChunkEvent(
|
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||||
EventState.PRE,
|
ibaritone.getGameEventHandler().onChunkEvent(
|
||||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
new ChunkEvent(
|
||||||
chunkX,
|
EventState.PRE,
|
||||||
chunkZ
|
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||||
)
|
chunkX,
|
||||||
);
|
chunkZ
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -53,13 +59,17 @@ public class MixinWorldClient {
|
|||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
new ChunkEvent(
|
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||||
EventState.POST,
|
ibaritone.getGameEventHandler().onChunkEvent(
|
||||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
new ChunkEvent(
|
||||||
chunkX,
|
EventState.POST,
|
||||||
chunkZ
|
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||||
)
|
chunkX,
|
||||||
);
|
chunkZ
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"client": [
|
"client": [
|
||||||
"MixinAnvilChunkLoader",
|
"MixinAnvilChunkLoader",
|
||||||
"MixinBlockPos",
|
"MixinBlockPos",
|
||||||
|
"MixinChunkProviderClient",
|
||||||
"MixinChunkProviderServer",
|
"MixinChunkProviderServer",
|
||||||
"MixinEntity",
|
"MixinEntity",
|
||||||
"MixinEntityLivingBase",
|
"MixinEntityLivingBase",
|
||||||
|
|||||||
@@ -18,16 +18,22 @@
|
|||||||
package baritone;
|
package baritone;
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.IBaritoneProvider;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.Settings;
|
import baritone.api.Settings;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IEventBus;
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
import baritone.behavior.*;
|
import baritone.behavior.*;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.cache.WorldScanner;
|
|
||||||
import baritone.event.GameEventHandler;
|
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.BaritoneAutoTest;
|
||||||
import baritone.utils.ExampleBaritoneControl;
|
import baritone.utils.ExampleBaritoneControl;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import baritone.utils.InputOverrideHandler;
|
||||||
|
import baritone.utils.PathingControlManager;
|
||||||
|
import baritone.utils.player.PrimaryPlayerContext;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -42,14 +48,23 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 10:50 PM
|
* @since 7/31/2018
|
||||||
*/
|
*/
|
||||||
public enum Baritone implements IBaritoneProvider {
|
public class Baritone implements IBaritone {
|
||||||
|
|
||||||
/**
|
private static ThreadPoolExecutor threadPool;
|
||||||
* Singleton instance of this class
|
private static File dir;
|
||||||
*/
|
|
||||||
INSTANCE;
|
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
|
* Whether or not {@link Baritone#init()} has been called yet
|
||||||
@@ -57,140 +72,146 @@ public enum Baritone implements IBaritoneProvider {
|
|||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
|
|
||||||
private GameEventHandler gameEventHandler;
|
private GameEventHandler gameEventHandler;
|
||||||
private InputOverrideHandler inputOverrideHandler;
|
|
||||||
private Settings settings;
|
|
||||||
private File dir;
|
|
||||||
private ThreadPoolExecutor threadPool;
|
|
||||||
|
|
||||||
private List<Behavior> behaviors;
|
private List<Behavior> behaviors;
|
||||||
|
private ControllerBehavior controllerBehavior;
|
||||||
private PathingBehavior pathingBehavior;
|
private PathingBehavior pathingBehavior;
|
||||||
private LookBehavior lookBehavior;
|
private LookBehavior lookBehavior;
|
||||||
private MemoryBehavior memoryBehavior;
|
private MemoryBehavior memoryBehavior;
|
||||||
private FollowBehavior followBehavior;
|
private InputOverrideHandler inputOverrideHandler;
|
||||||
private MineBehavior mineBehavior;
|
|
||||||
|
|
||||||
/**
|
private FollowProcess followProcess;
|
||||||
* Whether or not Baritone is active
|
private MineProcess mineProcess;
|
||||||
*/
|
private GetToBlockProcess getToBlockProcess;
|
||||||
private boolean active;
|
private CustomGoalProcess customGoalProcess;
|
||||||
|
|
||||||
|
private PathingControlManager pathingControlManager;
|
||||||
|
|
||||||
|
private IPlayerContext playerContext;
|
||||||
|
private WorldProvider worldProvider;
|
||||||
|
|
||||||
Baritone() {
|
Baritone() {
|
||||||
this.gameEventHandler = new GameEventHandler();
|
this.gameEventHandler = new GameEventHandler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void init() {
|
public synchronized void init() {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
|
||||||
this.inputOverrideHandler = new InputOverrideHandler();
|
|
||||||
|
|
||||||
// Acquire the "singleton" instance of the settings directly from the API
|
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
|
||||||
// We might want to change this...
|
this.playerContext = PrimaryPlayerContext.INSTANCE;
|
||||||
this.settings = BaritoneAPI.getSettings();
|
|
||||||
|
|
||||||
this.behaviors = new ArrayList<>();
|
this.behaviors = new ArrayList<>();
|
||||||
{
|
{
|
||||||
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
||||||
|
controllerBehavior = new ControllerBehavior(this);
|
||||||
pathingBehavior = new PathingBehavior(this);
|
pathingBehavior = new PathingBehavior(this);
|
||||||
lookBehavior = new LookBehavior(this);
|
lookBehavior = new LookBehavior(this);
|
||||||
memoryBehavior = new MemoryBehavior(this);
|
memoryBehavior = new MemoryBehavior(this);
|
||||||
followBehavior = new FollowBehavior(this);
|
inputOverrideHandler = new InputOverrideHandler(this);
|
||||||
mineBehavior = new MineBehavior(this);
|
|
||||||
new ExampleBaritoneControl(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) {
|
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
|
||||||
registerEventListener(BaritoneAutoTest.INSTANCE);
|
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
|
||||||
}
|
|
||||||
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
|
||||||
if (!Files.exists(dir.toPath())) {
|
|
||||||
try {
|
|
||||||
Files.createDirectories(dir.toPath());
|
|
||||||
} catch (IOException ignored) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.active = true;
|
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInitialized() {
|
|
||||||
return this.initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IGameEventListener getGameEventHandler() {
|
|
||||||
return this.gameEventHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputOverrideHandler getInputOverrideHandler() {
|
|
||||||
return this.inputOverrideHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Behavior> getBehaviors() {
|
public List<Behavior> getBehaviors() {
|
||||||
return this.behaviors;
|
return this.behaviors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Executor getExecutor() {
|
|
||||||
return threadPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerBehavior(Behavior behavior) {
|
public void registerBehavior(Behavior behavior) {
|
||||||
this.behaviors.add(behavior);
|
this.behaviors.add(behavior);
|
||||||
this.registerEventListener(behavior);
|
this.gameEventHandler.registerEventListener(behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FollowBehavior getFollowBehavior() {
|
public PathingControlManager getPathingControlManager() {
|
||||||
return followBehavior;
|
return this.pathingControlManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LookBehavior getLookBehavior() {
|
public InputOverrideHandler getInputOverrideHandler() {
|
||||||
return lookBehavior;
|
return this.inputOverrideHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControllerBehavior getControllerBehavior() {
|
||||||
|
return this.controllerBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MemoryBehavior getMemoryBehavior() {
|
public CustomGoalProcess getCustomGoalProcess() { // Iffy
|
||||||
return memoryBehavior;
|
return this.customGoalProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MineBehavior getMineBehavior() {
|
public GetToBlockProcess getGetToBlockProcess() { // Iffy
|
||||||
return mineBehavior;
|
return this.getToBlockProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PathingBehavior getPathingBehavior() {
|
public PathingBehavior getPathingBehavior() {
|
||||||
return pathingBehavior;
|
return this.pathingBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MemoryBehavior getMemoryBehavior() {
|
||||||
|
return this.memoryBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPlayerContext getPlayerContext() {
|
||||||
|
return this.playerContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FollowProcess getFollowProcess() {
|
||||||
|
return this.followProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldProvider getWorldProvider() {
|
public WorldProvider getWorldProvider() {
|
||||||
return WorldProvider.INSTANCE;
|
return this.worldProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldScanner getWorldScanner() {
|
public IEventBus getGameEventHandler() {
|
||||||
return WorldScanner.INSTANCE;
|
return this.gameEventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerEventListener(IGameEventListener listener) {
|
public LookBehavior getLookBehavior() {
|
||||||
this.gameEventHandler.registerEventListener(listener);
|
return this.lookBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActive() {
|
@Override
|
||||||
return this.active;
|
public MineProcess getMineProcess() {
|
||||||
|
return this.mineProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Settings getSettings() {
|
public static Executor getExecutor() {
|
||||||
return this.settings;
|
return threadPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Settings settings() {
|
public static Settings settings() {
|
||||||
return Baritone.INSTANCE.settings; // yolo
|
return BaritoneAPI.getSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getDir() {
|
public static File getDir() {
|
||||||
return this.dir;
|
return dir;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,59 +17,35 @@
|
|||||||
|
|
||||||
package baritone;
|
package baritone;
|
||||||
|
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.IBaritoneProvider;
|
import baritone.api.IBaritoneProvider;
|
||||||
import baritone.api.behavior.*;
|
|
||||||
import baritone.api.cache.IWorldProvider;
|
|
||||||
import baritone.api.cache.IWorldScanner;
|
import baritone.api.cache.IWorldScanner;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
|
||||||
import baritone.cache.WorldProvider;
|
|
||||||
import baritone.cache.WorldScanner;
|
import baritone.cache.WorldScanner;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo fix this cancer
|
|
||||||
*
|
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 9/29/2018
|
* @since 9/29/2018
|
||||||
*/
|
*/
|
||||||
public final class BaritoneProvider implements IBaritoneProvider {
|
public final class BaritoneProvider implements IBaritoneProvider {
|
||||||
|
|
||||||
|
private final Baritone primary = new Baritone();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IFollowBehavior getFollowBehavior() {
|
public IBaritone getPrimaryBaritone() {
|
||||||
return Baritone.INSTANCE.getFollowBehavior();
|
return primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ILookBehavior getLookBehavior() {
|
public List<IBaritone> getAllBaritones() {
|
||||||
return Baritone.INSTANCE.getLookBehavior();
|
// TODO return a CopyOnWriteArrayList
|
||||||
}
|
return Collections.singletonList(primary);
|
||||||
|
|
||||||
@Override
|
|
||||||
public IMemoryBehavior getMemoryBehavior() {
|
|
||||||
return Baritone.INSTANCE.getMemoryBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IMineBehavior getMineBehavior() {
|
|
||||||
return Baritone.INSTANCE.getMineBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPathingBehavior getPathingBehavior() {
|
|
||||||
return Baritone.INSTANCE.getPathingBehavior();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWorldProvider getWorldProvider() {
|
|
||||||
return WorldProvider.INSTANCE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IWorldScanner getWorldScanner() {
|
public IWorldScanner getWorldScanner() {
|
||||||
return WorldScanner.INSTANCE;
|
return WorldScanner.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void registerEventListener(IGameEventListener listener) {
|
|
||||||
Baritone.INSTANCE.registerEventListener(listener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,60 +19,22 @@ package baritone.behavior;
|
|||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.behavior.IBehavior;
|
import baritone.api.behavior.IBehavior;
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type of game event listener that can be toggled.
|
* A type of game event listener that is given {@link Baritone} instance context.
|
||||||
*
|
*
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/1/2018 6:29 PM
|
* @since 8/1/2018
|
||||||
*/
|
*/
|
||||||
public class Behavior implements IBehavior {
|
public class Behavior implements IBehavior {
|
||||||
|
|
||||||
public final Baritone baritone;
|
public final Baritone baritone;
|
||||||
|
public final IPlayerContext ctx;
|
||||||
/**
|
|
||||||
* Whether or not this behavior is enabled
|
|
||||||
*/
|
|
||||||
private boolean enabled = true;
|
|
||||||
|
|
||||||
protected Behavior(Baritone baritone) {
|
protected Behavior(Baritone baritone) {
|
||||||
this.baritone = baritone;
|
this.baritone = baritone;
|
||||||
|
this.ctx = baritone.getPlayerContext();
|
||||||
baritone.registerBehavior(this);
|
baritone.registerBehavior(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles the enabled state of this {@link Behavior}.
|
|
||||||
*
|
|
||||||
* @return The new state.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean toggle() {
|
|
||||||
return this.setEnabled(!this.isEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the enabled state of this {@link Behavior}.
|
|
||||||
*
|
|
||||||
* @return The new state.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean setEnabled(boolean enabled) {
|
|
||||||
if (enabled == this.enabled) {
|
|
||||||
return this.enabled;
|
|
||||||
}
|
|
||||||
if (this.enabled = enabled) {
|
|
||||||
this.onEnable();
|
|
||||||
} else {
|
|
||||||
this.onDisable();
|
|
||||||
}
|
|
||||||
return this.enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Whether or not this {@link Behavior} is active.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final boolean isEnabled() {
|
|
||||||
return this.enabled;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.behavior;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.event.events.ChatEvent;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.goals.GoalYLevel;
|
||||||
|
import baritone.api.process.IBaritoneProcess;
|
||||||
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
|
import baritone.utils.Helper;
|
||||||
|
import baritone.utils.pathing.SegmentedCalculator;
|
||||||
|
import cabaletta.comms.BufferedConnection;
|
||||||
|
import cabaletta.comms.IConnection;
|
||||||
|
import cabaletta.comms.IMessageListener;
|
||||||
|
import cabaletta.comms.downward.MessageChat;
|
||||||
|
import cabaletta.comms.downward.MessageComputationRequest;
|
||||||
|
import cabaletta.comms.iMessage;
|
||||||
|
import cabaletta.comms.upward.MessageComputationResponse;
|
||||||
|
import cabaletta.comms.upward.MessageStatus;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ControllerBehavior extends Behavior implements IMessageListener {
|
||||||
|
|
||||||
|
public ControllerBehavior(Baritone baritone) {
|
||||||
|
super(baritone);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedConnection conn;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTick(TickEvent event) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trySend(buildStatus());
|
||||||
|
readAndHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageStatus buildStatus() {
|
||||||
|
// TODO report inventory and echest contents
|
||||||
|
// TODO figure out who should remember echest contents when it isn't open, baritone or tenor?
|
||||||
|
BlockPos pathStart = baritone.getPathingBehavior().pathStart();
|
||||||
|
return new MessageStatus(
|
||||||
|
ctx.player().posX,
|
||||||
|
ctx.player().posY,
|
||||||
|
ctx.player().posZ,
|
||||||
|
ctx.player().rotationYaw,
|
||||||
|
ctx.player().rotationPitch,
|
||||||
|
ctx.player().onGround,
|
||||||
|
ctx.player().getHealth(),
|
||||||
|
ctx.player().getFoodStats().getSaturationLevel(),
|
||||||
|
ctx.player().getFoodStats().getFoodLevel(),
|
||||||
|
pathStart.getX(),
|
||||||
|
pathStart.getY(),
|
||||||
|
pathStart.getZ(),
|
||||||
|
baritone.getPathingBehavior().getCurrent() != null,
|
||||||
|
baritone.getPathingBehavior().getNext() != null,
|
||||||
|
baritone.getPathingBehavior().getInProgress().isPresent(),
|
||||||
|
baritone.getPathingBehavior().ticksRemainingInSegment().orElse(0D),
|
||||||
|
baritone.getPathingBehavior().calcFailedLastTick(),
|
||||||
|
baritone.getPathingBehavior().isSafeToCancel(),
|
||||||
|
baritone.getPathingBehavior().getGoal() + "",
|
||||||
|
baritone.getPathingControlManager().mostRecentInControl().map(IBaritoneProcess::displayName).orElse("")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readAndHandle() {
|
||||||
|
if (conn == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.handleAllPendingMessages(this);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean trySend(iMessage msg) {
|
||||||
|
if (conn == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
conn.sendMessage(msg);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
disconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connectTo(IConnection conn) {
|
||||||
|
disconnect();
|
||||||
|
this.conn = BufferedConnection.makeBuffered(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
conn = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(MessageChat msg) { // big brain
|
||||||
|
ChatEvent event = new ChatEvent(ctx.player(), msg.msg);
|
||||||
|
baritone.getGameEventHandler().onSendChatMessage(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(MessageComputationRequest msg) {
|
||||||
|
BetterBlockPos start = new BetterBlockPos(msg.startX, msg.startY, msg.startZ);
|
||||||
|
// TODO this may require scanning the world for blocks of a certain type, idk how to manage that
|
||||||
|
Goal goal = new GoalYLevel(Integer.parseInt(msg.goal)); // im already winston
|
||||||
|
SegmentedCalculator.calculateSegmentsThreaded(start, goal, new CalculationContext(baritone), path -> {
|
||||||
|
if (!Objects.equals(path.getGoal(), goal)) {
|
||||||
|
throw new IllegalStateException(); // sanity check
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
BetterBlockPos dest = path.getDest();
|
||||||
|
conn.sendMessage(new MessageComputationResponse(msg.computationID, path.length(), path.totalTicks(), path.getGoal().isInGoal(dest), dest.x, dest.y, dest.z));
|
||||||
|
} catch (IOException e) {
|
||||||
|
// nothing we can do about this, we just completed a computation but our tenor connection was closed in the meantime
|
||||||
|
// just discard the path we made for them =((
|
||||||
|
e.printStackTrace(); // and complain =)
|
||||||
|
}
|
||||||
|
}, () -> {
|
||||||
|
try {
|
||||||
|
conn.sendMessage(new MessageComputationResponse(msg.computationID, 0, 0, false, 0, 0, 0));
|
||||||
|
} catch (IOException e) {
|
||||||
|
// same deal
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unhandled(iMessage msg) {
|
||||||
|
Helper.HELPER.logDebug("Unhandled message received by ControllerBehavior " + msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Baritone.
|
|
||||||
*
|
|
||||||
* Baritone is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Baritone is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package baritone.behavior;
|
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.api.behavior.IFollowBehavior;
|
|
||||||
import baritone.api.event.events.TickEvent;
|
|
||||||
import baritone.api.pathing.goals.GoalNear;
|
|
||||||
import baritone.api.pathing.goals.GoalXZ;
|
|
||||||
import baritone.utils.Helper;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Follow an entity
|
|
||||||
*
|
|
||||||
* @author leijurv
|
|
||||||
*/
|
|
||||||
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
|
|
||||||
|
|
||||||
private Entity following;
|
|
||||||
|
|
||||||
public FollowBehavior(Baritone baritone) {
|
|
||||||
super(baritone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTick(TickEvent event) {
|
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
|
||||||
following = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (following == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// lol this is trashy but it works
|
|
||||||
BlockPos pos;
|
|
||||||
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
|
||||||
pos = following.getPosition();
|
|
||||||
} else {
|
|
||||||
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
|
||||||
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
|
||||||
}
|
|
||||||
baritone.getPathingBehavior().setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
|
|
||||||
((PathingBehavior) baritone.getPathingBehavior()).revalidateGoal();
|
|
||||||
baritone.getPathingBehavior().path();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void follow(Entity entity) {
|
|
||||||
this.following = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Entity following() {
|
|
||||||
return this.following;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() {
|
|
||||||
baritone.getPathingBehavior().cancel();
|
|
||||||
follow(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -23,9 +23,9 @@ import baritone.api.behavior.ILookBehavior;
|
|||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.api.event.events.RotationMoveEvent;
|
import baritone.api.event.events.RotationMoveEvent;
|
||||||
import baritone.api.utils.Rotation;
|
import baritone.api.utils.Rotation;
|
||||||
import baritone.utils.Helper;
|
|
||||||
|
|
||||||
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
|
public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target's values are as follows:
|
* Target's values are as follows:
|
||||||
* <p>
|
* <p>
|
||||||
@@ -63,28 +63,29 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Whether or not we're going to silently set our angles
|
// Whether or not we're going to silently set our angles
|
||||||
boolean silent = Baritone.settings().antiCheatCompatibility.get();
|
boolean silent = Baritone.settings().antiCheatCompatibility.get() && !this.force;
|
||||||
|
|
||||||
switch (event.getState()) {
|
switch (event.getState()) {
|
||||||
case PRE: {
|
case PRE: {
|
||||||
if (this.force) {
|
if (this.force) {
|
||||||
player().rotationYaw = this.target.getYaw();
|
ctx.player().rotationYaw = this.target.getYaw();
|
||||||
float oldPitch = player().rotationPitch;
|
float oldPitch = ctx.player().rotationPitch;
|
||||||
float desiredPitch = this.target.getPitch();
|
float desiredPitch = this.target.getPitch();
|
||||||
player().rotationPitch = desiredPitch;
|
ctx.player().rotationPitch = desiredPitch;
|
||||||
if (desiredPitch == oldPitch) {
|
if (desiredPitch == oldPitch) {
|
||||||
nudgeToLevel();
|
nudgeToLevel();
|
||||||
}
|
}
|
||||||
this.target = null;
|
this.target = null;
|
||||||
} else if (silent) {
|
}
|
||||||
this.lastYaw = player().rotationYaw;
|
if (silent) {
|
||||||
player().rotationYaw = this.target.getYaw();
|
this.lastYaw = ctx.player().rotationYaw;
|
||||||
|
ctx.player().rotationYaw = this.target.getYaw();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case POST: {
|
case POST: {
|
||||||
if (!this.force && silent) {
|
if (silent) {
|
||||||
player().rotationYaw = this.lastYaw;
|
ctx.player().rotationYaw = this.lastYaw;
|
||||||
this.target = null;
|
this.target = null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -97,31 +98,25 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
|||||||
@Override
|
@Override
|
||||||
public void onPlayerRotationMove(RotationMoveEvent event) {
|
public void onPlayerRotationMove(RotationMoveEvent event) {
|
||||||
if (this.target != null && !this.force) {
|
if (this.target != null && !this.force) {
|
||||||
switch (event.getState()) {
|
|
||||||
case PRE:
|
|
||||||
this.lastYaw = player().rotationYaw;
|
|
||||||
player().rotationYaw = this.target.getYaw();
|
|
||||||
break;
|
|
||||||
case POST:
|
|
||||||
player().rotationYaw = this.lastYaw;
|
|
||||||
|
|
||||||
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
event.setYaw(this.target.getYaw());
|
||||||
// Also the type has to be MOTION_UPDATE because that is called after JUMP
|
|
||||||
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
|
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
||||||
this.target = null;
|
// 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) {
|
||||||
break;
|
this.target = null;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
|
||||||
|
*/
|
||||||
private void nudgeToLevel() {
|
private void nudgeToLevel() {
|
||||||
if (player().rotationPitch < -20) {
|
if (ctx.player().rotationPitch < -20) {
|
||||||
player().rotationPitch++;
|
ctx.player().rotationPitch++;
|
||||||
} else if (player().rotationPitch > 10) {
|
} else if (ctx.player().rotationPitch > 10) {
|
||||||
player().rotationPitch--;
|
ctx.player().rotationPitch--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,7 @@ import baritone.api.event.events.PacketEvent;
|
|||||||
import baritone.api.event.events.PlayerUpdateEvent;
|
import baritone.api.event.events.PlayerUpdateEvent;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.cache.Waypoint;
|
import baritone.cache.Waypoint;
|
||||||
import baritone.cache.WorldProvider;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
|
||||||
import net.minecraft.block.BlockBed;
|
import net.minecraft.block.BlockBed;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
@@ -44,9 +42,9 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/6/2018 9:47 PM
|
* @since 8/6/2018
|
||||||
*/
|
*/
|
||||||
public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper {
|
public final class MemoryBehavior extends Behavior implements IMemoryBehavior {
|
||||||
|
|
||||||
private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>();
|
private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>();
|
||||||
|
|
||||||
@@ -69,7 +67,7 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
|||||||
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
|
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
|
||||||
CPacketPlayerTryUseItemOnBlock packet = event.cast();
|
CPacketPlayerTryUseItemOnBlock packet = event.cast();
|
||||||
|
|
||||||
TileEntity tileEntity = world().getTileEntity(packet.getPos());
|
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
|
||||||
|
|
||||||
// Ensure the TileEntity is a container of some sort
|
// Ensure the TileEntity is a container of some sort
|
||||||
if (tileEntity instanceof TileEntityLockable) {
|
if (tileEntity instanceof TileEntityLockable) {
|
||||||
@@ -121,14 +119,14 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
public void onBlockInteract(BlockInteractEvent event) {
|
||||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerDeath() {
|
public void onPlayerDeath() {
|
||||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
||||||
@@ -136,14 +134,14 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateInventory() {
|
private void updateInventory() {
|
||||||
getInventoryFromWindow(player().openContainer.windowId).ifPresent(inventory -> {
|
getInventoryFromWindow(ctx.player().openContainer.windowId).ifPresent(inventory -> {
|
||||||
inventory.items.clear();
|
inventory.items.clear();
|
||||||
inventory.items.addAll(player().openContainer.getInventory().subList(0, inventory.size));
|
inventory.items.addAll(ctx.player().openContainer.getInventory().subList(0, inventory.size));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private WorldDataContainer getCurrentContainer() {
|
private WorldDataContainer getCurrentContainer() {
|
||||||
return this.worldDataContainers.computeIfAbsent(WorldProvider.INSTANCE.getCurrentWorld(), data -> new WorldDataContainer());
|
return this.worldDataContainers.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), data -> new WorldDataContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,252 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Baritone.
|
|
||||||
*
|
|
||||||
* Baritone is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Baritone is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package baritone.behavior;
|
|
||||||
|
|
||||||
import baritone.Baritone;
|
|
||||||
import baritone.api.behavior.IMineBehavior;
|
|
||||||
import baritone.api.event.events.TickEvent;
|
|
||||||
import baritone.api.pathing.goals.*;
|
|
||||||
import baritone.api.utils.RotationUtils;
|
|
||||||
import baritone.cache.CachedChunk;
|
|
||||||
import baritone.cache.ChunkPacker;
|
|
||||||
import baritone.cache.WorldProvider;
|
|
||||||
import baritone.cache.WorldScanner;
|
|
||||||
import baritone.pathing.movement.MovementHelper;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.Helper;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.init.Blocks;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mine blocks of a certain type
|
|
||||||
*
|
|
||||||
* @author leijurv
|
|
||||||
*/
|
|
||||||
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
|
|
||||||
|
|
||||||
private List<Block> mining;
|
|
||||||
private List<BlockPos> knownOreLocations;
|
|
||||||
private BlockPos branchPoint;
|
|
||||||
private int desiredQuantity;
|
|
||||||
|
|
||||||
public MineBehavior(Baritone baritone) {
|
|
||||||
super(baritone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTick(TickEvent event) {
|
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mining == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (desiredQuantity > 0) {
|
|
||||||
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
|
|
||||||
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
|
|
||||||
System.out.println("Currently have " + curr + " " + item);
|
|
||||||
if (curr >= desiredQuantity) {
|
|
||||||
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
|
|
||||||
cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
|
||||||
if (mineGoalUpdateInterval != 0 && event.getCount() % mineGoalUpdateInterval == 0) {
|
|
||||||
Baritone.INSTANCE.getExecutor().execute(this::rescan);
|
|
||||||
}
|
|
||||||
if (Baritone.settings().legitMine.get()) {
|
|
||||||
addNearby();
|
|
||||||
}
|
|
||||||
updateGoal();
|
|
||||||
baritone.getPathingBehavior().revalidateGoal();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateGoal() {
|
|
||||||
if (mining == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<BlockPos> locs = knownOreLocations;
|
|
||||||
if (!locs.isEmpty()) {
|
|
||||||
List<BlockPos> locs2 = prune(new ArrayList<>(locs), mining, 64);
|
|
||||||
// can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final
|
|
||||||
baritone.getPathingBehavior().setGoalAndPath(new GoalComposite(locs2.stream().map(loc -> coalesce(loc, locs2)).toArray(Goal[]::new)));
|
|
||||||
knownOreLocations = locs2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// we don't know any ore locations at the moment
|
|
||||||
if (!Baritone.settings().legitMine.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// only in non-Xray mode (aka legit mode) do we do this
|
|
||||||
if (branchPoint == null) {
|
|
||||||
int y = Baritone.settings().legitMineYLevel.get();
|
|
||||||
if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
|
|
||||||
// cool, path is over and we are at desired y
|
|
||||||
branchPoint = playerFeet();
|
|
||||||
} else {
|
|
||||||
baritone.getPathingBehavior().setGoalAndPath(new GoalYLevel(y));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerFeet().equals(branchPoint)) {
|
|
||||||
// TODO mine 1x1 shafts to either side
|
|
||||||
branchPoint = branchPoint.north(10);
|
|
||||||
}
|
|
||||||
baritone.getPathingBehavior().setGoalAndPath(new GoalBlock(branchPoint));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rescan() {
|
|
||||||
if (mining == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Baritone.settings().legitMine.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<BlockPos> locs = searchWorld(mining, 64);
|
|
||||||
if (locs.isEmpty()) {
|
|
||||||
logDebug("No locations for " + mining + " known, cancelling");
|
|
||||||
mine(0, (String[]) null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
knownOreLocations = locs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Goal coalesce(BlockPos loc, List<BlockPos> locs) {
|
|
||||||
if (!Baritone.settings().forceInternalMining.get()) {
|
|
||||||
return new GoalTwoBlocks(loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
|
|
||||||
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
|
|
||||||
if (upwardGoal) {
|
|
||||||
if (downwardGoal) {
|
|
||||||
return new GoalTwoBlocks(loc);
|
|
||||||
} else {
|
|
||||||
return new GoalBlock(loc);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (downwardGoal) {
|
|
||||||
return new GoalBlock(loc.down());
|
|
||||||
} else {
|
|
||||||
return new GoalTwoBlocks(loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BlockPos> searchWorld(List<Block> mining, int max) {
|
|
||||||
List<BlockPos> locs = new ArrayList<>();
|
|
||||||
List<Block> uninteresting = new ArrayList<>();
|
|
||||||
//long b = System.currentTimeMillis();
|
|
||||||
for (Block m : mining) {
|
|
||||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
|
||||||
locs.addAll(WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, 1));
|
|
||||||
} else {
|
|
||||||
uninteresting.add(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
|
|
||||||
if (locs.isEmpty()) {
|
|
||||||
uninteresting = mining;
|
|
||||||
}
|
|
||||||
if (!uninteresting.isEmpty()) {
|
|
||||||
//long before = System.currentTimeMillis();
|
|
||||||
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
|
|
||||||
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
|
||||||
}
|
|
||||||
return prune(locs, mining, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addNearby() {
|
|
||||||
BlockPos playerFeet = playerFeet();
|
|
||||||
int searchDist = 4;//why four? idk
|
|
||||||
for (int x = playerFeet.getX() - searchDist; x <= playerFeet.getX() + searchDist; x++) {
|
|
||||||
for (int y = playerFeet.getY() - searchDist; y <= playerFeet.getY() + searchDist; y++) {
|
|
||||||
for (int z = playerFeet.getZ() - searchDist; z <= playerFeet.getZ() + searchDist; z++) {
|
|
||||||
BlockPos pos = new BlockPos(x, y, z);
|
|
||||||
if (mining.contains(BlockStateInterface.getBlock(pos)) && RotationUtils.reachable(player(), pos).isPresent()) {//crucial to only add blocks we can see because otherwise this is an x-ray and it'll get caught
|
|
||||||
knownOreLocations.add(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
knownOreLocations = prune(knownOreLocations, mining, 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BlockPos> prune(List<BlockPos> locs2, List<Block> mining, int max) {
|
|
||||||
List<BlockPos> locs = locs2
|
|
||||||
.stream()
|
|
||||||
|
|
||||||
// remove any that are within loaded chunks that aren't actually what we want
|
|
||||||
.filter(pos -> world().getChunk(pos) instanceof EmptyChunk || mining.contains(BlockStateInterface.get(pos).getBlock()))
|
|
||||||
|
|
||||||
// remove any that are implausible to mine (encased in bedrock, or touching lava)
|
|
||||||
.filter(MineBehavior::plausibleToBreak)
|
|
||||||
|
|
||||||
.sorted(Comparator.comparingDouble(Helper.HELPER.playerFeet()::distanceSq))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
if (locs.size() > max) {
|
|
||||||
return locs.subList(0, max);
|
|
||||||
}
|
|
||||||
return locs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean plausibleToBreak(BlockPos pos) {
|
|
||||||
if (MovementHelper.avoidBreaking(pos.getX(), pos.getY(), pos.getZ(), BlockStateInterface.get(pos))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// bedrock above and below makes it implausible, otherwise we're good
|
|
||||||
return !(BlockStateInterface.getBlock(pos.up()) == Blocks.BEDROCK && BlockStateInterface.getBlock(pos.down()) == Blocks.BEDROCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mine(int quantity, String... blocks) {
|
|
||||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
|
|
||||||
this.desiredQuantity = quantity;
|
|
||||||
this.knownOreLocations = new ArrayList<>();
|
|
||||||
this.branchPoint = null;
|
|
||||||
rescan();
|
|
||||||
updateGoal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mine(int quantity, Block... blocks) {
|
|
||||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
|
|
||||||
this.desiredQuantity = quantity;
|
|
||||||
this.knownOreLocations = new ArrayList<>();
|
|
||||||
this.branchPoint = null;
|
|
||||||
rescan();
|
|
||||||
updateGoal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() {
|
|
||||||
mine(0, (String[]) null);
|
|
||||||
baritone.getPathingBehavior().cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,18 +24,17 @@ import baritone.api.event.events.PlayerUpdateEvent;
|
|||||||
import baritone.api.event.events.RenderEvent;
|
import baritone.api.event.events.RenderEvent;
|
||||||
import baritone.api.event.events.TickEvent;
|
import baritone.api.event.events.TickEvent;
|
||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.calc.IPathFinder;
|
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.goals.GoalXZ;
|
import baritone.api.pathing.goals.GoalXZ;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.api.utils.PathCalculationResult;
|
||||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import baritone.pathing.calc.AStarPathFinder;
|
import baritone.pathing.calc.AStarPathFinder;
|
||||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.calc.CutoffPath;
|
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
|
import baritone.pathing.path.CutoffPath;
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import baritone.utils.BlockBreakHelper;
|
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.PathRenderer;
|
import baritone.utils.PathRenderer;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -52,7 +51,12 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
|
|
||||||
private Goal goal;
|
private Goal goal;
|
||||||
|
|
||||||
private volatile boolean isPathCalcInProgress;
|
private boolean safeToCancel;
|
||||||
|
private boolean pauseRequestedLastTick;
|
||||||
|
private boolean cancelRequested;
|
||||||
|
private boolean calcFailedLastTick;
|
||||||
|
|
||||||
|
private volatile AbstractNodeCostSearch inProgress;
|
||||||
private final Object pathCalcLock = new Object();
|
private final Object pathCalcLock = new Object();
|
||||||
|
|
||||||
private final Object pathPlanLock = new Object();
|
private final Object pathPlanLock = new Object();
|
||||||
@@ -72,8 +76,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
private void dispatchEvents() {
|
private void dispatchEvents() {
|
||||||
ArrayList<PathEvent> curr = new ArrayList<>();
|
ArrayList<PathEvent> curr = new ArrayList<>();
|
||||||
toDispatch.drainTo(curr);
|
toDispatch.drainTo(curr);
|
||||||
|
calcFailedLastTick = curr.contains(PathEvent.CALC_FAILED);
|
||||||
for (PathEvent event : curr) {
|
for (PathEvent event : curr) {
|
||||||
Baritone.INSTANCE.getGameEventHandler().onPathEvent(event);
|
baritone.getGameEventHandler().onPathEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,28 +86,40 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
public void onTick(TickEvent event) {
|
public void onTick(TickEvent event) {
|
||||||
dispatchEvents();
|
dispatchEvents();
|
||||||
if (event.getType() == TickEvent.Type.OUT) {
|
if (event.getType() == TickEvent.Type.OUT) {
|
||||||
cancel();
|
secretInternalSegmentCancel();
|
||||||
|
baritone.getPathingControlManager().cancelEverything();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
baritone.getPathingControlManager().preTick();
|
||||||
tickPath();
|
tickPath();
|
||||||
dispatchEvents();
|
dispatchEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickPath() {
|
private void tickPath() {
|
||||||
|
if (pauseRequestedLastTick && safeToCancel) {
|
||||||
|
pauseRequestedLastTick = false;
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cancelRequested) {
|
||||||
|
cancelRequested = false;
|
||||||
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
|
}
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean safe = current.onTick();
|
safeToCancel = current.onTick();
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
if (current.failed() || current.finished()) {
|
if (current.failed() || current.finished()) {
|
||||||
current = null;
|
current = null;
|
||||||
if (goal == null || goal.isInGoal(playerFeet())) {
|
if (goal == null || goal.isInGoal(ctx.playerFeet())) {
|
||||||
logDebug("All done. At " + goal);
|
logDebug("All done. At " + goal);
|
||||||
queuePathEvent(PathEvent.AT_GOAL);
|
queuePathEvent(PathEvent.AT_GOAL);
|
||||||
next = null;
|
next = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (next != null && !next.getPath().positions().contains(playerFeet())) {
|
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
|
// if the current path failed, we may not actually be on the next one, so make sure
|
||||||
logDebug("Discarding next path as it does not contain current position");
|
logDebug("Discarding next path as it does not contain current position");
|
||||||
// for example if we had a nicely planned ahead path that starts where current ends
|
// for example if we had a nicely planned ahead path that starts where current ends
|
||||||
@@ -123,18 +140,18 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
}
|
}
|
||||||
// at this point, current just ended, but we aren't in the goal and have no plan for the future
|
// at this point, current just ended, but we aren't in the goal and have no plan for the future
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (isPathCalcInProgress) {
|
if (inProgress != null) {
|
||||||
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
||||||
// if we aren't calculating right now
|
// if we aren't calculating right now
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
queuePathEvent(PathEvent.CALC_STARTED);
|
queuePathEvent(PathEvent.CALC_STARTED);
|
||||||
findPathInNewThread(pathStart(), true, Optional.empty());
|
findPathInNewThread(pathStart(), true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// at this point, we know current is in progress
|
// at this point, we know current is in progress
|
||||||
if (safe && next != null && next.snipsnapifpossible()) {
|
if (safeToCancel && next != null && next.snipsnapifpossible()) {
|
||||||
// a movement just ended; jump directly onto the next path
|
// a movement just ended; jump directly onto the next path
|
||||||
logDebug("Splicing into planned next path early...");
|
logDebug("Splicing into planned next path early...");
|
||||||
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
||||||
@@ -143,8 +160,12 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
current.onTick();
|
current.onTick();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
current = current.trySplice(next);
|
||||||
|
if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) {
|
||||||
|
next = null;
|
||||||
|
}
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (isPathCalcInProgress) {
|
if (inProgress != null) {
|
||||||
// if we aren't calculating right now
|
// if we aren't calculating right now
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -160,7 +181,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
// and this path has 5 seconds or less left
|
// and this path has 5 seconds or less left
|
||||||
logDebug("Path almost over. Planning ahead...");
|
logDebug("Path almost over. Planning ahead...");
|
||||||
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
||||||
findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath()));
|
findPathInNewThread(current.getPath().getDest(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,14 +212,13 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void secretInternalSetGoal(Goal goal) {
|
||||||
public void setGoal(Goal goal) {
|
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setGoalAndPath(Goal goal) {
|
public boolean secretInternalSetGoalAndPath(Goal goal) {
|
||||||
setGoal(goal);
|
secretInternalSetGoal(goal);
|
||||||
return path();
|
return secretInternalPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -217,8 +237,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<IPathFinder> getPathFinder() {
|
public Optional<AbstractNodeCostSearch> getInProgress() {
|
||||||
return Optional.ofNullable(AbstractNodeCostSearch.currentlyRunning());
|
return Optional.ofNullable(inProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -226,18 +246,61 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return this.current != null;
|
return this.current != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSafeToCancel() {
|
||||||
|
return current == null || safeToCancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestPause() {
|
||||||
|
pauseRequestedLastTick = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean cancelSegmentIfSafe() {
|
||||||
|
if (isSafeToCancel()) {
|
||||||
|
secretInternalSegmentCancel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public boolean cancelEverything() {
|
||||||
|
boolean doIt = isSafeToCancel();
|
||||||
|
if (doIt) {
|
||||||
|
secretInternalSegmentCancel();
|
||||||
|
}
|
||||||
|
baritone.getPathingControlManager().cancelEverything();
|
||||||
|
return doIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean calcFailedLastTick() { // NOT exposed on public api
|
||||||
|
return calcFailedLastTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void softCancelIfSafe() {
|
||||||
|
if (!isSafeToCancel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
current = null;
|
||||||
|
next = null;
|
||||||
|
cancelRequested = true;
|
||||||
|
getInProgress().ifPresent(AbstractNodeCostSearch::cancel); // only cancel ours
|
||||||
|
// do everything BUT clear keys
|
||||||
|
}
|
||||||
|
|
||||||
|
// just cancel the current path
|
||||||
|
public void secretInternalSegmentCancel() {
|
||||||
queuePathEvent(PathEvent.CANCELED);
|
queuePathEvent(PathEvent.CANCELED);
|
||||||
current = null;
|
current = null;
|
||||||
next = null;
|
next = null;
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
|
||||||
BlockBreakHelper.stopBreakingBlock();
|
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forceCancel() { // NOT exposed on public api
|
public void forceCancel() { // NOT exposed on public api
|
||||||
isPathCalcInProgress = false;
|
cancelEverything();
|
||||||
|
secretInternalSegmentCancel();
|
||||||
|
inProgress = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -245,12 +308,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
*
|
*
|
||||||
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
||||||
*/
|
*/
|
||||||
@Override
|
public boolean secretInternalPath() {
|
||||||
public boolean path() {
|
|
||||||
if (goal == null) {
|
if (goal == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (goal.isInGoal(playerFeet())) {
|
if (goal.isInGoal(ctx.playerFeet())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
@@ -258,11 +320,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (isPathCalcInProgress) {
|
if (inProgress != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
queuePathEvent(PathEvent.CALC_STARTED);
|
queuePathEvent(PathEvent.CALC_STARTED);
|
||||||
findPathInNewThread(pathStart(), true, Optional.empty());
|
findPathInNewThread(pathStart(), true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -273,12 +335,12 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
*
|
*
|
||||||
* @return The starting {@link BlockPos} for a new path
|
* @return The starting {@link BlockPos} for a new path
|
||||||
*/
|
*/
|
||||||
public BlockPos pathStart() {
|
public BlockPos pathStart() { // TODO move to a helper or util class
|
||||||
BetterBlockPos feet = playerFeet();
|
BetterBlockPos feet = ctx.playerFeet();
|
||||||
if (!MovementHelper.canWalkOn(feet.down())) {
|
if (!MovementHelper.canWalkOn(ctx, feet.down())) {
|
||||||
if (player().onGround) {
|
if (ctx.player().onGround) {
|
||||||
double playerX = player().posX;
|
double playerX = ctx.player().posX;
|
||||||
double playerZ = player().posZ;
|
double playerZ = ctx.player().posZ;
|
||||||
ArrayList<BetterBlockPos> closest = new ArrayList<>();
|
ArrayList<BetterBlockPos> closest = new ArrayList<>();
|
||||||
for (int dx = -1; dx <= 1; dx++) {
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
for (int dz = -1; dz <= 1; dz++) {
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
@@ -294,9 +356,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
// can't possibly be sneaking off of this one, we're too far away
|
// can't possibly be sneaking off of this one, we're too far away
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MovementHelper.canWalkOn(possibleSupport.down()) && MovementHelper.canWalkThrough(possibleSupport) && MovementHelper.canWalkThrough(possibleSupport.up())) {
|
if (MovementHelper.canWalkOn(ctx, possibleSupport.down()) && MovementHelper.canWalkThrough(ctx, possibleSupport) && MovementHelper.canWalkThrough(ctx, possibleSupport.up())) {
|
||||||
// this is plausible
|
// this is plausible
|
||||||
logDebug("Faking path start assuming player is standing off the edge of a block");
|
//logDebug("Faking path start assuming player is standing off the edge of a block");
|
||||||
return possibleSupport;
|
return possibleSupport;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,8 +366,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
} else {
|
} else {
|
||||||
// !onGround
|
// !onGround
|
||||||
// we're in the middle of a jump
|
// we're in the middle of a jump
|
||||||
if (MovementHelper.canWalkOn(feet.down().down())) {
|
if (MovementHelper.canWalkOn(ctx, feet.down().down())) {
|
||||||
logDebug("Faking path start assuming player is midair and falling");
|
//logDebug("Faking path start assuming player is midair and falling");
|
||||||
return feet.down();
|
return feet.down();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,23 +381,46 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
* @param start
|
* @param start
|
||||||
* @param talkAboutIt
|
* @param talkAboutIt
|
||||||
*/
|
*/
|
||||||
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt, final Optional<IPath> previous) {
|
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt) {
|
||||||
synchronized (pathCalcLock) {
|
// this must be called with synchronization on pathCalcLock!
|
||||||
if (isPathCalcInProgress) {
|
// actually, we can check this, muahaha
|
||||||
throw new IllegalStateException("Already doing it");
|
if (!Thread.holdsLock(pathCalcLock)) {
|
||||||
}
|
throw new IllegalStateException("Must be called with synchronization on pathCalcLock");
|
||||||
isPathCalcInProgress = true;
|
// why do it this way? it's already indented so much that putting the whole thing in a synchronized(pathCalcLock) was just too much lol
|
||||||
}
|
}
|
||||||
CalculationContext context = new CalculationContext(); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
|
if (inProgress != null) {
|
||||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
throw new IllegalStateException("Already doing it"); // should have been checked by caller
|
||||||
|
}
|
||||||
|
Goal goal = this.goal;
|
||||||
|
if (goal == null) {
|
||||||
|
logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long primaryTimeout;
|
||||||
|
long failureTimeout;
|
||||||
|
if (current == null) {
|
||||||
|
primaryTimeout = Baritone.settings().primaryTimeoutMS.get();
|
||||||
|
failureTimeout = Baritone.settings().failureTimeoutMS.get();
|
||||||
|
} else {
|
||||||
|
primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.get();
|
||||||
|
failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.get();
|
||||||
|
}
|
||||||
|
CalculationContext context = new CalculationContext(baritone); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
|
||||||
|
AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context);
|
||||||
|
if (!Objects.equals(pathfinder.getGoal(), goal)) {
|
||||||
|
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
||||||
|
}
|
||||||
|
inProgress = pathfinder;
|
||||||
|
Baritone.getExecutor().execute(() -> {
|
||||||
if (talkAboutIt) {
|
if (talkAboutIt) {
|
||||||
logDebug("Starting to search for path from " + start + " to " + goal);
|
logDebug("Starting to search for path from " + start + " to " + goal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<IPath> path = findPath(start, previous, context);
|
PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout);
|
||||||
|
Optional<IPath> path = calcResult.getPath();
|
||||||
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
||||||
path = path.map(p -> {
|
path = path.map(p -> {
|
||||||
IPath result = p.cutoffAtLoadedChunks();
|
IPath result = p.cutoffAtLoadedChunks(context.world());
|
||||||
|
|
||||||
if (result instanceof CutoffPath) {
|
if (result instanceof CutoffPath) {
|
||||||
logDebug("Cutting off path at edge of loaded chunks");
|
logDebug("Cutting off path at edge of loaded chunks");
|
||||||
@@ -356,7 +441,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}).map(PathExecutor::new);
|
}).map(p -> new PathExecutor(this, p));
|
||||||
|
|
||||||
synchronized (pathPlanLock) {
|
synchronized (pathPlanLock) {
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
@@ -364,7 +449,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||||
current = executor.get();
|
current = executor.get();
|
||||||
} else {
|
} else {
|
||||||
queuePathEvent(PathEvent.CALC_FAILED);
|
if (calcResult.getType() != PathCalculationResult.Type.CANCELLATION && calcResult.getType() != PathCalculationResult.Type.EXCEPTION) {
|
||||||
|
// don't dispatch CALC_FAILED on cancellation
|
||||||
|
queuePathEvent(PathEvent.CALC_FAILED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
@@ -378,88 +466,37 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
throw new IllegalStateException("I have no idea what to do with this path");
|
throw new IllegalStateException("I have no idea what to do with this path");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (talkAboutIt && current != null && current.getPath() != null) {
|
||||||
|
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
||||||
if (talkAboutIt && current != null && current.getPath() != null) {
|
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||||
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
} else {
|
||||||
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||||
} else {
|
}
|
||||||
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
}
|
||||||
|
synchronized (pathCalcLock) {
|
||||||
|
inProgress = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
synchronized (pathCalcLock) {
|
|
||||||
isPathCalcInProgress = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
|
||||||
* Actually do the pathing
|
Goal transformed = goal;
|
||||||
*
|
|
||||||
* @param start
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous, CalculationContext context) {
|
|
||||||
Goal goal = this.goal;
|
|
||||||
if (goal == null) {
|
|
||||||
logDebug("no goal");
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
||||||
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||||
if (world().getChunk(pos) instanceof EmptyChunk) {
|
if (context.world().getChunk(pos) instanceof EmptyChunk) {
|
||||||
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
||||||
goal = new GoalXZ(pos.getX(), pos.getZ());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
long timeout;
|
HashSet<Long> favoredPositions = null;
|
||||||
if (current == null) {
|
if (Baritone.settings().backtrackCostFavoringCoefficient.get() != 1D && previous != null) {
|
||||||
timeout = Baritone.settings().pathTimeoutMS.<Long>get();
|
favoredPositions = previous.positions().stream().map(BetterBlockPos::longHash).collect(Collectors.toCollection(HashSet::new));
|
||||||
} else {
|
|
||||||
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
|
|
||||||
}
|
|
||||||
Optional<HashSet<Long>> favoredPositions;
|
|
||||||
if (Baritone.settings().backtrackCostFavoringCoefficient.get() == 1D) {
|
|
||||||
favoredPositions = Optional.empty();
|
|
||||||
} else {
|
|
||||||
favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(BetterBlockPos::longHash)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions, context);
|
|
||||||
return pf.calculate(timeout);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logDebug("Pathing exception: " + e);
|
|
||||||
e.printStackTrace();
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void revalidateGoal() {
|
|
||||||
if (!Baritone.settings().cancelOnGoalInvalidation.get()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
synchronized (pathPlanLock) {
|
|
||||||
if (current == null || goal == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Goal intended = current.getPath().getGoal();
|
|
||||||
BlockPos end = current.getPath().getDest();
|
|
||||||
if (intended.isInGoal(end) && !goal.isInGoal(end)) {
|
|
||||||
// this path used to end in the goal
|
|
||||||
// but the goal has changed, so there's no reason to continue...
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoredPositions, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRenderPass(RenderEvent event) {
|
public void onRenderPass(RenderEvent event) {
|
||||||
PathRenderer.render(event, this);
|
PathRenderer.render(event, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable() {
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-8
@@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.api.cache.IBlockTypeAccess;
|
|
||||||
import baritone.utils.Helper;
|
|
||||||
import baritone.utils.pathing.PathingBlockType;
|
import baritone.utils.pathing.PathingBlockType;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
@@ -29,9 +27,9 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/3/2018 1:04 AM
|
* @since 8/3/2018
|
||||||
*/
|
*/
|
||||||
public final class CachedChunk implements IBlockTypeAccess, Helper {
|
public final class CachedChunk {
|
||||||
|
|
||||||
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
|
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
|
||||||
|
|
||||||
@@ -143,8 +141,7 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
|
|||||||
calculateHeightMap();
|
calculateHeightMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public final IBlockState getBlock(int x, int y, int z, int dimension) {
|
||||||
public final IBlockState getBlock(int x, int y, int z) {
|
|
||||||
int internalPos = z << 4 | x;
|
int internalPos = z << 4 | x;
|
||||||
if (heightMap[internalPos] == y) {
|
if (heightMap[internalPos] == y) {
|
||||||
// we have this exact block, it's a surface block
|
// we have this exact block, it's a surface block
|
||||||
@@ -155,10 +152,10 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
|
|||||||
return overview[internalPos];
|
return overview[internalPos];
|
||||||
}
|
}
|
||||||
PathingBlockType type = getType(x, y, z);
|
PathingBlockType type = getType(x, y, z);
|
||||||
if (type == PathingBlockType.SOLID && y == 127 && mc.player.dimension == -1) {
|
if (type == PathingBlockType.SOLID && y == 127 && dimension == -1) {
|
||||||
return Blocks.BEDROCK.getDefaultState();
|
return Blocks.BEDROCK.getDefaultState();
|
||||||
}
|
}
|
||||||
return ChunkPacker.pathingTypeToBlock(type);
|
return ChunkPacker.pathingTypeToBlock(type, dimension);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PathingBlockType getType(int x, int y, int z) {
|
private PathingBlockType getType(int x, int y, int z) {
|
||||||
|
|||||||
+6
-3
@@ -32,7 +32,7 @@ import java.util.zip.GZIPOutputStream;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/3/2018 9:35 PM
|
* @since 8/3/2018
|
||||||
*/
|
*/
|
||||||
public final class CachedRegion implements ICachedRegion {
|
public final class CachedRegion implements ICachedRegion {
|
||||||
|
|
||||||
@@ -59,22 +59,25 @@ public final class CachedRegion implements ICachedRegion {
|
|||||||
*/
|
*/
|
||||||
private final int z;
|
private final int z;
|
||||||
|
|
||||||
|
private final int dimension;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has this region been modified since its most recent load or save
|
* Has this region been modified since its most recent load or save
|
||||||
*/
|
*/
|
||||||
private boolean hasUnsavedChanges;
|
private boolean hasUnsavedChanges;
|
||||||
|
|
||||||
CachedRegion(int x, int z) {
|
CachedRegion(int x, int z, int dimension) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
this.hasUnsavedChanges = false;
|
this.hasUnsavedChanges = false;
|
||||||
|
this.dimension = dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final IBlockState getBlock(int x, int y, int z) {
|
public final IBlockState getBlock(int x, int y, int z) {
|
||||||
CachedChunk chunk = chunks[x >> 4][z >> 4];
|
CachedChunk chunk = chunks[x >> 4][z >> 4];
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
return chunk.getBlock(x & 15, y, z & 15);
|
return chunk.getBlock(x & 15, y, z & 15, dimension);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-13
@@ -18,7 +18,10 @@
|
|||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.cache.ICachedWorld;
|
import baritone.api.cache.ICachedWorld;
|
||||||
|
import baritone.api.cache.IWorldData;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
@@ -35,7 +38,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 12:02 AM
|
* @since 8/4/2018
|
||||||
*/
|
*/
|
||||||
public final class CachedWorld implements ICachedWorld, Helper {
|
public final class CachedWorld implements ICachedWorld, Helper {
|
||||||
|
|
||||||
@@ -56,7 +59,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
|
|
||||||
private final LinkedBlockingQueue<Chunk> toPack = new LinkedBlockingQueue<>();
|
private final LinkedBlockingQueue<Chunk> toPack = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
CachedWorld(Path directory) {
|
private final int dimension;
|
||||||
|
|
||||||
|
CachedWorld(Path directory, int dimension) {
|
||||||
if (!Files.exists(directory)) {
|
if (!Files.exists(directory)) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(directory);
|
Files.createDirectories(directory);
|
||||||
@@ -64,11 +69,12 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.directory = directory.toString();
|
this.directory = directory.toString();
|
||||||
|
this.dimension = dimension;
|
||||||
System.out.println("Cached world directory: " + directory);
|
System.out.println("Cached world directory: " + directory);
|
||||||
// Insert an invalid region element
|
// Insert an invalid region element
|
||||||
cachedRegions.put(0, null);
|
cachedRegions.put(0, null);
|
||||||
Baritone.INSTANCE.getExecutor().execute(new PackerThread());
|
Baritone.getExecutor().execute(new PackerThread());
|
||||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
Baritone.getExecutor().execute(() -> {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(30000);
|
Thread.sleep(30000);
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -103,10 +109,10 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq) {
|
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq) {
|
||||||
LinkedList<BlockPos> res = new LinkedList<>();
|
LinkedList<BlockPos> res = new LinkedList<>();
|
||||||
int playerRegionX = playerFeet().getX() >> 9;
|
int centerRegionX = centerX >> 9;
|
||||||
int playerRegionZ = playerFeet().getZ() >> 9;
|
int centerRegionZ = centerZ >> 9;
|
||||||
|
|
||||||
int searchRadius = 0;
|
int searchRadius = 0;
|
||||||
while (searchRadius <= maxRegionDistanceSq) {
|
while (searchRadius <= maxRegionDistanceSq) {
|
||||||
@@ -116,8 +122,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
if (distance != searchRadius) {
|
if (distance != searchRadius) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int regionX = xoff + playerRegionX;
|
int regionX = xoff + centerRegionX;
|
||||||
int regionZ = zoff + playerRegionZ;
|
int regionZ = zoff + centerRegionZ;
|
||||||
CachedRegion region = getOrCreateRegion(regionX, regionZ);
|
CachedRegion region = getOrCreateRegion(regionX, regionZ);
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
// TODO: 100% verify if this or addAll is faster.
|
// TODO: 100% verify if this or addAll is faster.
|
||||||
@@ -165,6 +171,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
* Delete regions that are too far from the player
|
* Delete regions that are too far from the player
|
||||||
*/
|
*/
|
||||||
private synchronized void prune() {
|
private synchronized void prune() {
|
||||||
|
if (!Baritone.settings().pruneRegionsFromRAM.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
BlockPos pruneCenter = guessPosition();
|
BlockPos pruneCenter = guessPosition();
|
||||||
for (CachedRegion region : allRegions()) {
|
for (CachedRegion region : allRegions()) {
|
||||||
if (region == null) {
|
if (region == null) {
|
||||||
@@ -184,9 +193,11 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
|
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
|
||||||
*/
|
*/
|
||||||
private BlockPos guessPosition() {
|
private BlockPos guessPosition() {
|
||||||
WorldData data = WorldProvider.INSTANCE.getCurrentWorld();
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
if (data != null && data.getCachedWorld() == this) {
|
IWorldData data = ibaritone.getWorldProvider().getCurrentWorld();
|
||||||
return playerFeet();
|
if (data != null && data.getCachedWorld() == this) {
|
||||||
|
return ibaritone.getPlayerContext().playerFeet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CachedChunk mostRecentlyModified = null;
|
CachedChunk mostRecentlyModified = null;
|
||||||
for (CachedRegion region : allRegions()) {
|
for (CachedRegion region : allRegions()) {
|
||||||
@@ -238,7 +249,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
|||||||
*/
|
*/
|
||||||
private synchronized CachedRegion getOrCreateRegion(int regionX, int regionZ) {
|
private synchronized CachedRegion getOrCreateRegion(int regionX, int regionZ) {
|
||||||
return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> {
|
return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> {
|
||||||
CachedRegion newRegion = new CachedRegion(regionX, regionZ);
|
CachedRegion newRegion = new CachedRegion(regionX, regionZ, dimension);
|
||||||
newRegion.load(this.directory);
|
newRegion.load(this.directory);
|
||||||
return newRegion;
|
return newRegion;
|
||||||
});
|
});
|
||||||
|
|||||||
+7
-7
@@ -18,7 +18,6 @@
|
|||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.utils.Helper;
|
|
||||||
import baritone.utils.pathing.PathingBlockType;
|
import baritone.utils.pathing.PathingBlockType;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockDoublePlant;
|
import net.minecraft.block.BlockDoublePlant;
|
||||||
@@ -36,9 +35,9 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/3/2018 1:09 AM
|
* @since 8/3/2018
|
||||||
*/
|
*/
|
||||||
public final class ChunkPacker implements Helper {
|
public final class ChunkPacker {
|
||||||
|
|
||||||
private ChunkPacker() {}
|
private ChunkPacker() {}
|
||||||
|
|
||||||
@@ -93,7 +92,8 @@ public final class ChunkPacker implements Helper {
|
|||||||
|
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
|
https:
|
||||||
|
//www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int y = 255; y >= 0; y--) {
|
for (int y = 255; y >= 0; y--) {
|
||||||
@@ -125,7 +125,7 @@ public final class ChunkPacker implements Helper {
|
|||||||
|
|
||||||
private static PathingBlockType getPathingBlockType(IBlockState state) {
|
private static PathingBlockType getPathingBlockType(IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block.equals(Blocks.WATER)) {
|
if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) {
|
||||||
// only water source blocks are plausibly usable, flowing water should be avoid
|
// only water source blocks are plausibly usable, flowing water should be avoid
|
||||||
return PathingBlockType.WATER;
|
return PathingBlockType.WATER;
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ public final class ChunkPacker implements Helper {
|
|||||||
return PathingBlockType.SOLID;
|
return PathingBlockType.SOLID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IBlockState pathingTypeToBlock(PathingBlockType type) {
|
public static IBlockState pathingTypeToBlock(PathingBlockType type, int dimension) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AIR:
|
case AIR:
|
||||||
return Blocks.AIR.getDefaultState();
|
return Blocks.AIR.getDefaultState();
|
||||||
@@ -154,7 +154,7 @@ public final class ChunkPacker implements Helper {
|
|||||||
return Blocks.LAVA.getDefaultState();
|
return Blocks.LAVA.getDefaultState();
|
||||||
case SOLID:
|
case SOLID:
|
||||||
// Dimension solid types
|
// Dimension solid types
|
||||||
switch (mc.player.dimension) {
|
switch (dimension) {
|
||||||
case -1:
|
case -1:
|
||||||
return Blocks.NETHERRACK.getDefaultState();
|
return Blocks.NETHERRACK.getDefaultState();
|
||||||
case 0:
|
case 0:
|
||||||
|
|||||||
+3
-3
@@ -42,9 +42,9 @@ public class Waypoint implements IWaypoint {
|
|||||||
* Constructor called when a Waypoint is read from disk, adds the creationTimestamp
|
* Constructor called when a Waypoint is read from disk, adds the creationTimestamp
|
||||||
* as a parameter so that it is reserved after a waypoint is wrote to the disk.
|
* as a parameter so that it is reserved after a waypoint is wrote to the disk.
|
||||||
*
|
*
|
||||||
* @param name The waypoint name
|
* @param name The waypoint name
|
||||||
* @param tag The waypoint tag
|
* @param tag The waypoint tag
|
||||||
* @param location The waypoint location
|
* @param location The waypoint location
|
||||||
* @param creationTimestamp When the waypoint was created
|
* @param creationTimestamp When the waypoint was created
|
||||||
*/
|
*/
|
||||||
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
|
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
|
||||||
|
|||||||
+5
-3
@@ -35,15 +35,17 @@ public class WorldData implements IWorldData {
|
|||||||
private final Waypoints waypoints;
|
private final Waypoints waypoints;
|
||||||
//public final MapData map;
|
//public final MapData map;
|
||||||
public final Path directory;
|
public final Path directory;
|
||||||
|
public final int dimension;
|
||||||
|
|
||||||
WorldData(Path directory) {
|
WorldData(Path directory, int dimension) {
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.cache = new CachedWorld(directory.resolve("cache"));
|
this.cache = new CachedWorld(directory.resolve("cache"), dimension);
|
||||||
this.waypoints = new Waypoints(directory.resolve("waypoints"));
|
this.waypoints = new Waypoints(directory.resolve("waypoints"));
|
||||||
|
this.dimension = dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onClose() {
|
public void onClose() {
|
||||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
Baritone.getExecutor().execute(() -> {
|
||||||
System.out.println("Started saving the world in a new thread");
|
System.out.println("Started saving the world in a new thread");
|
||||||
cache.save();
|
cache.save();
|
||||||
});
|
});
|
||||||
|
|||||||
+21
-17
@@ -22,7 +22,6 @@ import baritone.api.cache.IWorldProvider;
|
|||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.accessor.IAnvilChunkLoader;
|
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||||
import baritone.utils.accessor.IChunkProviderServer;
|
import baritone.utils.accessor.IChunkProviderServer;
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
|
||||||
import net.minecraft.server.integrated.IntegratedServer;
|
import net.minecraft.server.integrated.IntegratedServer;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
|
|
||||||
@@ -37,13 +36,11 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/4/2018 11:06 AM
|
* @since 8/4/2018
|
||||||
*/
|
*/
|
||||||
public enum WorldProvider implements IWorldProvider, Helper {
|
public class WorldProvider implements IWorldProvider, Helper {
|
||||||
|
|
||||||
INSTANCE;
|
private static final Map<Path, WorldData> worldCache = new HashMap<>(); // this is how the bots have the same cached world
|
||||||
|
|
||||||
private final Map<Path, WorldData> worldCache = new HashMap<>();
|
|
||||||
|
|
||||||
private WorldData currentWorld;
|
private WorldData currentWorld;
|
||||||
|
|
||||||
@@ -52,13 +49,20 @@ public enum WorldProvider implements IWorldProvider, Helper {
|
|||||||
return this.currentWorld;
|
return this.currentWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void initWorld(WorldClient world) {
|
/**
|
||||||
int dimensionID = world.provider.getDimensionType().getId();
|
* Called when a new world is initialized to discover the
|
||||||
|
*
|
||||||
|
* @param dimension The ID of the world's dimension
|
||||||
|
*/
|
||||||
|
public final void initWorld(int dimension) {
|
||||||
File directory;
|
File directory;
|
||||||
File readme;
|
File readme;
|
||||||
|
|
||||||
IntegratedServer integratedServer = mc.getIntegratedServer();
|
IntegratedServer integratedServer = mc.getIntegratedServer();
|
||||||
|
|
||||||
|
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
|
||||||
if (integratedServer != null) {
|
if (integratedServer != null) {
|
||||||
WorldServer localServerWorld = integratedServer.getWorld(dimensionID);
|
WorldServer localServerWorld = integratedServer.getWorld(dimension);
|
||||||
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
|
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
|
||||||
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
|
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
|
||||||
directory = loader.getChunkSaveLocation();
|
directory = loader.getChunkSaveLocation();
|
||||||
@@ -71,27 +75,27 @@ public enum WorldProvider implements IWorldProvider, Helper {
|
|||||||
|
|
||||||
directory = new File(directory, "baritone");
|
directory = new File(directory, "baritone");
|
||||||
readme = directory;
|
readme = directory;
|
||||||
|
} else { // Otherwise, the server must be remote...
|
||||||
} else {
|
directory = new File(Baritone.getDir(), mc.getCurrentServerData().serverIP);
|
||||||
//remote
|
readme = Baritone.getDir();
|
||||||
directory = new File(Baritone.INSTANCE.getDir(), mc.getCurrentServerData().serverIP);
|
|
||||||
readme = Baritone.INSTANCE.getDir();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lol wtf is this baritone folder in my minecraft save?
|
// lol wtf is this baritone folder in my minecraft save?
|
||||||
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {
|
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {
|
||||||
// good thing we have a readme
|
// good thing we have a readme
|
||||||
out.write("https://github.com/cabaletta/baritone\n".getBytes());
|
out.write("https://github.com/cabaletta/baritone\n".getBytes());
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
|
|
||||||
directory = new File(directory, "DIM" + dimensionID);
|
// We will actually store the world data in a subfolder: "DIM<id>"
|
||||||
Path dir = directory.toPath();
|
Path dir = new File(directory, "DIM" + dimension).toPath();
|
||||||
if (!Files.exists(dir)) {
|
if (!Files.exists(dir)) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(dir);
|
Files.createDirectories(dir);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Baritone world data dir: " + dir);
|
System.out.println("Baritone world data dir: " + dir);
|
||||||
this.currentWorld = this.worldCache.computeIfAbsent(dir, WorldData::new);
|
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void closeWorld() {
|
public final void closeWorld() {
|
||||||
|
|||||||
+7
-7
@@ -18,7 +18,7 @@
|
|||||||
package baritone.cache;
|
package baritone.cache;
|
||||||
|
|
||||||
import baritone.api.cache.IWorldScanner;
|
import baritone.api.cache.IWorldScanner;
|
||||||
import baritone.utils.Helper;
|
import baritone.api.utils.IPlayerContext;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
@@ -30,12 +30,12 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public enum WorldScanner implements IWorldScanner, Helper {
|
public enum WorldScanner implements IWorldScanner {
|
||||||
|
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BlockPos> scanChunkRadius(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
|
public List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
|
||||||
if (blocks.contains(null)) {
|
if (blocks.contains(null)) {
|
||||||
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blocks.toString());
|
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blocks.toString());
|
||||||
}
|
}
|
||||||
@@ -43,12 +43,12 @@ public enum WorldScanner implements IWorldScanner, Helper {
|
|||||||
if (blocks.isEmpty()) {
|
if (blocks.isEmpty()) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
ChunkProviderClient chunkProvider = world().getChunkProvider();
|
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
|
||||||
|
|
||||||
int maxSearchRadiusSq = maxSearchRadius * maxSearchRadius;
|
int maxSearchRadiusSq = maxSearchRadius * maxSearchRadius;
|
||||||
int playerChunkX = playerFeet().getX() >> 4;
|
int playerChunkX = ctx.playerFeet().getX() >> 4;
|
||||||
int playerChunkZ = playerFeet().getZ() >> 4;
|
int playerChunkZ = ctx.playerFeet().getZ() >> 4;
|
||||||
int playerY = playerFeet().getY();
|
int playerY = ctx.playerFeet().getY();
|
||||||
|
|
||||||
int searchRadiusSq = 0;
|
int searchRadiusSq = 0;
|
||||||
boolean foundWithinY = false;
|
boolean foundWithinY = false;
|
||||||
|
|||||||
@@ -20,75 +20,48 @@ package baritone.event;
|
|||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
import baritone.api.event.events.*;
|
import baritone.api.event.events.*;
|
||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
|
import baritone.api.event.listener.IEventBus;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
import baritone.api.utils.interfaces.Toggleable;
|
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.InputOverrideHandler;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import org.lwjgl.input.Keyboard;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 7/31/2018 11:04 PM
|
* @since 7/31/2018
|
||||||
*/
|
*/
|
||||||
public final class GameEventHandler implements IGameEventListener, Helper {
|
public final class GameEventHandler implements IEventBus, Helper {
|
||||||
|
|
||||||
private final ArrayList<IGameEventListener> listeners = new ArrayList<>();
|
private final Baritone baritone;
|
||||||
|
|
||||||
|
private final List<IGameEventListener> listeners = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
public GameEventHandler(Baritone baritone) {
|
||||||
|
this.baritone = baritone;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onTick(TickEvent event) {
|
public final void onTick(TickEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onTick(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onTick(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onPlayerUpdate(PlayerUpdateEvent event) {
|
public final void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onPlayerUpdate(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPlayerUpdate(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onProcessKeyBinds() {
|
public final void onProcessKeyBinds() {
|
||||||
InputOverrideHandler inputHandler = Baritone.INSTANCE.getInputOverrideHandler();
|
listeners.forEach(IGameEventListener::onProcessKeyBinds);
|
||||||
|
|
||||||
// Simulate the key being held down this tick
|
|
||||||
for (InputOverrideHandler.Input input : InputOverrideHandler.Input.values()) {
|
|
||||||
KeyBinding keyBinding = input.getKeyBinding();
|
|
||||||
|
|
||||||
if (inputHandler.isInputForcedDown(keyBinding) && !keyBinding.isKeyDown()) {
|
|
||||||
int keyCode = keyBinding.getKeyCode();
|
|
||||||
|
|
||||||
if (keyCode < Keyboard.KEYBOARD_SIZE) {
|
|
||||||
KeyBinding.onTick(keyCode < 0 ? keyCode + 100 : keyCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listeners.forEach(l -> {
|
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onProcessKeyBinds();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onSendChatMessage(ChatEvent event) {
|
public final void onSendChatMessage(ChatEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onSendChatMessage(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onSendChatMessage(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -97,118 +70,79 @@ public final class GameEventHandler implements IGameEventListener, Helper {
|
|||||||
ChunkEvent.Type type = event.getType();
|
ChunkEvent.Type type = event.getType();
|
||||||
|
|
||||||
boolean isPostPopulate = state == EventState.POST
|
boolean isPostPopulate = state == EventState.POST
|
||||||
&& type == ChunkEvent.Type.POPULATE;
|
&& (type == ChunkEvent.Type.POPULATE_FULL || type == ChunkEvent.Type.POPULATE_PARTIAL);
|
||||||
|
|
||||||
|
World world = baritone.getPlayerContext().world();
|
||||||
|
|
||||||
// Whenever the server sends us to another dimension, chunks are unloaded
|
// Whenever the server sends us to another dimension, chunks are unloaded
|
||||||
// technically after the new world has been loaded, so we perform a check
|
// technically after the new world has been loaded, so we perform a check
|
||||||
// to make sure the chunk being unloaded is already loaded.
|
// to make sure the chunk being unloaded is already loaded.
|
||||||
boolean isPreUnload = state == EventState.PRE
|
boolean isPreUnload = state == EventState.PRE
|
||||||
&& type == ChunkEvent.Type.UNLOAD
|
&& type == ChunkEvent.Type.UNLOAD
|
||||||
&& mc.world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
|
&& world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
|
||||||
|
|
||||||
if (isPostPopulate || isPreUnload) {
|
if (isPostPopulate || isPreUnload) {
|
||||||
WorldProvider.INSTANCE.ifWorldLoaded(world -> {
|
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
|
||||||
Chunk chunk = mc.world.getChunk(event.getX(), event.getZ());
|
Chunk chunk = world.getChunk(event.getX(), event.getZ());
|
||||||
world.getCachedWorld().queueForPacking(chunk);
|
worldData.getCachedWorld().queueForPacking(chunk);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onChunkEvent(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onChunkEvent(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onRenderPass(RenderEvent event) {
|
public final void onRenderPass(RenderEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onRenderPass(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onRenderPass(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onWorldEvent(WorldEvent event) {
|
public final void onWorldEvent(WorldEvent event) {
|
||||||
WorldProvider cache = WorldProvider.INSTANCE;
|
WorldProvider cache = baritone.getWorldProvider();
|
||||||
|
|
||||||
BlockStateInterface.clearCachedChunk();
|
|
||||||
|
|
||||||
if (event.getState() == EventState.POST) {
|
if (event.getState() == EventState.POST) {
|
||||||
cache.closeWorld();
|
cache.closeWorld();
|
||||||
if (event.getWorld() != null) {
|
if (event.getWorld() != null) {
|
||||||
cache.initWorld(event.getWorld());
|
cache.initWorld(event.getWorld().provider.getDimensionType().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onWorldEvent(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onWorldEvent(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onSendPacket(PacketEvent event) {
|
public final void onSendPacket(PacketEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onSendPacket(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onSendPacket(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onReceivePacket(PacketEvent event) {
|
public final void onReceivePacket(PacketEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onReceivePacket(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onReceivePacket(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerRotationMove(RotationMoveEvent event) {
|
public void onPlayerRotationMove(RotationMoveEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onPlayerRotationMove(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPlayerRotationMove(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
public void onBlockInteract(BlockInteractEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onBlockInteract(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onBlockInteract(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerDeath() {
|
public void onPlayerDeath() {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(IGameEventListener::onPlayerDeath);
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPlayerDeath();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPathEvent(PathEvent event) {
|
public void onPathEvent(PathEvent event) {
|
||||||
listeners.forEach(l -> {
|
listeners.forEach(l -> l.onPathEvent(event));
|
||||||
if (canDispatch(l)) {
|
|
||||||
l.onPathEvent(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final void registerEventListener(IGameEventListener listener) {
|
public final void registerEventListener(IGameEventListener listener) {
|
||||||
this.listeners.add(listener);
|
this.listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canDispatch(IGameEventListener listener) {
|
|
||||||
return !(listener instanceof Toggleable) || ((Toggleable) listener).isEnabled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import baritone.api.utils.BetterBlockPos;
|
|||||||
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
import baritone.utils.BlockStateInterface;
|
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
import baritone.utils.pathing.BetterWorldBorder;
|
import baritone.utils.pathing.BetterWorldBorder;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
@@ -40,17 +39,17 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||||
|
|
||||||
private final Optional<HashSet<Long>> favoredPositions;
|
private final HashSet<Long> favoredPositions;
|
||||||
private final CalculationContext calcContext;
|
private final CalculationContext calcContext;
|
||||||
|
|
||||||
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, Optional<HashSet<Long>> favoredPositions, CalculationContext context) {
|
public AStarPathFinder(int startX, int startY, int startZ, Goal goal, HashSet<Long> favoredPositions, CalculationContext context) {
|
||||||
super(startX, startY, startZ, goal);
|
super(startX, startY, startZ, goal, context);
|
||||||
this.favoredPositions = favoredPositions;
|
this.favoredPositions = favoredPositions;
|
||||||
this.calcContext = context;
|
this.calcContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Optional<IPath> calculate0(long timeout) {
|
protected Optional<IPath> calculate0(long primaryTimeout, long failureTimeout) {
|
||||||
startNode = getNodeAtPosition(startX, startY, startZ, BetterBlockPos.longHash(startX, startY, startZ));
|
startNode = getNodeAtPosition(startX, startY, startZ, BetterBlockPos.longHash(startX, startY, startZ));
|
||||||
startNode.cost = 0;
|
startNode.cost = 0;
|
||||||
startNode.combinedCost = startNode.estimatedCostToGoal;
|
startNode.combinedCost = startNode.estimatedCostToGoal;
|
||||||
@@ -64,25 +63,28 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
bestSoFar[i] = startNode;
|
bestSoFar[i] = startNode;
|
||||||
}
|
}
|
||||||
MutableMoveResult res = new MutableMoveResult();
|
MutableMoveResult res = new MutableMoveResult();
|
||||||
HashSet<Long> favored = favoredPositions.orElse(null);
|
HashSet<Long> favored = favoredPositions;
|
||||||
BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder());
|
BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world().getWorldBorder());
|
||||||
BlockStateInterface.clearCachedChunk();
|
|
||||||
long startTime = System.nanoTime() / 1000000L;
|
long startTime = System.nanoTime() / 1000000L;
|
||||||
boolean slowPath = Baritone.settings().slowPath.get();
|
boolean slowPath = Baritone.settings().slowPath.get();
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.<Long>get() + "ms instead of " + timeout + "ms");
|
logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.<Long>get() + "ms instead of " + primaryTimeout + "ms");
|
||||||
}
|
}
|
||||||
long timeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.<Long>get() : timeout);
|
long primaryTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.<Long>get() : primaryTimeout);
|
||||||
//long lastPrintout = 0;
|
long failureTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.<Long>get() : failureTimeout);
|
||||||
|
boolean failing = true;
|
||||||
int numNodes = 0;
|
int numNodes = 0;
|
||||||
int numMovementsConsidered = 0;
|
int numMovementsConsidered = 0;
|
||||||
int numEmptyChunk = 0;
|
int numEmptyChunk = 0;
|
||||||
boolean favoring = favoredPositions.isPresent();
|
boolean favoring = favored != null;
|
||||||
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
||||||
double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get();
|
double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get();
|
||||||
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
|
boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get();
|
||||||
loopBegin();
|
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) {
|
||||||
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && System.nanoTime() / 1000000L - timeoutTime < 0 && !cancelRequested) {
|
long now = System.nanoTime() / 1000000L;
|
||||||
|
if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (slowPath) {
|
if (slowPath) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.<Long>get());
|
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.<Long>get());
|
||||||
@@ -95,12 +97,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
numNodes++;
|
numNodes++;
|
||||||
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
|
if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
|
||||||
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
|
||||||
return Optional.of(new Path(startNode, currentNode, numNodes, goal));
|
return Optional.of(new Path(startNode, currentNode, numNodes, goal, calcContext));
|
||||||
}
|
}
|
||||||
for (Moves moves : Moves.values()) {
|
for (Moves moves : Moves.values()) {
|
||||||
int newX = currentNode.x + moves.xOffset;
|
int newX = currentNode.x + moves.xOffset;
|
||||||
int newZ = currentNode.z + moves.zOffset;
|
int newZ = currentNode.z + moves.zOffset;
|
||||||
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !BlockStateInterface.isLoaded(newX, newZ)) {
|
if ((newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) && !calcContext.isLoaded(newX, newZ)) {
|
||||||
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
|
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
|
||||||
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
|
if (!moves.dynamicXZ) { // only increment the counter if the movement would have gone out of bounds guaranteed
|
||||||
numEmptyChunk++;
|
numEmptyChunk++;
|
||||||
@@ -169,6 +171,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
}
|
}
|
||||||
bestHeuristicSoFar[i] = heuristic;
|
bestHeuristicSoFar[i] = heuristic;
|
||||||
bestSoFar[i] = neighbor;
|
bestSoFar[i] = neighbor;
|
||||||
|
if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
|
||||||
|
failing = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,7 +203,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
|||||||
System.out.println("But I'm going to do it anyway, because yolo");
|
System.out.println("But I'm going to do it anyway, because yolo");
|
||||||
}
|
}
|
||||||
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
|
System.out.println("Path goes for " + Math.sqrt(dist) + " blocks");
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal));
|
return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, calcContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
|
logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks");
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ import baritone.Baritone;
|
|||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.calc.IPathFinder;
|
import baritone.api.pathing.calc.IPathFinder;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.utils.PathCalculationResult;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
|
import baritone.utils.Helper;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -32,17 +35,14 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractNodeCostSearch implements IPathFinder {
|
public abstract class AbstractNodeCostSearch implements IPathFinder {
|
||||||
|
|
||||||
/**
|
|
||||||
* The currently running search task
|
|
||||||
*/
|
|
||||||
private static AbstractNodeCostSearch currentlyRunning = null;
|
|
||||||
|
|
||||||
protected final int startX;
|
protected final int startX;
|
||||||
protected final int startY;
|
protected final int startY;
|
||||||
protected final int startZ;
|
protected final int startZ;
|
||||||
|
|
||||||
protected final Goal goal;
|
protected final Goal goal;
|
||||||
|
|
||||||
|
private final CalculationContext context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a>
|
* @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a>
|
||||||
*/
|
*/
|
||||||
@@ -70,11 +70,12 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
*/
|
*/
|
||||||
protected final static double MIN_DIST_PATH = 5;
|
protected final static double MIN_DIST_PATH = 5;
|
||||||
|
|
||||||
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal) {
|
AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) {
|
||||||
this.startX = startX;
|
this.startX = startX;
|
||||||
this.startY = startY;
|
this.startY = startY;
|
||||||
this.startZ = startZ;
|
this.startZ = startZ;
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
|
this.context = context;
|
||||||
this.map = new Long2ObjectOpenHashMap<>(Baritone.settings().pathingMapDefaultSize.value, Baritone.settings().pathingMapLoadFactor.get());
|
this.map = new Long2ObjectOpenHashMap<>(Baritone.settings().pathingMapDefaultSize.value, Baritone.settings().pathingMapLoadFactor.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,32 +83,37 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
cancelRequested = true;
|
cancelRequested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Optional<IPath> calculate(long timeout) {
|
@Override
|
||||||
|
public synchronized PathCalculationResult calculate(long primaryTimeout, long failureTimeout) {
|
||||||
if (isFinished) {
|
if (isFinished) {
|
||||||
throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!");
|
throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!");
|
||||||
}
|
}
|
||||||
this.cancelRequested = false;
|
cancelRequested = false;
|
||||||
try {
|
try {
|
||||||
Optional<IPath> path = calculate0(timeout);
|
IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null);
|
||||||
path.ifPresent(IPath::postProcess);
|
|
||||||
isFinished = true;
|
isFinished = true;
|
||||||
return path;
|
if (cancelRequested) {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path);
|
||||||
|
}
|
||||||
|
if (path == null) {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.FAILURE);
|
||||||
|
}
|
||||||
|
if (goal.isInGoal(path.getDest())) {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_TO_GOAL, path);
|
||||||
|
} else {
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_SEGMENT, path);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Helper.HELPER.logDebug("Pathing exception: " + e);
|
||||||
|
e.printStackTrace();
|
||||||
|
return new PathCalculationResult(PathCalculationResult.Type.EXCEPTION);
|
||||||
} finally {
|
} finally {
|
||||||
// this is run regardless of what exception may or may not be raised by calculate0
|
// this is run regardless of what exception may or may not be raised by calculate0
|
||||||
currentlyRunning = null;
|
|
||||||
isFinished = true;
|
isFinished = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected abstract Optional<IPath> calculate0(long primaryTimeout, long failureTimeout);
|
||||||
* Don't set currentlyRunning to this until everything is all ready to go, and we're about to enter the main loop.
|
|
||||||
* For example, bestSoFar is null so bestPathSoFar (which gets bestSoFar[0]) could NPE if we set currentlyRunning before calculate0
|
|
||||||
*/
|
|
||||||
protected void loopBegin() {
|
|
||||||
currentlyRunning = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Optional<IPath> calculate0(long timeout);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the distance squared from the specified node to the start
|
* Determines the distance squared from the specified node to the start
|
||||||
@@ -141,30 +147,9 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forceCancel() {
|
|
||||||
currentlyRunning = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PathNode mostRecentNodeConsidered() {
|
|
||||||
return mostRecentConsidered;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PathNode bestNodeSoFar() {
|
|
||||||
return bestSoFar[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public PathNode startNode() {
|
|
||||||
return startNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<IPath> pathToMostRecentNodeConsidered() {
|
public Optional<IPath> pathToMostRecentNodeConsidered() {
|
||||||
try {
|
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context));
|
||||||
return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal));
|
|
||||||
} catch (IllegalStateException ex) {
|
|
||||||
System.out.println("Unable to construct path to render");
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int mapSize() {
|
protected int mapSize() {
|
||||||
@@ -173,7 +158,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<IPath> bestPathSoFar() {
|
public Optional<IPath> bestPathSoFar() {
|
||||||
if (startNode == null || bestSoFar[0] == null) {
|
if (startNode == null || bestSoFar == null) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < bestSoFar.length; i++) {
|
for (int i = 0; i < bestSoFar.length; i++) {
|
||||||
@@ -181,12 +166,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared
|
||||||
try {
|
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context));
|
||||||
return Optional.of(new Path(startNode, bestSoFar[i], 0, goal));
|
|
||||||
} catch (IllegalStateException ex) {
|
|
||||||
System.out.println("Unable to construct path to render");
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// instead of returning bestSoFar[0], be less misleading
|
// instead of returning bestSoFar[0], be less misleading
|
||||||
@@ -203,12 +183,4 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
public final Goal getGoal() {
|
public final Goal getGoal() {
|
||||||
return goal;
|
return goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<AbstractNodeCostSearch> getCurrentlyRunning() {
|
|
||||||
return Optional.ofNullable(currentlyRunning);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AbstractNodeCostSearch currentlyRunning() {
|
|
||||||
return currentlyRunning;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,16 @@
|
|||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.calc;
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
|
||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
import net.minecraft.client.Minecraft;
|
import baritone.pathing.path.CutoffPath;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import baritone.utils.Helper;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import baritone.utils.pathing.PathBase;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -38,7 +38,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
class Path implements IPath {
|
class Path extends PathBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The start position of this path
|
* The start position of this path
|
||||||
@@ -58,20 +58,26 @@ class Path implements IPath {
|
|||||||
|
|
||||||
private final List<Movement> movements;
|
private final List<Movement> movements;
|
||||||
|
|
||||||
|
private final List<PathNode> nodes;
|
||||||
|
|
||||||
private final Goal goal;
|
private final Goal goal;
|
||||||
|
|
||||||
private final int numNodes;
|
private final int numNodes;
|
||||||
|
|
||||||
|
private final CalculationContext context;
|
||||||
|
|
||||||
private volatile boolean verified;
|
private volatile boolean verified;
|
||||||
|
|
||||||
Path(PathNode start, PathNode end, int numNodes, Goal goal) {
|
Path(PathNode start, PathNode end, int numNodes, Goal goal, CalculationContext context) {
|
||||||
this.start = new BetterBlockPos(start.x, start.y, start.z);
|
this.start = new BetterBlockPos(start.x, start.y, start.z);
|
||||||
this.end = new BetterBlockPos(end.x, end.y, end.z);
|
this.end = new BetterBlockPos(end.x, end.y, end.z);
|
||||||
this.numNodes = numNodes;
|
this.numNodes = numNodes;
|
||||||
this.path = new ArrayList<>();
|
this.path = new ArrayList<>();
|
||||||
this.movements = new ArrayList<>();
|
this.movements = new ArrayList<>();
|
||||||
|
this.nodes = new ArrayList<>();
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
assemblePath(start, end);
|
this.context = context;
|
||||||
|
assemblePath(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,88 +86,80 @@ class Path implements IPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assembles this path given the start and end nodes.
|
* Assembles this path given the end node.
|
||||||
*
|
*
|
||||||
* @param start The start node
|
* @param end The end node
|
||||||
* @param end The end node
|
|
||||||
*/
|
*/
|
||||||
private void assemblePath(PathNode start, PathNode end) {
|
private void assemblePath(PathNode end) {
|
||||||
if (!path.isEmpty() || !movements.isEmpty()) {
|
if (!path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
PathNode current = end;
|
PathNode current = end;
|
||||||
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
|
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
|
||||||
|
LinkedList<PathNode> tempNodes = new LinkedList();
|
||||||
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
||||||
// Instead, do it into a linked list, then convert at the end
|
// Instead, do it into a linked list, then convert at the end
|
||||||
while (!current.equals(start)) {
|
while (current != null) {
|
||||||
|
tempNodes.addFirst(current);
|
||||||
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
|
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
|
||||||
current = current.previous;
|
current = current.previous;
|
||||||
}
|
}
|
||||||
tempPath.addFirst(this.start);
|
|
||||||
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
|
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
|
||||||
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
||||||
// to performantly do that conversion since it knows the length.
|
// to performantly do that conversion since it knows the length.
|
||||||
path.addAll(tempPath);
|
path.addAll(tempPath);
|
||||||
|
nodes.addAll(tempNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private boolean assembleMovements() {
|
||||||
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
|
||||||
*/
|
|
||||||
private void sanityCheck() {
|
|
||||||
if (!start.equals(path.get(0))) {
|
|
||||||
throw new IllegalStateException("Start node does not equal first path element");
|
|
||||||
}
|
|
||||||
if (!end.equals(path.get(path.size() - 1))) {
|
|
||||||
throw new IllegalStateException("End node does not equal last path element");
|
|
||||||
}
|
|
||||||
if (path.size() != movements.size() + 1) {
|
|
||||||
throw new IllegalStateException("Size of path array is unexpected");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < path.size() - 1; i++) {
|
|
||||||
BlockPos src = path.get(i);
|
|
||||||
BlockPos dest = path.get(i + 1);
|
|
||||||
Movement movement = movements.get(i);
|
|
||||||
if (!src.equals(movement.getSrc())) {
|
|
||||||
throw new IllegalStateException("Path source is not equal to the movement source");
|
|
||||||
}
|
|
||||||
if (!dest.equals(movement.getDest())) {
|
|
||||||
throw new IllegalStateException("Path destination is not equal to the movement destination");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assembleMovements() {
|
|
||||||
if (path.isEmpty() || !movements.isEmpty()) {
|
if (path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < path.size() - 1; i++) {
|
for (int i = 0; i < path.size() - 1; i++) {
|
||||||
movements.add(runBackwards(path.get(i), path.get(i + 1)));
|
double cost = nodes.get(i + 1).cost - nodes.get(i).cost;
|
||||||
|
Movement move = runBackwards(path.get(i), path.get(i + 1), cost);
|
||||||
|
if (move == null) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
movements.add(move);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Movement runBackwards(BetterBlockPos src, BetterBlockPos dest) { // TODO this is horrifying
|
private Movement runBackwards(BetterBlockPos src, BetterBlockPos dest, double cost) {
|
||||||
for (Moves moves : Moves.values()) {
|
for (Moves moves : Moves.values()) {
|
||||||
Movement move = moves.apply0(src);
|
Movement move = moves.apply0(context, src);
|
||||||
if (move.getDest().equals(dest)) {
|
if (move.getDest().equals(dest)) {
|
||||||
// TODO instead of recalculating here, could we take pathNode.cost - pathNode.prevNode.cost to get the cost as-calculated?
|
// have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
|
||||||
move.recalculateCost(); // have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
|
move.override(cost);
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this is no longer called from bestPathSoFar, now it's in postprocessing
|
// this is no longer called from bestPathSoFar, now it's in postprocessing
|
||||||
throw new IllegalStateException("Movement became impossible during calculation " + src + " " + dest + " " + dest.subtract(src));
|
Helper.HELPER.logDebug("Movement became impossible during calculation " + src + " " + dest + " " + dest.subtract(src));
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postProcess() {
|
public IPath postProcess() {
|
||||||
if (verified) {
|
if (verified) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
verified = true;
|
verified = true;
|
||||||
assembleMovements();
|
boolean failed = assembleMovements();
|
||||||
|
movements.forEach(m -> m.checkLoadedChunk(context));
|
||||||
|
|
||||||
|
if (failed) { // at least one movement became impossible during calculation
|
||||||
|
CutoffPath res = new CutoffPath(this, movements().size());
|
||||||
|
if (res.movements().size() != movements.size()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
// more post processing here
|
// more post processing here
|
||||||
movements.forEach(Movement::checkLoadedChunk);
|
|
||||||
sanityCheck();
|
sanityCheck();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,28 +189,4 @@ class Path implements IPath {
|
|||||||
public BetterBlockPos getDest() {
|
public BetterBlockPos getDest() {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPath cutoffAtLoadedChunks() {
|
|
||||||
for (int i = 0; i < positions().size(); i++) {
|
|
||||||
BlockPos pos = positions().get(i);
|
|
||||||
if (Minecraft.getMinecraft().world.getChunk(pos) instanceof EmptyChunk) {
|
|
||||||
return new CutoffPath(this, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPath staticCutoff(Goal destination) {
|
|
||||||
if (length() < BaritoneAPI.getSettings().pathCutoffMinimumLength.get()) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
if (destination == null || destination.isInGoal(getDest())) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
double factor = BaritoneAPI.getSettings().pathCutoffFactor.get();
|
|
||||||
int newLength = (int) (length() * factor);
|
|
||||||
return new CutoffPath(this, newLength);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,23 +18,35 @@
|
|||||||
package baritone.pathing.movement;
|
package baritone.pathing.movement;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.Baritone;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.pathing.movement.ActionCosts;
|
import baritone.api.pathing.movement.ActionCosts;
|
||||||
import baritone.utils.Helper;
|
import baritone.cache.WorldData;
|
||||||
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.ToolSet;
|
import baritone.utils.ToolSet;
|
||||||
import baritone.utils.pathing.BetterWorldBorder;
|
import baritone.utils.pathing.BetterWorldBorder;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Brady
|
* @author Brady
|
||||||
* @since 8/7/2018 4:30 PM
|
* @since 8/7/2018
|
||||||
*/
|
*/
|
||||||
public class CalculationContext implements Helper {
|
public class CalculationContext {
|
||||||
|
|
||||||
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
private static final ItemStack STACK_BUCKET_WATER = new ItemStack(Items.WATER_BUCKET);
|
||||||
|
|
||||||
|
private final IBaritone baritone;
|
||||||
|
private final EntityPlayerSP player;
|
||||||
|
private final World world;
|
||||||
|
private final WorldData worldData;
|
||||||
|
private final BlockStateInterface bsi;
|
||||||
private final ToolSet toolSet;
|
private final ToolSet toolSet;
|
||||||
private final boolean hasWaterBucket;
|
private final boolean hasWaterBucket;
|
||||||
private final boolean hasThrowaway;
|
private final boolean hasThrowaway;
|
||||||
@@ -47,16 +59,22 @@ public class CalculationContext implements Helper {
|
|||||||
private final double breakBlockAdditionalCost;
|
private final double breakBlockAdditionalCost;
|
||||||
private final BetterWorldBorder worldBorder;
|
private final BetterWorldBorder worldBorder;
|
||||||
|
|
||||||
public CalculationContext() {
|
public CalculationContext(IBaritone baritone) {
|
||||||
this.toolSet = new ToolSet();
|
this.baritone = baritone;
|
||||||
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(false);
|
this.player = baritone.getPlayerContext().player();
|
||||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player().inventory.getSlotFor(STACK_BUCKET_WATER)) && !world().provider.isNether();
|
this.world = baritone.getPlayerContext().world();
|
||||||
this.canSprint = Baritone.settings().allowSprint.get() && player().getFoodStats().getFoodLevel() > 6;
|
this.worldData = (WorldData) baritone.getWorldProvider().getCurrentWorld();
|
||||||
|
this.bsi = new BlockStateInterface(world, worldData); // TODO TODO TODO
|
||||||
|
// new CalculationContext() needs to happen, can't add an argument (i'll beat you), can we get the world provider from currentlyTicking?
|
||||||
|
this.toolSet = new ToolSet(player);
|
||||||
|
this.hasThrowaway = Baritone.settings().allowPlace.get() && MovementHelper.throwaway(baritone.getPlayerContext(), false);
|
||||||
|
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.get() && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
||||||
|
this.canSprint = Baritone.settings().allowSprint.get() && player.getFoodStats().getFoodLevel() > 6;
|
||||||
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.get();
|
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.get();
|
||||||
this.allowBreak = Baritone.settings().allowBreak.get();
|
this.allowBreak = Baritone.settings().allowBreak.get();
|
||||||
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.get();
|
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.get();
|
||||||
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.get();
|
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.get();
|
||||||
int depth = EnchantmentHelper.getDepthStriderModifier(player());
|
int depth = EnchantmentHelper.getDepthStriderModifier(player);
|
||||||
if (depth > 3) {
|
if (depth > 3) {
|
||||||
depth = 3;
|
depth = 3;
|
||||||
}
|
}
|
||||||
@@ -66,7 +84,27 @@ public class CalculationContext implements Helper {
|
|||||||
// why cache these things here, why not let the movements just get directly from settings?
|
// why cache these things here, why not let the movements just get directly from settings?
|
||||||
// because if some movements are calculated one way and others are calculated another way,
|
// because if some movements are calculated one way and others are calculated another way,
|
||||||
// then you get a wildly inconsistent path that isn't optimal for either scenario.
|
// then you get a wildly inconsistent path that isn't optimal for either scenario.
|
||||||
this.worldBorder = new BetterWorldBorder(world().getWorldBorder());
|
this.worldBorder = new BetterWorldBorder(world.getWorldBorder());
|
||||||
|
}
|
||||||
|
|
||||||
|
public final IBaritone getBaritone() {
|
||||||
|
return baritone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockState get(int x, int y, int z) {
|
||||||
|
return bsi.get0(x, y, z); // laughs maniacally
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoaded(int x, int z) {
|
||||||
|
return bsi.isLoaded(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockState get(BlockPos pos) {
|
||||||
|
return get(pos.getX(), pos.getY(), pos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock(int x, int y, int z) {
|
||||||
|
return get(x, y, z).getBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canPlaceThrowawayAt(int x, int y, int z) {
|
public boolean canPlaceThrowawayAt(int x, int y, int z) {
|
||||||
@@ -91,6 +129,22 @@ public class CalculationContext implements Helper {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public World world() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayerSP player() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockStateInterface bsi() {
|
||||||
|
return bsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorldData worldData() {
|
||||||
|
return worldData;
|
||||||
|
}
|
||||||
|
|
||||||
public ToolSet getToolSet() {
|
public ToolSet getToolSet() {
|
||||||
return toolSet;
|
return toolSet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,33 +17,29 @@
|
|||||||
|
|
||||||
package baritone.pathing.movement;
|
package baritone.pathing.movement;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.pathing.movement.MovementStatus;
|
import baritone.api.pathing.movement.MovementStatus;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.*;
|
||||||
import baritone.api.utils.Rotation;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.api.utils.RotationUtils;
|
|
||||||
import baritone.api.utils.VecUtils;
|
|
||||||
import baritone.utils.BlockBreakHelper;
|
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.Helper;
|
|
||||||
import baritone.utils.InputOverrideHandler;
|
|
||||||
import net.minecraft.block.BlockLiquid;
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static baritone.utils.InputOverrideHandler.Input;
|
public abstract class Movement implements IMovement, MovementHelper {
|
||||||
|
|
||||||
public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|
||||||
|
|
||||||
protected static final EnumFacing[] HORIZONTALS = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST};
|
protected static final EnumFacing[] HORIZONTALS = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST};
|
||||||
|
|
||||||
|
protected final IBaritone baritone;
|
||||||
|
protected final IPlayerContext ctx;
|
||||||
|
|
||||||
private MovementState currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
private MovementState currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
||||||
|
|
||||||
protected final BetterBlockPos src;
|
protected final BetterBlockPos src;
|
||||||
@@ -60,8 +56,6 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
*/
|
*/
|
||||||
protected final BetterBlockPos positionToPlace;
|
protected final BetterBlockPos positionToPlace;
|
||||||
|
|
||||||
private boolean didBreakLastTick;
|
|
||||||
|
|
||||||
private Double cost;
|
private Double cost;
|
||||||
|
|
||||||
public List<BlockPos> toBreakCached = null;
|
public List<BlockPos> toBreakCached = null;
|
||||||
@@ -70,21 +64,23 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
|
|
||||||
private Boolean calculatedWhileLoaded;
|
private Boolean calculatedWhileLoaded;
|
||||||
|
|
||||||
protected Movement(BetterBlockPos src, BetterBlockPos dest, BetterBlockPos[] toBreak, BetterBlockPos toPlace) {
|
protected Movement(IBaritone baritone, BetterBlockPos src, BetterBlockPos dest, BetterBlockPos[] toBreak, BetterBlockPos toPlace) {
|
||||||
|
this.baritone = baritone;
|
||||||
|
this.ctx = baritone.getPlayerContext();
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.positionsToBreak = toBreak;
|
this.positionsToBreak = toBreak;
|
||||||
this.positionToPlace = toPlace;
|
this.positionToPlace = toPlace;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Movement(BetterBlockPos src, BetterBlockPos dest, BetterBlockPos[] toBreak) {
|
protected Movement(IBaritone baritone, BetterBlockPos src, BetterBlockPos dest, BetterBlockPos[] toBreak) {
|
||||||
this(src, dest, toBreak, null);
|
this(baritone, src, dest, toBreak, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getCost() {
|
public double getCost() {
|
||||||
if (cost == null) {
|
if (cost == null) {
|
||||||
cost = calculateCost(new CalculationContext());
|
cost = calculateCost(new CalculationContext(baritone));
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
@@ -97,13 +93,13 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return getCost();
|
return getCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void override(double cost) {
|
public void override(double cost) {
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double calculateCostWithoutCaching() {
|
public double calculateCostWithoutCaching() {
|
||||||
return calculateCost(new CalculationContext());
|
return calculateCost(new CalculationContext(baritone));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,53 +110,32 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MovementStatus update() {
|
public MovementStatus update() {
|
||||||
player().capabilities.isFlying = false;
|
ctx.player().capabilities.isFlying = false;
|
||||||
MovementState latestState = updateState(currentState);
|
currentState = updateState(currentState);
|
||||||
if (MovementHelper.isLiquid(playerFeet())) {
|
if (MovementHelper.isLiquid(ctx, ctx.playerFeet())) {
|
||||||
latestState.setInput(Input.JUMP, true);
|
currentState.setInput(Input.JUMP, true);
|
||||||
}
|
}
|
||||||
if (player().isEntityInsideOpaqueBlock()) {
|
if (ctx.player().isEntityInsideOpaqueBlock()) {
|
||||||
latestState.setInput(Input.CLICK_LEFT, true);
|
currentState.setInput(Input.CLICK_LEFT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
|
// If the movement target has to force the new rotations, or we aren't using silent move, then force the rotations
|
||||||
latestState.getTarget().getRotation().ifPresent(rotation ->
|
currentState.getTarget().getRotation().ifPresent(rotation ->
|
||||||
Baritone.INSTANCE.getLookBehavior().updateTarget(
|
baritone.getLookBehavior().updateTarget(
|
||||||
rotation,
|
rotation,
|
||||||
latestState.getTarget().hasToForceRotations()));
|
currentState.getTarget().hasToForceRotations()));
|
||||||
|
|
||||||
// TODO: calculate movement inputs from latestState.getGoal().position
|
// TODO: calculate movement inputs from latestState.getGoal().position
|
||||||
// latestState.getTarget().position.ifPresent(null); NULL CONSUMER REALLY SHOULDN'T BE THE FINAL THING YOU SHOULD REALLY REPLACE THIS WITH ALMOST ACTUALLY ANYTHING ELSE JUST PLEASE DON'T LEAVE IT AS IT IS THANK YOU KANYE
|
// latestState.getTarget().position.ifPresent(null); NULL CONSUMER REALLY SHOULDN'T BE THE FINAL THING YOU SHOULD REALLY REPLACE THIS WITH ALMOST ACTUALLY ANYTHING ELSE JUST PLEASE DON'T LEAVE IT AS IT IS THANK YOU KANYE
|
||||||
|
|
||||||
this.didBreakLastTick = false;
|
currentState.getInputStates().forEach((input, forced) -> {
|
||||||
|
baritone.getInputOverrideHandler().setInputForceState(input, forced);
|
||||||
latestState.getInputStates().forEach((input, forced) -> {
|
|
||||||
if (Baritone.settings().leftClickWorkaround.get()) {
|
|
||||||
RayTraceResult trace = mc.objectMouseOver;
|
|
||||||
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
|
|
||||||
boolean isLeftClick = forced && input == Input.CLICK_LEFT;
|
|
||||||
|
|
||||||
// If we're forcing left click, we're in a gui screen, and we're looking
|
|
||||||
// at a block, break the block without a direct game input manipulation.
|
|
||||||
if (mc.currentScreen != null && isLeftClick && isBlockTrace) {
|
|
||||||
BlockBreakHelper.tryBreakBlock(trace.getBlockPos(), trace.sideHit);
|
|
||||||
this.didBreakLastTick = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced);
|
|
||||||
});
|
});
|
||||||
latestState.getInputStates().replaceAll((input, forced) -> false);
|
currentState.getInputStates().replaceAll((input, forced) -> false);
|
||||||
|
|
||||||
if (!this.didBreakLastTick) {
|
|
||||||
BlockBreakHelper.stopBreakingBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
currentState = latestState;
|
|
||||||
|
|
||||||
// If the current status indicates a completed movement
|
// If the current status indicates a completed movement
|
||||||
if (currentState.getStatus().isComplete()) {
|
if (currentState.getStatus().isComplete()) {
|
||||||
onFinish(latestState);
|
baritone.getInputOverrideHandler().clearAllKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentState.getStatus();
|
return currentState.getStatus();
|
||||||
@@ -172,21 +147,26 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
}
|
}
|
||||||
boolean somethingInTheWay = false;
|
boolean somethingInTheWay = false;
|
||||||
for (BetterBlockPos blockPos : positionsToBreak) {
|
for (BetterBlockPos blockPos : positionsToBreak) {
|
||||||
if (!MovementHelper.canWalkThrough(blockPos) && !(BlockStateInterface.getBlock(blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
|
if (!MovementHelper.canWalkThrough(ctx, blockPos) && !(BlockStateInterface.getBlock(ctx, blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
|
||||||
somethingInTheWay = true;
|
somethingInTheWay = true;
|
||||||
Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos);
|
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance());
|
||||||
if (reachable.isPresent()) {
|
if (reachable.isPresent()) {
|
||||||
MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos));
|
MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos));
|
||||||
state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true);
|
state.setTarget(new MovementState.MovementTarget(reachable.get(), true));
|
||||||
|
if (Objects.equals(ctx.getSelectedBlock().orElse(null), blockPos)) {
|
||||||
|
state.setInput(Input.CLICK_LEFT, true);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//get rekt minecraft
|
//get rekt minecraft
|
||||||
//i'm doing it anyway
|
//i'm doing it anyway
|
||||||
//i dont care if theres snow in the way!!!!!!!
|
//i dont care if theres snow in the way!!!!!!!
|
||||||
//you dont own me!!!!
|
//you dont own me!!!!
|
||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(blockPos)), true)
|
VecUtils.getBlockPosCenter(blockPos)), true)
|
||||||
).setInput(InputOverrideHandler.Input.CLICK_LEFT, 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);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,20 +198,6 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Run cleanup on state finish and declare success.
|
|
||||||
*/
|
|
||||||
public void onFinish(MovementState state) {
|
|
||||||
state.getInputStates().replaceAll((input, forced) -> false);
|
|
||||||
state.getInputStates().forEach((input, forced) -> Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancel() {
|
|
||||||
currentState.getInputStates().replaceAll((input, forced) -> false);
|
|
||||||
currentState.getInputStates().forEach((input, forced) -> Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(input, forced));
|
|
||||||
currentState.setStatus(MovementStatus.CANCELED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
currentState = new MovementState().setStatus(MovementStatus.PREPPING);
|
||||||
@@ -262,8 +228,8 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return getDest().subtract(getSrc());
|
return getDest().subtract(getSrc());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkLoadedChunk() {
|
public void checkLoadedChunk(CalculationContext context) {
|
||||||
calculatedWhileLoaded = !(world().getChunk(getDest()) instanceof EmptyChunk);
|
calculatedWhileLoaded = !(context.world().getChunk(getDest()) instanceof EmptyChunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -285,7 +251,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
}
|
}
|
||||||
List<BlockPos> result = new ArrayList<>();
|
List<BlockPos> result = new ArrayList<>();
|
||||||
for (BetterBlockPos positionToBreak : positionsToBreak) {
|
for (BetterBlockPos positionToBreak : positionsToBreak) {
|
||||||
if (!MovementHelper.canWalkThrough(positionToBreak)) {
|
if (!MovementHelper.canWalkThrough(ctx, positionToBreak)) {
|
||||||
result.add(positionToBreak);
|
result.add(positionToBreak);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,7 +265,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return toPlaceCached;
|
return toPlaceCached;
|
||||||
}
|
}
|
||||||
List<BlockPos> result = new ArrayList<>();
|
List<BlockPos> result = new ArrayList<>();
|
||||||
if (positionToPlace != null && !MovementHelper.canWalkOn(positionToPlace)) {
|
if (positionToPlace != null && !MovementHelper.canWalkOn(ctx, positionToPlace)) {
|
||||||
result.add(positionToPlace);
|
result.add(positionToPlace);
|
||||||
}
|
}
|
||||||
toPlaceCached = result;
|
toPlaceCached = result;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user